fix(fs): file transfer, reconnect, restore dir (#14925)

* fix(fs): file transfer, reconnect, restore dir

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2026-05-10 10:08:29 +08:00
committed by GitHub
parent b757e97c11
commit 9c831dc59b

View File

@@ -391,14 +391,30 @@ class FileController {
await Future.delayed(Duration(milliseconds: 100)); await Future.delayed(Duration(milliseconds: 100));
final dir = (await bind.sessionGetPeerOption( final savedDir = (await bind.sessionGetPeerOption(
sessionId: sessionId, name: isLocal ? "local_dir" : "remote_dir")); sessionId: sessionId, name: isLocal ? "local_dir" : "remote_dir"));
openDirectory(dir.isEmpty ? options.value.home : dir); Future<bool> tryOpenReadyDirs() async {
final dirs = <String>{
if (directory.value.path.isNotEmpty) directory.value.path,
if (savedDir.isNotEmpty) savedDir,
options.value.home,
};
for (final dir in dirs) {
if (await _openDirectoryPath(dir, isBack: true)) {
return true;
}
}
return false;
}
var opened = await tryOpenReadyDirs();
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
if (directory.value.path.isEmpty) { if (!opened) {
openDirectory(options.value.home); // The peer may become ready during the reconnect delay, so retry the
// same candidates instead of only retrying the default home directory.
await tryOpenReadyDirs();
} }
} }
@@ -429,19 +445,23 @@ class FileController {
}); });
} }
Future<void> refresh() async { Future<bool> refresh() async {
await openDirectory(directory.value.path); // "." can be both a refresh command and a real remote directory path.
// Refresh must bypass openDirectory's command dispatch to avoid recursion.
return await _openDirectoryPath(directory.value.path, isBack: true);
} }
Future<void> openDirectory(String path, {bool isBack = false}) async { Future<bool> openDirectory(String path, {bool isBack = false}) async {
if (path == ".") { if (!isBack && path == ".") {
refresh(); return await refresh();
return;
} }
if (path == "..") { if (!isBack && path == "..") {
goToParentDirectory(); return await _goToParentDirectory(isBack: isBack);
return;
} }
return await _openDirectoryPath(path, isBack: isBack);
}
Future<bool> _openDirectoryPath(String path, {bool isBack = false}) async {
if (!isBack) { if (!isBack) {
pushHistory(); pushHistory();
} }
@@ -458,8 +478,10 @@ class FileController {
final fd = await fileFetcher.fetchDirectory(path, isLocal, showHidden); final fd = await fileFetcher.fetchDirectory(path, isLocal, showHidden);
fd.format(isWindows, sort: sortBy.value); fd.format(isWindows, sort: sortBy.value);
directory.value = fd; directory.value = fd;
return true;
} catch (e) { } catch (e) {
debugPrint("Failed to openDirectory $path: $e"); debugPrint("Failed to openDirectory $path: $e");
return false;
} }
} }
@@ -487,19 +509,22 @@ class FileController {
goBack(); goBack();
return; return;
} }
openDirectory(path, isBack: true); unawaited(_openDirectoryPath(path, isBack: true).then<void>((_) {}));
} }
void goToParentDirectory() { void goToParentDirectory() {
unawaited(_goToParentDirectory().then<void>((_) {}));
}
Future<bool> _goToParentDirectory({bool isBack = false}) async {
final isWindows = options.value.isWindows; final isWindows = options.value.isWindows;
final dirPath = directory.value.path; final dirPath = directory.value.path;
var parent = PathUtil.dirname(dirPath, isWindows); var parent = PathUtil.dirname(dirPath, isWindows);
// specially for C:\, D:\, goto '/' // specially for C:\, D:\, goto '/'
if (parent == dirPath && isWindows) { if (parent == dirPath && isWindows) {
openDirectory('/'); return await _openDirectoryPath('/', isBack: isBack);
return;
} }
openDirectory(parent); return await _openDirectoryPath(parent, isBack: isBack);
} }
// TODO deprecated this // TODO deprecated this