diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 6d607cd8..75948054 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -126,6 +126,12 @@ abstract class S { /// **'Add private key'** String get addPrivateKey; + /// No description provided for @added2List. + /// + /// In en, this message translates to: + /// **'Added to task list'** + String get added2List; + /// No description provided for @all. /// /// In en, this message translates to: @@ -138,12 +144,6 @@ abstract class S { /// **'Already in last directory.'** String get alreadyLastDir; - /// No description provided for @appPrimaryColor. - /// - /// In en, this message translates to: - /// **'App primary color'** - String get appPrimaryColor; - /// No description provided for @attention. /// /// In en, this message translates to: @@ -864,6 +864,12 @@ abstract class S { /// **'Preview'** String get preview; + /// No description provided for @primaryColor. + /// + /// In en, this message translates to: + /// **'Primary color'** + String get primaryColor; + /// No description provided for @privateKey. /// /// 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 bcbeca05..6e9e5908 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -19,15 +19,15 @@ class SDe extends S { @override String get addPrivateKey => 'Private key hinzufügen'; + @override + String get added2List => 'Zur Aufgabenliste hinzugefügt'; + @override String get all => 'Alle'; @override String get alreadyLastDir => 'Bereits im letzten Verzeichnis.'; - @override - String get appPrimaryColor => 'Farbschema'; - @override String get attention => 'Achtung'; @@ -410,6 +410,9 @@ class SDe extends S { @override String get preview => 'Vorschau'; + @override + String get primaryColor => 'Farbschema'; + @override String get privateKey => 'Private Key'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 9c5dfabb..bb101517 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -19,15 +19,15 @@ class SEn extends S { @override String get addPrivateKey => 'Add private key'; + @override + String get added2List => 'Added to task list'; + @override String get all => 'All'; @override String get alreadyLastDir => 'Already in last directory.'; - @override - String get appPrimaryColor => 'App primary color'; - @override String get attention => 'Attention'; @@ -410,6 +410,9 @@ class SEn extends S { @override String get preview => 'Preview'; + @override + String get primaryColor => 'Primary color'; + @override String get privateKey => 'Private Key'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index 468c76e4..6212233a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -19,15 +19,15 @@ class SZh extends S { @override String get addPrivateKey => '添加一个私钥'; + @override + String get added2List => '已添加至任务列表'; + @override String get all => '所有'; @override String get alreadyLastDir => '已经是最上层目录了'; - @override - String get appPrimaryColor => 'App主要色'; - @override String get attention => '注意'; @@ -410,6 +410,9 @@ class SZh extends S { @override String get preview => '预览'; + @override + String get primaryColor => '主题色'; + @override String get privateKey => '私钥'; @@ -647,15 +650,15 @@ class SZhTw extends SZh { @override String get addPrivateKey => '新增一個私鑰'; + @override + String get added2List => '已添加至任務列表'; + @override String get all => '所有'; @override String get alreadyLastDir => '已經是最上層目錄了'; - @override - String get appPrimaryColor => '主要色調'; - @override String get attention => '注意'; @@ -1029,6 +1032,9 @@ class SZhTw extends SZh { @override String get preview => '預覽'; + @override + String get primaryColor => '主要色調'; + @override String get privateKey => '私鑰'; diff --git a/lib/app.dart b/lib/app.dart index ce23e7dd..8f3c6545 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -24,10 +24,10 @@ class MyApp extends StatelessWidget { return ValueListenableBuilder( valueListenable: _setting.themeMode.listenable(), builder: (_, tMode, __) { - final ok = tMode >= 0 && tMode <= ThemeMode.values.length - 1; + final isAMOLED = tMode >= 0 && tMode <= ThemeMode.values.length - 1; // Issue #57 // if not [ok] -> [AMOLED] mode, use [ThemeMode.dark] - final themeMode = ok ? ThemeMode.values[tMode] : ThemeMode.dark; + final themeMode = isAMOLED ? ThemeMode.values[tMode] : ThemeMode.dark; final localeStr = _setting.locale.fetch(); final locale = localeStr?.toLocale; final darkTheme = ThemeData( @@ -47,7 +47,7 @@ class MyApp extends StatelessWidget { useMaterial3: true, colorSchemeSeed: primaryColor, ), - darkTheme: ok + darkTheme: isAMOLED ? darkTheme : darkTheme.copyWith( scaffoldBackgroundColor: Colors.black, diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 2f414ccf..eb85c4b9 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -57,6 +57,10 @@ class ServerProvider extends BusyProvider { } else { _serverOrder.addAll(_servers.keys); } + final surplus = _serverOrder.where( + (e) => !_servers.containsKey(e), + ); + _serverOrder.removeWhere((element) => surplus.contains(element)); _settingStore.serverOrder.put(_serverOrder); _updateTags(); setBusyState(false); diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 115e535f..bd7b91ea 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -5,9 +5,9 @@ "add": "Neu", "addAServer": "Server hinzufügen", "addPrivateKey": "Private key hinzufügen", + "added2List": "Zur Aufgabenliste hinzugefügt", "all": "Alle", "alreadyLastDir": "Bereits im letzten Verzeichnis.", - "appPrimaryColor": "Farbschema", "attention": "Achtung", "auto": "System folgen", "backup": "Backup", @@ -125,6 +125,7 @@ "plzSelectKey": "Wähle einen Key.", "port": "Port", "preview": "Vorschau", + "primaryColor": "Farbschema", "privateKey": "Private Key", "process": "Prozess", "pushToken": "Push Token", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 069f5933..164c4332 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -5,9 +5,9 @@ "add": "Add", "addAServer": "add a server", "addPrivateKey": "Add private key", + "added2List": "Added to task list", "all": "All", "alreadyLastDir": "Already in last directory.", - "appPrimaryColor": "App primary color", "attention": "Attention", "auto": "Auto", "backup": "Backup", @@ -128,6 +128,7 @@ "plzSelectKey": "Please select a key.", "port": "Port", "preview": "Preview", + "primaryColor": "Primary color", "privateKey": "Private Key", "process": "Process", "pushToken": "Push token", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 1ab4c50c..06ea3ddd 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -5,9 +5,9 @@ "add": "新增", "addAServer": "添加服务器", "addPrivateKey": "添加一个私钥", + "added2List": "已添加至任务列表", "all": "所有", "alreadyLastDir": "已经是最上层目录了", - "appPrimaryColor": "App主要色", "attention": "注意", "auto": "自动", "backup": "备份", @@ -128,6 +128,7 @@ "plzSelectKey": "请选择私钥", "port": "端口", "preview": "预览", + "primaryColor": "主题色", "privateKey": "私钥", "process": "进程", "pushToken": "消息推送 Token", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 95fdec85..80c24353 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -5,9 +5,9 @@ "add": "新增", "addAServer": "新增服務器", "addPrivateKey": "新增一個私鑰", + "added2List": "已添加至任務列表", "all": "所有", "alreadyLastDir": "已經是最上層目錄了", - "appPrimaryColor": "主要色調", "attention": "注意", "auto": "自動", "backup": "備份", @@ -125,6 +125,7 @@ "plzSelectKey": "請選擇私鑰", "port": "端口", "preview": "預覽", + "primaryColor": "主要色調", "privateKey": "私鑰", "process": "進程", "pushToken": "消息推送 Token", diff --git a/lib/view/page/ping.dart b/lib/view/page/ping.dart index 830f499c..5f0b5ce8 100644 --- a/lib/view/page/ping.dart +++ b/lib/view/page/ping.dart @@ -106,10 +106,7 @@ class _PingPageState extends State return Center( child: Text( _s.noResult, - style: TextStyle( - fontSize: 18, - color: primaryColor, - ), + style: const TextStyle(fontSize: 18), ), ); } diff --git a/lib/view/page/setting.dart b/lib/view/page/setting.dart index e074fc9c..3b9641e9 100644 --- a/lib/view/page/setting.dart +++ b/lib/view/page/setting.dart @@ -247,12 +247,12 @@ class _SettingPageState extends State { ), ), title: Text( - _s.appPrimaryColor, + _s.primaryColor, ), onTap: () async { await showRoundDialog( context: context, - title: Text(_s.appPrimaryColor), + title: Text(_s.primaryColor), child: MaterialColorPicker( shrinkWrap: true, allowShades: true, @@ -640,7 +640,7 @@ class _SettingPageState extends State { }, ).toList(); return ListTile( - title: Text("${_s.editor} ${_s.theme}"), + title: Text(_s.theme), trailing: ValueBuilder( listenable: _editorTheme, build: () => PopupMenuButton( diff --git a/lib/view/page/sftp/local.dart b/lib/view/page/sftp/local.dart index 54d95d7d..6a8bad3d 100644 --- a/lib/view/page/sftp/local.dart +++ b/lib/view/page/sftp/local.dart @@ -9,8 +9,10 @@ import 'package:toolbox/data/provider/sftp.dart'; import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/locator.dart'; import 'package:toolbox/view/page/editor.dart'; +import 'package:toolbox/view/page/sftp/remote.dart'; import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/picker.dart'; +import 'package:toolbox/view/widget/round_rect_card.dart'; import '../../../core/extension/numx.dart'; import '../../../core/extension/stringx.dart'; @@ -112,13 +114,14 @@ class _SFTPDownloadedPageState extends State { final files = dir.listSync(); return ListView.builder( itemCount: files.length, + padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7), itemBuilder: (context, index) { var file = files[index]; var fileName = file.path.split('/').last; var stat = file.statSync(); var isDir = stat.type == FileSystemEntityType.directory; - return ListTile( + return RoundRectCard(ListTile( leading: isDir ? const Icon(Icons.folder) : const Icon(Icons.insert_drive_file), @@ -138,7 +141,7 @@ class _SFTPDownloadedPageState extends State { _path!.update(fileName); setState(() {}); }, - ); + )); }, ); } @@ -243,19 +246,6 @@ class _SFTPDownloadedPageState extends State { title: Text(_s.upload), onTap: () async { context.pop(); - final remotePath = await showRoundDialog( - context: context, - title: Text(_s.remotePath), - child: Input( - controller: TextEditingController(text: '/'), - onSubmitted: (p0) { - context.pop(p0); - }, - )); - if (remotePath == null) { - showSnackBar(context, Text(_s.fieldMustNotEmpty)); - return; - } final serverProvider = locator(); final ids = serverProvider.serverOrder; var idx = 0; @@ -277,10 +267,22 @@ class _SFTPDownloadedPageState extends State { showSnackBar(context, Text(_s.noResult)); return; } + final remotePath = await AppRoute( + SFTPPage( + spi, + selectPath: true, + ), + 'SFTP page (select)', + ).go(context); + if (remotePath == null) { + showSnackBar(context, Text(_s.fieldMustNotEmpty)); + return; + } locator().add( SftpReqItem(spi, remotePath, file.absolute.path), SftpReqType.upload, ); + showSnackBar(context, Text(_s.added2List)); }, ), ListTile( diff --git a/lib/view/page/sftp/remote.dart b/lib/view/page/sftp/remote.dart index bcb1f875..f20afbc5 100644 --- a/lib/view/page/sftp/remote.dart +++ b/lib/view/page/sftp/remote.dart @@ -9,6 +9,7 @@ import 'package:toolbox/core/extension/sftpfile.dart'; import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/view/page/editor.dart'; import 'package:toolbox/view/page/sftp/local.dart'; +import 'package:toolbox/view/widget/round_rect_card.dart'; import '../../../core/extension/numx.dart'; import '../../../core/extension/stringx.dart'; @@ -33,7 +34,14 @@ import 'mission.dart'; class SFTPPage extends StatefulWidget { final ServerPrivateInfo spi; final String? initPath; - const SFTPPage(this.spi, {Key? key, this.initPath}) : super(key: key); + final bool selectPath; + + const SFTPPage( + this.spi, { + Key? key, + this.initPath, + this.selectPath = false, + }) : super(key: key); @override _SFTPPageState createState() => _SFTPPageState(); @@ -86,6 +94,24 @@ class _SFTPPageState extends State { } Widget _buildBottom() { + final children = widget.selectPath + ? [ + IconButton( + onPressed: () => context.pop(_status.path?.path), + icon: const Icon(Icons.done)) + ] + : [ + IconButton( + padding: const EdgeInsets.all(0), + onPressed: () async { + await _backward(); + }, + icon: const Icon(Icons.arrow_back), + ), + _buildAddBtn(), + _buildGotoBtn(), + _buildUploadBtn(), + ]; return SafeArea( child: Container( padding: const EdgeInsets.fromLTRB(11, 7, 11, 11), @@ -96,18 +122,7 @@ class _SFTPPageState extends State { (_status.path?.path ?? _s.loadingFiles).omitStartStr(), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconButton( - padding: const EdgeInsets.all(0), - onPressed: () async { - await _backward(); - }, - icon: const Icon(Icons.arrow_back), - ), - _buildAddBtn(), - _buildGotoBtn(), - _buildUploadBtn(), - ], + children: children, ) ], ), @@ -250,10 +265,11 @@ class _SFTPPageState extends State { child: ListView.builder( itemCount: _status.files!.length, controller: _scrollController, + padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3), itemBuilder: (context, index) { final file = _status.files![index]; final isDir = file.attr.isDirectory; - return ListTile( + return RoundRectCard(ListTile( leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file), title: Text(file.filename), trailing: Text( @@ -272,7 +288,7 @@ class _SFTPPageState extends State { } }, onLongPress: () => _onItemPress(context, file, !isDir), - ); + )); }, ), ), @@ -335,7 +351,9 @@ class _SFTPPageState extends State { final completer = Completer(); final req = SftpReqItem(widget.spi, remotePath, localPath); _sftp.add(req, SftpReqType.download, completer: completer); + showRoundDialog(context: context, child: centerSizedLoading); await completer.future; + context.pop(); final result = await AppRoute( EditorPage(path: localPath),