mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
new: sftp jump history
This commit is contained in:
32
lib/data/store/history.dart
Normal file
32
lib/data/store/history.dart
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
import 'package:toolbox/core/persistant_store.dart';
|
||||||
|
|
||||||
|
typedef _HistoryType = List<String>;
|
||||||
|
|
||||||
|
/// index from 0 -> n : latest -> oldest
|
||||||
|
class _History {
|
||||||
|
final _HistoryType _history;
|
||||||
|
final String _name;
|
||||||
|
final Box<_HistoryType> _box;
|
||||||
|
|
||||||
|
_History({
|
||||||
|
required Box<_HistoryType> box,
|
||||||
|
required String name,
|
||||||
|
}) : _box = box,
|
||||||
|
_name = name,
|
||||||
|
_history = box.get(name, defaultValue: <String>[])!;
|
||||||
|
|
||||||
|
void add(String path) {
|
||||||
|
_history.remove(path);
|
||||||
|
_history.insert(0, path);
|
||||||
|
_box.put(_name, _history);
|
||||||
|
}
|
||||||
|
|
||||||
|
_HistoryType get all => _history;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HistoryStore extends PersistentStore<_HistoryType> {
|
||||||
|
late final _History sftpPath = _History(box: box, name: 'sftpPath');
|
||||||
|
|
||||||
|
late final _History sshCmds = _History(box: box, name: 'sshCmds');
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import 'data/provider/snippet.dart';
|
|||||||
import 'data/provider/virtual_keyboard.dart';
|
import 'data/provider/virtual_keyboard.dart';
|
||||||
import 'data/service/app.dart';
|
import 'data/service/app.dart';
|
||||||
import 'data/store/docker.dart';
|
import 'data/store/docker.dart';
|
||||||
|
import 'data/store/history.dart';
|
||||||
import 'data/store/private_key.dart';
|
import 'data/store/private_key.dart';
|
||||||
import 'data/store/server.dart';
|
import 'data/store/server.dart';
|
||||||
import 'data/store/setting.dart';
|
import 'data/store/setting.dart';
|
||||||
@@ -54,6 +55,10 @@ Future<void> _setupLocatorForStores() async {
|
|||||||
final docker = DockerStore();
|
final docker = DockerStore();
|
||||||
await docker.init(boxName: 'docker');
|
await docker.init(boxName: 'docker');
|
||||||
locator.registerSingleton(docker);
|
locator.registerSingleton(docker);
|
||||||
|
|
||||||
|
final history = HistoryStore();
|
||||||
|
await history.init(boxName: 'history');
|
||||||
|
locator.registerSingleton(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setupLocator() async {
|
Future<void> setupLocator() async {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:logging/logging.dart';
|
|||||||
import 'package:toolbox/core/extension/navigator.dart';
|
import 'package:toolbox/core/extension/navigator.dart';
|
||||||
import 'package:toolbox/core/extension/sftpfile.dart';
|
import 'package:toolbox/core/extension/sftpfile.dart';
|
||||||
import 'package:toolbox/data/res/misc.dart';
|
import 'package:toolbox/data/res/misc.dart';
|
||||||
|
import 'package:toolbox/data/store/history.dart';
|
||||||
import 'package:toolbox/view/page/editor.dart';
|
import 'package:toolbox/view/page/editor.dart';
|
||||||
import 'package:toolbox/view/page/storage/local.dart';
|
import 'package:toolbox/view/page/storage/local.dart';
|
||||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||||
@@ -52,6 +53,7 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
final SftpBrowserStatus _status = SftpBrowserStatus();
|
final SftpBrowserStatus _status = SftpBrowserStatus();
|
||||||
|
|
||||||
final _sftp = locator<SftpProvider>();
|
final _sftp = locator<SftpProvider>();
|
||||||
|
final _history = locator<HistoryStore>();
|
||||||
|
|
||||||
late S _s;
|
late S _s;
|
||||||
|
|
||||||
@@ -156,7 +158,6 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final idx = await showRoundDialog(
|
final idx = await showRoundDialog(
|
||||||
context: context,
|
context: context,
|
||||||
title: Text(_s.choose),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -224,12 +225,6 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
onTap: () => _newFile(context)),
|
onTap: () => _newFile(context)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => context.pop(),
|
|
||||||
child: Text(_s.close),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)),
|
)),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
);
|
);
|
||||||
@@ -242,31 +237,30 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
final p = await showRoundDialog<String>(
|
final p = await showRoundDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
title: Text(_s.goto),
|
title: Text(_s.goto),
|
||||||
child: Column(
|
child: Autocomplete<String>(
|
||||||
mainAxisSize: MainAxisSize.min,
|
optionsBuilder: (val) => _history.sftpPath.all.where(
|
||||||
children: [
|
(element) => element.contains(val.text),
|
||||||
Input(
|
),
|
||||||
|
fieldViewBuilder: (_, controller, node, __) {
|
||||||
|
return Input(
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
icon: Icons.abc,
|
icon: Icons.abc,
|
||||||
label: _s.path,
|
label: _s.path,
|
||||||
|
node: node,
|
||||||
|
controller: controller,
|
||||||
onSubmitted: (value) => context.pop(value),
|
onSubmitted: (value) => context.pop(value),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => context.pop(),
|
|
||||||
child: Text(_s.close),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// p == null || p.isEmpty
|
if (p == null || p.isEmpty) {
|
||||||
if (p?.isEmpty ?? true) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_status.path?.update(p!);
|
|
||||||
_listDir(path: p);
|
_status.path?.update(p);
|
||||||
|
final suc = await _listDir(path: p);
|
||||||
|
if (suc) _history.sftpPath.add(p);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.gps_fixed),
|
icon: const Icon(Icons.gps_fixed),
|
||||||
);
|
);
|
||||||
@@ -624,9 +618,10 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
return '${(await sftpDir).path}$remotePath';
|
return '${(await sftpDir).path}$remotePath';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _listDir({String? path, SSHClient? client}) async {
|
/// Only return true if the path is changed
|
||||||
|
Future<bool> _listDir({String? path, SSHClient? client}) async {
|
||||||
if (_status.isBusy) {
|
if (_status.isBusy) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
_status.isBusy = true;
|
_status.isBusy = true;
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
@@ -657,7 +652,9 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
_status.files = fs;
|
_status.files = fs;
|
||||||
_status.isBusy = false;
|
_status.isBusy = false;
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
} catch (e, trace) {
|
} catch (e, trace) {
|
||||||
_logger.warning('list dir failed', e, trace);
|
_logger.warning('list dir failed', e, trace);
|
||||||
await _backward();
|
await _backward();
|
||||||
@@ -675,6 +672,7 @@ class _SftpPageState extends State<SftpPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user