Ad and purchases enabled (still need actual testing)
This commit is contained in:
parent
2fcc6dcab7
commit
faf319322a
35 changed files with 1676 additions and 34 deletions
|
|
@ -95,6 +95,16 @@ abstract class CloudStorageSession {
|
|||
/// if none exists. If duplicates exist, the earliest-created one wins.
|
||||
Future<String> findOrCreateFolder({required String parentId, required String name});
|
||||
|
||||
/// Relocates the existing folder [folderId] to be a child of
|
||||
/// [newParentId] instead of wherever it currently lives, preserving its
|
||||
/// contents and (name/subtree) intact. Used when the user picks a
|
||||
/// different location for the app's already-existing folder (see
|
||||
/// [CloudSyncService.selectAppFolder]), so its synced data and receipts
|
||||
/// move with it instead of being abandoned in place while a fresh, empty
|
||||
/// folder is created at the new location. Returns the folder's
|
||||
/// (possibly new, for a path-addressed provider) id.
|
||||
Future<String> moveFolder({required String folderId, required String newParentId});
|
||||
|
||||
/// Looks up a file's ID + versionTag by name within [folderId] without
|
||||
/// downloading its content, or null if no such file exists yet.
|
||||
Future<CloudFileInfo?> findFile({required String folderId, required String name});
|
||||
|
|
|
|||
|
|
@ -244,6 +244,17 @@ class DropboxSession implements CloudStorageSession {
|
|||
return childPath;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> moveFolder({required String folderId, required String newParentId}) async {
|
||||
final name = folderId.substring(folderId.lastIndexOf('/') + 1);
|
||||
final toPath = _childPath(newParentId, name);
|
||||
if (toPath == folderId) return folderId;
|
||||
|
||||
final json = await _post('/2/files/move_v2', {'from_path': folderId, 'to_path': toPath});
|
||||
final metadata = json['metadata'] as Map<String, dynamic>?;
|
||||
return metadata?['path_display'] as String? ?? toPath;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CloudFileInfo?> findFile({required String folderId, required String name}) async {
|
||||
final filePath = _childPath(folderId, name);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,20 @@ class GoogleDriveSession implements CloudStorageSession {
|
|||
return created.id!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> moveFolder({required String folderId, required String newParentId}) async {
|
||||
final current = await _api.files.get(folderId, $fields: 'parents') as drive.File;
|
||||
final oldParents = (current.parents ?? []).join(',');
|
||||
final updated = await _api.files.update(
|
||||
drive.File(),
|
||||
folderId,
|
||||
addParents: newParentId,
|
||||
removeParents: oldParents.isEmpty ? null : oldParents,
|
||||
$fields: 'id',
|
||||
);
|
||||
return updated.id ?? folderId;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CloudFileInfo?> findFile({required String folderId, required String name}) async {
|
||||
final result = await _api.files.list(
|
||||
|
|
|
|||
|
|
@ -245,6 +245,22 @@ class OneDriveSession implements CloudStorageSession {
|
|||
return created['id'] as String;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> moveFolder({required String folderId, required String newParentId}) async {
|
||||
final response = await http.patch(
|
||||
_graph('/me/drive/${_itemSegment(folderId)}'),
|
||||
headers: {...await _authHeader(), 'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
'parentReference': {'id': newParentId},
|
||||
}),
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw StateError('OneDrive API error (moveFolder): ${response.statusCode} ${response.body}');
|
||||
}
|
||||
final json = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
return json['id'] as String? ?? folderId;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CloudFileInfo?> findFile({required String folderId, required String name}) async {
|
||||
final uri = _graph('/me/drive/${_itemSegment(folderId)}:/$name');
|
||||
|
|
|
|||
|
|
@ -282,6 +282,22 @@ class WebDavSession implements CloudStorageSession {
|
|||
return childUri.path;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> moveFolder({required String folderId, required String newParentId}) async {
|
||||
final name = _nameFromPath(folderId);
|
||||
final destination = _childUri(_uriFor(newParentId), name);
|
||||
|
||||
final response = await _send('MOVE', _uriFor(folderId), headers: {
|
||||
'Authorization': _provider._authHeader,
|
||||
'Destination': destination.toString(),
|
||||
'Overwrite': 'F',
|
||||
});
|
||||
if (response.statusCode != 201 && response.statusCode != 204) {
|
||||
throw StateError('WebDAV MOVE failed: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
return destination.path;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CloudFileInfo?> findFile({required String folderId, required String name}) async {
|
||||
final fileUri = _childUri(_uriFor(folderId), name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue