opt.: sftp dl

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-07-21 16:20:27 +08:00
parent 263d4eabb4
commit ec4bf3df24
8 changed files with 73 additions and 64 deletions

View File

@@ -58,7 +58,7 @@ Future<SSHClient> genClient(
Spi? jumpSpi, Spi? jumpSpi,
/// Handle keyboard-interactive authentication /// Handle keyboard-interactive authentication
FutureOr<List<String>?> Function(SSHUserInfoRequest)? onKeyboardInteractive, SSHUserInfoRequestHandler? onKeyboardInteractive,
}) async { }) async {
onStatus?.call(GenSSHClientStatus.socket); onStatus?.call(GenSSHClientStatus.socket);

View File

@@ -99,16 +99,21 @@ Future<void> _download(
mainSendPort.send(size); mainSendPort.send(size);
mainSendPort.send(SftpWorkerStatus.loading); mainSendPort.send(SftpWorkerStatus.loading);
// Read 2m each time
// Issue #161 // Issue #161
// The download speed is about 2m/s may due to single core performance // Due to single core performance, limit the chunk size
const defaultChunkSize = 1024 * 1024 * 2; const defaultChunkSize = 1024 * 1024 * 5;
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size; var totalRead = 0;
for (var i = 0; i < size; i += chunkSize) {
final fileData = file.read(length: chunkSize); while (totalRead < size) {
await for (var form in fileData) { final remaining = size - totalRead;
localFile.add(form); final chunkSize = remaining > defaultChunkSize ? defaultChunkSize : remaining;
mainSendPort.send((i + form.length) / size * 100); dprint('Size: $size, Total Read: $totalRead, Chunk Size: $chunkSize');
final fileData = file.read(offset: totalRead, length: chunkSize);
await for (var chunk in fileData) {
localFile.add(chunk);
totalRead += chunk.length;
mainSendPort.send(totalRead / size * 100);
} }
} }

View File

@@ -4,10 +4,7 @@ extension _Init on SSHPageState {
void _initStoredCfg() { void _initStoredCfg() {
final fontFamilly = Stores.setting.fontPath.fetch().getFileName(); final fontFamilly = Stores.setting.fontPath.fetch().getFileName();
final textSize = Stores.setting.termFontSize.fetch(); final textSize = Stores.setting.termFontSize.fetch();
final textStyle = TextStyle( final textStyle = TextStyle(fontFamily: fontFamilly, fontSize: textSize);
fontFamily: fontFamilly,
fontSize: textSize,
);
_terminalStyle = TerminalStyle.fromTextStyle(textStyle); _terminalStyle = TerminalStyle.fromTextStyle(textStyle);
} }
@@ -37,15 +34,12 @@ extension _Init on SSHPageState {
onStatus: (p0) { onStatus: (p0) {
_writeLn(p0.toString()); _writeLn(p0.toString());
}, },
onKeyboardInteractive: _onKeyboardInteractive, onKeyboardInteractive: (_) => KeybordInteractive.defaultHandle(widget.args.spi, ctx: context),
); );
_writeLn('${libL10n.execute}: Shell'); _writeLn('${libL10n.execute}: Shell');
final session = await _client?.shell( final session = await _client?.shell(
pty: SSHPtyConfig( pty: SSHPtyConfig(width: _terminal.viewWidth, height: _terminal.viewHeight),
width: _terminal.viewWidth,
height: _terminal.viewHeight,
),
environment: widget.args.spi.envs, environment: widget.args.spi.envs,
); );
@@ -98,7 +92,10 @@ extension _Init on SSHPageState {
return; return;
} }
stream.cast<List<int>>().transform(const Utf8Decoder()).listen( stream
.cast<List<int>>()
.transform(const Utf8Decoder())
.listen(
_terminal.write, _terminal.write,
onError: (Object error, StackTrace stack) { onError: (Object error, StackTrace stack) {
// _terminal.write('Stream error: $error\n'); // _terminal.write('Stream error: $error\n');
@@ -109,9 +106,7 @@ extension _Init on SSHPageState {
} }
void _setupDiscontinuityTimer() { void _setupDiscontinuityTimer() {
_discontinuityTimer = Timer.periodic( _discontinuityTimer = Timer.periodic(const Duration(seconds: 5), (_) async {
const Duration(seconds: 5),
(_) async {
var throwTimeout = true; var throwTimeout = true;
Future.delayed(const Duration(seconds: 3), () { Future.delayed(const Duration(seconds: 3), () {
if (throwTimeout) { if (throwTimeout) {
@@ -120,8 +115,7 @@ extension _Init on SSHPageState {
}); });
await _client?.ping(); await _client?.ping();
throwTimeout = false; throwTimeout = false;
}, });
);
} }
void _catchTimeout() { void _catchTimeout() {

View File

@@ -164,8 +164,4 @@ extension _VirtKey on SSHPageState {
} }
} }
} }
FutureOr<List<String>?> _onKeyboardInteractive(SSHUserInfoRequest req) {
return KeybordInteractive.defaultHandle(widget.args.spi, ctx: context);
}
} }

View File

@@ -73,11 +73,24 @@ class _LocalFilePageState extends State<LocalFilePage> with AutomaticKeepAliveCl
}, },
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
), ),
if (!isMobile)
IconButton(
icon: const Icon(Icons.refresh),
tooltip: MaterialLocalizations.of(context).refreshIndicatorSemanticLabel,
onPressed: () => setState(() {}),
),
if (!isPickFile) _buildMissionBtn(), if (!isPickFile) _buildMissionBtn(),
_buildSortBtn(), _buildSortBtn(),
], ],
), ),
body: _sortType.listen(_buildBody), body: isMobile
? RefreshIndicator(
onRefresh: () async {
setState(() {});
},
child: _sortType.listen(_buildBody),
)
: _sortType.listen(_buildBody),
); );
} }

