fix & opt

- sftp download unknown spent time
- shareFiles return bool
This commit is contained in:
Junyuan Feng
2022-05-08 09:07:03 +08:00
parent b0c3cd3834
commit 6f30976ef7
13 changed files with 71 additions and 28 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 = 128; CURRENT_PROJECT_VERSION = 129;
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.128; MARKETING_VERSION = 1.0.129;
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 = 128; CURRENT_PROJECT_VERSION = 129;
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.128; MARKETING_VERSION = 1.0.129;
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 = 128; CURRENT_PROJECT_VERSION = 129;
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.128; MARKETING_VERSION = 1.0.129;
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

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toolbox/core/persistant_store.dart'; import 'package:toolbox/core/persistant_store.dart';
import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/generated/l10n.dart';
import 'package:toolbox/view/widget/card_dialog.dart'; import 'package:toolbox/view/widget/card_dialog.dart';
@@ -97,3 +98,19 @@ String tabTitleName(BuildContext context, int i) {
return ''; return '';
} }
} }
Future<bool> shareFiles(BuildContext context, List<String> filePaths) async {
for (final filePath in filePaths) {
if (!await File(filePath).exists()) {
return false;
}
}
var text = '';
if (filePaths.length == 1) {
text = filePaths.first.split('/').last;
} else {
text = '${filePaths.length} ${S.of(context).files}';
}
await Share.shareFiles(filePaths, text: 'ServerBox -> $text');
return filePaths.isNotEmpty;
}

View File

@@ -82,7 +82,7 @@ class SftpDownloadWorker {
mainSendPort.send(Exception('can not get file size')); mainSendPort.send(Exception('can not get file size'));
return; return;
} }
const defaultChunkSize = 1024 * 512; const defaultChunkSize = 1024 * 1024;
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size; final chunkSize = size > defaultChunkSize ? defaultChunkSize : size;
mainSendPort.send(size); mainSendPort.send(size);
mainSendPort.send(SftpWorkerStatus.downloading); mainSendPort.send(SftpWorkerStatus.downloading);
@@ -93,9 +93,9 @@ class SftpDownloadWorker {
mainSendPort.send((i + form.length) / size * 100); mainSendPort.send((i + form.length) / size * 100);
} }
} }
mainSendPort.send(SftpWorkerStatus.finished);
localFile.close(); localFile.close();
mainSendPort.send(watch.elapsed); mainSendPort.send(watch.elapsed);
mainSendPort.send(SftpWorkerStatus.finished);
} catch (e) { } catch (e) {
mainSendPort.send(e); mainSendPort.send(e);
} }

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 128; static const int build = 129;
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 22:36:43.297250"; static const String buildAt = "2022-05-08 08:37:10.208726";
static const int modifications = 1; static const int modifications = 14;
} }

View File

