diff --git a/lib/data/model/app/menu_item.dart b/lib/data/res/menu.dart similarity index 67% rename from lib/data/model/app/menu_item.dart rename to lib/data/res/menu.dart index 70947bbb..5b68e860 100644 --- a/lib/data/model/app/menu_item.dart +++ b/lib/data/res/menu.dart @@ -1,27 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:toolbox/data/res/color.dart'; -class DropdownBtnItem { - final String text; - final IconData icon; - - const DropdownBtnItem({ - required this.text, - required this.icon, - }); - - Widget get build => Row( - children: [ - Icon(icon, color: primaryColor), - const SizedBox( - width: 10, - ), - Text( - text, - ), - ], - ); -} +import '../../generated/l10n.dart'; +import '../../view/widget/dropdown_menu.dart'; class ServerTabMenuItems { static const List firstItems = [sftp, snippet, pkg, docker]; @@ -42,3 +22,22 @@ class DockerMenuItems { static const start = DropdownBtnItem(text: 'Start', icon: Icons.play_arrow); static const stop = DropdownBtnItem(text: 'Stop', icon: Icons.stop); } + +String getDropdownBtnText(S s, String text) { + switch (text) { + case 'Snippet': + return s.snippet; + case 'Pkg': + return s.pkgManage; + case 'Remove': + return s.delete; + case 'Start': + return s.start; + case 'Stop': + return s.stop; + case 'Edit': + return s.edit; + default: + return text; + } +} diff --git a/lib/data/res/status.dart b/lib/data/res/status.dart index 509af40d..ba12e9d4 100644 --- a/lib/data/res/status.dart +++ b/lib/data/res/status.dart @@ -6,12 +6,12 @@ import '../model/server/server_status.dart'; import '../model/server/tcp_status.dart'; get _initMemory => Memory( - total: 1, - used: 0, - free: 1, - cache: 0, - avail: 1, -); + total: 1, + used: 0, + free: 1, + cache: 0, + avail: 1, + ); get _initOneTimeCpuStatus => OneTimeCpuStatus( 'cpu', 0, @@ -45,4 +45,4 @@ get initStatus => ServerStatus( [DiskInfo('/', '/', 0, '0', '0', '0')], TcpStatus(0, 0, 0, 0), initNetSpeed, - ); \ No newline at end of file + ); diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index a6ce34df..afd53b32 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -192,6 +192,7 @@ class MessageLookup extends MessageLookupByLibrary { "Please input a target IP/domain."), "pingNoServer": MessageLookupByLibrary.simpleMessage( "No server to ping.\nPlease add a server in server tab."), + "pkgManager": MessageLookupByLibrary.simpleMessage("Pkg mgr"), "platformNotSupportUpdate": MessageLookupByLibrary.simpleMessage( "Current platform does not support in app update.\nPlease build from source and install it."), "plzEnterHost": diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index 2c2d5e4c..8db8697c 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -168,6 +168,7 @@ class MessageLookup extends MessageLookupByLibrary { "pingInputIP": MessageLookupByLibrary.simpleMessage("请输入目标IP或域名"), "pingNoServer": MessageLookupByLibrary.simpleMessage( "没有服务器可用于Ping\n请在服务器tab添加服务器后再试"), + "pkgManager": MessageLookupByLibrary.simpleMessage("包管理"), "platformNotSupportUpdate": MessageLookupByLibrary.simpleMessage("当前平台不支持更新,请编译最新源码后手动安装"), "plzEnterHost": MessageLookupByLibrary.simpleMessage("请输入主机"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 71b22031..6bb9a17f 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -1550,6 +1550,16 @@ class S { args: [newest], ); } + + /// `Pkg mgr` + String get pkgManager { + return Intl.message( + 'Pkg mgr', + name: 'pkgManager', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index f9f7eccf..11a42a93 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -148,5 +148,6 @@ "addOne": "Add one", "sshTip": "This function is now in the experimental stage. \nPlease report bugs on {url} or join our development.", "updateTip": "Update: v1.0.{newest}", - "updateTipTooLow": "Current version is too low, please update to v1.0.{newest}" + "updateTipTooLow": "Current version is too low, please update to v1.0.{newest}", + "pkgManager": "Pkg mgr" } \ No newline at end of file diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index 1bdb46e9..89911713 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -148,5 +148,6 @@ "addOne": "前去新增", "sshTip": "该功能目前处于测试阶段,请在 {url} 反馈问题,或者加入我们开发。", "updateTip": "新版本: v1.0.{newest}", - "updateTipTooLow": "当前版本过低,请升级至 v1.0.{newest}" + "updateTipTooLow": "当前版本过低,请升级至 v1.0.{newest}", + "pkgManager": "包管理" } \ No newline at end of file diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 20905461..5641f46b 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:toolbox/core/utils.dart'; -import 'package:toolbox/data/model/app/menu_item.dart'; import 'package:toolbox/data/model/docker/ps.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/provider/docker.dart'; @@ -17,6 +16,9 @@ import 'package:toolbox/view/widget/two_line_text.dart'; import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/url_text.dart'; +import '../../data/res/menu.dart'; +import '../widget/dropdown_menu.dart'; + class DockerManagePage extends StatefulWidget { final ServerPrivateInfo spi; const DockerManagePage(this.spi, {Key? key}) : super(key: key); @@ -288,11 +290,35 @@ class _DockerManagePageState extends State { trailing: IconButton( icon: const Icon(Icons.delete), onPressed: () async { - final result = await _docker.run('docker rmi ${e.id} -f'); - if (result != null) { - showSnackBar( - context, Text(getErrMsg(result) ?? _s.unknownError)); - } + showRoundDialog( + context, + _s.attention, + Text(_s.sureDelete(e.repo)), + [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(_s.cancel), + ), + TextButton( + onPressed: () async { + Navigator.of(context).pop(); + final result = await _docker.run( + 'docker rmi ${e.id} -f', + ); + if (result != null) { + showSnackBar( + context, + Text(getErrMsg(result) ?? _s.unknownError), + ); + } + }, + child: Text( + _s.ok, + style: const TextStyle(color: Colors.red), + ), + ), + ], + ); }, ), ), @@ -414,27 +440,26 @@ class _DockerManagePageState extends State { children: running.map( (item) { return ListTile( - title: Text(item.image), - subtitle: Text(item.status), - trailing: - _buildMoreBtn(item.running, item.containerId, docker.isBusy), + title: Text(item.name), + subtitle: Text('${item.image} ${item.status}'), + trailing: _buildMoreBtn(item, docker.isBusy), ); }, ).toList(), ); } - Widget _buildMoreBtn(bool running, String containerId, bool busy) { - final item = running ? DockerMenuItems.stop : DockerMenuItems.start; + Widget _buildMoreBtn(DockerPsItem dItem, bool busy) { + final item = dItem.running ? DockerMenuItems.stop : DockerMenuItems.start; return buildPopuopMenu( items: [ PopupMenuItem( value: item, - child: item.build, + child: item.build(_s), ), PopupMenuItem( value: DockerMenuItems.rm, - child: DockerMenuItems.rm.build, + child: DockerMenuItems.rm.build(_s), ), ], onSelected: (value) { @@ -445,13 +470,19 @@ class _DockerManagePageState extends State { final item = value as DropdownBtnItem; switch (item) { case DockerMenuItems.rm: - _docker.delete(containerId); + showRoundDialog( + context, + _s.attention, + Text(_s.sureDelete(dItem.name)), + [], + ); + _docker.delete(dItem.containerId); break; case DockerMenuItems.start: - _docker.start(containerId); + _docker.start(dItem.containerId); break; case DockerMenuItems.stop: - _docker.stop(containerId); + _docker.stop(dItem.containerId); break; } }, diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index e263ae90..10e5b5cf 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -5,7 +5,6 @@ import 'package:get_it/get_it.dart'; import 'package:provider/provider.dart'; import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/utils.dart'; -import 'package:toolbox/data/model/app/menu_item.dart'; import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/model/server/server_status.dart'; @@ -27,6 +26,8 @@ import 'package:toolbox/view/page/ssh.dart'; import 'package:toolbox/view/widget/picker.dart'; import 'package:toolbox/view/widget/round_rect_card.dart'; +import '../../../data/res/menu.dart'; +import '../../widget/dropdown_menu.dart'; import '../../widget/url_text.dart'; class ServerPage extends StatefulWidget { @@ -239,14 +240,14 @@ class _ServerPageState extends State ...ServerTabMenuItems.firstItems.map( (item) => PopupMenuItem( value: item, - child: item.build, + child: item.build(_s), ), ), const PopupMenuDivider(height: 1), ...ServerTabMenuItems.secondItems.map( (item) => PopupMenuItem( value: item, - child: item.build, + child: item.build(_s), ), ), ], diff --git a/lib/view/widget/dropdown_menu.dart b/lib/view/widget/dropdown_menu.dart new file mode 100644 index 00000000..2b68da4c --- /dev/null +++ b/lib/view/widget/dropdown_menu.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:toolbox/data/res/color.dart'; +import 'package:toolbox/data/res/menu.dart'; +import 'package:toolbox/generated/l10n.dart'; + +class DropdownBtnItem { + final String text; + final IconData icon; + + const DropdownBtnItem({ + required this.text, + required this.icon, + }); + + Widget build(S s) => Row( + children: [ + Icon(icon, color: primaryColor), + const SizedBox( + width: 10, + ), + Text( + getDropdownBtnText(s, text), + ), + ], + ); +}