Δημοσίευση πηγής
Κατεβάστε την πηγή ZIP
CH-J SM Mobile
Περιηγηθείτε σε καταλόγους και αρχεία για μια συγκεκριμένη έκδοση εφαρμογών.
CH-J / SM Mobile
134 αρχεία
sm-mobile-20261016T050549Z-3678f2a05fa9
Προστέθηκε: · Χτισμένο:
1
import 'package:flutter/material.dart';2
import '../core/app_controller.dart';3
import '../l10n/strings.dart';4
import 'diagnostics_page.dart';5
import 'files_page.dart';6
import 'monitor_page.dart';7
import 'servers_page.dart';8
import 'settings_page.dart';9
import 'terminal_page.dart';11
class Workspace extends StatefulWidget {12
final AppController controller;13
const Workspace(this.controller, {super.key});14
@override15
State<Workspace> createState() => _WorkspaceState();16
}18
class _WorkspaceState extends State<Workspace> {19
int index = 0;20
static const names = [21
'servers',22
'terminal',23
'files',24
'monitor',25
'diagnostics',26
'settings',27
];28
static const icons = [29
Icons.dns_outlined,30
Icons.terminal,31
Icons.folder_outlined,32
Icons.monitor_heart_outlined,33
Icons.network_check,34
Icons.settings_outlined,35
];36
@override37
Widget build(BuildContext context) => ListenableBuilder(38
listenable: widget.controller.ssh,39
builder: (context, _) {40
final c = widget.controller;41
final tablet = MediaQuery.sizeOf(context).width >= 720;42
final page = switch (index) {43
0 => ServersPage(44
c,45
onConnected: () {46
if (mounted) setState(() => index = 1);47
},48
),49
1 => TerminalPage(50
c,51
key: ValueKey(c.ssh.connected ? c.ssh.client : null),52
),53
2 => FilesPage(c, key: ValueKey(c.ssh.connected ? c.ssh.client : null)),54
3 => MonitorPage(55
c,56
key: ValueKey(c.ssh.connected ? c.ssh.client : null),57
),58
4 => DiagnosticsPage(c),59
_ => SettingsPage(c),60
};61
return Scaffold(62
appBar: AppBar(63
title: Text('SM Mobile · ${context.tr(names[index])}'),64
actions: [65
if (c.ssh.connecting)66
IconButton(67
onPressed: c.ssh.disconnect,68
tooltip: context.tr('cancel'),69
icon: const Icon(Icons.close),70
),71
if (c.ssh.connected)72
IconButton(73
onPressed: c.ssh.disconnect,74
tooltip: context.tr('disconnect'),75
icon: const Icon(Icons.link_off),76
),77
if (!c.ssh.connected && !c.ssh.connecting && c.ssh.profile != null)78
IconButton(79
onPressed: () => connectProfile(context, c, c.ssh.profile!),80
tooltip: context.tr('reconnect'),81
icon: const Icon(Icons.refresh),82
),83
IconButton(84
onPressed: c.lock,85
tooltip: context.tr('lock'),86
icon: const Icon(Icons.lock_outline),87
),88
],89
),90
body: SafeArea(91
child: Column(92
children: [93
if (c.ssh.connecting) const LinearProgressIndicator(),94
if (c.ssh.error != null)95
MaterialBanner(96
content: Text(context.tr(c.ssh.error!)),97
actions: [98
TextButton(99
onPressed: () {100
c.ssh.error = null;101
c.changed();102
},103
child: Text(context.tr('done')),104
),105
],106
),107
if (c.ssh.connected)108
Padding(109
padding: const EdgeInsets.symmetric(110
horizontal: 16,111
vertical: 4,112
),113
child: Row(114
children: [115
const Icon(116
Icons.circle,117
color: Color(0xff43d6a0),118
size: 8,119
),120
const SizedBox(width: 8),121
Expanded(122
child: Text(123
'${c.ssh.profile!.name} · ${context.tr('connected')}',124
maxLines: 1,125
overflow: TextOverflow.ellipsis,126
),127
),128
],129
),130
),131
Expanded(132
child: Row(133
children: [134
if (tablet)135
LayoutBuilder(136
builder: (context, constraints) =>137
SingleChildScrollView(138
child: SizedBox(139
height: constraints.maxHeight.clamp(140
600 *141
MediaQuery.textScalerOf(context).scale(1),142
double.infinity,143
),144
child: NavigationRail(145
selectedIndex: index,146
onDestinationSelected: (v) =>147
setState(() => index = v),148
labelType: NavigationRailLabelType.all,149
destinations: List.generate(150
6,151
(i) => NavigationRailDestination(152
icon: Icon(icons[i]),153
label: Text(context.tr(names[i])),154
),155
),156
),157
),158
),159
),160
Expanded(child: page),161
],162
),163
),164
],165
),166
),167
bottomNavigationBar: tablet168
? null169
: NavigationBar(170
selectedIndex: index < 3 ? index : 3,171
onDestinationSelected: (v) async {172
if (v < 3) {173
setState(() => index = v);174
return;175
}176
final chosen = await showModalBottomSheet<int>(177
context: context,178
builder: (ctx) => SafeArea(179
child: Column(180
mainAxisSize: MainAxisSize.min,181
children: [182
for (var i = 3; i < 6; i++)183
ListTile(184
leading: Icon(icons[i]),185
title: Text(ctx.tr(names[i])),186
onTap: () => Navigator.pop(ctx, i),187
),188
],189
),190
),191
);192
if (chosen != null && mounted) setState(() => index = chosen);193
},194
destinations: [195
for (var i = 0; i < 3; i++)196
NavigationDestination(197
icon: Icon(icons[i]),198
label: context.tr(names[i]),199
),200
NavigationDestination(201
icon: Icon(index >= 3 ? icons[index] : Icons.more_horiz),202
label: context.tr(index >= 3 ? names[index] : 'settings'),203
),204
],205
),206
);207
},208
);209
}SHA-256
be8c5171d17a8ad3920c432d278a01341a870edda851e78dc286f84535814d3fCH-J Proprietary Software License 1.14 · Η πηγή παρέχεται στο CH-J Proprietary Software License 1.14. Η διαθεσιμότητά του δεν αλλάζει τους όρους της άδειας χρήσης ούτε χορηγεί πρόσθετα δικαιώματα.
Archive SHA-256
c486a807e4828998b9c57ab0f2e760f7980b31965fe118e89d3e1a5a2b65be65