new & fix

- new: switch of sftp `rm -rf` dir
- fix: sftp upload
- fix: sftp uploading progress
- opt.: editor will save content if is editing file
This commit is contained in:
lollipopkit
2023-08-27 00:10:01 +08:00
parent 65de4a8ca5
commit 7abadfb5a6
18 changed files with 129 additions and 74 deletions

View File

@@ -416,12 +416,6 @@ abstract class S {
/// **'Download'** /// **'Download'**
String get download; String get download;
/// No description provided for @downloadStatus.
///
/// In en, this message translates to:
/// **'{percent}% of {size}'**
String downloadStatus(Object percent, Object size);
/// No description provided for @edit. /// No description provided for @edit.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -920,6 +914,12 @@ abstract class S {
/// **'Path'** /// **'Path'**
String get path; String get path;
/// No description provided for @percentOfSize.
///
/// In en, this message translates to:
/// **'{percent}% of {size}'**
String percentOfSize(Object percent, Object size);
/// No description provided for @pickFile. /// No description provided for @pickFile.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -1154,6 +1154,12 @@ abstract class S {
/// **'Preparing to connect...'** /// **'Preparing to connect...'**
String get sftpDlPrepare; String get sftpDlPrepare;
/// No description provided for @sftpRmrfDir.
///
/// In en, this message translates to:
/// **'Use `rm -rf` to delete dir on SFTP'**
String get sftpRmrfDir;
/// No description provided for @sftpSSHConnected. /// No description provided for @sftpSSHConnected.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -171,11 +171,6 @@ class SDe extends S {
@override @override
String get download => 'Download'; String get download => 'Download';
@override
String downloadStatus(Object percent, Object size) {
return '$percent% von $size';
}
@override @override
String get edit => 'Bearbeiten'; String get edit => 'Bearbeiten';
@@ -437,6 +432,11 @@ class SDe extends S {
@override @override
String get path => 'Pfad'; String get path => 'Pfad';
@override
String percentOfSize(Object percent, Object size) {
return '$percent% von $size';
}
@override @override
String get pickFile => 'Datei wählen'; String get pickFile => 'Datei wählen';
@@ -558,6 +558,9 @@ class SDe extends S {
@override @override
String get sftpDlPrepare => 'Verbindung vorbereiten...'; String get sftpDlPrepare => 'Verbindung vorbereiten...';
@override
String get sftpRmrfDir => 'Verwenden Sie `rm -rf`, um das Verzeichnis auf SFTP zu löschen';
@override @override
String get sftpSSHConnected => 'SFTP Verbunden'; String get sftpSSHConnected => 'SFTP Verbunden';

View File

@@ -171,11 +171,6 @@ class SEn extends S {
@override @override
String get download => 'Download'; String get download => 'Download';
@override
String downloadStatus(Object percent, Object size) {
return '$percent% of $size';
}
@override @override
String get edit => 'Edit'; String get edit => 'Edit';
@@ -437,6 +432,11 @@ class SEn extends S {
@override @override
String get path => 'Path'; String get path => 'Path';
@override
String percentOfSize(Object percent, Object size) {
return '$percent% of $size';
}
@override @override
String get pickFile => 'Pick file'; String get pickFile => 'Pick file';
@@ -558,6 +558,9 @@ class SEn extends S {
@override @override
String get sftpDlPrepare => 'Preparing to connect...'; String get sftpDlPrepare => 'Preparing to connect...';
@override
String get sftpRmrfDir => 'Use `rm -rf` to delete dir on SFTP';
@override @override
String get sftpSSHConnected => 'SFTP Connected'; String get sftpSSHConnected => 'SFTP Connected';

View File

@@ -171,11 +171,6 @@ class SId extends S {
@override @override
String get download => 'Unduh'; String get download => 'Unduh';
@override
String downloadStatus(Object percent, Object size) {
return '$percent% dari $size';
}
@override @override
String get edit => 'Edit'; String get edit => 'Edit';
@@ -437,6 +432,11 @@ class SId extends S {
@override @override
String get path => 'Jalur'; String get path => 'Jalur';
@override
String percentOfSize(Object percent, Object size) {
return '$percent% dari $size';
}
@override @override
String get pickFile => 'Pilih file'; String get pickFile => 'Pilih file';
@@ -558,6 +558,9 @@ class SId extends S {
@override @override
String get sftpDlPrepare => 'Bersiap untuk terhubung ...'; String get sftpDlPrepare => 'Bersiap untuk terhubung ...';
@override
String get sftpRmrfDir => 'Gunakan `rm -rf` untuk menghapus direktori di SFTP';
@override @override
String get sftpSSHConnected => 'Sftp terhubung'; String get sftpSSHConnected => 'Sftp terhubung';

View File

@@ -171,11 +171,6 @@ class SZh extends S {
@override @override
String get download => '下载'; String get download => '下载';
@override
String downloadStatus(Object percent, Object size) {
return '$size$percent%';
}
@override @override
String get edit => '编辑'; String get edit => '编辑';
@@ -437,6 +432,11 @@ class SZh extends S {
@override @override
String get path => '路径'; String get path => '路径';
@override
String percentOfSize(Object percent, Object size) {
return '$size$percent%';
}
@override @override
String get pickFile => '选择文件'; String get pickFile => '选择文件';
@@ -558,6 +558,9 @@ class SZh extends S {
@override @override
String get sftpDlPrepare => '准备连接至服务器...'; String get sftpDlPrepare => '准备连接至服务器...';
@override
String get sftpRmrfDir => '在 SFTP 中使用 `rm -rf` 删除文件夹';
@override @override
String get sftpSSHConnected => 'SFTP 已连接...'; String get sftpSSHConnected => 'SFTP 已连接...';
@@ -888,11 +891,6 @@ class SZhTw extends SZh {
@override @override
String get download => '下載'; String get download => '下載';
@override
String downloadStatus(Object percent, Object size) {
return '$size$percent%';
}
@override @override
String get edit => '編輯'; String get edit => '編輯';
@@ -1154,6 +1152,11 @@ class SZhTw extends SZh {
@override @override
String get path => '路徑'; String get path => '路徑';
@override
String percentOfSize(Object percent, Object size) {
return '$size$percent%';
}
@override @override
String get pickFile => '選擇文件'; String get pickFile => '選擇文件';
@@ -1275,6 +1278,9 @@ class SZhTw extends SZh {
@override @override
String get sftpDlPrepare => '準備連接至服務器...'; String get sftpDlPrepare => '準備連接至服務器...';
@override
String get sftpRmrfDir => '在 SFTP 中使用 `rm -rf` 刪除文件夾';
@override @override
String get sftpSSHConnected => 'SFTP 已連接...'; String get sftpSSHConnected => 'SFTP 已連接...';

View File

@@ -86,4 +86,4 @@ class SftpReqStatus {
} }
} }
enum SftpWorkerStatus { preparing, sshConnectted, downloading, finished } enum SftpWorkerStatus { preparing, sshConnectted, loading, finished }

View File

@@ -5,9 +5,8 @@ import 'dart:typed_data';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:easy_isolate/easy_isolate.dart'; import 'package:easy_isolate/easy_isolate.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/core/utils/server.dart';
import '../../../core/utils/server.dart';
import 'req.dart'; import 'req.dart';
class SftpWorker { class SftpWorker {
@@ -78,16 +77,14 @@ Future<void> _download(
final client = await genClient(req.spi, privateKey: req.privateKey); final client = await genClient(req.spi, privateKey: req.privateKey);
mainSendPort.send(SftpWorkerStatus.sshConnectted); mainSendPort.send(SftpWorkerStatus.sshConnectted);
final remotePath = req.remotePath; await Directory(req.localPath.substring(0, req.localPath.lastIndexOf('/')))
final localPath = req.localPath;
await Directory(localPath.substring(0, req.localPath.lastIndexOf('/')))
.create(recursive: true); .create(recursive: true);
final local = File(localPath); final local = File(req.localPath);
if (await local.exists()) { if (await local.exists()) {
await local.delete(); await local.delete();
} }
final localFile = local.openWrite(mode: FileMode.append); final localFile = local.openWrite(mode: FileMode.append);
final file = await (await client.sftp()).open(remotePath); final file = await (await client.sftp()).open(req.remotePath);
final size = (await file.stat()).size; final size = (await file.stat()).size;
if (size == null) { if (size == null) {
mainSendPort.send(Exception('can not get file size')); mainSendPort.send(Exception('can not get file size'));
@@ -97,7 +94,7 @@ Future<void> _download(
const defaultChunkSize = 1024 * 1024; 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.loading);
for (var i = 0; i < size; i += chunkSize) { for (var i = 0; i < size; i += chunkSize) {
final fileData = file.read(length: chunkSize); final fileData = file.read(length: chunkSize);
await for (var form in fileData) { await for (var form in fileData) {
@@ -125,19 +122,23 @@ Future<void> _upload(
final client = await genClient(req.spi, privateKey: req.privateKey); final client = await genClient(req.spi, privateKey: req.privateKey);
mainSendPort.send(SftpWorkerStatus.sshConnectted); mainSendPort.send(SftpWorkerStatus.sshConnectted);
final localPath = req.localPath; final local = File(req.localPath);
final fileName = getFileName(localPath) ?? 'srvbox_sftp_upload';
final remotePath = '${req.remotePath}/$fileName';
final local = File(localPath);
if (!await local.exists()) { if (!await local.exists()) {
mainSendPort.send(Exception('local file not exists')); mainSendPort.send(Exception('local file not exists'));
return; return;
} }
final localLen = await local.length();
mainSendPort.send(localLen);
mainSendPort.send(SftpWorkerStatus.loading);
final localFile = local.openRead().cast<Uint8List>(); final localFile = local.openRead().cast<Uint8List>();
final sftp = await client.sftp(); final sftp = await client.sftp();
final file = await sftp.open(remotePath, final file = await sftp.open(
mode: SftpFileOpenMode.write | SftpFileOpenMode.create); req.remotePath,
final writer = file.write(localFile); mode: SftpFileOpenMode.write | SftpFileOpenMode.create,
);
final writer = file.write(localFile, onProgress: (total) {
mainSendPort.send(total / localLen * 100);
},);
await writer.done; await writer.done;
await file.close(); await file.close();
mainSendPort.send(watch.elapsed); mainSendPort.send(watch.elapsed);

View File

@@ -111,4 +111,8 @@ class SettingStore extends PersistentStore {
/// Otherwise, display them on the top of server detail page /// Otherwise, display them on the top of server detail page
StoreProperty<bool> get moveOutServerTabFuncBtns => StoreProperty<bool> get moveOutServerTabFuncBtns =>
property('moveOutServerTabFuncBtns', defaultValue: true); property('moveOutServerTabFuncBtns', defaultValue: true);
/// Whether use `rm -rf` to delete directory on SFTP
StoreProperty<bool> get sftpRmrfDir =>
property('sftpRmrfDir', defaultValue: true);
} }

View File

@@ -53,7 +53,6 @@
"dockerStatusRunningAndStoppedFmt": "{runningCount} aktiv, {stoppedCount} container gestoppt.", "dockerStatusRunningAndStoppedFmt": "{runningCount} aktiv, {stoppedCount} container gestoppt.",
"dockerStatusRunningFmt": "{count} Container aktiv", "dockerStatusRunningFmt": "{count} Container aktiv",
"download": "Download", "download": "Download",
"downloadStatus": "{percent}% von {size}",
"edit": "Bearbeiten", "edit": "Bearbeiten",
"editVirtKeys": "Virtuelle Tasten bearbeiten", "editVirtKeys": "Virtuelle Tasten bearbeiten",
"editor": "Editor", "editor": "Editor",
@@ -137,6 +136,7 @@
"open": "Öffnen", "open": "Öffnen",
"paste": "Einfügen", "paste": "Einfügen",
"path": "Pfad", "path": "Pfad",
"percentOfSize": "{percent}% von {size}",
"pickFile": "Datei wählen", "pickFile": "Datei wählen",
"pingAvg": "Avg:", "pingAvg": "Avg:",
"pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.", "pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.",
@@ -176,6 +176,7 @@
"serverTabUnkown": "Unbekannter Status", "serverTabUnkown": "Unbekannter Status",
"setting": "Einstellungen", "setting": "Einstellungen",
"sftpDlPrepare": "Verbindung vorbereiten...", "sftpDlPrepare": "Verbindung vorbereiten...",
"sftpRmrfDir": "Verwenden Sie `rm -rf`, um das Verzeichnis auf SFTP zu löschen",
"sftpSSHConnected": "SFTP Verbunden", "sftpSSHConnected": "SFTP Verbunden",
"showDistLogo": "Distributionslogo anzeigen", "showDistLogo": "Distributionslogo anzeigen",
"snippet": "Snippet", "snippet": "Snippet",

View File

@@ -53,7 +53,6 @@
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.", "dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
"dockerStatusRunningFmt": "{count} container running.", "dockerStatusRunningFmt": "{count} container running.",
"download": "Download", "download": "Download",
"downloadStatus": "{percent}% of {size}",
"edit": "Edit", "edit": "Edit",
"editVirtKeys": "Edit virtual keys", "editVirtKeys": "Edit virtual keys",
"editor": "Editor", "editor": "Editor",
@@ -137,6 +136,7 @@
"open": "Open", "open": "Open",
"paste": "Paste", "paste": "Paste",
"path": "Path", "path": "Path",
"percentOfSize": "{percent}% of {size}",
"pickFile": "Pick file", "pickFile": "Pick file",
"pingAvg": "Avg:", "pingAvg": "Avg:",
"pingInputIP": "Please input a target IP / domain.", "pingInputIP": "Please input a target IP / domain.",
@@ -176,6 +176,7 @@
"serverTabUnkown": "Unknown state", "serverTabUnkown": "Unknown state",
"setting": "Settings", "setting": "Settings",
"sftpDlPrepare": "Preparing to connect...", "sftpDlPrepare": "Preparing to connect...",
"sftpRmrfDir": "Use `rm -rf` to delete dir on SFTP",
"sftpSSHConnected": "SFTP Connected", "sftpSSHConnected": "SFTP Connected",
"showDistLogo": "Show distribution logo", "showDistLogo": "Show distribution logo",
"snippet": "Snippet", "snippet": "Snippet",

View File

@@ -53,7 +53,6 @@
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.", "dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
"dockerStatusRunningFmt": "{count} wadah berjalan.", "dockerStatusRunningFmt": "{count} wadah berjalan.",
"download": "Unduh", "download": "Unduh",
"downloadStatus": "{percent}% dari {size}",
"edit": "Edit", "edit": "Edit",
"editVirtKeys": "Edit kunci virtual", "editVirtKeys": "Edit kunci virtual",
"editor": "Editor", "editor": "Editor",
@@ -137,6 +136,7 @@
"open": "Membuka", "open": "Membuka",
"paste": "Tempel", "paste": "Tempel",
"path": "Jalur", "path": "Jalur",
"percentOfSize": "{percent}% dari {size}",
"pickFile": "Pilih file", "pickFile": "Pilih file",
"pingAvg": "Rata -rata:", "pingAvg": "Rata -rata:",
"pingInputIP": "Harap masukkan IP / domain target.", "pingInputIP": "Harap masukkan IP / domain target.",
@@ -176,6 +176,7 @@
"serverTabUnkown": "Negara yang tidak diketahui", "serverTabUnkown": "Negara yang tidak diketahui",
"setting": "Pengaturan", "setting": "Pengaturan",
"sftpDlPrepare": "Bersiap untuk terhubung ...", "sftpDlPrepare": "Bersiap untuk terhubung ...",
"sftpRmrfDir": "Gunakan `rm -rf` untuk menghapus direktori di SFTP",
"sftpSSHConnected": "Sftp terhubung", "sftpSSHConnected": "Sftp terhubung",
"showDistLogo": "Tampilkan logo distribusi", "showDistLogo": "Tampilkan logo distribusi",
"snippet": "Snippet", "snippet": "Snippet",

View File

@@ -53,7 +53,6 @@
"dockerStatusRunningAndStoppedFmt": "{runningCount}个正在运行, {stoppedCount}个已停止", "dockerStatusRunningAndStoppedFmt": "{runningCount}个正在运行, {stoppedCount}个已停止",
"dockerStatusRunningFmt": "{count}个容器正在运行", "dockerStatusRunningFmt": "{count}个容器正在运行",
"download": "下载", "download": "下载",
"downloadStatus": "{size} 的 {percent}%",
"edit": "编辑", "edit": "编辑",
"editVirtKeys": "编辑虚拟按键", "editVirtKeys": "编辑虚拟按键",
"editor": "编辑器", "editor": "编辑器",
@@ -137,6 +136,7 @@
"open": "打开", "open": "打开",
"paste": "粘贴", "paste": "粘贴",
"path": "路径", "path": "路径",
"percentOfSize": "{size} 的 {percent}%",
"pickFile": "选择文件", "pickFile": "选择文件",
"pingAvg": "平均:", "pingAvg": "平均:",
"pingInputIP": "请输入目标IP或域名", "pingInputIP": "请输入目标IP或域名",
@@ -176,6 +176,7 @@
"serverTabUnkown": "未知状态", "serverTabUnkown": "未知状态",
"setting": "设置", "setting": "设置",
"sftpDlPrepare": "准备连接至服务器...", "sftpDlPrepare": "准备连接至服务器...",
"sftpRmrfDir": "在 SFTP 中使用 `rm -rf` 删除文件夹",
"sftpSSHConnected": "SFTP 已连接...", "sftpSSHConnected": "SFTP 已连接...",
"showDistLogo": "显示发行版 Logo", "showDistLogo": "显示发行版 Logo",
"snippet": "代码片段", "snippet": "代码片段",

View File

@@ -53,7 +53,6 @@
"dockerStatusRunningAndStoppedFmt": "{runningCount}個正在運行, {stoppedCount}個已停止", "dockerStatusRunningAndStoppedFmt": "{runningCount}個正在運行, {stoppedCount}個已停止",
"dockerStatusRunningFmt": "{count}個容器正在運行", "dockerStatusRunningFmt": "{count}個容器正在運行",
"download": "下載", "download": "下載",
"downloadStatus": "{size} 的 {percent}%",
"edit": "編輯", "edit": "編輯",
"editVirtKeys": "編輯虛擬按鍵", "editVirtKeys": "編輯虛擬按鍵",
"editor": "編輯器", "editor": "編輯器",
@@ -137,6 +136,7 @@
"open": "打開", "open": "打開",
"paste": "貼上", "paste": "貼上",
"path": "路徑", "path": "路徑",
"percentOfSize": "{size} 的 {percent}%",
"pickFile": "選擇文件", "pickFile": "選擇文件",
"pingAvg": "平均:", "pingAvg": "平均:",
"pingInputIP": "請輸入目標IP或域名", "pingInputIP": "請輸入目標IP或域名",
@@ -176,6 +176,7 @@
"serverTabUnkown": "未知狀態", "serverTabUnkown": "未知狀態",
"setting": "設置", "setting": "設置",
"sftpDlPrepare": "準備連接至服務器...", "sftpDlPrepare": "準備連接至服務器...",
"sftpRmrfDir": "在 SFTP 中使用 `rm -rf` 刪除文件夾",
"sftpSSHConnected": "SFTP 已連接...", "sftpSSHConnected": "SFTP 已連接...",
"showDistLogo": "顯示發行版 Logo", "showDistLogo": "顯示發行版 Logo",
"snippet": "程式片段", "snippet": "程式片段",

View File

@@ -76,7 +76,18 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
body: _buildBody(), body: _buildBody(),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
child: const Icon(Icons.done), child: const Icon(Icons.done),
onPressed: () { onPressed: () async {
// If path is not null, then it's a file editor
// save the text and return true to pop the page
if (widget.path != null) {
showLoadingDialog(context);
await File(widget.path!).writeAsString(_controller.text);
context.pop();
context.pop(true);
return;
}
// else it's a text editor
// return the text to the previous page
context.pop(_controller.text); context.pop(_controller.text);
}, },
), ),

View File

@@ -191,6 +191,7 @@ class _SettingPageState extends State<SettingPage> {
_buildSSHVirtualKeyAutoOff(), _buildSSHVirtualKeyAutoOff(),
_buildKeyboardType(), _buildKeyboardType(),
_buildSSHVirtKeys(), _buildSSHVirtKeys(),
_buildSftpRmrfDir(),
].map((e) => RoundRectCard(e)).toList(), ].map((e) => RoundRectCard(e)).toList(),
); );
} }
@@ -1022,4 +1023,11 @@ class _SettingPageState extends State<SettingPage> {
], ],
); );
} }
Widget _buildSftpRmrfDir() {
return ListTile(
title: Text(_s.sftpRmrfDir),
trailing: buildSwitch(context, _setting.sftpRmrfDir),
);
}
} }

View File

@@ -315,7 +315,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
} }
locator<SftpProvider>().add(SftpReq( locator<SftpProvider>().add(SftpReq(
spi, spi,
remotePath, '$remotePath/$fileName',
file.absolute.path, file.absolute.path,
SftpReqType.upload, SftpReqType.upload,
)); ));

View File

@@ -1,6 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'package:after_layout/after_layout.dart';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
@@ -25,6 +25,7 @@ import '../../../data/provider/server.dart';
import '../../../data/provider/sftp.dart'; import '../../../data/provider/sftp.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
import '../../widget/fade_in.dart'; import '../../widget/fade_in.dart';
@@ -47,11 +48,12 @@ class SftpPage extends StatefulWidget {
_SftpPageState createState() => _SftpPageState(); _SftpPageState createState() => _SftpPageState();
} }
class _SftpPageState extends State<SftpPage> { class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final SftpBrowserStatus _status = SftpBrowserStatus(); final SftpBrowserStatus _status = SftpBrowserStatus();
final _sftp = locator<SftpProvider>(); final _sftp = locator<SftpProvider>();
final _history = locator<HistoryStore>(); final _history = locator<HistoryStore>();
final _setting = locator<SettingStore>();
late S _s; late S _s;
@@ -85,7 +87,6 @@ class _SftpPageState extends State<SftpPage> {
context.pop(); context.pop();
}, },
), ),
centerTitle: true,
title: TwoLineText(up: 'SFTP', down: widget.spi.name), title: TwoLineText(up: 'SFTP', down: widget.spi.name),
actions: [ actions: [
IconButton( IconButton(
@@ -191,7 +192,7 @@ class _SftpPageState extends State<SftpPage> {
_sftp.add( _sftp.add(
SftpReq( SftpReq(
widget.spi, widget.spi,
remotePath, '$remotePath/${path.split('/').last}',
path, path,
SftpReqType.upload, SftpReqType.upload,
), ),
@@ -267,9 +268,6 @@ class _SftpPageState extends State<SftpPage> {
Widget _buildFileView() { Widget _buildFileView() {
if (_status.files == null) { if (_status.files == null) {
final p_ = widget.initPath ?? '/';
_status.path = AbsolutePath(p_);
_listDir(path: p_, client: _client);
return centerLoading; return centerLoading;
} }
@@ -288,7 +286,7 @@ class _SftpPageState extends State<SftpPage> {
itemBuilder: (_, index) => _buildItem(_status.files![index]), itemBuilder: (_, index) => _buildItem(_status.files![index]),
), ),
), ),
onRefresh: () => _listDir(path: _status.path?.path), onRefresh: () => _listDir(),
); );
} }
@@ -390,8 +388,8 @@ class _SftpPageState extends State<SftpPage> {
await completer.future; await completer.future;
context.pop(); context.pop();
final result = await AppRoute.editor(path: localPath).go<String>(context); final result = await AppRoute.editor(path: localPath).go<bool>(context);
if (result != null) { if (result != null && result) {
_sftp.add(SftpReq(req.spi, remotePath, localPath, SftpReqType.upload)); _sftp.add(SftpReq(req.spi, remotePath, localPath, SftpReqType.upload));
} }
} }
@@ -431,7 +429,8 @@ class _SftpPageState extends State<SftpPage> {
void _delete(BuildContext context, SftpName file) { void _delete(BuildContext context, SftpName file) {
context.pop(); context.pop();
final isDir = file.attr.isDirectory; final isDir = file.attr.isDirectory;
final dirText = isDir ? '\n${_s.sureDirEmpty}' : ''; final useRmrf = _setting.sftpRmrfDir.fetch()!;
final dirText = (isDir && !useRmrf) ? '\n${_s.sureDirEmpty}' : '';
final text = '${_s.sureDelete(file.filename)}$dirText'; final text = '${_s.sureDelete(file.filename)}$dirText';
final child = Text(text); final child = Text(text);
showRoundDialog( showRoundDialog(
@@ -449,7 +448,9 @@ class _SftpPageState extends State<SftpPage> {
showLoadingDialog(context); showLoadingDialog(context);
final remotePath = _getRemotePath(file); final remotePath = _getRemotePath(file);
try { try {
if (file.attr.isDirectory) { if (useRmrf) {
await _client!.run('rm -rf "$remotePath"');
} else if (file.attr.isDirectory) {
await _status.client!.rmdir(remotePath); await _status.client!.rmdir(remotePath);
} else { } else {
await _status.client!.remove(remotePath); await _status.client!.remove(remotePath);
@@ -534,10 +535,6 @@ class _SftpPageState extends State<SftpPage> {
label: _s.name, label: _s.name,
), ),
actions: [ actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(_s.cancel),
),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
if (textController.text == '') { if (textController.text == '') {
@@ -554,9 +551,10 @@ class _SftpPageState extends State<SftpPage> {
); );
return; return;
} }
context.pop();
final path = '${_status.path!.path}/${textController.text}'; final path = '${_status.path!.path}/${textController.text}';
final file = await _status.client!.open(path); showLoadingDialog(context);
await file.writeBytes(Uint8List(0)); await _client!.run('touch "$path"');
context.pop(); context.pop();
_listDir(); _listDir();
}, },
@@ -700,6 +698,13 @@ class _SftpPageState extends State<SftpPage> {
await _listDir(); await _listDir();
} }
} }
@override
FutureOr<void> afterFirstLayout(BuildContext context) {
final p_ = widget.initPath ?? '/';
_status.path = AbsolutePath(p_);
_listDir(path: p_, client: _client);
}
} }
String? _getDecompressCmd(String filename) { String? _getDecompressCmd(String filename) {

View File

@@ -86,12 +86,12 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
], ],
), ),
); );
case SftpWorkerStatus.downloading: case SftpWorkerStatus.loading:
final percentStr = (status.progress ?? 0.0).toStringAsFixed(2); final percentStr = (status.progress ?? 0.0).toStringAsFixed(2);
final size = (status.size ?? 0).convertBytes; final size = (status.size ?? 0).convertBytes;
return _wrapInCard( return _wrapInCard(
status: status, status: status,
subtitle: _s.downloadStatus(percentStr, size), subtitle: _s.percentOfSize(percentStr, size),
trailing: _buildDelete(status.fileName, status.id), trailing: _buildDelete(status.fileName, status.id),
); );
case SftpWorkerStatus.preparing: case SftpWorkerStatus.preparing: