diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index b16d5b84..a5047905 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -968,6 +968,18 @@ abstract class S { /// **'Open'** String get open; + /// No description provided for @openLastPath. + /// + /// In en, this message translates to: + /// **'Open the last path'** + String get openLastPath; + + /// No description provided for @openLastPathTip. + /// + /// In en, this message translates to: + /// **'Different servers will have different logs, and the log is the path to the exit'** + String get openLastPathTip; + /// No description provided for @paste. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index 449f6270..73c0db1e 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -461,6 +461,12 @@ class SDe extends S { @override String get open => 'Öffnen'; + @override + String get openLastPath => 'Öffnen Sie den letzten Pfad'; + + @override + String get openLastPathTip => 'Verschiedene Server haben unterschiedliche Einträge, und der Eintrag ist der Pfad zum Ausgang'; + @override String get paste => 'Einfügen'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 3312c437..b24d0d9a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -461,6 +461,12 @@ class SEn extends S { @override String get open => 'Open'; + @override + String get openLastPath => 'Open the last path'; + + @override + String get openLastPathTip => 'Different servers will have different logs, and the log is the path to the exit'; + @override String get paste => 'Paste'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart index 31375585..46c6119b 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart @@ -461,6 +461,12 @@ class SId extends S { @override String get open => 'Membuka'; + @override + String get openLastPath => 'Buka jalur terakhir'; + + @override + String get openLastPathTip => 'Server yang berbeda akan memiliki catatan yang berbeda, dan catatan tersebut adalah jalur menuju pintu keluar'; + @override String get paste => 'Tempel'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index 0c315f5e..d4d67a68 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -461,6 +461,12 @@ class SZh extends S { @override String get open => '打开'; + @override + String get openLastPath => '打开上次的路径'; + + @override + String get openLastPathTip => '不同的服务器会有不同的记录,且记录的是退出时的路径'; + @override String get paste => '粘贴'; @@ -1211,6 +1217,12 @@ class SZhTw extends SZh { @override String get open => '打開'; + @override + String get openLastPath => '打開上次的路徑'; + + @override + String get openLastPathTip => '不同的服務器會有不同的記錄,且記錄的是退出時的路徑'; + @override String get paste => '貼上'; diff --git a/lib/data/store/history.dart b/lib/data/store/history.dart index 7f424365..8eaa83f2 100644 --- a/lib/data/store/history.dart +++ b/lib/data/store/history.dart @@ -1,16 +1,18 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:toolbox/core/persistant_store.dart'; -typedef _HistoryType = List; + +typedef _HistoryList = List; +typedef _HistoryMap = Map; /// index from 0 -> n : latest -> oldest -class _History { - final _HistoryType _history; +class _ListHistory { + final _HistoryList _history; final String _name; - final Box<_HistoryType> _box; + final Box _box; - _History({ - required Box<_HistoryType> box, + _ListHistory({ + required Box box, required String name, }) : _box = box, _name = name, @@ -22,11 +24,34 @@ class _History { _box.put(_name, _history); } - _HistoryType get all => _history; + _HistoryList get all => _history; } -class HistoryStore extends PersistentStore<_HistoryType> { - late final _History sftpPath = _History(box: box, name: 'sftpPath'); +class _MapHistory { + final _HistoryMap _history; + final String _name; + final Box _box; - late final _History sshCmds = _History(box: box, name: 'sshCmds'); + _MapHistory({ + required Box box, + required String name, + }) : _box = box, + _name = name, + _history = box.get(name, defaultValue: {})!; + + void put(String id, String val) { + _history[id] = val; + _box.put(_name, _history); + } + + String? fetch(String id) => _history[id]; +} + +class HistoryStore extends PersistentStore { + /// Paths that user has visited by 'Locate' button + late final sftpGoPath = _ListHistory(box: box, name: 'sftpPath'); + + late final sftpLastPath = _MapHistory(box: box, name: 'sftpLastPath'); + + late final sshCmds = _ListHistory(box: box, name: 'sshCmds'); } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index dc534b7e..8ae56db9 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -215,6 +215,9 @@ class SettingStore extends PersistentStore { /// The performance of highlight is bad late final editorHighlight = StoreProperty(box, 'editorHighlight', true); + /// Open SFTP with last viewed path + late final sftpOpenLastPath = StoreProperty(box, 'sftpOpenLastPath', true); + // Never show these settings for users // // ------BEGIN------ diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 65db8feb..3f07a2f2 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -145,6 +145,8 @@ "ok": "OK", "onServerDetailPage": "in Detailansicht des Servers", "open": "Öffnen", + "openLastPath": "Öffnen Sie den letzten Pfad", + "openLastPathTip": "Verschiedene Server haben unterschiedliche Einträge, und der Eintrag ist der Pfad zum Ausgang", "paste": "Einfügen", "path": "Pfad", "percentOfSize": "{percent}% von {size}", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5ec704cc..9ed37362 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -145,6 +145,8 @@ "ok": "OK", "onServerDetailPage": "On server detail page", "open": "Open", + "openLastPath": "Open the last path", + "openLastPathTip": "Different servers will have different logs, and the log is the path to the exit", "paste": "Paste", "path": "Path", "percentOfSize": "{percent}% of {size}", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 9d14dd49..78c43f83 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -145,6 +145,8 @@ "ok": "OKE", "onServerDetailPage": "Di halaman detail server", "open": "Membuka", + "openLastPath": "Buka jalur terakhir", + "openLastPathTip": "Server yang berbeda akan memiliki catatan yang berbeda, dan catatan tersebut adalah jalur menuju pintu keluar", "paste": "Tempel", "path": "Jalur", "percentOfSize": "{percent}% dari {size}", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 5421bc70..2d523bf9 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -145,6 +145,8 @@ "ok": "好", "onServerDetailPage": "在服务器详情页", "open": "打开", + "openLastPath": "打开上次的路径", + "openLastPathTip": "不同的服务器会有不同的记录,且记录的是退出时的路径", "paste": "粘贴", "path": "路径", "percentOfSize": "{size} 的 {percent}%", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index dcba2c5f..d264e574 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -145,6 +145,8 @@ "ok": "好", "onServerDetailPage": "在服務器詳情頁", "open": "打開", + "openLastPath": "打開上次的路徑", + "openLastPathTip": "不同的服務器會有不同的記錄,且記錄的是退出時的路徑", "paste": "貼上", "path": "路徑", "percentOfSize": "{size} 的 {percent}%", diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index c80f309e..ad447dc7 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -156,6 +156,8 @@ class _SettingPageState extends State { _buildServer(), _buildTitle('SSH'), _buildSSH(), + _buildTitle('SFTP'), + _buildSFTP(), _buildTitle(l10n.editor), _buildEditor(), _buildTitle(l10n.fullScreen), @@ -230,7 +232,6 @@ class _SettingPageState extends State { // Use hardware keyboard on desktop, so there is no need to set it if (isMobile) _buildKeyboardType(), _buildSSHVirtKeys(), - _buildSftpRmrDir(), ].map((e) => RoundRectCard(e)).toList(), ); } @@ -842,6 +843,23 @@ class _SettingPageState extends State { ); } + Widget _buildSFTP() { + return Column( + children: [ + _buildSftpRmrDir(), + _buildSftpOpenLastPath(), + ].map((e) => RoundRectCard(e)).toList(), + ); + } + + Widget _buildSftpOpenLastPath() { + return ListTile( + title: Text(l10n.openLastPath), + subtitle: Text(l10n.openLastPathTip, style: UIs.textGrey), + trailing: StoreSwitch(prop: _setting.sftpOpenLastPath), + ); + } + Widget _buildNetViewType() { final items = NetViewType.values .map((e) => PopupMenuItem( diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index 68f64773..8f206644 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -647,6 +647,12 @@ class _SftpPageState extends State with AfterLayoutMixin { _status.files = fs; }); context.pop(); + + // Only update history when success + if (Stores.setting.sftpOpenLastPath.fetch()) { + Stores.history.sftpLastPath.put(widget.spi.id, listPath); + } + return true; } return false; @@ -679,7 +685,14 @@ class _SftpPageState extends State with AfterLayoutMixin { @override FutureOr afterFirstLayout(BuildContext context) { - _status.path = AbsolutePath(widget.initPath ?? '/'); + var initPath = '/'; + if (Stores.setting.sftpOpenLastPath.fetch()) { + final history = Stores.history.sftpLastPath.fetch(widget.spi.id); + if (history != null) { + initPath = history; + } + } + _status.path = AbsolutePath(widget.initPath ?? initPath); _listDir(); } }