server removed both fields from AssetMediaCreateDto in #27818. zod silently strips unknown fields so uploads still work, but we send dead weight on every request.
drop from foreground + background upload paths + share intent path. deviceAssetId stays as the internal background_downloader taskId, just not in the multipart form fields anymore.
fix(mobile): deduplicate assets in person view timeline
Previously, assets with multiple face records for the same person (e.g.,
manual Digikam imports and Immich ML detections) appeared multiple times
in the person timeline. This was caused by an inner join on the
assetFaceEntity without proper deduplication.
This commit refactors the timeline queries to use a subquery approach
instead of joins and grouping. This ensures:
- _getPersonBucketAssets: Only unique assets are fetched, even if
multiple face records exist for a single asset.
- _watchPersonBucket: Asset counts in timeline headers are accurate
and represent unique assets.
- Performance: Database overhead is reduced by avoiding complex joins
and explicit groupBy operations on large result sets.
Signed-off-by: thowdev <12428285+thowdev@users.noreply.github.com>
_manualSyncAlbums fires a setState 1s after sync via Future.delayed
with no mounted check. if the widget is gone by then, setState throws
null check and the global error logger logs it severe.
#27666 removed LocalNotificationService with the legacy stack, which
was the only place calling FlutterLocalNotificationsPlugin().initialize().
without it, ios never prompts for the notification perm on fresh
installs so background_downloader notifications get dropped silently.
restores the init in the same spot the deleted call used to live.
* fix(mobile): view similar defaults to images only
* fix(mobile): reset filter chips when pre-filter is applied
---------
Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
* refactor: app metadata
* refactor to per row store
* cleanup
* more test
* review changes
* more refactor
* refactor
---------
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
* fix: add markFinished parameter to loadRequest and loadCodecRequest methods
* update loadRequest and loadCodecRequest methods to use isFinal
* Apply suggestions from code review
Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>
* remove redundant check
* fix: ensure isFinished is set correctly during cache eviction
* formatting
---------
Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>
We are generally looking to move away from hooks as they are hard to
reason about and have weird bugs. In particular, the timer did not
properly capture the ref of the callback, and so it would execute on old
state. A standard stateful widget does not have this problem, and is
easier to organise.
Co-authored-by: Alex <alex.tran1502@gmail.com>
* disable bottom safe area on trash bottom bar so that it extends below the system nav bar
* remove manual padding calculations
* re-add static vertical padding to maintain previous bottom bar height
The widget is not recreated correctly when videoPlayName changes, which
can cause weird behaviour with hooks and timers (like timers not firing
when they should do). Using a key forces flutter to recreate the widget
properly and allow the assumptions in build to work correctly.
* fix(mobile): don't update search filters in-place
Search filters are currently modified in-place, which can feel quite
janky. The chips behind the bottom sheet update instantly, and the
search page gets confused because filters have been applied but no
search has been initiated. Filters should keep their own copy of the
filter when they're opened, and the commit + search on apply.
The previous filter and pre-filter concepts were also cleaned up. They
added complexity, and `search()` now owns the full life cycle of the
filter.
This now also reverts the changes from #27155, as this solution should
be cleaner.
* refactor & color tweak
---------
Co-authored-by: Alex <alex.tran1502@gmail.com>
3 seconds is too long for some people, and it can be confusing to see
the video not playing and no indication that it's buffering. Reducing
the duration of the timer should show the spinner faster and prevent
confusion.
Co-authored-by: Alex <alex.tran1502@gmail.com>