Skip to content

Commit 805becc

Browse files
committed
fix: Correct migration procedure
Otherwise it keeps creating oldDir's child folders inside themselves indefinitely.
1 parent 2d30393 commit 805becc

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

lib/data/file_manager/file_manager.dart

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:saber/i18n/strings.g.dart';
1616
import 'package:saber/pages/editor/editor.dart';
1717
import 'package:saver_gallery/saver_gallery.dart';
1818
import 'package:share_plus/share_plus.dart';
19+
import 'package:path/path.dart' as p;
1920

2021
/// A collection of cross-platform utility functions for working with a virtual file system.
2122
class FileManager {
@@ -76,7 +77,7 @@ class FileManager {
7677
log.fine('Old data directory is empty or missing, nothing to migrate');
7778
} else {
7879
await moveDirContents(oldDir: oldDir, newDir: newDir);
79-
await oldDir.delete();
80+
await oldDir.delete(recursive: true);
8081
}
8182
}
8283

@@ -85,13 +86,33 @@ class FileManager {
8586
required Directory newDir,
8687
}) async {
8788
await newDir.create(recursive: true);
88-
await for (final entity in oldDir.list()) {
89-
final entityPath = '${newDir.path}/${entity.path.split('/').last}';
90-
switch (entity) {
91-
case File _:
92-
await entity.rename(entityPath);
93-
case Directory _:
94-
await moveDirContents(oldDir: oldDir, newDir: Directory(entityPath));
89+
90+
await for (final entity in oldDir.list(recursive: true)) {
91+
// Get the path under oldDir and map it into newDir.
92+
final relative = p.relative(entity.path, from: oldDir.path);
93+
final targetPath = p.join(newDir.path, relative);
94+
95+
if (entity is Directory) {
96+
await Directory(targetPath).create(recursive: true);
97+
continue;
98+
}
99+
100+
if (entity is File) {
101+
// Ensure parent exists
102+
await Directory(p.dirname(targetPath)).create(recursive: true);
103+
104+
try {
105+
await entity.rename(targetPath);
106+
} on FileSystemException catch (e) {
107+
// Cross device move, eg. private to public on android
108+
const exdev = 18;
109+
if (e.osError?.errorCode == exdev) {
110+
await entity.copy(targetPath);
111+
await entity.delete();
112+
} else {
113+
rethrow;
114+
}
115+
}
95116
}
96117
}
97118
}

0 commit comments

Comments
 (0)