Fix device sync: folder status badges, remove-deletes-local, multi-select, header summary
Build APK / build (push) Successful in 5m35s
Build APK / build (push) Successful in 5m35s
- Folders now show the synced status badge themselves, not just their nested files - device-sync state never tracked folders individually, so syncStatusFor derives a folder's badge from whether its path falls within sync scope instead. - Turning sync off for a path now deletes its local mirror and clears its native sync-state entries (SyncEngine.removeLocalSync), instead of just stopping future updates and leaving the downloaded copy behind. - "Sync to device" in Files' selection toolbar now works over the whole selection at once instead of being gated to a single selected item. - The sync header's expanded panel shows real folder/item counts instead of a static "Synced" label that stayed accurate-sounding even before anything had actually synced. - Confirmation SnackBars on starting/stopping sync from both the selection toolbar and Settings' Device Sync card. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+43
-12
@@ -292,18 +292,15 @@ class _FilesViewState extends State<FilesView>
|
||||
label: 'Rename',
|
||||
onTap: () => _renameItem(selected.single),
|
||||
),
|
||||
if (selected.length == 1)
|
||||
SelectionAction(
|
||||
icon: sync.isPathSynced(selected.single.path)
|
||||
? Icons.sync_rounded
|
||||
: Icons.sync_outlined,
|
||||
label: sync.isPathSynced(selected.single.path)
|
||||
? 'Stop syncing to device'
|
||||
: 'Sync to device',
|
||||
onTap: () => sync.isPathSynced(selected.single.path)
|
||||
? sync.removeSyncedPath(selected.single.path)
|
||||
: sync.addSyncedPath(selected.single.path),
|
||||
),
|
||||
SelectionAction(
|
||||
icon: selected.every((i) => sync.isPathSynced(i.path))
|
||||
? Icons.sync_rounded
|
||||
: Icons.sync_outlined,
|
||||
label: selected.every((i) => sync.isPathSynced(i.path))
|
||||
? 'Stop syncing to device'
|
||||
: 'Sync to device',
|
||||
onTap: () => _toggleSyncSelected(context, sync, selected),
|
||||
),
|
||||
if (selected.length == 1)
|
||||
SelectionAction(
|
||||
icon: Icons.info_outline_rounded,
|
||||
@@ -807,6 +804,40 @@ class _FilesViewState extends State<FilesView>
|
||||
_clearSelection();
|
||||
}
|
||||
|
||||
/// Toggles device sync for every selected item at once - if they're all
|
||||
/// already synced this stops syncing all of them (and deletes their local
|
||||
/// mirrors, see `SyncStatusController.removeSyncedPath`), otherwise it
|
||||
/// starts syncing whichever ones aren't synced yet.
|
||||
void _toggleSyncSelected(
|
||||
BuildContext context,
|
||||
SyncStatusController sync,
|
||||
List<NextcloudItem> items,
|
||||
) {
|
||||
final allSynced = items.every((i) => sync.isPathSynced(i.path));
|
||||
if (allSynced) {
|
||||
for (final item in items) {
|
||||
sync.removeSyncedPath(item.path);
|
||||
}
|
||||
} else {
|
||||
for (final item in items) {
|
||||
if (!sync.isPathSynced(item.path)) {
|
||||
sync.addSyncedPath(item.path, isFolder: item.isFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
_clearSelection();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
allSynced
|
||||
? 'Removed ${items.length} item(s) from device sync'
|
||||
: 'Syncing ${items.length} item(s) to this device',
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Hands the whole batch off to `DownloadService.kt` (see its doc
|
||||
/// comment) rather than downloading each item in Dart then prompting
|
||||
/// `file_saver` per file - same reasoning as `UploadService`/
|
||||
|
||||
Reference in New Issue
Block a user