@@ -16,6 +16,7 @@ import 'package:saber/i18n/strings.g.dart';
16
16
import 'package:saber/pages/editor/editor.dart' ;
17
17
import 'package:saver_gallery/saver_gallery.dart' ;
18
18
import 'package:share_plus/share_plus.dart' ;
19
+ import 'package:path/path.dart' as p;
19
20
20
21
/// A collection of cross-platform utility functions for working with a virtual file system.
21
22
class FileManager {
@@ -76,7 +77,7 @@ class FileManager {
76
77
log.fine ('Old data directory is empty or missing, nothing to migrate' );
77
78
} else {
78
79
await moveDirContents (oldDir: oldDir, newDir: newDir);
79
- await oldDir.delete ();
80
+ await oldDir.delete (recursive : true );
80
81
}
81
82
}
82
83
@@ -85,13 +86,33 @@ class FileManager {
85
86
required Directory newDir,
86
87
}) async {
87
88
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
+ }
95
116
}
96
117
}
97
118
}
0 commit comments