opt. & fix

opt.: upload file
fix: surplus server order
opt.: sftp view
This commit is contained in:
lollipopkit
2023-06-21 18:30:52 +08:00
parent 3a8e189dd7
commit 06d6500ef6
14 changed files with 105 additions and 62 deletions

View File

@@ -126,6 +126,12 @@ abstract class S {
/// **'Add private key'** /// **'Add private key'**
String get addPrivateKey; 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. /// No description provided for @all.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -138,12 +144,6 @@ abstract class S {
/// **'Already in last directory.'** /// **'Already in last directory.'**
String get alreadyLastDir; 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. /// No description provided for @attention.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -864,6 +864,12 @@ abstract class S {
/// **'Preview'** /// **'Preview'**
String get 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. /// No description provided for @privateKey.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -19,15 +19,15 @@ class SDe extends S {
@override @override
String get addPrivateKey => 'Private key hinzufügen'; String get addPrivateKey => 'Private key hinzufügen';
@override
String get added2List => 'Zur Aufgabenliste hinzugefügt';
@override @override
String get all => 'Alle'; String get all => 'Alle';
@override @override
String get alreadyLastDir => 'Bereits im letzten Verzeichnis.'; String get alreadyLastDir => 'Bereits im letzten Verzeichnis.';
@override
String get appPrimaryColor => 'Farbschema';
@override @override
String get attention => 'Achtung'; String get attention => 'Achtung';
@@ -410,6 +410,9 @@ class SDe extends S {
@override @override
String get preview => 'Vorschau'; String get preview => 'Vorschau';
@override
String get primaryColor => 'Farbschema';
@override @override
String get privateKey => 'Private Key'; String get privateKey => 'Private Key';

View File

@@ -19,15 +19,15 @@ class SEn extends S {
@override @override
String get addPrivateKey => 'Add private key'; String get addPrivateKey => 'Add private key';
@override
String get added2List => 'Added to task list';
@override @override
String get all => 'All'; String get all => 'All';
@override @override
String get alreadyLastDir => 'Already in last directory.'; String get alreadyLastDir => 'Already in last directory.';
@override
String get appPrimaryColor => 'App primary color';
@override @override
String get attention => 'Attention'; String get attention => 'Attention';
@@ -410,6 +410,9 @@ class SEn extends S {
@override @override
String get preview => 'Preview'; String get preview => 'Preview';
@override
String get primaryColor => 'Primary color';
@override @override
String get privateKey => 'Private Key'; String get privateKey => 'Private Key';

View File

@@ -19,15 +19,15 @@ class SZh extends S {
@override @override
String get addPrivateKey => '添加一个私钥'; String get addPrivateKey => '添加一个私钥';
@override
String get added2List => '已添加至任务列表';
@override @override
String get all => '所有'; String get all => '所有';
@override @override
String get alreadyLastDir => '已经是最上层目录了'; String get alreadyLastDir => '已经是最上层目录了';
@override
String get appPrimaryColor => 'App主要色';
@override @override
String get attention => '注意'; String get attention => '注意';
@@ -410,6 +410,9 @@ class SZh extends S {
@override @override
String get preview => '预览'; String get preview => '预览';
@override
String get primaryColor => '主题色';
@override @override
String get privateKey => '私钥'; String get privateKey => '私钥';
@@ -647,15 +650,15 @@ class SZhTw extends SZh {
@override @override
String get addPrivateKey => '新增一個私鑰'; String get addPrivateKey => '新增一個私鑰';
@override
String get added2List => '已添加至任務列表';
@override @override
String get all => '所有'; String get all => '所有';
@override @override
String get alreadyLastDir => '已經是最上層目錄了'; String get alreadyLastDir => '已經是最上層目錄了';
@override
String get appPrimaryColor => '主要色調';
@override @override
String get attention => '注意'; String get attention => '注意';
@@ -1029,6 +1032,9 @@ class SZhTw extends SZh {
@override @override
String get preview => '預覽'; String get preview => '預覽';
@override
String get primaryColor => '主要色調';
@override @override
String get privateKey => '私鑰'; String get privateKey => '私鑰';

View File

@@ -24,10 +24,10 @@ class MyApp extends StatelessWidget {
return ValueListenableBuilder<int>( return ValueListenableBuilder<int>(
valueListenable: _setting.themeMode.listenable(), valueListenable: _setting.themeMode.listenable(),
builder: (_, tMode, __) { builder: (_, tMode, __) {
final ok = tMode >= 0 && tMode <= ThemeMode.values.length - 1; final isAMOLED = tMode >= 0 && tMode <= ThemeMode.values.length - 1;
// Issue #57 // Issue #57
// if not [ok] -> [AMOLED] mode, use [ThemeMode.dark] // 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 localeStr = _setting.locale.fetch();
final locale = localeStr?.toLocale; final locale = localeStr?.toLocale;
final darkTheme = ThemeData( final darkTheme = ThemeData(
@@ -47,7 +47,7 @@ class MyApp extends StatelessWidget {
useMaterial3: true, useMaterial3: true,
colorSchemeSeed: primaryColor, colorSchemeSeed: primaryColor,
), ),
darkTheme: ok darkTheme: isAMOLED
? darkTheme ? darkTheme
: darkTheme.copyWith( : darkTheme.copyWith(
scaffoldBackgroundColor: Colors.black, scaffoldBackgroundColor: Colors.black,

View File

@@ -57,6 +57,10 @@ class ServerProvider extends BusyProvider {
} else { } else {
_serverOrder.addAll(_servers.keys); _serverOrder.addAll(_servers.keys);
} }
final surplus = _serverOrder.where(
(e) => !_servers.containsKey(e),
);
_serverOrder.removeWhere((element) => surplus.contains(element));
_settingStore.serverOrder.put(_serverOrder); _settingStore.serverOrder.put(_serverOrder);
_updateTags(); _updateTags();
setBusyState(false); setBusyState(false);

View File

@@ -5,9 +5,9 @@
"add": "Neu", "add": "Neu",
"addAServer": "Server hinzufügen", "addAServer": "Server hinzufügen",
"addPrivateKey": "Private key hinzufügen", "addPrivateKey": "Private key hinzufügen",
"added2List": "Zur Aufgabenliste hinzugefügt",
"all": "Alle", "all": "Alle",
"alreadyLastDir": "Bereits im letzten Verzeichnis.", "alreadyLastDir": "Bereits im letzten Verzeichnis.",
"appPrimaryColor": "Farbschema",
"attention": "Achtung", "attention": "Achtung",
"auto": "System folgen", "auto": "System folgen",
"backup": "Backup", "backup": "Backup",
@@ -125,6 +125,7 @@
"plzSelectKey": "Wähle einen Key.", "plzSelectKey": "Wähle einen Key.",
"port": "Port", "port": "Port",
"preview": "Vorschau", "preview": "Vorschau",
"primaryColor": "Farbschema",
"privateKey": "Private Key", "privateKey": "Private Key",
"process": "Prozess", "process": "Prozess",
"pushToken": "Push Token", "pushToken": "Push Token",

View File

@@ -5,9 +5,9 @@
"add": "Add", "add": "Add",
"addAServer": "add a server", "addAServer": "add a server",
"addPrivateKey": "Add private key", "addPrivateKey": "Add private key",
"added2List": "Added to task list",
"all": "All", "all": "All",
"alreadyLastDir": "Already in last directory.", "alreadyLastDir": "Already in last directory.",
"appPrimaryColor": "App primary color",
"attention": "Attention", "attention": "Attention",
"auto": "Auto", "auto": "Auto",
"backup": "Backup", "backup": "Backup",
@@ -128,6 +128,7 @@
"plzSelectKey": "Please select a key.", "plzSelectKey": "Please select a key.",
"port": "Port", "port": "Port",
"preview": "Preview", "preview": "Preview",
"primaryColor": "Primary color",
"privateKey": "Private Key", "privateKey": "Private Key",
"process": "Process", "process": "Process",
"pushToken": "Push token", "pushToken": "Push token",

View File

@@ -5,9 +5,9 @@
"add": "新增", "add": "新增",
"addAServer": "添加服务器", "addAServer": "添加服务器",
"addPrivateKey": "添加一个私钥", "addPrivateKey": "添加一个私钥",
"added2List": "已添加至任务列表",
"all": "所有", "all": "所有",
"alreadyLastDir": "已经是最上层目录了", "alreadyLastDir": "已经是最上层目录了",
"appPrimaryColor": "App主要色",
"attention": "注意", "attention": "注意",
"auto": "自动", "auto": "自动",
"backup": "备份", "backup": "备份",
@@ -128,6 +128,7 @@
"plzSelectKey": "请选择私钥", "plzSelectKey": "请选择私钥",
"port": "端口", "port": "端口",
"preview": "预览", "preview": "预览",
"primaryColor": "主题色",
"privateKey": "私钥", "privateKey": "私钥",
"process": "进程", "process": "进程",
"pushToken": "消息推送 Token", "pushToken": "消息推送 Token",

View File

@@ -5,9 +5,9 @@
"add": "新增", "add": "新增",
"addAServer": "新增服務器", "addAServer": "新增服務器",
"addPrivateKey": "新增一個私鑰", "addPrivateKey": "新增一個私鑰",
"added2List": "已添加至任務列表",
"all": "所有", "all": "所有",
"alreadyLastDir": "已經是最上層目錄了", "alreadyLastDir": "已經是最上層目錄了",
"appPrimaryColor": "主要色調",
"attention": "注意", "attention": "注意",
"auto": "自動", "auto": "自動",
"backup": "備份", "backup": "備份",
@@ -125,6 +125,7 @@
"plzSelectKey": "請選擇私鑰", "plzSelectKey": "請選擇私鑰",
"port": "端口", "port": "端口",
"preview": "預覽", "preview": "預覽",
"primaryColor": "主要色調",
"privateKey": "私鑰", "privateKey": "私鑰",
"process": "進程", "process": "進程",
"pushToken": "消息推送 Token", "pushToken": "消息推送 Token",

View File

@@ -106,10 +106,7 @@ class _PingPageState extends State<PingPage>
return Center( return Center(
child: Text( child: Text(
_s.noResult, _s.noResult,
style: TextStyle( style: const TextStyle(fontSize: 18),
fontSize: 18,
color: primaryColor,
),
), ),
); );
} }

View File

@@ -247,12 +247,12 @@ class _SettingPageState extends State<SettingPage> {
), ),
), ),
title: Text( title: Text(
_s.appPrimaryColor, _s.primaryColor,
), ),
onTap: () async { onTap: () async {
await showRoundDialog( await showRoundDialog(
context: context, context: context,
title: Text(_s.appPrimaryColor), title: Text(_s.primaryColor),
child: MaterialColorPicker( child: MaterialColorPicker(
shrinkWrap: true, shrinkWrap: true,
allowShades: true, allowShades: true,
@@ -640,7 +640,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
).toList(); ).toList();
return ListTile( return ListTile(
title: Text("${_s.editor} ${_s.theme}"), title: Text(_s.theme),
trailing: ValueBuilder( trailing: ValueBuilder(
listenable: _editorTheme, listenable: _editorTheme,
build: () => PopupMenuButton( build: () => PopupMenuButton(

View File

@@ -9,8 +9,10 @@ import 'package:toolbox/data/provider/sftp.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
import 'package:toolbox/view/page/editor.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/input_field.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 '../../../core/extension/numx.dart'; import '../../../core/extension/numx.dart';
import '../../../core/extension/stringx.dart'; import '../../../core/extension/stringx.dart';
@@ -112,13 +114,14 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
final files = dir.listSync(); final files = dir.listSync();
return ListView.builder( return ListView.builder(
itemCount: files.length, itemCount: files.length,
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7),
itemBuilder: (context, index) { itemBuilder: (context, index) {
var file = files[index]; var file = files[index];
var fileName = file.path.split('/').last; var fileName = file.path.split('/').last;
var stat = file.statSync(); var stat = file.statSync();
var isDir = stat.type == FileSystemEntityType.directory; var isDir = stat.type == FileSystemEntityType.directory;
return ListTile( return RoundRectCard(ListTile(
leading: isDir leading: isDir
? const Icon(Icons.folder) ? const Icon(Icons.folder)
: const Icon(Icons.insert_drive_file), : const Icon(Icons.insert_drive_file),
@@ -138,7 +141,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
_path!.update(fileName); _path!.update(fileName);
setState(() {}); setState(() {});
}, },
); ));
}, },
); );
} }
@@ -243,19 +246,6 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
title: Text(_s.upload), title: Text(_s.upload),
onTap: () async { onTap: () async {
context.pop(); 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<ServerProvider>(); final serverProvider = locator<ServerProvider>();
final ids = serverProvider.serverOrder; final ids = serverProvider.serverOrder;
var idx = 0; var idx = 0;
@@ -277,10 +267,22 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
showSnackBar(context, Text(_s.noResult)); showSnackBar(context, Text(_s.noResult));
return; return;
} }
final remotePath = await AppRoute(
SFTPPage(
spi,
selectPath: true,
),
'SFTP page (select)',
).go<String>(context);
if (remotePath == null) {
showSnackBar(context, Text(_s.fieldMustNotEmpty));
return;
}
locator<SftpProvider>().add( locator<SftpProvider>().add(
SftpReqItem(spi, remotePath, file.absolute.path), SftpReqItem(spi, remotePath, file.absolute.path),
SftpReqType.upload, SftpReqType.upload,
); );
showSnackBar(context, Text(_s.added2List));
}, },
), ),
ListTile( ListTile(

View File

@@ -9,6 +9,7 @@ import 'package:toolbox/core/extension/sftpfile.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/view/page/editor.dart'; import 'package:toolbox/view/page/editor.dart';
import 'package:toolbox/view/page/sftp/local.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/numx.dart';
import '../../../core/extension/stringx.dart'; import '../../../core/extension/stringx.dart';
@@ -33,7 +34,14 @@ import 'mission.dart';
class SFTPPage extends StatefulWidget { class SFTPPage extends StatefulWidget {
final ServerPrivateInfo spi; final ServerPrivateInfo spi;
final String? initPath; 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 @override
_SFTPPageState createState() => _SFTPPageState(); _SFTPPageState createState() => _SFTPPageState();
@@ -86,6 +94,24 @@ class _SFTPPageState extends State<SFTPPage> {
} }
Widget _buildBottom() { 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( return SafeArea(
child: Container( child: Container(
padding: const EdgeInsets.fromLTRB(11, 7, 11, 11), padding: const EdgeInsets.fromLTRB(11, 7, 11, 11),
@@ -96,18 +122,7 @@ class _SFTPPageState extends State<SFTPPage> {
(_status.path?.path ?? _s.loadingFiles).omitStartStr(), (_status.path?.path ?? _s.loadingFiles).omitStartStr(),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: children,
IconButton(
padding: const EdgeInsets.all(0),
onPressed: () async {
await _backward();
},
icon: const Icon(Icons.arrow_back),
),
_buildAddBtn(),
_buildGotoBtn(),
_buildUploadBtn(),
],
) )
], ],
), ),
@@ -250,10 +265,11 @@ class _SFTPPageState extends State<SFTPPage> {
child: ListView.builder( child: ListView.builder(
itemCount: _status.files!.length, itemCount: _status.files!.length,
controller: _scrollController, controller: _scrollController,
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final file = _status.files![index]; final file = _status.files![index];
final isDir = file.attr.isDirectory; final isDir = file.attr.isDirectory;
return ListTile( return RoundRectCard(ListTile(
leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file), leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file),
title: Text(file.filename), title: Text(file.filename),
trailing: Text( trailing: Text(
@@ -272,7 +288,7 @@ class _SFTPPageState extends State<SFTPPage> {
} }
}, },
onLongPress: () => _onItemPress(context, file, !isDir), onLongPress: () => _onItemPress(context, file, !isDir),
); ));
}, },
), ),
), ),
@@ -335,7 +351,9 @@ class _SFTPPageState extends State<SFTPPage> {
final completer = Completer(); final completer = Completer();
final req = SftpReqItem(widget.spi, remotePath, localPath); final req = SftpReqItem(widget.spi, remotePath, localPath);
_sftp.add(req, SftpReqType.download, completer: completer); _sftp.add(req, SftpReqType.download, completer: completer);
showRoundDialog(context: context, child: centerSizedLoading);
await completer.future; await completer.future;
context.pop();
final result = await AppRoute( final result = await AppRoute(
EditorPage(path: localPath), EditorPage(path: localPath),