- divide mkdir/newfile
This commit is contained in:
Junyuan Feng
2022-05-07 22:36:32 +08:00
parent b824e06736
commit d224ad8cf8
8 changed files with 116 additions and 38 deletions

View File

@@ -354,7 +354,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 126; CURRENT_PROJECT_VERSION = 127;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -362,7 +362,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.126; MARKETING_VERSION = 1.0.127;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -484,7 +484,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 126; CURRENT_PROJECT_VERSION = 127;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -492,7 +492,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.126; MARKETING_VERSION = 1.0.127;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -508,7 +508,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 126; CURRENT_PROJECT_VERSION = 127;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -516,7 +516,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.126; MARKETING_VERSION = 1.0.127;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 126; static const int build = 127;
static const String engine = 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"; "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 String buildAt = "2022-05-07 22:16:13.513462";
static const int modifications = 11; static const int modifications = 1;
} }

View File

@@ -73,6 +73,7 @@ class MessageLookup extends MessageLookupByLibrary {
"convert": MessageLookupByLibrary.simpleMessage("Convert"), "convert": MessageLookupByLibrary.simpleMessage("Convert"),
"copy": MessageLookupByLibrary.simpleMessage("Copy"), "copy": MessageLookupByLibrary.simpleMessage("Copy"),
"copyPath": MessageLookupByLibrary.simpleMessage("Copy path"), "copyPath": MessageLookupByLibrary.simpleMessage("Copy path"),
"createFile": MessageLookupByLibrary.simpleMessage("Create file"),
"createFolder": MessageLookupByLibrary.simpleMessage("Create folder"), "createFolder": MessageLookupByLibrary.simpleMessage("Create folder"),
"currentMode": MessageLookupByLibrary.simpleMessage("Current Mode"), "currentMode": MessageLookupByLibrary.simpleMessage("Current Mode"),
"debug": MessageLookupByLibrary.simpleMessage("Debug"), "debug": MessageLookupByLibrary.simpleMessage("Debug"),

View File

@@ -67,6 +67,7 @@ class MessageLookup extends MessageLookupByLibrary {
"convert": MessageLookupByLibrary.simpleMessage("转换"), "convert": MessageLookupByLibrary.simpleMessage("转换"),
"copy": MessageLookupByLibrary.simpleMessage("复制到剪切板"), "copy": MessageLookupByLibrary.simpleMessage("复制到剪切板"),
"copyPath": MessageLookupByLibrary.simpleMessage("复制路径"), "copyPath": MessageLookupByLibrary.simpleMessage("复制路径"),
"createFile": MessageLookupByLibrary.simpleMessage("创建文件"),
"createFolder": MessageLookupByLibrary.simpleMessage("创建文件夹"), "createFolder": MessageLookupByLibrary.simpleMessage("创建文件夹"),
"currentMode": MessageLookupByLibrary.simpleMessage("当前模式"), "currentMode": MessageLookupByLibrary.simpleMessage("当前模式"),
"debug": MessageLookupByLibrary.simpleMessage("调试"), "debug": MessageLookupByLibrary.simpleMessage("调试"),

View File

@@ -1071,6 +1071,16 @@ class S {
); );
} }
/// `Create file`
String get createFile {
return Intl.message(
'Create file',
name: 'createFile',
desc: '',
args: [],
);
}
/// `Rename` /// `Rename`
String get rename { String get rename {
return Intl.message( return Intl.message(

View File

@@ -101,6 +101,7 @@
"sftpNoDownloadTask": "No download task.", "sftpNoDownloadTask": "No download task.",
"goSftpDlPage": "Go to SFTP download page?", "goSftpDlPage": "Go to SFTP download page?",
"createFolder": "Create folder", "createFolder": "Create folder",
"createFile": "Create file",
"rename": "Rename", "rename": "Rename",
"dl2Local": "Download [{fileName}] to local?", "dl2Local": "Download [{fileName}] to local?",
"error": "Error" "error": "Error"

View File

@@ -101,6 +101,7 @@
"sftpNoDownloadTask": "没有下载任务", "sftpNoDownloadTask": "没有下载任务",
"goSftpDlPage": "前往下载页?", "goSftpDlPage": "前往下载页?",
"createFolder": "创建文件夹", "createFolder": "创建文件夹",
"createFile": "创建文件",
"rename": "重命名", "rename": "重命名",
"dl2Local": "下载 [{fileName}] 到本地?", "dl2Local": "下载 [{fileName}] 到本地?",
"error": "出错了" "error": "出错了"

View File

@@ -1,3 +1,5 @@
import 'dart:typed_data';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/numx.dart'; import 'package:toolbox/core/extension/numx.dart';
@@ -53,9 +55,34 @@ class _SFTPPageState extends State<SFTPPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: true, centerTitle: true,
title: TwoLineText(up: 'SFTP', down: widget.spi.name), 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(), body: _buildFileView(),
); );
} }
@@ -121,10 +148,10 @@ class _SFTPPageState extends State<SFTPPage> {
_status.path?.update(file.filename); _status.path?.update(file.filename);
listDir(path: _status.path?.path); listDir(path: _status.path?.path);
} else { } 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<SFTPPage> {
} }
} }
void onItemPress(BuildContext context, SftpName file) { void onItemPress(BuildContext context, SftpName file, bool showDownload) {
showRoundDialog( showRoundDialog(
context, context,
'Action', s.choose,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -146,20 +173,18 @@ class _SFTPPageState extends State<SFTPPage> {
title: Text(s.delete), title: Text(s.delete),
onTap: () => delete(context, file), onTap: () => delete(context, file),
), ),
ListTile(
leading: const Icon(Icons.folder),
title: Text(s.createFolder),
onTap: () => mkdir(context)),
ListTile( ListTile(
leading: const Icon(Icons.edit), leading: const Icon(Icons.edit),
title: Text(s.rename), title: Text(s.rename),
onTap: () => rename(context, file), onTap: () => rename(context, file),
), ),
ListTile( showDownload
leading: const Icon(Icons.download), ? ListTile(
title: Text(s.download), leading: const Icon(Icons.download),
onTap: () => download(context, file), title: Text(s.download),
) onTap: () => download(context, file),
)
: const SizedBox()
], ],
), ),
[ [
@@ -170,11 +195,9 @@ class _SFTPPageState extends State<SFTPPage> {
} }
void download(BuildContext context, SftpName name) { void download(BuildContext context, SftpName name) {
showRoundDialog( showRoundDialog(context, s.download, Text(s.dl2Local(name.filename)), [
context, s.download, Text(s.dl2Local(name.filename)), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)),
child: Text(s.cancel)),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
Navigator.of(context).pop(); Navigator.of(context).pop();
@@ -192,7 +215,10 @@ class _SFTPPageState extends State<SFTPPage> {
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.cancel)), 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)) child: Text(s.download))
@@ -201,8 +227,7 @@ class _SFTPPageState extends State<SFTPPage> {
void delete(BuildContext context, SftpName file) { void delete(BuildContext context, SftpName file) {
Navigator.of(context).pop(); Navigator.of(context).pop();
showRoundDialog( showRoundDialog(context, s.attention, Text(s.sureDelete(file.filename)), [
context, s.attention, Text(s.sureDelete(file.filename)), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel')), child: const Text('Cancel')),
@@ -238,8 +263,8 @@ class _SFTPPageState extends State<SFTPPage> {
TextButton( TextButton(
onPressed: () { onPressed: () {
if (textController.text == '') { if (textController.text == '') {
showRoundDialog(context, s.attention, showRoundDialog(
Text(s.fieldMustNotEmpty), [ context, s.attention, Text(s.fieldMustNotEmpty), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok)), child: Text(s.ok)),
@@ -258,6 +283,46 @@ class _SFTPPageState extends State<SFTPPage> {
]); ]);
} }
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) { void rename(BuildContext context, SftpName file) {
Navigator.of(context).pop(); Navigator.of(context).pop();
final textController = TextEditingController(); final textController = TextEditingController();
@@ -277,8 +342,8 @@ class _SFTPPageState extends State<SFTPPage> {
TextButton( TextButton(
onPressed: () async { onPressed: () async {
if (textController.text == '') { if (textController.text == '') {
showRoundDialog(context, s.attention, showRoundDialog(
Text(s.fieldMustNotEmpty), [ context, s.attention, Text(s.fieldMustNotEmpty), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: Text(s.ok)), child: Text(s.ok)),
@@ -320,8 +385,7 @@ class _SFTPPageState extends State<SFTPPage> {
} catch (e) { } catch (e) {
await showRoundDialog(context, s.error, Text(e.toString()), [ await showRoundDialog(context, s.error, Text(e.toString()), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(), child: Text(s.ok))
child: Text(s.ok))
]); ]);
if (_status.path!.undo()) { if (_status.path!.undo()) {
await listDir(); await listDir();