mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-01-31 13:25:10 +01:00
SFTP support download. listDIr() support rollback.
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 107;
|
||||
static const int build = 108;
|
||||
static const String engine =
|
||||
"Flutter 2.10.3 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 7e9793dee1 (8 days ago) • 2022-03-02 11:23:12 -0600\nEngine • revision bd539267b4\nTools • Dart 2.16.1 • DevTools 2.9.2\n";
|
||||
static const String buildAt = "2022-03-10 13:25:24.362670";
|
||||
static const int modifications = 11;
|
||||
static const String buildAt = "2022-03-10 15:25:32.032568";
|
||||
static const int modifications = 0;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ class PingPage extends StatefulWidget {
|
||||
class _PingPageState extends State<PingPage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
late TextEditingController _textEditingController;
|
||||
String _result = '';
|
||||
Ping? _ping;
|
||||
late MediaQueryData _media;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -33,6 +33,7 @@ class _PingPageState extends State<PingPage>
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_media = MediaQuery.of(context);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -46,13 +47,12 @@ class _PingPageState extends State<PingPage>
|
||||
const SizedBox(height: 13),
|
||||
buildInput(context, _textEditingController, maxLines: 1),
|
||||
_buildControl(),
|
||||
RoundRectCard(
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(7), child: Text(_result)),
|
||||
RoundRectCard(ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: double.infinity,
|
||||
minHeight: _media.size.height * 0.6,
|
||||
),
|
||||
),
|
||||
)),
|
||||
])),
|
||||
onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
|
||||
),
|
||||
@@ -60,12 +60,10 @@ class _PingPageState extends State<PingPage>
|
||||
}
|
||||
|
||||
void doPing() {
|
||||
_result = '';
|
||||
_ping = Ping(_textEditingController.text.trim());
|
||||
_ping!.stream.listen((event) {
|
||||
final resp = event.response.toString();
|
||||
if (resp == 'null') return;
|
||||
_result += '$resp\n';
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:toolbox/core/utils.dart';
|
||||
import 'package:toolbox/data/model/server/server_connection_state.dart';
|
||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||
@@ -7,6 +10,7 @@ import 'package:toolbox/data/model/sftp/absolute_path.dart';
|
||||
import 'package:toolbox/data/model/sftp/sftp_side_status.dart';
|
||||
import 'package:toolbox/data/provider/server.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
import 'package:toolbox/view/widget/center_loading.dart';
|
||||
import 'package:toolbox/view/widget/fade_in.dart';
|
||||
import 'package:toolbox/view/widget/two_line_text.dart';
|
||||
|
||||
@@ -144,6 +148,11 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
title: const Text('Rename'),
|
||||
onTap: () => rename(context, file),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.download),
|
||||
title: const Text('Download'),
|
||||
onTap: () => download(context, file),
|
||||
)
|
||||
],
|
||||
),
|
||||
[
|
||||
@@ -153,6 +162,42 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
]);
|
||||
}
|
||||
|
||||
void download(BuildContext context, SftpName name) {
|
||||
showRoundDialog(
|
||||
context, 'Download', Text('Download ${name.filename} to local?'), [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Cancel')),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
var result = '';
|
||||
try {
|
||||
Navigator.of(context).pop();
|
||||
showRoundDialog(context, name.filename, centerSizedLoading, [],
|
||||
barrierDismiss: false);
|
||||
final path = await getApplicationDocumentsDirectory();
|
||||
final localFile = File('${path.path}/${name.filename}');
|
||||
final remotePath = _status.path!.path + '/' + name.filename;
|
||||
final file = await _status.client?.open(remotePath);
|
||||
localFile.writeAsBytes(await file!.readBytes());
|
||||
Navigator.of(context).pop();
|
||||
} catch (e) {
|
||||
result = e.toString();
|
||||
} finally {
|
||||
if (result.isEmpty) {
|
||||
result = 'Donwloaded successfully.';
|
||||
}
|
||||
showRoundDialog(context, 'Result', Text(result), [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('OK'))
|
||||
]);
|
||||
}
|
||||
},
|
||||
child: const Text('Download'))
|
||||
]);
|
||||
}
|
||||
|
||||
void delete(BuildContext context, SftpName file) {
|
||||
Navigator.of(context).pop();
|
||||
showRoundDialog(
|
||||
@@ -274,15 +319,26 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
final sftpc = await client.sftp();
|
||||
_status.client = sftpc;
|
||||
}
|
||||
final fs =
|
||||
await _status.client!.listdir(path ?? (_status.path?.path ?? '/'));
|
||||
fs.sort((a, b) => a.filename.compareTo(b.filename));
|
||||
fs.removeAt(0);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_status.files = fs;
|
||||
_status.isBusy = false;
|
||||
});
|
||||
try {
|
||||
final fs =
|
||||
await _status.client!.listdir(path ?? (_status.path?.path ?? '/'));
|
||||
fs.sort((a, b) => a.filename.compareTo(b.filename));
|
||||
fs.removeAt(0);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_status.files = fs;
|
||||
_status.isBusy = false;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
await showRoundDialog(context, 'Error', Text(e.toString()), [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('OK'))
|
||||
]);
|
||||
if (_status.path!.undo()) {
|
||||
await listDir();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const centerLoading = Center(child: CircularProgressIndicator());
|
||||
|
||||
const centerSizedLoading = SizedBox(
|
||||
width: 77,
|
||||
height: 77,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user