Commit Graph

332 Commits

Author SHA1 Message Date
Min Idzelis 45ccdb37fb refactor(web): replace asset-viewer listener based face hover with overlay elements (#27400) 2026-04-27 12:08:34 +02:00
Jason Rasmussen a16d233a0c chore(web): sort imports (#27922)
* feat: sort imports

* fix: something?
2026-04-21 14:51:38 -04:00
Jason Rasmussen 4ffa26c969 feat: auth logout page (#27831)
* feat: auth logout page

* feat: skip login if already logged in
2026-04-15 16:33:52 -04:00
Jason Rasmussen fed5cc1ae1 feat: upgrade immich/ui (#27792) 2026-04-14 16:18:12 +00:00
Jason Rasmussen 1ba0989e15 refactor: auth manager (#27638) 2026-04-14 08:49:24 -04:00
Nicolas-micuda-becker 181b028b09 fix(web): keep upload totals stable when dismissing items (#27247) (#27354)
* fix(web): keep upload totals stable when dismissing items (#27247)

* chore: remove package-lock.json

---------

Co-authored-by: bwees <brandonwees@gmail.com>
2026-03-28 16:25:44 -05:00
Jason Rasmussen 9b80ffd9c6 refactor: selection mananger (#27325) 2026-03-27 12:41:52 -04:00
Min Idzelis 4b9ebc2cff refactor(web): migrate isFaceEditMode from standalone store to assetViewerManager (#27307) 2026-03-27 13:20:15 +01: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
Jason Rasmussen 7d58d5be12 refactor: memory manager (#27206) 2026-03-26 17:36:25 +00:00
Jason Rasmussen 7877097b3f refactor: asset viewing store (#27204) 2026-03-26 13:22:40 -04:00
Jason Rasmussen fb84c1cf61 chore: remove unused file (#27202) 2026-03-26 13:22:31 -04:00
Jason Rasmussen 940a1d4ab8 refactor: change location (#27201) 2026-03-26 13:22:14 -04:00
Nicolas-micuda-becker b98a227bbd fix(web): update upload summary when removing items (#27035) (#27139) 2026-03-23 10:02:09 -05:00
Michel Heusschen a47b232235 fix(web): refresh recent albums sidebar after album changes (#26757) 2026-03-09 17:11:32 +01:00
Paul Makles f94e0fbc39 fix(maintenance mode): wait for valid server config on restart (#26456)
Signed-off-by: izzy <me@insrt.uk>
2026-03-04 11:16:21 +00:00
Min Idzelis 4da3d68a67 refactor: use keyed each for face bounding boxes (#26648) 2026-03-02 22:16:13 -06: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
Michel Heusschen 30f6d4439e fix(web): prevent null folder tree on concurrent load (#26489) 2026-02-24 08:23:07 -05:00
Jason Rasmussen 1d11106dd0 refactor: add to album (#26366) 2026-02-19 15:27:30 -05:00
Michel Heusschen ceef65154d fix(web): clear cache when asset changes (#26257)
* fix(web): clear cache when asset changes

* formatting
2026-02-17 11:43:08 +01:00
Michel Heusschen ff7dca35f5 perf(web): speed up asset selection (#26216) 2026-02-14 15:31:04 -05:00
Jason Rasmussen 5bf4e9595c refactor: purchase store (#25734) 2026-02-12 13:32:17 -05:00
Michel Heusschen 1c1a000c78 fix(web): use locale for date picker (#26125) 2026-02-11 11:39:30 +01:00
Michel Heusschen a9e0fa43fa fix: correctly cancel select all assets (#26067) 2026-02-10 11:47:23 -05:00
Jason Rasmussen 10b53b525d refactor: event manager (#25565) 2026-01-29 08:52:18 -05:00
Jason Rasmussen e81faa1dbf fix: memory lane (#25652) 2026-01-28 15:51:13 -06:00
Min Idzelis 646bb372ab feat: add onMany to BaseEventManager (#25492)
Use a map of events instead of array of tuples for better ergonomics.
2026-01-26 10:34:26 -05:00
Avalanche Ridings 497003ec57 feat: loop slideshows (#25462)
* Add Repeat to the slideshow in the web UI.

* Fix typo in SlideshowSettingsModal description prop

Fixed spelling

---------

Co-authored-by: generalzero <generalzero@generalzero.org>
2026-01-24 04:09:29 +00:00
Min Idzelis d0d269677e refactor: rename mobileDevice to mediaQueryManager (#25464) 2026-01-23 20:55:10 -06:00
Jason Rasmussen 4fedae4150 refactor: event manager (#25481)
* refactor: event manager

* fix: broken downloadFile endpoint
2026-01-23 18:02:23 -05:00
Jason Rasmussen b52e8cd570 refactor: asset navbar (#25480) 2026-01-23 16:19:46 -05:00
Jason Rasmussen 6d9dc46619 chore: include sync dtos (#25470) 2026-01-23 14:24:25 +00:00
Min Idzelis 84679fb2b2 refactor: use assetCacheManager for OCR data (#25437) 2026-01-22 21:12:56 -06:00
Jason Rasmussen 417af66f30 refactor(web): on person thumbnail (#25422) 2026-01-21 13:13:02 -05:00
Paul Makles 61a9d5cbc7 feat: restore database backups (#23978)
* feat: ProcessRepository#createSpawnDuplexStream

* test: write tests for ProcessRepository#createSpawnDuplexStream

* feat: StorageRepository#createGzip,createGunzip,createPlainReadStream

* feat: backups util (args, create, restore, progress)

* feat: wait on maintenance operation lock on boot

* chore: use backup util from backup.service.ts
test: update backup.service.ts tests with new util

* feat: list/delete backups (maintenance services)

* chore: open api
fix: missing action in cli.service.ts

* chore: add missing repositories to MaintenanceModule

* refactor: move logSecret into module init

* feat: initialise StorageCore in maintenance mode

* feat: authenticate websocket requests in maintenance mode

* test: add mock for new storage fns

* feat: add MaintenanceEphemeralStateRepository
refactor: cache the secret in memory

* test: update service worker tests

* feat: add external maintenance mode status

* feat: synchronised status, restore db action

* test: backup restore service tests

* refactor: DRY end maintenance

* feat: list and delete backup routes

* feat: start action on boot

* fix: should set status on restore end

* refactor: add maintenanceStore to hold writables

* feat: sync status to web app

* feat: web impl.

* test: various utils for testings

* test: web e2e tests

* test: e2e maintenance spec

* test: update cli spec

* chore: e2e lint

* chore: lint fixes

* chore: lint fixes

* feat: start restore flow route

* test: update e2e tests

* chore: remove neon lights on maintenance action pages

* fix: use 'startRestoreFlow' on onboarding page

* chore: ignore any library folder in `docker/`

* fix: load status on boot

* feat: upload backups

* refactor: permit any .sql(.gz) to be listed/restored

* feat: download backups from list

* fix: permit uploading just .sql files

* feat: restore just .sql files

* fix: don't show backups list if logged out

* feat: system integrity check in restore flow

* test: not providing failed backups in API anymore

* test: util should also not try to use failedBackups

* fix: actually assign inputStream

* test: correct test backup prep.

* fix: ensure task is defined to show error

* test: fix docker cp command

* test: update e2e web spec to select next button

* test: update e2e api tests

* test: refactor timeouts

* chore: remove `showDelete` from maint. settings

* chore: lint

* chore: lint

* fix: make sure backups are correctly sorted for clean up

* test: update service spec

* test: adjust e2e timeout

* test: increase web timeouts for ci

* chore: move gitignore changes

* chore: additional filename validation

* refactor: better typings for integrity API

* feat: higher accuracy progress tracking

* chore: delay lock retry

* refactor: remove old maintenance settings

* refactor: clean up tailwind classes

* refactor: use while loop rather than recursive calls

* test: update service specs

* chore: check canParse too

* chore: lint

* fix: logic error causing infinite loop

* refactor: use <ProgressBar /> from ui library

* fix: create or overwrite file

* chore: i18n pass, update progress bar

* fix: wrong translation string

* chore: update colour variables

* test: update web test for new maint. page

* chore: format, fix key

* test: update tests to be more linter complaint & use new routines

* chore: update onClick -> onAction, title -> breadcrumbs

* fix: use wrench icon in admin settings sidebar

* chore: add translation strings to accordion

* chore: lint

* refactor: move maintenance worker init into service

* refactor: `maintenanceStatus` -> `getMaintenanceStatus`
refactor: `integrityCheck` -> `detectPriorInstall`
chore: add `v2.4.0` version
refactor: `/backups/list` -> `/backups`
refactor: use sendFile in download route
refactor: use separate backups permissions
chore: correct descriptions
refactor: permit handler that doesn't return promise for sendfile

* refactor: move status impl into service
refactor: add active flag to maintenance status

* refactor: split into database backup controller

* test: split api e2e tests and passing

* fix: move end button into authed default maint page

* fix: also show in restore flow

* fix: import getMaintenanceStatus

* test: split web e2e tests

* refactor: ensure detect install is consistently named

* chore: ensure admin for detect install while out of maint.

* refactor: remove state repository

* test: update maint. worker service spec

* test: split backup service spec

* refactor: rename db backup routes

* refactor: instead of param, allow bulk backup deletion

* test: update sdk use in e2e test

* test: correct deleteBackup call

* fix: correct type for serverinstall response dto

* chore: validate filename for deletion

* test: wip

* test: backups no longer take path param

* refactor: scope util to database-backups instead of backups

* fix: update worker controller with new route

* chore: use new admin page actions

* chore: remove stray comment

* test: rename outdated test

* refactor: getter pattern for maintenance secret

* refactor: `createSpawnDuplexStream` -> `spawnDuplexStream`

* refactor: prefer `Object.assign`

* refactor: remove useless try {} block

* refactor: prefer `type Props`
refactor: prefer arrow function

* refactor: use luxon API for minutesAgo

* chore: remove change to gitignore

* refactor: prefer `type Props`

* refactor: remove async from onMount

* refactor: use luxon toRelative for relative time

* refactor: duplicate logic check

* chore: open api

* refactor: begin moving code into web//services

* refactor: don't use template string with $t

* test: use dialog role to match prompt

* refactor: split actions into flow/restore

* test: fix action value

* refactor: move more service calls into web//services

* chore: should void fn return

* chore: bump 2.4.0 to 2.5.0 in controller

* chore: bump 2.4.0 to 2.5.0 in controller

* refactor: use events for web//services

* chore: open api

* chore: open api

* refactor: don't await returned promise

* refactor: remove redundant check

* refactor: add `type: command` to actions

* refactor: split backup entries into own component

* refactor: split restore flow into separate components

* refactor(web): split BackupDelete event

* chore: stylings

* chore: stylings

* fix: don't log query failure on first boot

* feat: support pg_dumpall backups

* feat: display information about each backup

* chore: i18n

* feat: rollback to restore point on migrations failure

* feat: health check after restore

* chore: format

* refactor: split health check into separate function

* refactor: split health into repository
test: write tests covering rollbacks

* fix: omit 'health' requirement from createDbBackup

* test(e2e): rollback test

* fix: wrap text in backup entry

* fix: don't shrink context menu button

* fix: correct CREATE DB syntax for postgres

* test: rename backups generated by test

* feat: add filesize to backup response dto

* feat: restore list

* feat: ui work

* fix: e2e test

* fix: e2e test

* pr feedback

* pr feedback

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-01-20 09:22:28 -06:00
Min Idzelis ca0d4b283a feat: zoom image improvements for reactive prop handlings (#25286) 2026-01-20 13:18:54 +01:00
Brandon Wees 1b56bb84f9 fix: mobile edit handling (#25315)
Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
2026-01-19 12:22:53 -06:00
Jason Rasmussen 4a7c4b6d15 refactor(web): routes (#25365) 2026-01-19 12:07:31 -05:00
Min Idzelis 80a5444bf4 feat: redesign asset-viewer previous/next and hide when nav not possible (#24903) 2026-01-15 12:55:01 +01:00
Brandon Wees e8c80d88a5 feat: image editing (#24155) 2026-01-09 17:59:52 -05:00
Jason Rasmussen fbd49e0b79 refactor: memory lane (#25134) 2026-01-08 12:40:17 -05:00
Min Idzelis 78229baeab feat: improve asset-viewer next/prev perf and standardize preloading behavior (#24422)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-01-07 21:17:12 +01:00
Jason Rasmussen 984f06ac40 refactor: asset viewer (#25059) 2026-01-05 21:02:01 +00:00
Jason Rasmussen c7510d572a chore: move models (#24778) 2025-12-22 15:23:57 +00:00
Min Idzelis 00290e1e71 feat: make OCR store reentrant-safe (#24419) 2025-12-15 21:06:04 -06:00
Daniel Dietzler 8755cd59fd chore: refactor svelte reactivity (#24072) 2025-11-24 18:57:46 -05:00
Jason Rasmussen 9a403d5886 refactor(web): user delete websocket event (#24015) 2025-11-20 07:54:29 -05:00
Jason Rasmussen 1a31faf1a2 fix: effect loop (#24014) 2025-11-20 07:52:37 -05:00
Alex 56e431226f feat: show OCR bounding box (#23717)
* feat: ocr bounding box

* bounding boxes

* pr feedback

* pr feedback

* allow copy across text boxes

* pr feedback
2025-11-19 15:52:40 +00:00