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));
final dir = (await bind.sessionGetPeerOption(
final savedDir = (await bind.sessionGetPeerOption(
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));
if (directory.value.path.isEmpty) {
openDirectory(options.value.home);
if (!opened) {
// 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 {
await openDirectory(directory.value.path);
Future<bool> refresh() async {
// "." 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 {
if (path == ".") {
refresh();
return;
Future<bool> openDirectory(String path, {bool isBack = false}) async {
if (!isBack && path == ".") {
return await refresh();
}
if (path == "..") {
goToParentDirectory();
return;
if (!isBack && path == "..") {
return await _goToParentDirectory(isBack: isBack);
}
return await _openDirectoryPath(path, isBack: isBack);
}
Future<bool> _openDirectoryPath(String path, {bool isBack = false}) async {
if (!isBack) {
pushHistory();
}
@@ -458,8 +478,10 @@ class FileController {
final fd = await fileFetcher.fetchDirectory(path, isLocal, showHidden);
fd.format(isWindows, sort: sortBy.value);
directory.value = fd;
return true;
} catch (e) {
debugPrint("Failed to openDirectory $path: $e");
return false;
}
}
@@ -487,19 +509,22 @@ class FileController {
goBack();
return;
}
openDirectory(path, isBack: true);
unawaited(_openDirectoryPath(path, isBack: true).then<void>((_) {}));
}
void goToParentDirectory() {
unawaited(_goToParentDirectory().then<void>((_) {}));
}
Future<bool> _goToParentDirectory({bool isBack = false}) async {
final isWindows = options.value.isWindows;
final dirPath = directory.value.path;
var parent = PathUtil.dirname(dirPath, isWindows);
// specially for C:\, D:\, goto '/'
if (parent == dirPath && isWindows) {
openDirectory('/');
return;
return await _openDirectoryPath('/', isBack: isBack);
}
openDirectory(parent);
return await _openDirectoryPath(parent, isBack: isBack);
}
// TODO deprecated this