feat(mobile): review remote-trashed assets before syncing deletions on Android#28280
Open
PeterOmbodi wants to merge 264 commits into
Open
feat(mobile): review remote-trashed assets before syncing deletions on Android#28280PeterOmbodi wants to merge 264 commits into
PeterOmbodi wants to merge 264 commits into
Conversation
- Refactor TrashSyncService and ActionService - Respect isSyncApproved value in timeline.trashSyncReview - Use i18n values instead of hardcoded strings - Close review page when out-of-sync record count reaches 0
…ash, isApproved → allow
refactor code
refactor outOfSyncCountProvider create appSettingStreamProvider ImmichToast: add warning mode, add onTap callback refactor code
allow/deny buttons on asset preview (draft)
…ssets_v2 # Conflicts: # i18n/en.json # mobile/drift_schemas/main/drift_schema_v7.json # mobile/lib/infrastructure/repositories/db.repository.dart # mobile/lib/infrastructure/repositories/db.repository.drift.dart # mobile/lib/infrastructure/repositories/db.repository.steps.dart # mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart # mobile/lib/routing/router.dart # mobile/test/drift/main/generated/schema.dart # mobile/test/drift/main/generated/schema_v7.dart
show warning mark on avatar instead rework out-of-sync button
…ssets_v2 # Conflicts: # i18n/en.json # mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart # mobile/lib/widgets/common/app_bar_dialog/app_bar_dialog.dart # mobile/lib/widgets/common/immich_sliver_app_bar.dart # mobile/lib/widgets/settings/advanced_settings.dart
…sync_assets_v2 # Conflicts: # mobile/lib/domain/services/sync_stream.service.dart # mobile/lib/domain/services/trash_sync.service.dart
refactor trash_sync service, action service add label for Deny/Allow actions buttons
delete LocalAssetEntity records when moved to trash refactor code
refactro code
…rashed_state # Conflicts: # mobile/test/domain/services/sync_stream_service_test.dart
…n flow - Add new `local_trashed_asset` table to store metadata of trashed assets - Save trashed asset info into `local_trashed_asset` before deletion - Use `local_trashed_asset` as source for asset restoration - Implement file restoration by `mediaId`
…rashed_state # Conflicts: # mobile/drift_schemas/main/drift_schema_v10.json # mobile/lib/infrastructure/repositories/db.repository.dart # mobile/lib/infrastructure/repositories/db.repository.drift.dart # mobile/lib/infrastructure/repositories/db.repository.steps.dart # mobile/test/drift/main/generated/schema_v10.dart
added 5 commits
May 7, 2026 10:40
Rename the local asset lookup to clarify remote trash candidate behavior and exclude assets that already have accepted or rejected trash sync decisions. Defer approving trash sync entries until local trash processing completes, and avoid updating rejected entries during candidate upserts. Add repository and service test coverage for the updated trash sync flow.
update action service tests for success, failure, and partial-delete cases.
use `AssetMediaRepository.deleteAll` for automatic remote trash handling update sync stream tests
added 2 commits
May 7, 2026 18:04
move manage media operations into `AssetMediaRepository` and remove the separate local files manager repository/service. remove unused Pigeon methods.
# Conflicts: # mobile/drift_schemas/main/drift_schema_v25.json # mobile/lib/domain/models/store.model.dart # mobile/lib/infrastructure/repositories/db.repository.dart # mobile/lib/infrastructure/repositories/db.repository.drift.dart # mobile/lib/infrastructure/repositories/db.repository.steps.dart # mobile/lib/services/app_settings.service.dart # mobile/lib/widgets/settings/advanced_settings.dart # mobile/test/drift/main/generated/schema_v25.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR adds a new Review remote deletions option for Android remote deletion sync.
It is based on the work from the previous review-related PRs:
The existing Android remote deletion sync behavior is preserved. The new option is added next to the existing modes:
MANAGE_MEDIAis available.Behavior
On Android, when a remote asset is moved to trash or permanently deleted remotely, the mobile app can detect matching local assets in backup-selected albums.
With Review remote deletions enabled, matching local assets that are currently in backup-selected albums are shown in a review queue instead of being moved automatically. The user can then:
If album backup selection changes after a remote trash intent was recorded, the review page only shows and applies decisions to matching local assets that are still in backup-selected albums.
Remote restore events can restore matching local trashed assets when the selected mode allows it and the app has the required Android media permission.
Technical Notes
Trash sync flow
The implementation separates remote trash intent handling from local trash snapshot reconciliation:
SyncStreamServiceowns remote trash/restore events from the sync stream.LocalSyncServiceowns Android local trash snapshot reconciliation.trashSyncEntitystores current review decisions for remote trash intents.trashedLocalAssetEntitystores current known local trash state.Remote trash events
SyncStreamServicehandles remote trash intents while remote ids and deleted timestamps are still available.For remote asset trash/delete events:
AssetMediaRepository.deleteAllwhenMANAGE_MEDIAis available.deleteAllare recorded as locally trashed.trashSyncEntityas review candidates so they can be surfaced in review mode.Review decisions
ActionService.resolveRemoteTrashapplies explicit user decisions:AssetMediaRepository.deleteAll, records successfully moved assets in local trash state, then marks those checksums as approved.The approval update happens after local trash state is written, because approved rows are excluded from future candidate lookup.
Local trash snapshot sync
LocalSyncServicedoes not derive remote trash candidates.It reconciles the Android local trash snapshot:
trashedLocalAssetEntity.Cleanup rules
trashSyncEntityis a current review queue, not a history table.Rows are cleaned when:
Approved/rejected decisions suppress repeated remote delete or permanent-delete events until a remote restore invalidates the decision.
Testing
Tested with updated unit/repository coverage for:
Manual test path:
Review decision branches:
Album selection branch:
Automatic sync regression branch:
Remote restore regression branch:
Checklist:
src/services/uses repositories implementations for database calls, filesystem operations, etc.src/repositories/is pretty basic/simple and does not have any immich specific logic (that belongs insrc/services/)Please describe to which degree, if any, an LLM was used in creating this pull request.
An LLM was used to review chages and draft this PR description.