mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
fix & opt.
fix: net iface parse opt: `ssh` page auto unpress `ctrl or alt` after call opt: enable translation for menu opt: add confirm to `docker` page
This commit is contained in:
@@ -1,27 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:toolbox/data/res/color.dart';
|
|
||||||
|
|
||||||
class DropdownBtnItem {
|
import '../../generated/l10n.dart';
|
||||||
final String text;
|
import '../../view/widget/dropdown_menu.dart';
|
||||||
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,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ServerTabMenuItems {
|
class ServerTabMenuItems {
|
||||||
static const List<DropdownBtnItem> firstItems = [sftp, snippet, pkg, docker];
|
static const List<DropdownBtnItem> firstItems = [sftp, snippet, pkg, docker];
|
||||||
@@ -42,3 +22,22 @@ class DockerMenuItems {
|
|||||||
static const start = DropdownBtnItem(text: 'Start', icon: Icons.play_arrow);
|
static const start = DropdownBtnItem(text: 'Start', icon: Icons.play_arrow);
|
||||||
static const stop = DropdownBtnItem(text: 'Stop', icon: Icons.stop);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ get _initMemory => Memory(
|
|||||||
free: 1,
|
free: 1,
|
||||||
cache: 0,
|
cache: 0,
|
||||||
avail: 1,
|
avail: 1,
|
||||||
);
|
);
|
||||||
get _initOneTimeCpuStatus => OneTimeCpuStatus(
|
get _initOneTimeCpuStatus => OneTimeCpuStatus(
|
||||||
'cpu',
|
'cpu',
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Please input a target IP/domain."),
|
"Please input a target IP/domain."),
|
||||||
"pingNoServer": MessageLookupByLibrary.simpleMessage(
|
"pingNoServer": MessageLookupByLibrary.simpleMessage(
|
||||||
"No server to ping.\nPlease add a server in server tab."),
|
"No server to ping.\nPlease add a server in server tab."),
|
||||||
|
"pkgManager": MessageLookupByLibrary.simpleMessage("Pkg mgr"),
|
||||||
"platformNotSupportUpdate": MessageLookupByLibrary.simpleMessage(
|
"platformNotSupportUpdate": MessageLookupByLibrary.simpleMessage(
|
||||||
"Current platform does not support in app update.\nPlease build from source and install it."),
|
"Current platform does not support in app update.\nPlease build from source and install it."),
|
||||||
"plzEnterHost":
|
"plzEnterHost":
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"pingInputIP": MessageLookupByLibrary.simpleMessage("请输入目标IP或域名"),
|
"pingInputIP": MessageLookupByLibrary.simpleMessage("请输入目标IP或域名"),
|
||||||
"pingNoServer": MessageLookupByLibrary.simpleMessage(
|
"pingNoServer": MessageLookupByLibrary.simpleMessage(
|
||||||
"没有服务器可用于Ping\n请在服务器tab添加服务器后再试"),
|
"没有服务器可用于Ping\n请在服务器tab添加服务器后再试"),
|
||||||
|
"pkgManager": MessageLookupByLibrary.simpleMessage("包管理"),
|
||||||
"platformNotSupportUpdate":
|
"platformNotSupportUpdate":
|
||||||
MessageLookupByLibrary.simpleMessage("当前平台不支持更新,请编译最新源码后手动安装"),
|
MessageLookupByLibrary.simpleMessage("当前平台不支持更新,请编译最新源码后手动安装"),
|
||||||
"plzEnterHost": MessageLookupByLibrary.simpleMessage("请输入主机"),
|
"plzEnterHost": MessageLookupByLibrary.simpleMessage("请输入主机"),
|
||||||
|
|||||||
@@ -1550,6 +1550,16 @@ class S {
|
|||||||
args: [newest],
|
args: [newest],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Pkg mgr`
|
||||||
|
String get pkgManager {
|
||||||
|
return Intl.message(
|
||||||
|
'Pkg mgr',
|
||||||
|
name: 'pkgManager',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||||
|
|||||||
@@ -148,5 +148,6 @@
|
|||||||
"addOne": "Add one",
|
"addOne": "Add one",
|
||||||
"sshTip": "This function is now in the experimental stage. \nPlease report bugs on {url} or join our development.",
|
"sshTip": "This function is now in the experimental stage. \nPlease report bugs on {url} or join our development.",
|
||||||
"updateTip": "Update: v1.0.{newest}",
|
"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"
|
||||||
}
|
}
|
||||||
@@ -148,5 +148,6 @@
|
|||||||
"addOne": "前去新增",
|
"addOne": "前去新增",
|
||||||
"sshTip": "该功能目前处于测试阶段,请在 {url} 反馈问题,或者加入我们开发。",
|
"sshTip": "该功能目前处于测试阶段,请在 {url} 反馈问题,或者加入我们开发。",
|
||||||
"updateTip": "新版本: v1.0.{newest}",
|
"updateTip": "新版本: v1.0.{newest}",
|
||||||
"updateTipTooLow": "当前版本过低,请升级至 v1.0.{newest}"
|
"updateTipTooLow": "当前版本过低,请升级至 v1.0.{newest}",
|
||||||
|
"pkgManager": "包管理"
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/utils.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/docker/ps.dart';
|
||||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||||
import 'package:toolbox/data/provider/docker.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/round_rect_card.dart';
|
||||||
import 'package:toolbox/view/widget/url_text.dart';
|
import 'package:toolbox/view/widget/url_text.dart';
|
||||||
|
|
||||||
|
import '../../data/res/menu.dart';
|
||||||
|
import '../widget/dropdown_menu.dart';
|
||||||
|
|
||||||
class DockerManagePage extends StatefulWidget {
|
class DockerManagePage extends StatefulWidget {
|
||||||
final ServerPrivateInfo spi;
|
final ServerPrivateInfo spi;
|
||||||
const DockerManagePage(this.spi, {Key? key}) : super(key: key);
|
const DockerManagePage(this.spi, {Key? key}) : super(key: key);
|
||||||
@@ -288,12 +290,36 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
|||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: const Icon(Icons.delete),
|
icon: const Icon(Icons.delete),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await _docker.run('docker rmi ${e.id} -f');
|
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) {
|
if (result != null) {
|
||||||
showSnackBar(
|
showSnackBar(
|
||||||
context, Text(getErrMsg(result) ?? _s.unknownError));
|
context,
|
||||||
|
Text(getErrMsg(result) ?? _s.unknownError),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
child: Text(
|
||||||
|
_s.ok,
|
||||||
|
style: const TextStyle(color: Colors.red),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -414,27 +440,26 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
|||||||
children: running.map(
|
children: running.map(
|
||||||
(item) {
|
(item) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(item.image),
|
title: Text(item.name),
|
||||||
subtitle: Text(item.status),
|
subtitle: Text('${item.image} ${item.status}'),
|
||||||
trailing:
|
trailing: _buildMoreBtn(item, docker.isBusy),
|
||||||
_buildMoreBtn(item.running, item.containerId, docker.isBusy),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
).toList(),
|
).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMoreBtn(bool running, String containerId, bool busy) {
|
Widget _buildMoreBtn(DockerPsItem dItem, bool busy) {
|
||||||
final item = running ? DockerMenuItems.stop : DockerMenuItems.start;
|
final item = dItem.running ? DockerMenuItems.stop : DockerMenuItems.start;
|
||||||
return buildPopuopMenu(
|
return buildPopuopMenu(
|
||||||
items: [
|
items: [
|
||||||
PopupMenuItem<DropdownBtnItem>(
|
PopupMenuItem<DropdownBtnItem>(
|
||||||
value: item,
|
value: item,
|
||||||
child: item.build,
|
child: item.build(_s),
|
||||||
),
|
),
|
||||||
PopupMenuItem<DropdownBtnItem>(
|
PopupMenuItem<DropdownBtnItem>(
|
||||||
value: DockerMenuItems.rm,
|
value: DockerMenuItems.rm,
|
||||||
child: DockerMenuItems.rm.build,
|
child: DockerMenuItems.rm.build(_s),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
@@ -445,13 +470,19 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
|||||||
final item = value as DropdownBtnItem;
|
final item = value as DropdownBtnItem;
|
||||||
switch (item) {
|
switch (item) {
|
||||||
case DockerMenuItems.rm:
|
case DockerMenuItems.rm:
|
||||||
_docker.delete(containerId);
|
showRoundDialog(
|
||||||
|
context,
|
||||||
|
_s.attention,
|
||||||
|
Text(_s.sureDelete(dItem.name)),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
_docker.delete(dItem.containerId);
|
||||||
break;
|
break;
|
||||||
case DockerMenuItems.start:
|
case DockerMenuItems.start:
|
||||||
_docker.start(containerId);
|
_docker.start(dItem.containerId);
|
||||||
break;
|
break;
|
||||||
case DockerMenuItems.stop:
|
case DockerMenuItems.stop:
|
||||||
_docker.stop(containerId);
|
_docker.stop(dItem.containerId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:get_it/get_it.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/route.dart';
|
import 'package:toolbox/core/route.dart';
|
||||||
import 'package:toolbox/core/utils.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.dart';
|
||||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||||
import 'package:toolbox/data/model/server/server_status.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/picker.dart';
|
||||||
import 'package:toolbox/view/widget/round_rect_card.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';
|
import '../../widget/url_text.dart';
|
||||||
|
|
||||||
class ServerPage extends StatefulWidget {
|
class ServerPage extends StatefulWidget {
|
||||||
@@ -239,14 +240,14 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
...ServerTabMenuItems.firstItems.map(
|
...ServerTabMenuItems.firstItems.map(
|
||||||
(item) => PopupMenuItem<DropdownBtnItem>(
|
(item) => PopupMenuItem<DropdownBtnItem>(
|
||||||
value: item,
|
value: item,
|
||||||
child: item.build,
|
child: item.build(_s),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const PopupMenuDivider(height: 1),
|
const PopupMenuDivider(height: 1),
|
||||||
...ServerTabMenuItems.secondItems.map(
|
...ServerTabMenuItems.secondItems.map(
|
||||||
(item) => PopupMenuItem<DropdownBtnItem>(
|
(item) => PopupMenuItem<DropdownBtnItem>(
|
||||||
value: item,
|
value: item,
|
||||||
child: item.build,
|
child: item.build(_s),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
26
lib/view/widget/dropdown_menu.dart
Normal file
26
lib/view/widget/dropdown_menu.dart
Normal file
@@ -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),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user