View File

@@ -537,7 +537,7 @@ extension _Actions on _SftpPageState {
/// Local file dir + server id + remote path /// Local file dir + server id + remote path
String _getLocalPath(String remotePath) { String _getLocalPath(String remotePath) {
return Paths.file.joinPath(widget.args.spi.id).joinPath(remotePath); return Paths.file.joinPath(widget.args.spi.oldId).joinPath(remotePath);
} }
/// Only return true if the path is changed /// Only return true if the path is changed

View File

@@ -324,7 +324,7 @@ packages:
source: hosted source: hosted
version: "0.3.4+2" version: "0.3.4+2"
crypto: crypto:
dependency: transitive dependency: "direct main"
description: description:
name: crypto name: crypto
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"

View File

@@ -12,29 +12,30 @@ dependencies:
sdk: flutter sdk: flutter
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
hive_ce_flutter: ^2.3.1 choice: ^2.3.2
crypto: ^3.0.6
dio: ^5.2.1 dio: ^5.2.1
easy_isolate: ^1.3.0
intl: ^0.20.2
highlight: ^0.7.0
flutter_highlight: ^0.7.0
re_editor: ^0.7.0
shared_preferences: ^2.1.1
dynamic_color: ^1.6.6 dynamic_color: ^1.6.6
xml: ^6.4.2 # for parsing nvidia-smi easy_isolate: ^1.3.0
flutter_displaymode: ^0.6.0
fl_chart: ^1.0.0
wakelock_plus: ^1.2.4
wake_on_lan: ^4.1.1+3
extended_image: ^10.0.0 extended_image: ^10.0.0
file_picker: ^10.1.9 file_picker: ^10.1.9
json_annotation: ^4.9.0
choice: ^2.3.2
webdav_client_plus: ^1.0.2
freezed_annotation: ^3.0.0
flutter_riverpod: ^2.6.1 flutter_riverpod: ^2.6.1
riverpod_annotation: ^2.6.1 flutter_highlight: ^0.7.0
flutter_displaymode: ^0.6.0
fl_chart: ^1.0.0
freezed_annotation: ^3.0.0
highlight: ^0.7.0
hive_ce_flutter: ^2.3.1
intl: ^0.20.2
json_annotation: ^4.9.0
responsive_framework: ^1.5.1 responsive_framework: ^1.5.1
re_editor: ^0.7.0
riverpod_annotation: ^2.6.1
shared_preferences: ^2.1.1
wakelock_plus: ^1.2.4
wake_on_lan: ^4.1.1+3
webdav_client_plus: ^1.0.2
xml: ^6.4.2 # for parsing nvidia-smi
dartssh2: dartssh2:
git: git:
url: https://github.com/lollipopkit/dartssh2 url: https://github.com/lollipopkit/dartssh2