diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 86840967..6d607cd8 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -870,6 +870,12 @@ abstract class S { /// **'Private Key'** String get privateKey; + /// No description provided for @process. + /// + /// In en, this message translates to: + /// **'Process'** + String get process; + /// No description provided for @pushToken. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index de58756a..bcbeca05 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -413,6 +413,9 @@ class SDe extends S { @override String get privateKey => 'Private Key'; + @override + String get process => 'Prozess'; + @override String get pushToken => 'Push Token'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 687b9ee8..9c5dfabb 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -413,6 +413,9 @@ class SEn extends S { @override String get privateKey => 'Private Key'; + @override + String get process => 'Process'; + @override String get pushToken => 'Push token'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index a87e4a7f..468c76e4 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -413,6 +413,9 @@ class SZh extends S { @override String get privateKey => '私钥'; + @override + String get process => '进程'; + @override String get pushToken => '消息推送 Token'; @@ -1029,6 +1032,9 @@ class SZhTw extends SZh { @override String get privateKey => '私鑰'; + @override + String get process => '進程'; + @override String get pushToken => '消息推送 Token'; diff --git a/lib/core/utils/ui.dart b/lib/core/utils/ui.dart index 8a888e01..bbbf8ba4 100644 --- a/lib/core/utils/ui.dart +++ b/lib/core/utils/ui.dart @@ -168,9 +168,9 @@ void showSnippetDialog( void switchStatusBar({required bool hide}) { if (hide) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, - overlays: []); + overlays: []); } else { SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge, - overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); + overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); } } diff --git a/lib/data/model/app/menu.dart b/lib/data/model/app/menu.dart index c46e7a5d..9e091900 100644 --- a/lib/data/model/app/menu.dart +++ b/lib/data/model/app/menu.dart @@ -6,6 +6,7 @@ enum ServerTabMenuType { snippet, pkg, docker, + process, edit; IconData get icon { @@ -20,6 +21,8 @@ enum ServerTabMenuType { return Icons.view_agenda; case ServerTabMenuType.edit: return Icons.edit; + case ServerTabMenuType.process: + return Icons.list_alt_outlined; } } @@ -35,6 +38,8 @@ enum ServerTabMenuType { return 'Docker'; case ServerTabMenuType.edit: return s.edit; + case ServerTabMenuType.process: + return s.process; } } diff --git a/lib/data/model/app/shell_func.dart b/lib/data/model/app/shell_func.dart new file mode 100644 index 00000000..545ac20b --- /dev/null +++ b/lib/data/model/app/shell_func.dart @@ -0,0 +1,41 @@ +class AppShellFunc { + final String name; + final String cmd; + final String flag; + + const AppShellFunc(this.name, this.cmd, this.flag); +} + +typedef AppShellFuncs = List; + +extension AppShellFuncsExt on AppShellFuncs { + String get generate { + final sb = StringBuffer(); + // Write each func + for (final func in this) { + sb.write(''' +${func.name}() { +${func.cmd} +} + +'''); + } + + // Write switch case + sb.write('case \$1 in\n'); + for (final func in this) { + sb.write(''' + '-${func.flag}') + ${func.name} + ;; +'''); + } + sb.write(''' + *) + echo "Invalid argument \$1" + ;; +esac +'''); + return sb.toString(); + } +} diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 8483711f..2f414ccf 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -240,7 +240,8 @@ class ServerProvider extends BusyProvider { if (s.client == null) return; // run script to get server status - raw = await s.client!.run("sh $shellPath").string; + raw = + await s.client!.run("sh $shellPath -${shellFuncStatus.flag}").string; segments = raw.split(seperator).map((e) => e.trim()).toList(); if (raw.isEmpty || segments.length != CmdType.values.length) { s.state = ServerState.failed; diff --git a/lib/data/res/server_cmd.dart b/lib/data/res/server_cmd.dart index 7ad6d0f8..69933f05 100644 --- a/lib/data/res/server_cmd.dart +++ b/lib/data/res/server_cmd.dart @@ -1,3 +1,4 @@ +import '../model/app/shell_func.dart'; import 'build_data.dart'; const seperator = 'SrvBox'; @@ -36,11 +37,37 @@ const _cmdList = [ 'cat /etc/redhat-release', ]; +final shellFuncStatus = AppShellFunc( + 'status', + _cmdList.join('\necho $seperator\n'), + 's', +); + +// Check if `htop` is installed. +// Then app open SSH term and use `htop` or `ps` to see process. +const shellFuncProcess = AppShellFunc( + 'process', + ''' +if command -v htop &> /dev/null +then + htop +else + top +fi +''', + 'p', +); + +final _generated = [ + shellFuncStatus, + shellFuncProcess, +].generate; + final shellCmd = """ -# Script for app `${BuildData.name} v${BuildData.build}` +# Script for app `${BuildData.name} v1.0.${BuildData.build}` # Delete this file while app is running will cause app crash -${_cmdList.join('\necho $seperator\n')} +$_generated """; final installShellCmd = "mkdir -p $serverBoxDir && " diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 941ce479..115e535f 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -126,6 +126,7 @@ "port": "Port", "preview": "Vorschau", "privateKey": "Private Key", + "process": "Prozess", "pushToken": "Push Token", "pwd": "Passwort", "remotePath": "Entfernte Pfade", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 853d3713..069f5933 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -129,6 +129,7 @@ "port": "Port", "preview": "Preview", "privateKey": "Private Key", + "process": "Process", "pushToken": "Push token", "pwd": "Password", "remotePath": "Remote path", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 8e6cfe4a..1ab4c50c 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -129,6 +129,7 @@ "port": "端口", "preview": "预览", "privateKey": "私钥", + "process": "进程", "pushToken": "消息推送 Token", "pwd": "密码", "remotePath": "远端路径", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 9e8a982d..95fdec85 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -126,6 +126,7 @@ "port": "端口", "preview": "預覽", "privateKey": "私鑰", + "process": "進程", "pushToken": "消息推送 Token", "pwd": "密碼", "remotePath": "遠端路徑", diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 99060254..aeb795f0 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/utils/misc.dart'; +import 'package:toolbox/data/res/server_cmd.dart'; import '../../../core/route.dart'; import '../../../core/utils/ui.dart'; @@ -336,6 +337,15 @@ class _ServerPageState extends State case ServerTabMenuType.docker: AppRoute(DockerManagePage(spi), 'Docker manage').go(context); break; + case ServerTabMenuType.process: + AppRoute( + SSHPage( + spi: spi, + initCmd: 'sh $shellPath -${shellFuncProcess.flag}', + ), + 'ssh page (process)', + ).go(context); + break; } }, );