2618 Commits

Author SHA1 Message Date
idubnori
3c80049192 chore(mobile): add kebabu menu in asset viewer (#24387)
* feat(mobile): implement viewer kebab menu with about option

* feat: revert exisitng buttons, adjust label name

* unify MenuAnchor usage

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-12-05 19:51:59 +00:00
Hai Sullivan
8f1669efbe chore(mobile): smoother UI experience for iOS devices (#24397)
allows the tab pages to use the standard Material page transition during push/pop navigation
2025-12-05 11:02:04 -06:00
shenlong
bbba1bfe8c fix: use adjustment time in iOS for hash reset (#24047)
* use adjustment time in iOS for hash reset

* migration

* fix equals check

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-12-03 21:15:58 -06:00
Alex
4fe494776e fix: local full sync on Android on resume (#24348) 2025-12-03 20:22:07 +00:00
Justin Forseth
76b4adf276 fix: Adjust the zoom level (#24353)
Adjust the zoom level
2025-12-03 14:19:57 -06:00
Alex
75dde0d076 fix: exposure info and better readability (#24344)
fix: exposure info and better readabilit
2025-12-03 20:19:45 +00:00
Alex
f5df5fa98d chore: change workflow column name (#24349)
chore-change-workflow-column-name
2025-12-02 14:40:17 -06:00
Hai Sullivan
b11aecd184 fix(mobile): use correct timezone displayed in the info sheet (#24310)
* fixed the timezone issue in the Immich mobile app's metadata sheet to match the web app's behavior

* format dart

* now uses the shared applyTimezoneOffset() utility function from mobile/lib/utils/timezone.dart

* add tests

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-12-02 16:37:19 +00:00
Yaros
a32f450059 feat(mobile): persist album sorting & layout in settings (#22133)
* fix(mobile): persist album sorting in settings

* fix(mobile): persist album layout

* fix: fixed store model id

* fix: corrupted AppSettingsEnum

* chore: refactor to remove RemoteAlbumSortMode

* refactor: use t instead of tr
2025-12-01 20:51:35 -06:00
Matthew Momjian
fa43fae2a5 fix(mobile): docs link (#24277)
update docs link
2025-11-30 13:01:33 -06:00
Hai Sullivan
46e1967760 chore: optimisation of several UI components of the mobile app (#24098)
* fix(mobile): normalize scrolling behavior in networking settings

Remove ClampingScrollPhysics from networking settings page to match
the scrolling behavior of other settings pages. This restores the
standard iOS bounce/elastic scrolling effect.

* fix(mobile): use consistent native transitions for Library pages

Change Trash, Shared Links, and Folders routes from CustomRoute to AutoRoute to enable native iOS transitions with swipe-back gesture support.

* fix(mobile): remove SafeArea wrapper and ClampingScrollPhysics from Settings

Remove SafeArea wrapper (Scaffold handles safe areas automatically) and ClampingScrollPhysics to enable native iOS bounce scrolling.

* fix(mobile): remove bottom white space in Sync Status page

Replace Padding wrapper with ListView padding to match other Settings pages and eliminate bottom white space.

* chore: fix Dart formatting

Run dart format to fix formatting issues in settings.page.dart and sync_status_and_actions.dart

* Format Dart files

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: kao-byte <benjaminliu@MacBook-Air.local>
2025-11-30 13:01:01 -06:00
Alex
e3ab16a5bd chore: refactor mobile events (#24263)
chore: refactor mobile evets
2025-11-30 12:43:33 -06:00
Yaros
f12f609038 fix(mobile): enable backup text overflows (#24227) 2025-11-28 10:18:44 -06:00
Jason Rasmussen
104fa09f69 feat: queues (#24142) 2025-11-25 08:19:40 -05:00
shenlong
c860809aa1 fix: getAspectRatio fallback to db width and height (#24131)
fix: getExif fallback to db width and height

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-24 10:23:17 -06:00
shenlong
24e5dabb51 fix: use proper updatedAt value in local assets (#24137)
* fix: incorrect updatedAt value in local assets

* add test

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-24 09:49:27 -06:00
Yaros
9f3eeed091 fix(mobile): first video memory on page doesn't play (#23906)
* fix(mobile): first video memory doesn't play

* refactor: moved logic to static method

* refactor: fix haptic feedback & empty check

* refactor: use DriftMemory on setMemory

* refactor: move video reset into if block
2025-11-21 09:11:30 -06:00
Brandon Wees
1dbc20fd77 fix: show archived assets in favorite page (#24052) 2025-11-21 09:09:16 -06:00
Joren Guillaume
ba8df712c4 fix: Use correct app store link (#24062) 2025-11-21 13:54:09 +01:00
Brandon Wees
ec2fa6e308 fix: disable animation "add to" action menu (#24040) 2025-11-20 11:54:15 -06:00
shenlong
b974ed5735 fix: do not clear hash on updated_at change (#24039)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-20 11:31:17 -06:00
github-actions
edbdc14178 chore: version v2.3.1 2025-11-20 02:20:16 +00:00
github-actions
45a0315606 chore: version v2.3.0 2025-11-19 17:46:53 +00:00
Brandon Wees
2a281e7906 feat(mobile): location edit from asset viewer (#23925)
* chore: break sheet tile into own file

* feat: set location from bottom sheet

* refactor: location picker

There was a lot of confusing controls here, simplified to 1 mode

* fix: local asset check

* chore: refactoring of location details widget

* fix: update currentAssetExifProvider when changing location

* chore: use SheetTile for location header

* chore: remove coordinate change check

* chore: remove comment
2025-11-18 21:06:51 -06:00
shenlong
38d4d1a573 chore: reset remote sync on app update (#23969)
reset remote sync on update

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-19 02:55:01 +00:00
Alex
c086a65fa8 chore: update drift (#23877)
* chore: update drift

* update drift dep

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-18 16:07:33 +00:00
Paul Makles
15e00f82f0 feat: maintenance mode (#23431)
* feat: add a `maintenance.enabled` config flag

* feat: implement graceful restart
feat: restart when maintenance config is toggled

* feat: boot a stripped down maintenance api if enabled

* feat: cli command to toggle maintenance mode

* chore: fallback IMMICH_SERVER_URL environment variable in process

* chore: add additional routes to maintenance controller

* fix: don't wait for nest application to close to finish request response

* chore: add a failsafe on restart to prevent other exit codes from preventing restart

* feat: redirect into/from maintenance page

* refactor: use system metadata for maintenance status

* refactor: wait on WebSocket connection to refresh

* feat: broadcast websocket event on server restart
refactor: listen to WS instead of polling

* refactor: bubble up maintenance information instead of hijacking in fetch function
feat: show modal when server is restarting

* chore: increase timeout for ungraceful restart

* refactor: deduplicate code between api/maintenance workers

* fix: skip config check if database is not initialised

* fix: add `maintenanceMode` field to system config test

* refactor: move maintenance resolution code to static method in service

* chore: clean up linter issues

* chore: generate dart openapi

* refactor: use try{} block for maintenance mode check

* fix: logic error in server redirect

* chore: include `maintenanceMode` key in e2e test

* chore: add i18n entries for maintenance screens

* chore: remove negated condition from hook

* fix: should set default value not override in service

* fix: minor error in page

* feat: initial draft of maintenance module, repo., worker controller, worker service

* refactor: move broadcast code into notification service

* chore: connect websocket on client if in maintenance

* chore: set maintenance module app name

* refactor: rename repository to include worker
chore: configure websocket adapter

* feat: reimplement maintenance mode exit with new module

* refactor: add a constant enum for ExitCode

* refactor: remove redundant route for maintenance

* refactor: only spin up kysely on boot (rather than a Nest app)

* refactor(web): move redirect logic into +layout file where modal is setup

* feat: add Maintenance permission

* refactor: merge common code between api/maintenance

* fix: propagate changes from the CLI to servers

* feat: maintenance authentication guard

* refactor: unify maintenance code into repository
feat: add a step to generate maintenance mode token

* feat: jwt auth for maintenance

* refactor: switch from nest jwt to just jsonwebtokens

* feat: log into maintenance mode from CLI command

* refactor: use `secret` instead of `token` in jwt terminology
chore: log maintenance mode login URL on boot
chore: don't make CLI actions reload if already in target state

* docs: initial draft for maintenance mode page

* refactor: always validate the maintenance auth on the server

* feat: add a link to maintenance mode documentation

* feat: redirect users back to the last page they were on when exiting maintenance

* refactor: provide closeFn in both maintenance repos.

* refactor: ensure the user is also redirected by the server

* chore: swap jsonwebtoken for jose

* refactor: introduce AppRestartEvent w/o secret passing

* refactor: use navigation goto

* refactor: use `continue` instead of `next`

* chore: lint fixes for server

* chore: lint fixes for web

* test: add mock for maintenance repository

* test: add base service dependency to maintenance

* chore: remove @types/jsonwebtoken

* refactor: close database connection after startup check

* refactor: use `request#auth` key

* refactor: use service instead of repository
chore: read token from cookie if possible
chore: rename client event to AppRestartV1

* refactor: more concise redirect logic on web

* refactor: move redirect check into utils
refactor: update translation strings to be more sensible

* refactor: always validate login (i.e. check cookie)

* refactor: lint, open-api, remove old dto

* refactor: encode at point of usage

* refactor: remove business logic from repositories

* chore: fix server/web lints

* refactor: remove repository mock

* chore: fix formatting

* test: write service mocks for maintenance mode

* test: write cli service tests

* fix: catch errors when closing app

* fix: always report no maintenance when usual API is available

* test: api e2e maintenance spec

* chore: add response builder

* chore: add helper to set maint. auth cookie

* feat: add SSR to maintenance API

* test(e2e): write web spec for maintenance

* chore: clean up lint issues

* chore: format files

* feat: perform 302 redirect at server level during maintenance

* fix: keep trying to stop immich until it succeeds (CLI issue)

* chore: lint/format

* refactor: annotate references to other services in worker service

* chore: lint

* refactor: remove unnecessary await

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* refactor: move static methods into util

* refactor: assert secret exists in maintenance worker

* refactor: remove assertion which isn't necessary anymore

* refactor: remove assertion

* refactor: remove outer try {} catch block from loadMaintenanceAuth

* refactor: undo earlier change to vite.config.ts

* chore: update tests due to refactors

* revert: vite.config.ts

* test: expect string jwt

* chore: move blanket exceptions into controllers

* test: update tests according with last change

* refactor: use respondWithCookie
refactor: merge start/end into one route
refactor: rename MaintenanceRepository to AppRepository
chore: use new ApiTag/Endpoint
refactor: apply other requested changes

* chore: regenerate openapi

* chore: lint/format

* chore: remove secureOnly for maint. cookie

* refactor: move maintenance worker code into src/maintenance\nfix: various test fixes

* refactor: use `action` property for setting maint. mode

* refactor: remove Websocket#restartApp in favour of individual methods

* chore: incomplete commit

* chore: remove stray log

* fix: call exitApp from maintenance worker on exit

* fix: add app repository mock

* fix: ensure maintenance cookies are secure

* fix: run playwright tests over secure context (localhost)

* test: update other references to 127.0.0.1

* refactor: use serverSideEmitWithAck

* chore: correct the logic in tryTerminate

* test: juggle cookies ourselves

* chore: fix lint error for e2e spec

* chore: format e2e test

* fix: set cookie secure/non-secure depending on context

* chore: format files

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
2025-11-17 17:15:44 +00:00
Yaros
eeee5147cc fix(mobile): delete from device warning shows incorrectly (#23935)
fix(mobile): delete warning on multiple assets
2025-11-17 10:17:04 -06:00
Christian
e94eb5012f feat(mobile): add to album from asset viewer (#23608)
* feat: add action button in photo viewer for adding assets to albums, archiving, and moving to locked folders

* fix: use const constructors for icons in action button menu

* Update mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart

Co-authored-by: Brandon Wees <brandonwees@gmail.com>

* Update mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart

Co-authored-by: Brandon Wees <brandonwees@gmail.com>

* remove de translation

* fixed PR comments: https://github.com/immich-app/immich/pull/23608

* menu styling

* menu styling

* i18n

---------

Co-authored-by: Brandon Wees <brandonwees@gmail.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-14 15:11:47 -06:00
Alex
4dcc049465 feat: workflow foundation (#23621)
* feat: plugins

* feat: table definition

* feat: type and migration

* feat: add repositories

* feat: validate manifest with class-validator and load manifest info to database

* feat: workflow/plugin controller/service layer

* feat: implement workflow logic

* feat: make trigger static

* feat: dynamical instantiate plugin instances

* fix: access control and helper script

* feat: it works

* chore: simplify

* refactor: refactor and use queue for workflow execution

* refactor: remove unsused property in plugin-schema

* build wasm in prod

* feat: plugin loader in transaction

* fix: docker build arm64

* generated files

* shell check

* fix tests

* fix: waiting for migration to finish before loading plugin

* remove context reassignment

* feat: use mise to manage extism tools (#23760)

* pr feedback

* refactor: create workflow now including create filters and actions

* feat: workflow medium tests

* fix: broken medium test

* feat: medium tests

* chore: unify workflow job

* sign user id with jwt

* chore: query plugin with filters and action

* chore: read manifest in repository

* chore: load manifest from server configs

* merge main

* feat: endpoint documentation

* pr feedback

* load plugin from absolute path

* refactor:handle trigger

* throw error and return early

* pr feedback

* unify plugin services

* fix: plugins code

* clean up

* remove triggerConfig

* clean up

* displayName and methodName

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: bo0tzz <git@bo0tzz.me>
2025-11-14 20:05:05 +00:00
Jason Rasmussen
d784d431d0 refactor: job vs queue naming (#23902) 2025-11-14 14:42:00 -05:00
Jason Rasmussen
4a6c50cd81 feat: endpoint versioning (#23858) 2025-11-13 08:18:43 -05:00
Alex
8969b8bdb2 fix: GHA build issue on iOS (#23849)
* fix: GHA build issue on iOS

* fix: resolve Swift Package dependencies in GitHub Actions

* fix: use Release configuration for iOS build

* fix: simplify code signing for build-only lane

* fix: explicitly resolve Swift packages before building

* fix: use specified XCode version
2025-11-12 15:32:08 -06:00
shenlong
c958f9856d chore: bump background_downloader (#23839)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-12 09:17:44 -06:00
Jason Rasmussen
edde0f93ae feat: endpoint descriptions (#23813) 2025-11-11 17:01:14 -05:00
Alex
896665bca9 fix: iOS release build dependency verification (#23814) 2025-11-11 15:35:44 -06:00
idubnori
337e3a8dac feat(mobile): album activity deep link (#23737)
* feat: add activity deep link support in DeepLinkService

* test: add unit tests for DeepLinkService handling of activity deep links

* Revert "test: add unit tests for DeepLinkService handling of activity deep links"

This reverts commit 0b1914be9a.
2025-11-11 10:04:54 -06:00
Mert
9e2208b8dd chore(mobile): add table schemas to swift (#23749)
* add schemas

* handle json, improve type safety

* formatting

* sync variants

* formatting
2025-11-10 20:21:08 +00:00
exelix
7a2c8e0662 feat(mobile): Quick date picker in the search page (#22653)
* Quick date picker

* Include current year in quick date picker

* Quick date picker: localization, fix datetime overflows

* Properly localized 'last_months'

* Move quick_date_picker.dart to lib/presentation/widgets/search

* Wrap the quick date picker state into its own class, improve the interaction patterns

* Fix last9Months value

* Improve method naming

* Subtitle for "custom range" in quick date picker

* Fix style warnings

* Fix lint warning

* fix:  mobile unawaited_futures lint (#21661)

* chore: add unawaited_futures lint as warning

* remove unused dcm lints

They will be added back later on a case by case basis

* fix warning

* auto gen file

* review changes

* conflict resolution

---------

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

* Quick date picker

* Wrap the quick date picker state into its own class, improve the interaction patterns

* chore: delete file from rebase

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: bwees <brandonwees@gmail.com>
2025-11-10 13:55:09 -06:00
idubnori
b0a0b7c2e1 feat(mobile): chat-style for asset activity view (#23347)
* feat(mobile): open assetviewer via album activities page

* adjust ui behavior: keep current asset & disable initial forcus

* init of v2...

* refactoring...

* refactor: remove _DismissibleWrapper

* feat: initial scrolling to bottom

* refactor: use feature toggle

* refactor: new route page

* fix: file name, dcm analyze

* fix: test failure

* fix: remove toggle and the exisitng style based on review feedback

* refactorr: rename methods for clarity in comment bubble widget

* feat: (mobile) chat-style asset activity timeline

* chore: extract as a new file

* chore: styling (based on 2c12bc56)

* chore: clean up

* fix: albumActivityProvider parameter

* fix: review point

* fix
2025-11-10 13:26:27 -06:00
idubnori
cb6d81771d fix(mobile): sync album and asset activity state when add/remove asset level activity (#23484)
* fix; sync album-asset state when remove activity

* make build

* fix: support adding case

* make build

* Update mobile/lib/providers/activity.provider.dart

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

* fix: add missing import for collection package

* make build

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2025-11-10 13:25:43 -06:00
Noel S
d6307b262f fix(mobile): Hide download button in asset viewer "immersive mode" (#23720)
* Hide download FAB in asset viewer immersive mode

* Remove commented out code

* Remove more comments
2025-11-10 12:13:04 -06:00
Viktor Mykhailiv
b2cbefe41e fix(mobile): Set dynamic height of actions row in BottomSheet (#23755)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-10 12:03:12 -06:00
shenlong
da5a72f6de chore: patch MemoriesResponse (#23764)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-10 11:37:45 -06:00
Peter Ombodi
493cde9d55 feat: opt-in sync of deletes and restores from web to Android (beta timeline) (#20473)
* feature(mobile, beta, Android): handle remote asset trash/restore events and rescan media
- Handle move to trash and restore from trash for remote assets on Android
- Trigger MediaScannerConnection to rescan affected media files

* feature(mobile, beta, Android): fix rescan

* fix imports

* fix checking conditions

* refactor naming

* fix line breaks

* refactor code
rollback changes in BackgroundServicePlugin

* refactor code (use separate TrashService)

* refactor code

* parallelize restoreFromTrash calls with Future.wait
format trash.provider.dart

* try to re-format trash.provider.dart

* re-format trash.provider.dart

* rename TrashService to TrashSyncService to avoid duplicated names
revert changes in original trash.provider.dart

* refactor code (minor nitpicks)

* process restoreFromTrash sequentially instead of Future.wait

* group local assets by checksum before moving to trash
delete LocalAssetEntity records when moved to trash
refactor code

* fix format

* use checksum for asset restoration
refactro code

* fix format

* sync trash only for backup-selected assets

* feat(db): add local_trashed_asset table and integrate with restoration 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`

* resolve merge conflicts

* fix index creating on migration

* rework trashed assets handling
- add new table trashed_local_asset
- mirror trashed assets data in trashed_local_asset.
- compute checksums for assets trashed out-of-app.
- restore assets present in trashed_local_asset and non-trashed in remote_asset.
- simplify moving-to-trash logic based on remote_asset events.

* resolve merge conflicts
use updated approach for calculating checksums

* use CurrentPlatform instead _platform
fix mocks

* revert redundant changes

* Include trashed items in getMediaChanges
Process trashed items delta during incremental sync

* fix merge conflicts

* fix format

* trashed_local_asset table mirror of local_asset table structure
trashed_local_asset<->local_asset transfer data on move to trash or restore
refactor code

* refactor and format code

* refactor TrashedAsset model
fix missed data transfering

* refactor code
remove unused model

* fix label

* fix merge conflicts

* optimize, refactor code
remove redundant code and checking
getTrashedAssetsForAlbum for iOS
tests for hash trashed assets

* format code

* fix migration
fix tests

* fix generated file

* reuse exist checksums on trash data update
handle restoration errors
fix import

* format code

* sync_stream.service depend on repos
refactor assets restoration
update dependencies in tests

* remove trashed asset model
remove trash_sync.service
refactor DriftTrashedLocalAssetRepository, LocalSyncService

* rework fetching trashed assets data on native side
optimize handling trashed assets in local sync service
refactor code

* update NativeSyncApi on iOS side
remove unused code

* optimize sync trashed assets call in full sync mode
refactor code

* fix format

* remove albumIds from getTrashedAssets params
fix upsert in trashed local asset repo
refactor code

* fix getTrashedAssets params

* fix(trash-sync): clean up NativeSyncApiImplBase and correct applyDelta

* refactor(trash-sync): optimize performance and fix minor issues

* refactor(trash-sync): add missed index

* feat(trash-sync): remove sinceLastCheckpoint param from getTrashedAssets

* fix(trash-sync): fix target table

* fix(trash-sync): remove unused extension

* fix(trash-sync): remove unused code

* fix(trash-sync): refactor code

* fix(trash-sync): reformat file

* fix(trash_sync): refactor code

* fix(trash_sync): improve moving to trash

* refactor(trash_sync): integrate MANAGE_MEDIA permission request into login flow and advanced settings

* refactor(trash_sync): add additional checking for experimental trash sync flag and MANAGE_MEDIA permission.

* refactor(trash_sync): resolve merge conflicts

* refactor(trash_sync): fix format

* resolve merge conflicts
add await for alert dialog
add missed request

* refactor(trash_sync): rework MANAGE_MEDIA info widget
show rationale text in permission request alert dialog
refactor setting getter

* fix(trash_sync): restore missing text values

* fix(trash_sync): format file

* fix(trash_sync): check backup enabled and remove remote asset existence check

* fix(trash_sync): remove checking backup enabled
test(trash_sync): cover sync-stream trash/restore paths and dedupe mocks

* test(trash_sync): cover trash/restore flows for local_sync_service

* chore(e2e): restore test-assets submodule pointer

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-10 16:20:51 +00:00
bo0tzz
8a73de018c feat: mise monorepo tasks (#23691) 2025-11-10 15:55:15 +01:00
Jonathan Gilbert
d92df63f84 feat: random memories sort order (#20025) 2025-11-10 09:38:50 -05:00
Mees Frensel
9cc88ed2a6 feat: make memories slideshow duration configurable (#22783) 2025-11-08 17:46:43 -05:00
Noel S
853d19dc2d fix(mobile): Add fade-in to asset viewer transition (#23692)
Add fade-in animation
2025-11-07 17:13:43 -06:00
fabianbees
93ab42fa24 feat(mobile): Show lens model information in the asset viewer detail panel (#23601)
* feat(mobile): add lens info to details bottom sheet

* fix unrelated typo

* order same like in web app: first exposure time, than iso
2025-11-07 17:10:59 +00:00