Commit Graph

3050 Commits (main)

Author SHA1 Message Date
github-actions 95e57a24cb chore: version v2.7.5 2026-04-13 14:27:31 +00:00
github-actions bee49cef02 chore: version v2.7.4 2026-04-10 16:32:26 +00:00
shenlong 6d0c6a4008
chore: pump cronet version (#27685)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-04-10 16:29:05 +00:00
Luis Nachtigall 8a975e5ea9
refactor(mobile): cleanup iOS image loading pipeline (#27672)
* refactor: replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing

* implement RequestRegistry and UnfairLock for managing cancellable requests

* implement requests registry for local and remote image processing

* remove Cancellable protocol and cancel method from request registry

* refactor: introduce ImageRequest base class with unified cancellation and finish helpers

* refactor: add get method to RequestRegistry and streamline request removal in image processing

* add guard to cancel to prevent double onCancel calls

* fix duplicate code merge issue

* refactor(ios): enhance finish method to return callback status

* remove unfitting methods form ImageRequest.swift and fix memory issue

* revert bad merge

* refactor(ios): resolve cancellation issues

* refactor(ios): streamline image request completion handling

* add return statements

* refactor(ios): simplify image request cancellation and registry handling

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-04-10 10:56:35 -05:00
Luis Nachtigall d39e7da10d
fix(mobile): fix flutter cache eviction on thumbnails (#27663)
* 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>
2026-04-10 10:28:55 -05:00
github-actions 3254d31cd2 chore: version v2.7.3 2026-04-09 17:51:40 +00:00
Luis Nachtigall b5bed02300
fix(mobile): get provider refs before async gaps in backup page (#27597)
* fix(mobile): get provider refs before async gaps in backup page

* fix(mobile): use previously created provider refs in start backup function
2026-04-08 20:55:53 -05:00
Luis Nachtigall 2b0f6c9202
fix(mobile): improve image load cancellation handling (#27624)
fix(image): improve image load cancellation handling
2026-04-08 17:23:42 -04:00
github-actions 6a63e814a5 chore: version v2.7.2 2026-04-07 20:58:38 +00:00
github-actions b03a649e74 chore: version v2.7.1 2026-04-07 20:22:28 +00:00
github-actions afec61addc chore: version v2.7.0 2026-04-07 15:08:18 +00:00
Afonso Mendonça Ribeiro 95c1f0efeb
fix: timestamp handling for database backup in Web UI (#27359)
* Fix #26502: Fix timestamp handling for database backup in Web UI

Frontend parsed backup timestamps as UTC, but they were in the
server's local timezone, causing wrong relative times.

Add `timezone` field to DatabaseBackupDto to expose server timezone.
Update frontend to parse timestamps using this timezone.
Convert timestamps to user's local timezone before rendering.
Fallback to browser timezone if server timezone is missing.

Ensures correct relative time display in Web UI.

* fix: regenerate open-api types and remove custom backup type

- Ran `make open-api` to update types based on backend changes
- Removed custom BackupWithTimezone type in MaintenanceBackupsList
- Updated timezone props to use the newly generated native type

* fix: simplify timezone handling for database backups

- Updated DatabaseBackupDto to make timezone a required property
- Removed manual DateTime.local().zoneName fallbacks
- Cleaned up type casts after regenerating OpenAPI types

* fix: Add missing newline at end of spec file
2026-04-06 17:27:48 +02:00
Thomas fbe631fe91
fix(mobile): convert video controls from hook to stateful widget (#27514)
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>
2026-04-06 10:13:45 -05:00
Putu Prema 2143a0c935
fix(mobile): transparent system navbar when trash bottom bar is visible (#27093)
* 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
2026-04-06 09:28:07 -05:00
Luis Nachtigall cd86a83c33
refactor(mobile): introduce image request registry on iOS (#27486)
* refactor: replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing

* implement RequestRegistry and UnfairLock for managing cancellable requests

* implement requests registry for local and remote image processing

* remove Cancellable protocol and cancel method from request registry

* use mutex

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
2026-04-05 18:55:43 -04:00
Luis Nachtigall 6fcf651d76
refactor(mobile): IOS replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing (#27471)
refactor: replace DispatchQueue + DispatchSemaphore with OperationQueue for image processing
2026-04-05 16:11:02 -04:00
Thomas 776b9cbad5
fix(mobile): use key on video controls (#27512)
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.
2026-04-04 21:54:34 -05:00
Thomas 960be0c27a
fix(mobile): don't update search filters in-place (#26965)
* 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>
2026-04-04 22:53:03 +00:00
Thomas 123119ca0d
chore(mobile): reduce buffering timer duration (#27111)
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>
2026-04-04 21:25:40 +00:00
Thomas 1772f720bf
fix(mobile): reset video controls hide timer when showing controls ch… (#26985)
fix(mobile): reset video controls hide timer when showing controls changes

The hide timer currently only resets when the status of the video
changes, but does not account for when the controls change. This means
that two things happen:

 1. The hide timer does not reset when the controls become visible
    again, the controls will stay visible forever or until the playback
    status changes.
 2. The hide timer will fire too quickly, and will hide the controls
    much sooner than 5 seconds if the controls are hidden and then shown
    again before the hide timer fires.
2026-04-04 16:12:56 -05:00
Thomas bcc29903de
chore(mobile): persist video controls visibility when swiping (#26986)
At current, the controls for videos are always hidden when opening an
asset from the timeline, and when swiping between assets. The latter is
actually quite annoying, so it would be better UX if video controls were
hidden when opening from the timeline like before, but visibility of the
controls was retained when swiping between assets.
2026-04-04 16:11:59 -05:00
Thomas 767caf9bfe
fix(mobile): ignore pointer events on toasts (#26990)
These toasts can sometimes cover UI elements and make them impossible to
interact with until they are dismissed. Specifically, deleting an asset
will show a toast over the video controls and prevent seeking.
2026-04-04 10:39:13 -05:00
Jason Rasmussen 207672c481
fix: user-agent format (#27488)
* fix: user-agent format

* ci: fix static analysis

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-04-03 12:26:50 -04:00
Yaros 6b1dd6f680
fix(mobile): favorite button not updating state (#27271) 2026-03-30 21:24:56 -05:00
Mert a1a2939868
fix(mobile): low upload timeout on android (#27399)
fix timeout
2026-03-30 16:05:21 -05:00
Luis Nachtigall a277c6311f
fix(mobile): streamline error handling for live photo saving (#27337) 2026-03-27 19:07:38 -05:00
Luis Nachtigall 306a3b8c7f
fix(mobile): images loads sometimes cancel too early (#27067)
* refactor listener tracking for image stream completers and fix early cancel call

* fix: improve cache listener identification in image stream tracking

* add documentation and test cases for listener tracking in ImageStreamCompleter

* fix: remove unnecessary image provision flag from listener tracking

* fix: override setImage method in cache aware listener tracker mixin

* fix: rename test file
2026-03-27 10:35:50 -04:00
Putu Prema be0fc403d8
fix(mobile): mismatch between system and app color when using low-chroma system color scheme (#27282)
use DynamicSchemeVariant.fidelity to preserve low-chroma system color scheme as the app color
2026-03-27 09:21:43 -05:00
Yaros c13fd9e4b5
fix(mobile): video icon not showing on memories (#27311) 2026-03-27 09:11:02 -05:00
Thomas 8724848fce
chore(mobile): reduce spacing on video controls (#27313)
The spacing was required for the old slider, but the new one has its own
spacing and makes it redundant. There is too much now, and we've
received feedback that it should be less sparse. The default track
height of 16px is an improvement over the old track height, but it is
very thick. A middleground of 12px might be better.
2026-03-27 09:10:19 -05:00
Phlogi 8c6adf7157
feat(server): resolve duplicates (#25316)
* feat(web): Synchronize information from deduplicated images

* Added new settings menu to the the deduplication tab.
* The toggable options in the settings are synchronization of: albums, favorites, ratings, description, visibility and location.
* When synchronizing the albums, the resolved images will be added to all albums of the duplicates.
* When synchronizing the favorite status, the resolved images will be marked as favorite, if at least one selectable image is marked as favorite.
* When synchronizing the ratings, the highest rating from the selectable images will be applied to the resolved image.
* When synchronizing the description, all descriptions from the selectable images will be merged into one description for the resolved image.
* When synchronizing the visibility, the most restrictive visibility setting from the selectable images will be applied to the resolved image.
* When synchronizing the location, if exactly one unique location exists among the selectable images, this location will be applied to the resolved image.
* There is no additional UI for these settings to keep the visual clutter minimal. The settings are applied automatically based on the user's preferences.

* Replace addAssetToAlbums with copyAsset

* fix linter

* feat(web): add duplicate sync fields and fix typo

* feat(web): add tag sync and enhance duplicate resolution

This update introduces tag synchronization for duplicate resolution,
ensuring all unique tag IDs from duplicates are applied to kept assets.
The visibility sync logic is updated to use a simplified ordering, as the hidden status items will never show up in a duplicate set.
Album synchronization now merges albums directly via addAssetsToAlbums; as the approach with copyAsset API endpoint was ineffiecient.
Description, rating, and location sync logic is improved for correctness.
and deduplication. i18n strings were added / updated.

* feat(server): move duplicate resolution to backend with sync and stacking

Moves duplicate metadata synchronization from frontend to backend, enabling robust
batch operations and proper validation. This is an improved refactor of PR #13851.

New endpoints:
- POST /duplicates/resolve - batch resolve with configurable metadata sync
- POST /duplicates/stack - create stacks from duplicate groups
- GET /duplicates - now includes suggestedKeepAssetIds based on file size and EXIF

Key changes:
- Move sync logic (albums, tags, favorites, ratings, descriptions, location, visibility) to server
- Add server-side metadata merge policies with proper conflict resolution
- Replace client-side resolution logic with new backend endpoints
- Add comprehensive E2E tests (70+ test cases) and unit tests
- Update OpenAPI specs and TypeScript SDK

No breaking changes - only additions to existing API.

* feat(preferences): enable all duplicate sync settings by default

* chore: clean up

* chore: clean up

* refactor: rename & clean up

* fix: preference upgrade

* chore: linting

* refactor(e2e): use updateAssets API for setAssetDuplicateId

* fix: visibility sync logic in duplicate resolution

* fix(duplicate): write description to exifUpdate

Previously the duplicate resolution populated assetUpdate.description even
though description belongs to exif info.

* fix(duplicate): remove redundant updateLockedColumns wrapper

updateAllExif already computes lockedProperties via distinctLocked
using Object.keys(options). The wrapper added a lockedProperties key
to the options object, causing the spurious string 'lockedProperties'
to be stored in the lockedProperties array.

* fix(duplicate): write merged tags to asset_exif to survive metadata re-extraction

During duplicate resolution, replaceAssetTags correctly wrote merged tag
IDs to the tag_asset table, but never updated asset_exif.tags or locked
the tags property. The subsequent SidecarWrite → AssetExtractMetadata
chain calls applyTagList, which destructively replaces tag_asset rows
with whatever is in asset_exif.tags — still the original per-asset tags,
not the merged set.

Write merged tag values to asset_exif.tags via updateAllExif (which also
locks the property via distinctLocked), and queue SidecarWrite when tags
change so they persist to the sidecar file.

* docs(duplicates): clarify location and tag sync behavior

* refactor(duplicate): remove sync settings, always sync all metadata on resolve

Remove DuplicateSyncSettingsDto and the per-field sync toggles
(albums, favorites, rating, description, visibility, location, tags).
Duplicate resolution now unconditionally syncs all metadata from
trashed assets to kept assets.

- Remove DuplicateSyncSettingsDto and settings field from DuplicateResolveDto
- Update DuplicateService to always run all sync logic without conditionals
- Delete DuplicateSettingsModal.svelte and settings gear button from UI
- Remove DuplicateSettings type and duplicateSettings persisted store
- Update unit and e2e tests to remove settings from resolve requests

* docs: update duplicates utility to reflect automatic metadata sync

* docs(web): replace duplicates info modal with link to documentation

* chore: clean up

* fix: add missing type cast to jsonAgg in duplicate repository getAll

* fix: skip persisting rating=0 in duplicate merge to avoid unnecessary sidecar write

---------

Co-authored-by: Toni <51962051+EinToni@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2026-03-26 18:33:55 +00:00
github-actions a2ff075e9a chore: version v2.6.3 2026-03-26 16:23:35 +00:00
Yaros c980f5fc19
chore(docs): withPeople parameter description (#27262)
* fix(server): withPeople inconsistent

* fix: query failing in some occasions

* test: add medium tests for withPeople option

* Revert "test: add medium tests for withPeople option"

This reverts commit 6c1505ba6b.

* Revert "fix: query failing in some occasions"

This reverts commit 221feeca45.

* Revert "fix(server): withPeople inconsistent"

This reverts commit 4289a9f23d.

* chore: change endpoint description

* chore: generate open-api
2026-03-26 11:50:29 +01:00
Mert a9666d2cef
fix(mobile): remove upload timeout (#27237)
remove timeout
2026-03-24 14:40:48 -04:00
github-actions ce9b32a61a chore: version v2.6.2 2026-03-24 02:51:55 +00:00
Yaros 4ddc288cd1
fix(mobile/web): album cover buttons consistency (#27213)
* fix(mobile/web): album cover buttons consistency

* test: adjust test
2026-03-23 21:40:17 -05:00
Mert 1506776891
fix(mobile): add cookie for auxiliary url (#27209)
add cookie before validating
2026-03-23 16:22:46 -05:00
Yaros 0e93aa74cf
fix(mobile): add keys to people list (#27112)
mobile(fix): add keys to people list
2026-03-23 10:50:56 -05:00
Yaros e95ad9d2eb
fix(mobile): option padding on search dropdowns (#27154)
* fix(mobile): option padding on search dropdowns

* chore: prevent height fill up screen and block the bottom menu entry

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-23 15:03:07 +00:00
Yaros e2eb03d3a4
fix(mobile): star rating always defaults to 0 (#27157) 2026-03-23 09:56:27 -05:00
Yaros bf065a834f
fix(mobile): no results before applying filter (#27155) 2026-03-23 09:41:13 -05:00
Yaros 33666ccd21
fix(mobile): view similar photos from search (#27149)
* fix(mobile): view similar photos from search

* clean up

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2026-03-23 09:36:42 -05:00
Luis Nachtigall 00dae6ac38
fix(mobile): cronet image cache clearing on android (#27054) 2026-03-20 18:28:24 -04:00
Luis Nachtigall 644f705be1
fix(mobile): correct maximumSizeBytes setter to use maximumSizeBytes property (#27098)
fix: correct maximumSizeBytes setter to use maximumSizeBytes property
2026-03-20 12:22:59 -04:00
Yaros 9c227aeaf5
fix(mobile): simplified chinese not available (#27066) 2026-03-20 00:27:50 -05:00
github-actions e939fde6f1 chore: version v2.6.1 2026-03-19 17:56:42 +00:00
Mert 019beaed0b
fix(mobile): server url migration (#27050)
decode json
2026-03-19 12:52:51 -05:00
github-actions f413f5c692 chore: version v2.6.0 2026-03-18 20:37:39 +00:00
Thomas 677cb660f5
fix(mobile): reflect asset deletions instantly (#26835)
Sometimes the current asset won't update when deleted, or it won't
refresh until an event (like showing details) happens.
2026-03-17 06:43:14 -05:00
Yaros 82db581cc5
feat(mobile): open in browser (#26369)
* feat(mobile): open in browser

* chore: open in browser instead of webview

* chore: allow archived asset

* fix: moved openinbrowser above unstack

* feat: deeplink into favorites, trash & archived

* fix: use remoteId (for tests to succeed)

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-16 18:06:51 +00:00
Mert b66c97b785
fix(mobile): use shared auth for background_downloader (#26911)
shared client for background_downloader on ios
2026-03-13 22:23:07 -05:00
Mert ff936f901d
fix(mobile): duplicate server urls returned (#26864)
remove server url

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-13 22:09:42 -05:00
Mert 226b9390db
fix(mobile): video auth (#26887)
* fix video auth

* update commit
2026-03-13 09:38:21 -05:00
Michel Heusschen 3fd24e2083
fix(server): restrict individual shared link asset removal to owners (#26868)
* fix(server): restrict individual shared link asset removal to owners

* make open-api
2026-03-12 14:48:00 -04:00
Alex 6c531e0a5a
chore: add shadow to video play/pause icon shadow (#26836) 2026-03-11 14:15:31 -05:00
Thomas 471c27cd33
chore(mobile): remove background from asset viewer back button (#26851)
We recently changed the asset viewer to use a gradient. The circle
button looks out of place now.
2026-03-11 14:15:18 -05:00
Mert c403e03a42
fix(mobile): logout on upgrade (#26827)
* use cookiejar

* cookie duping hook

* remove old pref

* handle network switching on logout

* remove bootstrapCookies

* dead code

* fix cast

* use constants

* use new event name

* update api
2026-03-11 12:07:27 -05:00
Luis Nachtigall e7db3b220d
feat(mobile): show animated images in asset viewer (#26614)
* Add support for showing animated images in AssetViewer with AnimatedImageStreamCompleter

* Add GIF overlay to thumbnail tile for animated assets

* formatting

* require isAnimated parameter in image providers for better asset handling

* feat: refactor AnimatedImageStreamCompleter to use streams for codec loading and initial image handling

* formatting

* add isAnimatedImage property to BaseAsset

* remove ApiService.getRequestHeaders() usage
2026-03-11 12:07:06 -05:00
Thomas 9fc32b6f7a
feat(mobile): use material design 3 slider (#26829)
* feat(mobile): use material design 3 slider

The new slider is easier to use, and looks more modern.

* chore: add shadow to button and text for better visibility

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-11 01:58:01 +00:00
Thomas 4571940a4e
fix(mobile): wrap backup error message text (#26834)
Refs: #25022
2026-03-10 20:40:01 -05:00
Thomas 1ceb6d2e21
fix(mobile): use tabular figures in backup page (#26830)
The numbers in the backup page are not monospace, and so changes cause
the layout to shift. Using tabular figures (monospace) will prevent
that.

Refs: #25021
2026-03-10 20:12:33 -05:00
Thomas f79c8cf1c1
feat(mobile): consolidate video controls (#26673)
Videos have recently been changed to support zooming, but this can make
the controls in the centre of the screen unergonomic as they will either
stay in the centre when dismissing, or stick to the video when zooming.
Neither is great. We should align the behaviour with other apps which
has the play/pause toggle at the bottom of the screen with the seeker
bar instead.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-10 10:55:31 -05:00
Luis Nachtigall df0c86920d
fix(mobile): restrict trashed asset migration to Android platform (#26726)
* fix(migration): restrict trashed asset migration to Android platform

* playbackStyle migration add different log depending on platform
2026-03-09 09:56:27 -05:00
Sergey Katsubo 4a384bca86
fix(server): opus handling as accepted audio codec in transcode policy (#26736)
* Fix opus handling as accepted audio codec in transcode policy

Fix the issue when opus is among accepted audio codecs in transcode policy
(which is default) but it still triggers transcoding because the codec name
from ffprobe (opus) does not match `libopus` literal in Immich.

Make a distinction between a codec name and encoder:
- codec name: switch to `opus` as the audio codec name. This matches what ffprobe
returns for a media file with opus audio.
- encoder: continue using the `libopus` encoder in ffmpeg.

* Add unit tests for accepted audio codecs and for libopus encoder

* Add db migration for ffmpeg.targetAudioCodec opus

* backward compatibility

* tweak

* noisy logs

* full mapping

* make check happy

* mark deprecated

* update api

* indexOf

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
2026-03-07 13:08:42 -05:00
Thomas dd72ec2621
fix(mobile): correct local asset dimensions (#26677)
* fix(mobile): correct local asset dimensions

We are constraining the size of videos so that they play nicely with
hero animations, and don't stretch in weird ways. This however caused a
regression as we are not account for local assets on Android which have
un-oriented dimensions.

* post-orientation width and height in local sync

* migration

* no need to handle it in asset viewer

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-07 13:07:34 -05:00
Luis Nachtigall e73686bd76
feat(android): enhance playback style detection using MIME type, reducing glide exposure (#26747)
* feat(android): enhance playback style detection using MIME type

* feat(android): improve playback style detection for GIF and WebP formats

* fix(android): make playback style detection faster

* refactor(android): simplify XMP reading logic for API 29 and below

* update playback style detection documentation

* use DefaultImageHeaderParser instead of all available ones for webp playbackStyle type detection
2026-03-07 10:41:26 -05:00
Thomas 6012d22d98
fix(mobile): incorrect asset dimensions in search (#26725)
Search results use a different provider than the main timeline, and they
appear appear to have diverged a bit. This means that assets can
sometimes look wrong or different in search compared to the main
timeline or albums.
2026-03-05 21:58:58 -06:00
Brandon Wees 9597f8c37f
feat(mobile): SyncAssetEditV1 (#26518)
* feat(mobile): SyncAssetEditV1

* fix: websocket handling

* fix: server version requirement

* fix: revert pubspec changes
2026-03-05 13:03:59 -06:00
Alex 7b0deb1fd3
fix: playback style migration (#26718) 2026-03-05 12:51:58 -06:00
Thomas 5ab05e57fa
fix(mobile): inconsistent asset details background (#26634)
The background of the photo view does not extend below the height of the
viewport, and so the asset details fade in over black with the photo
view, and the standard surface colour scheme of the scaffold for the
rest. This leads to a janky animation. We can't change the background of
the scaffold to black, as it in turn makes the iOS bouncing scroll
physics cut off incorrectly. The best fix is to remove background
decoration from the photo view, and defer to the parent to colour the
background.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-05 17:45:21 +00:00
Marvin M ba3f114625
chore: always use Package Imports (#26630)
* chore: always_use_package_imports

* fix: lint

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-05 11:18:01 -06:00
Mert a05c8c6087
feat(mobile): use shared native client (#25942)
* use shared client in dart

fix android

* websocket integration

platform-side headers

update comment

consistent platform check

tweak websocket handling

support streaming

* redundant logging

* fix proguard

* formatting

* handle onProgress

* support videos on ios

* inline return

* improved ios impl

* cleanup

* sync stopForegroundBackup

* voidify

* future already completed

* stream request on android

* outdated ios ws code

* use `choosePrivateKeyAlias`

* return result

* formatting

* update tests

* redundant check

* handle custom headers

* move completer outside of state

* persist auth

* dispose old socket

* use group id for cookies

* redundant headers

* cache global ref

* handle network switching

* handle basic auth

* apply custom headers immediately

* video player update

* fix

* persist url

* potential logout fix

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-05 11:04:45 -06:00
Thomas 228ac63ab9
feat(mobile): keep search results visible (#26498)
Search results are replaced with a spinner when loading the next page,
which is quite jarring. Search results now remain visible when loading
the next page with a spinner at the bottom. The next page also loads
sooner, which makes it feel a lot smoother.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-04 11:27:11 -06:00
Thomas 7e9da945f6
chore(mobile): simplify asset page scroll (#26635)
In order to scroll smoothly without interfering with the gesture
detector on the photo view, we have an offstate scroll view which we
defer all drags to, and then forward scroll offsets to the real scroll
controller. This works well, but it can be simpler. Instead, we can
create a custom scroll controller on a scroll view with never scrollable
physics, and then forward drag events to that, bypassing the need for a
proxy scroll controller.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-03-04 10:28:55 -06:00
Thomas dd03c9c0a9
fix(mobile): add safe area for asset details (#26675) 2026-03-04 09:47:51 -06:00
Thomas 4eb08eee18
fix(mobile): video state (#26574)
Consolidate video state into a single asset-scoped provider, and reduce
dependency on global state generally. Overall this should fix a few
timing issues and race conditions with videos specifically, and make
future changes in this area easier.
2026-03-03 10:28:07 -06:00
Thomas 05010c3a84
fix(mobile): asset viewer hero animation (#26545)
The image in the photo view has no height, and is therefore entirely
unconstrained. This causes the image to take up the full height of the
viewport during the hero animation, which can make look out of sync. In
some other cases, it can stretch or resize the image to fill the entire
viewport.
2026-03-02 22:26:53 -06:00
Luis Nachtigall 6deb97d5bc
fix(mobile): android detect supported version for special format column (#26633)
* fix(android): detect supported version for special format column

* fix(android): remove unnecessary suppression for new API in special format check

* fix(android): change visibility of hasSpecialFormatColumn method to private
2026-03-02 17:06:35 -05:00
shenlong f54924d46a
refactor: simplify video zooming (#26527)
fix: simplify video zooming

# Conflicts:
#	mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart
#	mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-03-02 17:53:49 +00:00
shenlong d4434f2276
fix: reset db from splash screen (#26617)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-03-01 15:23:26 -06:00
Luis Nachtigall f4e156494f
feat(mobile): add playbackStyle to local asset entity and related database schema (#26596)
* feat: add playbackStyle to local asset entity and related database schema

* implement conversion function for playbackStyle in local sync service

* implement conversion function for playbackStyle in local sync service

* refactor: remove deducedPlaybackStyle from TrashedLocalAssetEntityData

* add playbackStyle column to trashed local asset entity

* make playbackStyle non-nullable across the mobile codebase

* Streamline playbackStyle backfill:
- only backfill local assets playbackStyle in flutter/dart code
- only update trashed local assets in db migration

* bump target database version to 23 and update migration logic for playbackStyle

* set playback_style to 0 in merged_asset.drift as its a getter in base asset

* run make pigeon

* Populate playbackStyle for trashed assets during native migration
2026-03-01 14:50:21 -05:00
Yaros e06cedb626
fix: hide download action for local/merged assets (#26461)
* fix: hide download action for local/merged assets

* chore: use onlyRemote

* chore: rename hasLocal to onlyLocal
2026-03-01 11:16:45 +05:30
Luis Nachtigall ac5ef6a56d
feat(mobile): add support for encoded image requests in local/remote image APIs (#26584)
* feat(mobile): add support for encoded image requests in local and remote image APIs

* fix(mobile): handle memory cleanup for cancelled image requests

* refactor(mobile): simplify memory management and response handling for encoded image requests

* fix(mobile): correct formatting in cancellation check for image requests

* Apply suggestion from @mertalev

Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>

* refactor(mobile): rename 'encoded' parameter to 'preferEncoded' for clarity in image request APIs

* fix(mobile): ensure proper resource cleanup for cancelled image requests

* refactor(mobile): streamline codec handling by removing unnecessary descriptor disposal in loadCodec request

---------

Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>
2026-02-28 11:43:58 -05:00
Luis Nachtigall d6c724b13b
feat(mobile): add playbackStyle to native sync API (#26541)
* feat(mobile): add playbackStyle to native sync API

Adds a `playbackStyle` field to `PlatformAsset` in the pigeon sync API so
native platforms can communicate the asset's playback style (image, video,
animated, livePhoto) to Flutter during sync.

- Add `playbackStyleValue` computed property to `PHAsset` extension (iOS)
- Populate `playbackStyle` in `toPlatformAsset()` and the full-sync path
- Update generated Dart/Kotlin/Swift files

* fix(tests): add playbackStyle to local asset test cases

* fix(tests): update playbackStyle to use integer values in local sync tests

* feat(mobile): extend playbackStyle enum to include videoLooping

* Update PHAssetExtensions.swift

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(playback): simplify playbackStyleValue implementation by removing iOS version check

* feat(android): implement proper playbackStyle detection

* add PlatformAssetPlaybackStyle enum

* linting

---------

Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-28 03:08:51 +00:00
Marius 7dbd08a747
feat(mobile): add confirmation dialog to permanent delete action (#26442) 2026-02-27 15:49:57 +00:00
Thomas 1d89190f96
fix(mobile): don't cut off top corners of app bar (#26550)
It's not visible normally, but in screenshots and when casting, the top
corners of the app bar are cut off. This should fix that.
2026-02-27 17:39:58 +05:30
Thomas c2d8400899
fix(mobile): prevent video player from being recreated unnecessarily (#26553)
The changes in #25952 inadvertently removed an optimisation which
prevents the video player from being recreated when the tree changed.
This happens surprisingly often, namely when the hero animation
finishes. The widget is particularly expensive, so recreating it 2-3 in
a short period not only feels sluggish, but also causes the video to
hitch and restart.

The solution is to bring the global key back for the native video
player. Unlike before, we are using a custom global key which compares
the values of hero tags directly. This means we don't need to maintain a
map of hero tags to global keys in the state, and also means we don't
have to pass the global key down multiple layers.

This also fixes #25981.
2026-02-27 17:39:38 +05:30
Thomas 789d82632a
fix(mobile): race condition showing details (#26559)
Asset details are prematurely hidden when a drag ends if the simulation
shows that it will close given its current velocity. It makes for a much
more responsible feeling UI. However, this behaviour conflicts with the
logic which determines whether details are showing based on the current
offset. The result is that the details are hidden, then immediately
shown again, and then hidden once it passes the min snap distance
threshold.

This can be fixed by only evaluating the position based logic when a
drag is active, and then inferring upcoming state with a simulation.
2026-02-27 12:12:24 +05:30
Michel Heusschen 771816f601
feat(web): map timeline sidepanel (#26532)
* feat(web): map timeline panel

* update openapi

* remove #key

* add index on lat/lng
2026-02-26 12:03:23 -05:00
shenlong 177d1c9a30
feat: splash screen error page (#26460)
* feat: splash screen error page

* Update mobile/lib/pages/common/splash_screen.page.dart

Co-authored-by: Alex <alex.tran1502@gmail.com>

* add clear data action

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-26 16:47:28 +00:00
Noel S ded8d4e2b4
fix(mobile): set correct initial system-ui mode in asset viewer (#26500)
* fix: set correct initial system-ui mode on asset open

* move to function and add details visibility to initial state logic

* switch to ref.read
2026-02-26 10:10:46 -06:00
Mees Frensel e454c3566b
refactor: star rating (#26357)
* refactor: star rating

* transform rating 0 to null in controller dto

* migrate rating 0 to null

* deprecate rating -1

* rating type annotation

* update Rating type
2026-02-26 14:54:20 +01:00
Luis Nachtigall 4c79c3c902
feat(mobile): Prevent premature image cache eviction when higher image loading is enabled (#26208)
* feat(mobile): enhance image loading with error handling and eviction options

* pull request suggestions: remove log and remove useless local implementation
2026-02-25 17:31:37 -05:00
Brandon Wees 3c9fb651d0
feat(server): SyncAssetEditV1 (#26446)
* feat: SyncAssetEditV1

* fix: audit table import

* fix: sql tools table fetch

* fix: medium tests (wip)

* fix: circ dependency

* chore: finalize tests

* chore: codegen/lint

* fix: code review
2026-02-25 18:12:41 +00:00
socksprox d94d9600a7
fix(mobile): birthday picker shows limited months when no date exists (#26407)
* ScrollDatePicker defaults maximumDate to DateTime.now(). When no birthday exists, the picker starts at today (Feb 2026) with max also Feb 2026 — so only Jan–Feb are available for the current year.

Fix applied: Added maximumDate: DateTime(DateTime.now().year, 12, 31) at person_edit_birthday_modal.widget.dart:93, allowing all 12 months to be selected while still preventing future-year birthdays.

* fix(mobile): initialize birthday picker to past date to prevent future birthdays

When no birthday exists, initialize to 30 years ago instead of today.
This allows all 12 months to be selectable while keeping maximumDate
as DateTime.now() to prevent future birthday selection.

Fixes issue where only current months were available due to maxDate constraint.

---------

Co-authored-by: socksprox <info@shadowfly.net>
2026-02-25 07:58:02 +05:30
shenlong 33c6cf8325
test: backup repository (#26494)
test: backup repository tests

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-24 15:50:02 -05:00
shenlong 4b8f90aa55
refactor: remote album repository test to use context (#26481)
* refactor: remote album repository test to use context

* refactor: medium repo context (#26482)

* refactor: medium repo context

* store userId in closure

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-24 13:25:07 +00:00
shenlong 5234e21241
fix: retain asset when either asset is a favorite (#26473)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 16:52:34 -05:00
shenlong 17b327bfcd
refactor: medium repository context (#26472)
refactor: repository test context

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 21:34:21 +00:00
Mees Frensel bf47147fbb
fix(server): accept showAt and hideAt for creating memories (#26429)
* fix(server): accept showAt and hideAt for creating memories

* fix history
2026-02-23 21:26:34 +00:00
aviv926 9ea0a69a72
feat(docs): Adding information about parameter c= (#26430)
* Adding information about parameter c=

* Apply suggestions from code review

Co-authored-by: bo0tzz <git@bo0tzz.me>

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: bo0tzz <git@bo0tzz.me>
2026-02-23 21:21:06 +00:00
shenlong 00f43ffc25
chore: add Option type (#26467)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 16:20:25 -05:00
shenlong db7158b967
refactor: ImmichHtmlText to ImmichFormattedText (#26466)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 16:05:00 -05:00
Brandon Wees e5722c525b
feat: getAssetEdits respond with edit IDs (#26445)
* feat: getAssetEdits respond with edit IDs

* chore: cleanup typings for edit API

* chore: cleanup types with jason

* fix: openapi sync

* fix: factory
2026-02-23 20:57:57 +00:00
shenlong f616de5af8
chore(mobile): nudge users to switch to the new timeline (#26458)
* nudge users to switch to the new timeline

* remove timeline switch setting from new timeline

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 13:42:32 -06:00
shenlong 4f39663d27
fix: simplify timeline rebuild on orientation (#26408)
* revert: current fix

# Conflicts:
#	mobile/lib/presentation/widgets/timeline/timeline.widget.dart

* fix: simpler fix

* rebase

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-23 13:30:09 -05:00
Thomas 367025a3a8
chore(mobile): simplify showing details toggle (#26403)
Keeping track of the last scroll offset and guarding on scroll direction
is not necessary. The dead zone with kTouchSlop is more than sufficient,
and much simpler.

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2026-02-23 23:49:35 +05:30
Yaros 16c1c3c780
fix(mobile): join local on archived timeline (#26387) 2026-02-23 20:21:32 +05:30
Brandon Wees e633bc3f24
fix: missing deletedAt and isVisible columns on mobile (#26414)
* feat: SyncAssetV2

* feat: mobile sync handling

* feat: request correct sync object based on server version

* fix: mobile queries

* chore: sync sql

* fix: test

* chore: switch to mapper

* fix: sql sync
2026-02-23 09:50:54 -05:00
Yaros a469d350be
feat(mobile): prompt when deleting from trash (#26392)
* feat(mobile): prompt when deleting from trash

* refactor: use existing strings

* chore: use type-safe translations

* chore: remove old translation function
2026-02-23 14:45:05 +00:00
Yaros ccab4c88bb
perf(mobile): optimized album sorting (#25179)
* perf(mobile): optimized album sorting

* refactor: add index & sql query

* fix: migration

* refactor: enum, ordering & list

* test: update album service tests

* chore: fix enums

broken during merging main

* chore: remove unnecessary tests

* test: add tests for getSortedAlbumIds

* test: added back stubs in service test
2026-02-23 20:13:45 +05:30
Thomas caebe5166a
chore(mobile): remove redundant assignment (#26404)
The view controller is already assigned during page build. Reassigning
it for every drag doesn't really make any sense.
2026-02-23 12:48:25 +00:00
Thomas 8b2e1509ff
chore(mobile): simplify pop logic (#26410)
We have all the information we need to decide on whether we should pop
or not at the end of a drag. There's no need to track that separately,
and update the value constantly.
2026-02-23 14:49:15 +05:30
Lauritz Tieste d0cb97f994
feat(mobile): Add slug support for shared links (#26441)
* feat(mobile): add slug support for shared links

* fix(mobile): ensure slug retains existing value when unchanged
2026-02-23 14:31:42 +05:30
Timon f0cf3311d5
feat(mobile): Allow users to set profile picture from asset viewer (#25517)
* init

* fix

* styling

* temporary workaround for 500 error

**Root cause:**
The autogenerated Dart OpenAPI client (`UsersApi.createProfileImage()`) had two issues:
1. It set `Content-Type: multipart/form-data` without a boundary, which overrode the correct header that Dart's `MultipartRequest` would set (`multipart/form-data; boundary=...`).
2. It added the file to both `mp.fields` and `mp.files`, creating a duplicate text field.

**Result:**
Multer on the server failed to parse the multipart body, so `@UploadedFile()` was `undefined` → accessing `file.path` in `UserService.createProfileImage()` threw → **500 Internal Server Error**.

**Workaround:**
Bypass the autogenerated method in `UserApiRepository.createProfileImage()` and send the multipart request directly using the same `ApiClient` (basePath + auth), ensuring:
- No manual `Content-Type` header (let `MultipartRequest` set it with boundary)
- File only in `mp.files`, not `mp.fields`
- Proper filename fallback

* Revert "temporary workaround for 500 error"

This reverts commit 8436cd402632ca7be9272a1c72fdaf0763dcefb6.

* generate route for ProfilePictureCropPage

* add route import

* simplify

* try this

* Revert "try this"

This reverts commit fcf37d2801055c49010ddb4fd271feb900ee645a.

* try patching

* Reapply "temporary workaround for 500 error"

This reverts commit faeed810c21e4c9f0839dfff1f34aa6183469e56.

* Revert "Reapply "temporary workaround for 500 error""

This reverts commit a14a0b76d14975af98ef91748576a79cef959635.

* fix upload

* Refactor image conversion logic by introducing a new utility function. Replace inline image-to-Uint8List conversion with the new utility in EditImagePage, DriftEditImagePage, and ProfilePictureCropPage.

* use toast over snack

* format

* Revert "try patching"

This reverts commit 68a616522a1eee88c4a9755a314c0017e6450c0f.

* Enhance toast notification in ProfilePictureCropPage to include success type for better user feedback.

* Revert "simplify"

This reverts commit 8e85057a40.

* format

* add tests

* refactor to use statefulwidget

* format

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-22 06:02:33 +00:00
Timon 3ce0654cab
feat(mobile): Allow users to set album cover from mobile app (#25515)
* set album cover from asset

* add to correct kebab group

* add to album selection

* add to legacy control bottom bar

* add tests

* format

* analyze

* Revert "add to legacy control bottom bar"

This reverts commit 9d68e12a08.

* remove unnecessary event emission

* lint

* fix tests

* fix: button order and remove unncessary check

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-22 05:53:39 +00:00
Noel S f0e2fced57
feat(mobile): video zooming in asset viewer (#22036)
* wip

* Functional implementation, still need to bug test.

* Fixed flickering bugs

* Fixed bug with drag actions interfering with zoom panning. Fixed video being zoomable when bottom sheet is shown. Code cleanup.

* Add comments and simplify video controls

* Clearer variable name

* Fix bug where the redundant onTapDown would interfere with zooming gestures

* Fix zoom not working the second time when viewing a video.

* fix video of live photo retaining pan from photo portion

* code cleanup and simplified widget stack

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-21 23:37:36 -06:00
Alex Balgavy 8ba20cbd44
feat: tap to see next/previous image (#20286)
* feat(mobile): tap behavior for next/previous image

This change enables switching to the next/previous photo in the photo
viewer by tapping the left/right quarter of the screen.

* Avoid animation on first/last image

* Add changes to asset_viewer.page

* Add setting for tap navigation, disable by default

Not everyone wants to have tapping for next/previous image enabled, so
this commit adds a settings toggle. Since it might be confusing behavior
for new users, it is disabled by default.

* chore: refactor

* fix: lint

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2026-02-22 05:28:17 +00:00
Mert 1d25267f22
fix(mobile): buffer width/height referenced after recycling (#26415)
recycle after getters
2026-02-21 09:41:44 -06:00
Peter Ombodi 82c6302549
feat(mobile): timeline - add persistentBottomBar flag (#25634)
* feat(mobile): timeline - add selectable all-assets control

* feature(mobile): introduce bottomWidgetBuilder in Timeline
remove redundant code

* fix(mobile): remove redundant code

* refactor(mobile): refactor new code in Timeline

* fix(mobile): fix format

* refactor(mobile): replace unsupported Dart syntax for analyzer compatibility

* refactor(mobile): remove Timeline.bottomSheet and migrate to bottomWidgetBuilder

* refactor(mobile): restore Timeline.bottomSheet and remove bottomWidgetBuilder
add withPersistentBottomBar param to Timeline class

* refactor(mobile): refactor var name

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
2026-02-20 23:51:26 +05:30
Benjamin Nguyen 18bf96b4b2
fix(mobile): handle userPreferencesProvider error state during sync (#26332)
fix drift_search_page render bug
2026-02-20 08:57:28 -06:00
Benjamin Nguyen a1839b3676
fix(mobile): Reset "People" search filter chip if no selections are made (#26267)
* filter by tags

* reset people search filter chip if no selections
2026-02-20 16:37:26 +05:30
Thomas a43680c8b1
chore(mobile): simplify drag logic (#26291)
We were manually tracking whether gestures should be blocked, which was
a remnant of how the old code worked. This is no longer needed as we
have better heuristics for knowing whether we should skip drag updates
now.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-19 14:18:44 -06:00
shenlong a0077a0f51
feat(mobile): html text (#25739)
* feat: html text

* feat: mobile ui showcase (#25827)

* feat: mobile ui showcase

* remove showcase from main app

* update fonts

* update code to be loaded from asset

* fix ci

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
# Conflicts:
#	mobile/lib/widgets/common/immich_sliver_app_bar.dart

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-19 12:27:16 -06:00
Thomas aa02310d63
chore(mobile): cleanup asset viewer state (#26300)
initState was quite noisy, so I've moved some things around and made the
intention a bit clearer.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-19 12:26:21 -06:00
Thomas 0fa385c465
fix(mobile): infer drag intent early (#26344)
The drag intent was not set until it reached the kTouchSlop threshold.
This is not necessary as flutter already has its own heuristics for
preventing unintended drags.

The result of using kTouchSlop is that dismissing or scroll can feel a
little delayed, and will jump from 0 to kTouchSlop (18px) rather than
moving smoothly.
2026-02-19 09:56:51 -06:00
Thomas dadd20acfc
chore(mobile): reduce the asset details snap target (#26343)
We were snapping to 75%, but 66.6% may be more natural.

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-02-19 15:48:21 +00:00
Jorge Montejo 1f8359ead4
fix: Download the edited version when downloading multiple photos (#26259)
* fix: download the edited version when downloading multiple photos

* test: update tests

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-02-18 21:47:45 +00:00
Benjamin Nguyen ae8dad68fc
feat(mobile): filter by tags (#26196)
filter by tags
2026-02-18 21:16:26 +00:00
Timon 5f95aab437
chore: align mobile mise tasks (#26237)
* chore: align mobile mise tasks

* fix
2026-02-18 14:11:01 -05:00
renovate[bot] 85cb515cae
chore(deps): update dependency github:cqlabs/homebrew-dcm to v1.35.1 (#26278)
* chore(deps): update dependency github:cqlabs/homebrew-dcm to v1.35.1

* fix static analysis

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-18 23:47:54 +05:30
Thomas 3f41916ad7
chore(mobile): fix asset marker icon file name (#26290) 2026-02-17 11:53:44 -05:00
Thomas 5c6433b4ca
feat(mobile): inline asset details (#25952)
The existing implementation for showing asset details uses a bottom
sheet, and is not in sync with the preview or scroll intent. Other apps
use inline details, which is much cleaner and feels better to use.
2026-02-17 09:24:34 -06:00
shenlong 9211013996
fix: bring back timeline args auto-scoping (#26219)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-16 08:20:28 -06:00
Alex 156e3479fa
chore: styling tweak profile panel (#26248) 2026-02-16 08:20:01 -06:00
Thomas d2682f160e
fix(mobile): inherit toolbar opacity (#25694)
Some widgets, like Icon widgets, automatically inherit opacity from the
icon theme in the context. Many other widgets however, do not. The
Immich logo, profile picture, and backup badge are examples of widgets
of this.

All unsupported toolbar widgets have been updated to support inheriting
the opacity from the icon theme.

IconButtons internally animate properties like opacity, which is kind of
nice, but means we have to do more work to replicate that behaviour for
other widgets. In most cases, we can simply use an IconButton widget and
forward the correct opacity. The Immich logo however is not a button,
and therefore we need to use a custom TweenAnimationBuilder.

All widgets are using efficient, native opacity rather than the heavy
Opacity widget.
2026-02-16 09:54:57 +05:30
Nicolas c9dd8e0a79
feat(mobile): hide search by context/OCR if disabled on server (#25472) (#26063)
* feat(mobile): hide search by context/OCR if disabled on server (#25472)

* revert(mobile): remove changes to old search page

---------

Co-authored-by: Nicolas <nicolasroy@MacBookPro>
2026-02-16 08:11:56 +05:30
Thomas 5f87047490
feat(mobile): dynamic multi-line album name (#26040)
* feat(mobile): dynamic multi-line album name

Album names are currently limited to a single line, and scroll on
overflow. It would be better if album names were multi-line, and even
better if the font size was dynamic depending on how many lines there
are. The album name should then overflow with an ellipsis.

This is actually quite similar to how Google Photos handles album names.

* lint

---------

Co-authored-by: timonrieger <mail@timonrieger.de>
2026-02-15 22:23:45 +05:30
shenlong 2d6580acd8
feat(mobile): dynamic layout in new timeline (#23837)
* feat(mobile): dynamic layout in new timeline

* simplify _buildAssetRow

* auto dynamic mode on smaller column count

* auto layout on smaller tiles

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-13 09:15:42 +05:30
Yaros 9aa3fe82c1
fix(mobile): inconsistent query for people (#24437)
* fix(mobile): inconsistent query for people

* refactor: implement suggestions

* refactor: refactored query impl suggestions
2026-02-13 09:13:21 +05:30
Arne Schwarck 66733eb4c0
feat: add people deeplink (#25686)
* Change path prefix from '/memories/' to '/people/'

Updated the AndroidManifest.xml to change the path prefix from '/memories/' to '/people/'.
Memories is anyway wrong and was replaced by /memory
and now the people path completes the known deeplinks.

* Add regex for people deep link handling

Add regex for people deep link handling

* Add deep link handling for 'people' route

* fix: missing person route builder method

---------

Co-authored-by: bwees <brandonwees@gmail.com>
2026-02-13 09:13:04 +05:30
Thomas e5156df4f1
fix(mobile): hide latest version warnings (#26036)
The latest version is already hidden in the server info widget if
disabled (https://github.com/immich-app/immich/pull/25691), however I
did not realise there are more places where this warning is shown. This
hides the warning everywhere, and cleans up the code a bit.
2026-02-13 08:15:25 +05:30
Jason Rasmussen 72cef8b94b
feat: shared link login (#25678) 2026-02-12 12:08:38 -05:00
Christos Longros b06c21325e
fix(mobile): prevent nav bar label text wrapping (#26011)
* fix(mobile): prevent nav bar label text wrapping (#25921)

* chore: fix format

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-12 16:57:03 +00:00
Bastian Köcher 730b770e67
fix(mobile): timeline orientation & foldable phones handling (#25088)
* [mobile]: Fix timeline handling on foldable phones + ensuring that images are not cut off

This fixes the handling of unfolding the phone while having the application opened. So,
the timeline is correctly rescaled and the current position is kept.
Besides that it fixes a bug with the ordering which lead to images being "cut off" at the right side
of the screen.

* refactor + cleanup

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-12 22:20:00 +05:30
Thomas 0d35231dfd
chore(mobile): cleanup server storage info (#26038)
The server storage info has a lot of whitespace due to the ListTile.
Converting it to be inline makes the styling appear more intentional.

There are also a few semantically relevant list items in the app bar
dialog which have been grouped together.
2026-02-12 21:09:55 +05:30
shenlong 675bbf3ac3
chore: remove unused key and fix casing for recent_albums (#24691)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-12 16:06:22 +01:00
shenlong 78c8f1d5a9
chore: add indexes for foreign keys (#25925)
* chore: add indexes for foreign keys

* update idx_asset_face_person_id index

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-12 19:58:31 +05:30
shenlong ec4de54ea2
fix: null local date time in timeline queries (#26133)
* fix: null local date time in timeline queries

* refactor effectiveCreatedAt

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-12 19:58:00 +05:30
Peter Ombodi 420cd5193b
fix(mobile): Login routing on Splash screen (#26128)
* fix(mobile): fix Login routing on Splash screen

* fix(mobile): remove _duplicateGuard from the LoginRoute
revert changes in splash_screen

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
2026-02-12 19:57:43 +05:30
github-actions 3be8e265cd chore: version v2.5.6 2026-02-10 18:24:40 +00:00
Alex adfb003d03
fix: local date time group fall back (#26110)
* fix: local date time group fall back

* remove else clause
2026-02-10 11:47:13 -06:00
Thomas c3730c8eab
chore(mobile): enable high refresh rate in debug builds (#26085)
I'm testing changes to animations and app performance, and noticed it
felt quite sluggish on a 120hz display. It turns out that high refresh
is disabled in debug builds. It's probably a good idea to enable it so
that it more closely mirrors the production build.
2026-02-10 03:51:33 +00:00
Luis Nachtigall 3462fc434e
fix: evict image from cache on error during image loading (#26078) 2026-02-09 17:01:10 -05:00
Luis Nachtigall 561469b826
fix(mobile): handle image stream completion when no image is emitted (#25984)
* Fix image cancellation to be stream-scoped instead of widget-scoped

* fix(OneFramePlaceholderImageStreamCompleter): make onLastListenerRemoved callback synchronous with removing the last listener

* fix(OneFrameMultiImageStreamCompleter): remove unnecessary blank line in code

* fix(OneFramePlaceholderImageStreamCompleter): cancel pending requests when only cache listener remains

* fix(OneFrameMultiImageStreamCompleter): ensure onLastListenerRemoved callback is invoked only once
2026-02-09 16:59:29 -05:00
Alex 57485023ae
fix: free up space using small batch size to reliably work on Android (#26047)
* fix: free up space delete in small batch

* fix: free up space delete in small batch
2026-02-09 11:48:55 -06:00
Alex 906c38273f
fix: profile dialog auto dismiss after opening on iPad (#26046) 2026-02-08 17:30:57 -06:00
Alex 10b2bf7970
fix: iOS slow start (#26043) 2026-02-08 16:28:51 -06:00
Luis Nachtigall 354dd3cc3c
feat(mobile): enhance album sorting functionality with order handling (#24816)
* feat: enhance album sorting functionality with effective order handling

* mobile: formatting

* test: align album sorting order in unit tests with defaultSortOrder

* test(mobile): add reverse order validation for album sorting

* chore(PR): remove OppositeSortOrder Extension and move it directly into SortOrder enum

* refactor: return sorted list directly in album sorting function

* refactor: remove sort_order_extensions.dart
2026-02-07 10:11:37 +05:30
shenlong 57483a1e7f
fix: user profile refetched each time on opening app dialog (#25992)
fix: user profile on opening app dialog

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-07 10:10:17 +05:30
Romo bcea64875f
fix: image and video download complete notification shows "file_name" (#25975)
* fix: image and video download complete notification shows "file_name"

* fix lint

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-07 02:56:14 +00:00
github-actions ff9052f7f5 chore: version v2.5.5 2026-02-06 03:49:02 +00:00
github-actions 8581b4f350 chore: version v2.5.4 2026-02-05 21:16:52 +00:00
Jason Rasmussen 94d3039606
fix: prettier not found (#25941) 2026-02-05 20:44:09 +00:00
Romo 1b3c0e4f65
fix: image download complete notification shows an extra {file_name} template tag (#25936)
* [fix] Image download complete notification shows an extra {file_name} template tag

fixes https://github.com/immich-app/immich/issues/25690
added

```dart
final FileName = 'file_name'.t( args: {'file_name': '{filename}', }, );
```

* chore: fix formatting

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-05 19:19:33 +00:00
Mert fd49d7d566
chore(mobile): skip macro validation (#25744)
* use podfile

* update deps
2026-02-05 14:16:21 -05:00
cmdPromptCritical ad9f3cfa05
fix(mobile): cancel share download when dialog is dismissed (#25466)
* fix(mobile): cancel share download when dialog is dismissed

* refactor: centralize temporary file cleanup logic

* refactor: replace `CancellationToken` with `Completer<void>` for asset sharing cancellation

---------

Co-authored-by: cmdpromptcritical <cmdpromptcritical@github.com>
2026-02-05 19:08:35 +00:00
shenlong f0da875e37
fix: allow clear text traffic on android (#25933)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-06 00:15:33 +05:30
Peter Ombodi b0e1a425b3
fix(mobile): jump to previous asset when last asset is deleted (#25563)
* fix(mobile): fix wrong index, update pageController

* fix(mobile): refactor code

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2026-02-05 18:19:40 +00:00
shenlong 92c79a7122
chore: increase cache_size and use memory temp store (#25930)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-05 11:55:07 -06:00
shenlong 2dd3a764ae
fix: timezone in timeline bucketing (#25894)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-05 11:47:16 -06:00
Thomas a42c08ed84
fix(mobile): reset asset index on timeline refresh (#25729)
The current asset changes when the timeline refreshes, which can be
quite jarring. Assets are tracked by their index, and that index becomes
stale when the timeline refreshes. This can be resolved by updating the
index of asset based on a unique identifier (like the hero tag).
2026-02-05 11:46:38 -06:00
Mert 27a2808470
fix(mobile): mtls on native clients (#25802)
* handle mtls on ios

* update android impl

* ui improvements

* dead code

* no need to store data separately

* improve concurrency

* dead code

* add migration

* remove unused dependency

* trust user-installed certs

* removed print statement

* fix ios

* improve android styling

* outdated comments

* update lock file

* handle translation

* fix prompt cancellation

* fix video playback

* Apply suggestion from @shenlong-tanwen

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* Apply suggestion from @shenlong-tanwen

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* formatting

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2026-02-05 17:42:53 +00:00
shenlong 2b6055e830
chore: do not process cloud ids during sync & hash (#25914)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-02-05 11:23:50 -06:00
Mert ba2dfa7df6
refactor(mobile): consolidate image requests (#25743)
remote url image provider

remove cached_network_image

formatting

linting

remove thumb provider

formatting
2026-02-05 12:16:42 -05:00
Jason Rasmussen 9dddccd831
fix: null validation (#25891) 2026-02-04 12:27:52 -05:00
Jason Rasmussen 3ea65f8d27
fix: album dto docs (#25873) 2026-02-03 21:05:18 +00:00
github-actions 38c1f0b1fd chore: version v2.5.3 2026-02-03 18:14:21 +00:00
Alex 3870ebc3c6
fix: prevent album page get rebuilt when resuming app (#25862) 2026-02-03 16:35:53 +00:00
Alex 8872d2c7ae
chore: remove swift logs (#25857) 2026-02-03 16:00:17 +00:00
Alex 23445fdcc1
fix: upload progress bar flickering (#25829)
* fix: upload progress bar flickering

* pr feedback and more logs
2026-02-03 09:28:29 -06:00
Thomas 855817514c
fix(mobile): hide latest version if disabled (#25691)
* fix(mobile): hide latest version if disabled

If the version check feature is disabled, the server will currently send
stale data to the client. In addition to no longer sending stale data,
the client should also not show the latest version if the feature is
disabled.

This complements the server PR #25688.

* lint

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-01-30 16:17:03 +00:00
Thomas d5ad35ea52
chore(mobile): remove references to fvm, add mise docs, use java 21 (#25703) 2026-01-29 23:03:56 -06:00
shenlong e63213d774
fix(mobile): do not autocorrect on endpoint input (#25696)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-01-29 23:03:26 -06:00
Timon 8db61d341f
docs(openapi): add descriptions to OpenAPI specification (#25185)
* faces

* add openapi descriptions

* remove dto descriptions

* gen openapi

* dtos

* fix dtos

* fix more

* fix build

* more

* complete dtos

* descriptions on rebase

* gen rebase

* revert correct integer type conversion

* gen after revert

* revert correct nullables

* regen after revert

* actually incorrect adding default here

* revert correct number type conversion

* regen after revert

* revert nullable usage

* regen fully

* readd some comments

* one more

* one more

* use enum

* add missing

* add missing controllers

* add missing dtos

* complete it

* more

* describe global key and slug

* add remaining body and param descriptions

* lint and format

* cleanup

* response and schema descriptions

* test patch according to suggestion

* revert added api response objects

* revert added api body objects

* revert added api param object

* revert added api query objects

* revert reorganized http code objects

* revert reorganize ApiOkResponse objects

* revert added api response objects (2)

* revert added api tag object

* revert added api schema objects

* migrate missing asset.dto.ts

* regenerate openapi builds

* delete generated mustache files

* remove descriptions from properties that are schemas

* lint

* revert nullable type changes

* revert int/num type changes

* remove explicit default

* readd comment

* lint

* pr fixes

* last bits and pieces

* lint and format

* chore: remove rejected patches

* fix: deleting asset from asset-viewer on search results (#25596)

* fix: escape handling in search asset viewer (#25621)

* fix: correctly show owner in album options modal (#25618)

* fix: validation issues

* fix: validation issues

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: Min Idzelis <min123@gmail.com>
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
Co-authored-by: Paul Makles <me@insrt.uk>
2026-01-29 08:49:15 -05:00
github-actions eadb2f89af chore: version v2.5.2 2026-01-28 22:05:10 +00:00
Marius f2f11b1924
fix(mobile): tall image scrolling (#25649)
Add cross-axis gesture detection in PhotoView so vertical scrolling works on tall images that don't fill the screen width (have black bars)
2026-01-28 17:03:11 -05:00
Alex 0beb1f9e7a
fix: width and height migration issue (#25643)
* fix: width and height migration issue

* chore: sync stream migration tests

* lint and test

---------

Co-authored-by: bwees <brandonwees@gmail.com>
2026-01-28 15:14:50 -06:00
Mert e07a91f9c2
fix(mobile): actually load original image (#25646)
fix decoding
2026-01-28 15:14:37 -06:00
Noel S c6defd453b
fix(mobile): set correct system-ui mode on asset viewer init (#25610)
fix: set correct systemui mode on asset viewer init
2026-01-28 15:14:23 -06:00
Noel S 84c3980844
fix(mobile): show controls by default on motion photos (#25638)
fix: show controls by default on motion photos
2026-01-28 13:46:29 -06:00
Alex 12d23e987b
chore: post release tasks (#25582) 2026-01-28 08:55:58 -05:00
github-actions 41e2ed3754 chore: version v2.5.1 2026-01-27 23:10:13 +00:00
Alex 97df9fd53f
chore: prevent going into sleep mode for large deletion (#25592) 2026-01-27 22:50:28 +00:00
shenlong 46d2238431
fix: migration on trash source column (#25590)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-01-27 16:25:35 -06:00
github-actions 6fd3c9fffa chore: version v2.5.0 2026-01-27 18:19:23 +00:00
Alex 44b4f35019
chore: expose upload errors to UI (#25566) 2026-01-27 16:33:44 +00:00
shenlong 7cedb5ea04
feat: add manual cloud id sync button (#25531)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-01-27 08:10:18 -06:00
Alex 6587d45f1e
chore: star rating letter casing (#25554) 2026-01-27 08:57:39 +00:00
Brandon Wees da590995ab
fix: use edited thumbs for widgets (#25550)
* fix(server): enforce crop is the first action

* chore: test

* fix: use edited thumbs for widgets

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-01-27 03:16:27 +00:00