feat(mobile): add review mode for remote trash sync - #30275
Open
PeterOmbodi wants to merge 20 commits into
Open
Conversation
PeterOmbodi
requested review from
agg23,
santoshakil and
shenlong-tanwen
as code owners
July 27, 2026 13:39
PeterOmbodi
marked this pull request as draft
July 27, 2026 13:40
Contributor
|
📖 Documentation deployed to docs.pr-30275.preview.immich.app |
PeterOmbodi
force-pushed
the
feature/trash-sync-review-v3
branch
from
July 28, 2026 08:12
ad79cdc to
58ab96a
Compare
shenlong-tanwen
force-pushed
the
refactor/auto-trash-sync
branch
from
July 28, 2026 10:41
aa6e6f4 to
2fa33ad
Compare
added 6 commits
July 28, 2026 15:10
Adds review mode for remote trash changes on top of the auto trash sync flow: - add trash sync mode config and advanced settings selector - record pending review markers for soft and hard remote deletions - add trash review timeline, route, bottom bar, and viewer actions - resolve review decisions by checksum, including duplicate local copies - group review timeline by remote/server timeline date - add i18n strings and coverage for settings, providers, actions, timeline, and repositories
PeterOmbodi
force-pushed
the
feature/trash-sync-review-v3
branch
from
July 28, 2026 12:17
58ab96a to
d2ddc12
Compare
added 5 commits
July 28, 2026 18:49
- apply review decisions and partial results per local asset ID - build the review timeline and counts from local asset markers - simplify Drift queries and review status updates - group and count review items by local asset - remove the unused server deletion timeline timestamp - add coverage for mode switches, duplicates, partial failures, and restore
Contributor
|
This PR has been automatically closed as the description doesn't follow our template. After you edit it to match the template, the PR will automatically be reopened. |
added 6 commits
August 10, 2026 15:51
…eady-reviewed rows
PeterOmbodi
marked this pull request as ready for review
August 11, 2026 13:25
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 Review mode for syncing remote trash changes to local assets in the mobile app.
It builds on the automatic trash and restore synchronization introduced in #29922 and reimplements the review flow previously developed in #23992, #27785, and #28280 on top of the new trash sync architecture.
Users can choose how remote trash changes are handled:
Off — ignore remote trash changes
Auto sync — automatically apply supported trash and restore changes locally where supported
Review — collect affected local assets for manual review before applying remote deletions
Android shows the full mode selector. iOS shows a single “Review remote deletions” toggle, since Auto sync is not available there.
Review mode gives users explicit control over whether a remote deletion should also be applied to media on their device.
Review flow
When Review mode is enabled and an asset is moved to trash or permanently deleted remotely:
Each local asset is reviewed independently. Checksum is used to correlate remote deletion state with local content, while local asset ID identifies the review item and its decision.
Keep on device
Keeps the selected local assets unchanged and marks their pending review items as rejected.
The decision remains valid for those local asset IDs while the matching content stays deleted remotely. If the remote asset is restored, the decisions are cleared so a later deletion can be reviewed again.
Other local copies with the same checksum remain independent review items.
Move to trash
Applies the remote deletion to the selected actionable local assets.
Each asset is processed independently. Successfully handled assets are marked as approved and removed from the local asset database. Assets that the platform media API fails to process remain pending and can be retried.
Backup album selection
Only local assets in albums currently selected for backup are counted, displayed, and affected by review actions.
If an album is removed from backup selection, its unresolved assets disappear from the actionable review list. Re-selecting the album makes them available again while the underlying remote deletion is still active.
Backup selection affects actionability and does not remove the underlying pending marker or review decision.
Platform behaviour
On Android, the available modes are Off, Auto sync, and Review.
Review mode can be enabled without Media Management Access, but moving assets to trash may require additional system confirmation. Remote restores are applied automatically only when the permission is available.
On iOS, the available modes are Off and Review. Auto sync and local trash restore are not offered because iOS does not expose a manageable local trash state equivalent to Android MediaStore.
Review timeline
The review page uses the standard mobile timeline with review-specific behaviour:
Technical details
Configuration
The previous boolean
trashSyncEnabledsetting is replaced byTrashSyncConfigwith aTrashSyncMode:offautoSyncreviewExisting values are migrated as follows:
trashSyncEnabled: true→TrashSyncMode.autoSynctrashSyncEnabled: false→TrashSyncMode.offThe legacy setting key remains compatible and maps to Auto sync or Off.
Recording review candidates
Review mode uses the existing
TrashSyncStatus.pendingstatus for unresolved assets.Auto sync and Review share the same pending backlog. Switching from Review to Auto processes unresolved candidates automatically, while switching from Auto to Review exposes unresolved candidates for a user decision.
The implementation adds two decision states:
reviewRejectedreviewApprovedReview candidates are recorded for:
remoteAssetEntityserverDeletedChecksumEntityRemote deletion state is matched to local content by checksum. A separate marker is then stored for every matching local asset ID in a backup-selected album.
An existing approved or rejected decision excludes only the same local asset ID. Other local copies with the same checksum remain independently reviewable.
Candidate discovery uses correlated queries rather than joining every matching remote row. This prevents duplicate local candidates when the same checksum exists in multiple server libraries.
Permanent deletions
A remote asset row may be removed before the review flow processes a permanent deletion.
serverDeletedChecksumEntityretains the checksum so matching local assets can still be discovered after the remote row is removed.Timeline placement does not require retained remote metadata. Review items use the local asset creation date.
Review decisions
The review timeline, pending count, and review actions operate on local asset IDs.
Keep on device changes actionable pending rows for the selected local asset IDs to
reviewRejected.Move to trash:
AssetMediaRepository.deleteAll.reviewApproved.localAssetEntity.The platform result is handled per local asset. A partial success does not approve or remove assets that failed to move to trash.
Approved markers retain the checksum and local asset update time required by the existing restore reconciliation flow.
Cleanup and restore
Pending markers are removed when their saved checksum no longer matches the current local asset content.
Pending and rejected markers are removed when the corresponding remote content becomes active again.
Approved markers are preserved because they represent local work that may need to be reversed after a remote restore.
On supported Android devices, restored assets are marked as
restored. After local media synchronization recreates the local asset row,restoreChecksums()restores the saved checksum when the local asset ID and update time still match, then removes the completed marker.Backup selection is used as an actionability filter and does not by itself remove an unresolved marker or decision.
Timeline integration
The review page uses a dedicated
TimelineOrigin.syncTrash.The timeline query combines:
It returns one item per actionable local asset and groups items by the local asset creation date.
The profile count reports actionable pending local assets rather than distinct checksums.
Main changes
reviewRejectedandreviewApproveddecision statesHow Has This Been Tested?
Automated tests
dart analyzeflutter test test/services/action.service_test.dartflutter test test/medium/repositories/trash_sync_repository_test.dartflutter test test/medium/repositories/timeline_repository_test.dartflutter test test/drift/main/migration_test.dartAdditional coverage includes:
Manual Android test
Manual Android test without Media Management Access
Manual iOS test
Backup-selection test
Multiple-copy test
Mode-switch test
Screenshots
Move-to-trash confirmation
Review asset viewer
Checklist
src/services/uses repository implementations for database calls, filesystem operations, etc.src/repositories/is basic/simple and does not contain Immich-specific business logic.Please describe to which degree, if any, an LLM was used in creating this pull request.
An LLM was used to review changes and draft this PR description.