@@ -36,7 +36,7 @@ class MessageLookup extends MessageLookupByLibrary {
static String m6(myGithub) => "\nMade with ❤️ by ${myGithub}"; static String m6(myGithub) => "\nMade with ❤️ by ${myGithub}";
static String m7(time) => "Spent time: ${time} seconds"; static String m7(time) => "Spent time: ${time}";
static String m8(name) => "Are you sure to delete [${name}]?"; static String m8(name) => "Are you sure to delete [${name}]?";
@@ -79,6 +79,7 @@ class MessageLookup extends MessageLookupByLibrary {
"debug": MessageLookupByLibrary.simpleMessage("Debug"), "debug": MessageLookupByLibrary.simpleMessage("Debug"),
"decode": MessageLookupByLibrary.simpleMessage("Decode"), "decode": MessageLookupByLibrary.simpleMessage("Decode"),
"delete": MessageLookupByLibrary.simpleMessage("Delete"), "delete": MessageLookupByLibrary.simpleMessage("Delete"),
"disconnected": MessageLookupByLibrary.simpleMessage("Disconnected"),
"dl2Local": m1, "dl2Local": m1,
"dockerStatusRunningAndStoppedFmt": m2, "dockerStatusRunningAndStoppedFmt": m2,
"dockerStatusRunningFmt": m3, "dockerStatusRunningFmt": m3,
@@ -95,6 +96,7 @@ class MessageLookup extends MessageLookupByLibrary {
"export": MessageLookupByLibrary.simpleMessage("Export"), "export": MessageLookupByLibrary.simpleMessage("Export"),
"fieldMustNotEmpty": MessageLookupByLibrary.simpleMessage( "fieldMustNotEmpty": MessageLookupByLibrary.simpleMessage(
"These fields must not be empty."), "These fields must not be empty."),
"files": MessageLookupByLibrary.simpleMessage("Files"),
"go": MessageLookupByLibrary.simpleMessage("Go"), "go": MessageLookupByLibrary.simpleMessage("Go"),
"goSftpDlPage": "goSftpDlPage":
MessageLookupByLibrary.simpleMessage("Go to SFTP download page?"), MessageLookupByLibrary.simpleMessage("Go to SFTP download page?"),

View File

@@ -36,7 +36,7 @@ class MessageLookup extends MessageLookupByLibrary {
static String m6(myGithub) => "\n用❤️制作 by ${myGithub}"; static String m6(myGithub) => "\n用❤️制作 by ${myGithub}";
static String m7(time) => "耗时: ${time}"; static String m7(time) => "耗时: ${time}";
static String m8(name) => "确定删除[${name}]"; static String m8(name) => "确定删除[${name}]";
@@ -73,6 +73,7 @@ class MessageLookup extends MessageLookupByLibrary {
"debug": MessageLookupByLibrary.simpleMessage("调试"), "debug": MessageLookupByLibrary.simpleMessage("调试"),
"decode": MessageLookupByLibrary.simpleMessage("解码"), "decode": MessageLookupByLibrary.simpleMessage("解码"),
"delete": MessageLookupByLibrary.simpleMessage("删除"), "delete": MessageLookupByLibrary.simpleMessage("删除"),
"disconnected": MessageLookupByLibrary.simpleMessage("连接断开"),
"dl2Local": m1, "dl2Local": m1,
"dockerStatusRunningAndStoppedFmt": m2, "dockerStatusRunningAndStoppedFmt": m2,
"dockerStatusRunningFmt": m3, "dockerStatusRunningFmt": m3,
@@ -86,6 +87,7 @@ class MessageLookup extends MessageLookupByLibrary {
"exampleName": MessageLookupByLibrary.simpleMessage("名称示例"), "exampleName": MessageLookupByLibrary.simpleMessage("名称示例"),
"export": MessageLookupByLibrary.simpleMessage("导出"), "export": MessageLookupByLibrary.simpleMessage("导出"),
"fieldMustNotEmpty": MessageLookupByLibrary.simpleMessage("这些输入框不能为空。"), "fieldMustNotEmpty": MessageLookupByLibrary.simpleMessage("这些输入框不能为空。"),
"files": MessageLookupByLibrary.simpleMessage("文件"),
"go": MessageLookupByLibrary.simpleMessage("开始"), "go": MessageLookupByLibrary.simpleMessage("开始"),
"goSftpDlPage": MessageLookupByLibrary.simpleMessage("前往下载页?"), "goSftpDlPage": MessageLookupByLibrary.simpleMessage("前往下载页?"),
"host": MessageLookupByLibrary.simpleMessage("主机"), "host": MessageLookupByLibrary.simpleMessage("主机"),

View File

@@ -900,10 +900,10 @@ class S {
); );
} }
/// `Spent time: {time} seconds` /// `Spent time: {time}`
String spentTime(Object time) { String spentTime(Object time) {
return Intl.message( return Intl.message(
'Spent time: $time seconds', 'Spent time: $time',
name: 'spentTime', name: 'spentTime',
desc: '', desc: '',
args: [time], args: [time],
@@ -1110,6 +1110,26 @@ class S {
args: [], args: [],
); );
} }
/// `Disconnected`
String get disconnected {
return Intl.message(
'Disconnected',
name: 'disconnected',
desc: '',
args: [],
);
}
/// `Files`
String get files {
return Intl.message(
'Files',
name: 'files',
desc: '',
args: [],
);
}
} }
class AppLocalizationDelegate extends LocalizationsDelegate<S> { class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -84,7 +84,7 @@
"downloadStatus": "{percent}% of {size}", "downloadStatus": "{percent}% of {size}",
"sftpDlPrepare": "Preparing to connect...", "sftpDlPrepare": "Preparing to connect...",
"sftpSSHConnected": "SFTP Connected", "sftpSSHConnected": "SFTP Connected",
"spentTime": "Spent time: {time} seconds", "spentTime": "Spent time: {time}",
"backDir": "Back", "backDir": "Back",
"alreadyLastDir": "Already in last directory.", "alreadyLastDir": "Already in last directory.",
"open": "Open", "open": "Open",
@@ -104,5 +104,7 @@
"createFile": "Create file", "createFile": "Create file",
"rename": "Rename", "rename": "Rename",
"dl2Local": "Download [{fileName}] to local?", "dl2Local": "Download [{fileName}] to local?",
"error": "Error" "error": "Error",
"disconnected": "Disconnected",
"files": "Files"
} }

View File

@@ -84,7 +84,7 @@
"downloadStatus": "{size} 的 {percent}%", "downloadStatus": "{size} 的 {percent}%",
"sftpDlPrepare": "准备连接至服务器...", "sftpDlPrepare": "准备连接至服务器...",
"sftpSSHConnected": "SFTP 已连接,即将开始下载...", "sftpSSHConnected": "SFTP 已连接,即将开始下载...",
"spentTime": "耗时: {time}", "spentTime": "耗时: {time}",
"backDir": "返回上一级", "backDir": "返回上一级",
"alreadyLastDir": "已经是最上层目录了", "alreadyLastDir": "已经是最上层目录了",
"open": "打开", "open": "打开",
@@ -104,5 +104,7 @@
"createFile": "创建文件", "createFile": "创建文件",
"rename": "重命名", "rename": "重命名",
"dl2Local": "下载 [{fileName}] 到本地?", "dl2Local": "下载 [{fileName}] 到本地?",
"error": "出错了" "error": "出错了",
"disconnected": "连接断开",
"files": "文件"
} }

