mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
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:
@@ -416,12 +416,6 @@ abstract class S {
|
||||
/// **'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.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
@@ -920,6 +914,12 @@ abstract class S {
|
||||
/// **'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.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
@@ -1154,6 +1154,12 @@ abstract class S {
|
||||
/// **'Preparing to connect...'**
|
||||
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.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -171,11 +171,6 @@ class SDe extends S {
|
||||
@override
|
||||
String get download => 'Download';
|
||||
|
||||
@override
|
||||
String downloadStatus(Object percent, Object size) {
|
||||
return '$percent% von $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get edit => 'Bearbeiten';
|
||||
|
||||
@@ -437,6 +432,11 @@ class SDe extends S {
|
||||
@override
|
||||
String get path => 'Pfad';
|
||||
|
||||
@override
|
||||
String percentOfSize(Object percent, Object size) {
|
||||
return '$percent% von $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pickFile => 'Datei wählen';
|
||||
|
||||
@@ -558,6 +558,9 @@ class SDe extends S {
|
||||
@override
|
||||
String get sftpDlPrepare => 'Verbindung vorbereiten...';
|
||||
|
||||
@override
|
||||
String get sftpRmrfDir => 'Verwenden Sie `rm -rf`, um das Verzeichnis auf SFTP zu löschen';
|
||||
|
||||
@override
|
||||
String get sftpSSHConnected => 'SFTP Verbunden';
|
||||
|
||||
|
||||
@@ -171,11 +171,6 @@ class SEn extends S {
|
||||
@override
|
||||
String get download => 'Download';
|
||||
|
||||
@override
|
||||
String downloadStatus(Object percent, Object size) {
|
||||
return '$percent% of $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get edit => 'Edit';
|
||||
|
||||
@@ -437,6 +432,11 @@ class SEn extends S {
|
||||
@override
|
||||
String get path => 'Path';
|
||||
|
||||
@override
|
||||
String percentOfSize(Object percent, Object size) {
|
||||
return '$percent% of $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pickFile => 'Pick file';
|
||||
|
||||
@@ -558,6 +558,9 @@ class SEn extends S {
|
||||
@override
|
||||
String get sftpDlPrepare => 'Preparing to connect...';
|
||||
|
||||
@override
|
||||
String get sftpRmrfDir => 'Use `rm -rf` to delete dir on SFTP';
|
||||
|
||||
@override
|
||||
String get sftpSSHConnected => 'SFTP Connected';
|
||||
|
||||
|
||||
@@ -171,11 +171,6 @@ class SId extends S {
|
||||
@override
|
||||
String get download => 'Unduh';
|
||||
|
||||
@override
|
||||
String downloadStatus(Object percent, Object size) {
|
||||
return '$percent% dari $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get edit => 'Edit';
|
||||
|
||||
@@ -437,6 +432,11 @@ class SId extends S {
|
||||
@override
|
||||
String get path => 'Jalur';
|
||||
|
||||
@override
|
||||
String percentOfSize(Object percent, Object size) {
|
||||
return '$percent% dari $size';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pickFile => 'Pilih file';
|
||||
|
||||
@@ -558,6 +558,9 @@ class SId extends S {
|
||||
@override
|
||||
String get sftpDlPrepare => 'Bersiap untuk terhubung ...';
|
||||
|
||||
@override
|
||||
String get sftpRmrfDir => 'Gunakan `rm -rf` untuk menghapus direktori di SFTP';
|
||||
|
||||
@override
|
||||
String get sftpSSHConnected => 'Sftp terhubung';
|
||||
|
||||
|
||||
@@ -171,11 +171,6 @@ class SZh extends S {
|
||||
@override
|
||||
String get download => '下载';
|
||||
|
||||
@override
|
||||
String downloadStatus(Object percent, Object size) {
|
||||
return '$size 的 $percent%';
|
||||
}
|
||||
|
||||
@override
|
||||
String get edit => '编辑';
|
||||
|
||||
@@ -437,6 +432,11 @@ class SZh extends S {
|
||||
@override
|
||||
String get path => '路径';
|
||||
|
||||
@override
|
||||
String percentOfSize(Object percent, Object size) {
|
||||
return '$size 的 $percent%';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pickFile => '选择文件';
|
||||
|
||||
@@ -558,6 +558,9 @@ class SZh extends S {
|
||||
@override
|
||||
String get sftpDlPrepare => '准备连接至服务器...';
|
||||
|
||||
@override
|
||||
String get sftpRmrfDir => '在 SFTP 中使用 `rm -rf` 删除文件夹';
|
||||
|
||||
@override
|
||||
String get sftpSSHConnected => 'SFTP 已连接...';
|
||||
|
||||
@@ -888,11 +891,6 @@ class SZhTw extends SZh {
|
||||
@override
|
||||
String get download => '下載';
|
||||
|
||||
@override
|
||||
String downloadStatus(Object percent, Object size) {
|
||||
return '$size 的 $percent%';
|
||||
}
|
||||
|
||||
@override
|
||||
String get edit => '編輯';
|
||||
|
||||
@@ -1154,6 +1152,11 @@ class SZhTw extends SZh {
|
||||
@override
|
||||
String get path => '路徑';
|
||||
|
||||
@override
|
||||
String percentOfSize(Object percent, Object size) {
|
||||
return '$size 的 $percent%';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pickFile => '選擇文件';
|
||||
|
||||
@@ -1275,6 +1278,9 @@ class SZhTw extends SZh {
|
||||
@override
|
||||
String get sftpDlPrepare => '準備連接至服務器...';
|
||||
|
||||
@override
|
||||
String get sftpRmrfDir => '在 SFTP 中使用 `rm -rf` 刪除文件夾';
|
||||
|
||||
@override
|
||||
String get sftpSSHConnected => 'SFTP 已連接...';
|
||||
|
||||
|
||||
@@ -86,4 +86,4 @@ class SftpReqStatus {
|
||||
}
|
||||
}
|
||||
|
||||
enum SftpWorkerStatus { preparing, sshConnectted, downloading, finished }
|
||||
enum SftpWorkerStatus { preparing, sshConnectted, loading, finished }
|
||||
|
||||
@@ -5,9 +5,8 @@ import 'dart:typed_data';
|
||||
|
||||
import 'package:dartssh2/dartssh2.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';
|
||||
|
||||
class SftpWorker {
|
||||
@@ -78,16 +77,14 @@ Future<void> _download(
|
||||
final client = await genClient(req.spi, privateKey: req.privateKey);
|
||||
mainSendPort.send(SftpWorkerStatus.sshConnectted);
|
||||
|
||||
final remotePath = req.remotePath;
|
||||
final localPath = req.localPath;
|
||||
await Directory(localPath.substring(0, req.localPath.lastIndexOf('/')))
|
||||
await Directory(req.localPath.substring(0, req.localPath.lastIndexOf('/')))
|
||||
.create(recursive: true);
|
||||
final local = File(localPath);
|
||||
final local = File(req.localPath);
|
||||
if (await local.exists()) {
|
||||
await local.delete();
|
||||
}
|
||||
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;
|
||||
if (size == null) {
|
||||
mainSendPort.send(Exception('can not get file size'));
|
||||
@@ -97,7 +94,7 @@ Future<void> _download(
|
||||
const defaultChunkSize = 1024 * 1024;
|
||||
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size;
|
||||
mainSendPort.send(size);
|
||||
mainSendPort.send(SftpWorkerStatus.downloading);
|
||||
mainSendPort.send(SftpWorkerStatus.loading);
|
||||
for (var i = 0; i < size; i += chunkSize) {
|
||||
final fileData = file.read(length: chunkSize);
|
||||
await for (var form in fileData) {
|
||||
@@ -125,19 +122,23 @@ Future<void> _upload(
|
||||
final client = await genClient(req.spi, privateKey: req.privateKey);
|
||||
mainSendPort.send(SftpWorkerStatus.sshConnectted);
|
||||
|
||||
final localPath = req.localPath;
|
||||
final fileName = getFileName(localPath) ?? 'srvbox_sftp_upload';
|
||||
final remotePath = '${req.remotePath}/$fileName';
|
||||
final local = File(localPath);
|
||||
final local = File(req.localPath);
|
||||
if (!await local.exists()) {
|
||||
mainSendPort.send(Exception('local file not exists'));
|
||||
return;
|
||||
}
|
||||
final localLen = await local.length();
|
||||
mainSendPort.send(localLen);
|
||||
mainSendPort.send(SftpWorkerStatus.loading);
|
||||
final localFile = local.openRead().cast<Uint8List>();
|
||||
final sftp = await client.sftp();
|
||||
final file = await sftp.open(remotePath,
|
||||
mode: SftpFileOpenMode.write | SftpFileOpenMode.create);
|
||||
final writer = file.write(localFile);
|
||||
final file = await sftp.open(
|
||||
req.remotePath,
|
||||
mode: SftpFileOpenMode.write | SftpFileOpenMode.create,
|
||||
);
|
||||
final writer = file.write(localFile, onProgress: (total) {
|
||||
mainSendPort.send(total / localLen * 100);
|
||||
},);
|
||||
await writer.done;
|
||||
await file.close();
|
||||
mainSendPort.send(watch.elapsed);
|
||||
|
||||
@@ -111,4 +111,8 @@ class SettingStore extends PersistentStore {
|
||||
/// Otherwise, display them on the top of server detail page
|
||||
StoreProperty<bool> get moveOutServerTabFuncBtns =>
|
||||
property('moveOutServerTabFuncBtns', defaultValue: true);
|
||||
|
||||
/// Whether use `rm -rf` to delete directory on SFTP
|
||||
StoreProperty<bool> get sftpRmrfDir =>
|
||||
property('sftpRmrfDir', defaultValue: true);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount} aktiv, {stoppedCount} container gestoppt.",
|
||||
"dockerStatusRunningFmt": "{count} Container aktiv",
|
||||
"download": "Download",
|
||||
"downloadStatus": "{percent}% von {size}",
|
||||
"edit": "Bearbeiten",
|
||||
"editVirtKeys": "Virtuelle Tasten bearbeiten",
|
||||
"editor": "Editor",
|
||||
@@ -137,6 +136,7 @@
|
||||
"open": "Öffnen",
|
||||
"paste": "Einfügen",
|
||||
"path": "Pfad",
|
||||
"percentOfSize": "{percent}% von {size}",
|
||||
"pickFile": "Datei wählen",
|
||||
"pingAvg": "Avg:",
|
||||
"pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.",
|
||||
@@ -176,6 +176,7 @@
|
||||
"serverTabUnkown": "Unbekannter Status",
|
||||
"setting": "Einstellungen",
|
||||
"sftpDlPrepare": "Verbindung vorbereiten...",
|
||||
"sftpRmrfDir": "Verwenden Sie `rm -rf`, um das Verzeichnis auf SFTP zu löschen",
|
||||
"sftpSSHConnected": "SFTP Verbunden",
|
||||
"showDistLogo": "Distributionslogo anzeigen",
|
||||
"snippet": "Snippet",
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
|
||||
"dockerStatusRunningFmt": "{count} container running.",
|
||||
"download": "Download",
|
||||
"downloadStatus": "{percent}% of {size}",
|
||||
"edit": "Edit",
|
||||
"editVirtKeys": "Edit virtual keys",
|
||||
"editor": "Editor",
|
||||
@@ -137,6 +136,7 @@
|
||||
"open": "Open",
|
||||
"paste": "Paste",
|
||||
"path": "Path",
|
||||
"percentOfSize": "{percent}% of {size}",
|
||||
"pickFile": "Pick file",
|
||||
"pingAvg": "Avg:",
|
||||
"pingInputIP": "Please input a target IP / domain.",
|
||||
@@ -176,6 +176,7 @@
|
||||
"serverTabUnkown": "Unknown state",
|
||||
"setting": "Settings",
|
||||
"sftpDlPrepare": "Preparing to connect...",
|
||||
"sftpRmrfDir": "Use `rm -rf` to delete dir on SFTP",
|
||||
"sftpSSHConnected": "SFTP Connected",
|
||||
"showDistLogo": "Show distribution logo",
|
||||
"snippet": "Snippet",
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
|
||||
"dockerStatusRunningFmt": "{count} wadah berjalan.",
|
||||
"download": "Unduh",
|
||||
"downloadStatus": "{percent}% dari {size}",
|
||||
"edit": "Edit",
|
||||
"editVirtKeys": "Edit kunci virtual",
|
||||
"editor": "Editor",
|
||||
@@ -137,6 +136,7 @@
|
||||
"open": "Membuka",
|
||||
"paste": "Tempel",
|
||||
"path": "Jalur",
|
||||
"percentOfSize": "{percent}% dari {size}",
|
||||
"pickFile": "Pilih file",
|
||||
"pingAvg": "Rata -rata:",
|
||||
"pingInputIP": "Harap masukkan IP / domain target.",
|
||||
@@ -176,6 +176,7 @@
|
||||
"serverTabUnkown": "Negara yang tidak diketahui",
|
||||
"setting": "Pengaturan",
|
||||
"sftpDlPrepare": "Bersiap untuk terhubung ...",
|
||||
"sftpRmrfDir": "Gunakan `rm -rf` untuk menghapus direktori di SFTP",
|
||||
"sftpSSHConnected": "Sftp terhubung",
|
||||
"showDistLogo": "Tampilkan logo distribusi",
|
||||
"snippet": "Snippet",
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount}个正在运行, {stoppedCount}个已停止",
|
||||
"dockerStatusRunningFmt": "{count}个容器正在运行",
|
||||
"download": "下载",
|
||||
"downloadStatus": "{size} 的 {percent}%",
|
||||
"edit": "编辑",
|
||||
"editVirtKeys": "编辑虚拟按键",
|
||||
"editor": "编辑器",
|
||||
@@ -137,6 +136,7 @@
|
||||
"open": "打开",
|
||||
"paste": "粘贴",
|
||||
"path": "路径",
|
||||
"percentOfSize": "{size} 的 {percent}%",
|
||||
"pickFile": "选择文件",
|
||||
"pingAvg": "平均:",
|
||||
"pingInputIP": "请输入目标IP或域名",
|
||||
@@ -176,6 +176,7 @@
|
||||
"serverTabUnkown": "未知状态",
|
||||
"setting": "设置",
|
||||
"sftpDlPrepare": "准备连接至服务器...",
|
||||
"sftpRmrfDir": "在 SFTP 中使用 `rm -rf` 删除文件夹",
|
||||
"sftpSSHConnected": "SFTP 已连接...",
|
||||
"showDistLogo": "显示发行版 Logo",
|
||||
"snippet": "代码片段",
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount}個正在運行, {stoppedCount}個已停止",
|
||||
"dockerStatusRunningFmt": "{count}個容器正在運行",
|
||||
"download": "下載",
|
||||
"downloadStatus": "{size} 的 {percent}%",
|
||||
"edit": "編輯",
|
||||
"editVirtKeys": "編輯虛擬按鍵",
|
||||
"editor": "編輯器",
|
||||
@@ -137,6 +136,7 @@
|
||||
"open": "打開",
|
||||
"paste": "貼上",
|
||||
"path": "路徑",
|
||||
"percentOfSize": "{size} 的 {percent}%",
|
||||
"pickFile": "選擇文件",
|
||||
"pingAvg": "平均:",
|
||||
"pingInputIP": "請輸入目標IP或域名",
|
||||
@@ -176,6 +176,7 @@
|
||||
"serverTabUnkown": "未知狀態",
|
||||
"setting": "設置",
|
||||
"sftpDlPrepare": "準備連接至服務器...",
|
||||
"sftpRmrfDir": "在 SFTP 中使用 `rm -rf` 刪除文件夾",
|
||||
"sftpSSHConnected": "SFTP 已連接...",
|
||||
"showDistLogo": "顯示發行版 Logo",
|
||||
"snippet": "程式片段",
|
||||
|
||||
@@ -76,7 +76,18 @@ class _EditorPageState extends State<EditorPage> with AfterLayoutMixin {
|
||||
body: _buildBody(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
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);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -191,6 +191,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
_buildSSHVirtualKeyAutoOff(),
|
||||
_buildKeyboardType(),
|
||||
_buildSSHVirtKeys(),
|
||||
_buildSftpRmrfDir(),
|
||||
].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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
}
|
||||
locator<SftpProvider>().add(SftpReq(
|
||||
spi,
|
||||
remotePath,
|
||||
'$remotePath/$fileName',
|
||||
file.absolute.path,
|
||||
SftpReqType.upload,
|
||||
));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.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/res/path.dart';
|
||||
import '../../../data/res/ui.dart';
|
||||
import '../../../data/store/setting.dart';
|
||||
import '../../../locator.dart';
|
||||
import '../../widget/custom_appbar.dart';
|
||||
import '../../widget/fade_in.dart';
|
||||
@@ -47,11 +48,12 @@ class SftpPage extends StatefulWidget {
|
||||
_SftpPageState createState() => _SftpPageState();
|
||||
}
|
||||
|
||||
class _SftpPageState extends State<SftpPage> {
|
||||
class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
final SftpBrowserStatus _status = SftpBrowserStatus();
|
||||
|
||||
final _sftp = locator<SftpProvider>();
|
||||
final _history = locator<HistoryStore>();
|
||||
final _setting = locator<SettingStore>();
|
||||
|
||||
late S _s;
|
||||
|
||||
@@ -85,7 +87,6 @@ class _SftpPageState extends State<SftpPage> {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
centerTitle: true,
|
||||
title: TwoLineText(up: 'SFTP', down: widget.spi.name),
|
||||
actions: [
|
||||
IconButton(
|
||||
@@ -191,7 +192,7 @@ class _SftpPageState extends State<SftpPage> {
|
||||
_sftp.add(
|
||||
SftpReq(
|
||||
widget.spi,
|
||||
remotePath,
|
||||
'$remotePath/${path.split('/').last}',
|
||||
path,
|
||||
SftpReqType.upload,
|
||||
),
|
||||
@@ -267,9 +268,6 @@ class _SftpPageState extends State<SftpPage> {
|
||||
|
||||
Widget _buildFileView() {
|
||||
if (_status.files == null) {
|
||||
final p_ = widget.initPath ?? '/';
|
||||
_status.path = AbsolutePath(p_);
|
||||
_listDir(path: p_, client: _client);
|
||||
return centerLoading;
|
||||
}
|
||||
|
||||
@@ -288,7 +286,7 @@ class _SftpPageState extends State<SftpPage> {
|
||||
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;
|
||||
context.pop();
|
||||
|
||||
final result = await AppRoute.editor(path: localPath).go<String>(context);
|
||||
if (result != null) {
|
||||
final result = await AppRoute.editor(path: localPath).go<bool>(context);
|
||||
if (result != null && result) {
|
||||
_sftp.add(SftpReq(req.spi, remotePath, localPath, SftpReqType.upload));
|
||||
}
|
||||
}
|
||||
@@ -431,7 +429,8 @@ class _SftpPageState extends State<SftpPage> {
|
||||
void _delete(BuildContext context, SftpName file) {
|
||||
context.pop();
|
||||
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 child = Text(text);
|
||||
showRoundDialog(
|
||||
@@ -449,7 +448,9 @@ class _SftpPageState extends State<SftpPage> {
|
||||
showLoadingDialog(context);
|
||||
final remotePath = _getRemotePath(file);
|
||||
try {
|
||||
if (file.attr.isDirectory) {
|
||||
if (useRmrf) {
|
||||
await _client!.run('rm -rf "$remotePath"');
|
||||
} else if (file.attr.isDirectory) {
|
||||
await _status.client!.rmdir(remotePath);
|
||||
} else {
|
||||
await _status.client!.remove(remotePath);
|
||||
@@ -534,10 +535,6 @@ class _SftpPageState extends State<SftpPage> {
|
||||
label: _s.name,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(_s.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (textController.text == '') {
|
||||
@@ -554,9 +551,10 @@ class _SftpPageState extends State<SftpPage> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
final path = '${_status.path!.path}/${textController.text}';
|
||||
final file = await _status.client!.open(path);
|
||||
await file.writeBytes(Uint8List(0));
|
||||
showLoadingDialog(context);
|
||||
await _client!.run('touch "$path"');
|
||||
context.pop();
|
||||
_listDir();
|
||||
},
|
||||
@@ -700,6 +698,13 @@ class _SftpPageState extends State<SftpPage> {
|
||||
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) {
|
||||
|
||||
@@ -86,12 +86,12 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
|
||||
],
|
||||
),
|
||||
);
|
||||
case SftpWorkerStatus.downloading:
|
||||
case SftpWorkerStatus.loading:
|
||||
final percentStr = (status.progress ?? 0.0).toStringAsFixed(2);
|
||||
final size = (status.size ?? 0).convertBytes;
|
||||
return _wrapInCard(
|
||||
status: status,
|
||||
subtitle: _s.downloadStatus(percentStr, size),
|
||||
subtitle: _s.percentOfSize(percentStr, size),
|
||||
trailing: _buildDelete(status.fileName, status.id),
|
||||
);
|
||||
case SftpWorkerStatus.preparing:
|
||||
|
||||
Reference in New Issue
Block a user