From d224ad8cf85d461ad3f4465059d6bd9534dcad0c Mon Sep 17 00:00:00 2001 From: Junyuan Feng Date: Sat, 7 May 2022 22:36:32 +0800 Subject: [PATCH] Optimize - divide mkdir/newfile --- ios/Runner.xcodeproj/project.pbxproj | 12 +-- lib/data/res/build_data.dart | 6 +- lib/generated/intl/messages_en.dart | 1 + lib/generated/intl/messages_zh.dart | 1 + lib/generated/l10n.dart | 10 +++ lib/l10n/intl_en.arb | 1 + lib/l10n/intl_zh.arb | 1 + lib/view/page/sftp/view.dart | 122 ++++++++++++++++++++------- 8 files changed, 116 insertions(+), 38 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 162a4d10..4be13256 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 127; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -362,7 +362,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.126; + MARKETING_VERSION = 1.0.127; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -484,7 +484,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 127; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -492,7 +492,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.126; + MARKETING_VERSION = 1.0.127; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -508,7 +508,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 127; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -516,7 +516,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.126; + MARKETING_VERSION = 1.0.127; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index c895ab66..9ffcb91e 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 126; + static const int build = 127; static const String engine = "Flutter 2.10.5 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 5464c5bac7 (3 weeks ago) • 2022-04-18 09:55:37 -0700\nEngine • revision 57d3bac3dd\nTools • Dart 2.16.2 • DevTools 2.9.2\n"; - static const String buildAt = "2022-05-07 21:49:09.473227"; - static const int modifications = 11; + static const String buildAt = "2022-05-07 22:16:13.513462"; + static const int modifications = 1; } diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 01698a81..352ddbd3 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -73,6 +73,7 @@ class MessageLookup extends MessageLookupByLibrary { "convert": MessageLookupByLibrary.simpleMessage("Convert"), "copy": MessageLookupByLibrary.simpleMessage("Copy"), "copyPath": MessageLookupByLibrary.simpleMessage("Copy path"), + "createFile": MessageLookupByLibrary.simpleMessage("Create file"), "createFolder": MessageLookupByLibrary.simpleMessage("Create folder"), "currentMode": MessageLookupByLibrary.simpleMessage("Current Mode"), "debug": MessageLookupByLibrary.simpleMessage("Debug"), diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index 73564527..1ac6f582 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -67,6 +67,7 @@ class MessageLookup extends MessageLookupByLibrary { "convert": MessageLookupByLibrary.simpleMessage("转换"), "copy": MessageLookupByLibrary.simpleMessage("复制到剪切板"), "copyPath": MessageLookupByLibrary.simpleMessage("复制路径"), + "createFile": MessageLookupByLibrary.simpleMessage("创建文件"), "createFolder": MessageLookupByLibrary.simpleMessage("创建文件夹"), "currentMode": MessageLookupByLibrary.simpleMessage("当前模式"), "debug": MessageLookupByLibrary.simpleMessage("调试"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 6196ac58..87543919 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -1071,6 +1071,16 @@ class S { ); } + /// `Create file` + String get createFile { + return Intl.message( + 'Create file', + name: 'createFile', + desc: '', + args: [], + ); + } + /// `Rename` String get rename { return Intl.message( diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 9b915ef8..92062ea8 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -101,6 +101,7 @@ "sftpNoDownloadTask": "No download task.", "goSftpDlPage": "Go to SFTP download page?", "createFolder": "Create folder", + "createFile": "Create file", "rename": "Rename", "dl2Local": "Download [{fileName}] to local?", "error": "Error" diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index a6652c10..63b580a7 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -101,6 +101,7 @@ "sftpNoDownloadTask": "没有下载任务", "goSftpDlPage": "前往下载页?", "createFolder": "创建文件夹", + "createFile": "创建文件", "rename": "重命名", "dl2Local": "下载 [{fileName}] 到本地?", "error": "出错了" diff --git a/lib/view/page/sftp/view.dart b/lib/view/page/sftp/view.dart index 0b947885..a487ba9a 100644 --- a/lib/view/page/sftp/view.dart +++ b/lib/view/page/sftp/view.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:dartssh2/dartssh2.dart'; import 'package:flutter/material.dart'; import 'package:toolbox/core/extension/numx.dart'; @@ -53,9 +55,34 @@ class _SFTPPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - centerTitle: true, - title: TwoLineText(up: 'SFTP', down: widget.spi.name), - ), + centerTitle: true, + title: TwoLineText(up: 'SFTP', down: widget.spi.name), + actions: [ + IconButton( + onPressed: (() => showRoundDialog( + context, + s.choose, + Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.folder), + title: Text(s.createFolder), + onTap: () => mkdir(context)), + ListTile( + leading: const Icon(Icons.insert_drive_file), + title: Text(s.createFile), + onTap: () => newFile(context)), + ], + ), + [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(s.close)) + ])), + icon: const Icon(Icons.add), + ) + ]), body: _buildFileView(), ); } @@ -121,10 +148,10 @@ class _SFTPPageState extends State { _status.path?.update(file.filename); listDir(path: _status.path?.path); } else { - onItemPress(context, file); + onItemPress(context, file, true); } }, - onLongPress: () => onItemPress(context, file), + onLongPress: () => onItemPress(context, file, false), ); }, ), @@ -134,10 +161,10 @@ class _SFTPPageState extends State { } } - void onItemPress(BuildContext context, SftpName file) { + void onItemPress(BuildContext context, SftpName file, bool showDownload) { showRoundDialog( context, - 'Action', + s.choose, Column( mainAxisSize: MainAxisSize.min, children: [ @@ -146,20 +173,18 @@ class _SFTPPageState extends State { title: Text(s.delete), onTap: () => delete(context, file), ), - ListTile( - leading: const Icon(Icons.folder), - title: Text(s.createFolder), - onTap: () => mkdir(context)), ListTile( leading: const Icon(Icons.edit), title: Text(s.rename), onTap: () => rename(context, file), ), - ListTile( - leading: const Icon(Icons.download), - title: Text(s.download), - onTap: () => download(context, file), - ) + showDownload + ? ListTile( + leading: const Icon(Icons.download), + title: Text(s.download), + onTap: () => download(context, file), + ) + : const SizedBox() ], ), [ @@ -170,11 +195,9 @@ class _SFTPPageState extends State { } void download(BuildContext context, SftpName name) { - showRoundDialog( - context, s.download, Text(s.dl2Local(name.filename)), [ + showRoundDialog(context, s.download, Text(s.dl2Local(name.filename)), [ TextButton( - onPressed: () => Navigator.of(context).pop(), - child: Text(s.cancel)), + onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)), TextButton( onPressed: () async { Navigator.of(context).pop(); @@ -192,7 +215,10 @@ class _SFTPPageState extends State { TextButton( onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)), - TextButton(onPressed: () => AppRoute(const SFTPDownloadingPage(), 'sftp downloading'), child: Text(s.ok)) + TextButton( + onPressed: () => + AppRoute(const SFTPDownloadingPage(), 'sftp downloading'), + child: Text(s.ok)) ]); }, child: Text(s.download)) @@ -201,8 +227,7 @@ class _SFTPPageState extends State { void delete(BuildContext context, SftpName file) { Navigator.of(context).pop(); - showRoundDialog( - context, s.attention, Text(s.sureDelete(file.filename)), [ + showRoundDialog(context, s.attention, Text(s.sureDelete(file.filename)), [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel')), @@ -238,8 +263,8 @@ class _SFTPPageState extends State { TextButton( onPressed: () { if (textController.text == '') { - showRoundDialog(context, s.attention, - Text(s.fieldMustNotEmpty), [ + showRoundDialog( + context, s.attention, Text(s.fieldMustNotEmpty), [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)), @@ -258,6 +283,46 @@ class _SFTPPageState extends State { ]); } + void newFile(BuildContext context) { + Navigator.of(context).pop(); + final textController = TextEditingController(); + showRoundDialog( + context, + s.createFile, + TextField( + controller: textController, + decoration: InputDecoration( + labelText: s.name, + ), + ), + [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(s.cancel)), + TextButton( + onPressed: () async { + if (textController.text == '') { + showRoundDialog( + context, s.attention, Text(s.fieldMustNotEmpty), [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(s.ok)), + ]); + return; + } + (await _status.client! + .open(_status.path!.path + '/' + textController.text)) + .writeBytes(Uint8List(0)); + Navigator.of(context).pop(); + listDir(); + }, + child: Text( + s.ok, + style: const TextStyle(color: Colors.red), + )), + ]); + } + void rename(BuildContext context, SftpName file) { Navigator.of(context).pop(); final textController = TextEditingController(); @@ -277,8 +342,8 @@ class _SFTPPageState extends State { TextButton( onPressed: () async { if (textController.text == '') { - showRoundDialog(context, s.attention, - Text(s.fieldMustNotEmpty), [ + showRoundDialog( + context, s.attention, Text(s.fieldMustNotEmpty), [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)), @@ -320,8 +385,7 @@ class _SFTPPageState extends State { } catch (e) { await showRoundDialog(context, s.error, Text(e.toString()), [ TextButton( - onPressed: () => Navigator.of(context).pop(), - child: Text(s.ok)) + onPressed: () => Navigator.of(context).pop(), child: Text(s.ok)) ]); if (_status.path!.undo()) { await listDir();