View File

@@ -301,7 +301,7 @@ class _ServerPageState extends State<ServerPage>
String? failedInfo) { String? failedInfo) {
switch (cs) { switch (cs) {
case ServerConnectionState.disconnected: case ServerConnectionState.disconnected:
return 'Disconnected'; return s.disconnected;
case ServerConnectionState.connected: case ServerConnectionState.connected:
if (temp == '') { if (temp == '') {
if (upTime == '') { if (upTime == '') {

View File

@@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toolbox/core/extension/colorx.dart'; import 'package:toolbox/core/extension/colorx.dart';
import 'package:toolbox/core/extension/numx.dart'; import 'package:toolbox/core/extension/numx.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
@@ -173,8 +172,7 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
leading: const Icon(Icons.open_in_new), leading: const Icon(Icons.open_in_new),
title: Text(s.open), title: Text(s.open),
onTap: () { onTap: () {
Share.shareFiles([file.absolute.path], shareFiles(context, [file.absolute.path]);
text: '$fileName from ServerBox');
}), }),
], ],
), ),

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toolbox/core/extension/numx.dart'; import 'package:toolbox/core/extension/numx.dart';
import 'package:toolbox/core/utils.dart'; import 'package:toolbox/core/utils.dart';
import 'package:toolbox/data/model/sftp/download_status.dart'; import 'package:toolbox/data/model/sftp/download_status.dart';
@@ -77,11 +76,11 @@ class _SFTPDownloadingPageState extends State<SFTPDownloadingPage> {
} }
switch (status.status) { switch (status.status) {
case SftpWorkerStatus.finished: case SftpWorkerStatus.finished:
final time = status.spentTime.toString();
return _wrapInCard(status, return _wrapInCard(status,
'${s.downloadFinished} ${s.spentTime(status.spentTime ?? s.unknown)}', '${s.downloadFinished} ${s.spentTime(time == 'null' ? s.unknown : (time.substring(0, time.length - 7)))}',
trailing: IconButton( trailing: IconButton(
onPressed: () => Share.shareFiles([status.item.localPath], onPressed: () => shareFiles(context, [status.item.localPath]),
text: '${status.fileName} from ServerBox'),
icon: const Icon(Icons.open_in_new))); icon: const Icon(Icons.open_in_new)));
case SftpWorkerStatus.downloading: case SftpWorkerStatus.downloading:
return _wrapInCard( return _wrapInCard(

View File

@@ -195,7 +195,8 @@ class _SFTPPageState extends State<SFTPPage> {
} }
void download(BuildContext context, SftpName name) { void download(BuildContext context, SftpName name) {
showRoundDialog(context, s.download, Text(s.dl2Local(name.filename)), [ showRoundDialog(context, s.download,
Text('${s.dl2Local(name.filename)}\n${s.keepForeground}'), [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)), onPressed: () => Navigator.of(context).pop(), child: Text(s.cancel)),
TextButton( TextButton(