Compare commits

..

253 Commits

Author SHA1 Message Date
Hosted Weblate 02df29a15b chore(web): update translations
Co-authored-by: -J- <heyj0e@tuta.io>
Co-authored-by: 12LuA <Luca.strack@gmx.de>
Co-authored-by: AM <alex2539rulez@yahoo.com>
Co-authored-by: Abdel rahman Abdaldeen <abd.abdaldeen@gmail.com>
Co-authored-by: Abhijeet Bonde <abhijeetbonde19@gmail.com>
Co-authored-by: Adam Havránek <adamhavra@seznam.cz>
Co-authored-by: Ahmed Khaleel Shihab <ahmed91shihab@gmail.com>
Co-authored-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com>
Co-authored-by: Alessandro Mandelli <mandelli.alessandro@ngi.it>
Co-authored-by: Alex <darkstylo@gmail.com>
Co-authored-by: Alvaro Samudio <alvarosamudio1@gmail.com>
Co-authored-by: Andreas Fjetland <andreas@fjet.no>
Co-authored-by: Andreas W. Pross <andreas.pross@styletronix.net>
Co-authored-by: AntonPalmqvist <apq@users.noreply.hosted.weblate.org>
Co-authored-by: Antonio Labate <antoniolabate19@gmail.com>
Co-authored-by: Arif Budiman <arifpedia@gmail.com>
Co-authored-by: Avihai Zarouk <myaulamyau@gmail.com>
Co-authored-by: Bartłomiej <20731216+Jarsey45@users.noreply.github.com>
Co-authored-by: Bas Wevers <baswevers@gmail.com>
Co-authored-by: Bat-Uyanga Batdelger <batuyanga@gmail.com>
Co-authored-by: Benjamin Serec <serec.benjamin@gmail.com>
Co-authored-by: Bonnie 20402 <darioperreira2013@gmail.com>
Co-authored-by: Bora Atıcı <boratici.acc@gmail.com>
Co-authored-by: BrekkeLiten <david@brek.ke>
Co-authored-by: Calvin Erfmann <calvin.erfmann@pm.me>
Co-authored-by: Carlo Beltrame <weblate@pendantmusic.ch>
Co-authored-by: Charles Frégeau <fregeauc@outlook.com>
Co-authored-by: Climent Fernández Andújar <climentfean@gmail.com>
Co-authored-by: Clément Pingliez <pingliezclement@gmail.com>
Co-authored-by: Cédric <cedric@laubacher.io>
Co-authored-by: D S <weblate.2w8z9@slmail.me>
Co-authored-by: Dan <rattly@duck.com>
Co-authored-by: David Bono <dbono2454@gmail.com>
Co-authored-by: David Maneiro <david.maneiro8@gmail.com>
Co-authored-by: David Miguel Rodrigues Rosa <dmr.rosa@gmail.com>
Co-authored-by: Denis Pacquier <denis.pacquier@gmail.com>
Co-authored-by: DevServs <bonov@mail.ru>
Co-authored-by: Dmitry Banny <dj.icecore@gmail.com>
Co-authored-by: Don't use my name <maxabmeyer@gmail.com>
Co-authored-by: Dusan Hlavaty <dhlavaty@gmail.com>
Co-authored-by: Dániel Gál <galdaniel.school@gmail.com>
Co-authored-by: Elyas Sindi <elyassindi@proton.me>
Co-authored-by: Enric Pagès i Gassull <enricpages@hotmail.com>
Co-authored-by: Felix Noren <fnoren17@gmail.com>
Co-authored-by: Filipe Monteiro <pimonteiro@protonmail.com>
Co-authored-by: Fjuro <fjuro@users.noreply.hosted.weblate.org>
Co-authored-by: Focron <eliaelmas55@gmail.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Gnubblz <philipp@phild.de>
Co-authored-by: HackingAll <hacking.all.YT@gmail.com>
Co-authored-by: Hamza Foziljonov <hamza.uztranslator@gmail.com>
Co-authored-by: Hans Cats <hanscats@gmail.com>
Co-authored-by: Happy <59247878+happy2452354@users.noreply.github.com>
Co-authored-by: Haru Ijima <haruijimakun@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Hurricane_32 <rodrigorimo@hotmail.com>
Co-authored-by: Indrek Haav <indrekhaav@users.noreply.hosted.weblate.org>
Co-authored-by: Iren <iren.biggel@gmail.com>
Co-authored-by: Ivan Dimitrov <idimitrov08@gmail.com>
Co-authored-by: JPar99 <github.wad969@passmail.com>
Co-authored-by: Jarle K. Hopland <jarlekh@gmail.com>
Co-authored-by: Jayson <mrjaysonbulugagao@gmail.com>
Co-authored-by: Jeanré du Plessis <jeanreduplessis2000@gmail.com>
Co-authored-by: Jedediah Russell <john17three@protonmail.com>
Co-authored-by: Jeppe Nellemann <jepnel@proton.me>
Co-authored-by: Joel Molina Navarro <joelmolinanavarro21@gmail.com>
Co-authored-by: Jozef Gaal <preklady@mayday.sk>
Co-authored-by: KecskeTech <teonyitas@gmail.com>
Co-authored-by: Kristian Franceschini <kristian@kmsfhost.com>
Co-authored-by: Leo Bottaro <github@leobottaro.com>
Co-authored-by: Loonatiq <Loona9422@pm.me>
Co-authored-by: Lorenz Schmid <schmidlorenz@gmx.ch>
Co-authored-by: MSDNicrosoft <i@msdnicrosoft.work>
Co-authored-by: Manfred Bjørlin <manfred.bjorlin@gmail.com>
Co-authored-by: MarcSerraPeralta <marcserraperalta@gmail.com>
Co-authored-by: Marco Janssen <Marco@neverminds.net>
Co-authored-by: Marco Mertel <mertel.marco@gmail.com>
Co-authored-by: Marian Wolf <marian.wolf2008@gmail.com>
Co-authored-by: Matjaž T. <matjaz@moj-svet.si>
Co-authored-by: Matteo Morari <matteo.morari04@gmail.com>
Co-authored-by: Matthias Cramer <matthias.cramer@iway.ch>
Co-authored-by: Maxi Herczegh <maxiherczegh@outlook.com>
Co-authored-by: Maćvej Pažytnykh <ma.pazhitnykh@gmail.com>
Co-authored-by: Mees Frensel <meesfrensel@gmail.com>
Co-authored-by: Melih Ozkan <malihozkan156@gmail.com>
Co-authored-by: Mike Moolenaar <mike.moolenaar@posteo.nl>
Co-authored-by: Molnár Bence Attila <it@bence0327.hu>
Co-authored-by: Mona Lisa <monalisa@users.noreply.hosted.weblate.org>
Co-authored-by: Mona Lisa <nickwick@users.noreply.hosted.weblate.org>
Co-authored-by: Mārtiņš Bruņenieks <martinsb@gmail.com>
Co-authored-by: NAL <niko.a.leinonen@gmail.com>
Co-authored-by: Nandhakumar Subramanian <nandha.kumar790@gmail.com>
Co-authored-by: Nuno Aparicio <nunoxyz@gmail.com>
Co-authored-by: OffsetMonkey538 <offsetmonkey538@gmail.com>
Co-authored-by: Oleksandr Yurov <oyurov@icloud.com>
Co-authored-by: Osama <laptooxz@proton.me>
Co-authored-by: PPNplus <ppnplus@protonmail.com>
Co-authored-by: Patrick Raths <piroh1990@gmail.com>
Co-authored-by: Pavel Miniutka <pavel.miniutka@gmail.com>
Co-authored-by: Pavlo Sydoriuk <sidopas@gmail.com>
Co-authored-by: Pazystamas <pazystamas@gmail.com>
Co-authored-by: Petri Hämäläinen <petri.hamalainen@mailbox.org>
Co-authored-by: Phillip Kang <phillipxkang@gmail.com>
Co-authored-by: Piero Bi <biagini93@ik.me>
Co-authored-by: PilgrimToHyperion <pilgrimtohyperion@gmail.com>
Co-authored-by: Piotr Pazhytnykh <pazhitnykhpetr@gmail.com>
Co-authored-by: PontusÖsterlindh <pontus@osterlindh.com>
Co-authored-by: Raul <raul.plesa@gmail.com>
Co-authored-by: Ravuru Umesh <umeshravuru@gmail.com>
Co-authored-by: Remco <remco@pander.io>
Co-authored-by: Ricardo Tomazela do Prado <kao.prado@gmail.com>
Co-authored-by: Richiondrugs <riccardocastellano07@gmail.com>
Co-authored-by: Robert Virkus <robert.virkus@enough.de>
Co-authored-by: Roger Pueyo Centelles <roger.pueyo@guifi.net>
Co-authored-by: Sebastian <sebastiankiwidk@gmail.com>
Co-authored-by: Seungbeom Ha <tmdqja75@gmail.com>
Co-authored-by: Shaw <shawyunz@gmail.com>
Co-authored-by: Simone Ognibene <ognibene2001@gmail.com>
Co-authored-by: Steffen Seubert <seubert.steffen@gmail.com>
Co-authored-by: Sylvain Pichon <service@spichon.fr>
Co-authored-by: TA <tobi@warsnich.de>
Co-authored-by: Taleh Rzayev <talehji@gmail.com>
Co-authored-by: Thomas van Gemert <dendolla@users.noreply.hosted.weblate.org>
Co-authored-by: Thế Anh Hoàng <the.anh.ls@gmail.com>
Co-authored-by: Tim Morley <weblate.3919org@timsk.org>
Co-authored-by: Tom Mueller <muellertomgabsnichtmehr@gmail.com>
Co-authored-by: Tomislav Renić <trenic@gmail.com>
Co-authored-by: UDP <udp@users.noreply.hosted.weblate.org>
Co-authored-by: Ulices <hasecilu@tuta.io>
Co-authored-by: User 123456789 <user123456789@users.noreply.hosted.weblate.org>
Co-authored-by: VRADDB <dimitri.debruyne@vanroey.be>
Co-authored-by: Vegard Fladby <vegard@fladby.org>
Co-authored-by: Vishal Ghelani <vishal.ghelani@gmail.com>
Co-authored-by: WellsTsai <dan50907@gmail.com>
Co-authored-by: Yago Raña Gayoso <yago.rana.gayoso@gmail.com>
Co-authored-by: Yohsi <yohan.simard@proton.me>
Co-authored-by: Yolopix <13918281+y0lopix@users.noreply.github.com>
Co-authored-by: Yusuf Soyipek <yusuf@soyipek.com>
Co-authored-by: Zhigang Wu <wu.zhigang@xuan-ming.net>
Co-authored-by: Zillazapdos <harald.vagle.undheim@icloud.com>
Co-authored-by: adun <github.scariness216@passinbox.com>
Co-authored-by: anton garcias <isaga.percompartir@gmail.com>
Co-authored-by: arvissidorovs <arvis.sidorovs@gmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: bosund <bosund@gmail.com>
Co-authored-by: chamdim <chamdim@protonmail.com>
Co-authored-by: daniqss <danielqueijo14@gmail.com>
Co-authored-by: david7xw <davdavid7xw@gmail.com>
Co-authored-by: dkorecko <github@david.korecko.com>
Co-authored-by: eav5jhl0 <eav5jhl0@users.noreply.hosted.weblate.org>
Co-authored-by: fascinate722 <fascinate722@gmail.com>
Co-authored-by: guillermo <guillermoremesa@gmail.com>
Co-authored-by: h1nnak <gerlich@mailbox.org>
Co-authored-by: iwonder <iwonder@users.noreply.hosted.weblate.org>
Co-authored-by: jasoisjaso <jaso.bih@gmail.com>
Co-authored-by: jicetus. <jicetus@users.noreply.hosted.weblate.org>
Co-authored-by: jmilovic <krunazajecar@gmail.com>
Co-authored-by: josuloo99 <josuloidi1999@gmail.com>
Co-authored-by: kylo32 <kylo32@gmail.com>
Co-authored-by: miiyuh <itsazripp2@gmail.com>
Co-authored-by: millallo <millallo@tiscali.it>
Co-authored-by: muziqaz <muziqaz@users.noreply.hosted.weblate.org>
Co-authored-by: oliwia <mroskarez@gmail.com>
Co-authored-by: on9686 <on9686@gmail.com>
Co-authored-by: outsider-tabby-pox <outsider-tabby-pox@duck.com>
Co-authored-by: pneuly <pneuly@gmail.com>
Co-authored-by: pyccl <changcongliang@163.com>
Co-authored-by: s0nprem0 <s0nprem0@proton.me>
Co-authored-by: scudo <whiteshield.tg@protonmail.com>
Co-authored-by: slick-daddy <129640104+slick-daddy@users.noreply.github.com>
Co-authored-by: tct123 <tct1234@protonmail.com>
Co-authored-by: traumanndylan <traumanndylan@gmail.com>
Co-authored-by: tvirolai <tuomo.virolainen@rebase.fi>
Co-authored-by: veiskiboi <vesahok@gmail.com>
Co-authored-by: waclaw66 <waclaw66@seznam.cz>
Co-authored-by: x0x0b <42596409+x0x0b@users.noreply.github.com>
Co-authored-by: Вячеслав Лукьяненко <madeinchuguev@gmail.com>
Co-authored-by: Сергій Савчук <serge.savchuk@gmail.com>
Co-authored-by: 星 <seirun124@gmail.com>
Co-authored-by: 정동걸 <i.jdk.dev@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/immich/immich/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/af/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ar/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/az/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/be/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/bg/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ca/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/cs/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/da/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/de/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/de_CH/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/el/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/eo/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/es/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/et/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/eu/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fil/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ga/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/gl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/gsw/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/gu/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/he/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hu/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/id/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/it/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ja/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ko/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/mn/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/mr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ms/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ro/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ru/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sr_Latn/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ta/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/te/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/th/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/tr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/uk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/uz/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/vi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_Hant/
Translation: Immich/immich
2026-06-04 10:01:07 +02:00
Santo Shakil 429e181c8f fix(mobile): run iOS bg task phases in parallel (#28293)
onIosUpload runs sync local, sync remote, hash and handle backup
sequentially. on the bg refresh task path that's a 20s budget from
iOS, and sync + hash usually eat all of it before backup gets a turn
to enqueue any candidates.

these phases don't actually depend on each other. local + remote sync
touch different tables. hash works off whatever's already in drift.
handle backup reads candidates and just enqueues to URLSession bg.
anything one phase produces in this fire shows up to the others on
the next fire, and server-side dedup catches the rare race where
backup enqueues something sync remote was about to mark as already
uploaded.

so this runs all four concurrently via Future.wait, with hash getting
the full maxSeconds-1 budget instead of a fixed 5s. outer budget
timeout still caps everything before iOS expires.

second small change: getAssetsToHash orders by createdAt DESC instead
of id ASC to match getCandidates. when hash runs inside a refresh
fire it processes recent photos first.
2026-06-03 20:13:52 -05:00
winston 7f611d9031 test: fix tests when OpenVINO provider is available (#28802)
mocking `onnxruntime.get_available_providers()` to always use the CPU EP.
2026-06-03 20:52:08 -04:00
Timon e94e22f3f8 fix(server): respect timezone in iso date string encoding (#28810) 2026-06-03 19:00:10 -04:00
Timon 4a8c3b60be fix(mobile): clear album description sends null instead of empty string (#28817) 2026-06-03 18:22:19 -04:00
Timon 2190aa72a8 refactor(server): zod int validation (#28804) 2026-06-03 18:21:07 -04:00
Timon d21cb28526 fix(mobile): shared link edit sends explicit null instead of empty string (#28812)
* fix(mobile): clear shared link password

* fix(mobile): clear shared link description

* fix(mobile): clear shared link expiry
2026-06-03 18:19:35 -04:00
Timon 5c33eb3204 refactor(server)!: drop empty string to null conversion (#28808)
refactor(server): drop empty string to null conversion
2026-06-03 18:16:53 -04:00
Mert 137687bc0f fix(web): set src for progressive video player (#28813)
set src
2026-06-03 17:07:23 -04:00
Peter Ombodi 9d4a6614b1 feat(mobile): Android. Immich as a gallery / image viewer app (#26109)
* feat(mobile): handle Android ACTION_VIEW intent
- add ViewIntent Pigeon API and generated bindings
- implement Android ViewIntentPlugin + iOS no-op host
- route ExternalMediaViewer by ViewIntentAttachment
- buffer pending view intents and flush on user ready/resume

* feat(mobile): fallback to computed checksum for timeline match
- hash local asset on-demand when checksum missing
- search main timeline by localId or checksum before standalone viewer
- persist computed hash into local_asset_entity

* fix(mobile): proper handling is user authenticated

* feat(mobile): open ACTION_VIEW fallback in AssetViewer
drop ExternalMediaViewer route

* feat(mobile): add logger

* test(mobile): add unit tests for view intent pending/flush flow

* fix(mobile): fix format

* fix(mobile): remove redundant iOS code
update code related to LocalAsset model and asset viewer

* refactor(mobile): simplify view intent flow and support file-backed ACTION_VIEW assets
remove redundant view intent model/repository layer
handle transient ACTION_VIEW files in viewer/upload flow
clean up managed temp files for fallback assets

* refactor(mobile): extract MediaStore utils and resolve view intents via merged assets

* refactor(mobile): move deferred view intents into providers, split view-intent providers, and clean up ACTION_VIEW handling

* refactor(mobile): resolve merge conflicts
use NativeSyncApi for hash files instead method from removed BackgroundServicePlugin.kt

* style(mobile): format files

* style(mobile): format files #2

* refactor(mobile): lazily materialize view-intent files and clean up temp-file handling

* fix(mobile): flush pending view intents after login navigation

* refactor(mobile): split view intent handler by platform and trigger it from app events

* refactor(mobile): move view intent handling behind platform-specific factories

* refactor(mobile): simplify code

* fix(mobile): hand off deep-link viewer to main timeline after upload
Add MainTimelineHandoffCoordinator to switch the asset viewer to the main timeline once a view-intent asset is uploaded and becomes available, and guard viewer reload/navigation transitions to avoid race conditions and crashes.

* refactor(mobile): use remote asset ids for view intent handoff and simplify resolver

* refactor(mobile): resolve merge conflicts

* style(mobile): reformat code

* style(mobile): reformat code #2

* fix(mobile): stabilize Android view intent asset resolution and fallback viewer

* refactor(mobile): share AssetViewer pre-navigation state preparation

* fix(mobile): wait for main timeline before deferred view intent handoff

* refactor(mobile): decouple view intent asset resolver from providers

* fix(mobile): avoid double pop when canceling upload dialog

* fix(mobile): resolve view intent MIME type with fallbacks

* docs(mobile): clarify view intent fallback asset TODO

* fix(mobile): resolve merge conflicts

* cleanup

* lint

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2026-06-03 12:05:52 -05:00
Jason Rasmussen e4352a7817 fix: error log on aborted uploads (#28806) 2026-06-03 12:47:38 -04:00
shenlong 911dde39c9 ci: verify mobile backward compatibility (#28786)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-06-03 15:21:23 +00:00
moversity afa836181c fix(cli): prevent out-of-memory on file upload due to undici storing the request body (#28723)
fix(cli): add fetch param to prevent OOM of upload

Issue due to undici storing the entire request body in memory.
Related undici bug report: https://github.com/nodejs/undici/issues/4058

Fixes https://github.com/immich-app/immich/issues/28720

Signed-off-by: moversity <148445403+moversity@users.noreply.github.com>
2026-06-03 15:19:35 +00:00
Mert 963862b1b9 fix(mobile): proper background task cleanup (#28694)
* event-based cancellation

wire hash cancellation

await cleanup

remove forced kill

add regression tests

abort sync requests

fix cleanup ordering in teardown

exit isolate

test background sync

test sigabrt crash

cleanup

* abort local sync
2026-06-03 08:16:19 -04:00
Timon 96d521e149 feat(mobile): add three-state field serialization (#27231)
* bump to v7.22.0 and update patching

* gen client

* migrate mobile call sites
2026-06-03 08:13:17 -04:00
shenlong 1bb7517da0 chore: pump flutter to 3.44.1 (#28785)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-06-02 23:45:31 -05:00
shenlong 814c2e32e4 chore: patch minFaces and realtimeTranscoding (#28784)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-06-03 09:15:31 +05:30
immich-tofu[bot] 92841f311f Added Code of conduct 2026-06-02 21:57:50 +00:00
immich-tofu[bot] 9d2e576630 chore: modify .github/FUNDING.yml 2026-06-02 21:57:47 +00:00
immich-tofu[bot] 936418a464 chore: use immich.app email for security reports (#10594)
chore: use  immich.app email for security reports
2026-06-02 21:57:45 +00:00
Daniel Dietzler 84c75d95c7 fix: migration order (#28779) 2026-06-02 21:33:13 +00:00
shenlong 9287fa08c6 fix!: unauthorized face creation (#28561)
* fix: unauthorized face creation

* review changes

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-06-02 22:44:11 +05:30
renovate[bot] 408e1180ca chore(deps): update machine-learning (#28239)
* chore(deps): update machine-learning

* fix typing

* fix deprecation log

* no control socket

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
2026-06-02 16:44:50 +00:00
renovate[bot] 07f19d2caa chore(deps): update base-image to v202606021219 (#28771) 2026-06-02 18:31:52 +02:00
Tim Jones 368cb7a4ad feat: minimum face count per user (#27452)
* add user metadata table and use to filter persons in person.getAllForUser query

* update PersonRepository.getAllForUser query

* remove minFaces from PersonSearchOptions interface

* fix person.getAllForUser query

* update types and openapi specs

* add minFaces field to user settings page

* remove old arg from tests

* add e2e test to verify minimumFace user preference

* add i18n label and description for english

* update default min faces

* fetch minFaces ML default and use as per-user default in frontend

* update e2e tests

* fix bugs in people getAllForUser query

* update person getNumberOfPeople query to reflect correct number of people according to minFaces threshold

* updated mobile openapi specs?

* use subquery in coalesce instead of join

* remove out of scope query update
2026-06-02 18:05:55 +02:00
Timon 109e0a7ad0 fix(mobile): invisible ink splashes in asset sheet (#28756) 2026-06-02 10:37:20 -05:00
Timon 59750dad7d feat: places in context search (#28768) 2026-06-02 17:19:59 +02:00
okxint 13ecfc8876 fix(web): prevent partner assets from being selected in geolocation utility (#28737)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-06-02 15:05:15 +00:00
Min Idzelis 65d8b35f8b refactor(web): align gallery-viewer viewport naming and tunables (#28743) 2026-06-02 14:54:44 +02:00
renovate[bot] 942d3c648c chore(deps): lock file maintenance (npm) (#28729) 2026-06-02 14:51:55 +02:00
renovate[bot] 82db8be5ff chore(deps): update dependency testcontainers to v12 (#28763) 2026-06-02 12:05:42 +00:00
Min Idzelis 03554b24ad fix(web): skip thumbhash fade for offscreen thumbnails (#27335) 2026-06-02 13:42:33 +02:00
renovate[bot] c5fb67c004 chore(deps): update dependency prettier-plugin-svelte to v4 (#28762) 2026-06-02 13:38:57 +02:00
renovate[bot] 40983b46c8 chore(deps): update dependency @vitest/coverage-v8 to v4 (#28761) 2026-06-02 13:37:34 +02:00
renovate[bot] 5dcdbf04ea chore(deps): update base-image to v202605121138 (#28760) 2026-06-02 11:47:20 +02:00
renovate[bot] da8ed3eceb chore(deps): update docker.io/valkey/valkey:9 docker digest to 4963247 (#28622) 2026-06-02 08:09:27 +00:00
renovate[bot] 2afde23a5d chore(deps): update github-actions (#28750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-02 00:39:19 -04:00
renovate[bot] d57a152040 chore(deps): update prom/prometheus docker digest to 69f5241 (#28757)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-02 00:37:42 -04:00
renovate[bot] 728e92ea33 chore(deps): update dependency @immich/ui to v0.79.3 (#28758)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-02 00:37:10 -04:00
Mert 138e2d9158 feat(web): hls player (#28312)
* update e2e

* hls player

* fix transcoding restart on explicit quality selection

* move level filtering to manager

* move init to manager declaration

* refactor commit on release

* these lints...

* fix seek sometimes being ignored

* fix panic downswitch
2026-06-01 15:49:57 -04:00
Mert 7eabac6702 feat(server): hls with real-time transcoding (#28230)
* hls implementation

* fix stale state after ffmpeg exit
2026-06-01 18:52:29 +00:00
renovate[bot] cf4789e008 chore(deps): update github-actions (major) (#28752) 2026-06-01 18:35:36 +00:00
renovate[bot] 412884fce3 chore(deps): update ghcr.io/jdx/mise docker tag to v2026.5.18 (#28749) 2026-06-01 19:47:53 +02:00
Jason Rasmussen 16aee2b869 fix: album name (#28751) 2026-06-01 19:45:24 +02:00
Daniel Dietzler 3f7af51531 fix: version check (#28746) 2026-06-01 13:41:08 -04:00
Brandon Wees 4eb100327e fix: disallow cross origin/non http protocols for continueUrl on login (#28706)
* fix: disallow cross origin/non http protocols for continueUrl on login

* chore: use Route helper

* fix: also use Route.continue in pin code prompt

* fix: typecheck
2026-06-01 13:38:26 -04:00
bo0tzz 69b1946484 feat: handle prereleases in publish workflows (#28701) 2026-06-01 17:11:45 +02:00
bo0tzz 61cd69a286 fix: strip rc suffix from iOS marketing version (#28741) 2026-06-01 09:56:43 -05:00
Daniel Dietzler c8a1d0e400 feat: release candidate support (#28665)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-06-01 16:10:07 +02:00
Paul Makles d120444a87 fix(devcontainer): update build cache volume (#28736) 2026-06-01 12:41:53 +00:00
shenlong 2382894fa2 fix: auto route rebuild on settings change (#28717)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-31 09:00:37 -05:00
Alex a52e7dc11a chore: feat iOS run debug build (#28712)
# Conflicts:
#	mobile/ios/Runner.xcodeproj/project.pbxproj
2026-05-31 04:10:03 +00:00
Alex 206992605e feat: upload local assets to album from bottom sheet (#28531)
* feat: upload local assets to album from bottom sheet

* Cancel token

* refactor

* refactor

* Update mobile/lib/domain/services/remote_album.service.dart

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

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2026-05-30 13:14:49 -05:00
Mert 65611bb860 chore(mobile): make openapi requests abortable (#28692)
make open-api requests abortable
2026-05-30 10:31:17 -05:00
shenlong 14aff51da9 refactor: rename metadata to settings (#28691)
rename metadata to settings

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-30 10:27:55 -05:00
shenlong c42cea5ca9 refactor: use widget previews for ui showcase (#28548)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-29 20:22:47 +00:00
Jason Rasmussen da8505f61d feat: more plugin triggers and methods (#28690) 2026-05-29 14:02:07 -04:00
Alex 58586483dc feat: render album's name in workflow step card (#28680)
* feat: render album name in step card body

* clean up

* i18n
2026-05-29 10:37:37 -05:00
pneuly a838167f11 fix(ml): pass model_root_dir to OcrOptions for RapidOCR compatibility (#28610)
* fix(ml): pass model_root_dir to OcrOptions for RapidOCR compatibility

Fix a TypeError (Path(None)) when the OCR model is invoked, caused by an upstream change in RapidOCR v3.8.1 (RapidAI/RapidOCR@8ea9626).
RapidOCR now internally calls `Path(cfg.get("model_root_dir"))`. Since `model_root_dir` was missing from `OcrOptions`, it evaluated to `None` and triggered a `TypeError: argument should be a str or an os.PathLike`.
This fix adds the missing `model_root_dir` argument to prevent the error.
Ref: #28331

* fix(ml-test): update OCR tests for RapidOCR schema change

* chore(ml-test): remove unused `cache_dir` parameter from `TextRecognizer`

* Revert "chore(ml-test): remove unused `cache_dir` parameter from `TextRecognizer`"

This reverts commit 007ad7b3f2.

* fix(ml): use self.cache_dir for model_root_dir in OcrOptions
2026-05-28 22:54:04 -04:00
Mert b189fc571c fix: make ts a peer dependency for swagger (#28677)
make ts a peer dependency
2026-05-28 22:04:25 +00:00
Jason Rasmussen 96923f6115 refactor: plugin sdk types (#28674) 2026-05-28 22:04:15 +00:00
shenlong 0d6cce4a5b fix: api repositories using stale endpoint (#28667)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-28 16:44:11 -05:00
shenlong 55947cb227 refactor: drop metadata scope (#28668)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-28 16:42:59 -05:00
Jason Rasmussen 8783180cf3 refactor: plugin manifest (#28673) 2026-05-28 17:23:49 -04:00
Jason Rasmussen 134c0d4dfb feat: search by album name and id (#28672) 2026-05-28 17:01:47 -04:00
Alex aecf8ec88b fix: timeline scroll flicker (#28653)
* test: fix scroll flicker

* lint
2026-05-28 08:20:54 -05:00
Daniel Dietzler bcff1d42b0 chore: migrate more make targets (#28663) 2026-05-28 08:33:57 -04:00
Min Idzelis 1bd367bd51 refactor(web): replace per-asset viewport proximity with day-tier active indices (#28597) 2026-05-28 11:44:18 +02:00
Daniel Dietzler 725f266b81 chore: migrate more make targets to mise (#28651) 2026-05-28 11:31:02 +02:00
Daniel Dietzler d08e3de207 fix: e2e linting (#28659) 2026-05-28 11:12:26 +02:00
Timon 26714f6bfe fix(server): prevent locked assets from leaking to partners (#28652)
* fix(server): prevent locked assets from leaking to partners

* fix tests
2026-05-27 17:33:49 -04:00
Lauritz Tieste a5ce3fc927 fix: Refresh local album overview page after asset deletion (#28586)
fix: invalidate local album provider on asset delete
2026-05-28 01:20:32 +05:30
shenlong 3b23f71a3f refactor: cleanup metadata (#28485)
jason-ify metadata

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-28 01:19:25 +05:30
shenlong dec33cadd9 fix: verify form disposal before notifyListeners (#28578)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-27 19:45:48 +00:00
Daniel Dietzler 80c15a5e27 fix: workflow drag and drop (#28650) 2026-05-27 14:05:38 -05:00
Yaros 936c28a40b feat(mobile): improve downloading algorithm for sharing (#27312)
* feat(mobile): better downloading while sharing

* chore: separate download group

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-27 17:00:49 +00:00
Spencer Stingley 1a837a28ac fix: dev container properly builds @immich/plugin-sdk for import (#28620)
Co-authored-by: Spencer Stingley <accounts@blankcanvas.io>
2026-05-27 12:41:35 -04:00
shenlong 8d5d12b108 chore: upgrade flutter to 3.44.0 (#28537)
* chore: upgrade flutter to 3.44.0

# Conflicts:
#	mise.lock

* static analysis fix

* fix ios ci

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-27 11:14:44 -05:00
Daniel Dietzler dd7a94135f refactor: workflow components (#28648) 2026-05-27 18:08:12 +02:00
Jason Rasmussen 1acc511b5c chore: install mise in Dockerfile.dev (#28649) 2026-05-27 11:43:17 -04:00
Daniel Dietzler 452e88267a fix: strip metadata from timeline responses for shared links without exif sharing (#28644) 2026-05-27 17:29:37 +02:00
Timon b941108cbd chore: update documentation to use mise commands (#28515) 2026-05-27 10:33:23 -04:00
Jason Rasmussen e46f2843f7 refactor: asset create event (#28647) 2026-05-27 10:28:02 -04:00
Jason Rasmussen cf991e7b1b feat: workflow actions (#28639) 2026-05-27 10:24:31 -04:00
Thomas van Gemert 748a13104a chore(docs): update FAQ with profile picture change instructions (#28634)
Update FAQ with profile picture change instructions

Based on this discussion (https://github.com/immich-app/immich/discussions/27168) it seems I am not the only one confused by how Immich lets you change your profile picture. An addition to the FAQ will help. I also added another horizontal separator to be consistent with the rest of the document.
2026-05-27 09:17:12 -05:00
Brandon Wees 2dd6b47714 fix: OCR bounding box positioning (#28568) 2026-05-27 12:01:30 +02:00
Alex 8682be4774 feat: workflow template (#28553)
* wip: confirm before existing and disable/enable save button condition

* fix: get correct workflow detail

* wip: add back workflow summary

* wip: add back json editor

* wip: step property badge

* wip: redesign card flow

* wip: redesign card flow

* redesign workflow summary

* wworkflow summary styling

* wip

* drag and drop

* list redesign

* refactor

* refactor

* remove deadcode

* refactor

* insert steps

* push down when dropped

* feat: workflow template

* simplify

* move template to manifest

* feat: hash manifest file

* fix: template column

* fix: migration

* fix: workflow lookup

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-26 16:47:05 -04:00
Brandon Wees dc66892ca1 fix: await sync asset v2 (#28569)
* fix: await sync asset v2

* fix: support previous server versions for edit ready events
2026-05-26 15:43:12 -04:00
Fabian Wimberger 53a24783f5 fix(ml): stabilize MIGraphX inference (#28444)
* fix: stabilize ROCm MIGraphX inference

Serialize MIGraphX session runs so lazy compiles cannot overlap within a worker.

Use a fixed face-recognition batch size for MIGraphX to avoid compiling a new program for each detected face count.

* fix(ml): increase ROCm worker timeout

* fix(ml): narrow MIGraphX compile locking

* docs: format environment variables table

* docs: apply prettier to environment variables table
2026-05-26 18:41:56 +00:00
Alex 0546bc900c chore: workflow UI (#28536)
* wip: confirm before existing and disable/enable save button condition

* fix: get correct workflow detail

* wip: add back workflow summary

* wip: add back json editor

* wip: step property badge

* wip: redesign card flow

* wip: redesign card flow

* redesign workflow summary

* wworkflow summary styling

* wip

* drag and drop

* list redesign

* refactor

* refactor

* remove deadcode

* refactor

* insert steps

* push down when dropped

* fix: query by workflow id

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-26 14:06:20 -04:00
Brandon Wees 7c25bcc0a7 refactor: use ControlBar UI Library component (#28567)
* refactor: use ControlBar UI Library component

* chore: ci fix

* fix: memory viewer bar

* chore: rework e2e test

* chore: more ci fixes
2026-05-26 12:03:37 -04:00
Luis Nachtigall 7905853639 fix(mobile): preserve zoom level during image loading and live photo playback (#27960)
* fix(mobile): preserve zoom level when new images load in asset viewer

* fix(mobile): use actual child size for live photo

* revert fixes

* fix(mobile): keep zoom consistent when scale boundaries change

* fix(mobile): simplify scale handling in photo_view_core.dart
2026-05-26 21:10:02 +05:30
Mees Frensel 073dcc1fbe chore(server): deprecate total field of asset search response (#28551) 2026-05-26 16:20:24 +02:00
renovate[bot] ccdaa4223c chore(deps): update github-actions (#28623) 2026-05-26 15:04:51 +02:00
Aaron Liu 5386b62dc4 chore(ml): allow insightface 1.x (#28595)
* chore(ml): allow insightface 1.x

The new insightface 1.0 release appears to have no breaking code changes nor relevant license changes ([before](https://github.com/deepinsight/insightface/blob/2a78baec428354883e0cda39c54b555a5ed8358a/README.md), [after](https://github.com/deepinsight/insightface/blob/70f3269ea628d0658c5723976944c9de414e96f8/README.md), c.f. https://github.com/immich-app/immich/blob/fd7ddfef54cdf2b6256c4fc08bc5ff3f86176775/machine-learning/README.md), and it works on my machine.

* Update uv.lock

* please excuse my incompetence
2026-05-25 12:32:50 -04:00
Ben Beckford 9733fa4872 fix(web): timeline stuttering with many assets in 1 day (#28509)
* fix(web): timeline stuttering with many assets in 1 day

* cache isInOrNearViewport per day

* skip inOrNearViewport check on first run
2026-05-24 16:03:46 -05:00
Alex 3b34c53092 feat: command for user pages (#28554) 2026-05-24 16:03:12 -05:00
Alex fd7ddfef54 fix: plugin prod build typo (#28566) 2026-05-22 11:01:18 -05:00
Daniel Dietzler 0975b1599c fix: remove stray migration (#28565) 2026-05-22 15:20:47 +00:00
Peter Ombodi 78ac0ade01 feat(mobile): add manage media APIs to NativeSyncApi (#28441)
* feat(mobile): add manage media APIs to NativeSyncApi

* fix(mobile): remove legacy local file manager from trash sync

* refactor(mobile): move media permission methods to PermissionApi

* cleanup

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-22 17:40:11 +05:30
Mert 7b9dab872b fix(mobile): separate group ids for separate app installs (#28448)
* separate group ids

* remove pigeon method

* Revert "remove pigeon method"

This reverts commit d699ff2094.
2026-05-21 12:25:20 -05:00
Daniel Dietzler 6413495fb8 fix: mise lockfile (#28541) 2026-05-21 13:13:37 +02:00
Caltsic b414b3d32b fix: improve form control focus visibility (#28512)
* Improve form control focus visibility

* fix: align form input focus styles
2026-05-20 15:33:56 -05:00
renovate[bot] 20da7c4267 chore(deps): lock file maintenance (terragrunt) (#28488) 2026-05-20 17:20:50 +02:00
renovate[bot] 92b6778d2d fix(deps): update typescript-projects (#28371)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-05-20 16:56:27 +02:00
Daniel Dietzler 5a61e589e8 chore: always run ci when mise.toml changes and install flutter from aqua (#28521) 2026-05-20 14:43:30 +00:00
renovate[bot] 85192bb110 chore(deps): update ghcr.io/jdx/mise docker tag to v2026.5.11 (#28522) 2026-05-20 14:29:17 +00:00
Timon c7ae97fa2b chore: handle docusaurus deprecation warning (#28516) 2026-05-20 15:27:33 +02:00
Timon 8d02f3625d chore: update mobile makefile command usage instructions (#28514) 2026-05-20 15:26:24 +02:00
bo0tzz a5a7380a26 feat: use lockfile for mise tools (#28503) 2026-05-20 11:37:33 +00:00
renovate[bot] d9ce3d2046 chore(deps): update dependency @types/node to ^24.12.4 (#28490) 2026-05-20 12:41:17 +02:00
renovate[bot] 815ff677fc chore(deps): update github-actions (#28493) 2026-05-19 22:22:44 +00:00
bo0tzz 915d865ce2 chore: use custom sticky-comment action (#28505) 2026-05-19 20:25:46 +00:00
immich-tofu[bot] c28e5f90b6 chore: modify .github/workflows/org-zizmor.yml 2026-05-19 10:45:23 +00:00
Timon 4383473ed6 fix: cleanup nestjs-zod properties (#28447)
* fix: cleanup nestjs-zod properties

* lint
2026-05-18 15:31:08 -04:00
shenlong 77701dd5a3 refactor: migrate backup config (#28483) 2026-05-19 00:40:10 +05:30
shenlong d4808fdc4d refactor: migrate album config (#28482)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-18 23:28:59 +05:30
renovate[bot] 7fa967a98e chore(deps): update dependency svelte to v5.55.7 [security] (#28434)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-05-18 17:42:01 +00:00
shenlong 9cffcc9f4e refactor: migrate network config (#28471) 2026-05-18 16:22:42 +00:00
shenlong 40925f0a06 refactor: immich form and text input (#28479)
refacotr: immich form

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-18 16:21:36 +00:00
Oliver Roed Schøler 0544d22902 feat: Selectable metadata in duplicates utility with diffing (#26328) 2026-05-18 17:49:51 +02:00
Jason Rasmussen 3d075f2bf8 feat: workflows & plugins (#26727)
feat: plugins

chore: better types

feat: plugins
2026-05-18 11:09:33 -04:00
Luis Nachtigall 7384799f19 fix(mobile): asset viewer stuck on spinner after rotation (#28019) 2026-05-18 20:32:51 +05:30
Alex 4a7f06e8fd feat: upload and add local asset directly to album (#28123)
* feat: manually upload local assets to album

* feat: manually upload local assets to album

* refactor

* Upload status

* pr feedback
2026-05-18 20:31:22 +05:30
Lauritz Tieste 8f662fc459 refactor: enhance shared link UI and functionality (#26464)
* feat(shared-link): enhance shared link UI and functionality with new expiry options and improved layout

* rebase & cleanup

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-18 20:29:56 +05:30
Benjamin Nguyen 24b1dae9f2 feat(mobile): "Add Tags" asset multiselect option (#26269)
* add bulk_tag_assets_action_button to general_bottom_sheet.widget

include create tag tile in 'Add Tags' action modal

* follow provider -> svc -> repo pattern for tags

* rebase and cleanup

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-18 20:29:09 +05:30
Lauritz Tieste 3a3469a5f9 feat(ui): add ImmichURLInput (#27105)
feat(ui): implement shared URL input configuration and update input fields
2026-05-18 20:28:57 +05:30
Adam Gastineau 7993619ed2 fix(ios): respect status bar scroll to top in timeline views (#28469)
* fix(ios): respect status bar scroll to top in library views

* Make sure to wrap all loading states in Scaffold
2026-05-18 20:28:01 +05:30
shenlong 4d1f6f869b chore: cleanup mobile mise config (#28473)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-18 19:18:52 +05:30
Yaros 3eb03f7934 chore: update readmes to match main (#28458) 2026-05-17 13:08:27 -05:00
Alex 03ed3daa31 chore: improve mobile slideshow (#28460) 2026-05-17 10:54:21 -05:00
Min Idzelis 02581e81a7 fix(web): work around Chrome HDR image seam lines during zoom (#27715)
Change-Id: Ic5a5b1a476c2af93b465ef23dabc601a6a6a6964

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-16 02:15:24 +00:00
Santo Shakil 3ab3d5cf43 fix(mobile): don't force-unwrap nil localizedTitle in ios getAlbums (#28452)
crashes on ios 26 when a PHAssetCollection returns nil for
localizedTitle. fall back to localIdentifier. ref #28428
2026-05-15 18:12:28 -05:00
Ben Beckford 0ef04d9baa feat(mobile): slideshow view (#28421)
* feat(mobile): slideshow view

* move slideshow settings to metadata store

* remove watch in initState

* wrap progress bar in safearea

* show slideshow button on remote albums

* fix crash on unknown assets

* always show slideshow option

* add zoom effect

* add padding to slideshow settings

* chore: styling tweak

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-15 18:12:04 -05:00
Santo Shakil df016f9228 fix(mobile): mounted check in ThumbnailTile hero flight listener (#28451)
When the user pops back from the asset viewer mid-flight, the hero
animation can fire its status listener after _ThumbnailTileState has
been disposed. setState then throws a null check on State._element.

Guard the listener with `if (!mounted) return;` — same pattern as
#28300 in the album sync action.
2026-05-15 21:41:04 +00:00
Santo Shakil 17779c1e74 fix(mobile): cronet thumbnail buffer overflow regression from #28439 (#28450)
The hybrid added in onReadCompleted reuses Cronet's ByteBuffer between
reads to save a JNI wrap call when no grow is needed. That reuse breaks
advance() — Cronet's position() is cumulative across reads, so the same
K bytes get counted on every subsequent iteration. b.offset overshoots
b.capacity, the reuse branch keeps firing on a now-empty buffer, and
request.read() throws the original IllegalArgumentException again.

Always pass a fresh wrap from wrapRemaining() so byteBuffer.position()
reflects only this iteration's bytes. Same shape as the original PR
had before the broken optimization was layered on top.
2026-05-15 17:25:31 -04:00
Santo Shakil 01d6a244d8 fix(mobile): cronet buffer overflow on compressed thumbnails (#28439)
CronetImageFetcher sized the response buffer from Content-Length, which is
the compressed wire size. Cronet auto-decompresses gzip/br responses and
writes decompressed bytes into the buffer, exceeding it and throwing
IllegalArgumentException: ByteBuffer is already full on the next read. Use
the growable path; Content-Length becomes an initial alloc hint only,
capped at 128 MB so an untrusted server can't overflow Int.MAX_VALUE or
OOM us upfront. Reuse Cronet's ByteBuffer between reads when no grow is
needed.
2026-05-15 14:48:23 -04:00
Ben Beckford 21d6755f39 fix(web): recently added ux (#28435) 2026-05-14 22:22:23 -05:00
Robert Deaton e91c017dd0 fix(server): dedupe database backup jobs (#28341)
* fix(server): dedupe database backup jobs via jobId

#27268 shows backup jobs piling up in the queue across upgrades; one pending
backup is always enough.

* fix(tests): Avoid stale backup files from previous test runs being erroneously returned from createBackup

* fix(jobs): Use bullmq's deduplication over jobId to avoid failed jobs from blocking future executions.

---------

Co-authored-by: Robert Deaton <immich@rdeaton.space>
2026-05-14 20:59:15 -04:00
Alex 43687cd8b4 fix: kebab menu icon colors and actions (#28433) 2026-05-14 22:23:50 +00:00
shenlong 06729ee5a5 chore: cleanup unused store keys (#28415)
cleanup unused store keys

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-14 16:21:06 -05:00
Nojus Gudinavičius b0c9743d9a feat(server): allow subpaths for machine learning URL (#28427)
This allows to use a machine learning server URL under a subpath,
such as "http://example.com/ml-server/".
2026-05-14 12:46:31 +00:00
Marius 37cc028868 fix(mobile): use correct delete action (#26575)
fix(mobile): use correct delete for trashed assets

When viewing a trashed asset, the viewer bottom bar now shows the permanent delete button instead of the trash button, which had no effect on already-trashed assets.
2026-05-14 11:57:19 +00:00
Inês Costa 84a2b7a3c8 fix(mobile): add restore option to trashed assets (#27442) 2026-05-14 07:19:00 +00:00
racehd 89b3433346 feat(docs): add fixed subnet guide for Synology to prevent firewall issues (#26554)
* - Add Set Fixed Subnet section
- Add newline after details summary to properly render summary with mdx

* pnpm run format --write

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-13 23:54:13 +00:00
shenlong 3ff0d47ee3 chore: do not cache dart_tool (#28409)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-13 19:46:24 -04:00
shenlong aeaf846482 chore: cleanup unused store keys (#28415)
cleanup unused store keys

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-13 18:03:57 -05:00
Santo Shakil b031548791 fix(mobile): don't block app open on slow validateAccessToken (#28405)
* fix(mobile): don't block app open on slow validateAccessToken

AuthGuard.onNavigation was async so auto_route awaited the body through validateAccessToken's OS timeout. now it's sync and the validate runs in bg. kicks to login on 401.

* fix(mobile): handle re-login race in AuthGuard validate

if user logs out + logs back in during a slow validate, the old 401 was logging them out again. now we check the token hasn't changed before redirecting, and dedupe in-flight calls.

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-13 11:52:43 -05:00
Jason Rasmussen fcea617313 fix: ignore icc profile make and model (#28412) 2026-05-13 12:07:35 -04:00
Mees Frensel 024f20ea26 chore(web): use DatePicker component from UI lib (#28406) 2026-05-13 09:37:07 -05:00
shenlong 0a4ed6fd71 refactor: migrate viewer config to metadata table (#28396)
* refactor: app metadata

* refactor to per row store

* cleanup

* more test

* review changes

* more refactor

* refactor

* migrate primary color

* migrate dynamic theme

* migrate colorfulInterface

* cleanup providers

* migrate cleanup

* migrate mapconfig

* remove unused keys

* migrate timeline config

* migrate image config

* migrate viewer config

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-13 09:36:19 -05:00
Alex b6e2ce1f35 fix(mobile): revert drop deprecated deviceAssetId / deviceId from upload fields (#28384) (#28400)
* Revert "chore(mobile): drop deprecated deviceAssetId / deviceId from upload fields (#28384)"

This reverts commit 571e6a8560.

* chore(mobile): add note on kept deprecated upload fields

---------

Co-authored-by: Santo Shakil <shakil.mezbah@gmail.com>
2026-05-13 09:36:16 -05:00
bo0tzz e323e778cd fix: update server-commands subcommand list (#28402) 2026-05-13 09:27:25 -04:00
renovate[bot] 6a87797649 chore(deps): update terraform cloudflare to v4.52.7 (#28370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 23:50:23 -04:00
renovate[bot] f4a4649bbc chore(deps): update dependency canvas to v3 (#28376)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 23:49:22 -04:00
Alex 6ca54ee722 feat: display more info in asset viewer (#24630)
* feat(mobile): more info for asset viewer

* feat(mobile): more info for asset viewer
2026-05-13 02:07:23 +00:00
shenlong 8e3035f783 chore: run mobile tests in parallel (#28393)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-12 17:17:07 -05:00
shenlong 79801595db refactor: move image config to metadata table (#28228)
* migrate image config

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-13 03:20:35 +05:30
Yaros 3e1c8aacb1 feat(mobile): trash/restore all (#28116)
* feat(mobile): trash/restore all

* chore: remove themeData variable

* chore: filter query by user

* refactor

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-12 14:56:19 -05:00
shenlong 91ac56cef2 refactor: move timeline config to metadata table (#28227)
* migrate timeline config

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-13 01:23:25 +05:30
Jason Rasmussen 58beac8fe0 chore: migrate mobile makefile to mise (#28390) 2026-05-12 15:21:04 -04:00
Santo Shakil f632d320f5 fix(mobile): clear linkedRemoteAlbumId in reset() so FK refs dont dangle (#28382)
* fix(mobile): clear linkedRemoteAlbumId in reset() so FK refs dont dangle

reset() runs with foreign_keys off before wiping remote_* tables, so the ON DELETE SET NULL cascade on linkedRemoteAlbumId doesnt fire. local rows keep pointing at deleted remote ids.

affects logout (clearLocalData calls reset()) and the server SyncResetV1 path (30 day idle, etc). after re-login, syncLinkedAlbum either silently warns or fires 400s (those are covered by #28299).

null the column manually inside the same transaction. cascade still works for normal SyncAlbumDeleteV1.

verified on pixel 9a with this branch built locally: logged out, deleted album from web, logged back in. without fix linkedRemoteAlbumId stayed dangling. with fix all three local rows have linkedRemoteAlbumId = NULL after the logout reset, and recovery is clean once manageLinkedAlbums runs again.

* fix(mobile): always re-enable foreign_keys in reset() + simplify the update

re-enable foreign_keys inside a try/finally so it always runs even if the transaction throws. without this, a failed reset would leave the connection with foreign_keys = OFF and silently disable cascades for everything after (per copilot review).

also drop the where filter on the linkedRemoteAlbumId update, unconditional update-all is simpler and we wipe everything in reset anyway (per ganka review).
2026-05-12 13:43:15 -05:00
shenlong 2ddaf6a611 fix: indexes on remote_asset_entity (#28264)
* fix: periodically execute pragma optimize

* fix: indexes on remote_asset_entity

* regen files

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-12 16:43:24 +00:00
shenlong 1932c60e1c fix: kekab icon colors in light mode (#28366)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-12 11:27:55 -05:00
Brandon Wees dc6f8e746e fix: deep link for assets when asset viewer already open (#27971) 2026-05-12 16:19:54 +00:00
Jason Rasmussen ad7aedb843 refactor: move plugins to packages (#28389) 2026-05-12 13:28:30 +00:00
Santo Shakil 571e6a8560 chore(mobile): drop deprecated deviceAssetId / deviceId from upload fields (#28384)
server removed both fields from AssetMediaCreateDto in #27818. zod silently strips unknown fields so uploads still work, but we send dead weight on every request.

drop from foreground + background upload paths + share intent path. deviceAssetId stays as the internal background_downloader taskId, just not in the multipart form fields anymore.
2026-05-12 09:12:26 -04:00
bo0tzz 4791313def fix: manage oazapfts through mise (#28380) 2026-05-12 08:12:27 -04:00
renovate[bot] f88fdae048 fix(deps): update dependency @immich/ui to ^0.77.0 (#28373)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 12:15:47 +02:00
renovate[bot] bcef7aa6b6 chore(deps): update github-actions (#28372)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 12:07:32 +02:00
renovate[bot] ce292bdce9 chore(deps): update base-image to v202605051129 (#28374)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 12:02:43 +02:00
renovate[bot] 4eee023648 chore(deps): update docker.io/valkey/valkey:9 docker digest to 8436e10 (#28369)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 11:52:30 +02:00
shenlong 8f4b0fce49 fix: limit android background worker duration (#23566)
* fix: limit each android background run to 20 mins

# Conflicts:
#	mobile/lib/domain/services/background_worker.service.dart

* review chages

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-11 23:08:17 -05:00
Timon c6b3127b35 feat(web): add individual filter removal from search result chips (#28166)
* feat(web): add individual filter removal from search result chips

* drop cast

* use delete

* lint

* stylings

* filter

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-12 03:50:40 +00:00
shenlong 4d6a50c2cb refactor: move map config to metadata table (#28226)
* refactor: app metadata

* refactor to per row store

* cleanup

* more test

* review changes

* more refactor

* refactor

* migrate primary color

* migrate dynamic theme

* migrate colorfulInterface

* cleanup providers

* migrate cleanup

* migrate mapconfig

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-11 22:43:52 -05:00
Jason Rasmussen 15f3947ae6 chore: mise scripts (#28367) 2026-05-11 17:46:02 -04:00
Ben Beckford e142e3aca7 feat: recently added assets page (#28272)
* feat(server): add ordering date option to time buckets

* feat(web): add recently added page

* feat(server): recently created assets in explore data

* feat(web): recently added in explore tab

* fix: recently added assets ordering

* fix(server): failing bucket test

* feat(web): improve recently added preview

* chore: update e2e explore/timeline tests

* chore: rename and refactor timeline ordering dates

* fix(web): invalid timeline option

* feat(mobile): recently added page

* fix(server): sync tests

* fix(mobile): resync assets to get uploadedAt column

* chore: rename assetorderby enum

* chore(mobile): formatting

* minor fixes

* stylings

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-11 21:35:10 +00:00
Brandon Wees 38438c8d9a refactor!: remove asset faces from AssetResponseDto (#27779)
* refactor!: remove faces from `people` in AssetResposnseDto

* chore: tests

* chore: e2e generator

* chore: code review readonly

* chore: code review changes

* chore: cleanup

* fix: openapi

* chore: format

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-11 17:05:40 -04:00
Alex a278c10c75 fix: mobile upload duration type (#28362) 2026-05-11 15:46:00 -05:00
renovate[bot] 2276443c56 fix(deps): update dependency kysely to v0.28.17 [security] (#28363)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 22:38:25 +02:00
Jason Rasmussen bb44773e57 chore: remove unused commands (#28361) 2026-05-11 16:19:40 -04:00
Jason Rasmussen 14d9e90a03 refactor: move i18n formatting to workspace root (#28360)
refactor: move i18n formatting to project root
2026-05-11 16:19:28 -04:00
Jason Rasmussen 03e042213c refactor: move e2e-auth-server to packages (#28358) 2026-05-11 15:39:59 -04:00
Jason Rasmussen db589455f4 refactor: move cli to package folder (#28356) 2026-05-11 14:49:45 -04:00
Jason Rasmussen fb0a54d548 chore: mise on windows (#28351)
* chore: mise on windows

* chore: bump use-mise
2026-05-11 20:04:38 +02:00
renovate[bot] 7013cc0904 fix(deps): update dependency @opentelemetry/exporter-prometheus to ^0.217.0 [security] (#28353)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 18:03:30 +00:00
renovate[bot] dcaf7b4a65 fix(deps): update dependency @opentelemetry/sdk-node to ^0.217.0 [security] (#28354)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 19:48:25 +02:00
shenlong 12f7b2a005 chore: add always_put_control_body_on_new_line lint (#28352)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-11 13:47:24 -04:00
Jason Rasmussen 7837d40f57 chore: move sdk to packages (#28350) 2026-05-11 13:37:10 -04:00
bo0tzz b4f719653f fix: indentation and typo (#28349)
* fix: indentation and typo

* neline
2026-05-11 09:17:39 -05:00
bo0tzz f370b4bac6 chore: fold apk comment qr in <details> (#28348) 2026-05-11 09:40:19 -04:00
Mert d788169bf3 chore(server)!: remove libopus enum (#28325) 2026-05-11 08:02:57 -04:00
Mert eea820fa2f chore(server): enable hw decoding by default (#28324) 2026-05-11 08:02:26 -04:00
Timon 271f1cb868 feat(web): Add metadata overlay to slideshow (#24627)
* feat: add slideshow metadata overlay and settings

* Introduced a new SlideshowMetadataOverlay component to display image information during slideshows.
* Updated slideshow settings modal to include options for showing the metadata overlay and selecting its display mode (Description Only or Full).
* Added corresponding translations and store management for the new overlay features.

* remove noisy log

* constant opacity

* 2nd pass

* more

* use text components

* lint
2026-05-11 11:49:12 +02:00
Mert 8c8dc9d32f chore(ml)!: remove deprecated envs (#28326)
remove deprecated envs
2026-05-09 22:40:05 +00:00
Alex fd18e55f7c chore: token extraction for build mobile (#28320)
Co-authored-by: bo0tzz <git@bo0tzz.me>
2026-05-09 15:08:07 +00:00
shenlong faab9e620d refactor: medium repository context helpers (#28311)
* refactor: medium repository context helpers

* test: add regress test for 26723

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-09 08:19:31 -05:00
Matthew Momjian 5ba3efafd8 fix(deployment): remove unneeded volume (#28307)
remove unneeded volume
2026-05-09 09:07:54 -04:00
Alex 8b3c9bf9c3 feat(ci): publish PR Android APK to comment (#28283)
* feat(ci): publish PR Android APK to R2 with installable links

Adds a universal debug APK to PR builds and uploads it to a public
R2 bucket alongside the existing GitHub Actions artifact. Posts a
sticky PR comment with tap-to-install links and a QR code so testers
can install directly on their device without unzipping artifacts.

Required setup:
- Secrets: R2_APK_ACCESS_KEY_ID, R2_APK_SECRET_ACCESS_KEY,
  R2_APK_ACCOUNT_ID, R2_APK_BUCKET
- Optional repo variable: APK_PUBLIC_HOST (defaults to apk.immich.app)
- R2 bucket configured with a public custom domain matching APK_PUBLIC_HOST

* chore(ci): drop R2 upload, link directly to GitHub artifact

Surfaces the existing release-apk-signed artifact in a sticky PR
comment with a QR code. Avoids new infra and secrets — the trade-off
is GitHub login and a zip wrapper instead of tap-to-install.

* feat(ci): build PR APK as release and publish to GitHub Release

PR builds now produce a release APK signed with the release keystore.
The universal APK is published as a GitHub Release asset under tag
'pr-<num>' (prerelease), giving testers a direct, unzipped, tap-to-
install URL plus a QR code in the PR comment. The release-apk-signed
artifact is unchanged.

* chore(ci): drop GitHub Release, publish universal APK as own artifact

Reverts the prerelease publish. Uploads the universal release APK as
a separate single-file artifact so its download URL gives a zip
containing only that APK — no extra files to dig through. The QR in
the PR comment points at this universal-only artifact.

* chore(ci): build only universal APK for PR, drop split artifact

PR builds skip the arm64-only split — release-apk-signed now contains
just the universal app-release.apk, so the download zip is a single
file. Removes the redundant separate universal artifact and points
the PR comment QR at the main artifact URL.

* feat(mobile): suffix PR APK applicationId so it installs alongside production

Each PR build now becomes app.alextran.immich.pr<num> via PR_NUMBER env
read in build.gradle, so testers can install multiple PR builds and the
Play Store version on the same device without uninstalling. Also tags
the version with -pr<num> for visibility.

* feat(ci): allow PR APK build to run on forks

Forks can now run the Android build job. Steps that need repo secrets
(create-workflow-token, Create Keystore) are skipped when the PR is
from a fork, the checkout falls back to GITHUB_TOKEN, and build.gradle
falls back to debug signing if the release keystore isn't materialised.
The PR comment still requires write access, so it's gated to non-fork
PRs — fork APKs are reachable from the workflow run's artifact tab.
2026-05-09 07:46:40 -05:00
Yaros 41f285aa3e feat(mobile): increased tap area on video player overlay (#27269)
* fix(mobile): improved tap area on video player

* fix: back button padding

* chore: use sizedbox.square & button padding

* chore: fixed padding
2026-05-09 10:47:41 +07:00
Sandro fdac6c8bc4 fix(docs): missing colon in config file doc (#28313)
Fix missing colon
2026-05-09 09:44:41 +07:00
Thorsten Winkler d7f05d2510 fix(mobile): Deduplicate assets in person view timeline (#26723)
fix(mobile): deduplicate assets in person view timeline

Previously, assets with multiple face records for the same person (e.g.,
manual Digikam imports and Immich ML detections) appeared multiple times
in the person timeline. This was caused by an inner join on the
assetFaceEntity without proper deduplication.

This commit refactors the timeline queries to use a subquery approach
instead of joins and grouping. This ensures:

- _getPersonBucketAssets: Only unique assets are fetched, even if
  multiple face records exist for a single asset.
- _watchPersonBucket: Asset counts in timeline headers are accurate
  and represent unique assets.
- Performance: Database overhead is reduced by avoiding complex joins
  and explicit groupBy operations on large result sets.

Signed-off-by: thowdev <12428285+thowdev@users.noreply.github.com>
2026-05-09 01:53:18 +00:00
stfn 3100bd5eed fix(mobile): avoid duplicate assets in album view (#28152)
fix(mobile): avoid duplicate assets in remote album timeline

Co-authored-by: Stefan Friedli <stefan@stefanfriedli.ch>
2026-05-09 08:24:54 +07:00
Jason Rasmussen 8a024e2b50 chore: faster web linting (#28303) 2026-05-08 16:55:14 -04:00
Jason Rasmussen 25a6a38b30 chore: use mise (#28298) 2026-05-08 15:21:33 -04:00
Santo Shakil 7c6750941e fix(mobile): mounted check before setState in album sync action (#28300)
_manualSyncAlbums fires a setState 1s after sync via Future.delayed
with no mounted check. if the widget is gone by then, setState throws
null check and the global error logger logs it severe.
2026-05-08 18:55:03 +00:00
renovate[bot] 832ed4d015 chore(deps): update dependency exiftool-vendored to v35.19.0 [security] (#28261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-05-08 12:24:31 +02:00
Santo Shakil 238895cad9 fix(mobile): restore notification plugin init (#28284)
#27666 removed LocalNotificationService with the legacy stack, which
was the only place calling FlutterLocalNotificationsPlugin().initialize().
without it, ios never prompts for the notification perm on fresh
installs so background_downloader notifications get dropped silently.

restores the init in the same spot the deleted call used to live.
2026-05-08 10:45:52 +07:00
sakshamchawla e2ec04e86c feat: hide hidden person from memories (#20877)
* hide hidden person from memories

* clean up

* fix united test

* clean up

* moved sql to inline, rebased

* clean up

* clean up again

* chore: sync sql

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-07 19:54:26 +00:00
renovate[bot] 6050526360 fix(deps): update dependency connectivity_plus to v7 (#22921)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 15:22:26 -04:00
renovate[bot] bfd76570c5 chore(deps): update dependency python-multipart to v0.0.27 [security] (#28286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 15:22:03 -04:00
renovate[bot] 37e6a49652 fix(deps): update dependency nestjs-otel to v8 (#27863)
* fix(deps): update dependency nestjs-otel to v8

* fix: apiMetrics

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jason@rasm.me>
2026-05-07 19:14:15 +00:00
Mert 36caeb34ec chore(ml)!: require numpy 2.4 (#28158)
require numpy 2.4
2026-05-07 19:07:39 +00:00
renovate[bot] 87713c7f2f chore(deps): update dependency flutter to v3.41.9 (#28235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 15:00:37 -04:00
Daniel Dietzler 2039c129f2 refactor: settings accordion reactivity (#28281) 2026-05-07 19:00:23 +00:00
Timon 52b00b0bad chore(ml): add mise checklist command (#28267)
* chore(ml): add mise checklist command

* don't depend tests on installing a cpu flavor
2026-05-07 12:28:24 -04:00
shenlong 21af184045 refactor: move cleanup config to metadata table (#28225)
* refactor: app metadata

* refactor to per row store

* cleanup

* more test

* review changes

* more refactor

* refactor

* migrate primary color

* migrate dynamic theme

* migrate colorfulInterface

* cleanup providers

* migrate cleanup

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-07 11:27:06 -05:00
Timon 1fcc2b704b feat(server)!: add isOwned filter to albums API (#28213)
* feat(server)!: add owned filter to albums API

BREAKING CHANGE: GET /albums with no parameters now returns all accessible albums (owned + shared-with-me) instead of only owned albums.

* document tri-state matrix

* web impl

* collapse to single method and handover branching to sql

* dedupe

* verify that owned, shared, and notShared counts are mapped independently from their respective queries

* refactor(server): add select:['id'] overload to albumRepository.getAll

Avoid fetching full album rows (with albumUsers/sharedLinks subqueries) in map.service where only album IDs are needed.

* focus relevant test filters

* fmt

* Revert "verify that owned, shared, and notShared counts are mapped independently from their respective queries"

This reverts commit 47aab458192c766de4662aada5a6841b091d2a80.

* sync sql

* Revert "document tri-state matrix"

This reverts commit a5b2355d0c.

* address review comments

* inline shared condition and return as ternary

* sync sql

* use [...albums].sort

Array.toSorted() is not supported in Chrome 109

* use isShared and isOwned nomenclature

* fix e2e tests

* add params to sql query
2026-05-07 12:13:07 -04:00
Timon 7de73dc176 fix(server): hide isFavorite from partner asset sync stream (#28035)
* fix(server): hide isFavorite from partner asset sync stream

* use new column entry instead

* sync sql

* add migration

* use sql.val

* sync sql
2026-05-07 12:00:54 -04:00
TheBestX11 fe2bf0c6dd fix(mobile): correct filter default and UI desync in similar photos search (#27516)
* fix(mobile): view similar defaults to images only

* fix(mobile): reset filter chips when pre-filter is applied

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2026-05-07 15:22:35 +00:00
shenlong d4a97f2d25 refactor: move theme config to metadata table (#28224)
* refactor: app metadata

* refactor to per row store

* cleanup

* more test

* review changes

* more refactor

* refactor

* migrate primary color

* migrate dynamic theme

* migrate colorfulInterface

* cleanup providers

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-07 15:12:14 +00:00
shenlong bd58db4fcc fix: periodically execute pragma optimize (#28241)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-07 09:54:35 -05:00
Luis Nachtigall 7f43c6a3a3 fix(mobile): prevent asset loading issues when changing page or when closing memories (#27596) 2026-05-07 09:13:22 -04:00
Mees Frensel 87175ee56c fix(docs): document upgrade-insecure-requests default (#28279) 2026-05-07 08:40:14 -04:00
Mees Frensel 13587bf13c feat(web): video player i18n (#28192) 2026-05-07 13:39:37 +02:00
Thomas f09769a2f3 chore(mobile): add box shadow to asset details (#27510)
The details widget can blend with the image when they are similar
colours.
2026-05-06 19:43:55 +00:00
bo0tzz bfdff12ee0 chore: use app token for mise in workflows (#28270) 2026-05-06 14:51:25 -04:00
bo0tzz eb6dca6a31 chore: switch push-o-matic auth from app-id to client-id (#28269) 2026-05-06 17:01:14 +00:00
Daniel Dietzler c2e3739a58 chore: run relevant tests for pnpm updates (#28266) 2026-05-06 15:38:00 +00:00
Daniel Dietzler f6bd514cdc chore: silence svelte state referenced locally warning (#28263) 2026-05-06 17:22:39 +02:00
Timon d93ab7707e chore(ml): configure mise for machine-learning directory (#25579) 2026-05-06 11:03:54 -04:00
renovate[bot] 6bb47c802f chore(deps): update github-actions (#28262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 16:00:03 +02:00
mws-weekend-projects 90a69e2ba6 feat(web): add full-path search mode to UI (#26758)
Co-authored-by: mws-weekend-projects <mws-weekend-projects@users.noreply.github.com>
Co-authored-by: Mert <101130780+mertalev@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
2026-05-06 15:45:40 +02:00
Mert 6580394cfe chore(server): simplify sharp edit code (#28249) 2026-05-06 09:32:49 -04:00
Daniel Dietzler 42ff3b705d fix: revert "chore(deps): update dependency exiftool-vendored to v35.19.0 [security]" (#28260) 2026-05-06 15:32:25 +02:00
Mert 0f00053bb1 chore(server): simplify preview extraction (#28250) 2026-05-06 09:32:19 -04:00
Mert c5c59ed040 refactor(server): move video interface fetch to storage core (#28248) 2026-05-06 09:32:03 -04:00
Aigars Mahinovs 576b1eb999 docs: update rocm installation instructions (#25434) 2026-05-06 09:30:42 -04:00
Mees Frensel 24189702da fix(web): shared album avatars opening modal (#26719)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2026-05-06 13:49:12 +02:00
Sky ad0d01005e fix(web): migrate people management component to page, enabling tooltips (#26971) 2026-05-06 13:25:59 +02:00
Brent Hugh 3e6d053f93 chore: enhance documentation on wildcard and exclusion patterns (#27884)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2026-05-06 12:36:25 +02:00
renovate[bot] 1bb3fd985f chore(deps): update dependency exiftool-vendored to v35.19.0 [security] (#28254)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 12:28:47 +02:00
Andreas Heinz f72aa54a1f feat(enhancement): Navigate stack with up and down arrow keys (#27854)
* feat(enhancement): navigate stack with up and down arrow keys

* remove unnecessary code

* move shortcut to section; no need for document level
2026-05-06 11:56:23 +02:00
shenlong dafe9d7966 chore: pump version (#28231)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-05 16:27:04 -05:00
Daniel Dietzler 7acda0572d fix: stale person name after merge (#28222) 2026-05-05 15:34:49 +02:00
renovate[bot] 98bc9f6a6e chore(deps): update dependency terragrunt to v1.0.3 (#28236)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-05 12:52:14 +02:00
renovate[bot] 63a3b405c3 chore(deps): update grafana/grafana docker tag to v12.4.3 (#28238)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-05 12:51:18 +02:00
Ben Beckford 0058df798d fix(mobile): show lens info without lens name (#28234)
* fix(mobile): always display lens subtitle

* fix(mobile): hide empty lens subtitles
2026-05-05 10:46:09 +07:00
shenlong 97100a4362 refactor: app metadata (#28113)
* refactor: app metadata

* refactor to per row store

* cleanup

* more test

* review changes

* more refactor

* refactor

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2026-05-05 10:45:51 +07:00
Alex af39384efb chore: better contrast for highlighted button on control bar (#28217) 2026-05-04 09:39:37 -05:00
Mert 01712cf0a7 fix(server): av typing (#28223)
* fix av typing, move fixtures to stub file

* fix tests
2026-05-04 09:04:29 -04:00
Michel Heusschen 2015f95ff5 fix(web): correct timeline yesterday label across month boundaries (#28183) 2026-05-04 13:46:11 +02:00
Timon d4f29ab6ac fix(server): validate duplicate group ownership before dismissal (#28221) 2026-05-04 12:51:54 +02:00
1233 changed files with 87444 additions and 33527 deletions
+1 -1
View File
@@ -75,7 +75,7 @@
{
"label": "Build Immich CLI",
"type": "shell",
"command": "pnpm --filter cli build:dev"
"command": "pnpm --filter @immich/cli build:dev"
}
]
}
@@ -15,8 +15,8 @@ services:
volumes:
- ${UPLOAD_LOCATION:-upload-devcontainer-volume}${UPLOAD_LOCATION:+/photos}:/data
- /etc/localtime:/etc/localtime:ro
- pnpm_store_server:/buildcache/pnpm-store
- ../plugins:/build/corePlugin
- build_cache:/buildcache
- ../packages/plugin-core:/build/plugins/immich-plugin-core
immich-web:
env_file: !reset []
immich-machine-learning:
@@ -8,6 +8,8 @@ log "Preparing Immich Web Frontend"
log ""
run_cmd pnpm --filter @immich/sdk install
run_cmd pnpm --filter @immich/sdk build
run_cmd pnpm --filter @immich/plugin-sdk install
run_cmd pnpm --filter @immich/plugin-sdk build
run_cmd pnpm --filter immich-web install
log "Starting Immich Web Frontend"
+1 -3
View File
@@ -30,9 +30,7 @@ machine-learning/
misc/
mobile/
open-api/typescript-sdk/build/
!open-api/typescript-sdk/package.json
!open-api/typescript-sdk/package-lock.json
packages/sdk/build/
server/upload/
server/src/queries
+2 -2
View File
@@ -24,7 +24,7 @@ mobile/lib/infrastructure/repositories/db.repository.steps.dart linguist-generat
mobile/test/drift/main/generated/** -diff -merge
mobile/test/drift/main/generated/** linguist-generated=true
open-api/typescript-sdk/fetch-client.ts -diff -merge
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
packages/sdk/fetch-client.ts -diff -merge
packages/sdk/fetch-client.ts linguist-generated=true
*.sh text eol=lf
-1
View File
@@ -1 +0,0 @@
custom: ['https://buy.immich.app', 'https://immich.store']
+1 -1
View File
@@ -1,7 +1,7 @@
cli:
- changed-files:
- any-glob-to-any-file:
- cli/src/**
- packages/cli/src/**
documentation:
- changed-files:
+55 -31
View File
@@ -51,14 +51,14 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
@@ -73,24 +73,30 @@ jobs:
needs: pre-job
permissions:
contents: read
# Skip when PR from a fork
if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
pull-requests: write
if: ${{ github.actor != 'dependabot[bot]' && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
runs-on: mich
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.ref || github.sha }}
ref: ${{ inputs.ref }}
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
github_token: ${{ steps.token.outputs.token }}
- name: Create the Keystore
if: ${{ !github.event.pull_request.head.repo.fork }}
env:
KEY_JKS: ${{ secrets.KEY_JKS }}
working-directory: ./mobile
@@ -110,16 +116,8 @@ jobs:
~/.gradle/wrapper
~/.android/sdk
mobile/android/.gradle
mobile/.dart_tool
key: build-mobile-gradle-${{ runner.os }}-main
- name: Setup Flutter SDK
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
cache: true
- name: Setup Android SDK
uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
with:
@@ -130,11 +128,10 @@ jobs:
run: flutter pub get
- name: Generate translation file
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
working-directory: ./mobile
run: mise //mobile:codegen:translation
- name: Generate platform APIs
run: make pigeon
run: mise //mobile:codegen:pigeon
working-directory: ./mobile
- name: Build Android App Bundle
@@ -144,20 +141,43 @@ jobs:
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
IS_MAIN: ${{ github.ref == 'refs/heads/main' }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
if [[ $IS_MAIN == 'true' ]]; then
flutter build apk --release
flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64
else
flutter build apk --debug --split-per-abi --target-platform android-arm64
flutter build apk --release
fi
- name: Publish Android Artifact
id: upload-apk
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: release-apk-signed
path: mobile/build/app/outputs/flutter-apk/*.apk
- name: Comment APK download link on PR
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork }}
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
APK_URL: ${{ steps.upload-apk.outputs.artifact-url }}
with:
id: mobile-android-apk
token: ${{ steps.token.outputs.token }}
body: |
📱 **Android release APK (universal)** — `${{ env.HEAD_SHA }}`
Download: ${{ env.APK_URL }}
<details>
<summary>QR code</summary>
<img src="https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=${{ env.APK_URL }}" alt="QR code" />
</details>
Installs as a separate app (applicationId `app.alextran.immich.pr${{ github.event.pull_request.number }}`), so it coexists with the Play Store version and any other PR builds.
- name: Save Gradle Cache
id: cache-gradle-save
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -168,7 +188,6 @@ jobs:
~/.gradle/wrapper
~/.android/sdk
mobile/android/.gradle
mobile/.dart_tool
key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }}
build-sign-ios:
@@ -181,6 +200,12 @@ jobs:
runs-on: macos-15
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Select Xcode 26
run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
@@ -190,27 +215,27 @@ jobs:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Setup Flutter SDK
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
cache: true
github_token: ${{ steps.token.outputs.token }}
- name: Install Flutter dependencies
working-directory: ./mobile
run: flutter pub get
- name: Generate translation files
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
working-directory: ./mobile
run: mise //mobile:codegen:translation
- name: Generate platform APIs
run: make pigeon
run: mise //mobile:codegen:pigeon
- name: Resolve iOS Swift Packages
working-directory: ./mobile
run: flutter build ios --config-only --no-codesign
- name: Setup Ruby
uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0
uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
with:
ruby-version: '3.3'
bundler-cache: true
@@ -267,7 +292,6 @@ jobs:
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
ENVIRONMENT: ${{ inputs.environment || 'development' }}
BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }}
GITHUB_REF: ${{ github.ref }}
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 120
FASTLANE_XCODEBUILD_SETTINGS_RETRIES: 6
+2 -2
View File
@@ -19,9 +19,9 @@ jobs:
actions: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check out code
+34 -1
View File
@@ -4,6 +4,7 @@ on:
pull_request:
paths:
- 'open-api/**'
- 'mobile/lib/utils/openapi_patching.dart'
- '.github/workflows/check-openapi.yml'
concurrency:
@@ -24,8 +25,40 @@ jobs:
persist-credentials: false
- name: Check for breaking API changes
uses: oasdiff/oasdiff-action/breaking@f8cb9308b42121e793f835bd14c0b8090420430c # v0.0.39
uses: oasdiff/oasdiff-action/breaking@50e6a3413e5aa9c3ae4d8393c34745be44288b46 # v0.0.48
with:
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
revision: open-api/immich-openapi-specs.json
fail-on: ERR
check-mobile-patches:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
github_token: ${{ github.token }}
- name: Get packages
working-directory: ./mobile
run: flutter pub get
- name: Fetch base spec from main
run: |
curl -fsSL \
"https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json" \
-o /tmp/base-spec.json
- name: Check newly-required fields have a backward-compat patch
working-directory: ./mobile
env:
OPENAPI_BASE_SPEC: /tmp/base-spec.json
OPENAPI_REVISION_SPEC: ../open-api/immich-openapi-specs.json
run: flutter test test/openapi_patches_coverage.dart
+24 -32
View File
@@ -3,11 +3,11 @@ on:
push:
branches: [main]
paths:
- 'cli/**'
- 'packages/cli/**'
- '.github/workflows/cli.yml'
pull_request:
paths:
- 'cli/**'
- 'packages/cli/**'
- '.github/workflows/cli.yml'
release:
types: [published]
@@ -28,38 +28,30 @@ jobs:
packages: write
defaults:
run:
working-directory: ./cli
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './cli/.nvmrc'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Setup typescript-sdk
run: pnpm install && pnpm run build
working-directory: ./open-api/typescript-sdk
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm publish --provenance --no-git-checks
- name: Publish
if: ${{ github.event_name == 'release' }}
env:
NPM_TAG: ${{ github.event.release.prerelease && 'rc' || 'latest' }}
run: mise run ci-publish -- --tag "$NPM_TAG"
docker:
name: Docker
@@ -71,9 +63,9 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
@@ -83,13 +75,13 @@ jobs:
token: ${{ steps.token.outputs.token }}
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Login to GitHub Container Registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
registry: ghcr.io
@@ -99,12 +91,12 @@ jobs:
- name: Get package version
id: package-version
run: |
version=$(jq -r '.version' cli/package.json)
version=$(jq -r '.version' packages/cli/package.json)
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Generate docker image tags
id: metadata
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
flavor: |
latest=false
@@ -112,12 +104,12 @@ jobs:
name=ghcr.io/${{ github.repository_owner }}/immich-cli
tags: |
type=raw,value=${{ steps.package-version.outputs.version }},enable=${{ github.event_name == 'release' }}
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
- name: Build and push image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
file: cli/Dockerfile
file: packages/cli/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name == 'release' }}
cache-from: type=gha
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
needs: [get_body, should_run]
if: ${{ needs.should_run.outputs.should_run == 'true' }}
container:
image: ghcr.io/immich-app/mdq:main@sha256:557cca601891b8b7d78b940071d35aaf7aaeb9b327d19b22cf282118edbc5272
image: ghcr.io/immich-app/mdq:main@sha256:e73f60195b39748c4876f23e3e6cd22a68a9754acec8aef1fd6979fd52cd2c9f
outputs:
checked: ${{ steps.get_checkbox.outputs.checked }}
steps:
+5 -5
View File
@@ -44,9 +44,9 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout repository
@@ -57,7 +57,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -70,7 +70,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -83,6 +83,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
with:
category: '/language:${{matrix.language}}'
+11 -11
View File
@@ -23,14 +23,14 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
@@ -60,7 +60,7 @@ jobs:
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -90,7 +90,7 @@ jobs:
suffix: ['']
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -132,7 +132,7 @@ jobs:
suffixes: '-rocm'
platforms: linux/amd64
runner-mapping: '{"linux/amd64": "pokedex-large"}'
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.0
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@db54dcf16fbb12c43479a23749ceea0ad1b4a704 # multi-runner-build-workflow-v3.0.0
permissions:
contents: read
actions: read
@@ -147,7 +147,7 @@ jobs:
platforms: ${{ matrix.platforms }}
runner-mapping: ${{ matrix.runner-mapping }}
suffixes: ${{ matrix.suffixes }}
dockerhub-push: ${{ github.event_name == 'release' }}
dockerhub-push: ${{ github.event_name == 'release' && !github.event.release.prerelease }}
build-args: |
DEVICE=${{ matrix.device }}
@@ -155,7 +155,7 @@ jobs:
name: Build and Push Server
needs: pre-job
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.0
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@db54dcf16fbb12c43479a23749ceea0ad1b4a704 # multi-runner-build-workflow-v3.0.0
permissions:
contents: read
actions: read
@@ -167,7 +167,7 @@ jobs:
image: immich-server
context: .
dockerfile: server/Dockerfile
dockerhub-push: ${{ github.event_name == 'release' }}
dockerhub-push: ${{ github.event_name == 'release' && !github.event.release.prerelease }}
build-args: |
DEVICE=cpu
@@ -178,7 +178,7 @@ jobs:
runs-on: ubuntu-latest
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}
@@ -189,6 +189,6 @@ jobs:
runs-on: ubuntu-latest
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}
+8 -14
View File
@@ -21,14 +21,14 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
@@ -54,9 +54,9 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -64,17 +64,11 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './docs/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Run install
run: pnpm install
+19 -10
View File
@@ -20,9 +20,9 @@ jobs:
artifact: ${{ steps.get-artifact.outputs.result }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- if: ${{ github.event.workflow_run.conclusion != 'success' }}
@@ -98,9 +98,16 @@ jobs:
shouldDeploy: true
};
} else if (eventType == "release") {
const tag = context.payload.workflow_run.head_branch;
const { data: release } = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag,
});
parameters = {
event: "release",
name: context.payload.workflow_run.head_branch,
name: tag,
prerelease: release.prerelease,
shouldDeploy: !isFork
};
}
@@ -119,9 +126,9 @@ jobs:
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -131,7 +138,9 @@ jobs:
token: ${{ steps.token.outputs.token }}
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
github_token: ${{ steps.token.outputs.token }}
- name: Load parameters
id: parameters
@@ -144,6 +153,7 @@ jobs:
const parameters = JSON.parse(process.env.PARAM_JSON);
core.setOutput("event", parameters.event);
core.setOutput("name", parameters.name);
core.setOutput("prerelease", parameters.prerelease);
core.setOutput("shouldDeploy", parameters.shouldDeploy);
- name: Download artifact
@@ -201,7 +211,7 @@ jobs:
run: mise run //docs:deploy
- name: Deploy Docs Release Domain
if: ${{ steps.parameters.outputs.event == 'release' }}
if: ${{ steps.parameters.outputs.event == 'release' && steps.parameters.outputs.prerelease != 'true' }}
env:
TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
@@ -211,12 +221,11 @@ jobs:
run: 'mise run //deployment:tf apply'
- name: Comment
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
if: ${{ steps.parameters.outputs.event == 'pr' }}
with:
id: docs-pr-url
token: ${{ steps.token.outputs.token }}
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
body: |
📖 Documentation deployed to [${{ steps.docs-output.outputs.subdomain }}](https://${{ steps.docs-output.outputs.subdomain }})
emojis: 'rocket'
body-include: '<!-- Docs PR URL -->'
+7 -6
View File
@@ -17,9 +17,9 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -29,7 +29,9 @@ jobs:
token: ${{ steps.token.outputs.token }}
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
github_token: ${{ steps.token.outputs.token }}
- name: Destroy Docs Subdomain
env:
@@ -42,9 +44,8 @@ jobs:
run: 'mise run //deployment:tf destroy -- -refresh=false'
- name: Comment
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
with:
id: docs-pr-url
token: ${{ steps.token.outputs.token }}
number: ${{ github.event.number }}
delete: true
body-include: '<!-- Docs PR URL -->'
+8 -14
View File
@@ -14,29 +14,23 @@ jobs:
contents: write
pull-requests: write
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
- id: token
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: 'Checkout'
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Fix formatting
run: pnpm --recursive install && pnpm run --recursive --if-present --parallel format:fix
+3 -3
View File
@@ -4,7 +4,7 @@ on:
workflow_dispatch:
workflow_call:
secrets:
PUSH_O_MATIC_APP_ID:
PUSH_O_MATIC_APP_CLIENT_ID:
required: true
PUSH_O_MATIC_APP_KEY:
required: true
@@ -31,9 +31,9 @@ jobs:
- name: Generate a token
id: generate_token
if: ${{ inputs.skip != true }}
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Find translation PR
+1
View File
@@ -13,3 +13,4 @@ jobs:
actions: read
contents: read
security-events: write
secrets: inherit
+2 -2
View File
@@ -14,9 +14,9 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Require PR to have a changelog label
+3 -3
View File
@@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
with:
repo-token: ${{ steps.token.outputs.token }}
+16 -21
View File
@@ -36,7 +36,7 @@ jobs:
permissions:
pull-requests: write
secrets:
PUSH_O_MATIC_APP_ID: ${{ secrets.PUSH_O_MATIC_APP_ID }}
PUSH_O_MATIC_APP_CLIENT_ID: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
PUSH_O_MATIC_APP_KEY: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
@@ -48,32 +48,27 @@ jobs:
version: ${{ steps.output.outputs.version }}
permissions: {} # No job-level permissions are needed because it uses the app-token
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
- id: token
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ steps.generate-token.outputs.token }}
token: ${{ steps.token.outputs.token }}
persist-credentials: true
ref: main
- name: Install uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
# TODO move to mise
- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Bump version
env:
@@ -124,9 +119,9 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
@@ -142,7 +137,7 @@ jobs:
github-token: ${{ steps.generate-token.outputs.token }}
- name: Create draft release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
draft: true
tag_name: ${{ needs.bump_version.outputs.version }}
+16 -16
View File
@@ -14,16 +14,16 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
with:
github-token: ${{ steps.token.outputs.token }}
message-id: 'preview-status'
message: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.build/'
id: preview-status
token: ${{ steps.token.outputs.token }}
body: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.build/'
remove-label:
runs-on: ubuntu-latest
@@ -32,9 +32,9 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -48,16 +48,16 @@ jobs:
name: 'preview'
})
- uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
if: ${{ github.event.pull_request.head.repo.fork }}
with:
github-token: ${{ steps.token.outputs.token }}
message-id: 'preview-status'
message: 'PRs from forks cannot have preview environments.'
id: preview-status
token: ${{ steps.token.outputs.token }}
body: 'PRs from forks cannot have preview environments.'
- uses: mshick/add-pr-comment@64b8e914979889d746c99dea15a76e77ef64580a # v3.10.0
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
github-token: ${{ steps.token.outputs.token }}
message-id: 'preview-status'
message: 'Preview environment has been removed.'
id: preview-status
token: ${{ steps.token.outputs.token }}
body: 'Preview environment has been removed.'
+15 -18
View File
@@ -14,34 +14,31 @@ jobs:
contents: read
id-token: write
packages: write
defaults:
run:
working-directory: ./open-api/typescript-sdk
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './open-api/typescript-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Install deps
run: pnpm install --frozen-lockfile
run: pnpm --filter @immich/sdk install --frozen-lockfile
- name: Build
run: pnpm build
run: pnpm --filter @immich/sdk build
- name: Publish
run: pnpm publish --provenance --no-git-checks
env:
NPM_TAG: ${{ github.event.release.prerelease && 'rc' || 'latest' }}
run: pnpm --filter @immich/sdk publish --provenance --no-git-checks --tag "$NPM_TAG"
+19 -35
View File
@@ -20,14 +20,14 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
@@ -49,9 +49,9 @@ jobs:
working-directory: ./mobile
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -60,38 +60,26 @@ jobs:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup Flutter SDK
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
github_token: ${{ steps.token.outputs.token }}
- name: Install dependencies
run: dart pub get
run: flutter pub get
- name: Install dependencies for UI package
run: dart pub get
run: flutter pub get
working-directory: ./mobile/packages/ui
- name: Install dependencies for UI Showcase
run: dart pub get
working-directory: ./mobile/packages/ui/showcase
- name: Install DCM
uses: CQLabs/setup-dcm@8697ae0790c0852e964a6ef1d768d62a6675481a # v2.0.1
with:
github-token: ${{ steps.token.outputs.token }}
version: auto
working-directory: ./mobile
- name: Generate translation file
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
- name: Generate translation files
run: mise //mobile:codegen:translation
- name: Run Build Runner
run: make build
run: mise //mobile:codegen:dart
- name: Generate platform API
run: make pigeon
run: mise //mobile:codegen:pigeon
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
@@ -107,20 +95,16 @@ jobs:
env:
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
run: |
echo "ERROR: Generated files not up to date! Run 'make build' and 'make pigeon' inside the mobile directory"
echo "ERROR: Generated files not up to date! Run 'mise //mobile:codegen:dart' and 'mise //mobile:codegen:pigeon'"
echo "Changed files: ${CHANGED_FILES}"
exit 1
- name: Run dart analyze
run: dart analyze --fatal-infos
- name: Run analyze
run: mise //mobile:analyze
- name: Run dart format
run: make format
- name: Run format
run: mise //mobile:format
# TODO: Re-enable after upgrading custom_lint
# - name: Run dart custom_lint
# run: dart run custom_lint
# TODO: Use https://github.com/CQLabs/dcm-action
- name: Run DCM
run: dcm analyze lib --fatal-style --fatal-warnings
+223 -256
View File
@@ -17,34 +17,45 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
i18n:
- 'i18n/**'
- 'mise.toml'
web:
- 'web/**'
- 'i18n/**'
- 'open-api/typescript-sdk/**'
- 'packages/sdk/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
server:
- 'server/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
cli:
- 'cli/**'
- 'open-api/typescript-sdk/**'
- 'packages/cli/**'
- 'packages/sdk/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
e2e:
- 'e2e/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
mobile:
- 'mobile/**'
- 'mise.toml'
machine-learning:
- 'machine-learning/**'
- 'mise.toml'
.github:
- '.github/**'
force-filters: |
@@ -58,14 +69,11 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: ./server
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -74,28 +82,14 @@ jobs:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run package manager install
run: pnpm install
- name: Run linter
run: pnpm lint
if: ${{ !cancelled() }}
- name: Run formatter
run: pnpm format
if: ${{ !cancelled() }}
- name: Run tsc
run: pnpm check
if: ${{ !cancelled() }}
- name: Run small tests & coverage
run: pnpm test
if: ${{ !cancelled() }}
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-unit
run: mise run //server:ci-unit
cli-unit-tests:
name: Unit Test CLI
needs: pre-job
@@ -105,12 +99,12 @@ jobs:
contents: read
defaults:
run:
working-directory: ./cli
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -118,31 +112,15 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './cli/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Setup typescript-sdk
run: pnpm install && pnpm run build
working-directory: ./open-api/typescript-sdk
- name: Install deps
run: pnpm install
- name: Run linter
run: pnpm lint
if: ${{ !cancelled() }}
- name: Run formatter
run: pnpm format
if: ${{ !cancelled() }}
- name: Run tsc
run: pnpm check
if: ${{ !cancelled() }}
- name: Run unit tests & coverage
run: pnpm test
if: ${{ !cancelled() }}
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-unit
run: mise run ci-unit
cli-unit-tests-win:
name: Unit Test CLI (Windows)
needs: pre-job
@@ -152,12 +130,12 @@ jobs:
contents: read
defaults:
run:
working-directory: ./cli
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -165,26 +143,28 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './cli/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
- name: Install deps
github_token: ${{ steps.token.outputs.token }}
- name: Run setup @immich/sdk
run: mise run //:sdk:install && mise run //:sdk:build
- name: Run pnpm install
run: pnpm install --frozen-lockfile
# Skip linter & formatter in Windows test.
- name: Run tsc
run: pnpm check
if: ${{ !cancelled() }}
- name: Run unit tests & coverage
run: pnpm test
if: ${{ !cancelled() }}
web-lint:
name: Lint Web
needs: pre-job
@@ -197,9 +177,9 @@ jobs:
working-directory: ./web
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -207,28 +187,22 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './web/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
github_token: ${{ steps.token.outputs.token }}
- name: Run setup @immich/sdk
run: mise run //:sdk:install && mise run //:sdk:build
- name: Run pnpm install
run: pnpm rebuild && pnpm install --frozen-lockfile
run: pnpm install --frozen-lockfile
- name: Run linter
run: pnpm lint
if: ${{ !cancelled() }}
- name: Run formatter
run: pnpm format
if: ${{ !cancelled() }}
- name: Run svelte checks
run: pnpm check:svelte
if: ${{ !cancelled() }}
web-unit-tests:
name: Test Web
needs: pre-job
@@ -241,9 +215,9 @@ jobs:
working-directory: ./web
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -251,25 +225,15 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './web/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
- name: Run npm install
run: pnpm install --frozen-lockfile
- name: Run tsc
run: pnpm check:typescript
if: ${{ !cancelled() }}
- name: Run unit tests & coverage
run: pnpm test
if: ${{ !cancelled() }}
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-unit
run: mise run ci-unit
i18n-tests:
name: Test i18n
needs: pre-job
@@ -279,9 +243,9 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -289,24 +253,25 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './web/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Install dependencies
run: pnpm --filter=immich-i18n install --frozen-lockfile
run: pnpm -w install --frozen-lockfile
- name: Format
run: pnpm --filter=immich-i18n format:fix
run: pnpm format:fix
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files
with:
files: |
i18n/**
- name: Verify files have not changed
if: steps.verify-changed-files.outputs.files_changed == 'true'
env:
@@ -315,6 +280,7 @@ jobs:
echo "ERROR: i18n files not up to date!"
echo "Changed files: ${CHANGED_FILES}"
exit 1
e2e-tests-lint:
name: End-to-End Lint
needs: pre-job
@@ -327,9 +293,9 @@ jobs:
working-directory: ./e2e
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -337,30 +303,16 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './e2e/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
if: ${{ !cancelled() }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
if: ${{ !cancelled() }}
- name: Run linter
run: pnpm lint
if: ${{ !cancelled() }}
- name: Run formatter
run: pnpm format
if: ${{ !cancelled() }}
- name: Run tsc
run: pnpm check
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-unit
run: mise run ci-unit
if: ${{ !cancelled() }}
server-medium-tests:
name: Medium Tests (Server)
needs: pre-job
@@ -373,9 +325,9 @@ jobs:
working-directory: ./server
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -384,21 +336,16 @@ jobs:
persist-credentials: false
submodules: 'recursive'
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
- name: Run pnpm install
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
- name: Run medium tests
run: pnpm test:medium
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-medium
run: mise run ci-medium
if: ${{ !cancelled() }}
e2e-tests-server-cli:
name: End-to-End Tests (Server & CLI)
needs: pre-job
@@ -414,9 +361,9 @@ jobs:
runner: [ubuntu-latest, ubuntu-24.04-arm]
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -425,52 +372,57 @@ jobs:
persist-credentials: false
submodules: 'recursive'
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: './e2e/.nvmrc'
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
if: ${{ !cancelled() }}
- name: Setup packages
run: pnpm --filter @immich/sdk --filter @immich/cli install --frozen-lockfile && pnpm --filter @immich/sdk --filter @immich/cli build
- name: Run setup web
run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync
working-directory: ./web
if: ${{ !cancelled() }}
- name: Run setup cli
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./cli
if: ${{ !cancelled() }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
if: ${{ !cancelled() }}
- name: Start Docker Compose
run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300
if: ${{ !cancelled() }}
- name: Run e2e tests (api & cli)
env:
VITEST_DISABLE_DOCKER_SETUP: true
run: pnpm test
if: ${{ !cancelled() }}
- name: Run e2e tests (maintenance)
env:
VITEST_DISABLE_DOCKER_SETUP: true
run: pnpm test:maintenance
if: ${{ !cancelled() }}
- name: Capture Docker logs
if: always()
run: docker compose logs --no-color > docker-compose-logs.txt
working-directory: ./e2e
- name: Archive Docker logs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: e2e-server-docker-logs-${{ matrix.runner }}
path: e2e/docker-compose-logs.txt
e2e-tests-web:
name: End-to-End Tests (Web)
needs: pre-job
@@ -486,9 +438,9 @@ jobs:
runner: [ubuntu-latest, ubuntu-24.04-arm]
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -497,70 +449,84 @@ jobs:
persist-credentials: false
submodules: 'recursive'
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: './e2e/.nvmrc'
node-version-file: '.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Run setup typescript-sdk
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./open-api/typescript-sdk
- name: Run setup @immich/sdk
run: pnpm --filter @immich/sdk install --frozen-lockfile && pnpm --filter @immich/sdk build
if: ${{ !cancelled() }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
if: ${{ !cancelled() }}
- name: Install Playwright Browsers
run: pnpm exec playwright install chromium --only-shell
if: ${{ !cancelled() }}
- name: Docker build
run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300
if: ${{ !cancelled() }}
- name: Run e2e tests (web)
env:
PLAYWRIGHT_DISABLE_WEBSERVER: true
run: pnpm test:web
if: ${{ !cancelled() }}
- name: Archive e2e test (web) results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: success() || failure()
with:
name: e2e-web-test-results-${{ matrix.runner }}
path: e2e/playwright-report/
- name: Run ui tests (web)
env:
PLAYWRIGHT_DISABLE_WEBSERVER: true
run: pnpm test:web:ui
if: ${{ !cancelled() }}
- name: Archive ui test (web) results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: success() || failure()
with:
name: e2e-ui-test-results-${{ matrix.runner }}
path: e2e/playwright-report/
- name: Run maintenance tests
env:
PLAYWRIGHT_DISABLE_WEBSERVER: true
run: pnpm test:web:maintenance
if: ${{ !cancelled() }}
- name: Archive maintenance tests (web) results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: success() || failure()
with:
name: e2e-maintenance-isolated-test-results-${{ matrix.runner }}
path: e2e/playwright-report/
- name: Capture Docker logs
if: always()
run: docker compose logs --no-color > docker-compose-logs.txt
working-directory: ./e2e
- name: Archive Docker logs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: e2e-web-docker-logs-${{ matrix.runner }}
path: e2e/docker-compose-logs.txt
success-check-e2e:
name: End-to-End Tests Success
needs: [e2e-tests-server-cli, e2e-tests-web]
@@ -568,7 +534,7 @@ jobs:
runs-on: ubuntu-latest
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}
mobile-unit-tests:
@@ -580,26 +546,31 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup Flutter SDK
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
- name: Generate translation file
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
github_token: ${{ steps.token.outputs.token }}
- name: Install dependencies
run: flutter pub get
working-directory: ./mobile
- name: Generate translation files
run: mise //mobile:codegen:translation
- name: Run tests
working-directory: ./mobile
run: flutter test -j 1
run: mise //mobile:test
ml-unit-tests:
name: Unit Test ML
needs: pre-job
@@ -612,34 +583,24 @@ jobs:
working-directory: ./machine-learning
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Install uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
python-version: 3.11
- name: Install dependencies
run: |
uv sync --extra cpu
- name: Lint with ruff
run: |
uv run ruff check --output-format=github immich_ml
- name: Format with ruff
run: |
uv run ruff format --check immich_ml
- name: Run mypy type checking
run: |
uv run mypy --strict immich_ml/
- name: Run tests and coverage
run: |
uv run pytest --cov=immich_ml --cov-report term-missing
github_token: ${{ steps.token.outputs.token }}
- name: Run ci-unit
run: mise run ci-unit
github-files-formatting:
name: .github Files Formatting
needs: pre-job
@@ -652,9 +613,9 @@ jobs:
working-directory: ./.github
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -662,19 +623,19 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './.github/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Run pnpm install
run: pnpm install --frozen-lockfile
- name: Run formatter
run: pnpm format
if: ${{ !cancelled() }}
shellcheck:
name: ShellCheck
runs-on: ubuntu-latest
@@ -682,9 +643,9 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -703,9 +664,9 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -713,29 +674,27 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Install server dependencies
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich install --frozen-lockfile
- name: Build the app
run: pnpm --filter immich build
- name: Run API generation
run: ./bin/generate-open-api.sh
run: mise //:open-api
working-directory: open-api
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files
with:
files: |
mobile/openapi
open-api/typescript-sdk
packages/sdk
open-api/immich-openapi-specs.json
- name: Verify files have not changed
if: steps.verify-changed-files.outputs.files_changed == 'true'
env:
@@ -744,6 +703,7 @@ jobs:
echo "ERROR: Generated files not up to date!"
echo "Changed files: ${CHANGED_FILES}"
exit 1
sql-schema-up-to-date:
name: SQL Schema Checks
runs-on: ubuntu-latest
@@ -760,14 +720,11 @@ jobs:
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 5432:5432
defaults:
run:
working-directory: ./server
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
@@ -775,31 +732,38 @@ jobs:
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- name: Setup Mise
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
github_token: ${{ steps.token.outputs.token }}
- name: Install server dependencies
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
- name: Build plugins
run: mise //:plugins
- name: Build the app
run: pnpm build
run: mise //server:build
- name: Run existing migrations
run: pnpm migrations:run
run: pnpm --filter immich migrations:run
- name: Test npm run schema:reset command works
run: pnpm schema:reset
run: pnpm --filter immich schema:reset
- name: Generate new migrations
continue-on-error: true
run: pnpm migrations:generate src/TestMigration
run: pnpm --filter migrations:generate src/TestMigration
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files
with:
files: |
server/src
- name: Verify migration files have not changed
if: steps.verify-changed-files.outputs.files_changed == 'true'
env:
@@ -807,18 +771,21 @@ jobs:
run: |
echo "ERROR: Generated migration files not up to date!"
echo "Changed files: ${CHANGED_FILES}"
cat ./src/*-TestMigration.ts
cat ./server/src/*-TestMigration.ts
exit 1
- name: Run SQL generation
run: pnpm sync:sql
run: mise //:sql
env:
DB_URL: postgres://postgres:postgres@localhost:5432/immich
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-sql-files
with:
files: |
server/src/queries
- name: Verify SQL files have not changed
if: steps.verify-changed-sql-files.outputs.files_changed == 'true'
env:
+7 -7
View File
@@ -24,19 +24,19 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check what should run
id: check
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
i18n:
- modified: 'i18n/!(en|package)**\.json'
- modified: 'i18n/!(en)**\.json'
skip-force-logic: 'true'
enforce-lock:
@@ -47,9 +47,9 @@ jobs:
if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Bot review status
@@ -68,6 +68,6 @@ jobs:
permissions: {}
if: always()
steps:
- uses: immich-app/devtools/actions/success-check@53bb77345ee9f953f93bd6fd9980f07a2f24965e # success-check-action-v0.0.5
- uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6
with:
needs: ${{ toJSON(needs) }}
+1 -1
View File
@@ -20,7 +20,7 @@ mobile/openapi/doc
mobile/openapi/.openapi-generator/FILES
mobile/ios/build
open-api/typescript-sdk/build
packages/**/build
mobile/android/fastlane/report.xml
mobile/ios/fastlane/report.xml
View File
View File
+6 -4
View File
@@ -23,15 +23,17 @@
"type": "node",
"request": "launch",
"name": "Immich CLI",
"program": "${workspaceFolder}/cli/dist/index.js",
"program": "${workspaceFolder}/packages/cli/dist/index.js",
"args": ["upload", "--help"],
"runtimeArgs": ["--enable-source-maps"],
"console": "integratedTerminal",
"resolveSourceMapLocations": ["${workspaceFolder}/cli/dist/**/*.js.map"],
"resolveSourceMapLocations": [
"${workspaceFolder}/packages/cli/dist/**/*.js.map"
],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/cli/dist/**/*.js"],
"outFiles": ["${workspaceFolder}/packages/cli/dist/**/*.js"],
"skipFiles": ["<node_internals>/**"],
"preLaunchTask": "Build Immich CLI"
"preLaunchTask": "Build @immich/cli"
}
]
}
+3
View File
@@ -29,6 +29,9 @@
"editor.formatOnSave": true,
"tailwindCSS.lint.suggestCanonicalClasses": "ignore"
},
"svelte.plugin.svelte.compilerWarnings": {
"state_referenced_locally": "ignore"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
-134
View File
@@ -1,134 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation
in our community a harassment-free experience for everyone, regardless
of age, body size, visible or invisible disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open,
welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for
our community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our
mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or
political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in
a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our
standards of acceptable behavior and will take appropriate and fair
corrective action in response to any behavior that they deem
inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, and will
communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also
applies when an individual is officially representing the community in
public spaces. Examples of representing our community include using an
official e-mail address, posting via an official social media account,
or acting as an appointed representative at an online or offline
event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior
may be reported to the community leaders responsible for enforcement
at our Discord channel. All complaints
will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and
security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in
determining the consequences for any action they deem in violation of
this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior
deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders,
providing clarity around the nature of the violation and an
explanation of why the behavior was inappropriate. A public apology
may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued
behavior. No interaction with the people involved, including
unsolicited interaction with those enforcing the Code of Conduct, for
a specified period of time. This includes avoiding interactions in
community spaces as well as external channels like social
media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards,
including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or
public communication with the community for a specified period of
time. No public or private interaction with the people involved,
including unsolicited interaction with those enforcing the Code of
Conduct, is allowed during this period. Violating these terms may lead
to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of
community standards, including sustained inappropriate behavior,
harassment of an individual, or aggression toward or disparagement of
classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction
within the community.
## Attribution
This Code of Conduct is adapted from the [Contributor
Covenant][homepage], version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of
conduct enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the
FAQ at https://www.contributor-covenant.org/faq. Translations are
available at https://www.contributor-covenant.org/translations.
+15 -109
View File
@@ -1,152 +1,58 @@
dev:
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
@printf "This command has been removed. Please use:\n\n mise dev # or mise //:dev from another directory\n\n" >&2 && exit 1
dev-down:
docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans
@printf "This command has been removed. Please use:\n\n mise dev-down # or mise //:dev-down from another directory\n\n" >&2 && exit 1
dev-update:
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
@printf "This command has been removed. Please use:\n\n mise dev-update # or mise //:dev-update from another directory\n\n" >&2 && exit 1
dev-scale:
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
@printf "This command has been removed. Please use:\n\n mise dev-scale # or mise //:dev-scale from another directory\n\n" >&2 && exit 1
dev-docs:
npm --prefix docs run start
.PHONY: e2e
e2e:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
@printf "This command has been removed. Please use:\n\n mise e2e # or mise //:e2e from another directory\n\n" >&2 && exit 1
e2e-dev:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans
@printf "This command has been removed. Please use:\n\n mise e2e-dev # or mise //:e2e-dev from another directory\n\n" >&2 && exit 1
e2e-update:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
@printf "This command has been removed. Please use:\n\n mise e2e-update # or mise //:e2e-update from another directory\n\n" >&2 && exit 1
e2e-down:
docker compose -f ./e2e/docker-compose.yml down --remove-orphans
@printf "This command has been removed. Please use:\n\n mise e2e-down # or mise //:e2e-down from another directory\n\n" >&2 && exit 1
prod:
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --remove-orphans
@printf "This command has been removed. Please use:\n\n mise prod # or mise //:prod from another directory\n\n" >&2 && exit 1
prod-down:
docker compose -f ./docker/docker-compose.prod.yml down --remove-orphans
@printf "This command has been removed. Please use:\n\n mise prod-down # or mise //:prod-down from another directory\n\n" >&2 && exit 1
prod-scale:
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
@printf "This command has been removed. Please use:\n\n mise prod-scale # or mise //:prod-scale from another directory\n\n" >&2 && exit 1
.PHONY: open-api
open-api:
cd ./open-api && bash ./bin/generate-open-api.sh
open-api-dart:
cd ./open-api && bash ./bin/generate-open-api.sh dart
open-api-typescript:
cd ./open-api && bash ./bin/generate-open-api.sh typescript
@printf "This command has been removed. Please use:\n\n mise open-api # or mise //:open-api from another directory\n\n" >&2 && exit 1
sql:
pnpm --filter immich run sync:sql
@printf "This command has been removed. Please use:\n\n mise sql # or mise //:sql from another directory\n\n" >&2 && exit 1
attach-server:
docker exec -it docker_immich-server_1 sh
renovate:
LOG_LEVEL=debug pnpm exec renovate --platform=local --repository-cache=reset
# Directories that need to be created for volumes or build output
VOLUME_DIRS = \
./.pnpm-store \
./web/.svelte-kit \
./web/node_modules \
./web/coverage \
./e2e/node_modules \
./docs/node_modules \
./server/node_modules \
./open-api/typescript-sdk/node_modules \
./.github/node_modules \
./node_modules \
./cli/node_modules
# Include .env file if it exists
-include docker/.env
MODULES = e2e server web cli sdk docs .github
# directory to package name mapping function
# cli = @immich/cli
# docs = documentation
# e2e = immich-e2e
# open-api/typescript-sdk = @immich/sdk
# server = immich
# web = immich-web
map-package = $(subst sdk,@immich/sdk,$(subst cli,@immich/cli,$(subst docs,documentation,$(subst e2e,immich-e2e,$(subst server,immich,$(subst web,immich-web,$1))))))
audit-%:
pnpm --filter $(call map-package,$*) audit fix
install-%:
pnpm --filter $(call map-package,$*) install $(if $(FROZEN),--frozen-lockfile) $(if $(OFFLINE),--offline)
build-cli: build-sdk
build-web: build-sdk
build-%: install-%
pnpm --filter $(call map-package,$*) run build
format-%:
pnpm --filter $(call map-package,$*) run format:fix
lint-%:
pnpm --filter $(call map-package,$*) run lint:fix
check-%:
pnpm --filter $(call map-package,$*) run check
check-web:
pnpm --filter immich-web run check:typescript
pnpm --filter immich-web run check:svelte
test-%:
pnpm --filter $(call map-package,$*) run test
test-e2e:
docker compose -f ./e2e/docker-compose.yml build
pnpm --filter immich-e2e run test
pnpm --filter immich-e2e run test:web
test-medium:
docker run \
--rm \
-v ./server/src:/usr/src/app/src \
-v ./server/test:/usr/src/app/test \
-v ./server/vitest.config.medium.mjs:/usr/src/app/vitest.config.medium.mjs \
-v ./server/tsconfig.json:/usr/src/app/tsconfig.json \
-e NODE_ENV=development \
immich-server:latest \
-c "pnpm test:medium -- --run"
test-medium-dev:
docker exec -it immich_server /bin/sh -c "pnpm run test:medium"
install-all:
pnpm -r --filter '!documentation' install
build-all: $(foreach M,$(filter-out e2e docs .github,$(MODULES)),build-$M) ;
check-all:
pnpm -r --filter '!documentation' run "/^(check|check\:svelte|check\:typescript)$/"
lint-all:
pnpm -r --filter '!documentation' run lint:fix
format-all:
pnpm -r --filter '!documentation' run format:fix
audit-all:
pnpm -r --filter '!documentation' audit fix
hygiene-all: audit-all
pnpm -r --filter '!documentation' run "/(format:fix|check|check:svelte|check:typescript|sql)/"
test-all:
pnpm -r --filter '!documentation' run "/^test/"
@printf "This command has been removed. Please use:\n\n mise //e2e:test # or mise //e2e:test-web for web tests, respectively\n\n" >&2 && exit 1
clean:
find . -name "node_modules" -type d -prune -exec rm -rf {} +
find . -name "dist" -type d -prune -exec rm -rf '{}' +
find . -name "build" -type d -prune -exec rm -rf '{}' +
find . -name ".svelte-kit" -type d -prune -exec rm -rf '{}' +
find . -name "coverage" -type d -prune -exec rm -rf '{}' +
find . -name ".pnpm-store" -type d -prune -exec rm -rf '{}' +
command -v docker >/dev/null 2>&1 && docker compose -f ./docker/docker-compose.dev.yml down -v --remove-orphans || true
command -v docker >/dev/null 2>&1 && docker compose -f ./e2e/docker-compose.yml down -v --remove-orphans || true
setup-server-dev: install-server
setup-web-dev: install-sdk build-sdk install-web
@printf "This command has been removed. Please use:\n\n mise clean # or mise //:clean from another directory\n\n" >&2 && exit 1
-5
View File
@@ -1,5 +0,0 @@
# Security Policy
## Reporting a Vulnerability
Please report security issues to `security@immich.app`
-1
View File
@@ -1 +0,0 @@
24.15.0
-14
View File
@@ -1,14 +0,0 @@
FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a7dea969802d7e0c2b25 AS core
WORKDIR /usr/src/app
COPY package* pnpm* .pnpmfile.cjs ./
COPY ./cli ./cli/
COPY ./open-api/typescript-sdk ./open-api/typescript-sdk/
RUN corepack enable pnpm && \
pnpm install --filter @immich/sdk --filter @immich/cli --frozen-lockfile && \
pnpm --filter @immich/sdk build && \
pnpm --filter @immich/cli build
WORKDIR /import
ENTRYPOINT ["node", "/usr/src/app/cli/dist"]
+65
View File
@@ -0,0 +1,65 @@
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
[[tools.opentofu]]
version = "1.11.6"
backend = "aqua:opentofu/opentofu"
[tools.opentofu."platforms.linux-arm64"]
checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz"
[tools.opentofu."platforms.linux-arm64-musl"]
checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz"
[tools.opentofu."platforms.linux-x64"]
checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz"
[tools.opentofu."platforms.linux-x64-musl"]
checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz"
[tools.opentofu."platforms.macos-arm64"]
checksum = "sha256:62d7fa8539e13b444827aa0a3b90c5972da5c47e8f8882d9dcf2e430e78840c1"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_arm64.tar.gz"
[tools.opentofu."platforms.macos-x64"]
checksum = "sha256:1408cdef1c380f914565e6b4bb70794c6b163f195fcb233357f3d6c5745906b6"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_amd64.tar.gz"
[tools.opentofu."platforms.windows-x64"]
checksum = "sha256:27323f70c875b8251bfd7e61a4cffc3ebff4e56ed1e611b955016f0c7077367e"
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_windows_amd64.tar.gz"
[[tools.terragrunt]]
version = "1.0.3"
backend = "aqua:gruntwork-io/terragrunt"
[tools.terragrunt."platforms.linux-arm64"]
checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz"
[tools.terragrunt."platforms.linux-arm64-musl"]
checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz"
[tools.terragrunt."platforms.linux-x64"]
checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz"
[tools.terragrunt."platforms.linux-x64-musl"]
checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz"
[tools.terragrunt."platforms.macos-arm64"]
checksum = "sha256:aacb5be2ca5475300cbce246dfbd8a45eb47510fbaa70fab8561c49ef5db03aa"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_arm64.tar.gz"
[tools.terragrunt."platforms.macos-x64"]
checksum = "sha256:3133c2251e191aede8e3dd2a5b3aee2e91c5f08f88f117aee40eed9a24c8ef6b"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_amd64.tar.gz"
[tools.terragrunt."platforms.windows-x64"]
checksum = "sha256:183b2745b4e04980a6bfa4450ff81956a12596ca22d70f7aaa793980f5b036db"
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_windows_amd64.exe.tar.gz"
+1 -1
View File
@@ -1,5 +1,5 @@
[tools]
terragrunt = "1.0.2"
terragrunt = "1.0.3"
opentofu = "1.11.6"
[tasks."tg:fmt"]
+30 -30
View File
@@ -2,37 +2,37 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
version = "4.52.5"
constraints = "4.52.5"
version = "4.52.7"
constraints = "4.52.7"
hashes = [
"h1:+rfzF+16ZcWZWnTyW/p1HHTzYbPKX8Zt2nIFtR/+f+E=",
"h1:18bXaaOSq8MWKuMxo/4y7EB7/i7G90y5QsKHZRmkoDo=",
"h1:4vZVOpKeEQZsF2VrARRZFeL37Ed/gD4rRMtfnvWQres=",
"h1:BZOsTF83QPKXTAaYqxPKzdl1KRjk/L2qbPpFjM0w28A=",
"h1:CDuC+HXLvc1z6wkCRsSDcc/+QENIHEtssYshiWg3opA=",
"h1:DE+YFzLnqSe79pI2R4idRGx5QzLdrA7RXvngTkGfZ30=",
"h1:DfaJwH3Ml4yrRbdAY4AcDVy0QTQk5T3A622TXzS/u2E=",
"h1:EIDXP0W3kgIv2pecrFmqtK/DnlqkyckzBzhxKaXU+4A=",
"h1:EV4kYyaOnwGA0bh/3hU6Ezqnt1PFDxopH7i85e48IzY=",
"h1:M0iXabfzamU+MPDi0G9XACpbacFKMakmM+Z9HZ8HrsM=",
"h1:YWmCbGF/KbsrUzcYVBLscwLizidbp95TDQa0N2qpmVo=",
"h1:cxPcCB5gbrpUO1+IXkQYs1YTY50/0IlApCzGea0cwuQ=",
"h1:g6DldikTV2HXUu9uoeNY5FuLufgaYWF4ufgZg7wq62s=",
"h1:oi/Hrx9pwoQ+Z52CBC+rrowVH387EIj0qvnxQgDeI+0=",
"zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b",
"zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a",
"zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7",
"zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238",
"zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b",
"zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072",
"zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661",
"zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c",
"h1:+O72J3QYiZtYmYYZM/Eh0f4NNfl1BvjX1eju43qTQsQ=",
"h1:0oqjYIPXcXh7XiDiKI085cHDYQQ5mh8kDl9dmBtvtog=",
"h1:4b4ESb87MGv5bnadgYe7sK5rEkKMZhbkQcwPubQTsR4=",
"h1:6mTr3eA1Ddb348lLmJuyvn98z4KF+ejqaUEJ76D1rzQ=",
"h1:9/3YH+9k9HqsvFtbmBf7SO2+xqZeZrXNKzLkjNuhUEA=",
"h1:Jcq4tBWgyH4/2JsojNBSRaN0mcItVMchO+lynonrlqc=",
"h1:Y4Vv/2RdP0Q+uxqhOxzOdKxuuEMjXPDcU0vPc5bCQzI=",
"h1:a0gW8FBKsbP9Fi0HEDoy49WIbEWVHk9+BR4/iwuBdDQ=",
"h1:gElv6iqJtg8OKN77gbw+MjrkrQmJHPkkMEi1J+0xkpU=",
"h1:oslXUugD/NQ+duJgT4BhKQyfGbuFOANknMvR73fiOeM=",
"h1:pPItIWii5oymR+geZB219ROSPuSODPLTlM4S/u8xLvM=",
"h1:u67GWw8GwD9NDlDzp9Y5VRnSQGcCrE8rSpkGPaBpDl0=",
"h1:uUUa9dY0XQOycI8pxg16PFFtL0WCTi9uEJz8trTQ7pU=",
"h1:y3rV8KF2q6GEMANNlf5EkKJurlfbKlIKpjGcdxoy7pQ=",
"zh:0c904ce31a4c6c4a5b3bf7ff1560e77c0cc7e2450c8553ded8e8c90398e1418b",
"zh:36183d310c36373fe4cb936b83c595c6fd3b0a94bc7827f28e5789ccbf59752e",
"zh:556a568a6f0235e8f41647de9e4d3a1e7b1d6502df8b19b54ec441f1c653ea10",
"zh:633ebbd5b0245e75e500ef9be4d9e62288f97e8da3baaa51323892a786d90285",
"zh:6acfe60cf52a65ba8f044f748548d2119e7f4fd7f8ebcb14698960d87c68f529",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54",
"zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852",
"zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0",
"zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5",
"zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036",
"zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803",
"zh:904acc31ebb9d6ef68c792074b30532ee61bf515f19e0a3c75b46f126cca1f13",
"zh:a1d0a81246afc8750286d3f6fe7a8fbe6460dd2662407b28dbfbabb612e5fa9d",
"zh:a41a36fe253fc365fe2b7ffc749624688b2693b4634862fda161179ab100029f",
"zh:a7ef269e77ffa8715c8945a2c14322c7ff159ea44c15f62505f3cbb2cae3b32d",
"zh:b01aa3bed30610633b762df64332b26f8844a68c3960cebcb30f04918efc67fe",
"zh:b069cc2cd18cae10757df3ae030508eac8d55de7e49eda7a5e3e11f2f7fe6455",
"zh:b2d2c6313729ebb7465dceece374049e2d08bda34473901be9ff46a8836d42b2",
"zh:db0e114edaf4bc2f3d4769958807c83022bfbc619a00bdf4c4bd17faa4ab2d8b",
"zh:ecc0aa8b9044f664fd2aaf8fa992d976578f78478980555b4b8f6148e8d1a5fe",
]
}
@@ -5,7 +5,7 @@ terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "4.52.5"
version = "4.52.7"
}
}
}
+30 -30
View File
@@ -2,37 +2,37 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
version = "4.52.5"
constraints = "4.52.5"
version = "4.52.7"
constraints = "4.52.7"
hashes = [
"h1:+rfzF+16ZcWZWnTyW/p1HHTzYbPKX8Zt2nIFtR/+f+E=",
"h1:18bXaaOSq8MWKuMxo/4y7EB7/i7G90y5QsKHZRmkoDo=",
"h1:4vZVOpKeEQZsF2VrARRZFeL37Ed/gD4rRMtfnvWQres=",
"h1:BZOsTF83QPKXTAaYqxPKzdl1KRjk/L2qbPpFjM0w28A=",
"h1:CDuC+HXLvc1z6wkCRsSDcc/+QENIHEtssYshiWg3opA=",
"h1:DE+YFzLnqSe79pI2R4idRGx5QzLdrA7RXvngTkGfZ30=",
"h1:DfaJwH3Ml4yrRbdAY4AcDVy0QTQk5T3A622TXzS/u2E=",
"h1:EIDXP0W3kgIv2pecrFmqtK/DnlqkyckzBzhxKaXU+4A=",
"h1:EV4kYyaOnwGA0bh/3hU6Ezqnt1PFDxopH7i85e48IzY=",
"h1:M0iXabfzamU+MPDi0G9XACpbacFKMakmM+Z9HZ8HrsM=",
"h1:YWmCbGF/KbsrUzcYVBLscwLizidbp95TDQa0N2qpmVo=",
"h1:cxPcCB5gbrpUO1+IXkQYs1YTY50/0IlApCzGea0cwuQ=",
"h1:g6DldikTV2HXUu9uoeNY5FuLufgaYWF4ufgZg7wq62s=",
"h1:oi/Hrx9pwoQ+Z52CBC+rrowVH387EIj0qvnxQgDeI+0=",
"zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b",
"zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a",
"zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7",
"zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238",
"zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b",
"zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072",
"zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661",
"zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c",
"h1:+O72J3QYiZtYmYYZM/Eh0f4NNfl1BvjX1eju43qTQsQ=",
"h1:0oqjYIPXcXh7XiDiKI085cHDYQQ5mh8kDl9dmBtvtog=",
"h1:4b4ESb87MGv5bnadgYe7sK5rEkKMZhbkQcwPubQTsR4=",
"h1:6mTr3eA1Ddb348lLmJuyvn98z4KF+ejqaUEJ76D1rzQ=",
"h1:9/3YH+9k9HqsvFtbmBf7SO2+xqZeZrXNKzLkjNuhUEA=",
"h1:Jcq4tBWgyH4/2JsojNBSRaN0mcItVMchO+lynonrlqc=",
"h1:Y4Vv/2RdP0Q+uxqhOxzOdKxuuEMjXPDcU0vPc5bCQzI=",
"h1:a0gW8FBKsbP9Fi0HEDoy49WIbEWVHk9+BR4/iwuBdDQ=",
"h1:gElv6iqJtg8OKN77gbw+MjrkrQmJHPkkMEi1J+0xkpU=",
"h1:oslXUugD/NQ+duJgT4BhKQyfGbuFOANknMvR73fiOeM=",
"h1:pPItIWii5oymR+geZB219ROSPuSODPLTlM4S/u8xLvM=",
"h1:u67GWw8GwD9NDlDzp9Y5VRnSQGcCrE8rSpkGPaBpDl0=",
"h1:uUUa9dY0XQOycI8pxg16PFFtL0WCTi9uEJz8trTQ7pU=",
"h1:y3rV8KF2q6GEMANNlf5EkKJurlfbKlIKpjGcdxoy7pQ=",
"zh:0c904ce31a4c6c4a5b3bf7ff1560e77c0cc7e2450c8553ded8e8c90398e1418b",
"zh:36183d310c36373fe4cb936b83c595c6fd3b0a94bc7827f28e5789ccbf59752e",
"zh:556a568a6f0235e8f41647de9e4d3a1e7b1d6502df8b19b54ec441f1c653ea10",
"zh:633ebbd5b0245e75e500ef9be4d9e62288f97e8da3baaa51323892a786d90285",
"zh:6acfe60cf52a65ba8f044f748548d2119e7f4fd7f8ebcb14698960d87c68f529",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54",
"zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852",
"zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0",
"zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5",
"zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036",
"zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803",
"zh:904acc31ebb9d6ef68c792074b30532ee61bf515f19e0a3c75b46f126cca1f13",
"zh:a1d0a81246afc8750286d3f6fe7a8fbe6460dd2662407b28dbfbabb612e5fa9d",
"zh:a41a36fe253fc365fe2b7ffc749624688b2693b4634862fda161179ab100029f",
"zh:a7ef269e77ffa8715c8945a2c14322c7ff159ea44c15f62505f3cbb2cae3b32d",
"zh:b01aa3bed30610633b762df64332b26f8844a68c3960cebcb30f04918efc67fe",
"zh:b069cc2cd18cae10757df3ae030508eac8d55de7e49eda7a5e3e11f2f7fe6455",
"zh:b2d2c6313729ebb7465dceece374049e2d08bda34473901be9ff46a8836d42b2",
"zh:db0e114edaf4bc2f3d4769958807c83022bfbc619a00bdf4c4bd17faa4ab2d8b",
"zh:ecc0aa8b9044f664fd2aaf8fa992d976578f78478980555b4b8f6148e8d1a5fe",
]
}
+1 -1
View File
@@ -5,7 +5,7 @@ terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "4.52.5"
version = "4.52.7"
}
}
}
+8 -13
View File
@@ -21,14 +21,14 @@ services:
volumes:
- ..:/usr/src/app
# - ../../ui:/usr/src/ui
- pnpm_cache:/buildcache/pnpm_cache
- build_cache:/buildcache
- server_node_modules:/usr/src/app/server/node_modules
- web_node_modules:/usr/src/app/web/node_modules
- github_node_modules:/usr/src/app/.github/node_modules
- cli_node_modules:/usr/src/app/cli/node_modules
- cli_node_modules:/usr/src/app/packages/cli/node_modules
- docs_node_modules:/usr/src/app/docs/node_modules
- e2e_node_modules:/usr/src/app/e2e/node_modules
- sdk_node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
- sdk_node_modules:/usr/src/app/packages/sdk/node_modules
- app_node_modules:/usr/src/app/node_modules
- sveltekit:/usr/src/app/web/.svelte-kit
- coverage:/usr/src/app/web/coverage
@@ -45,11 +45,11 @@ services:
target: dev
command:
- |
pnpm install
mise install
touch /tmp/init-complete
exec tail -f /dev/null
volumes:
- pnpm_store_server:/buildcache/pnpm-store
- build_cache:/buildcache
restart: 'no'
healthcheck:
test: ['CMD', 'test', '-f', '/tmp/init-complete']
@@ -73,8 +73,7 @@ services:
volumes:
- ${UPLOAD_LOCATION}/photos:/data
- /etc/localtime:/etc/localtime:ro
- pnpm_store_server:/buildcache/pnpm-store
- ../plugins:/build/corePlugin
- ../packages/plugin-core:/build/plugins/immich-plugin-core
env_file:
- .env
environment:
@@ -122,8 +121,6 @@ services:
ports:
- 3000:3000
- 24678:24678
volumes:
- pnpm_store_web:/buildcache/pnpm-store
restart: unless-stopped
depends_on:
immich-init:
@@ -157,7 +154,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1
@@ -203,9 +200,7 @@ volumes:
model_cache:
prometheus_data:
grafana_data:
pnpm_cache:
pnpm_store_server:
pnpm_store_web:
build_cache:
server_node_modules:
web_node_modules:
github_node_modules:
+3 -3
View File
@@ -56,7 +56,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1
restart: always
@@ -85,7 +85,7 @@ services:
container_name: immich_prometheus
ports:
- 9090:9090
image: prom/prometheus@sha256:e4254400b85610324913f0dc4acf92603d9984e7519414c5a12811aa6146acc3
image: prom/prometheus@sha256:69f5241418838263316593f7274a304b095c40bcf22e57272865da91bd60a8ac
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
@@ -97,7 +97,7 @@ services:
command: ['./run.sh', '-disable-reporting']
ports:
- 3000:3000
image: grafana/grafana:12.4.2-ubuntu@sha256:78839fe49e1425c02416fa8072591533a72bd9598e563b54a07d78f9e27fb5d3
image: grafana/grafana:12.4.3-ubuntu@sha256:ca3f764fdc48cebdf22dd206f33ecb0795a9a7210eacd1b5c02204aebd78b223
volumes:
- grafana-data:/var/lib/grafana
+1 -4
View File
@@ -61,7 +61,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
user: '1000:1000'
security_opt:
- no-new-privileges:true
@@ -95,6 +95,3 @@ services:
restart: always
healthcheck:
disable: false
volumes:
model-cache:
+1 -1
View File
@@ -49,7 +49,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1
restart: always
-1
View File
@@ -1 +0,0 @@
24.15.0
+6
View File
@@ -26,6 +26,8 @@ For organizations seeking to resell Immich, we have established the following gu
When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app
---
## User
### How can I reset the admin password?
@@ -36,6 +38,10 @@ The admin password can be reset by running the [reset-admin-password](/administr
You can see the list of all users by running [list-users](/administration/server-commands.md) Command on the Immich-server.
### How can I change my profile picture?
View a single photo, press the three dots in the top-right to show context menu, and select "Set as profile picture". In the pop-up, use your mouse scroll wheel to zoom in the picture until it completely fills the circle. Click and drag the picture to align it to your liking. Press "Save" to save your changes.
---
## Mobile App
@@ -13,8 +13,11 @@ The `immich-server` docker image comes preinstalled with an administrative CLI (
| `enable-oauth-login` | Enable OAuth login |
| `disable-oauth-login` | Disable OAuth login |
| `list-users` | List Immich users |
| `grant-admin` | Grant admin privileges to a user (by email) |
| `revoke-admin` | Revoke admin privileges from a user (by email) |
| `version` | Print Immich version |
| `change-media-location` | Change database file paths to align with a new media location |
| `schema-check` | Verify database migrations and check for schema drift |
## How to run a command
@@ -102,6 +105,22 @@ immich-admin list-users
]
```
Grant Admin
```
immich-admin grant-admin
? Please enter the user email: user@example.com
Admin access has been granted to user@example.com
```
Revoke Admin
```
immich-admin revoke-admin
? Please enter the user email: user@example.com
Admin access has been revoked from user@example.com
```
Print Immich Version
```
@@ -126,3 +145,12 @@ immich-admin change-media-location
Database file paths updated successfully! 🎉
...
```
Schema Check
```
immich-admin schema-check
Migrations are up to date
No schema drift detected
```
+1 -1
View File
@@ -10,4 +10,4 @@ OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generato
make open-api
```
You can find the generated client SDK in the `open-api/typescript-sdk/client` for Typescript SDK and `mobile/openapi` for Dart SDK.
You can find the generated client SDK in the `packages/sdk/client` for Typescript SDK and `mobile/openapi` for Dart SDK.
+2 -2
View File
@@ -5,7 +5,7 @@ After making any changes in the `server/src/schema`, a database migration need t
1. Run the command
```bash
pnpm run migrations:generate <migration-name>
mise //server:migrations generate <migration-name>
```
2. Check if the migration file makes sense.
@@ -18,7 +18,7 @@ The server will automatically detect `*.ts` file changes and restart. Part of th
If you need to undo the most recently applied migration—for example, when developing or testing on schema changes—run:
```bash
pnpm run migrations:revert
mise //server:migrations revert
```
This command rolls back the latest migration and brings the database schema back to its previous state.
+20 -72
View File
@@ -205,7 +205,7 @@ When the Dev Container starts, it automatically:
1. **Runs post-create script** (`container-server-post-create.sh`):
- Adjusts file permissions for the `node` user
- Installs dependencies: `pnpm install` in all packages
- Builds TypeScript SDK: `pnpm run build` in `open-api/typescript-sdk`
- Builds TypeScript SDK: `pnpm --filter @immich/sdk build`
2. **Starts development servers** via VS Code tasks:
- `Immich API Server (Nest)` - API server with hot-reloading on port 2283
@@ -243,8 +243,8 @@ To connect the mobile app to your Dev Container:
- **Server code** (`/server`): Changes trigger automatic restart
- **Web code** (`/web`): Changes trigger hot module replacement
- **Database migrations**: Run `pnpm run sync:sql` in the server directory
- **API changes**: Regenerate TypeScript SDK with `make open-api`
- **Database migrations**: Run `mise //:sql`
- **API changes**: Regenerate TypeScript SDK with `mise //:open-api`
## Testing
@@ -252,85 +252,33 @@ To connect the mobile app to your Dev Container:
The Dev Container supports multiple ways to run tests:
#### Using Make Commands (Recommended)
```bash
# Run tests for specific components
make test-server # Server unit tests
make test-web # Web unit tests
make test-e2e # End-to-end tests
make test-cli # CLI tests
# Server
mise //server:test # unit tests
mise //server:test-medium # medium / integration tests
# Run all tests
make test-all # Runs tests for all components
# Web
mise //web:test # unit tests
# Medium tests (integration tests)
make test-medium-dev # End-to-end tests
# E2E
mise //e2e:test # API tests
mise //e2e:test-web # web UI tests (Playwright)
# Run all checks for a component
mise //server:checklist
mise //web:checklist
```
#### Using PNPM Directly
### Additional Commands
```bash
# Server tests
cd /workspaces/immich/server
pnpm test # Run all tests
pnpm run test:medium # Medium tests (integration tests)
pnpm run test:watch # Watch mode
pnpm run test:cov # Coverage report
# Web tests
cd /workspaces/immich/web
pnpm test # Run all tests
pnpm run test:watch # Watch mode
# E2E tests
cd /workspaces/immich/e2e
pnpm run test # Run API tests
pnpm run test:web # Run web UI tests
```
### Code Quality Commands
```bash
# Linting
make lint-server # Lint server code
make lint-web # Lint web code
make lint-all # Lint all components
# Formatting
make format-server # Format server code
make format-web # Format web code
make format-all # Format all code
# Type checking
make check-server # Type check server
make check-web # Type check web
make check-all # Check all components
# Complete hygiene check
make hygiene-all # Run lint, format, check, SQL sync, and audit
```
### Additional Make Commands
```bash
# Build commands
make build-server # Build server
make build-web # Build web app
make build-all # Build everything
# API generation
make open-api # Generate OpenAPI specs
make open-api-typescript # Generate TypeScript SDK
make open-api-dart # Generate Dart SDK
mise //:open-api # Generate OpenAPI specs
mise //:open-api-typescript # Generate TypeScript SDK
mise //:open-api-dart # Generate Dart SDK
# Database
make sql # Sync database schema
# Dependencies
make install-server # Install server dependencies
make install-web # Install web dependencies
make install-all # Install all dependencies
mise //server:sql # Sync database schema
```
### Debugging
+2 -1
View File
@@ -10,7 +10,8 @@ Our [GitHub Repository](https://github.com/immich-app/immich) is a [monorepo](ht
| :------------------ | :------------------------------------------------------------------- |
| `.github/` | Github templates and action workflows |
| `.vscode/` | VSCode debug launch profiles |
| `cli/` | Source code for the work-in-progress CLI rewrite |
| `packages/cli` | Source code for the CLI |
| `packages/sdk` | Source code for the generated OpenAPI SDK |
| `docker/` | Docker compose resources for dev, test, production |
| `design/` | Screenshots and logos for the README |
| `docs/` | Source code for the [https://immich.app](https://immich.app) website |
+43 -22
View File
@@ -8,47 +8,68 @@ When contributing code through a pull request, please check the following:
## Web Checks
- [ ] `pnpm run lint` (linting via ESLint)
- [ ] `pnpm run format` (formatting via Prettier)
- [ ] `pnpm run check:svelte` (Type checking via SvelteKit)
- [ ] `pnpm run check:typescript` (check typescript)
- [ ] `pnpm test` (unit tests)
- [ ] `mise //web:lint` (linting via ESLint)
- [ ] `mise //web:format` (formatting via Prettier)
- [ ] `mise //web:check-svelte` (type checking via SvelteKit)
- [ ] `mise //web:check-typescript` (type checking via `tsc`)
- [ ] `mise //web:test` (unit tests)
:::tip AIO
Run all web checks with `pnpm run check:all`
Run all web checks with `mise //web:checklist`
:::
:::tip Auto Fix
Use `mise //web:lint-fix` and `mise //web:format-fix` to automatically correct some issues.
:::
## Documentation
- [ ] `pnpm run format` (formatting via Prettier)
- [ ] `mise //docs:format` (formatting via Prettier)
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
:::tip Auto Fix
Use `mise //docs:format-fix` to automatically fix formatting.
:::
## Server Checks
- [ ] `pnpm run lint` (linting via ESLint)
- [ ] `pnpm run format` (formatting via Prettier)
- [ ] `pnpm run check` (Type checking via `tsc`)
- [ ] `pnpm test` (unit tests)
- [ ] `mise //server:lint` (linting via ESLint)
- [ ] `mise //server:format` (formatting via Prettier)
- [ ] `mise //server:check` (type checking via `tsc`)
- [ ] `mise //server:test` (unit tests)
:::tip AIO
Run all server checks with `pnpm run check:all`
Run all server checks with `mise //server:checklist`
:::
:::info Auto Fix
You can use `pnpm run __:fix` to potentially correct some issues automatically for `pnpm run format` and `lint`.
:::tip Auto Fix
Use `mise //server:lint-fix` and `mise //server:format-fix` to automatically correct some issues.
:::
## Mobile Checks
## Mobile Checklist
The following commands must be executed from within the mobile app directory of the codebase.
- [ ] `mise //mobile:codegen` (auto-generate files using build_runner)
- [ ] `mise //mobile:lint` (static analysis via Dart Analyzer and DCM)
- [ ] `mise //mobile:format` (formatting via Dart Formatter)
- [ ] `mise //mobile:test` (unit tests)
- [ ] `make build` (auto-generate files using build_runner)
- [ ] `make analyze` (static analysis via Dart Analyzer and DCM)
- [ ] `make format` (formatting via Dart Formatter)
- [ ] `make test` (unit tests)
:::tip
Run all these commands at once with `mise //mobile:checklist`
:::
:::info Auto Fix
You can use `dart fix --apply` and `dcm fix lib` to potentially correct some issues automatically for `make analyze`.
:::tip Auto Fix
You can use `mise //mobile:lint-fix` to potentially correct some issues automatically for `mise //mobile:lint`.
:::
## Machine Learning Checklist
- [ ] `mise //machine-learning:lint` (linting via ruff)
- [ ] `mise //machine-learning:format` (formatting via ruff)
- [ ] `mise //machine-learning:check` (type checking via mypy)
- [ ] `mise //machine-learning:test` (unit tests via pytest)
:::tip AIO
Run all machine learning checks with `mise //machine-learning:checklist`
:::
## OpenAPI
+36 -17
View File
@@ -32,6 +32,10 @@ This environment includes the services below. Additional details are available i
All the services are packaged to run as with single Docker Compose command.
:::tip mise
[mise](https://mise.jdx.dev) is used throughout the project to manage tool versions and run tasks. [Install mise](https://mise.jdx.dev/installing-mise.html), then from the repo root run `mise trust` and `mise install` to get all required tools. Tasks for each service can be run from the repo root using `mise //namespace:task` (e.g. `mise //server:lint`). To list all available tasks, run `mise tasks ls --all`.
:::
### Server and web apps
1. Clone the project repo.
@@ -56,22 +60,23 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3
#### Connect web to a remote backend
If you only want to do web development connected to an existing, remote backend, follow these steps:
1. Build the Immich SDK - `cd open-api/typescript-sdk && pnpm i && pnpm run build && cd -`
2. Enter the web directory - `cd web/`
3. Install web dependencies - `pnpm i`
4. Start the web development server
If you only want to do web development connected to an existing, remote backend, run from the repo root:
```bash
IMMICH_SERVER_URL=https://demo.immich.app/ pnpm run dev
IMMICH_SERVER_URL=https://demo.immich.app/ mise //web:start
```
This will install all dependencies (including the SDK) and start the dev server in one step. To connect to the hosted demo server specifically, use the shorthand:
```bash
mise //web:start-demo
```
If you're using PowerShell on Windows you may need to set the env var separately like so:
```powershell
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
pnpm run dev
mise //web:start
```
#### `@immich/ui`
@@ -90,24 +95,38 @@ To see local changes to `@immich/ui` in Immich, do the following:
#### Setup
1. [Install mise](https://mise.jdx.dev/installing-mise.html).
2. Change to the immich (root) directory and trust the mise config with `mise trust`.
3. Install tools with mise: `mise install`.
4. Change to the `mobile/` directory.
5. Run `flutter pub get` to install the dependencies.
6. Run `make translation` to generate the translation file.
7. Run `flutter run` to start the app.
1. Run `mise //mobile:install` to install Flutter dependencies.
2. Run `mise //mobile:translation` to generate the translation file.
3. Change to the `mobile/` directory and run `flutter run` to start the app.
#### Translation
To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then, from the `mobile/` directory, run
To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then run:
```bash
make translation
mise //mobile:translation
```
The mobile app asks you what backend to connect to. You can utilize the demo backend (https://demo.immich.app/) if you don't need to change server code or upload photos. Alternatively, you can run the server yourself per the instructions above.
#### UI components and widget previews
Shared design-system widgets (buttons, inputs, forms) live in the
[`immich_ui` package](https://github.com/immich-app/immich/tree/main/mobile/packages/ui/)
under `mobile/packages/ui/`. Components are defined in `lib/src/components/`
and have matching previews in `lib/src/previews/`.
To inspect a component in isolation with a light/dark toggle and hot reload,
launch [Flutter's Widget Previewer](https://docs.flutter.dev/tools/widget-previewer):
```bash
cd mobile/packages/ui
flutter widget-preview start
```
In VS Code or Android Studio with the Flutter plugin, the previewer
auto-starts when you open the **Flutter Widget Preview** tab in the sidebar.
## IDE setup
### Lint / format extensions
+5 -7
View File
@@ -4,8 +4,8 @@
### Unit tests
Unit are run by calling `pnpm run test` from the `server/` directory.
You need to run `pnpm install` (in `server/`) before _once_.
Unit tests are run with `mise //server:test`.
You need to run `mise //server:install` before _once_.
### End to end tests
@@ -17,15 +17,13 @@ make e2e
Before you can run the tests, you need to run the following commands _once_:
- `pnpm install` (in `e2e/`)
- `pnpm run build` (in `cli/`)
- `make open-api` (in the project root `/`)
- `mise //e2e:ci-setup` (installs e2e, SDK, and CLI dependencies)
- `mise //:open-api`
Once the test environment is running, the e2e tests can be run via:
```bash
cd e2e/
pnpm test
mise //e2e:test
```
The tests check various things including:
+2
View File
@@ -50,6 +50,8 @@ Some basic examples:
- `**/Raw/**` will exclude all files in any directory named `Raw`
- `**/*.{tif,jpg}` will exclude all files with the extension `.tif` or `.jpg`
Note that `*` is a wildcard matching zero or more characters (i.e., withinin a filename or single directory name). `**` matches zero or more subdirectories, recursively. It also includes any/all files within a subdirectory, i.e., when used at the end of a pattern. For example, `**/exclude_me/**` will exclude all files in any directory named `exclude_me`, as well as all files in any subdirectories of `exclude_me`, recursively.
Special characters such as @ should be escaped, for instance:
- `**/\@eaDir/**` will exclude all files in any directory named `@eaDir`
@@ -47,6 +47,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele
#### ROCm
- On Linux, The [AMDGPU driver module](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html) needs to be installed on the server and, if secure boot is used, the signing key of DKMS [needs to be enrolled in UEFI BIOS](https://wiki.debian.org/SecureBoot)
- The GPU must be supported by ROCm. If it isn't officially supported, you can attempt to use the `HSA_OVERRIDE_GFX_VERSION` environmental variable: `HSA_OVERRIDE_GFX_VERSION=<a supported version, e.g. 10.3.0>`. If this doesn't work, you might need to also set `HSA_USE_SVM=0`.
- The ROCm image is quite large and requires at least 35GiB of free disk space. However, pulling later updates to the service through Docker will generally only amount to a few hundred megabytes as the rest will be cached.
- This backend is new and may experience some issues. For example, GPU power consumption can be higher than usual after running inference, even if the machine learning service is idle. In this case, it will only go back to normal after being idle for 5 minutes (configurable with the [MACHINE_LEARNING_MODEL_TTL](/install/environment-variables) setting).
+7
View File
@@ -18,6 +18,7 @@ You can search the following types of content:
| People | Faces that are recognized in your photos/videos. |
| Contextual | Content of the photos and videos. |
| File name or extension | Full or partial file's name, or file's extension |
| Full path or folder | Full or partial folder names from the original path. |
| Description | Description added to assets. |
| Optical Character Recognition (OCR) | Text in images |
| Locations | Cities, states, and countries from reverse geocoding. |
@@ -30,6 +31,12 @@ You can search the following types of content:
<img src={require('./img/advanced-search-filters.webp').default} width="70%" title='Advanced search filters' />
### Full path or folder
Use this mode when you know a folder name or part of the original asset path.
Example: for /John/Projects/3D_Printing/2026-07-01/IMG_0001.jpg, searches like Projects, 3D, Printing, or 2026 match the asset.
## Configuration
Navigating to `Administration > Settings > Machine Learning Settings > Smart Search` will show the options available.
+2 -2
View File
@@ -26,7 +26,7 @@ The default configuration looks like this:
},
"ffmpeg": {
"accel": "disabled",
"accelDecode": false,
"accelDecode": true,
"acceptedAudioCodecs": ["aac", "mp3", "opus"],
"acceptedContainers": ["mov", "ogg", "webm"],
"acceptedVideoCodecs": ["h264"],
@@ -264,4 +264,4 @@ volumes:
- ./configuration.yml:${IMMICH_CONFIG_FILE}
```
::
:::
+46 -44
View File
@@ -29,29 +29,31 @@ These environment variables are used by the `docker-compose.yml` file and do **N
## General
| Variable | Description | Default | Containers | Workers |
| :---------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- |
| `TZ` | Timezone | <sup>\*1</sup> | server | microservices |
| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices |
| `IMMICH_LOG_LEVEL` | Log level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices |
| `IMMICH_LOG_FORMAT` | Log output format (`console`, `json`) | `console` | server | api, microservices |
| `IMMICH_MEDIA_LOCATION` | Media location inside the container ⚠️**You probably shouldn't set this**<sup>\*2</sup>⚠️ | `/data` | server | api, microservices |
| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices |
| `IMMICH_HELMET_FILE` | Path to a json file with [helmet](https://www.npmjs.com/package/helmet) options. Set to `false` to disable. Set to `true` to use `server/helmet.json`. | `false` | server | api |
| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | |
| `CPU_CORES` | Number of cores available to the Immich server | auto-detected CPU core count | server | |
| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api |
| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices |
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
| `IMMICH_TRUSTED_PROXIES` | List of comma-separated IPs set as trusted proxies | | server | api |
| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/administration/system-integrity) | | server | api, microservices |
| `IMMICH_ALLOW_SETUP` | When `false` disables the `/auth/admin-sign-up` endpoint | `true` | server | api |
| Variable | Description | Default | Containers | Workers |
| :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- |
| `TZ` | Timezone | <sup>\*1</sup> | server | microservices |
| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices |
| `IMMICH_LOG_LEVEL` | Log level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices |
| `IMMICH_LOG_FORMAT` | Log output format (`console`, `json`) | `console` | server | api, microservices |
| `IMMICH_MEDIA_LOCATION` | Media location inside the container ⚠️**You probably shouldn't set this**<sup>\*2</sup>⚠️ | `/data` | server | api, microservices |
| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices |
| `IMMICH_HELMET_FILE` | Path to a json file with [helmet](https://www.npmjs.com/package/helmet) options. Set to `false` to disable. Set to `true` to use `server/helmet.json`<sup>\*3</sup>. | `false` | server | api |
| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | |
| `CPU_CORES` | Number of cores available to the Immich server | auto-detected CPU core count | server | |
| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api |
| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices |
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
| `IMMICH_TRUSTED_PROXIES` | List of comma-separated IPs set as trusted proxies | | server | api |
| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/administration/system-integrity) | | server | api, microservices |
| `IMMICH_ALLOW_SETUP` | When `false` disables the `/auth/admin-sign-up` endpoint | `true` | server | api |
\*1: `TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`.
`TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution.
\*2: This path is where the Immich code looks for the files, which is internal to the docker container. Setting it to a path on your host will certainly break things, you should use the `UPLOAD_LOCATION` variable instead.
\*3: The [default configuration](https://helmetjs.github.io/#content-security-policy) sets `upgrade-insecure-requests`, which tells the browser to upgrade all requests to HTTPS. This breaks on HTTP-only deployments. If you cannot use HTTPS, you should use a custom helmet config file with `"upgrade-insecure-requests": null`.
## Workers
| Variable | Description | Default | Containers |
@@ -152,33 +154,33 @@ Redis (Sentinel) URL example JSON before encoding:
## Machine Learning
| Variable | Description | Default | Containers |
| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------: | :--------------- |
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `120` (`300` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning |
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning |
| Variable | Description | Default | Containers |
| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :--------------- |
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `300` (`900` if using ROCm) | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning |
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning |
\*1: It is recommended to begin with this parameter when changing the concurrency levels of the machine learning service and then tune the other ones.
+66 -2
View File
@@ -52,7 +52,7 @@ Scroll to the bottom of the "**Details**" section and find the `IP Address` list
## Step 4 - Configure Firewall Settings
Once your project completes the build process, your containers will start. In order to be able to access Immich from your browser, you need to configure the firewall settings for your Synology NAS.
Once your project completes the build process, your containers will start. In order to be able to access Immich from your browser, you need to configure the firewall settings for your Synology NAS to allow communication between the Immich containers.
Open "**Control Panel**" on your Synology NAS, and select "**Security**". Navigate to "**Firewall**"
@@ -74,6 +74,7 @@ Read the [Post Installation](/install/post-install.mdx) steps and [upgrade instr
<details>
<summary>Updating Immich using Container Manager</summary>
Check the post installation and upgrade instructions at the links above before proceeding with this section.
## Step 1. Backup
@@ -110,7 +111,7 @@ Go to **Project**, select **Action** then **Build**. This will download, unpack,
## Step 5. Update firewall rule
The default behavior is to automatically start the containers once installed. If `immich_server` runs for a few seconds and then stops, it may be because the firewall rule no longer matches the server IP address.
Without a fixed subnet, the default behavior is to automatically start the containers once installed. If `immich_server` runs for a few seconds and then stops, it may be because the firewall rule no longer matches the server IP address.
Go to the **Container** section. Click on `immich_server` and scroll down on **General** to find the IP address.
![Container IP](../../static/img/synology-container-ip.png)
@@ -123,4 +124,67 @@ In this example, the IP addresses mismatch and the firewall rule needs to be edi
![Edit IP](../../static/img/synology-fw-ipedit.png)
To prevent future firewall issues, you may set a fixed subnet. [See Set Fixed Subnet](#set-fixed-subnet) for instructions.
</details>
<details id="set-fixed-subnet">
<summary>Set Fixed Subnet</summary>
Docker by default assigns dynamic subnets to bridge networks which can change when rebuilding containers and can cause firewall rules to break. To avoid this, define a fixed subnet in your `docker-compose.yml`:
## Step 1. Determine current subnet
Go to the **Container** section. Click on `immich_server` and scroll down on **General** to find the IP address.
![Container IP](../../static/img/synology-container-ip.png)
## Step 2. Add network configuration
Add the following network configuration at the end of your `docker-compose.yml` file:
```yaml
networks:
immich-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
```
If your docker container is running on a different subnet then update accordingly.
## Step 3. Add network to each service
Add the network to each service (immich-server, immich-machine-learning, redis, database):
```yaml
services:
immich-server:
# other config options
networks:
- immich-network
immich-machine-learning:
# other config options
networks:
- immich-network
redis:
# other config options
networks:
- immich-network
database:
# other config options
networks:
- immich-network
```
Save your changes. Synology will ask if you want to save changes only or rebuild containers. Select rebuild containers.
## Step 4. Update Firewall Rules, if necessary
If your firewall rules were not already set for this subnet, the firewall rules will need to be updated. See [Step 4 - Configure Firewall Settings](#step-4---configure-firewall-settings).
</details>
+3 -1
View File
@@ -10,7 +10,6 @@ const config = {
url: 'https://docs.immich.app',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.png',
// GitHub pages deployment config.
@@ -29,6 +28,9 @@ const config = {
// Mermaid diagrams
markdown: {
mermaid: true,
hooks: {
onBrokenMarkdownLinks: 'warn',
},
},
themes: ['@docusaurus/theme-mermaid'],
+5
View File
@@ -0,0 +1,5 @@
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
[[tools.wrangler]]
version = "4.66.0"
backend = "npm:wrangler"
+2 -2
View File
@@ -3,7 +3,7 @@ run = "pnpm install --filter documentation --frozen-lockfile"
[tasks.start]
env._.path = "./node_modules/.bin"
run = "docusaurus --port 3005"
run = "docusaurus start --port 3005"
[tasks.build]
env._.path = "./node_modules/.bin"
@@ -28,4 +28,4 @@ run = "prettier --write ."
run = "wrangler pages deploy build --project-name=${PROJECT_NAME} --branch=${BRANCH_NAME}"
[tools]
wrangler = "4.66.0"
wrangler = "4.91.0"
-3
View File
@@ -56,8 +56,5 @@
},
"engines": {
"node": ">=20"
},
"volta": {
"node": "24.15.0"
}
}
-1
View File
@@ -1 +0,0 @@
24.15.0
+1 -3
View File
@@ -83,9 +83,7 @@ volumes:
model_cache:
prometheus_data:
grafana_data:
pnpm_cache:
pnpm_store_server:
pnpm_store_web:
build_cache:
server_node_modules:
web_node_modules:
github_node_modules:
+2 -2
View File
@@ -4,7 +4,7 @@ services:
e2e-auth-server:
container_name: immich-e2e-auth-server
build:
context: ../e2e-auth-server
context: ../packages/e2e-auth-server
ports:
- 2286:2286
@@ -44,7 +44,7 @@ services:
redis:
container_name: immich-e2e-redis
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1
+30
View File
@@ -1,11 +1,21 @@
[tasks.install]
run = "pnpm install --filter immich-e2e --frozen-lockfile"
[tasks.build]
dir = "{{ config_root }}"
run = "docker compose build"
[tasks.test]
depends = ["//e2e:build", "//e2e:ci-setup"]
env._.path = "./node_modules/.bin"
run = "vitest --run"
[tasks.playwright-install]
env._.path = "./node_modules/.bin"
run = "playwright install"
[tasks."test-web"]
depends = ["//e2e:build", "//e2e:ci-setup", "//e2e:playwright-install"]
env._.path = "./node_modules/.bin"
run = "playwright test"
@@ -27,3 +37,23 @@ run = { task = "lint --fix" }
[tasks.check]
env._.path = "./node_modules/.bin"
run = "tsc --noEmit"
[tasks.ci-setup]
depends = [
"//:sdk:install",
"//:sdk:build",
"//packages/cli:install",
"//packages/cli:build",
]
run = { task = ":install" }
[tasks.ci-unit]
depends = ["//:sdk:install", "//:sdk:build"]
run = [
{ task = ":install" },
{ task = ":format" },
{ task = ":lint" },
{ task = ":check" },
]
+1 -4
View File
@@ -32,7 +32,7 @@
"@playwright/test": "^1.44.1",
"@socket.io/component-emitter": "^3.1.2",
"@types/luxon": "^3.4.2",
"@types/node": "^24.12.2",
"@types/node": "^24.12.4",
"@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4",
"@types/supertest": "^7.0.0",
@@ -56,8 +56,5 @@
"utimes": "^5.2.1",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^4.0.0"
},
"volta": {
"node": "24.15.0"
}
}
@@ -2,7 +2,7 @@ import { LoginResponseDto, ManualJobName } from '@immich/sdk';
import { errorDto } from 'src/responses';
import { app, utils } from 'src/utils';
import request from 'supertest';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
describe('/admin/database-backups', () => {
let cookie: string | undefined;
@@ -13,6 +13,9 @@ describe('/admin/database-backups', () => {
admin = await utils.adminSetup({
onboarding: false,
});
});
beforeEach(async () => {
await utils.resetBackups(admin.accessToken);
});
+74 -10
View File
@@ -146,7 +146,7 @@ describe('/albums', () => {
it('should not return shared albums with a deleted owner', async () => {
const { status, body } = await request(app)
.get('/albums?shared=true')
.get('/albums?isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
@@ -188,7 +188,7 @@ describe('/albums', () => {
it('should return the album collection including owned and shared', async () => {
const { status, body } = await request(app).get('/albums').set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
expect(body).toHaveLength(5);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -219,13 +219,20 @@ describe('/albums', () => {
]),
shared: false,
}),
expect.objectContaining({
albumName: user2SharedUser,
albumUsers: expect.arrayContaining([
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
]),
shared: true,
}),
]),
);
});
it('should return the album collection filtered by shared', async () => {
it('should return the album collection filtered by isShared', async () => {
const { status, body } = await request(app)
.get('/albums?shared=true')
.get('/albums?isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
@@ -263,9 +270,9 @@ describe('/albums', () => {
);
});
it('should return the album collection filtered by NOT shared', async () => {
it('should return the album collection filtered by NOT isShared', async () => {
const { status, body } = await request(app)
.get('/albums?shared=false')
.get('/albums?isShared=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(1);
@@ -282,6 +289,63 @@ describe('/albums', () => {
);
});
it('should return only owned albums when filtered by isOwned=true', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(4);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ albumName: user1SharedEditorUser }),
expect.objectContaining({ albumName: user1SharedViewerUser }),
expect.objectContaining({ albumName: user1SharedLink }),
expect.objectContaining({ albumName: user1NotShared }),
]),
);
});
it('should return only shared-with-me albums when filtered by isOwned=false', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(1);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
albumName: user2SharedUser,
albumUsers: expect.arrayContaining([
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
]),
}),
]),
);
});
it('should return owned shared-out albums when filtered by isOwned=true&ishared=true', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=true&isShared=true')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(3);
expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({ albumName: user1SharedEditorUser }),
expect.objectContaining({ albumName: user1SharedViewerUser }),
expect.objectContaining({ albumName: user1SharedLink }),
]),
);
});
it('should return empty list when filtered by isOwned=false&isShared=false', async () => {
const { status, body } = await request(app)
.get('/albums?isOwned=false&isShared=false')
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(0);
});
it('should return the album collection filtered by assetId', async () => {
const { status, body } = await request(app)
.get(`/albums?assetId=${user1Asset2.id}`)
@@ -290,17 +354,17 @@ describe('/albums', () => {
expect(body).toHaveLength(2);
});
it('should return the album collection filtered by assetId and ignores shared=true', async () => {
it('should return the album collection filtered by assetId and ignores isShared=true', async () => {
const { status, body } = await request(app)
.get(`/albums?shared=true&assetId=${user1Asset1.id}`)
.get(`/albums?isShared=true&assetId=${user1Asset1.id}`)
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(5);
});
it('should return the album collection filtered by assetId and ignores shared=false', async () => {
it('should return the album collection filtered by assetId and ignores isShared=false', async () => {
const { status, body } = await request(app)
.get(`/albums?shared=false&assetId=${user1Asset1.id}`)
.get(`/albums?isShared=false&assetId=${user1Asset1.id}`)
.set('Authorization', `Bearer ${user1.accessToken}`);
expect(status).toBe(200);
expect(body).toHaveLength(5);
@@ -7,7 +7,6 @@ import {
getMyUser,
LoginResponseDto,
SharedLinkType,
updateConfig,
} from '@immich/sdk';
import { exiftool } from 'exiftool-vendored';
import { DateTime } from 'luxon';
@@ -24,7 +23,6 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
const locationAssetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
const ratingAssetFilepath = `${testAssetDir}/metadata/rating/mongolels.jpg`;
const facesAssetDir = `${testAssetDir}/metadata/faces`;
const readTags = async (bytes: Buffer, filename: string) => {
const filepath = join(tempDir, filename);
@@ -185,78 +183,6 @@ describe('/asset', () => {
});
});
describe('faces', () => {
const metadataFaceTests = [
{
description: 'without orientation',
filename: 'portrait.jpg',
},
{
description: 'adjusting face regions to orientation',
filename: 'portrait-orientation-6.jpg',
},
];
// should produce same resulting face region coordinates for any orientation
const expectedFaces = [
{
name: 'Marie Curie',
birthDate: null,
isHidden: false,
faces: [
{
imageHeight: 700,
imageWidth: 840,
boundingBoxX1: 261,
boundingBoxX2: 356,
boundingBoxY1: 146,
boundingBoxY2: 284,
sourceType: 'exif',
},
],
},
{
name: 'Pierre Curie',
birthDate: null,
isHidden: false,
faces: [
{
imageHeight: 700,
imageWidth: 840,
boundingBoxX1: 536,
boundingBoxX2: 618,
boundingBoxY1: 83,
boundingBoxY2: 252,
sourceType: 'exif',
},
],
},
];
it.each(metadataFaceTests)('should get the asset faces from $filename $description', async ({ filename }) => {
const config = await utils.getSystemConfig(admin.accessToken);
config.metadata.faces.import = true;
await updateConfig({ systemConfigDto: config }, { headers: asBearerAuth(admin.accessToken) });
const facesAsset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: await readFile(`${facesAssetDir}/${filename}`),
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: facesAsset.id });
const { status, body } = await request(app)
.get(`/assets/${facesAsset.id}`)
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body.id).toEqual(facesAsset.id);
const sortedPeople = body.people.toSorted((a: any, b: any) => a.name.localeCompare(b.name));
expect(sortedPeople).toMatchObject(expectedFaces);
});
});
it('should work with a shared link', async () => {
const sharedLink = await utils.createSharedLink(user1.accessToken, {
type: SharedLinkType.Individual,
+12 -35
View File
@@ -259,17 +259,6 @@ describe('/search', () => {
assets: [assetHeic],
}),
},
{
should: "should search city ('')",
deferred: () => ({
dto: {
city: '',
visibility: AssetVisibility.Timeline,
includeNull: true,
},
assets: [assetLast],
}),
},
{
should: 'should search city (null)',
deferred: () => ({
@@ -291,18 +280,6 @@ describe('/search', () => {
assets: [assetDensity],
}),
},
{
should: "should search state ('')",
deferred: () => ({
dto: {
state: '',
visibility: AssetVisibility.Timeline,
withExif: true,
includeNull: true,
},
assets: [assetLast, assetNotocactus],
}),
},
{
should: 'should search state (null)',
deferred: () => ({
@@ -324,17 +301,6 @@ describe('/search', () => {
assets: [assetFalcon],
}),
},
{
should: "should search country ('')",
deferred: () => ({
dto: {
country: '',
visibility: AssetVisibility.Timeline,
includeNull: true,
},
assets: [assetLast],
}),
},
{
should: 'should search country (null)',
deferred: () => ({
@@ -441,7 +407,18 @@ describe('/search', () => {
.get('/search/explore')
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body).toEqual([{ fieldName: 'exifInfo.city', items: [] }]);
expect(Array.isArray(body)).toBe(true);
expect(body).toEqual(expect.arrayContaining([{ fieldName: 'exifInfo.city', items: [] }]));
expect(body).toEqual(
expect.arrayContaining([
{
fieldName: 'createdAt',
items: expect.arrayContaining([
expect.objectContaining({ data: expect.objectContaining({ id: assetLast.id }) }),
]),
},
]),
);
});
});
@@ -95,6 +95,7 @@ describe('/server', () => {
major: expect.any(Number),
minor: expect.any(Number),
patch: expect.any(Number),
prerelease: null,
});
});
});
@@ -115,6 +116,7 @@ describe('/server', () => {
oauthAutoLaunch: false,
ocr: false,
passwordLogin: true,
realtimeTranscoding: false,
search: true,
sidecar: true,
trash: true,
@@ -139,6 +141,7 @@ describe('/server', () => {
maintenanceMode: false,
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
minFaces: 3,
});
});
});
@@ -21,18 +21,18 @@ describe('/system-config', () => {
const response1 = await request(app)
.put('/system-config')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ ...config, newVersionCheck: { enabled: false } });
.send({ ...config, newVersionCheck: { enabled: false, channel: 'stable' } });
expect(response1.status).toBe(200);
expect(response1.body).toEqual({ ...config, newVersionCheck: { enabled: false } });
expect(response1.body).toEqual({ ...config, newVersionCheck: { enabled: false, channel: 'stable' } });
const response2 = await request(app)
.put('/system-config')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ ...config, newVersionCheck: { enabled: true } });
.send({ ...config, newVersionCheck: { enabled: true, channel: 'stable' } });
expect(response2.status).toBe(200);
expect(response2.body).toEqual({ ...config, newVersionCheck: { enabled: true } });
expect(response2.body).toEqual({ ...config, newVersionCheck: { enabled: true, channel: 'stable' } });
});
it('should reject an invalid config entry', async () => {
+15
View File
@@ -230,6 +230,21 @@ describe('/users', () => {
const after = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
expect(after).toMatchObject({ download: { includeEmbeddedVideos: true } });
});
it('should update minimum face count to display people', async () => {
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
expect(before).toMatchObject({ people: { minimumFaces: 3 } });
const { status, body } = await request(app)
.put('/users/me/preferences')
.send({ people: { minimumFaces: 2 } })
.set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(body).toMatchObject({ people: { minimumFaces: 2 } });
const after = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
expect(after).toMatchObject({ people: { minimumFaces: 2 } });
});
});
describe('GET /users/:id', () => {
+1 -1
View File
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
import { immichCli } from 'src/utils';
import { describe, expect, it } from 'vitest';
const pkg = JSON.parse(readFileSync('../cli/package.json', 'utf8'));
const pkg = JSON.parse(readFileSync('../packages/cli/package.json', 'utf8'));
describe(`immich --version`, () => {
describe('immich --version', () => {
@@ -28,6 +28,7 @@ export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetRe
ownerId: [],
ratio: [],
thumbhash: [],
createdAt: [],
fileCreatedAt: [],
localOffsetHours: [],
isFavorite: [],
@@ -54,8 +55,8 @@ export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetRe
result.duration.push(asset.duration);
result.projectionType.push(asset.projectionType);
result.livePhotoVideoId.push(asset.livePhotoVideoId);
result.city.push(asset.city);
result.country.push(asset.country);
result.city?.push(asset.city);
result.country?.push(asset.country);
result.visibility.push(asset.visibility);
}
@@ -338,7 +339,6 @@ export function toAssetResponseDto(asset: MockTimelineAsset, owner?: UserRespons
livePhotoVideoId: asset.livePhotoVideoId,
tags: [],
people: [],
unassignedFaces: [],
stack: asset.stack,
isOffline: false,
hasMetadata: true,
+2 -1
View File
@@ -240,7 +240,8 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI
});
});
await context.route('**/api/albums*', async (route, request) => {
if (request.url().endsWith('albums?shared=true') || request.url().endsWith('albums')) {
const url = request.url();
if (url.endsWith('albums?isShared=true') || url.endsWith('albums?isOwned=true') || url.endsWith('albums')) {
return route.fulfill({
status: 200,
contentType: 'application/json',
@@ -66,7 +66,6 @@ export const createMockStackAsset = (ownerId: string): AssetResponseDto => {
livePhotoVideoId: null,
tags: [],
people: [],
unassignedFaces: [],
stack: undefined,
isOffline: false,
hasMetadata: true,
@@ -536,7 +536,7 @@ test.describe('Timeline', () => {
force: false,
ids: [assetToTrash.id],
});
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.locator('#control-bar').getByLabel('Close').click();
await page.getByText('Trash', { exact: true }).click();
await timelineUtils.waitForTimelineLoad(page);
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
@@ -676,7 +676,7 @@ test.describe('Timeline', () => {
ids: [assetToArchive.id],
});
await thumbnailUtils.expectThumbnailIsArchive(page, assetToArchive.id);
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.locator('#control-bar').getByLabel('Close').click();
await page.getByRole('link').getByText('Archive').click();
await timelineUtils.waitForTimelineLoad(page);
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
@@ -823,7 +823,7 @@ test.describe('Timeline', () => {
});
// ensure thumbnail still exists and has favorite icon
await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id);
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.locator('#control-bar').getByLabel('Close').click();
await page.getByRole('link').getByText('Favorites').click();
await timelineUtils.waitForTimelineLoad(page);
await pageUtils.goToAsset(page, assetToFavorite.fileCreatedAt);
+3 -1
View File
@@ -90,7 +90,7 @@ export const tempDir = tmpdir();
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
export const immichCli = (args: string[]) =>
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../cli' }).promise;
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../packages/cli' }).promise;
export const dockerExec = (args: string[]) =>
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', args.join(' ')]);
export const immichAdmin = (args: string[]) => dockerExec([`immich-admin ${args.join(' ')}`]);
@@ -568,6 +568,8 @@ export const utils = {
name: ManualJobName.BackupDatabase,
});
await utils.waitForQueueFinish(accessToken, 'backupDatabase');
return utils.poll(
() => request(app).get('/admin/database-backups').set('Authorization', `Bearer ${accessToken}`),
({ status, body }) => status === 200 && body.backups.length === 1,
+13 -1
View File
@@ -5,8 +5,10 @@
"acknowledge": "Neem kennis",
"action": "Aksie",
"action_common_update": "Werk by",
"action_description": "n Stel van aksies om op die gefiltreerde bates uit te voer",
"actions": "Aksies",
"active": "Aktief",
"active_count": "Aktief: {count}",
"activity": "Aktiwiteite",
"activity_changed": "Aktiwiteit is {enabled, select, true {geaktiveer} other {gedeaktiveer}}",
"add": "Voeg toe",
@@ -14,6 +16,9 @@
"add_a_location": "Voeg n ligging toe",
"add_a_name": "Voeg n naam toe",
"add_a_title": "Voeg n titel toe",
"add_action": "Voeg aksie toe",
"add_action_description": "Klik om n aksie toe te voeg om uit te voer",
"add_assets": "Voeg bates by",
"add_birthday": "Voeg n verjaarsdag toe",
"add_endpoint": "Voeg eindpunt toe",
"add_exclusion_pattern": "Voeg uitsluitingspatroon toe",
@@ -27,9 +32,13 @@
"add_to_album": "Voeg toe tot album",
"add_to_album_bottom_sheet_added": "Tot {album} toegevoeg",
"add_to_album_bottom_sheet_already_exists": "Reeds in {album}",
"add_to_album_bottom_sheet_some_local_assets": "Sommige plaaslike bates kon nie toe gevoeg word tot die album nie",
"add_to_album_toggle": "Wissel seleksie vir {album}",
"add_to_albums": "Voeg toe tot albums",
"add_to_albums_count": "Voeg toe tot albums ({count})",
"add_to_bottom_bar": "Voeg toe",
"add_to_shared_album": "Voeg toe tot gedeelde album",
"add_upload_to_stack": "Voeg oplaai by stapel",
"add_url": "Voeg bronadres toe",
"added_to_archive": "Tot argief toegevoeg",
"added_to_favorites": "Tot gunstelinge toegevoeg",
@@ -46,6 +55,7 @@
"backup_database": "Skep Databasisstortlêer",
"backup_database_enable_description": "Aktiveer databasisstortlêers",
"backup_keep_last_amount": "Aantal vorige stortlêers om te hou",
"backup_onboarding_2_description": "plaaslike kopieë op verskillende toestelle. Dit sluit die hooflêers en n rugsteun van daardie lêers plaaslik in.",
"backup_onboarding_3_description": "totale kopieë van u data, insluitend die oorspronklike lêers. Dit sluit 1 kopie op n ander perseel en 2 lokale kopieë in.",
"backup_onboarding_description": "n <backblaze-link>3-2-1-rugsteunstrategie</backblaze-link> word sterk aanbeveel om u data veilig te hou. Hou kopieë van u fotos/videos sowel as die Immich-databasis vir n volledige rugsteunoplossing.",
"backup_onboarding_footer": "Lees hierdie <link>dokument</link> vir meer inligting oor hoe om n rugsteunkopie van Immich te maak.",
@@ -61,6 +71,7 @@
"confirm_reprocess_all_faces": "Is u seker u wil alle gesigte herverwerk? Dit sal ook genoemde mense skoonmaak.",
"confirm_user_password_reset": "Is u seker u wil {user} se wagwoord terugstel?",
"confirm_user_pin_code_reset": "Is u seker u wil {user} se PIN-kode herstel?",
"copy_config_to_clipboard_description": "Kopieer die huidige stelselkonfigurasie as n JSONobjek na die klipbord",
"create_job": "Skep taak",
"cron_expression": "Cron-uitdrukking",
"cron_expression_description": "Stel die skanderingsinterval in met die cron-formaat. Kyk gerus na bv. <link>Crontab Guru</link> vir meer inligting",
@@ -68,6 +79,8 @@
"disable_login": "Deaktiveer aantekening",
"duplicate_detection_job_description": "Begin masjienleer op items om soortgelyke beelde op te spoor. Maak staat op Slimsoek",
"exclusion_pattern_description": "Met uitsluitingspatrone kan u lêers en vouers ignoreer wanneer u u biblioteek skandeer. Dit is nuttig as u vouers het wat lêers bevat wat u nie wil invoer nie, soos RAW-lêers.",
"export_config_as_json_description": "Laai die huidige stelselkonfigurasie af as n JSONlêer",
"external_libraries_page_description": "Admin eksterne biblioteekbladsy",
"face_detection": "Gesigherkenning",
"face_detection_description": "Identifiseer die gesigte in media d.m.v. masjienleer. Vir videos word slegs die duimnael oorweeg. “Herlaai” (ver)werk al die media weer. “Stel terug” verwyder alle huidige gesigdata. “Onverwerk” plaas items in die ry wat nog nie verwerk is nie. Geïdentifiseerde gesigte sal ná voltooiing van Gesigidentifikasie vir Gesigherkenning in die ry geplaas word om hulle in bestaande of nuwe persone te groepeer.",
"facial_recognition_job_description": "Groepeer gesigte in mense. Die stap is vinniger nadat Gesigherkenning klaar is. “Herstel” (her-)groepeer alle gesigte. “Vermiste” plaas gesigte in ry wat nie n persoon gekoppel het nie.",
@@ -189,7 +202,6 @@
"unsupported_field_type": "Onondersteunde veldtipe",
"unsupported_file_type": "Lêer {file} kan nie opgelaai word nie omdat die lêertipe {type} nie ondersteun word nie.",
"untagged": "Sonder etiket",
"untitled_workflow": "Naamlose werkvloei",
"up_next": "Volgende",
"update_location_action_prompt": "Werk die ligging van {count} gekose items by met:",
"updated_at": "Bygewerk",
+107 -19
View File
@@ -5,10 +5,10 @@
"acknowledge": "أُدرك ذلك",
"action": "إجراء",
"action_common_update": "تحديث",
"action_description": "مجموعة من الفعاليات التي ستنفذ على الأصول التي تم تصفيتها",
"action_description": "مجموعة إجراءات لتنفيذها على المحتويات المصفاة",
"actions": "عمليات",
"active": "نشط",
"active_count": "فعال: {count}",
"active_count": "نشط: {count}",
"activity": "نشاط",
"activity_changed": "النشاط {enabled, select, true {مُفْعل} other {معطّل}}",
"add": "إضافة",
@@ -22,13 +22,12 @@
"add_birthday": "أضف تاريخ الميلاد",
"add_endpoint": "اضف نقطة نهاية",
"add_exclusion_pattern": "إضافة نمط إستثناء",
"add_filter": "اضف تصفية",
"add_filter_description": "اضغط لاضافة شرط تصفية",
"add_location": "إضافة موقع",
"add_more_users": "إضافة مستخدمين آخرين",
"add_partner": "أضف شريكًا",
"add_path": "إضافة مسار",
"add_photos": "إضافة صور",
"add_step": "اضف خطوة",
"add_tag": "اضف علامة",
"add_to": "إضافة إلى…",
"add_to_album": "إضافة إلى ألبوم",
@@ -42,7 +41,6 @@
"add_to_shared_album": "إضافة إلى ألبوم مشارك",
"add_upload_to_stack": "اضف رفع الى حزمة",
"add_url": "إضافة رابط",
"add_workflow_step": "اضف خطوة سير عمل",
"added_to_archive": "أُضيفت للأرشيف",
"added_to_favorites": "أُضيفت للمفضلات",
"added_to_favorites_count": "تم إضافة {count, number} إلى المفضلات",
@@ -61,8 +59,8 @@
"backup_onboarding_1_description": "نسخة خارج الموقع في موقع آخر.",
"backup_onboarding_2_description": "نسخ محلية على أجهزة مختلفة. يشمل ذلك الملفات الرئيسية ونسخة احتياطية محلية منها.",
"backup_onboarding_3_description": "إجمالي نُسخ بياناتك، بما في ذلك الملفات الأصلية. يشمل ذلك نسخةً واحدةً خارج الموقع ونسختين محليتين.",
"backup_onboarding_description": "يُنصح باتباع <backblaze-link>استراتيجية النسخ الاحتياطي 3-2- 1</backblaze-link> لحماية بياناتك. احتفظ بنسخ احتياطية من صورك/فيديوهاتك المحمّلة، بالإضافة إلى قاعدة بيانات Immich، لضمان حل نسخ احتياطي شامل.",
"backup_onboarding_footer": "لمزيد من المعلومات حول النسخ الاحتياطي لـ <link>Immich</link>، يرجى الرجوع إلى <link>الوثائق</link>.",
"backup_onboarding_description": "يُنصح باتباع استراتيجية النسخ الاحتياطي <backblaze-link>3-2-1 backup strategy</backblaze-link> لحماية بياناتك. يجب عليك الاحتفاظ بنسخ من الصور/مقاطع الفيديو المرفوعة بالإضافة إلى قاعدة بيانات Immich للحصول على حل نسخ احتياطي شامل.",
"backup_onboarding_footer": "لمزيد من المعلومات حول النسخ الاحتياطي لـ Immich، يرجى الرجوع إلى <link>الوثائق</link>.",
"backup_onboarding_parts_title": "يتضمن النسخ الاحتياطي 3-2-1 ما يلي:",
"backup_onboarding_title": "النسخ الاحتياطية",
"backup_settings": "إعدادات تفريغ قاعدة البيانات",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "تفعيل إشعارات البريد الإلكتروني",
"notification_settings": "إعدادات الإشعارات",
"notification_settings_description": "إدارة إعدادات الإشعارات، بما في ذلك البريد الإلكتروني",
"oauth_allow_insecure_requests": "السماح بالطلبات الغير الآمنة",
"oauth_allow_insecure_requests_description": "تحذير: هذا يعطل التحقق من صحة شهادة أمن طبقة النقل لطلبات الترخيص المفتوح وقد يعرضك الهجمات الوسطية.",
"oauth_auto_launch": "التشغيل التلقائي",
"oauth_auto_launch_description": "ابدأ تدفق تسجيل الدخول OAuth تلقائيًا عند الانتقال إلى صفحة تسجيل الدخول",
"oauth_auto_register": "التسجيل التلقائي",
@@ -274,9 +274,11 @@
"oauth_button_text": "نص الزر",
"oauth_client_secret_description": "مطلوب للعميل السري، او اذا PKCE(مفتاح الاثبات لتبادل الكود) ليس مدعوم من العميل العام.",
"oauth_enable_description": "تسجيل الدخول باستخدام OAuth",
"oauth_end_session_url_description": "إعادة توجيه المستخدم إلى معرف الموارد الموحد (URI) هذا عند تسجيل الخروج.",
"oauth_mobile_redirect_uri": "عنوان URI لإعادة التوجيه على الهاتف",
"oauth_mobile_redirect_uri_override": "تجاوز عنوان URI لإعادة التوجيه على الهاتف",
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما لا يسمح موفر OAuth بمعرف URI للجوال، مثل ''{callback}''",
"oauth_prompt_description": "مُعامل التوجيه (مثلselect_account, login, consent)",
"oauth_role_claim": "المطالبة بالدور(صلاحيات)",
"oauth_role_claim_description": "منح وصول المسؤول تلقائيًا بناءً على وجود هذا الطلب. قد يكون الطلب إما 'مستخدم' أو 'مسؤول'.",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "تحديث كافة المكتبات",
"registration": "تسجيل المدير",
"registration_description": "بما أنك أول مستخدم في النظام، سيتم تعيينك كمسؤول وستكون مسؤولًا عن المهام الإدارية، وسيتم إنشاء مستخدمين إضافيين بواسطتك.",
"release_channel_release_candidate": "إصدار مرشح",
"release_channel_stable": "مستقر",
"remove_failed_jobs": "ازالة العمليات التي فشلت",
"require_password_change_on_login": "الطلب من المستخدم تغيير كلمة المرور عند تسجيل الدخول الأول",
"reset_settings_to_default": "إعادة ضبط الإعدادات إلى الوضع الافتراضي",
@@ -333,7 +337,7 @@
"storage_template_migration_description": "قم بتطبيق القالب الحالي <link>{template}</link> على المحتويات التي تم رفعها سابقًا",
"storage_template_migration_info": "تغييرات النموذج الخزني ستغير جميع الصيغ الى احرف صغيرة. تغييرات النموذج ستنطبق فقط على المحتويات الجديدة. لتطبيق النموذج على المحتويات التي تم رفعها سابقًا، قم بتشغيل <link>{job}</link>.",
"storage_template_migration_job": "وظيفة تهجير قالب التخزين",
"storage_template_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <template-link>Storage Template</template-link> و <implications-link>implications</implications-link>.",
"storage_template_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <template-link>Storage Template</template-link> و <implications-link>implications</implications-link>",
"storage_template_onboarding_description_v2": "عند التفعيل. هذه الخاصية ستقوم بالترتيب التلقائي للملفات بناء على نموذج معرف من قبل المستخدم. رجاء اطلع على <link>التوثيق</link>.",
"storage_template_path_length": "الحد التقريبي لطول المسار: <b>{length, number}</b>/{limit, number}",
"storage_template_settings": "قالب التخزين",
@@ -397,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "ينطبق فقط على VAAPI وQSV. يضبط عقدة dri المستخدمة لتحويل ترميز الأجهزة.",
"transcoding_preset_preset": "الضبط المُسبق (-preset)",
"transcoding_preset_preset_description": "سرعة الضغط. تؤدي الإعدادات المسبقة الأبطأ إلى إنتاج ملفات أصغر حجمًا، وزيادة الجودة عند استهداف معدل بت معين. يتجاهل VP9 السرعات الأعلى من 'الأسرع'.",
"transcoding_realtime": "تحويل الترميز في الوقت الفعلي [تجريبي]",
"transcoding_realtime_description": "يتيح إجراء تحويل الترميز في الوقت الفعلي أثناء بث الفيديو. كما يمكّن من تبديل الجودة، ولكنه قد يتسبب في زيادة زمن تأخير التشغيل وحدوث تقطيع، اعتماداً على قدرات الخادم.",
"transcoding_realtime_enabled": "تفعيل تحويل الترميز في الوقت الفعلي",
"transcoding_realtime_enabled_description": "في حال تعطيله، سيرفض الخادم بدء جلسات تحويل ترميز جديدة في الوقت الفعلي.",
"transcoding_reference_frames": "الإطارات المرجعية",
"transcoding_reference_frames_description": "عدد الإطارات التي يجب الرجوع إليها عند ضغط إطار معين. تعمل القيم الأعلى على تحسين كفاءة الضغط، ولكنها تبطئ عملية التشفير. 0 يضبط هذه القيمة تلقائيًا.",
"transcoding_required_description": "فقط مقاطع الفيديو ذات التنسيق غير المقبول",
@@ -440,6 +448,8 @@
"user_settings_description": "إدارة إعدادات المستخدم",
"user_successfully_removed": "المستخدم {email} تمت ازالته بنجاح.",
"users_page_description": "صفحة ادارة المستخدمين",
"version_check_channel": "قناة الإصدار",
"version_check_channel_description": "اختر قناة الإصدار التي ترغب في تلقي إعلانات الإصدارات لها",
"version_check_enabled_description": "تفعيل التحقق من الإصدارات الجديدة",
"version_check_implications": "تعتمد ميزة التحقق من الإصدار على التواصل الدوري مع {server}",
"version_check_settings": "التحقق من الإصدار",
@@ -566,7 +576,7 @@
"asset_hashing": "التجزئة…",
"asset_list_group_by_sub_title": "تنظيم بواسطة",
"asset_list_layout_settings_dynamic_layout_title": "تخطيط ديناميكي",
"asset_list_layout_settings_group_automatically": "تلقائي",
"asset_list_layout_settings_group_automatically": "تلقائيا",
"asset_list_layout_settings_group_by": "مجموعة الأصول حسب",
"asset_list_layout_settings_group_by_month_day": "شهر + يوم",
"asset_list_layout_sub_title": "تصميم",
@@ -696,6 +706,7 @@
"birthdate_saved": "تم حفظ تاريخ الميلاد بنجاح",
"birthdate_set_description": "يتم استخدام تاريخ الميلاد لحساب عمر هذا الشخص وقت التقاط الصورة.",
"blurred_background": "خلفية مشوشة",
"browse_templates": "تصفح القوالب",
"bugs_and_feature_requests": "الأخطاء وطلبات الميزات",
"build": "يبني",
"build_image": "بناء الصورة",
@@ -729,6 +740,7 @@
"cannot_update_the_description": "لا يمكن تحديث الوصف",
"cast": "بث",
"cast_description": "ضبط وجهات البث المتوفرة",
"change": "تغيير",
"change_date": "غيّر التاريخ",
"change_description": "تغيير الوصف",
"change_display_order": "تغيير ترتيب العرض",
@@ -757,6 +769,7 @@
"check_corrupt_asset_backup_description": "قم بإجراء هذا الفحص فقط عبر شبكة Wi-Fi وبعد نسخ جميع الأصول احتياطيًا. قد يستغرق الإجراء بضع دقائق.",
"check_logs": "تحقق من السجلات",
"checksum": "مجموع التحقق",
"choose": "اختيار",
"choose_matching_people_to_merge": "اختر الأشخاص المتطابقين لدمجهم",
"city": "المدينة",
"cleanup_confirm_description": "Immich وجد {count} اصول (انشئت قبل {date}) تم خزنها احتياطيا الى الخادم. ازالة النسخ المحلية من هذا الجهاز?",
@@ -774,6 +787,7 @@
"clear": "إخلاء",
"clear_all": "إخلاء الكل",
"clear_all_recent_searches": "مسح جميع عمليات البحث الأخيرة",
"clear_failed_count": "فشل المسح ({count})",
"clear_file_cache": "مسح ذاكرة التخزين المؤقت للملفات",
"clear_message": "إخلاء الرسالة",
"clear_value": "إخلاء القيمة",
@@ -805,6 +819,7 @@
"comments_are_disabled": "التعليقات معطلة",
"common_create_new_album": "إنشاء ألبوم جديد",
"completed": "اكتمل",
"configuration": "اعدادات",
"confirm": "تأكيد",
"confirm_admin_password": "تأكيد كلمة مرور المسؤول",
"confirm_delete_face": "هل أنت متأكد من حذف وجه {name} من الأصول؟",
@@ -819,6 +834,7 @@
"contain": "محتواة",
"context": "السياق",
"continue": "متابعة",
"control_bottom_app_bar_add_tags": "اضافة علامات",
"control_bottom_app_bar_create_new_album": "إنشاء ألبوم جديد",
"control_bottom_app_bar_delete_from_immich": "حذف من Immich",
"control_bottom_app_bar_delete_from_local": "حذف من الجهاز",
@@ -832,6 +848,7 @@
"copy_error": "نسخ الخطأ",
"copy_file_path": "نسخ مسار الملف",
"copy_image": "نسخ الصورة",
"copy_json": "نسخ JSON",
"copy_link": "نسخ الرابط",
"copy_link_to_clipboard": "انسخ الرابط إلى الحافظة",
"copy_password": "نسخ كلمة المرور",
@@ -881,17 +898,16 @@
"cutoff_date_description": "احتفظ بالصور من آخر…",
"cutoff_day": "{count, plural, one {يوم} other {ايام}}",
"cutoff_year": "{count, plural, one {سنة} other {سنوات}}",
"daily_title_text_date": "E ، MMM DD",
"daily_title_text_date_year": "E ، MMM DD ، yyyy",
"dark": "معتم",
"dark_theme": "تبديل المظهر إلى الداكن",
"date": "تاريخ",
"date_after": "التارخ بعد",
"date_and_time": "التاريخ و الوقت",
"date_before": "التاريخ قبل",
"date_format": "E ، Lll D ، Y • H: MM A",
"date_of_birth": "تاريخ الميلاد",
"date_of_birth_saved": "تم حفظ تاريخ الميلاد بنجاح",
"date_range": "نطاق الموعد",
"date_time_original": "تاريخ/وقت الاصلي",
"day": "يوم",
"days": "ايام",
"deduplicate_all": "إلغاء تكرار الكل",
@@ -970,7 +986,10 @@
"downloading_asset_filename": "جاري تنزيل الاصل {filename}",
"downloading_from_icloud": "التنزيل من iCloud",
"downloading_media": "تنزيل الوسائط",
"drag_to_reorder": "اسحب لإعادة الترتيب",
"drop_files_to_upload": "قم بإسقاط الملفات في أي مكان لرفعها",
"duplicate": "تكرار",
"duplicate_workflow": "تكرار سير العمل",
"duplicates": "التكرارات",
"duplicates_description": "قم بحل كل مجموعة من خلال الإشارة إلى التكرارات، إن وجدت.",
"duration": "المدة",
@@ -1072,6 +1091,7 @@
"failed_to_remove_product_key": "تعذر إزالة مفتاح المنتج",
"failed_to_reset_pin_code": "فشل اعادة تعيين رمز الPIN",
"failed_to_stack_assets": "فشل في تكديس المحتويات",
"failed_to_tag_assets": "فشل في وضع علامات على الأصول",
"failed_to_unstack_assets": "فشل في فصل المحتويات",
"failed_to_update_notification_status": "فشل في تحديث حالة الإشعار",
"incorrect_email_or_password": "بريد أو كلمة مرور غير صحيحة",
@@ -1191,11 +1211,13 @@
"export_as_json": "تصدير كـ JSON",
"export_database": "تصدير قاعدة البيانات",
"export_database_description": "تصدير قاعدة البيانات من نوع SQLite",
"exposure_time": "وقت التعرض",
"extension": "الإمتداد",
"external": "خارجي",
"external_libraries": "المكتبات الخارجية",
"external_network": "شبكة خارجية",
"external_network_sheet_info": "عندما لا يتواجد على شبكة Wi-Fi المفضلة، فإنه سيتصل بالخادم من خلال أول عناوين URL أدناه التي يمكنه الوصول إليها، بدءًا من الأعلى إلى الأسفل",
"f_number": "الفتحة البؤرية",
"face_unassigned": "غير معين",
"failed": "فشل",
"failed_count": "فشل: {count}",
@@ -1213,7 +1235,6 @@
"features_setting_description": "إدارة ميزات التطبيق",
"file_name_or_extension": "اسم الملف أو امتداده",
"file_name_text": "أسم الملف",
"file_name_with_value": "اسم الملف: {file_name}",
"file_size": "حجم الملف",
"filename": "اسم الملف",
"filetype": "نوع الملف",
@@ -1226,6 +1247,7 @@
"find_them_fast": "يمكنك العثور عليها بسرعة بالاسم من خلال البحث",
"first": "الاول",
"fix_incorrect_match": "إصلاح المطابقة غير الصحيحة",
"focal_length": "البعد البؤري",
"folder": "مجلد",
"folder_not_found": "لم يتم العثور على المجلد",
"folders": "المجلدات",
@@ -1236,6 +1258,7 @@
"free_up_space_description": "نقل الصور والفديوات التي تم خزنها احتياطياالى سلة المهملات الخاصه بجهازك لتحرير المساحة. نسخك على اىخادم ستبقى بأمان.",
"free_up_space_settings_subtitle": "تحرير خزن الجهاز",
"full_path": "مسار كامل:{path}",
"full_path_or_folder": "المسار الكامل او المجلد",
"gcast_enabled": "كوكل كاست",
"gcast_enabled_description": "تقوم هذه الميزة بتحميل الموارد الخارجية من Google حتى تعمل.",
"general": "عام",
@@ -1345,6 +1368,7 @@
"ios_debug_info_no_sync_yet": "لم يتم تشغيل أي مهمة مزامنة في الخلفية حتى الآن",
"ios_debug_info_processes_queued": "{count, plural, one {{count} عملية خلفية ادخلتةفي طابور} other {{count} عمليات خلفية ادخلت في طابور}}",
"ios_debug_info_processing_ran_at": "المعالجة جرت في {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# عنصر} other {# عناصر}}",
"jobs": "الوظائف",
"json_editor": "محرر JSON",
@@ -1392,11 +1416,13 @@
"light_theme": "التبديل إلى المظهر الفاتح",
"like": "اعجاب",
"like_deleted": "تم حذف الإعجاب",
"link": "رابط",
"link_motion_video": "رابط فيديو الحركة",
"link_to_docs": "لمزيد من المعلومات، يُرجى الرجوع إلى <link>الوثائق</link>.",
"link_to_oauth": "الربط مع OAuth",
"linked_oauth_account": "حساب مرتبط بـ OAuth",
"list": "قائمة",
"live": "حي",
"loading": "تحميل",
"loading_search_results_failed": "فشل تحميل نتائج البحث",
"local": "محلّي",
@@ -1518,6 +1544,38 @@
"marked_all_as_read": "تم تحديد الكل كمقروء",
"matches": "تطابقات",
"matching_assets": "‏الاصول المطابقة",
"media_chrome": {
"auto": "تلقائي",
"captions": "التعليقات التوضيحية",
"captions_off": "اطفاء",
"closed_captions": "الترجمة المرئية المغلقة",
"decode_error": "فشل فك التشفير",
"disable_captions": "تعطيل الترجمة",
"enable_captions": "تفعيل الترجمة",
"enter_fullscreen_mode": "ادخل إلى وضع ملء الشاشة",
"exit_fullscreen_mode": "اخرج من وضع ملء الشاشة",
"loop": "حلقة",
"media_error_description": "خطأ في الوسائط تسبب في ايقاف التشغيل. قد تكون الوسائط تالفة او ان متصفحك لا يدعم الصيغة.",
"media_loading": "تحميل الوسائط",
"mute": "كتم",
"network_error": "خطأ في الشبكة",
"network_error_description": "خطأ في الشبكة تسبب في فشل تنزيل الوسائط.",
"not_supported_error": "المصدر غير مدعوم",
"playback_rate": "معدل التشغيل",
"playback_rate_current": "معدل التشغيل الحالي",
"playback_rate_value": "معدل التشغيل {playbackRate}",
"playback_time": "وقت التشغيل",
"quality": "جودة",
"second": "ثانية",
"seconds": "ثواني",
"time_value_of_total_time": "{currentTime} من {totalTime}",
"time_value_remaining": "{time} متبقي",
"unmute": "الغاء الكتم",
"unsupported_error_description": "حدث خطأ غير مدعوم. حدث فشل في الخادم او الشبكة, او المتصفح الخاص بك لا يدعم هذه الصيغة.",
"video_not_loaded_unknown_time": "الفيديو غير محمل, الوقت غير معلوم.",
"video_player": "مشغل الفيديو",
"volume": "حجم"
},
"media_type": "نوع الوسائط",
"memories": "الذكريات",
"memories_all_caught_up": "كل شيء محدث",
@@ -1543,9 +1601,10 @@
"mobile_app": "تطبيق الجوال",
"mobile_app_download_onboarding_note": "قم بتنزيل التطبيق المصاحب للهاتف المحمول باستخدام الخيارات التالية",
"model": "نموذج",
"modify_date": "تغيير التاريخ",
"month": "شهر",
"monthly_title_text_date_format": "ط ط ط",
"more": "المزيد",
"motion": "حركة",
"move": "تحريك",
"move_down": "انزل الى الاسفل",
"move_off_locked_folder": "تحريك خارج المجلد المقفل",
@@ -1562,6 +1621,8 @@
"multiselect_grid_edit_gps_err_read_only": "لا يمكن تعديل موقع الأصول (المواد) للقراءة فقط، سوف يتخطى",
"mute_memories": "كتم الذكريات",
"my_albums": "ألبوماتي",
"my_immich_description": "نسخ الصفحة الحالية كرابط Immich الخاص بي",
"my_immich_title": "رابط Immich الخاص بي",
"name": "الاسم",
"name_or_nickname": "الاسم أو اللقب",
"name_required": "الاسم مطلوب",
@@ -1589,7 +1650,6 @@
"next": "التالي",
"next_memory": "الذكرى التالية",
"no": "لا",
"no_actions_added": "لم تتم إضافة إجراءات حتى الان",
"no_albums_found": "لم يتم ايجاد البومات",
"no_albums_message": "قم بإنشاء ألبوم لتنظيم الصور ومقاطع الفيديو الخاصة بك",
"no_albums_with_name_yet": "يبدو أنه ليس لديك أي ألبومات بهذا الاسم حتى الآن.",
@@ -1606,7 +1666,6 @@
"no_exif_info_available": "لا تتوفر معلومات exif",
"no_explore_results_message": "قم برفع المزيد من الصور لاستكشاف مجموعتك.",
"no_favorites_message": "أضف المفضلة للعثور بسرعة على أفضل الصور ومقاطع الفيديو",
"no_filters_added": "لم تتم إضافة أي فلتر بعد",
"no_libraries_message": "إنشاء مكتبة خارجية لعرض الصور ومقاطع الفيديو الخاصة بك",
"no_local_assets_found": "لم يتم العثور على أي اصول محلية تتطابق مع قيمة التحقق هذه",
"no_location_set": "لم يتم تحديد موقع",
@@ -1619,6 +1678,7 @@
"no_results": "لا يوجد نتائج",
"no_results_description": "جرب كلمة رئيسية مرادفة أو أكثر عمومية",
"no_shared_albums_message": "قم بإنشاء ألبوم لمشاركة الصور ومقاطع الفيديو مع الأشخاص في شبكتك",
"no_steps": "لم يتم اضافة خطوات بعد",
"no_uploads_in_progress": "لا يوجد اي ملفات قيد الرفع",
"none": "لا يوجد",
"not_allowed": "غير مسموح",
@@ -1664,6 +1724,7 @@
"organize_into_albums": "ترتيب في ألبومات",
"organize_into_albums_description": "أضف الصور الموجودة إلى الألبومات باستخدام إعدادات النسخ المتزامن الحالية",
"organize_your_library": "تنظيم مكتبتك",
"orientation": "اتجاه",
"original": "أصلي",
"other": "أخرى",
"other_devices": "أجهزة أخرى",
@@ -1755,6 +1816,8 @@
"play_original_video_setting_description": "تفضيل تشغيل مقاطع الفيديو الأصلية بدلاً من مقاطع الفيديو المحولة. إذا لم يكن الملف الأصلي متوافقًا، فقد لا يتم تشغيله بشكل صحيح.",
"play_transcoded_video": "تشغيل الفيديو المُعاد ترميزه",
"please_auth_to_access": "الرجاء القيام بالمصادقة للوصول",
"plugin_method_filter_type": "تصفية",
"plugin_method_filter_type_description": "هذه الوسيلة تستطيع تصفية الاحداث و تمنع تشغيل الخطوات التالية شرطيا",
"port": "المنفذ",
"preferences_settings_subtitle": "ادارة تفضيلات التطبيق",
"preferences_settings_title": "التفضيلات",
@@ -1776,6 +1839,7 @@
"profile_drawer_readonly_mode": "تم تفعيل وضع القراءة فقط. اضغط مطولا على رمز صورة المستخدم للخروج.",
"profile_image_of_user": "صورة الملف الشخصي لـ {user}",
"profile_picture_set": "مجموعة الصور الشخصية.",
"projection_type": "نوع العرض",
"public_album": "الألبوم العام",
"public_share": "مشاركة عامة",
"purchase_account_info": "داعم",
@@ -1853,6 +1917,7 @@
"remove_assets_title": "هل تريد إزالة المحتويات؟",
"remove_custom_date_range": "إزالة النطاق الزمني المخصص",
"remove_deleted_assets": "إزالة الملفات الغير متصلة",
"remove_filter": "ازالة التصفية",
"remove_from_album": "إزالة من الألبوم",
"remove_from_album_action_prompt": "تم ازالة {count} من الالبوم",
"remove_from_favorites": "إزالة من المفضلة",
@@ -1926,6 +1991,8 @@
"scan_settings": "إعدادات الفحص",
"scanning": "جاري البحث",
"scanning_for_album": "جارٍ الفحص عن ألبوم...",
"screencast_mode_description": "إظهار مؤشرات أحداث لوحة المفاتيح والماوس على الشاشة",
"screencast_mode_title": "تبديل وضع تسجيل الشاشة",
"search": "البحث",
"search_albums": "البحث في الألبومات",
"search_by_context": "البحث حسب السياق",
@@ -1933,6 +2000,8 @@
"search_by_description_example": "يوم المشي لمسافات طويلة في سابا",
"search_by_filename": "البحث بإسم الملف أو نوعه",
"search_by_filename_example": "كـ IMG_1234.JPG أو PNG",
"search_by_full_path": "بحث بالمسار الكامل او المجلد",
"search_by_full_path_example": "/احمد/مشاريع/طباعة_ثلاثية_الابعاد/2026-07-01 - يمكنك البحث عن مشاريع, طباعة_ثلاثية_الابعاد, 2026 الخ.",
"search_by_ocr": "البحث عن طريق التعرف البصري على الحروف",
"search_by_ocr_example": "لاتيه",
"search_camera_lens_model": "بحث نموذج العدسة...",
@@ -2140,7 +2209,9 @@
"show_in_timeline": "إظهار في المخطط الزمني",
"show_in_timeline_setting_description": "إظهار الصور ومقاطع الفيديو من هذا المستخدم في المخطط الزمني الخاص بك",
"show_keyboard_shortcuts": "إظهار اختصارات لوحة المفاتيح",
"show_less": "اضهر اقل",
"show_metadata": "إظهار البيانات الوصفية",
"show_more_fields": "{count, plural, one {اضهر #حقل اكثر} other {اضهر # حقول اكثر}}",
"show_or_hide_info": "إظهار أو إخفاء المعلومات",
"show_password": "إظهار كلمة المرور",
"show_person_options": "إظهار خيارات الشخص",
@@ -2148,6 +2219,7 @@
"show_schema": "أظهر المخطط",
"show_search_options": "إظهار خيارات البحث",
"show_shared_links": "عرض الروابط المشتركة",
"show_slideshow_metadata_overlay": "عرض معلومات الصورة",
"show_slideshow_transition": "إظهار انتقال عرض الشرائح",
"show_supporter_badge": "شارة المؤيد",
"show_supporter_badge_description": "إظهار شارة المؤيد",
@@ -2163,9 +2235,13 @@
"skip_to_folders": "تخطي إلى المجلدات",
"skip_to_tags": "تخطي إلى العلامات",
"slideshow": "عرض الشرائح",
"slideshow_metadata_overlay_mode": "محتوى التراكب",
"slideshow_metadata_overlay_mode_description_only": "وصف فقط",
"slideshow_metadata_overlay_mode_full": "كامل",
"slideshow_repeat": "اعادة عرض الشرائح",
"slideshow_repeat_description": "العودة إلى البداية عند انتهاء عرض الشرائح",
"slideshow_settings": "إعدادات عرض الشرائح",
"smart_album": "ألبوم ذكي",
"sort_albums_by": "رتب الألبومات حسب...",
"sort_created": "تاريخ الإنشاء",
"sort_items": "عدد العناصر",
@@ -2188,6 +2264,11 @@
"start_date_before_end_date": "يجب أن يكون تاريخ بدء الفترة قبل تاريخ نهايتها",
"state": "الولاية",
"status": "الحالة",
"step_delete": "حذف خطوة",
"step_delete_confirm": "هل انت متاكد من انك تريد حذف هذه الخطوة؟",
"step_details": "تفاصيل الخطوة",
"steps": "خطوات",
"steps_count": "{count, plural, one {# خطوة} other {# خطوات}}",
"stop_casting": "ايقاف البث",
"stop_motion_photo": "إيقاف حركة الصورة",
"stop_photo_sharing": "توقف عن مشاركة صورك؟",
@@ -2214,6 +2295,8 @@
"sync_status": "حالة النسخ المتزامن",
"sync_status_subtitle": "عرض وإدارة نظام النسخ المتزامن",
"sync_upload_album_setting_subtitle": "انشئ و ارفع صورك و فديوهاتك الالبومات المختارة في Immich",
"system_theme": "سمة النظام",
"system_theme_command_description": "استعمل سمة النظام ({value})",
"tag": "العلامة",
"tag_assets": "أصول العلامة",
"tag_created": "تم إنشاء العلامة: {tag}",
@@ -2279,7 +2362,7 @@
"trash_page_title": "سلة المهملات ({count})",
"trashed_items_will_be_permanently_deleted_after": "سيتم حذفُ العناصر المحذوفة نِهائيًا بعد {days, plural, one {# يوم} other {# أيام }}.",
"trigger": "مفعِل",
"trigger_asset_uploaded": "تم رفع الاصل",
"trigger_asset_uploaded": "رفع الاصل",
"trigger_asset_uploaded_description": "يتم تفعيله عند تحميل أصل جديد",
"trigger_description": "حدث يبدأ سير العمل",
"trigger_person_recognized": "تم التعرف على شخص",
@@ -2319,7 +2402,6 @@
"unsupported_field_type": "نوع حقل غير مدعوم",
"unsupported_file_type": "لا يمكن رفع الملف {file} لأن نوع الملف {type} غير مدعوم.",
"untagged": "غير مُعَلَّم",
"untitled_workflow": "خطة سير عمل بدون عنوان",
"up_next": "التالي",
"update_location_action_prompt": "تحديث موقع {count} عناصر محددة على النحو التالي:",
"updated_at": "تم التحديث",
@@ -2348,6 +2430,7 @@
"use_browser_locale_description": "تنسيق التواريخ والأوقات والأرقام وفقًا لإعدادات اللغة في متصفحك",
"use_current_connection": "استخدم الاتصال الحالي",
"use_custom_date_range": "استخدم النطاق الزمني المخصص بدلاً من ذلك",
"use_template": "استخدام القالب",
"user": "مستخدم",
"user_has_been_deleted": "هذا المستخدم تم حذفه.",
"user_id": "معرف المستخدم",
@@ -2377,6 +2460,7 @@
"video": "فيديو",
"video_hover_setting": "تشغيل الصورة المصغرة للفيديو عند التمرير",
"video_hover_setting_description": "تشغيل الصورة المصغرة للفيديو عند تحريك الماوس فوق العنصر. حتى عند التعطيل، يمكن بدء التشغيل عن طريق التمرير فوق رمز التشغيل.",
"video_quality": "جودة الفيديو",
"videos": "فيديوهات",
"videos_count": "{count, plural, one {# مقطع فيديو } other {# مقاطع الفيديو }}",
"videos_only": "الفديوات فقط",
@@ -2409,8 +2493,10 @@
"week": "أسبوع",
"welcome": "مرحباً",
"welcome_to_immich": "مرحباً بك في Immich",
"when": "عندما",
"width": "عُرض",
"wifi_name": "اسم شبكة Wi-Fi",
"workflow": "سير العمل",
"workflow_delete_prompt": "متأكد من حذف سير العمل هذا؟",
"workflow_deleted": "تم حذف سير العمل",
"workflow_description": "وصف سير العمل",
@@ -2420,11 +2506,13 @@
"workflow_name": "اسم سير العمل",
"workflow_navigation_prompt": "متاكد من المغادرة بدون حفظ التغييرات؟",
"workflow_summary": "ملخص سير العمل",
"workflow_templates": "قوالب سير العمل",
"workflow_update_success": "تم تحديث سير العمل بنجاح",
"workflow_updated": "تم تحديث سير العمل",
"workflows": "سير العمل",
"workflows": "سير العمليات",
"workflows_help_text": "تعمل سير العمل على أتمتة الإجراءات على أصولك بناءً على المفعلات والفلاتر",
"wrong_pin_code": "رمز التعريف الشخصي خاطئ",
"x_of_total": "{x}\\{total}",
"year": "سنة",
"years_ago": "{years, plural, one {# سنة} other {# سنوات}} مضت",
"yes": "نعم",
+24 -2
View File
@@ -5,6 +5,7 @@
"acknowledge": "Təsdiq et",
"action": "Əməliyyat",
"action_common_update": "Yenilə",
"action_description": "Filtrlənmiş aktivliklər üzərində yerinə yetiriləcək əməliyyatlar toplusu",
"actions": "Əməliyyatlar",
"active": "Aktiv",
"active_count": "Aktiv: {count}",
@@ -15,6 +16,9 @@
"add_a_location": "Məkan əlavə et",
"add_a_name": "Ad əlavə et",
"add_a_title": "Başlıq əlavə et",
"add_action": "Yeni əməliyyat əlavə et",
"add_action_description": "Əməliyyat əlavə etmək üçün klikləyin",
"add_assets": "Aktivlik əlavə et",
"add_birthday": "Doğum günü əlavə et",
"add_endpoint": "Son nöqtə əlavə et",
"add_exclusion_pattern": "Çıxarma nümunəsi əlavə et",
@@ -46,7 +50,7 @@
"authentication_settings": "Səlahiyyətləndirmə parametrləri",
"authentication_settings_description": "Şifrə, OAuth və digər səlahiyyətləndirmə parametrləri",
"authentication_settings_disable_all": "Bütün giriş etmə metodlarını söndürmək istədiyinizdən əminsinizmi? Giriş etmə funksiyası tamamilə söndürüləcəkdir.",
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link> -ni istifadə edin.",
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link>-ni istifadə edin.",
"background_task_job": "Arxa plan tapşırıqları",
"backup_database": "Verilənlər bazasının dump-ını yaradın",
"backup_database_enable_description": "Verilənlər bazasının artıq nüsxələrini aktiv et",
@@ -54,6 +58,7 @@
"backup_onboarding_1_description": "buludda və ya başqa fiziki yerdə saytdan kənar surət.",
"backup_onboarding_2_description": "müxtəlif cihazlarda yerli nüsxələr. Bura əsas fayllar və həmin faylların ehtiyat lokal nüsxəsi daxildir.",
"backup_onboarding_3_description": "orijinal fayllar da daxil olmaqla məlumatlarınızın ümumi surətləri. Buraya 1 kənar nüsxə və 2 lokal nüsxə daxildir.",
"backup_onboarding_description": "<backblaze-link>3-2-1 yedəkləmə strategiyası</backblaze-link> məlumatlarınızı qorumaq üçün tövsiyə olunur. Yüklədiyiniz şəkil və videoların, həmçinin Immich verilənlər bazasının surətlərini saxlamalısınız ki, hərtərəfli yedəkləmə həlli əldə edəsiniz.",
"backup_onboarding_footer": "Immich-in ehtiyat nüsxəsini çıxarmaq haqqında ətraflı məlumat üçün <link>sənədlərə</link> müraciət edin.",
"backup_onboarding_parts_title": "3-2-1 ehtiyat nüsxəsinə aşağıdakılar daxildir:",
"backup_onboarding_title": "Ehtiyat surətlər",
@@ -61,14 +66,31 @@
"backup_settings_description": "Verilənlər bazasının ehtiyat nüsxə parametrlərini idarə et",
"cleared_jobs": "{job} üçün tapşırıqlar silindi",
"config_set_by_file": "Konfiqurasiya hal-hazırda konfiqurasiya faylı ilə təyin olunub",
"confirm_delete_library": "{library} kitabxanasını silmək istədiyinizdən əminmisiniz?",
"confirm_delete_library": "{library} kitabxanasını silmək istədiyinizə əminmisiniz?",
"confirm_email_below": "Təsdiqləmək üçün aşağıya {email} yazın",
"confirm_reprocess_all_faces": "Bütün üzləri yenidən emal etmək istədiyinizə əminsiniz? Bu, həmçinin adlandırılmış şəxsləri siləcək.",
"confirm_user_password_reset": "{user} adlı istifadəçinin şifrəsini sıfırlamaq istədiyinizdən əminmisiniz?",
"confirm_user_pin_code_reset": "{user} istifadəçisinin PIN kodunu sıfırlamaq istədiyinizə əminsiniz?",
"copy_config_to_clipboard_description": "Cari sistem konfiqurasiyasını JSON obyekt kimi mübadilə buferinə kopyalayın",
"create_job": "İş yarat",
"cron_expression": "Cron ifadəsi",
"cron_expression_description": "Cron formatından istifadə edərək skan intervalını təyin edin. Ətraflı məlumat üçün nümunələrə baxa bilərsiniz. <link>Crontab Guru</link>",
"cron_expression_presets": "Cron ifadəsi ön ayarları",
"disable_login": "Giriş etməni söndür",
"duplicate_detection_job_description": "Bənzər şəkilləri tapmaq üçün maşın öyrənməsini işə salın. Bu prosses Smart Search funksiyasına əsaslanır",
"exclusion_pattern_description": "İstisna nümunələri kitabxananızı skan edərkən faylları və qovluqları nəzərə almamağa imkan verir. Bu, RAW faylları kimi idxal etmək istəmədiyiniz faylları olan qovluqlarınız olduqda faydalıdır.",
"export_config_as_json_description": "Cari sistem konfiqurasiyasını JSON faylı kimi endirin",
"external_libraries_page_description": "Admin xarici kitabxana səhifəsi",
"face_detection": "Üz tanıma",
"failed_job_command": "{command} əmri {job} işi üçün uğursuz oldu",
"force_delete_user_warning": "XƏBƏRDARLIQ: Bu əməliyyat istifadəçi və bütün məlumatları siləcəkdir. Bu prossesi və silinən faylları geri qaytarmaq olmaz.",
"image_format": "Format",
"image_format_description": "WebP, JPEG faylına görə daha kiçik həcmə sahibdir, lakin onu kodlaşdırmaq daha çox vaxt alır.",
"image_fullsize_description": "Böyüdülmüş halda istifadə edilən, metadata-sı silinmiş tam ölçülü şəkil",
"image_fullsize_enabled": "Tam ölçülü şəkil generasiyasını aktiv et",
"image_fullsize_enabled_description": "Veb üçün uyğun olmayan formatlar üçün tam ölçülü şəkil yaradın. “Daxili önizləməyə üstünlük ver” aktiv olduqda, daxili önizləmələr çevrilmədən birbaşa istifadə olunur. JPEG kimi veb üçün uyğun formatlara təsir etmir.",
"image_fullsize_quality_description": "Tam ölçülü şəkil keyfiyyəti (1-100). Daha yüksək dəyər daha yaxşı keyfiyyət verir, lakin daha böyük ölçülü fayl yaradır.",
"image_fullsize_title": "Tam ölçülü şəkil tənzimləmələri",
"image_preview_title": "Önizləmə parametrləri",
"image_quality": "Keyfiyyət",
"image_resolution": "Çözümlülük",
+1942 -34
View File
File diff suppressed because it is too large Load Diff
+102 -12
View File
@@ -22,13 +22,12 @@
"add_birthday": "Добави дата на раждане",
"add_endpoint": "Добави крайна точка",
"add_exclusion_pattern": "Добави модел за изключване",
"add_filter": "Добави филтър",
"add_filter_description": "Натиснете за да добавите условие за филтър",
"add_location": "Дoбави местоположение",
"add_more_users": "Добави още потребители",
"add_partner": "Добави партньор",
"add_path": "Добави път",
"add_photos": "Добави снимки",
"add_step": "Добави стъпка",
"add_tag": "Добави маркер",
"add_to": "Добави към…",
"add_to_album": "Добави към албум",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Добави към споделен албум",
"add_upload_to_stack": "Добави качените в група",
"add_url": "Добави URL",
"add_workflow_step": "Добави стъпка от работния процес",
"added_to_archive": "Добавено към архива",
"added_to_favorites": "Добавени към любимите ви",
"added_to_favorites_count": "Добавени {count, number} към любими",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "Включване на имейл известията",
"notification_settings": "Настройки на известията",
"notification_settings_description": "Управление на настройките за известия, вкл. имейл",
"oauth_allow_insecure_requests": "Разрешаване на несигурни заявки",
"oauth_allow_insecure_requests_description": "ПРЕДУПРЕЖДЕНИЕ: Това изключва проверката за валидност на TLS сертификата при OAuth заявки и отваря възможност за атака от типа \"човек по средата\".",
"oauth_auto_launch": "Автоматично стартиране",
"oauth_auto_launch_description": "Автоматично стартиране на вход чрез OAuth, когато се отвори страницата за вход",
"oauth_auto_register": "Автоматична регистрация",
@@ -274,9 +274,11 @@
"oauth_button_text": "Текст на бутона",
"oauth_client_secret_description": "Задължително за поверителен клиент или когато не се поддържа PKCE (Proof Key for Code Exchange) за публичен клиент.",
"oauth_enable_description": "Влизане с OAuth",
"oauth_end_session_url_description": "Пренасочване на потребителя към този URI адрес, когато излезе от системата.",
"oauth_mobile_redirect_uri": "URI за мобилно пренасочване",
"oauth_mobile_redirect_uri_override": "URI пренасочване за мобилни устройства",
"oauth_mobile_redirect_uri_override_description": "Разреши когато доставчика за OAuth удостоверяване не позволява за мобилни URI идентификатори, като ''{callback}''",
"oauth_prompt_description": "Параметър за подкана (напр. select_account, login, consent)",
"oauth_role_claim": "Потвърждение на роля",
"oauth_role_claim_description": "Автоматично предоставяне на административни права при наличие на това потвържение. Потвърждението може да има стойност 'user' или 'admin'.",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "Опресняване на всички библиотеки",
"registration": "Администраторска регистрация",
"registration_description": "Тъй като сте първият потребител в системата, ще бъдете назначен като администратор и ще отговаряте за административните задачи, а допълнителните потребители ще бъдат създадени от вас.",
"release_channel_release_candidate": "Предварителна версия",
"release_channel_stable": "Стабилна версия",
"remove_failed_jobs": "Премахване на неуспешни задачи",
"require_password_change_on_login": "Изискване за промяна паролата при първо влизане",
"reset_settings_to_default": "Възстановяване на настройките по подразбиране",
@@ -397,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "Прилага се само за VAAPI и QSV. Задава dri възела, използван за хардуерно транскодиране.",
"transcoding_preset_preset": "Предварително зададени(-preset)",
"transcoding_preset_preset_description": "Скорост на компресия. По-бавните предварително зададени настройки създават по-малки файлове и повишават качеството при насочване към определен битрейт. VP9 игнорира скорости над „по-бързо“.",
"transcoding_realtime": "Транскодиране в реално време [ЕКСПЕРИМЕНТАЛНО]",
"transcoding_realtime_description": "Позволява транскодиране на видео по време на възпроизвеждане. Разрешава превключване на качеството, но може да предизвика по-голямо забавяне или накъсване на възпроизвеждането според възможностите на сървъра.",
"transcoding_realtime_enabled": "Включи транскодиране в реално време",
"transcoding_realtime_enabled_description": "Ако е изключено, сървъра ще отказва нова сесия за транскодиране в реално време.",
"transcoding_reference_frames": "Референтни кадри",
"transcoding_reference_frames_description": "Броят кадри за препратка при компресиране на даден кадър. По-високите стойности подобряват ефективността на компресията, но забавят кодирането. 0 задава тази стойност автоматично.",
"transcoding_required_description": "Само видеа, които не са в приет формат",
@@ -440,6 +448,8 @@
"user_settings_description": "Управление на потребителските настройки",
"user_successfully_removed": "Потребител {email} е успешно премахнат.",
"users_page_description": "Страница за администриране на потребители",
"version_check_channel": "Канал за обновявания",
"version_check_channel_description": "Посочете канал, по който да получавате известия за нова версия",
"version_check_enabled_description": "Активирай проверка на версията",
"version_check_implications": "Функцията за проверка на версията разчита на периодична комуникация с {server}",
"version_check_settings": "Проверка на версията",
@@ -696,6 +706,7 @@
"birthdate_saved": "Датата на раждане е запазена успешно",
"birthdate_set_description": "Датата на раждане се използва за изчисляване на възрастта на този човек към момента на снимката.",
"blurred_background": "Замъглен заден фон",
"browse_templates": "Разглеждане на шаблони",
"bugs_and_feature_requests": "Бъгове и заявки за функции",
"build": "Версия",
"build_image": "Docker версия",
@@ -729,6 +740,7 @@
"cannot_update_the_description": "Описанието не може да бъде обновено",
"cast": "Поточно предаване",
"cast_description": "Настройка на наличните цели за предаване",
"change": "Промени",
"change_date": "Промени датата",
"change_description": "Промени описанието",
"change_display_order": "Промени реда на показване",
@@ -757,6 +769,7 @@
"check_corrupt_asset_backup_description": "Изпълни тази проверка само при Wi-Fi и след архивиране на всички обекти. Процедурата може да продължи няколко минути.",
"check_logs": "Провери логовете",
"checksum": "Контролна сума",
"choose": "Избeри",
"choose_matching_people_to_merge": "Изберете подходящи хора за сливане",
"city": "Град",
"cleanup_confirm_description": "Immich намери {count} обекта (създадени преди {date}), които са архивирани на сървъра. Да се премахнат ли локалните копия от това устройство?",
@@ -774,6 +787,7 @@
"clear": "Изчисти",
"clear_all": "Изчисти всичко",
"clear_all_recent_searches": "Изчистете всички скорошни търсения",
"clear_failed_count": "Неуспешно изчистване на ({count})",
"clear_file_cache": "Изчистване на кеша на файловете",
"clear_message": "Изчисти съобщението",
"clear_value": "Изчисти стойността",
@@ -805,6 +819,7 @@
"comments_are_disabled": "Коментарите са деактивирани",
"common_create_new_album": "Създай нов албум",
"completed": "Завършено",
"configuration": "Конфигурация",
"confirm": "Потвърди",
"confirm_admin_password": "Потвърждаване на паролата на администратора",
"confirm_delete_face": "Сигурни ли сте, че искате да изтриете лицето на {name} от актива?",
@@ -819,6 +834,7 @@
"contain": "В рамките на",
"context": "Контекст",
"continue": "Продължи",
"control_bottom_app_bar_add_tags": "Добавяне на етикети",
"control_bottom_app_bar_create_new_album": "Създай нов албум",
"control_bottom_app_bar_delete_from_immich": "Премахни от Immich съръра",
"control_bottom_app_bar_delete_from_local": "Премахни от устройството",
@@ -832,6 +848,7 @@
"copy_error": "Грешка при копирането",
"copy_file_path": "Копирай пътя на файла",
"copy_image": "Копиране на изображението",
"copy_json": "Копирай JSON",
"copy_link": "Копиране на линк",
"copy_link_to_clipboard": "Копиране на връзката в клипборда",
"copy_password": "Копиране на парола",
@@ -881,17 +898,16 @@
"cutoff_date_description": "Запазване на снимки от последните…",
"cutoff_day": "{count, plural, one {ден} other {дни}}",
"cutoff_year": "{count, plural, one {година} other {години}}",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM yyyy",
"dark": "Тъмен",
"dark_theme": "Премини към тъмна тема",
"date": "Дата",
"date_after": "Дата след",
"date_and_time": "Дата и час",
"date_before": "Дата преди",
"date_format": "E, d LLL y • h:mm a",
"date_of_birth": "Дата на раждане",
"date_of_birth_saved": "Дата на раждане е записана успешно",
"date_range": "Период от време",
"date_time_original": "Дата/Час на оригинала",
"day": "Ден",
"days": "Дни",
"deduplicate_all": "Дедупликиране на всички",
@@ -970,7 +986,10 @@
"downloading_asset_filename": "Изтегляне на файл {filename}",
"downloading_from_icloud": "Сваляне от iCloud",
"downloading_media": "Изтегляне на медия",
"drag_to_reorder": "Плъзнете, за да пренаредите",
"drop_files_to_upload": "Пуснете файловете, за да ги качите",
"duplicate": "Направи копие",
"duplicate_workflow": "Дублиране на работен процес",
"duplicates": "Дубликати",
"duplicates_description": "Изберете всяка група, като посочите кои, ако има такива, са дубликати.",
"duration": "Продължителност",
@@ -1072,6 +1091,7 @@
"failed_to_remove_product_key": "Неуспешно премахване на продуктовия ключ",
"failed_to_reset_pin_code": "Неуспешно нулиране на ПИН кода",
"failed_to_stack_assets": "Неуспешно подреждане на обекти",
"failed_to_tag_assets": "Неуспешно добавяне на етикет",
"failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти",
"failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията",
"incorrect_email_or_password": "Неправилен имейл или парола",
@@ -1191,11 +1211,13 @@
"export_as_json": "Експортиране като JSON",
"export_database": "Експорт на базата данни",
"export_database_description": "Експорт на базата данни SQLite",
"exposure_time": "Време на експозиция",
"extension": "Разширение",
"external": "Външно",
"external_libraries": "Външни библиотеки",
"external_network": "Външна мрежа",
"external_network_sheet_info": "Когато няма връзка с предпочитаната Wi-Fi мрежа, приложението ще опитва да се свърже със сървъра чрез първия достъпен URL адрес, започвайки отгоре надолу",
"f_number": "F-число",
"face_unassigned": "Незададено",
"failed": "Неуспешно",
"failed_count": "Неуспешни: {count}",
@@ -1213,7 +1235,6 @@
"features_setting_description": "Управление на функциите на приложението",
"file_name_or_extension": "Име на файл или разширение",
"file_name_text": "Имe на файл",
"file_name_with_value": "Име на файл: {file_name}",
"file_size": "Размер на файла",
"filename": "Име на файл",
"filetype": "Тип на файл",
@@ -1226,6 +1247,7 @@
"find_them_fast": "Намерете ги бързо по име с търсене",
"first": "Първи",
"fix_incorrect_match": "Поправяне на неправилно съвпадение",
"focal_length": "Фокусно разстояние",
"folder": "Папка",
"folder_not_found": "Папката не е намерена",
"folders": "Папки",
@@ -1236,6 +1258,7 @@
"free_up_space_description": "Преместете архивираните снимки и видеа в кошчето на устройството, за да освободите място. Копията на сървъра ще бъдат запазени.",
"free_up_space_settings_subtitle": "Освобождаване на място за съхранение на устройството",
"full_path": "Пълен път: {path}",
"full_path_or_folder": "Пълен път или папка",
"gcast_enabled": "Gооgle Cast",
"gcast_enabled_description": "За да работи тази функция зарежда външни ресурси от Google.",
"general": "Общи",
@@ -1345,6 +1368,7 @@
"ios_debug_info_no_sync_yet": "Все още не е изпълнявана задача за фонова синхронизация",
"ios_debug_info_processes_queued": "{count, plural, one {{count} фонов процес} many {{count} фонови процеса} other {{count} фонови процеса}} в опашката",
"ios_debug_info_processing_ran_at": "Започната обработка на {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# елемент} other {# елементи}}",
"jobs": "Задачи",
"json_editor": "JSON редактор",
@@ -1392,11 +1416,13 @@
"light_theme": "Премини към светла тема",
"like": "Харесайте",
"like_deleted": "Като изтрит",
"link": "Връзка",
"link_motion_video": "Линк към видео",
"link_to_docs": "За повече информация вижте <link>документацията</link>.",
"link_to_oauth": "Линк към OAuth",
"linked_oauth_account": "Свързан OAuth акаунт",
"list": "Лист",
"live": "Живот",
"loading": "Зареждане",
"loading_search_results_failed": "Зареждането на резултатите от търсенето е неуспешно",
"local": "Локално",
@@ -1518,6 +1544,38 @@
"marked_all_as_read": "Всички маркирани като прочетени",
"matches": "Съвпадения",
"matching_assets": "Съвпадащи обекти",
"media_chrome": {
"auto": "Авто",
"captions": "Субтитри",
"captions_off": "Изключенo",
"closed_captions": "субтитри",
"decode_error": "Грешка при декодиране",
"disable_captions": "Изключи субтитри",
"enable_captions": "Включи субтитри",
"enter_fullscreen_mode": "На цял екран",
"exit_fullscreen_mode": "Изход от цял екран",
"loop": "Повтаряй",
"media_error_description": "Възпроизвеждането е спряно поради грешка във файла. Може би файлът е повреден или браузъра не поддържа този формат.",
"media_loading": "зареждане на медия",
"mute": "Без звук",
"network_error": "Грешка в мрежата",
"network_error_description": "Прекъсване на зареждането поради грешка в мрежата.",
"not_supported_error": "Този източник не се поддържа",
"playback_rate": "Скорост на възпроизвеждане",
"playback_rate_current": "текуща скорост на възпроизвеждане",
"playback_rate_value": "Скорост на възпроизвеждане {playbackRate}",
"playback_time": "продължителност",
"quality": "Качество",
"second": "секунда",
"seconds": "секунди",
"time_value_of_total_time": "{currentTime} от {totalTime}",
"time_value_remaining": "{time} остават",
"unmute": "Включи звук",
"unsupported_error_description": "Възникна непоправима грешка. Проблем в сървъра или мрежата, възможно е браузъра да не поддържа този формат.",
"video_not_loaded_unknown_time": "не е заредено видео, неизвестно време.",
"video_player": "видеоплеер",
"volume": "сила на звука"
},
"media_type": "Вид медия",
"memories": "Спомени",
"memories_all_caught_up": "Това е всичко за днес",
@@ -1534,6 +1592,8 @@
"merge_people_prompt": "Искате ли да слеете тези хора? Това действие е необратимо.",
"merge_people_successfully": "Успешно сливане на хора",
"merged_people_count": "Слят {count, plural, one {# човек} other {# човека}}",
"minFaces": "Минимум лица",
"minFaces_description": "Минималният брой разпознати лица, за да бъде показан човек като разпознат",
"minimize": "Минимизиране",
"minute": "Минута",
"minutes": "Минути",
@@ -1543,9 +1603,10 @@
"mobile_app": "Мобилно приложение",
"mobile_app_download_onboarding_note": "Свалете мобилното приложение Immich с някоя от следните опции",
"model": "Модел",
"modify_date": "Дата на промянa",
"month": "Месец",
"monthly_title_text_date_format": "MMMM г",
"more": "Още",
"motion": "Движение",
"move": "Премести",
"move_down": "Премести надолу",
"move_off_locked_folder": "Извади от заключената папка",
@@ -1562,6 +1623,8 @@
"multiselect_grid_edit_gps_err_read_only": "Не може да се редактира местоположението на обект само за четене, пропускане",
"mute_memories": "Изключване на звука на спомените",
"my_albums": "Мои албуми",
"my_immich_description": "Копирай адреса на текущата страница като връзка към моя Immich",
"my_immich_title": "Връзка към моя Immich",
"name": "Име",
"name_or_nickname": "Име или прякор",
"name_required": "Задължително е Име",
@@ -1589,7 +1652,6 @@
"next": "Следващо",
"next_memory": "Следващ спомен",
"no": "Не",
"no_actions_added": "Все още не са добавени действия",
"no_albums_found": "Не са намерени албуми",
"no_albums_message": "Създайте албум за организиране на снимки и видеоклипове",
"no_albums_with_name_yet": "Изглежда, че все още нямате албуми с това име.",
@@ -1606,7 +1668,6 @@
"no_exif_info_available": "Няма exif информация",
"no_explore_results_message": "Качете още снимки, за да разгледате колекцията си.",
"no_favorites_message": "Добавете в любими, за да намирате бързо най-добрите си снимки и видеоклипове",
"no_filters_added": "Все още не са добавени филтри",
"no_libraries_message": "Създайте външна библиотека за да разглеждате снимки и видеоклипове",
"no_local_assets_found": "Не е намерен локален обект с такава контролна сума",
"no_location_set": "Не е зададено местоположение",
@@ -1619,6 +1680,7 @@
"no_results": "Няма резултати",
"no_results_description": "Опитайте със синоним или по-обща ключова дума",
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
"no_steps": "Все още няма добавени стъпки",
"no_uploads_in_progress": "Няма качване в момента",
"none": "Нищо",
"not_allowed": "Не е разрешено",
@@ -1664,6 +1726,7 @@
"organize_into_albums": "Подредете в албуми",
"organize_into_albums_description": "Добавете наличните снимки в албуми, като използвате текущите настройки за синхронизиране",
"organize_your_library": "Организиране на вашата библиотека",
"orientation": "Ориентация",
"original": "оригинал",
"other": "Други",
"other_devices": "Други устройства",
@@ -1755,6 +1818,8 @@
"play_original_video_setting_description": "Предпочитане на показване на оригиналното видео, вместо транскодирани. Ако формата на оригиналния файл не се поддържа, възпроизвеждането може да бъде неправилно.",
"play_transcoded_video": "Покажи транскодирано видео",
"please_auth_to_access": "Моля, удостовери за достъп",
"plugin_method_filter_type": "Филтър",
"plugin_method_filter_type_description": "Този метод може да филтрира събития и по условие да спира изпълнението на следващи стъпки",
"port": "Порт",
"preferences_settings_subtitle": "Управление на предпочитанията на приложението",
"preferences_settings_title": "Предпочитания",
@@ -1776,6 +1841,7 @@
"profile_drawer_readonly_mode": "Режима само за четене е активиран. С дълго натискане върху картиката-аватар на потребителя ще деактивирате само за четене.",
"profile_image_of_user": "Профилна снимка на {user}",
"profile_picture_set": "Профилната снимка е сложена.",
"projection_type": "Тип проекция",
"public_album": "Публичен албум",
"public_share": "Публично споделяне",
"purchase_account_info": "Поддръжник",
@@ -1853,6 +1919,7 @@
"remove_assets_title": "Премахване на елементите?",
"remove_custom_date_range": "Премахни зададения диапазон от дати",
"remove_deleted_assets": "Премахни Изтритите Елементи",
"remove_filter": "Премахни филтър",
"remove_from_album": "Премахни от албума",
"remove_from_album_action_prompt": "{count} са премахнати от албума",
"remove_from_favorites": "Премахни от Любими",
@@ -1926,6 +1993,8 @@
"scan_settings": "Сканирай настройките",
"scanning": "Сканиране",
"scanning_for_album": "Сканирай за албум...",
"screencast_mode_description": "Показване на екрана на индикатори за събития от клавиатурата и мишката",
"screencast_mode_title": "Превключване на режима на скрийнкаст",
"search": "Търсене",
"search_albums": "Търси албуми",
"search_by_context": "Търси по контекст",
@@ -1933,6 +2002,8 @@
"search_by_description_example": "Разходка в Сапа",
"search_by_filename": "Търси по име на файла или разширение",
"search_by_filename_example": "например IMG_1234.JPG или PNG",
"search_by_full_path": "Търсене по пълен път или папка",
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - търсена за Projects, 3D, Printing, 2026 и т.н.",
"search_by_ocr": "Търсене на текст",
"search_by_ocr_example": "Lattе",
"search_camera_lens_model": "Търсене на модел на обектива...",
@@ -2140,7 +2211,9 @@
"show_in_timeline": "Показване във времевата линия",
"show_in_timeline_setting_description": "Показване на снимки и видеа от този потребител във времевата линия",
"show_keyboard_shortcuts": "Покажи клавишни комбинации",
"show_less": "Покажи по-малко",
"show_metadata": "Покажи метаданни",
"show_more_fields": "{count, plural, one {Покажи още # поле} other {Покажи още # полета}}",
"show_or_hide_info": "Покажи или скрий информацията",
"show_password": "Покажи паролата",
"show_person_options": "Показване на опции за лица",
@@ -2148,6 +2221,7 @@
"show_schema": "Покажи схема",
"show_search_options": "Показване на опциите за търсене",
"show_shared_links": "Покажи споделени линкове",
"show_slideshow_metadata_overlay": "Покажи информационния слой",
"show_slideshow_transition": "Покажи прехода на слайдшоуто",
"show_supporter_badge": "Значка поддръжник",
"show_supporter_badge_description": "Покажи значка поддръжник",
@@ -2163,9 +2237,13 @@
"skip_to_folders": "Премини към папките",
"skip_to_tags": "Премини към етикетите",
"slideshow": "Слайдшоу",
"slideshow_metadata_overlay_mode": "Съдържание на слоя с информация",
"slideshow_metadata_overlay_mode_description_only": "Само описание",
"slideshow_metadata_overlay_mode_full": "Пълна",
"slideshow_repeat": "Повтаряй слайдшоуто",
"slideshow_repeat_description": "Започвай отново, когато слайдшоуто приключи",
"slideshow_settings": "Настройки за слайдшоу",
"smart_album": "Умен албум",
"sort_albums_by": "Сортиране на албуми по...",
"sort_created": "Дата на създаване",
"sort_items": "Брой елементи",
@@ -2188,6 +2266,11 @@
"start_date_before_end_date": "Началната дата трябва да бъде преди крайната дата",
"state": "Щат",
"status": "Статус",
"step_delete": "Премахни стъпката",
"step_delete_confirm": "Сигурни ли сте, че искате да премахнете тази стъпка?",
"step_details": "Подробности за стъпката",
"steps": "Стъпки",
"steps_count": "{count, plural, one {# стъпка} other {# стъпки}}",
"stop_casting": "Спри предаването",
"stop_motion_photo": "Снимка със стоп кадър",
"stop_photo_sharing": "Да спра ли споделянето на вашите снимки?",
@@ -2214,6 +2297,8 @@
"sync_status": "Състояние на синхронизацията",
"sync_status_subtitle": "Преглед и управление на системата за синхронизация",
"sync_upload_album_setting_subtitle": "Създавайте и зареждайте снимки и видеа в избрани албуми в Immich",
"system_theme": "Тема от системата",
"system_theme_command_description": "Използвай системната тема ({value})",
"tag": "Таг",
"tag_assets": "Тагни елементи",
"tag_created": "Създаден етикет: {tag}",
@@ -2279,7 +2364,7 @@
"trash_page_title": "В коша ({count})",
"trashed_items_will_be_permanently_deleted_after": "Изхвърлените в кошчето елементи ще бъдат изтрити за постоянно след {days, plural, one {# ден} other {# дни}}.",
"trigger": "Тригер",
"trigger_asset_uploaded": "Обектът е зареден",
"trigger_asset_uploaded": "Качване на файлове",
"trigger_asset_uploaded_description": "Сработва при зареждане на нов обект",
"trigger_description": "Събитие, което стартира работния процес",
"trigger_person_recognized": "Разпознато е лице",
@@ -2319,7 +2404,6 @@
"unsupported_field_type": "Типа на полето не се поддържа",
"unsupported_file_type": "Файлът {file} не може да бъде зареден, защото неговият тип {type} не се поддържа.",
"untagged": "Немаркирани",
"untitled_workflow": "Работен процес без име",
"up_next": "Следващ",
"update_location_action_prompt": "Обнови координатите на {count} избрани обекта с:",
"updated_at": "Обновено",
@@ -2348,6 +2432,7 @@
"use_browser_locale_description": "Формат на дата, време и числа според езиковата настройка на браузъра",
"use_current_connection": "Използвай текущата връзка",
"use_custom_date_range": "Използвайте собствен диапазон от дати вместо това",
"use_template": "Използвайте шаблон",
"user": "Потребител",
"user_has_been_deleted": "Този потребител е премахнат.",
"user_id": "Потребител ИД",
@@ -2377,6 +2462,7 @@
"video": "Видеоклип",
"video_hover_setting": "Възпроизвеждане на видеоклип при посочване с мишката",
"video_hover_setting_description": "Възпроизвеждане на видеоклипа, когато мишката се движи над елемента. Дори когато е деактивирано, възпроизвеждането може да бъде стартирано чрез задържане на курсора на мишката върху иконата за възпроизвеждане.",
"video_quality": "Качество на видеото",
"videos": "Видеоклипове",
"videos_count": "{count, plural, one {# Видео} other {# Видеа}}",
"videos_only": "Само видеа",
@@ -2409,8 +2495,10 @@
"week": "Седмица",
"welcome": "Добре дошли",
"welcome_to_immich": "Добре дошли в Immich",
"when": "Когато",
"width": "Ширинa",
"wifi_name": "Wi-Fi мрежа",
"workflow": "Работен процес",
"workflow_delete_prompt": "Наистина ли искате да изтриете този работен процес?",
"workflow_deleted": "Работния процес е изтрит",
"workflow_description": "Описание на работния процес",
@@ -2420,11 +2508,13 @@
"workflow_name": "Име на работния процес",
"workflow_navigation_prompt": "Наистина ли искате да излезете без да съхраните промените?",
"workflow_summary": "Обобщение за работния процес",
"workflow_templates": "Шаблони на работния процес",
"workflow_update_success": "Работният процес е успешно обновен",
"workflow_updated": "Работният процес е обновен",
"workflows": "Работни процеси",
"workflows_help_text": "Работните процеси автоматизират действията с вашите обекти чрез тригери и филтри",
"wrong_pin_code": "Грешен PIN код",
"x_of_total": "{x}/{total}",
"year": "Година",
"years_ago": "преди {years, plural, one {# година} other {# години}}",
"yes": "Да",
-3
View File
@@ -22,8 +22,6 @@
"add_birthday": "জন্মদিন যোগ করুন",
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
"add_filter": "ফিল্টার যোগ করুন",
"add_filter_description": "একটি ফিল্টার শর্ত যোগ করতে ক্লিক করুন",
"add_location": "অবস্থান যুক্ত করুন",
"add_more_users": "আরো ব্যবহারকারী যুক্ত করুন",
"add_partner": "অংশীদার যোগ করুন",
@@ -42,7 +40,6 @@
"add_to_shared_album": "শেয়ার করা অ্যালবামে যোগ করুন",
"add_upload_to_stack": "আপলোড স্ট্যাকে যোগ করুন",
"add_url": "লিঙ্ক যোগ করুন",
"add_workflow_step": "কাজের ধাপ যোগ করুন",
"added_to_archive": "আর্কাইভ এ যোগ করা হয়েছে",
"added_to_favorites": "ফেভারিটে যোগ করা হয়েছে",
"added_to_favorites_count": "পছন্দের তালিকায় {count, number} যোগ করা হয়েছে",
+97 -14
View File
@@ -22,13 +22,12 @@
"add_birthday": "Afegeix la data de naixement",
"add_endpoint": "afegir endpoint",
"add_exclusion_pattern": "Afegir un patró d'exclusió",
"add_filter": "Afegir filtre",
"add_filter_description": "Feu clic per afegir una condició de filtre",
"add_location": "Afegir la ubicació",
"add_more_users": "Afegir més usuaris",
"add_partner": "Afegir company/a",
"add_path": "Afegir una ruta",
"add_photos": "Afegir fotografies",
"add_step": "Afegeix pas",
"add_tag": "Afegir una etiqueta",
"add_to": "Afegir a…",
"add_to_album": "Afegir a un l'àlbum",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Afegir a un àlbum compartit",
"add_upload_to_stack": "Afegeix la càrrega a la pila",
"add_url": "Afegir URL",
"add_workflow_step": "Afegeix un pas del flux de treball",
"added_to_archive": "Afegir a l'arxiu",
"added_to_favorites": "Afegit als preferits",
"added_to_favorites_count": "{count, number} afegits als preferits",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "Habilita les notificacions de correu electrònic",
"notification_settings": "Configuració de notificacions",
"notification_settings_description": "Gestiona la configuració de notificacions, incloent-hi el correu electrònic",
"oauth_allow_insecure_requests": "Permet sol·licituds no segures",
"oauth_allow_insecure_requests_description": "AVÍS: Això inhabilita la validació de certificats TLS per a les sol·licituds OAuth i us pot exposar a atacs MITM.",
"oauth_auto_launch": "Execució automàtica",
"oauth_auto_launch_description": "Inicia el flux d'inici de sessió OAuth automàticament en accedir a la pàgina d'inici de sessió",
"oauth_auto_register": "Registre automàtic",
@@ -274,9 +274,11 @@
"oauth_button_text": "Text del botó",
"oauth_client_secret_description": "Requerit per clients confidencials, o si PKCE (Proof Key for Code Exchange) no està suportat pel client públic.",
"oauth_enable_description": "Iniciar sessió amb OAuth",
"oauth_end_session_url_description": "Redirigeix l'usuari a aquest URI quan tanqui la sessió.",
"oauth_mobile_redirect_uri": "URI de redirecció mòbil",
"oauth_mobile_redirect_uri_override": "Sobreescriu l'URI de redirecció mòbil",
"oauth_mobile_redirect_uri_override_description": "Habilita quan el proveïdor d'OAuth no permet una URI mòbil, com ara ''{callback}''",
"oauth_prompt_description": "Paràmetre de sol·licitud (per exemple, select_account, login, consent)",
"oauth_role_claim": "Concessió de rol",
"oauth_role_claim_description": "Atorgar accés d'administrador automàticament segons la presència d'aquesta concessió. La concessió pot ser 'usuari' o 'admin'.",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "Actualitzant totes les biblioteques",
"registration": "Registre d'administrador",
"registration_description": "Com que ets el primer usuari del sistema, seràs designat com a administrador i seràs responsable de les tasques administratives. També seràs l'encarregat de crear usuaris addicionals.",
"release_channel_release_candidate": "Candidat a versió",
"release_channel_stable": "Estable",
"remove_failed_jobs": "Eliminar treballs fallits",
"require_password_change_on_login": "Requerir que l'usuari canviï la contrasenya en el primer inici de sessió",
"reset_settings_to_default": "Restablir configuracions per defecte",
@@ -440,6 +444,8 @@
"user_settings_description": "Gestiona la configuració dels usuaris",
"user_successfully_removed": "L'usuari {email} s'ha eliminat correctament.",
"users_page_description": "Pàgina d'usuaris de l'administrador",
"version_check_channel": "Canal de publicació",
"version_check_channel_description": "Tria el canal de publicació del qual vols rebre avisos de noves versions",
"version_check_enabled_description": "Activa la comprovació de la versió",
"version_check_implications": "La funció de comprovació de versions depèn de comunicacions periòdiques amb {server}",
"version_check_settings": "Comprovació de versió",
@@ -696,9 +702,10 @@
"birthdate_saved": "Data de naixement guardada amb èxit",
"birthdate_set_description": "La data de naixement s'utilitza per calcular l'edat d'aquesta persona en el moment d'una foto.",
"blurred_background": "Fons difuminat",
"browse_templates": "Explorar plantilles",
"bugs_and_feature_requests": "Errors i sol·licituds de funcions",
"build": "Construeix",
"build_image": "Construeix la imatge",
"build": "Número de compilació",
"build_image": "Versió de la imatge compilada",
"bulk_delete_duplicates_confirmation": "Esteu segurs que voleu suprimir de manera massiva {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i esborrarà permanentment tots els altres duplicats. No podeu desfer aquesta acció!",
"bulk_keep_duplicates_confirmation": "Esteu segur que voleu mantenir {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això resoldrà tots els grups duplicats sense eliminar res.",
"bulk_trash_duplicates_confirmation": "Esteu segur que voleu enviar a les escombraries {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i eliminarà la resta de duplicats.",
@@ -729,6 +736,7 @@
"cannot_update_the_description": "No es pot actualitzar la descripció",
"cast": "Emet",
"cast_description": "Configurar les destinacions de transmissió disponibles",
"change": "Canvia",
"change_date": "Canvia la data",
"change_description": "Canvia la descripció",
"change_display_order": "Canvia l'ordre de visualització",
@@ -757,6 +765,7 @@
"check_corrupt_asset_backup_description": "Executeu aquesta comprovació només mitjançant Wi-Fi i un cop s'hagi fet una còpia de seguretat de tots els actius. El procediment pot trigar uns minuts.",
"check_logs": "Comprovar els registres",
"checksum": "Suma de control",
"choose": "Tria",
"choose_matching_people_to_merge": "Trieu les persones que coincideixin per combinar-les",
"city": "Ciutat",
"cleanup_confirm_description": "Immich ha trobat {count} recursos (creats abans del {date}) carregats adequadament al servidor. Eliminar les còpies locals d'aquest dispositiu?",
@@ -774,6 +783,7 @@
"clear": "Buida",
"clear_all": "Neteja-ho tot",
"clear_all_recent_searches": "Esborra totes les cerques recents",
"clear_failed_count": "Buida fallades ({count})",
"clear_file_cache": "Buida la memòria cau de fitxers",
"clear_message": "Neteja el missatge",
"clear_value": "Neteja el valor",
@@ -805,6 +815,7 @@
"comments_are_disabled": "Els comentaris estan desactivats",
"common_create_new_album": "Crea un àlbum nou",
"completed": "Completat",
"configuration": "Configuració",
"confirm": "Confirmar",
"confirm_admin_password": "Confirmeu la contrasenya d'administrador",
"confirm_delete_face": "Estàs segur que vols eliminar la cara de {name} de les cares reconegudes?",
@@ -819,6 +830,7 @@
"contain": "Contingut",
"context": "Context",
"continue": "Continuar",
"control_bottom_app_bar_add_tags": "Afegeix etiquetes",
"control_bottom_app_bar_create_new_album": "Crea un àlbum nou",
"control_bottom_app_bar_delete_from_immich": "Suprimeix del Immich",
"control_bottom_app_bar_delete_from_local": "Suprimeix del dispositiu",
@@ -832,6 +844,7 @@
"copy_error": "Error de còpia",
"copy_file_path": "Copia la ruta del fitxer",
"copy_image": "Còpia imatge",
"copy_json": "Copia el JSON",
"copy_link": "Còpia l'enllaç",
"copy_link_to_clipboard": "Còpia l'enllaç al porta-retalls",
"copy_password": "Còpia la contrasenya",
@@ -881,17 +894,16 @@
"cutoff_date_description": "Manté fotos des de l'últim…",
"cutoff_day": "{count, plural, one {dia} other {dies}}",
"cutoff_year": "{count, plural, one {any} other {anys}}",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Fosc",
"dark_theme": "Canvia a tema fosc",
"date": "Data",
"date_after": "Data posterior a",
"date_and_time": "Data i hora",
"date_before": "Data anterior a",
"date_format": "E, d LLL, y • hh:mm",
"date_of_birth": "Data de naixement",
"date_of_birth_saved": "Data de naixement guardada amb èxit",
"date_range": "Interval de dates",
"date_time_original": "Data/Hora original",
"day": "Dia",
"days": "Dies",
"deduplicate_all": "Desduplica-ho tot",
@@ -970,7 +982,10 @@
"downloading_asset_filename": "Descarregant l'element {filename}",
"downloading_from_icloud": "Descarregant des d'iCloud",
"downloading_media": "Descàrrega multimèdia",
"drag_to_reorder": "Arrossegueu per reordenar",
"drop_files_to_upload": "Deixeu els fitxers a qualsevol lloc per pujar-los",
"duplicate": "Duplica",
"duplicate_workflow": "Duplica el flux de treball",
"duplicates": "Duplicats",
"duplicates_description": "Resol cada grup indicant, si n'hi ha, quins són duplicats.",
"duration": "Durada",
@@ -1072,6 +1087,7 @@
"failed_to_remove_product_key": "No s'ha pogut eliminar la clau del producte",
"failed_to_reset_pin_code": "No s'ha pogut reiniciar el codi PIN",
"failed_to_stack_assets": "No s'han pogut apilar els elements",
"failed_to_tag_assets": "Ha fallat l'assignació d'etiquetes",
"failed_to_unstack_assets": "No s'han pogut desapilar els elements",
"failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions",
"incorrect_email_or_password": "Correu electrònic o contrasenya incorrectes",
@@ -1191,11 +1207,13 @@
"export_as_json": "Exportar com a JSON",
"export_database": "Exportar base de dades",
"export_database_description": "Exportar la base de dades SQLite",
"exposure_time": "Temps d'exposició",
"extension": "Extensió",
"external": "Extern",
"external_libraries": "Llibreries externes",
"external_network": "Xarxa externa",
"external_network_sheet_info": "Quan no estigui a la xarxa Wi-Fi preferida, l'aplicació es connectarà al servidor mitjançant el primer dels URL següents a què pot arribar, començant de dalt a baix",
"f_number": "Obertura",
"face_unassigned": "Sense assignar",
"failed": "Fallat",
"failed_count": "Fallits: {count}",
@@ -1213,7 +1231,6 @@
"features_setting_description": "Administrar les funcions de l'aplicació",
"file_name_or_extension": "Nom de l'arxiu o extensió",
"file_name_text": "Nom del fitxer",
"file_name_with_value": "Nom del fitxer: {file_name}",
"file_size": "Mida del fitxer",
"filename": "Nom del fitxer",
"filetype": "Tipus d'arxiu",
@@ -1226,6 +1243,7 @@
"find_them_fast": "Trobeu-los ràpidament pel nom amb la cerca",
"first": "Primer",
"fix_incorrect_match": "Corregiu la coincidència incorrecta",
"focal_length": "Longitud focal",
"folder": "Carpeta",
"folder_not_found": "Carpeta no trobada",
"folders": "Carpetes",
@@ -1236,6 +1254,7 @@
"free_up_space_description": "Mou fotos i videos que ja tinguen còpia al servidor a la paperera del teu dispositiu per alliberar espai. Les còpies del servidor no es modificaran.",
"free_up_space_settings_subtitle": "Alliberar espai del dispositiu",
"full_path": "Ruta completa: {path}",
"full_path_or_folder": "Camí sencer o carpeta",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Aquesta funció carrega recursos externs de Google per funcionar.",
"general": "General",
@@ -1345,6 +1364,7 @@
"ios_debug_info_no_sync_yet": "Encara no s'ha executat cap tasca de sincronització en segon pla",
"ios_debug_info_processes_queued": "{count, plural, one {Un procés en segon pla a la cua} other {{count} processos en segon pla a la cua}}",
"ios_debug_info_processing_ran_at": "El processament s'ha executat {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# element} other {# elements}}",
"jobs": "Tasques",
"json_editor": "Editor JSON",
@@ -1392,11 +1412,13 @@
"light_theme": "Canviar a tema clar",
"like": "M'agrada",
"like_deleted": "M'agrada suprimit",
"link": "Enllaç",
"link_motion_video": "Enllaçar vídeo en moviment",
"link_to_docs": "Per més informació, mirar la <link>documentation</link>.",
"link_to_oauth": "Enllaç a OAuth",
"linked_oauth_account": "Compte OAuth enllaçat",
"list": "Llista",
"live": "En viu",
"loading": "Carregant",
"loading_search_results_failed": "No s'han pogut carregar els resultats de la cerca",
"local": "Local",
@@ -1518,6 +1540,38 @@
"marked_all_as_read": "Marcat tot com a llegit",
"matches": "Coincidències",
"matching_assets": "Recursos Coincidents",
"media_chrome": {
"auto": "Auto",
"captions": "Llegendes",
"captions_off": "Desactivat",
"closed_captions": "Llegendes tancades",
"decode_error": "Error de decodificació",
"disable_captions": "Desactivar llegendes",
"enable_captions": "Activar llegendes",
"enter_fullscreen_mode": "Activar mode pantalla sencera",
"exit_fullscreen_mode": "Desactivar mode pantalla sencera",
"loop": "Bucle",
"media_error_description": "Un error dels mitjans ha provocat l'aturada de la reproducció. El mitjà pot estar corromput o el navegador no suporta el format.",
"media_loading": "carregant el mitjà",
"mute": "Silencia",
"network_error": "Error de xarxa",
"network_error_description": "Un error de xarxa ha provocat la fallada de la descarrega.",
"not_supported_error": "Font origen no suportada",
"playback_rate": "Velocitat de reproducció",
"playback_rate_current": "velocitat actual de reproducció",
"playback_rate_value": "Velocitat de reproducció {playbackRate}",
"playback_time": "temps de reproducció",
"quality": "Quallitat",
"second": "segon",
"seconds": "segons",
"time_value_of_total_time": "{currentTime} de {totalTime}",
"time_value_remaining": "{time} restant",
"unmute": "Activa so",
"unsupported_error_description": "Un error no suportat ha passat. El servidor o la xarxa han fallat, o el vostre navegador no accepta aquest format.",
"video_not_loaded_unknown_time": "vídeo no carregat, temps desconegut.",
"video_player": "reproductor de vídeo",
"volume": "volum"
},
"media_type": "Tipus de mitjà",
"memories": "Records",
"memories_all_caught_up": "Posat al dia",
@@ -1543,9 +1597,10 @@
"mobile_app": "Aplicació mòbil",
"mobile_app_download_onboarding_note": "Descarregar la App de mòbil fent servir les seguents opcions",
"model": "Model",
"modify_date": "Canvia la data",
"month": "Mes",
"monthly_title_text_date_format": "MMMM a",
"more": "Més",
"motion": "Moviment",
"move": "Moure",
"move_down": "Moure cap avall",
"move_off_locked_folder": "Moure fora de la carpeta bloquejada",
@@ -1562,6 +1617,8 @@
"multiselect_grid_edit_gps_err_read_only": "No es pot canviar la localització de fitxers de només lectura, saltant",
"mute_memories": "Silenciar records",
"my_albums": "Els meus àlbums",
"my_immich_description": "Copia la pàgina actual com a enllaç de My Immich",
"my_immich_title": "Enllaç My Immich",
"name": "Nom",
"name_or_nickname": "Nom o sobrenom",
"name_required": "El nom és obligatori",
@@ -1589,7 +1646,6 @@
"next": "Següent",
"next_memory": "Següent record",
"no": "No",
"no_actions_added": "Encara no s'han afegit accions",
"no_albums_found": "No s'han trobat àlbums",
"no_albums_message": "Creeu un àlbum per organitzar les vostres fotos i vídeos",
"no_albums_with_name_yet": "Sembla que encara no tens cap àlbum amb aquest nom.",
@@ -1606,7 +1662,6 @@
"no_exif_info_available": "No hi ha informació d'exif disponible",
"no_explore_results_message": "Penja més fotos per explorar la teva col·lecció.",
"no_favorites_message": "Afegiu preferits per trobar les millors fotos i vídeos a l'instant",
"no_filters_added": "Encara no s'han afegit filtres",
"no_libraries_message": "Creeu una llibreria externa per veure les vostres fotos i vídeos",
"no_local_assets_found": "No s'ha trobat cap recurs local amb aquest checksum",
"no_location_set": "No s'ha definit cap ubicació",
@@ -1619,6 +1674,7 @@
"no_results": "Sense resultats",
"no_results_description": "Proveu un sinònim o una paraula clau més general",
"no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa",
"no_steps": "Encara no s'ha afegit cap pas",
"no_uploads_in_progress": "Cap pujada en progrés",
"none": "Cap",
"not_allowed": "No permès",
@@ -1664,6 +1720,7 @@
"organize_into_albums": "Organitzar en àlbums",
"organize_into_albums_description": "Posar fotos existents en àlbums utilitzant la configuració de sincronització actual",
"organize_your_library": "Organitzeu la llibreria",
"orientation": "Orientació",
"original": "original",
"other": "Altres",
"other_devices": "Altres dispositius",
@@ -1755,6 +1812,8 @@
"play_original_video_setting_description": "Preferir la reproducció del video original sobre el video recodificat. Si el video original no es compatible potser no es reprodueixi correctament.",
"play_transcoded_video": "Veure el video recodificat",
"please_auth_to_access": "Per favor, autentica't per accedir",
"plugin_method_filter_type": "Filtre",
"plugin_method_filter_type_description": "Aquest mètode pot filtrar esdeveniments i, condicionat, evitar que s'executin els passos següents",
"port": "Port",
"preferences_settings_subtitle": "Gestiona les preferències de l'aplicació",
"preferences_settings_title": "Preferències",
@@ -1776,6 +1835,7 @@
"profile_drawer_readonly_mode": "Mode només lectura. Feu pulsació llarga a la icona de l'avatar d'usuari per sortir.",
"profile_image_of_user": "Imatge de perfil de {user}",
"profile_picture_set": "Imatge de perfil configurada.",
"projection_type": "Tipus de Projecció",
"public_album": "Àlbum públic",
"public_share": "Compartit públicament",
"purchase_account_info": "Contribuent",
@@ -1853,6 +1913,7 @@
"remove_assets_title": "Eliminar els elements?",
"remove_custom_date_range": "Elimina l'interval de dates personalitzat",
"remove_deleted_assets": "Suprimeix fitxers fora de línia",
"remove_filter": "Elimina el filtre",
"remove_from_album": "Treu de l'àlbum",
"remove_from_album_action_prompt": "{count} eliminats de l'àlbum",
"remove_from_favorites": "Eliminar dels preferits",
@@ -1926,6 +1987,8 @@
"scan_settings": "Configuració d'escaneig",
"scanning": "Escanejant",
"scanning_for_album": "S'està buscant l'àlbum...",
"screencast_mode_description": "Mostra els indicadors d'esdeveniments del teclat i del ratolí a la pantalla",
"screencast_mode_title": "Activa/desactiva el mode de captura de pantalla",
"search": "Cerca",
"search_albums": "Buscar àlbums",
"search_by_context": "Buscar per context",
@@ -1933,6 +1996,8 @@
"search_by_description_example": "Jornada de senderisme a Sapa",
"search_by_filename": "Cerca per nom de fitxer o extensió",
"search_by_filename_example": "per exemple IMG_1234.JPG o PNG",
"search_by_full_path": "Cerca per camí complert o carpeta",
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - pots buscar Projectes, 3D, Impressió, 2026 etc.",
"search_by_ocr": "Buscar per OCR",
"search_by_ocr_example": "Després",
"search_camera_lens_model": "Buscar model de lents....",
@@ -2140,7 +2205,9 @@
"show_in_timeline": "Mostra a la cronologia",
"show_in_timeline_setting_description": "Mostra fotos i vídeos d'aquest usuari a la cronologia",
"show_keyboard_shortcuts": "Mostra dreceres de teclat",
"show_less": "Mostra'n menys",
"show_metadata": "Mostra metadades",
"show_more_fields": "{count, plural, one {Veure # camp més} other {Veure # camps més}}",
"show_or_hide_info": "Mostra o amaga informació",
"show_password": "Mostra contrasenya",
"show_person_options": "Mostra opcions de la persona",
@@ -2148,6 +2215,7 @@
"show_schema": "Mostrar esquema",
"show_search_options": "Mostra opcions de cerca",
"show_shared_links": "Mostra els enllaços compartits",
"show_slideshow_metadata_overlay": "Mostra informació sobre la imatge",
"show_slideshow_transition": "Mostra la transició de la presentació de diapositives",
"show_supporter_badge": "Insígnia de contribuent",
"show_supporter_badge_description": "Mostra una insígnia de contributor",
@@ -2163,9 +2231,13 @@
"skip_to_folders": "Anar a carpetes",
"skip_to_tags": "Anar a etiquetes",
"slideshow": "Diapositives",
"slideshow_metadata_overlay_mode": "Contingut de superposició",
"slideshow_metadata_overlay_mode_description_only": "Descripció només",
"slideshow_metadata_overlay_mode_full": "Tot",
"slideshow_repeat": "Repeteix la presentació de diapositives",
"slideshow_repeat_description": "Torna al principi quan acaba la presentació de diapositives",
"slideshow_settings": "Configuració de diapositives",
"smart_album": "Àlbum inteŀligent",
"sort_albums_by": "Ordena àlbums per...",
"sort_created": "Data de creació",
"sort_items": "Quantitat d'elements",
@@ -2188,6 +2260,11 @@
"start_date_before_end_date": "La data d'inici ha de ser abans de la data de fi",
"state": "Regió",
"status": "Estat",
"step_delete": "Elimina el pas",
"step_delete_confirm": "Esteu segur que voleu eliminar el pas?",
"step_details": "Detalls del pas",
"steps": "Passos",
"steps_count": "{count, plural, one {# pas} other {# passos}}",
"stop_casting": "Atura la transmisió",
"stop_motion_photo": "Atura foto en moviment",
"stop_photo_sharing": "Deixar de compartir les teves fotos?",
@@ -2214,6 +2291,8 @@
"sync_status": "Estat de la incronització",
"sync_status_subtitle": "Observa i administra el sistema de sincronització",
"sync_upload_album_setting_subtitle": "Creeu i pugeu les seves fotos i vídeos als àlbums seleccionats a Immich",
"system_theme": "Tema del sistema",
"system_theme_command_description": "Utilitza el tema del sistema ({value})",
"tag": "Etiqueta",
"tag_assets": "Etiquetar actius",
"tag_created": "Etiqueta creada: {tag}",
@@ -2279,7 +2358,7 @@
"trash_page_title": "Paperera ({count})",
"trashed_items_will_be_permanently_deleted_after": "Els elements que s'enviïn a la paperera s'eliminaran permanentment després de {days, plural, one {# dia} other {# dies}}.",
"trigger": "Disparador",
"trigger_asset_uploaded": "Mitjà Carregat",
"trigger_asset_uploaded": "Càrrega de Mitjans",
"trigger_asset_uploaded_description": "Es dispara quan un nou mitjà es puge al servidor",
"trigger_description": "L'esdeveniment que inicia l'automatització",
"trigger_person_recognized": "Persona identificada",
@@ -2319,7 +2398,6 @@
"unsupported_field_type": "Tipus de camp no suportat",
"unsupported_file_type": "No es pot carregar el fitxer {file} perquè el seu tipus de fitxer {type} no és compatible.",
"untagged": "Sense etiqueta",
"untitled_workflow": "Automatització sense títol",
"up_next": "Pròxim",
"update_location_action_prompt": "Actualitza la ubicació de {count} elements seleccionats amb:",
"updated_at": "Actualitzat",
@@ -2348,6 +2426,7 @@
"use_browser_locale_description": "Formatejar dates, hores i números segons la llengua i regió del navegador",
"use_current_connection": "Utilitza la connexió actual",
"use_custom_date_range": "Fes servir un rang de dates personalitzat",
"use_template": "Utilitza la plantilla",
"user": "Usuari",
"user_has_been_deleted": "Aquest usuari ha sigut eliminat.",
"user_id": "ID d'usuari",
@@ -2409,8 +2488,10 @@
"week": "Setmana",
"welcome": "Benvingut",
"welcome_to_immich": "Benvingut a immich",
"when": "Quan",
"width": "Amplada",
"wifi_name": "Nom Wi-Fi",
"workflow": "Flux de treball",
"workflow_delete_prompt": "Segur que vols eliminar aquesta automatització?",
"workflow_deleted": "Automatització eliminada",
"workflow_description": "Descripció de l'automatització",
@@ -2420,11 +2501,13 @@
"workflow_name": "Nom de l'automatització",
"workflow_navigation_prompt": "Segur que vols sortir sense desar els canvis?",
"workflow_summary": "Resum de l'automatització",
"workflow_templates": "Plantilles de fluxos de treball",
"workflow_update_success": "Automatització actualitzada amb èxit",
"workflow_updated": "Automatització actualitzada",
"workflows": "Automatitzacions",
"workflows_help_text": "Les automatitzacions realitzen accions automàticament sobre els teus mitjans basant-se en disparadors i filtres",
"wrong_pin_code": "Codi PIN incorrecte",
"x_of_total": "{x}/{total}",
"year": "Any",
"years_ago": "Fa {years, plural, one {# any} other {# anys}}",
"yes": "Sí",
+103 -13
View File
@@ -22,13 +22,12 @@
"add_birthday": "Přidat datum narození",
"add_endpoint": "Přidat koncový bod",
"add_exclusion_pattern": "Přidat vzor vyloučení",
"add_filter": "Přidat filtr",
"add_filter_description": "Kliknutím přidejte podmínku filtru",
"add_location": "Přidat polohu",
"add_more_users": "Přidat další uživatele",
"add_partner": "Přidat partnera",
"add_path": "Přidat cestu",
"add_photos": "Přidat fotky",
"add_step": "Přidat krok",
"add_tag": "Přidat značku",
"add_to": "Přidat do…",
"add_to_album": "Přidat do alba",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Přidat do sdíleného alba",
"add_upload_to_stack": "Přidat nahrané do seskupení",
"add_url": "Přidat URL",
"add_workflow_step": "Přidat krok pracovního postupu",
"added_to_archive": "Přidáno do archivu",
"added_to_favorites": "Přidáno do oblíbených",
"added_to_favorites_count": "Přidáno {count, number} do oblíbených",
@@ -232,7 +230,7 @@
"migration_job": "Migrace",
"migration_job_description": "Migrace miniatur snímků a obličejů do nejnovější struktury složek",
"nightly_tasks_cluster_faces_setting_description": "Spustit rozpoznávání obličeje na nově nalezených obličejích",
"nightly_tasks_cluster_new_faces_setting": "Seskupit nové tváře",
"nightly_tasks_cluster_new_faces_setting": "Seskupit nové obličeje",
"nightly_tasks_database_cleanup_setting": "Úlohy čištění databáze",
"nightly_tasks_database_cleanup_setting_description": "Vyčistit databázi od starých dat, jejichž platnost vypršela",
"nightly_tasks_generate_memories_setting": "Vytváření vzpomínek",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "Povolení e-mailových oznámení",
"notification_settings": "Oznámení",
"notification_settings_description": "Správa nastavení oznámení včetně e-mailu",
"oauth_allow_insecure_requests": "Povolit nezabezpečené požadavky",
"oauth_allow_insecure_requests_description": "VAROVÁNÍ: Toto zakáže ověřování TLS certifikátů u požadavků OAuth, což vás může vystavit riziku útoků typu MITM.",
"oauth_auto_launch": "Automatické zahájení",
"oauth_auto_launch_description": "Automatické zahájení přihlašovacího toku OAuth po přechodu na přihlašovací stránku",
"oauth_auto_register": "Automatická registrace",
@@ -274,9 +274,11 @@
"oauth_button_text": "Text tlačítka",
"oauth_client_secret_description": "Vyžadováno pro důvěrné klienty nebo pokud PKCE (Proof Key for Code Exchange) není podporováno pro veřejné klienty.",
"oauth_enable_description": "Přihlásit pomocí OAuth",
"oauth_end_session_url_description": "Přesměrovat uživatele po odhlášení na tuto adresu.",
"oauth_mobile_redirect_uri": "Mobilní přesměrování URI",
"oauth_mobile_redirect_uri_override": "Přepsat mobilní přesměrování URI",
"oauth_mobile_redirect_uri_override_description": "Povolit, pokud poskytovatel OAuth nepovoluje mobilní URI, například ''{callback}''",
"oauth_prompt_description": "Parametr dotazu (např. select_account, login, consent)",
"oauth_role_claim": "Deklarace Role",
"oauth_role_claim_description": "Automaticky udělit přístup správce na základě přítomnosti této deklarace. Deklarace může mít hodnotu 'user' nebo 'admin'.",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "Obnovení všech knihoven",
"registration": "Registrace správce",
"registration_description": "Vzhledem k tomu, že jste prvním uživatelem v systému, budete přiřazen jako správce a budete zodpovědný za úkoly správy a další uživatelé budou vytvořeni vámi.",
"release_channel_release_candidate": "Kandidát na vydání",
"release_channel_stable": "Stabilní",
"remove_failed_jobs": "Odebrat neúspěšné úlohy",
"require_password_change_on_login": "Požadovat, aby si uživatel při prvním přihlášení změnil heslo",
"reset_settings_to_default": "Obnovení výchozího nastavení",
@@ -397,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "Platí pouze pro VAAPI a QSV. Nastaví dri uzel použitý pro hardwarové překódování.",
"transcoding_preset_preset": "Předvolba (-preset)",
"transcoding_preset_preset_description": "Rychlost komprese. Pomalejší předvolby vytvářejí menší soubory a zvyšují kvalitu při dosažení určitého datového toku. VP9 ignoruje rychlosti vyšší než 'faster'.",
"transcoding_realtime": "Překódování v reálném čase [EXPERIMENTÁLNÍ]",
"transcoding_realtime_description": "Umožňuje provádět překódování v reálném čase během přenosu videa. Zpřístupní přepínání kvality, ale v závislosti na výkonu serveru může docházet k delším zpožděním při přehrávání a k trhanému přehrávání.",
"transcoding_realtime_enabled": "Povolit překódování v reálném čase",
"transcoding_realtime_enabled_description": "Pokud je zakázáno, server odmítne spustit nové relace překódování v reálném čase.",
"transcoding_reference_frames": "Referenční snímky",
"transcoding_reference_frames_description": "Počet referenčních snímků při kompresi daného snímku. Vyšší hodnoty zvyšují účinnost komprese, ale zpomalují kódování. Hodnota 0 toto nastavuje automaticky.",
"transcoding_required_description": "Pouze videa, která nejsou v akceptovaném formátu",
@@ -440,6 +448,8 @@
"user_settings_description": "Správa nastavení uživatelů",
"user_successfully_removed": "Uživatel {email} byl úspěšně odstraněn.",
"users_page_description": "Stránka správců",
"version_check_channel": "Kanál vydání",
"version_check_channel_description": "Vyberte si kanál vydání, pro který chcete dostávat oznámení o nových verzích",
"version_check_enabled_description": "Povolit kontrolu verzí",
"version_check_implications": "Kontrola verze je založena na pravidelné komunikaci s {server}",
"version_check_settings": "Kontrola verze",
@@ -696,6 +706,7 @@
"birthdate_saved": "Datum narození úspěšně uloženo",
"birthdate_set_description": "Datum narození se používá k výpočtu věku osoby v době pořízení fotografie.",
"blurred_background": "Rozmazané pozadí",
"browse_templates": "Procházet šablony",
"bugs_and_feature_requests": "Chyby a návrhy na funkce",
"build": "Sestavení",
"build_image": "Sestavení obrazu",
@@ -729,6 +740,7 @@
"cannot_update_the_description": "Nelze aktualizovat popis",
"cast": "Odeslat do zařízení",
"cast_description": "Nastavení dostupných cílů přenosu",
"change": "Změnit",
"change_date": "Změnit datum",
"change_description": "Změnit popis",
"change_display_order": "Změnit pořadí zobrazení",
@@ -757,6 +769,7 @@
"check_corrupt_asset_backup_description": "Tuto kontrolu provádějte pouze přes Wi-Fi a po zálohování všech prostředků. Takto operace může trvat několik minut.",
"check_logs": "Zkontrolujte protokoly",
"checksum": "Kontrolní součet",
"choose": "Vybrat",
"choose_matching_people_to_merge": "Zvolte odpovídající osoby ke sloučení",
"city": "Město",
"cleanup_confirm_description": "Immich našel {count} položek (vytvořených před {date}), které jsou bezpečně zálohovány na serveru. Chcete odstranit místní kopie z tohoto zařízení?",
@@ -774,6 +787,7 @@
"clear": "Vymazat",
"clear_all": "Vymazat vše",
"clear_all_recent_searches": "Vymazat všechna nedávná vyhledávání",
"clear_failed_count": "Vymazání selhalo ({count})",
"clear_file_cache": "Vymazat mezipaměť souborů",
"clear_message": "Vymazat zprávu",
"clear_value": "Vymazat hodnotu",
@@ -805,6 +819,7 @@
"comments_are_disabled": "Komentáře jsou vypnuty",
"common_create_new_album": "Vytvořit nové album",
"completed": "Dokončeno",
"configuration": "Nastavení",
"confirm": "Potvrdit",
"confirm_admin_password": "Potvrzení hesla správce",
"confirm_delete_face": "Opravdu chcete z položky odstranit obličej osoby {name}?",
@@ -819,6 +834,7 @@
"contain": "Obsah",
"context": "Kontext",
"continue": "Pokračovat",
"control_bottom_app_bar_add_tags": "Přidat značky",
"control_bottom_app_bar_create_new_album": "Vytvořit nové album",
"control_bottom_app_bar_delete_from_immich": "Smazat ze serveru Immich",
"control_bottom_app_bar_delete_from_local": "Smazat ze zařízení",
@@ -832,6 +848,7 @@
"copy_error": "Chyba kopírování",
"copy_file_path": "Kopírovat cestu k souboru",
"copy_image": "Kopírovat obrázek",
"copy_json": "Kopírovat JSON",
"copy_link": "Kopírovat odkaz",
"copy_link_to_clipboard": "Kopírovat odkaz do schránky",
"copy_password": "Kopírovat heslo",
@@ -881,17 +898,16 @@
"cutoff_date_description": "Zanechat fotografie a videa z posledních…",
"cutoff_day": "{count, plural, one {den} few {dny} other {dnů}}",
"cutoff_year": "{count, plural, one {rok} few {roky} other {let}}",
"daily_title_text_date": "EEEE, d. MMMM",
"daily_title_text_date_year": "EEEE, d. MMMM y",
"dark": "Tmavý",
"dark_theme": "Přepnout na tmavý motiv",
"date": "Datum",
"date_after": "Datum po",
"date_and_time": "Datum a čas",
"date_before": "Datum před",
"date_format": "EEEE, d. MMMM y • H:mm",
"date_of_birth": "Datum narození",
"date_of_birth_saved": "Datum narození úspěšně uloženo",
"date_range": "Rozsah dat",
"date_time_original": "Původní datum/čas",
"day": "Den",
"days": "Dnů",
"deduplicate_all": "Odstranit všechny duplicity",
@@ -970,7 +986,10 @@
"downloading_asset_filename": "Stahování položky {filename}",
"downloading_from_icloud": "Stahování z iCloudu",
"downloading_media": "Stahování média",
"drag_to_reorder": "Posuňte pro změnu pořadí",
"drop_files_to_upload": "Pro nahrání sem přetáhněte soubory",
"duplicate": "Duplikovat",
"duplicate_workflow": "Duplikovat pracovní postup",
"duplicates": "Duplicity",
"duplicates_description": "Vyřešte každou skupinu tak, že uvedete, které skupiny jsou duplicitní.",
"duration": "Doba trvání",
@@ -1072,6 +1091,7 @@
"failed_to_remove_product_key": "Nepodařilo se odebrat klíč produktu",
"failed_to_reset_pin_code": "Nepodařilo se resetovat PIN kód",
"failed_to_stack_assets": "Nepodařilo se seskupit položky",
"failed_to_tag_assets": "Nepodařilo se přidat značky k položkám",
"failed_to_unstack_assets": "Nepodařilo se zrušit seskupení položek",
"failed_to_update_notification_status": "Nepodařilo se aktualizovat stav oznámení",
"incorrect_email_or_password": "Nesprávný e-mail nebo heslo",
@@ -1191,11 +1211,13 @@
"export_as_json": "Exportovat jako JSON",
"export_database": "Exportovat databázi",
"export_database_description": "Exportovat databázi SQLite",
"exposure_time": "Expoziční čas",
"extension": "Přípona",
"external": "Externí",
"external_libraries": "Externí knihovny",
"external_network": "Externí síť",
"external_network_sheet_info": "Pokud nejste v preferované síti Wi-Fi, aplikace se připojí k serveru prostřednictvím první z níže uvedených adres URL, které může dosáhnout, počínaje shora dolů",
"f_number": "Clonové číslo",
"face_unassigned": "Nepřiřazena",
"failed": "Selhalo",
"failed_count": "Selhalo: {count}",
@@ -1213,7 +1235,6 @@
"features_setting_description": "Správa funkcí aplikace",
"file_name_or_extension": "Název nebo přípona souboru",
"file_name_text": "Název souboru",
"file_name_with_value": "Název souboru: {file_name}",
"file_size": "Velikost souboru",
"filename": "Název souboru",
"filetype": "Typ souboru",
@@ -1226,6 +1247,7 @@
"find_them_fast": "Najděte je rychle vyhledáním jejich jména",
"first": "První",
"fix_incorrect_match": "Opravit nesprávnou shodu",
"focal_length": "Ohnisková vzdálenost",
"folder": "Složka",
"folder_not_found": "Složka nebyla nalezena",
"folders": "Složky",
@@ -1236,6 +1258,7 @@
"free_up_space_description": "Přesunout zálohované fotografie a videa do koše zařízení, abyste uvolnili místo. Vaše kopie na serveru zůstanou v bezpečí.",
"free_up_space_settings_subtitle": "Uvolnit úložiště zařízení",
"full_path": "Úplná cesta: {path}",
"full_path_or_folder": "Celá cesta nebo složka",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Tato funkce načítá externí zdroje z Googlu, aby mohla fungovat.",
"general": "Obecné",
@@ -1345,6 +1368,7 @@
"ios_debug_info_no_sync_yet": "Dosud nebyla spuštěna žádná úloha synchronizace na pozadí",
"ios_debug_info_processes_queued": "{count, plural, one {{count} proces na pozadí ve frontě} few {{count} procesy na pozadí ve frontě} other {{count} procesů na pozadí ve frontě}}",
"ios_debug_info_processing_ran_at": "Zpracování spuštěno {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# položka} few {# položky} other {# položek}}",
"jobs": "Úlohy",
"json_editor": "JSON editor",
@@ -1392,11 +1416,13 @@
"light_theme": "Přepnout na světlý motiv",
"like": "Líbí se mi",
"like_deleted": "Oblíbení smazáno",
"link": "Odkaz",
"link_motion_video": "Připojit pohyblivé video",
"link_to_docs": "Další informace najdete v <link>dokumentaci</link>.",
"link_to_oauth": "Propojit s OAuth",
"linked_oauth_account": "Propojený OAuth účet",
"list": "Seznam",
"live": "Živý",
"loading": "Načítání",
"loading_search_results_failed": "Načítání výsledků vyhledávání se nezdařilo",
"local": "Místní",
@@ -1518,6 +1544,38 @@
"marked_all_as_read": "Vše označeno jako přečtené",
"matches": "Shody",
"matching_assets": "Odpovídající položky",
"media_chrome": {
"auto": "Automaticky",
"captions": "Titulky",
"captions_off": "Vypnuto",
"closed_captions": "skryté titulky",
"decode_error": "Chyba dekódování",
"disable_captions": "Vypnout titulky",
"enable_captions": "Zapnout titulky",
"enter_fullscreen_mode": "Přepnout do režimu celé obrazovky",
"exit_fullscreen_mode": "Ukončit režim celé obrazovky",
"loop": "Smyčka",
"media_error_description": "K přerušení přehrávání došlo kvůli chybě souboru. Soubor může být poškozený, případně váš prohlížeč tento formát nepodporuje.",
"media_loading": "načítání médií",
"mute": "Ztlumit",
"network_error": "Chyba sítě",
"network_error_description": "K selhání stahování médií došlo kvůli síťové chybě.",
"not_supported_error": "Zdroj není podporován",
"playback_rate": "Rychlost přehrávání",
"playback_rate_current": "aktuální rychlost přehrávání",
"playback_rate_value": "Rychlost přehrávání {playbackRate}",
"playback_time": "doba přehrávání",
"quality": "Kvalita",
"second": "sekunda",
"seconds": "sekund",
"time_value_of_total_time": "{currentTime} z {totalTime}",
"time_value_remaining": "zbývá {time}",
"unmute": "Zrušit ztlumení",
"unsupported_error_description": "Došlo k chybě způsobené nepodporovaným formátem. Došlo k selhání serveru nebo sítě, případně váš prohlížeč tento formát nepodporuje.",
"video_not_loaded_unknown_time": "video se nenačetlo, známý čas.",
"video_player": "videopřehrávač",
"volume": "hlasitost"
},
"media_type": "Typ média",
"memories": "Vzpomínky",
"memories_all_caught_up": "To je všechno",
@@ -1534,6 +1592,8 @@
"merge_people_prompt": "Chcete tyto lidi sloučit? Tato akce je nevratná.",
"merge_people_successfully": "Sloučení osob proběhlo úspěšně",
"merged_people_count": "{count, plural, one {Sloučena # osoba} few {Sloučeny # osoby} other {Sloučeno # lidí}}",
"minFaces": "Minimální počet obličejů",
"minFaces_description": "Minimální počet rozpoznaných obličejů, aby byla daná osoba zobrazena",
"minimize": "Minimalizovat",
"minute": "Minuta",
"minutes": "Minut",
@@ -1543,9 +1603,10 @@
"mobile_app": "Mobilní aplikace",
"mobile_app_download_onboarding_note": "Stáhněte si doprovodnou mobilní aplikaci pomocí následujících možností",
"model": "Model",
"modify_date": "Datum úpravy",
"month": "Měsíc",
"monthly_title_text_date_format": "LLLL y",
"more": "Více",
"motion": "Pohyb",
"move": "Přesunout",
"move_down": "Přesunout dolů",
"move_off_locked_folder": "Přesunout z uzamčené složky",
@@ -1562,6 +1623,8 @@
"multiselect_grid_edit_gps_err_read_only": "Nelze upravit polohu položek pouze pro čtení, přeskakuji",
"mute_memories": "Ztlumit vzpomínky",
"my_albums": "Moje alba",
"my_immich_description": "Zkopírovat aktuální stránku jako odkaz na Můj Immich",
"my_immich_title": "Odkaz na Můj Immich",
"name": "Jméno",
"name_or_nickname": "Jméno nebo přezdívka",
"name_required": "Jméno je povinné",
@@ -1589,7 +1652,6 @@
"next": "Další",
"next_memory": "Další vzpomínka",
"no": "Ne",
"no_actions_added": "Zatím nebyly přidány žádné akce",
"no_albums_found": "Žádná alba nenalezena",
"no_albums_message": "Vytvořte si album pro uspořádání fotografií a videí",
"no_albums_with_name_yet": "Vypadá to, že zatím nemáte žádná alba s tímto názvem.",
@@ -1606,7 +1668,6 @@
"no_exif_info_available": "Exif není k dispozici",
"no_explore_results_message": "Nahrajte další fotografie a prozkoumejte svou sbírku.",
"no_favorites_message": "Přidejte si oblíbené položky a rychle najděte své nejlepší obrázky a videa",
"no_filters_added": "Zatím nebyly přidány žádné filtry",
"no_libraries_message": "Vytvořte si externí knihovnu pro zobrazení fotografií a videí",
"no_local_assets_found": "Nebyly nalezeny žádné místní položky s tímto kontrolním součtem",
"no_location_set": "Není nastavena poloha",
@@ -1619,6 +1680,7 @@
"no_results": "Žádné výsledky",
"no_results_description": "Zkuste použít synonymum nebo obecnější klíčové slovo",
"no_shared_albums_message": "Vytvořte si album a sdílejte fotografie a videa s lidmi ve své síti",
"no_steps": "Zatím nebyly přidány žádné kroky",
"no_uploads_in_progress": "Neprobíhá žádné nahrávání",
"none": "Žádné",
"not_allowed": "Nepovoleno",
@@ -1664,6 +1726,7 @@
"organize_into_albums": "Organizovat do alb",
"organize_into_albums_description": "Umístit existující fotky do alb s použitím aktuálního nastavení synchronizace",
"organize_your_library": "Uspořádejte si knihovnu",
"orientation": "Orientace",
"original": "originál",
"other": "Ostatní",
"other_devices": "Ostatní zařízení",
@@ -1755,6 +1818,8 @@
"play_original_video_setting_description": "Upřednostňujte přehrávání originálních videí před překódovanými videi. Pokud originální soubor není kompatibilní, nemusí se přehrávat správně.",
"play_transcoded_video": "Přehrát překódované video",
"please_auth_to_access": "Pro přístup se prosím ověřte",
"plugin_method_filter_type": "Filtr",
"plugin_method_filter_type_description": "Tato metoda umožňuje filtrovat události a podmíněně zabránit spuštění dalších kroků",
"port": "Port",
"preferences_settings_subtitle": "Správa předvoleb aplikace",
"preferences_settings_title": "Předvolby",
@@ -1776,6 +1841,7 @@
"profile_drawer_readonly_mode": "Režim jen pro čtení. Ukončíte ho dlouhým podržením ikony avataru.",
"profile_image_of_user": "Profilový obrázek uživatele {user}",
"profile_picture_set": "Profilový obrázek nastaven.",
"projection_type": "Typ projekce",
"public_album": "Veřejné album",
"public_share": "Veřejné sdílení",
"purchase_account_info": "Podporovatel",
@@ -1853,6 +1919,7 @@
"remove_assets_title": "Odstranit položky?",
"remove_custom_date_range": "Odstranit vlastní rozsah dat",
"remove_deleted_assets": "Odstranit offline soubory",
"remove_filter": "Odstranit filtr",
"remove_from_album": "Odstranit z alba",
"remove_from_album_action_prompt": "{count} odstraněných z alba",
"remove_from_favorites": "Odstranit z oblíbených",
@@ -1926,6 +1993,8 @@
"scan_settings": "Nastavení prohledávání",
"scanning": "Prohládává se",
"scanning_for_album": "Prohledávání alba...",
"screencast_mode_description": "Zobrazit na obrazovce indikátory událostí klávesnice a myši",
"screencast_mode_title": "Přepnout režim screencastu",
"search": "Hledat",
"search_albums": "Vyhledávejte alba",
"search_by_context": "Vyhledávání podle obsahu",
@@ -1933,6 +2002,8 @@
"search_by_description_example": "Pěší turistika v Sapě",
"search_by_filename": "Vyhledávání podle názvu nebo přípony souboru",
"search_by_filename_example": "např. IMG_1234.JPG nebo PNG",
"search_by_full_path": "Hledat podle celé cesty nebo složky",
"search_by_full_path_example": "/Jan/Projekty/3D_tisk/2026-07-01 můžete hledat Projekty, 3D, tisk, 2026 apod.",
"search_by_ocr": "Hledat pomocí OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Vyhledat model objektivu...",
@@ -2140,7 +2211,9 @@
"show_in_timeline": "Zobrazit na časové ose",
"show_in_timeline_setting_description": "Zobrazit fotky a videa tohoto uživatele na časové ose",
"show_keyboard_shortcuts": "Zobrazit klávesové zkratky",
"show_less": "Zobrazit méně",
"show_metadata": "Zobrazit metadata",
"show_more_fields": "{count, plural, one {Zobrazit # další pole} few {Zobrazit # další pole} other {Zobrazit # dalších polí}}",
"show_or_hide_info": "Zobrazit nebo skrýt informace",
"show_password": "Zobrazit heslo",
"show_person_options": "Zobrazit možnosti osoby",
@@ -2148,6 +2221,7 @@
"show_schema": "Zobrazit schéma",
"show_search_options": "Zobrazit možnosti vyhledávání",
"show_shared_links": "Zobrazit sdílené odkazy",
"show_slideshow_metadata_overlay": "Zobrazit překryvné informace k obrázku",
"show_slideshow_transition": "Zobrazit přechod prezentace",
"show_supporter_badge": "Odznak podporovatele",
"show_supporter_badge_description": "Zobrazit odznak podporovatele",
@@ -2163,9 +2237,13 @@
"skip_to_folders": "Přeskočit na složky",
"skip_to_tags": "Přeskočit na značky",
"slideshow": "Prezentace",
"slideshow_metadata_overlay_mode": "Obsah překryvného panelu",
"slideshow_metadata_overlay_mode_description_only": "Pouze popis",
"slideshow_metadata_overlay_mode_full": "Úplný",
"slideshow_repeat": "Opakovat prezentaci",
"slideshow_repeat_description": "Po skončení prezentace se vrátit na začátek",
"slideshow_settings": "Nastavení prezentace",
"smart_album": "Chytré album",
"sort_albums_by": "Seřadit alba podle...",
"sort_created": "Datum vytvoření",
"sort_items": "Počet položek",
@@ -2188,6 +2266,11 @@
"start_date_before_end_date": "Počáteční datum se musí nacházet před konečným datem",
"state": "Stát",
"status": "Stav",
"step_delete": "Odstranit krok",
"step_delete_confirm": "Opravdu chcete odstranit tento krok?",
"step_details": "Podrobnosti o kroku",
"steps": "Kroky",
"steps_count": "{count, plural, one {# krok} few {# kroky} other {# kroků}}",
"stop_casting": "Zastavit odesílání",
"stop_motion_photo": "Zastavit pohyblivou fotografii",
"stop_photo_sharing": "Přestat sdílet své fotografie?",
@@ -2214,6 +2297,8 @@
"sync_status": "Stav synchronizace",
"sync_status_subtitle": "Zobrazit a spravovat synchronizační systém",
"sync_upload_album_setting_subtitle": "Vytvořit a nahrát fotografie a videa do vybraných alb na Immich",
"system_theme": "Vzhled systému",
"system_theme_command_description": "Použít systémové téma ({value})",
"tag": "Značka",
"tag_assets": "Přiřadit značku",
"tag_created": "Vytvořena značka: {tag}",
@@ -2279,7 +2364,7 @@
"trash_page_title": "Koš ({count})",
"trashed_items_will_be_permanently_deleted_after": "Smazané položky budou trvale odstraněny po {days, plural, one {# dni} other {# dnech}}.",
"trigger": "Spouštěč",
"trigger_asset_uploaded": "Položka nahrána",
"trigger_asset_uploaded": "Nahrání položky",
"trigger_asset_uploaded_description": "Spustí se při nahrání nového souboru",
"trigger_description": "Událost, která spustí pracovní postup",
"trigger_person_recognized": "Osoba rozpoznána",
@@ -2319,7 +2404,6 @@
"unsupported_field_type": "Nepodporovaný typ pole",
"unsupported_file_type": "Soubor {file} nelze nahrát, protože jeho typ {type} není podporován.",
"untagged": "Neoznačeno",
"untitled_workflow": "Pracovní postup bez názvu",
"up_next": "To je prozatím vše",
"update_location_action_prompt": "Aktualizovat polohu {count} vybraných položek pomocí:",
"updated_at": "Aktualizováno",
@@ -2348,6 +2432,7 @@
"use_browser_locale_description": "Formátujte data, časy a čísla podle nastavení místního formátu vašeho prohlížeče",
"use_current_connection": "Použít aktuální připojení",
"use_custom_date_range": "Použít vlastní rozsah dat",
"use_template": "Použít šablonu",
"user": "Uživatel",
"user_has_been_deleted": "Tento uživatel byl smazán.",
"user_id": "ID uživatele",
@@ -2377,6 +2462,7 @@
"video": "Video",
"video_hover_setting": "Přehrávat miniaturu videa po najetí myší",
"video_hover_setting_description": "Přehrát miniaturu videa při najetí myší na položku. I když je přehrávání vypnuto, lze jej spustit najetím na ikonu přehrávání.",
"video_quality": "Kvalita videa",
"videos": "Videa",
"videos_count": "{count, plural, one {# video} few {# videa} other {# videí}}",
"videos_only": "Pouze videa",
@@ -2409,8 +2495,10 @@
"week": "Týden",
"welcome": "Vítejte",
"welcome_to_immich": "Vítejte v Immichi",
"when": "Kdy",
"width": "Šířka",
"wifi_name": "Název Wi-Fi",
"workflow": "Workflow",
"workflow_delete_prompt": "Opravdu chcete tento pracovní postup smazat?",
"workflow_deleted": "Pracovní postup smazán",
"workflow_description": "Popis pracovního postupu",
@@ -2420,11 +2508,13 @@
"workflow_name": "Název pracovního postupu",
"workflow_navigation_prompt": "Opravdu chcete odejít bez uložení změn?",
"workflow_summary": "Shrnutí pracovního postupu",
"workflow_templates": "Šablony pracovních postupů",
"workflow_update_success": "Pracovní postup byl úspěšně aktualizován",
"workflow_updated": "Pracovní postup aktualizován",
"workflows": "Pracovní postupy",
"workflows_help_text": "Pracovní postupy automatizují akce týkající se vašich položek na základě spouštěčů a filtrů",
"wrong_pin_code": "Chybný PIN kód",
"x_of_total": "{x}/{total}",
"year": "Rok",
"years_ago": "Před {years, plural, one {rokem} other {# lety}}",
"yes": "Ano",
+95 -17
View File
@@ -22,13 +22,12 @@
"add_birthday": "Tilføj en fødselsdag",
"add_endpoint": "Tilføj endepunkt",
"add_exclusion_pattern": "Tilføj udelukkelsesmønster",
"add_filter": "Tilføj filter",
"add_filter_description": "Klik for at tilføje en filterbetingelse",
"add_location": "Tilføj placering",
"add_more_users": "Tilføj flere brugere",
"add_partner": "Tilføj partner",
"add_path": "Tilføj sti",
"add_photos": "Tilføj billeder",
"add_step": "Tilføj trin",
"add_tag": "Tilføj tag",
"add_to": "Tilføj til…",
"add_to_album": "Tilføj til album",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Tilføj til delt album",
"add_upload_to_stack": "Tilføj upload til stack",
"add_url": "Tilføj URL",
"add_workflow_step": "Tilføj workflow-trin",
"added_to_archive": "Tilføjet til arkiv",
"added_to_favorites": "Tilføjet til favoritter",
"added_to_favorites_count": "Tilføjede {count, number} til favoritter",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "Slå emailnotifikationer til",
"notification_settings": "Notifikationsindstillinger",
"notification_settings_description": "Administrer notifikationsindstillinger, inklusiv email",
"oauth_allow_insecure_requests": "Tillad usikre anmodninger",
"oauth_allow_insecure_requests_description": "ADVARSEL: Dette deaktiverer TLS-certificering for OAuth anmodninger og kan udsætte dig for MITM angreb.",
"oauth_auto_launch": "Auto-opstart",
"oauth_auto_launch_description": "Påbegynd OAuth login-flow automatisk når loginsiden tilgås",
"oauth_auto_register": "Autoregistrér",
@@ -274,9 +274,11 @@
"oauth_button_text": "Knaptekst",
"oauth_client_secret_description": "Påkrævet for en fortrolig klient eller hvis PKCE (Proof Key for Code Exchange) ikke understøttes for en offentlig klient.",
"oauth_enable_description": "Log ind med OAuth",
"oauth_end_session_url_description": "Omdiriger brugeren til denne URI, når de logger ud.",
"oauth_mobile_redirect_uri": "Mobilomdiregerings-URL",
"oauth_mobile_redirect_uri_override": "Tilsidesættelse af mobil omdiregerings-URL",
"oauth_mobile_redirect_uri_override_description": "Aktiver, når OAuth-udbyderen ikke tillader en mobil URI, som ''{callback}''",
"oauth_prompt_description": "Prompt-parameter (f.eks. select_account, login, consent)",
"oauth_role_claim": "Rolle attribut",
"oauth_role_claim_description": "Tildel automatisk admin adgang på basis af forekomst af denne påstand. Dén kan være enten 'user' eller 'admin'.",
"oauth_settings": "OAuth",
@@ -696,6 +698,7 @@
"birthdate_saved": "Fødselsdatoen blev gemt",
"birthdate_set_description": "Fødselsdato bruges til at beregne denne persons alder på det tidspunkt, et billede er taget.",
"blurred_background": "Sløret baggrund",
"browse_templates": "Gennemse skabeloner",
"bugs_and_feature_requests": "Fejl & forbedringsønsker",
"build": "Byg",
"build_image": "Byggefil",
@@ -729,6 +732,7 @@
"cannot_update_the_description": "Kan ikke opdatere beskrivelsen",
"cast": "Caste",
"cast_description": "Konfigurer tilgængelige cast destinationer",
"change": "Ændr",
"change_date": "Ændr dato",
"change_description": "Ændr beskrivelse",
"change_display_order": "Ændrer visningsrækkefølge",
@@ -757,6 +761,7 @@
"check_corrupt_asset_backup_description": "Kør kun denne kontrol via Wi-Fi, og når alle elementer er blevet sikkerhedskopieret. Proceduren kan tage et par minutter.",
"check_logs": "Tjek logfiler",
"checksum": "Checksum",
"choose": "Vælg",
"choose_matching_people_to_merge": "Vælg matchende personer til sammenfletning",
"city": "By",
"cleanup_confirm_description": "Immich fandt {count} assets (oprettet før {date}) sikkert sikkerhedskopieret til serveren. Fjern de lokale kopier fra denne enhed?",
@@ -774,6 +779,7 @@
"clear": "Ryd",
"clear_all": "Ryd alle",
"clear_all_recent_searches": "Ryd alle seneste søgninger",
"clear_failed_count": "Ryd mislykkede ({count})",
"clear_file_cache": "Ryd filcache",
"clear_message": "Ryd bedsked",
"clear_value": "Ryd værdi",
@@ -805,6 +811,7 @@
"comments_are_disabled": "Kommentarer er slået fra",
"common_create_new_album": "Opret et nyt album",
"completed": "Fuldført",
"configuration": "Konfiguration",
"confirm": "Bekræft",
"confirm_admin_password": "Bekræft administratoradgangskode",
"confirm_delete_face": "Er du sikker på, du vil slette {name}s ansigt fra denne mediefil?",
@@ -819,6 +826,7 @@
"contain": "Inddæm",
"context": "Kontekst",
"continue": "Fortsæt",
"control_bottom_app_bar_add_tags": "Tilføj Tags",
"control_bottom_app_bar_create_new_album": "Opret nyt album",
"control_bottom_app_bar_delete_from_immich": "Slet fra Immich",
"control_bottom_app_bar_delete_from_local": "Slet fra enhed",
@@ -832,6 +840,7 @@
"copy_error": "Kopifejl",
"copy_file_path": "Kopiér filsti",
"copy_image": "Kopiér billede",
"copy_json": "Kopier JSON",
"copy_link": "Kopiér link",
"copy_link_to_clipboard": "Kopiér link til udklipsholder",
"copy_password": "Kopier adgangskode",
@@ -881,17 +890,16 @@
"cutoff_date_description": "Behold fotos fra den sidste…",
"cutoff_day": "{count, plural, one {dag} other {dage}}",
"cutoff_year": "{count, plural, one {år} other {år}}",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Mørk",
"dark_theme": "Skift til mørkt tema",
"date": "Dato",
"date_after": "Dato efter",
"date_and_time": "Dato og klokkeslæt",
"date_before": "Dato før",
"date_format": "E d. LLL y • hh:mm",
"date_of_birth": "Fødselsdag",
"date_of_birth_saved": "Fødselsdatoen blev gemt korrekt",
"date_range": "Datointerval",
"date_time_original": "Dato/Tid Original",
"day": "Dag",
"days": "Dage",
"deduplicate_all": "Dedubliker alle",
@@ -970,9 +978,12 @@
"downloading_asset_filename": "Downloader mediefil {filename}",
"downloading_from_icloud": "Downloading fra iCloud",
"downloading_media": "Download medier",
"drag_to_reorder": "Træk for at ændre rækkefølgen",
"drop_files_to_upload": "Slip filer hvor som helst for at uploade dem",
"duplicate": "Duplikere",
"duplicate_workflow": "Duplikeret arbejdsgang",
"duplicates": "Duplikater",
"duplicates_description": "Løs hver gruppe ved at angive hvilke, hvis nogen, er dubletter",
"duplicates_description": "Løs hver gruppe ved at angive hvilke, hvis nogen, er dubletter.",
"duration": "Varighed",
"edit": "Rediger",
"edit_album": "Redigér album",
@@ -998,7 +1009,7 @@
"edit_title": "Redigér titel",
"edit_user": "Redigér bruger",
"edit_workflow": "Rediger workflow",
"editor": "Redaktør",
"editor": "Rediger",
"editor_close_without_save_prompt": "Ændringerne vil ikke blive gemt",
"editor_close_without_save_title": "Luk editor?",
"editor_confirm_reset_all_changes": "Er du sikker på, at du vil nulstille alle ændringer?",
@@ -1072,6 +1083,7 @@
"failed_to_remove_product_key": "Fjernelse af produktnøgle mislykkedes",
"failed_to_reset_pin_code": "Kunne ikke resette PIN-koden",
"failed_to_stack_assets": "Det lykkedes ikke at stable mediefiler",
"failed_to_tag_assets": "Kunne ikke tagge mediefiler",
"failed_to_unstack_assets": "Det lykkedes ikke at fjerne gruperingen af mediefiler",
"failed_to_update_notification_status": "Kunne ikke uploade notifikations status",
"incorrect_email_or_password": "Forkert email eller kodeord",
@@ -1191,11 +1203,13 @@
"export_as_json": "Eksportér som JSON",
"export_database": "Eksporter database",
"export_database_description": "Eksporter SQLite databasen",
"exposure_time": "Eksponeringstid",
"extension": "Udvidelse",
"external": "Ekstern",
"external_libraries": "Eksterne biblioteker",
"external_network": "Eksternt netværk",
"external_network_sheet_info": "Nå der er ikke er forbundet til det foretrukne Wi-Fi netværk, vil appen forbinde til den første URL den kan forbinde til, på listen nedenfor. Startende fra toppen",
"f_number": "F-Nummer",
"face_unassigned": "Ikke tildelt",
"failed": "Fejlet",
"failed_count": "Fejlede: {count}",
@@ -1213,7 +1227,6 @@
"features_setting_description": "Administrer app-funktioner",
"file_name_or_extension": "Filnavn eller filtype",
"file_name_text": "Filnavn",
"file_name_with_value": "Filnavn: {file_name}",
"file_size": "Fil størrelse",
"filename": "Filnavn",
"filetype": "Filtype",
@@ -1226,6 +1239,7 @@
"find_them_fast": "Find dem hurtigt med søgning via navn",
"first": "Første",
"fix_incorrect_match": "Fix forkert match",
"focal_length": "Brændvidde",
"folder": "Mappe",
"folder_not_found": "Mappe ikke fundet",
"folders": "Mapper",
@@ -1236,6 +1250,7 @@
"free_up_space_description": "Flyt sikkerhedskopierede fotos og videoer til din enheds skraldespand for at frigøre plads. Dine kopier på serveren forbliver sikre.",
"free_up_space_settings_subtitle": "Frigør enhedslagerplads",
"full_path": "Fuld sti: {path}",
"full_path_or_folder": "Fuld sti eller mappe",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Denne funktion indlæser eksterne ressourcer fra Google for at virke.",
"general": "Generel",
@@ -1345,6 +1360,7 @@
"ios_debug_info_no_sync_yet": "Der er endnu ikke kørt noget baggrundssynkroniseringsjob",
"ios_debug_info_processes_queued": "{count, plural, one {{count} baggrundsproces i kø} other {{count} baggrundsprocesser i kø}}",
"ios_debug_info_processing_ran_at": "Behandlingen kørte {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# element} other {# elementer}}",
"jobs": "Opgaver",
"json_editor": "JSON editor",
@@ -1392,11 +1408,13 @@
"light_theme": "Skift til lyst tema",
"like": "Synes om",
"like_deleted": "Ligesom slettet",
"link": "Link",
"link_motion_video": "Link bevægelsesvideo",
"link_to_docs": "For yderligere information, se <link>dokumentationen</link>.",
"link_to_oauth": "Link til OAuth",
"linked_oauth_account": "Tilsluttet OAuth-konto",
"list": "Liste",
"live": "Live",
"loading": "Indlæser",
"loading_search_results_failed": "Indlæsning af søgeresultater fejlede",
"local": "Lokal",
@@ -1518,7 +1536,39 @@
"marked_all_as_read": "Markerede alle som læst",
"matches": "Parringer",
"matching_assets": "Matchende objekter",
"media_type": "Medietype",
"media_chrome": {
"auto": "Auto",
"captions": "Undertekster",
"captions_off": "Fra",
"closed_captions": "Undertekster for hørehæmmede",
"decode_error": "Fejl ved dekodning",
"disable_captions": "Slå undertekster fra",
"enable_captions": "Slå undertekster til",
"enter_fullscreen_mode": "Fuld skærm",
"exit_fullscreen_mode": "Luk fuld skærm",
"loop": "Gentag",
"media_error_description": "En mediefejl stoppede afspilningen. Filen kan være korrupt eller browseren understøtter ikke filtypen.",
"media_loading": "Loader medie",
"mute": "Sluk lyd",
"network_error": "Netværksfejl",
"network_error_description": "En netværksfejl fik download til at fejle.",
"not_supported_error": "Kilde er ikke understøttet",
"playback_rate": "Afspilningshastighed",
"playback_rate_current": "nuværende afspilningshastighed",
"playback_rate_value": "Afspilningshastighed {playbackRate}",
"playback_time": "afspilnings varighed",
"quality": "Kvalitet",
"second": "sekund",
"seconds": "sekunder",
"time_value_of_total_time": "{currentTime} af {totalTime}",
"time_value_remaining": "{time} tilbage",
"unmute": "Lyd til",
"unsupported_error_description": "En ukendt fejl opstod. Fejl på server, netværk eller din browser understøtter ikke formatet.",
"video_not_loaded_unknown_time": "video er ikke indlæst, ukendt tidspunkt.",
"video_player": "videoafspiller",
"volume": "lydstyrke"
},
"media_type": "Medieformat",
"memories": "Minder",
"memories_all_caught_up": "Ajour",
"memories_check_back_tomorrow": "Kom tilbage i morgen for at se nye minder",
@@ -1543,9 +1593,10 @@
"mobile_app": "Mobil App",
"mobile_app_download_onboarding_note": "Hent den tilhørende mobilapp via en af følgende muligheder",
"model": "Model",
"modify_date": "Ændre dato",
"month": "Måned",
"monthly_title_text_date_format": "MMMM å",
"more": "Mere",
"motion": "Bevægelse",
"move": "Flyt",
"move_down": "Flyt ned",
"move_off_locked_folder": "Flyt ud af låst mappe",
@@ -1562,6 +1613,8 @@
"multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af skrivebeskyttet elementer. Springer over",
"mute_memories": "Dæmp minder",
"my_albums": "Mine albummer",
"my_immich_description": "Kopier aktuel side som et Mit Immich link",
"my_immich_title": "Mit Immich link",
"name": "Navn",
"name_or_nickname": "Navn eller kaldenavn",
"name_required": "Navn er påkrævet",
@@ -1589,7 +1642,6 @@
"next": "Næste",
"next_memory": "Næste minde",
"no": "Nej",
"no_actions_added": "Ingen handlinger tilføjet endnu",
"no_albums_found": "Ingen album fundet",
"no_albums_message": "Opret et album for at organisere dine billeder og videoer",
"no_albums_with_name_yet": "Det ser ud til, at du ikke har noget album med dette navn endnu.",
@@ -1606,7 +1658,6 @@
"no_exif_info_available": "Ingen tilgængelig exif information",
"no_explore_results_message": "Upload flere billeder for at udforske din samling.",
"no_favorites_message": "Tilføj favoritter for hurtigt at finde dine bedst billeder og videoer",
"no_filters_added": "Ingen filtre tilføjet endnu",
"no_libraries_message": "Opret et eksternt bibliotek for at se dine billeder og videoer",
"no_local_assets_found": "Ingen lokale objekter fundet med denne checksum",
"no_location_set": "Ingen placering sat",
@@ -1619,6 +1670,7 @@
"no_results": "Ingen resultater",
"no_results_description": "Prøv et synonym eller et mere generelt søgeord",
"no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk",
"no_steps": "Ingen trin tilføjet endnu",
"no_uploads_in_progress": "Ingen upload i gang",
"none": "Ingen",
"not_allowed": "Ikke tilladt",
@@ -1664,6 +1716,7 @@
"organize_into_albums": "Organiser i album",
"organize_into_albums_description": "Sæt eksisterende billeder i albummer ved hjælp af aktuelle synkroniseringsindstillinger",
"organize_your_library": "Organisér dit bibliotek",
"orientation": "Orientering",
"original": "original",
"other": "Andet",
"other_devices": "Andre enheder",
@@ -1755,6 +1808,8 @@
"play_original_video_setting_description": "Foretrækker afspilning af originale videoer frem for transkodede videoer. Hvis det originale element ikke er kompatibelt, afspilles det muligvis ikke korrekt.",
"play_transcoded_video": "Afspil transkodet video",
"please_auth_to_access": "Log venligst ind for at tilgå",
"plugin_method_filter_type": "Filter",
"plugin_method_filter_type_description": "Denne metode kan filtrere hændelser og betinget forhindre efterfølgende trin i at køre",
"port": "Port",
"preferences_settings_subtitle": "Administrer appens indstillinger",
"preferences_settings_title": "Præferencer",
@@ -1776,6 +1831,7 @@
"profile_drawer_readonly_mode": "Skrivebeskyttet tilstand aktiveret. Lang tryk på bruger avatar ikonet for at afslutte.",
"profile_image_of_user": "Profilbillede af {user}",
"profile_picture_set": "Profilbillede indstillet.",
"projection_type": "Projektionstype",
"public_album": "Offentligt album",
"public_share": "Offentlig deling",
"purchase_account_info": "Supporter",
@@ -1853,6 +1909,7 @@
"remove_assets_title": "Fjern mediefiler?",
"remove_custom_date_range": "Fjern tilpasset datointerval",
"remove_deleted_assets": "Fjern slettede mediefiler",
"remove_filter": "Fjern filter",
"remove_from_album": "Fjern fra album",
"remove_from_album_action_prompt": "{count} fjernet fra albummet",
"remove_from_favorites": "Fjern fra favoritter",
@@ -1908,7 +1965,7 @@
"review_duplicates": "Gennemgå dubletter",
"review_large_files": "Gennemgå store filer",
"role": "Rolle",
"role_editor": "Redaktør",
"role_editor": "Rediger",
"role_viewer": "Seer",
"running": "Kører",
"save": "Gem",
@@ -1926,6 +1983,8 @@
"scan_settings": "Skanningsindstillinger",
"scanning": "Skanner",
"scanning_for_album": "Skanner efter albummer...",
"screencast_mode_description": "Vis indikatorer for tastatur- og musehændelse på skærmen",
"screencast_mode_title": "Skift skærmcast-tilstand",
"search": "Søg",
"search_albums": "Søg i albummer",
"search_by_context": "Søg efter kontekst",
@@ -1933,6 +1992,8 @@
"search_by_description_example": "Vandredag i Paris",
"search_by_filename": "Søg efter filnavn eller filtypenavn",
"search_by_filename_example": "dvs. IMG_1234.JPG eller PNG",
"search_by_full_path": "søg efter fuld sti eller mappe",
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - du kan søge efter Projects, 3D, Printing, 2026 osv.",
"search_by_ocr": "Søg via OCR",
"search_by_ocr_example": "Søg efter tekst i dine billeder",
"search_camera_lens_model": "Søg objektiv model...",
@@ -2101,7 +2162,7 @@
"shared_link_edit_expire_after_option_year": "{count} år",
"shared_link_edit_password_hint": "Indtast kodeordet",
"shared_link_edit_submit_button": "Opdater link",
"shared_link_error_server_url_fetch": "Kan ikke hente server URL",
"shared_link_error_server_url_fetch": "Kan ikke hente server url",
"shared_link_expires_day": "Udløber om {count} dag",
"shared_link_expires_days": "Udløber om {count} dage",
"shared_link_expires_hour": "Udløber om {count} time",
@@ -2140,7 +2201,9 @@
"show_in_timeline": "Vis på tidslinje",
"show_in_timeline_setting_description": "Vis billeder og videoer fra denne bruger på din tidslinje",
"show_keyboard_shortcuts": "Vis tastaturgenveje",
"show_less": "Vis mindre",
"show_metadata": "Vis metadata",
"show_more_fields": "{count, plural, one {Vis # mere felt} other {Vis # flere felter}}",
"show_or_hide_info": "Vis eller skjul info",
"show_password": "Vis adgangskode",
"show_person_options": "Vis personindstillinger",
@@ -2148,6 +2211,7 @@
"show_schema": "Vis skema",
"show_search_options": "Vis søgeindstillinger",
"show_shared_links": "Vis delte links",
"show_slideshow_metadata_overlay": "Vis billedinfo-overlay",
"show_slideshow_transition": "Vis overgang til diasshow",
"show_supporter_badge": "Supporter skilt",
"show_supporter_badge_description": "Vis et supporter ikon",
@@ -2163,6 +2227,9 @@
"skip_to_folders": "Spring til mapper",
"skip_to_tags": "Spring til tags",
"slideshow": "Diasshow",
"slideshow_metadata_overlay_mode": "Overlay indhold",
"slideshow_metadata_overlay_mode_description_only": "Kun beskrivelse",
"slideshow_metadata_overlay_mode_full": "Fuld",
"slideshow_repeat": "Gentag diasshow",
"slideshow_repeat_description": "Hop tilbage til begyndelsen når diasshow stopper",
"slideshow_settings": "Diasshowindstillinger",
@@ -2188,6 +2255,11 @@
"start_date_before_end_date": "Startdato skal ligge før slutdato",
"state": "Stat",
"status": "Status",
"step_delete": "Slet trin",
"step_delete_confirm": "Er du sikker på, at du vil slette dette trin?",
"step_details": "Trin detaljer",
"steps": "Trin",
"steps_count": "{count, plural, one {# trin} other {# trin}}",
"stop_casting": "Stop med at caste",
"stop_motion_photo": "Stopmotionbillede",
"stop_photo_sharing": "Stop med at dele dine billeder?",
@@ -2214,6 +2286,8 @@
"sync_status": "Synkroniserings Status",
"sync_status_subtitle": "Se og administrér synkroniseringssystemet",
"sync_upload_album_setting_subtitle": "Opret og upload dine billeder og videoer til de valgte albummer i Immich",
"system_theme": "Systemtema",
"system_theme_command_description": "Brug systemtemaet ({value})",
"tag": "Tag",
"tag_assets": "Tag mediefiler",
"tag_created": "Oprettet tag: {tag}",
@@ -2279,7 +2353,7 @@
"trash_page_title": "Papirkurv ({count})",
"trashed_items_will_be_permanently_deleted_after": "Mediefiler i papirkurven vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.",
"trigger": "Udløser",
"trigger_asset_uploaded": "Mediefil uploaded",
"trigger_asset_uploaded": "Mediefil upload",
"trigger_asset_uploaded_description": "Udløses, når et nyt asset bliver uploaded",
"trigger_description": "En begivenhed, der starter en arbejdsgang",
"trigger_person_recognized": "Peron genkendt",
@@ -2319,7 +2393,6 @@
"unsupported_field_type": "Ikke-understøttet felttype",
"unsupported_file_type": "Filen {file} kan ikke uploades, fordi filtypen {type} ikke understøttes.",
"untagged": "Umærket",
"untitled_workflow": "Unavngivet arbejdsgang",
"up_next": "Næste",
"update_location_action_prompt": "Opdater lokationen for {count} valgte objekter med:",
"updated_at": "Opdateret",
@@ -2348,6 +2421,7 @@
"use_browser_locale_description": "Formatér datoer, klokkeslæt og tal baseret på din browsers lokalitet",
"use_current_connection": "Brug nuværende forbindelse",
"use_custom_date_range": "Brug tilpasset datointerval i stedet",
"use_template": "Brug skabelon",
"user": "Bruger",
"user_has_been_deleted": "Denne bruger er slettet.",
"user_id": "Bruger-ID",
@@ -2409,8 +2483,10 @@
"week": "Uge",
"welcome": "Velkommen",
"welcome_to_immich": "Velkommen til Immich",
"when": "Hvornår",
"width": "Bredde",
"wifi_name": "Wi-Fi navn",
"workflow": "Arbejdsgang",
"workflow_delete_prompt": "Er du sikker på, at du vil slette denne arbejdsgang?",
"workflow_deleted": "Arbejdsgang slettet",
"workflow_description": "Arbejdsgangsbeskrivelse",
@@ -2420,11 +2496,13 @@
"workflow_name": "Navn på arbejdsgang",
"workflow_navigation_prompt": "Er du sikker på, at du vil forlade uden at gemme dine ændringer?",
"workflow_summary": "Arbejdsgangsoversigt",
"workflow_templates": "Arbejdsgangsskabeloner",
"workflow_update_success": "Arbejdsgang opdateret korrekt",
"workflow_updated": "Arbejdsgang opdateret",
"workflows": "Arbejdsgange",
"workflows_help_text": "Arbejdsgange automatiserer handlinger på dine filer baseret på udløsere og filtre",
"wrong_pin_code": "Forkert PIN kode",
"x_of_total": "{x}/{total}",
"year": "År",
"years_ago": "{years, plural, one {# år} other {# år}} siden",
"yes": "Ja",
+114 -24
View File
@@ -1,8 +1,8 @@
{
"about": "Über",
"about": "Über Immich",
"account": "Konto",
"account_settings": "Kontoeinstellungen",
"acknowledge": "Verstanden",
"acknowledge": "Schließen",
"action": "Aktion",
"action_common_update": "Aktualisieren",
"action_description": "Eine Reihe von Aktionen, die an den gefilterten Assets ausgeführt werden sollen",
@@ -22,13 +22,12 @@
"add_birthday": "Geburtsdatum hinzufügen",
"add_endpoint": "Endpunkt hinzufügen",
"add_exclusion_pattern": "Ausschlussmuster hinzufügen",
"add_filter": "Filter hinzufügen",
"add_filter_description": "Klicken um eine Filterbedingung hinzuzufügen",
"add_location": "Standort hinzufügen",
"add_more_users": "Weitere Nutzer hinzufügen",
"add_partner": "Partner hinzufügen",
"add_path": "Pfad hinzufügen",
"add_photos": "Fotos hinzufügen",
"add_step": "Schritt hinzufügen",
"add_tag": "Tag hinzufügen",
"add_to": "Hinzufügen zu …",
"add_to_album": "Zu Album hinzufügen",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Zu geteiltem Album hinzufügen",
"add_upload_to_stack": "Upload zum Stapel hinzufügen",
"add_url": "URL hinzufügen",
"add_workflow_step": "Workflow-Schritt hinzufügen",
"added_to_archive": "Zum Archiv hinzugefügt",
"added_to_favorites": "Zu Favoriten hinzugefügt",
"added_to_favorites_count": "{count, number} zu Favoriten hinzugefügt",
@@ -78,7 +76,7 @@
"copy_config_to_clipboard_description": "Kopieren Sie die aktuelle Systemkonfiguration als JSON-Objekt in die Zwischenablage",
"create_job": "Aufgabe erstellen",
"cron_expression": "Cron-Ausdruck",
"cron_expression_description": "Setze das Scanintervall im Cron-Format. Hilfe mit dem Format bietet dir dabei z. B. der <link>Crontab Guru</link>",
"cron_expression_description": "Legen Sie das Scanintervall im Cron-Format fest. Weitere Informationen finden Sie z. B. bei <link>Crontab Guru</link>",
"cron_expression_presets": "Vorlagen für Cron-Zeitangabe",
"disable_login": "Login deaktivieren",
"duplicate_detection_job_description": "Diese Aufgabe führt das maschinelle Lernen für jede Datei aus, um Duplikate zu finden. Diese Aufgabe beruht auf der intelligenten Suche",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "E-Mail-Benachrichtigungen aktivieren",
"notification_settings": "Benachrichtigungseinstellungen",
"notification_settings_description": "Benachrichtigungseinstellungen (inkl. E-Mail) verwalten",
"oauth_allow_insecure_requests": "Unsichere Anfragen erlauben",
"oauth_allow_insecure_requests_description": "WARNUNG: Dies deaktiviert die TLS-Zertifikatsvalidierung für OAuth-Anfragen und kann Sie MITM-Angriffen aussetzen.",
"oauth_auto_launch": "Auto-Start",
"oauth_auto_launch_description": "Automatischer Start des OAuth-Anmeldevorgangs beim Aufrufen der Anmeldeseite",
"oauth_auto_register": "Automatische Registrierung",
@@ -274,9 +274,11 @@
"oauth_button_text": "Button-Text",
"oauth_client_secret_description": "Erforderlich für Confidential Clients oder wenn PKCE (Proof Key for Code Exchange) nicht für Public Clients unterstützt wird.",
"oauth_enable_description": "Anmeldung mit OAuth",
"oauth_end_session_url_description": "Leite den Benutzer nach dem Abmelden zu dieser URI weiter.",
"oauth_mobile_redirect_uri": "Mobile Umleitungs-URI",
"oauth_mobile_redirect_uri_override": "Mobile Umleitungs-URI überschreiben",
"oauth_mobile_redirect_uri_override_description": "Einschalten, wenn der OAuth-Anbieter keine mobile URI wie ''{callback}'' erlaubt",
"oauth_prompt_description": "Eingabe Parameter (z. B. Konto auswählen, Login, Einwilligung)",
"oauth_role_claim": "Rollen-Claim",
"oauth_role_claim_description": "Gewähre automatisch Admin-Zugriff basierend auf dem Vorhandensein dieses Claims. Der Claim kann entweder 'user' oder 'admin' sein.",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "Alle Bibliotheken aktualisieren",
"registration": "Admin-Registrierung",
"registration_description": "Da du der erste Benutzer im System bist, wird dir die Rolle des Administrators zugewiesen, womit du für die Verwaltungsaufgaben verantwortlich bist. Weitere Benutzer werden von dir erstellt.",
"release_channel_release_candidate": "Release Candidate",
"release_channel_stable": "Stabil",
"remove_failed_jobs": "Entferne fehlgeschlagene Aufgaben",
"require_password_change_on_login": "Benutzer muss das Passwort beim ersten Login ändern",
"reset_settings_to_default": "Einstellungen auf Standard zurücksetzen",
@@ -397,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "Gilt nur für VAAPI und QSV. Legt den für die Hardware-Transkodierung verwendeten dri-Node fest.",
"transcoding_preset_preset": "Voreinstellung (-preset)",
"transcoding_preset_preset_description": "Komprimierungsgeschwindigkeit. Eine langsamere Voreinstellungen erzeugt kleinere Dateien und erhöht die Qualität, wenn man eine gewisse Bitrate anstrebt. VP9 ignoriert Geschwindigkeiten über „Schneller“.",
"transcoding_realtime": "Echtzeit-Transkodierung [EXPERIMENTELL]",
"transcoding_realtime_description": "Ermöglicht die Transkodierung in Echtzeit während des Videostreams. Ermöglicht einen Qualitätswechsel, kann jedoch je nach Serverkapazität zu einer höheren Wiedergabelatenz und Rucklern führen.",
"transcoding_realtime_enabled": "Echtzeit-Transkodierung aktivieren",
"transcoding_realtime_enabled_description": "Wenn diese Option deaktiviert ist, lehnt der Server den Start neuer Echtzeit-Transkodierungssitzungen ab.",
"transcoding_reference_frames": "Referenz-Frames",
"transcoding_reference_frames_description": "Die Anzahl der Bilder, auf die bei der Komprimierung eines bestimmten Bildes Bezug genommen wird. Höhere Werte verbessern die Komprimierungseffizienz, verlangsamen aber die Kodierung. 0 setzt diesen Wert automatisch.",
"transcoding_required_description": "Nur Videos in einem nicht akzeptierten Format",
@@ -440,6 +448,8 @@
"user_settings_description": "Benutzereinstellungen verwalten",
"user_successfully_removed": "Der Benutzer {email} wurde erfolgreich entfernt.",
"users_page_description": "Administrator-Benutzerseite",
"version_check_channel": "Release Kanal",
"version_check_channel_description": "Wählen Sie den Release-Kanal aus, für den Sie Versionsankündigungen erhalten möchten",
"version_check_enabled_description": "Versionsprüfung aktivieren",
"version_check_implications": "Die Funktion zur Versionsprüfung basiert auf regelmäßiger Kommunikation mit {server}",
"version_check_settings": "Versionsprüfung",
@@ -696,6 +706,7 @@
"birthdate_saved": "Geburtsdatum erfolgreich gespeichert",
"birthdate_set_description": "Das Geburtsdatum wird verwendet, um das Alter dieser Person zum Zeitpunkt eines Fotos zu berechnen.",
"blurred_background": "Unscharfer Hintergrund",
"browse_templates": "Vorlagen durchsuchen",
"bugs_and_feature_requests": "Fehler & Verbesserungsvorschläge",
"build": "Build",
"build_image": "Abbildversion",
@@ -729,6 +740,7 @@
"cannot_update_the_description": "Beschreibung kann nicht aktualisiert werden",
"cast": "Übertragen",
"cast_description": "Verfügbare Cast-Ziele konfigurieren",
"change": "Ändern",
"change_date": "Datum ändern",
"change_description": "Beschreibung anpassen",
"change_display_order": "Anzeigereihenfolge ändern",
@@ -757,6 +769,7 @@
"check_corrupt_asset_backup_description": "Führe diese Prüfung nur mit aktivierten WLAN durch, nachdem alle Dateien gesichert worden sind. Dieser Vorgang kann ein paar Minuten dauern.",
"check_logs": "Logs prüfen",
"checksum": "Prüfsumme",
"choose": "Wählen",
"choose_matching_people_to_merge": "Wähle passende Personen zum Zusammenführen",
"city": "Stadt",
"cleanup_confirm_description": "Immich hat {count} Dateien (vor dem {date} erstellt) sicher auf dem Server gefunden. Sollen die lokalen Kopien von diesem Gerät gelöscht werden?",
@@ -774,6 +787,7 @@
"clear": "Leeren",
"clear_all": "Alles leeren",
"clear_all_recent_searches": "Alle letzten Suchvorgänge löschen",
"clear_failed_count": "({count}) Löschungen fehlgeschlagen",
"clear_file_cache": "Dateien-Cache leeren",
"clear_message": "Nachrichten leeren",
"clear_value": "Wert leeren",
@@ -805,6 +819,7 @@
"comments_are_disabled": "Kommentare sind deaktiviert",
"common_create_new_album": "Neues Album erstellen",
"completed": "Abgeschlossen",
"configuration": "Konfiguration",
"confirm": "Bestätigen",
"confirm_admin_password": "Administrator Passwort bestätigen",
"confirm_delete_face": "Bist du sicher, dass du das Gesicht von {name} aus der Datei entfernen willst?",
@@ -819,6 +834,7 @@
"contain": "Vollständig",
"context": "Kontext",
"continue": "Fortsetzen",
"control_bottom_app_bar_add_tags": "Tags hinzufügen",
"control_bottom_app_bar_create_new_album": "Neues Album erstellen",
"control_bottom_app_bar_delete_from_immich": "Aus Immich löschen",
"control_bottom_app_bar_delete_from_local": "Vom Gerät löschen",
@@ -832,6 +848,7 @@
"copy_error": "Kopier-Fehler",
"copy_file_path": "Dateipfad kopieren",
"copy_image": "Bild kopieren",
"copy_json": "JSON kopieren",
"copy_link": "Link kopieren",
"copy_link_to_clipboard": "Link in die Zwischenablage kopieren",
"copy_password": "Passwort kopieren",
@@ -881,17 +898,16 @@
"cutoff_date_description": "Behalte Fotos der letzten…",
"cutoff_day": "{count, plural, one {Tag} other {Tage}}",
"cutoff_year": "{count, plural, one {Jahr} other {Jahre}}",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Dunkel",
"dark_theme": "Auf dunkle Ansicht umschalten",
"date": "Datum",
"date_after": "Datum nach",
"date_and_time": "Datum und Zeit",
"date_before": "Datum vor",
"date_format": "E d. LLL y • hh:mm",
"date_of_birth_saved": "Das Geburtsdatum wurde erfolgreich gespeichert",
"date_of_birth": "Geburtstag",
"date_of_birth_saved": "Der Geburtstag wurde erfolgreich gespeichert",
"date_range": "Datumsbereich",
"date_time_original": "Datum/Uhrzeit Original",
"day": "Tag",
"days": "Tage",
"deduplicate_all": "Alle Duplikate entfernen",
@@ -970,7 +986,10 @@
"downloading_asset_filename": "Datei {filename} wird heruntergeladen",
"downloading_from_icloud": "von iCloud herunterladen",
"downloading_media": "Medien werden heruntergeladen",
"drag_to_reorder": "Ziehen um Reihenfolge zu ändern",
"drop_files_to_upload": "Lade Dateien hoch, indem du sie hierhin ziehst",
"duplicate": "Duplikat",
"duplicate_workflow": "Workflow duplizieren",
"duplicates": "Duplikate",
"duplicates_description": "Löse jede Gruppe auf, indem du angibst, welche, wenn überhaupt, Duplikate sind.",
"duration": "Dauer",
@@ -1072,6 +1091,7 @@
"failed_to_remove_product_key": "Fehler beim Entfernen des Produktschlüssels",
"failed_to_reset_pin_code": "Zurücksetzen des PIN-Codes fehlgeschlagen",
"failed_to_stack_assets": "Dateien konnten nicht gestapelt werden",
"failed_to_tag_assets": "Dateien konnten nicht getaggt werden",
"failed_to_unstack_assets": "Dateien konnten nicht entstapelt werden",
"failed_to_update_notification_status": "Benachrichtigungsstatus aktualisieren fehlgeschlagen",
"incorrect_email_or_password": "Ungültige E-Mail oder Passwort",
@@ -1167,7 +1187,7 @@
},
"errors_text": "Fehler",
"exclusion_pattern": "Ausschlussmuster",
"exif": "EXIF",
"exif": "Exif",
"exif_bottom_sheet_description": "Beschreibung hinzufügen...",
"exif_bottom_sheet_description_error": "Fehler bei der Aktualisierung der Beschreibung",
"exif_bottom_sheet_details": "DETAILS",
@@ -1191,11 +1211,13 @@
"export_as_json": "Als JSON exportieren",
"export_database": "Datenbank exportieren",
"export_database_description": "Exportiert die SQLite Datenbank",
"exposure_time": "Belichtungszeit",
"extension": "Erweiterung",
"external": "Extern",
"external_libraries": "Externe Bibliotheken",
"external_network": "Externes Netzwerk",
"external_network_sheet_info": "Wenn sich die App nicht im bevorzugten WLAN-Netzwerk befindet, verbindet sie sich mit dem Server über die erste der folgenden URLs, die sie erreichen kann (von oben nach unten)",
"f_number": "F-Nummer",
"face_unassigned": "Nicht zugewiesen",
"failed": "Fehlgeschlagen",
"failed_count": "Fehlgeschlagen: {count}",
@@ -1213,7 +1235,6 @@
"features_setting_description": "Funktionen der App verwalten",
"file_name_or_extension": "Dateiname oder -erweiterung",
"file_name_text": "Dateiname",
"file_name_with_value": "Dateiname: {file_name}",
"file_size": "Dateigröße",
"filename": "Dateiname",
"filetype": "Dateityp",
@@ -1226,6 +1247,7 @@
"find_them_fast": "Finde sie schneller mit der Suche nach Namen",
"first": "Erste",
"fix_incorrect_match": "Fehlerhafte Übereinstimmung beheben",
"focal_length": "Brennweite",
"folder": "Ordner",
"folder_not_found": "Ordner nicht gefunden",
"folders": "Ordner",
@@ -1236,6 +1258,7 @@
"free_up_space_description": "Bewege Fotos und Videos, die bereits gesichert wurden, in den Papierkorb auf deinem Gerät. Die Kopie auf dem Server bleibt unberührt.",
"free_up_space_settings_subtitle": "Gerätespeicher freigeben",
"full_path": "Vollständiger Pfad: {path}",
"full_path_or_folder": "Voller Ordnerpfad oder Ordner",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Diese Funktion lädt externe Quellen von Google, um zu funktionieren.",
"general": "Allgemein",
@@ -1345,6 +1368,7 @@
"ios_debug_info_no_sync_yet": "Noch kein Hintergrundsynchronisierungsauftrag ausgeführt",
"ios_debug_info_processes_queued": "{count, plural, one {{count} Hintergrundprozess in der Warteschlange} other {{count} Hintergrundprozesse in der Warteschlange}}",
"ios_debug_info_processing_ran_at": "Prozess läuft {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# Eintrag} other {# Einträge}}",
"jobs": "Aufgaben",
"json_editor": "JSON-Editor",
@@ -1370,7 +1394,7 @@
"last": "Letzte",
"last_months": "{count, plural, one {Letzter Monat} other {Letzte # Monate}}",
"last_seen": "Zuletzt gesehen",
"latest_version": "Aktuelle Version",
"latest_version": "Neuste Version",
"latitude": "Breitengrad",
"leave": "Verlassen",
"leave_album": "Album verlassen",
@@ -1392,11 +1416,13 @@
"light_theme": "Auf helle Ansicht umschalten",
"like": "Gefällt mir",
"like_deleted": "Like gelöscht",
"link": "Link",
"link_motion_video": "Bewegungsvideo verknüpfen",
"link_to_docs": "Weitere Informationen finden Sie in der <link>Dokumentation</link>.",
"link_to_oauth": "Mit OAuth verknüpfen",
"linked_oauth_account": "Verknüpftes OAuth-Konto",
"list": "Liste",
"live": "Live",
"loading": "Laden",
"loading_search_results_failed": "Laden von Suchergebnissen fehlgeschlagen",
"local": "Lokal",
@@ -1494,7 +1520,7 @@
"map_assets_in_bounds": "{count, plural, =0 {Keine Fotos in diesem Gebiet} one {# Foto} other {# Fotos}}",
"map_cannot_get_user_location": "Standort konnte nicht ermittelt werden",
"map_location_dialog_yes": "Ja",
"map_location_picker_page_use_location": "Aufnahmeort verwenden",
"map_location_picker_page_use_location": "Diesen Standort verwenden",
"map_location_service_disabled_content": "Ortungsdienste müssen aktiviert sein, um Inhalte am aktuellen Standort anzuzeigen. Willst du die Ortungsdienste jetzt aktivieren?",
"map_location_service_disabled_title": "Ortungsdienste deaktiviert",
"map_marker_for_images": "Kartenmarkierung für Bilder, die in {city}, {country} aufgenommen wurden",
@@ -1518,6 +1544,38 @@
"marked_all_as_read": "Alle als gelesen markiert",
"matches": "Treffer",
"matching_assets": "Passende Dateien",
"media_chrome": {
"auto": "Auto",
"captions": "Untertitel",
"captions_off": "Aus",
"closed_captions": "Untertitel",
"decode_error": "Dekodierungsfehler",
"disable_captions": "Untertitel deaktivieren",
"enable_captions": "Untertitel aktivieren",
"enter_fullscreen_mode": "Vollbildmodus aktivieren",
"exit_fullscreen_mode": "Vollbildmodus beenden",
"loop": "Endlosschleife",
"media_error_description": "Ein Medienfehler hat die Wiedergabe abgebrochen. Das Medium könnte beschädigt sein oder Ihr Browser unterstützt dieses Format nicht.",
"media_loading": "Medien werden geladen",
"mute": "Stumm schalten",
"network_error": "Netzwerkfehler",
"network_error_description": "Ein Netzwerkfehler hat dazu geführt, dass der Medien-Download fehlgeschlagen ist.",
"not_supported_error": "Quelle nicht unterstützt",
"playback_rate": "Wiedergabegeschwindigkeit",
"playback_rate_current": "aktuelle Wiedergabegeschwindigkeit",
"playback_rate_value": "Wiedergabegeschwindigkeit {playbackRate}",
"playback_time": "Wiedergabezeit",
"quality": "Qualität",
"second": "Sekunde",
"seconds": "Sekunden",
"time_value_of_total_time": "{currentTime} von {totalTime}",
"time_value_remaining": "{time} verbleibend",
"unmute": "Stummschaltung aufheben",
"unsupported_error_description": "Ein nicht unterstützter Fehler ist aufgetreten. Der Server oder das Netzwerk ist fehlgeschlagen, oder Ihr Browser unterstützt dieses Format nicht.",
"video_not_loaded_unknown_time": "Video nicht geladen, unbekannte Zeit.",
"video_player": "Videoplayer",
"volume": "Lautstärke"
},
"media_type": "Medientyp",
"memories": "Erinnerungen",
"memories_all_caught_up": "Alles aufgeholt",
@@ -1534,6 +1592,8 @@
"merge_people_prompt": "Willst du diese Personen zusammenführen? Diese Aktion kann nicht rückgängig gemacht werden.",
"merge_people_successfully": "Personen erfolgreich zusammengeführt",
"merged_people_count": "{count, plural, one {# Person} other {# Personen}} zusammengefügt",
"minFaces": "Mindestanzahl Gesichter",
"minFaces_description": "Die Mindestanzahl an erkannten Gesichtern, damit eine Person angezeigt wird",
"minimize": "Minimieren",
"minute": "Minute",
"minutes": "Minuten",
@@ -1541,11 +1601,12 @@
"mirror_vertical": "Vertikal",
"missing": "Fehlende",
"mobile_app": "Mobile App",
"mobile_app_download_onboarding_note": "Herunterladen der mobilen Begleiter-App über einen der folgenden Möglichkeiten",
"mobile_app_download_onboarding_note": "Herunterladen der mobilen Begleiter-App über eine der folgenden Möglichkeiten",
"model": "Modell",
"modify_date": "Änderungsdatum",
"month": "Monat",
"monthly_title_text_date_format": "MMMM y",
"more": "Mehr",
"motion": "Bewegung",
"move": "Verschieben",
"move_down": "Nach unten",
"move_off_locked_folder": "Aus dem gesperrten Ordner verschieben",
@@ -1562,6 +1623,8 @@
"multiselect_grid_edit_gps_err_read_only": "Der Aufnahmeort von schreibgeschützten Inhalten kann nicht verändert werden, überspringen",
"mute_memories": "Erinnerungen stumm schalten",
"my_albums": "Meine Alben",
"my_immich_description": "Diese Seite als „Mein Immich“-Link kopieren",
"my_immich_title": "Mein Immich-Link",
"name": "Name",
"name_or_nickname": "Name oder Nickname",
"name_required": "Name ist erforderlich",
@@ -1589,7 +1652,6 @@
"next": "Weiter",
"next_memory": "Nächste Erinnerung",
"no": "Nein",
"no_actions_added": "Noch keine Aktionen hinzugefügt",
"no_albums_found": "Keine Alben gefunden",
"no_albums_message": "Erstelle ein Album, um deine Fotos und Videos zu organisieren",
"no_albums_with_name_yet": "Es sieht so aus, als hättest du noch keine Alben mit diesem Namen.",
@@ -1603,10 +1665,9 @@
"no_configuration_needed": "Keine Konfiguration benötigt",
"no_devices": "Keine verwendeten Geräte",
"no_duplicates_found": "Es wurden keine Duplikate gefunden.",
"no_exif_info_available": "Keine EXIF-Informationen vorhanden",
"no_exif_info_available": "Keine Exif-Informationen vorhanden",
"no_explore_results_message": "Lade weitere Fotos hoch, um deine Sammlung zu erkunden.",
"no_favorites_message": "Füge Favoriten hinzu, um deine besten Bilder und Videos schnell zu finden",
"no_filters_added": "Noch keine Filter hinzugefügt",
"no_libraries_message": "Eine externe Bibliothek erstellen, um deine Fotos und Videos anzusehen",
"no_local_assets_found": "Keine lokale Datei mit dieser Prüfsumme gefunden",
"no_location_set": "Kein Standort festgelegt",
@@ -1619,6 +1680,7 @@
"no_results": "Keine Ergebnisse",
"no_results_description": "Versuche es mit einem Synonym oder einem allgemeineren Stichwort",
"no_shared_albums_message": "Erstelle ein Album, um Fotos und Videos mit Personen in deinem Netzwerk zu teilen",
"no_steps": "Noch keine Schritte hinzugefügt",
"no_uploads_in_progress": "Kein Upload in Bearbeitung",
"none": "Keine",
"not_allowed": "Nicht erlaubt",
@@ -1664,6 +1726,7 @@
"organize_into_albums": "In Alben organisieren",
"organize_into_albums_description": "Aktuelle Synchronisationseinstellungen verwenden, um existierende Fotos in Alben zu laden",
"organize_your_library": "Organisiere deine Bibliothek",
"orientation": "Orientierung",
"original": "Original",
"other": "Sonstiges",
"other_devices": "Andere Geräte",
@@ -1749,12 +1812,14 @@
"places_count": "{count, plural, one {{count, number} Ort} other {{count, number} Orte}}",
"play": "Abspielen",
"play_memories": "Erinnerungen abspielen",
"play_motion_photo": "Bewegte Bilder abspielen",
"play_motion_photo": "Live-Foto abspielen",
"play_or_pause_video": "Video abspielen oder pausieren",
"play_original_video": "Originales Video abspielen",
"play_original_video_setting_description": "Bevorzugen die Wiedergabe von Originalvideos gegenüber transkodierten Videos. Wenn das Original nicht kompatibel ist, wird es möglicherweise nicht korrekt wiedergegeben.",
"play_transcoded_video": "Transkodiertes Video abspielen",
"please_auth_to_access": "Für den Zugriff bitte Authentifizieren",
"plugin_method_filter_type": "Filter",
"plugin_method_filter_type_description": "Mit dieser Methode lassen sich Ereignisse filtern und die Ausführung nachfolgender Schritte bedingt verhindern",
"port": "Port",
"preferences_settings_subtitle": "App-Einstellungen verwalten",
"preferences_settings_title": "Voreinstellungen",
@@ -1776,6 +1841,7 @@
"profile_drawer_readonly_mode": "Schreibgeschützter Modus aktiviert. Halte das Benutzer-Avatar-Symbol gedrückt, um den Modus zu verlassen.",
"profile_image_of_user": "Profilbild von {user}",
"profile_picture_set": "Profilbild gesetzt.",
"projection_type": "Projektionstyp",
"public_album": "Öffentliches Album",
"public_share": "Öffentliche Freigabe",
"purchase_account_info": "Unterstützer",
@@ -1853,6 +1919,7 @@
"remove_assets_title": "Dateien entfernen?",
"remove_custom_date_range": "Benutzerdefinierten Datumsbereich entfernen",
"remove_deleted_assets": "Offline-Dateien entfernen",
"remove_filter": "Filter entfernen",
"remove_from_album": "Aus Album entfernen",
"remove_from_album_action_prompt": "{count} vom Album entfernt",
"remove_from_favorites": "Aus Favoriten entfernen",
@@ -1926,6 +1993,8 @@
"scan_settings": "Scan-Einstellungen",
"scanning": "Scanne",
"scanning_for_album": "Nach Alben scannen...",
"screencast_mode_description": "Tastatur- und Mausereignisindikatoren auf dem Bildschirm anzeigen",
"screencast_mode_title": "Bildschirmübertragungsmodus umschalten",
"search": "Suche",
"search_albums": "Album suchen",
"search_by_context": "Suche nach Kontext",
@@ -1933,6 +2002,8 @@
"search_by_description_example": "Wandern in Sapa",
"search_by_filename": "Suche nach Dateiname oder -erweiterung",
"search_by_filename_example": "z.B. IMG_1234.JPG oder PNG",
"search_by_full_path": "Suchen nach Ordnerpfad oder Ordner",
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - Sie können nach Projekten, 3D, Drucken, 2026 usw. suchen.",
"search_by_ocr": "Suche per OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Suche nach Kameralinse...",
@@ -2140,7 +2211,9 @@
"show_in_timeline": "In Zeitleiste anzeigen",
"show_in_timeline_setting_description": "Fotos und Videos dieses Benutzers in deiner Zeitleiste anzeigen",
"show_keyboard_shortcuts": "Tastaturkürzel anzeigen",
"show_less": "Weniger zeigen",
"show_metadata": "Metadaten anzeigen",
"show_more_fields": "{count, plural, one {Zeige # weiteres Feld} other {Zeige # weitere Felder}}",
"show_or_hide_info": "Informationen ein- oder ausblenden",
"show_password": "Passwort anzeigen",
"show_person_options": "Personen-Optionen anzeigen",
@@ -2148,6 +2221,7 @@
"show_schema": "Schema anzeigen",
"show_search_options": "Suchoptionen anzeigen",
"show_shared_links": "Zeige geteilte Links",
"show_slideshow_metadata_overlay": "Bildinformationen anzeigen",
"show_slideshow_transition": "Slideshow-Übergang anzeigen",
"show_supporter_badge": "Unterstützerabzeichen",
"show_supporter_badge_description": "Zeige Unterstützerabzeichen",
@@ -2163,13 +2237,17 @@
"skip_to_folders": "Springe zu Ordnern",
"skip_to_tags": "Springe zu Tags",
"slideshow": "Diashow",
"slideshow_metadata_overlay_mode": "Overlay Inhalt",
"slideshow_metadata_overlay_mode_description_only": "Nur Beschreibung",
"slideshow_metadata_overlay_mode_full": "Alles",
"slideshow_repeat": "Slideshow wiederholen",
"slideshow_repeat_description": "Wenn Slideshow beendet, zum Anfang zurückkehren",
"slideshow_settings": "Diashow-Einstellungen",
"smart_album": "Smart Album",
"sort_albums_by": "Alben sortieren nach...",
"sort_created": "Erstellungsdatum",
"sort_items": "Anzahl der Einträge",
"sort_modified": "Änderungsdatum",
"sort_modified": "Datum geändert",
"sort_newest": "Neuestes Foto",
"sort_oldest": "Ältestes Foto",
"sort_people_by_similarity": "Personen nach Ähnlichkeit sortieren",
@@ -2188,8 +2266,13 @@
"start_date_before_end_date": "Anfangsdatum muss vor dem Enddatum liegen",
"state": "Bundesland / Provinz",
"status": "Status",
"step_delete": "Schritt löschen",
"step_delete_confirm": "Möchten Sie diesen Schritt wirklich löschen?",
"step_details": "Details zum Schritt",
"steps": "Schritte",
"steps_count": "{count, plural, one {# Schritt} other {# Schritte}}",
"stop_casting": "Übertragung stoppen",
"stop_motion_photo": "Stop-Motion-Foto",
"stop_motion_photo": "Live-Foto stoppen",
"stop_photo_sharing": "Deine Fotos nicht mehr teilen?",
"stop_photo_sharing_description": "{partner} wird keinen Zugriff mehr auf deine Fotos haben.",
"stop_sharing_photos_with_user": "Aufhören Fotos mit diesem Benutzer zu teilen",
@@ -2214,6 +2297,8 @@
"sync_status": "Synchronisierungstatus",
"sync_status_subtitle": "Synchronisierungssystem anzeigen und bearbeiten",
"sync_upload_album_setting_subtitle": "Erstelle und lade deine ausgewählten Fotos und Videos in die ausgewählten Alben auf Immich hoch",
"system_theme": "Systemthema",
"system_theme_command_description": "Systemdesign verwenden ({value})",
"tag": "Tag",
"tag_assets": "Dateien taggen",
"tag_created": "Tag erstellt: {tag}",
@@ -2279,7 +2364,7 @@
"trash_page_title": "Papierkorb ({count})",
"trashed_items_will_be_permanently_deleted_after": "Objekte im Papierkorb werden nach {days, plural, one {# Tag} other {# Tagen}} endgültig gelöscht.",
"trigger": "Auslöser",
"trigger_asset_uploaded": "Datei hochgeladen",
"trigger_asset_uploaded": "Datei hochladen",
"trigger_asset_uploaded_description": "Löst aus, wenn eine neue Datei hochgeladen wurde",
"trigger_description": "Ein Ereignis, das den Workflow startet",
"trigger_person_recognized": "Person erkannt",
@@ -2319,7 +2404,6 @@
"unsupported_field_type": "Nicht unterstützter Feldtyp",
"unsupported_file_type": "Die Datei {file} kann nicht hochgeladen werden, da der Dateityp {type} nicht unterstützt wird.",
"untagged": "Ohne Tag",
"untitled_workflow": "Unbenannter Workflow",
"up_next": "Weiter",
"update_location_action_prompt": "Aktualisiere den Ort von {count} ausgewählten Dateien mit:",
"updated_at": "Aktualisiert",
@@ -2348,6 +2432,7 @@
"use_browser_locale_description": "Datum, Uhrzeit und Zahlen werden entsprechend den Einstellungen Ihres Browsers formatiert",
"use_current_connection": "Aktuelle Verbindung verwenden",
"use_custom_date_range": "Stattdessen einen benutzerdefinierten Datumsbereich verwenden",
"use_template": "Vorlage verwenden",
"user": "Nutzer",
"user_has_been_deleted": "Dieser Benutzer wurde gelöscht.",
"user_id": "Nutzer-ID",
@@ -2377,6 +2462,7 @@
"video": "Video",
"video_hover_setting": "Videovorschau beim Hovern abspielen",
"video_hover_setting_description": "Spiele die Miniaturansicht des Videos ab, wenn sich die Maus über dem Element befindet. Auch wenn die Funktion deaktiviert ist, kann die Wiedergabe gestartet werden, indem du mit der Maus über das Wiedergabesymbol fährst.",
"video_quality": "Videoqualität",
"videos": "Videos",
"videos_count": "{count, plural, one {# Video} other {# Videos}}",
"videos_only": "Nur Videos",
@@ -2409,8 +2495,10 @@
"week": "Woche",
"welcome": "Willkommen",
"welcome_to_immich": "Willkommen bei Immich",
"when": "Wann",
"width": "Breite",
"wifi_name": "WLAN-Netzwerk",
"workflow": "Workflow",
"workflow_delete_prompt": "Bist du sicher, dass du diesen Workflow löschen willst?",
"workflow_deleted": "Workflow gelöscht",
"workflow_description": "Workflow-Beschreibung",
@@ -2420,11 +2508,13 @@
"workflow_name": "Workflow-Name",
"workflow_navigation_prompt": "Bist du sicher, dass du den Editor ohne zu speichern verlassen willst?",
"workflow_summary": "Workflow-Zusammenfassung",
"workflow_templates": "Vorlagen für Workflows",
"workflow_update_success": "Workflow erfolgreich aktualisiert",
"workflow_updated": "Workflow aktualisiert",
"workflows": "Workflows",
"workflows_help_text": "Workflows automatisieren Aktionen auf deinen Dateien, basierend auf Auslösern und Filtern",
"wrong_pin_code": "PIN-Code falsch",
"x_of_total": "{x}/{total}",
"year": "Jahr",
"years_ago": "Vor {years, plural, one {einem Jahr} other {# Jahren}}",
"yes": "Ja",
+64 -19
View File
@@ -1,19 +1,19 @@
{
"about": "Über",
"account": "Konto",
"account_settings": "Konto Einstellungen",
"account_settings": "Kontoistellige",
"acknowledge": "Bestätigä",
"action": "Aktion",
"action_common_update": "Update",
"action_description": "Aktionä, wo uf de gefilterti Mediä ausgführt werdä solled",
"actions": "Aktionen",
"action_description": "Aktionä, wo uf de gfilterte Medie usgführt wärde sölled",
"actions": "Aktionä",
"active": "Aktiv",
"active_count": "Aktiv: {count}",
"activity": "Aktivität",
"activity_changed": "Aktivität ist {enabled, select, true {aktiviert} other {deaktiviert}}",
"add": "Hinzuefüge",
"add_a_description": "Beschreibung hinzufügen",
"add_a_location": "Standort hinzuefügä",
"add_a_description": "Beschribig aege",
"add_a_location": "Standort afüege",
"add_a_name": "Namä hinzefügä",
"add_a_title": "Titel hinzufeügä",
"add_action": "Aktion hinzuefügä",
@@ -22,13 +22,12 @@
"add_birthday": "Geburtstag hinzuefüge",
"add_endpoint": "Endpunkt hinzuefüge",
"add_exclusion_pattern": "Ausschlussmuster hinzufügen",
"add_filter": "Filter hinzufügen",
"add_filter_description": "Klicke hier um eine Filterbedingung hinzuzufügen",
"add_location": "Standort hinzufügen",
"add_more_users": "Mehr Benutzer hinzufügen",
"add_partner": "Partner hinzufügen",
"add_path": "Pfad hinzufügen",
"add_photos": "Fotos hinzufügen",
"add_step": "Schritt hinzuefüege",
"add_tag": "Tag hinzufügen",
"add_to": "Hinzufügen zu…",
"add_to_album": "Zu Album hinzufügen",
@@ -38,11 +37,10 @@
"add_to_album_toggle": "Auswahl umschalten für {album}",
"add_to_albums": "Zu Alben hinzufügen",
"add_to_albums_count": "Zu Alben hinzufügen ({count})",
"add_to_bottom_bar": "Hinzufügen zu",
"add_to_bottom_bar": "zueege zu",
"add_to_shared_album": "Zu geteiltem Album hinzufügen",
"add_upload_to_stack": "Upload zum Stapel hinzufügen",
"add_url": "URL hinzufügen",
"add_workflow_step": "Workflow-Schritt hinzufügen",
"add_url": "URL zueege",
"added_to_archive": "Zum Archiv hinzugefügt",
"added_to_favorites": "Zu Favoriten hinzugefügt",
"added_to_favorites_count": "{count, number} zu Favoriten hinzugefügt",
@@ -54,7 +52,7 @@
"authentication_settings_description": "Passwort-, OAuth- und andere Authentifizierungseinstellungen verwalten",
"authentication_settings_disable_all": "Bist du sicher, dass du alle Loginmethoden deaktivieren willst? Die Anmeldung wird vollständig deaktiviert.",
"authentication_settings_reenable": "Nutze einen <link>Server-Befehl</link> zur Reaktivierung.",
"background_task_job": "Hintergrundaufgaben",
"background_task_job": "Hintergrundfarbä",
"backup_database": "Datenbanksicherung erstellen",
"backup_database_enable_description": "Datenbank regelmässig sichern",
"backup_keep_last_amount": "Anzahl der aufzubewahrenden früheren Sicherungen",
@@ -64,7 +62,7 @@
"backup_onboarding_description": "Eine <backblaze-link>3-2-1 Sicherungsstrategie</backblaze-link> wird empfohlen, um deine Daten zu schützen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende Sicherungslösung zu haben.",
"backup_onboarding_footer": "Weitere Informationen zum Sichern von Immich findest du in der <link>Dokumentation</link>.",
"backup_onboarding_parts_title": "Eine 3-2-1-Sicherung umfasst:",
"backup_onboarding_title": "Backups",
"backup_onboarding_title": "Sicherige",
"backup_settings": "Einstellungen für Datenbanksicherung",
"backup_settings_description": "Einstellungen zur regelmässigen Sicherung der Datenbank.",
"cleared_jobs": "Folgende Aufgaben zurückgesetzt: {job}",
@@ -76,16 +74,16 @@
"confirm_user_password_reset": "Bist du sicher, dass du das Passwort für {user} zurücksetzen möchtest?",
"confirm_user_pin_code_reset": "Bist du sicher, dass du den PIN-Code von {user} zurücksetzen möchtest?",
"copy_config_to_clipboard_description": "Aktuelle Systemkonfiguration als JSON-Objekt in die Zwischenablage kopieren",
"create_job": "Aufgabe erstellen",
"create_job": "Ufgab erstelle",
"cron_expression": "Cron-Ausdruck",
"cron_expression_description": "Setze das Scanintervall im Cron-Format. Für mehr Informationen, siehe z. B. <link>Crontab Guru</link>",
"cron_expression_presets": "Vorlagen für Cron-Ausdrücke",
"disable_login": "Login deaktivieren",
"disable_login": "Login deaktivierä",
"duplicate_detection_job_description": "Verwendet maschinelles Lernen auf den Dateien, um Duplikate zu finden. Baut auf der intelligenten Suche auf",
"exclusion_pattern_description": "Mit Ausschlussmustern können Dateien und Ordner beim Scannen deiner Bibliothek ignoriert werden. Dies ist nützlich, wenn du Ordner hast, die Dateien enthalten, die du nicht importieren möchtest, wie z. B. RAW-Dateien.",
"export_config_as_json_description": "Aktuelle Systemkonfiguration als JSON-Datei herunterladen",
"external_libraries_page_description": "Externe Bibliotheksseite für Administratoren",
"face_detection": "Gesichtserkennung",
"face_detection": "Gsichtserkennig",
"face_detection_description": "Diese Aufgabe erkennt mit maschinellem Lernen Gesichter in Dateien. Bei Videos wird nur das Vorschaubild verwendet. „Aktualisieren“ verarbeitet alle Dateien neu. „Zurücksetzen“ setzt zusätzlich alle Gesichter zurück. „Fehlende“ fügt nur nicht verarbeitete Dateien in die Warteschlange ein. Erfasste Gesichter werden zur Gesichtsidentifizierung in die Warteschlange eingefügt, um sie in bestehende oder neue Personen zu gruppieren.",
"facial_recognition_job_description": "Diese Aufgabe gruppiert im Anschluss an die Gesichtserkennung die erkannten Gesichter zu Personen. „Zurücksetzen“ gruppiert alle Gesichter neu, während „Fehlende“ Gesichter ohne Zuordnung in die Warteschlange stellt.",
"failed_job_command": "Befehl {command} ist für Aufgabe {job} fehlgeschlagen",
@@ -99,7 +97,7 @@
"image_fullsize_title": "Hochauflösende Vorschaueinstellungen",
"image_prefer_embedded_preview": "Eingebettete Vorschau bevorzugen",
"image_prefer_embedded_preview_setting_description": "Verwende eingebettete Vorschaubilder in RAW-Fotos als Grundlage für die Bildverarbeitung, sofern diese zur Verfügung stehen. Dies kann bei einigen Bildern genauere Farben erzeugen, allerdings ist die Qualität der Vorschau kameraabhängig und das Bild kann mehr Kompressionsartefakte aufweisen.",
"image_prefer_wide_gamut": "Breites Spektrum bevorzugen",
"image_prefer_wide_gamut": "weiterer Farbraum bevorzugen",
"image_prefer_wide_gamut_setting_description": "Display P3 (DCI-P3) für Vorschaubilder verwenden. Dadurch bleibt die Lebendigkeit von Bildern mit breiten Farbräumen besser erhalten, aber die Bilder können auf älteren Geräten mit einer älteren Browserversion etwas anders aussehen. sRGB-Bilder werden im sRGB-Format belassen, um Farbverschiebungen zu vermeiden.",
"image_preview_description": "Mittelgrosses Bild mit entfernten Metadaten, das bei der Betrachtung einer einzelnen Datei und für maschinelles Lernen verwendet wird",
"image_preview_quality_description": "Vorschauqualität von 1-100. Ein höherer Wert ist besser, erzeugt dadurch aber grössere Dateien und kann die Reaktionsfähigkeit der App beeinträchtigen. Ein niedriger Wert kann dafür aber die Qualität des maschinellen Lernens beeinträchtigen.",
@@ -107,7 +105,7 @@
"image_progressive": "Fortlaufend",
"image_progressive_description": "JPEG-Bilder schrittweise kodieren, um ein stufenweises Laden zu ermöglichen. Dies hat keine Auswirkungen auf WebP-Bilder.",
"image_quality": "Qualität",
"image_resolution": "Auflösung",
"image_resolution": "Uflösig",
"image_resolution_description": "Höhere Auflösungen können mehr Details erhalten, benötigen aber mehr Zeit für die Kodierung, haben grössere Dateigrössen und können die Reaktionsfähigkeit der App beeinträchtigen.",
"image_settings": "Bildeinstellungen",
"image_settings_description": "Qualität und Auflösung der generierten Bilder verwalten",
@@ -120,6 +118,8 @@
"job_not_concurrency_safe": "Diese Aufgabe kann nicht mehrmals parallel laufen gelassen werden.",
"job_settings": "Aufgabeneinstellungen",
"job_settings_description": "Gleichzeitige Ausführung von Aufgaben verwalten",
"jobs_delayed": "Qualität",
"jobs_failed": "{jobCount, plural, other {# failed}}",
"jobs_over_time": "Jobs im Laufe der Zeit",
"library_created": "Bibliothek erstellt: {library}",
"library_deleted": "Bibliothek gelöscht",
@@ -127,6 +127,51 @@
"library_folder_description": "Wähle einen Ordner zum Importieren. Dieser Ordner wird inklusive Unterordnern nach Bildern und Videos durchsucht.",
"library_remove_exclusion_pattern_prompt": "Bilst du sicher, dass du dieses Ausschlussmuster entfernen möchtest?",
"library_remove_folder_prompt": "Bist du sicher, dass du diesen Import-Ordner entfernen möchtest?",
"library_scanning": "Regelmässiges Scannen"
}
"library_scanning": "Regelmässiges Scannen",
"library_scanning_description": "Regelmässiges Scannen der Bibliothek konfigurieren",
"library_scanning_enable_description": "Regelmässiges Scannen der Bibliothek aktivieren",
"library_settings": "Externe Bibliothek",
"library_settings_description": "Einstellungen für externe Bibliotheken verwalten",
"library_tasks_description": "Externe Bibliotheken nach neuen und/oder geänderten Assets durchsuchen",
"library_updated": "Aktualisierte Bibliothek",
"library_watching_enable_description": "Änderungen an Dateien in externen Bibliotheken überwachen",
"library_watching_settings": "Bibliothek beobachten [EXPERIMENTELL]",
"library_watching_settings_description": "Automatisch nach geänderten Dateien suchen",
"logging_enable_description": "Logging aktivieren",
"logging_level_description": "Wenn aktiviert, welches Logging-Level soll verwendet werden.",
"logging_settings": "Logging",
"machine_learning_availability_checks": "Verfügbarkeitsüberprüfungen",
"machine_learning_availability_checks_description": "Verfügbare Machine-Learning-Server automatisch erkennen und bevorzugen",
"machine_learning_availability_checks_enabled": "Verfügbarkeitsüberprüfungen aktivieren",
"machine_learning_availability_checks_interval": "Überprüfungsintervall",
"machine_learning_availability_checks_interval_description": "Intervall in Millisekunden zwischen Verfügbarkeitsüberprüfungen",
"machine_learning_availability_checks_timeout": "Zeitüberschreitung der Anfrage",
"machine_learning_availability_checks_timeout_description": "Timeout in Millisekunden für Verfügbarkeitsüberprüfungen",
"machine_learning_clip_model": "CLIP Model",
"machine_learning_clip_model_description": "Der Name eines der <link>hier</link> gelisteten CLIP-Modelle. Hinweis: Nach dem Ändern eines Modells muss der Smart Search-Vorgang für alle Bilder erneut gestartet werden.",
"machine_learning_duplicate_detection": "Duplikatserkennung",
"machine_learning_duplicate_detection_enabled": "Duplikatserkennung aktivieren",
"machine_learning_duplicate_detection_enabled_description": "Falls deaktiviert, werden exakt identische Assets weiterhin dedupliziert.",
"machine_learning_duplicate_detection_setting_description": "Verwende CLIP embeddings um wahrscheinliche Dublikate zu finden",
"machine_learning_enabled": "Maschinelles Lernen aktivieren",
"machine_learning_enabled_description": "Falls deaktiviert, werden alle ML-Funktionen deaktiviert, unabhängig von den untenstehenden Einstellungen.",
"machine_learning_facial_recognition": "Gesichtserkennung",
"machine_learning_facial_recognition_description": "Gesichter in Bildern erkennen, identifizieren und gruppieren",
"machine_learning_facial_recognition_model": "Model für die Gesichtserkennung",
"machine_learning_facial_recognition_model_description": "Modell sind noch abstigender Grössi ufglitet. Grösseri Modell sind langsamer und bruched meh Arbeitsspeicher, aber produziered besseri Resultat. Gsichterkennig muss für alli Fotis neu usgfüehrt wärde, nochdem s Modell gwächslet worde esch.",
"machine_learning_facial_recognition_setting": "Gsichtserkennig ischalte",
"machine_learning_facial_recognition_setting_description": "Wenn usgschalte wärded Fotis ned für Gsichtserkennig enkodiert und wärded ned ide Personesektion uf de",
"machine_learning_max_detection_distance": "Maximali Erkennigsdistanz",
"machine_learning_max_detection_distance_description": "Maximali Distanz zwüsche zwei Bilder, um si als Duplikat z erkenne, zwische 0.001 - 0.1. Höcheri Wärt erkenned meh Duplikat, aber chönd Falschpositivi erzüge."
},
"video_quality": "Videoqualität",
"videos": "Videos",
"videos_only": "Nume Videos",
"view": "Aasicht",
"view_album": "Album aazeige",
"view_all": "Alles aazeige",
"view_all_users": "Alli Nutzer aazeige",
"view_details": "Details aaluege",
"view_link": "Link aazeige",
"view_links": "Links aazeige"
}
+11 -11
View File
@@ -22,8 +22,6 @@
"add_birthday": "Προσθήκη γενεθλίων",
"add_endpoint": "Προσθήκη τελικού σημείου",
"add_exclusion_pattern": "Προσθήκη μοτίβου αποκλεισμού",
"add_filter": "Προσθήκη φίλτρου",
"add_filter_description": "Κάντε κλικ για να προσθέσετε συνθήκη φίλτρου",
"add_location": "Προσθήκη τοποθεσίας",
"add_more_users": "Προσθήκη επιπλέον χρηστών",
"add_partner": "Προσθήκη συνεργάτη",
@@ -42,7 +40,6 @@
"add_to_shared_album": "Προσθήκη σε κοινόχρηστο άλμπουμ",
"add_upload_to_stack": "Προσθήκη αρχείου στην ουρά",
"add_url": "Προσθήκη Συνδέσμου",
"add_workflow_step": "Προσθήκη βήματος ροής εργασίας",
"added_to_archive": "Προστέθηκε στο αρχείο",
"added_to_favorites": "Προστέθηκε στα αγαπημένα",
"added_to_favorites_count": "Προστέθηκαν {count, number} στα αγαπημένα",
@@ -267,6 +264,8 @@
"notification_enable_email_notifications": "Ενεργοποίηση ειδοποιήσεων μέσω email",
"notification_settings": "Ρυθμίσεις ειδοποιήσεων",
"notification_settings_description": "Διαχείρηση ρυθμίσεων ειδοποιήσεων, συμπεριλαμβανομένου του email",
"oauth_allow_insecure_requests": "Να επιτρέπονται μη ασφαλή αιτήματα",
"oauth_allow_insecure_requests_description": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Αυτό απενεργοποιεί την επαλήθευση πιστοποιητικών TLS για αιτήματα OAuth και μπορεί να σας εκθέσει σε επιθέσεις MITM.",
"oauth_auto_launch": "Αυτόματη εκκίνηση",
"oauth_auto_launch_description": "Αυτόματη εκκίνιση της υπηρεσίας OAuth με την πλοήγηση στην σελίδα σύνδεσης",
"oauth_auto_register": "Αυτόματη καταχώρηση",
@@ -274,9 +273,11 @@
"oauth_button_text": "Κείμενο κουμπιού",
"oauth_client_secret_description": "Απαιτείται για έμπιστο πρόγραμμα πελάτη ή αν δεν υποστηρίζεται PKCE (Proof Key for Code Exchange) σε δημόσιο πρόγραμμα πελάτη.",
"oauth_enable_description": "Σύνδεση με OAuth",
"oauth_end_session_url_description": "Ανακατεύθυνση του χρήστη σε αυτό το URI όταν αποσυνδέεται.",
"oauth_mobile_redirect_uri": "URI Ανακατεύθυνσης για κινητά τηλέφωνα",
"oauth_mobile_redirect_uri_override": "Προσπέλαση URI ανακατεύθυνσης για κινητά τηλέφωνα",
"oauth_mobile_redirect_uri_override_description": "Ενεργοποιήστε το όταν ο πάροχος OAuth δεν επιτρέπει μια URI για κινητά, όπως το ''{callback}''",
"oauth_prompt_description": "Παράμετρος προτροπής (π.χ. επιλογή_λογαριασμού, σύνδεση, συναίνεση)",
"oauth_role_claim": "Ανάθεση ρόλου",
"oauth_role_claim_description": "Αυτόματη παραχώρηση πρόσβασης διαχειριστή με βάση την ύπαρξη αυτής της ανάθεσης. Η ανάθεση μπορεί να είναι είτε 'χρήστης' είτε 'διαχειριστής'.",
"oauth_settings": "OAuth",
@@ -881,15 +882,12 @@
"cutoff_date_description": "Διατήρηση φωτογραφιών από τις τελευταίες…",
"cutoff_day": "{count, plural, one {ημέρα} other {ημέρες}}",
"cutoff_year": "{count, plural, one {έτος} other {έτη}}",
"daily_title_text_date": "Ε, MMM dd",
"daily_title_text_date_year": "Ε, MMM dd, yyyy",
"dark": "Σκούρο",
"dark_theme": "Μετάβαση σε σκοτεινό θέμα",
"date": "Ημερομηνία",
"date_after": "Ημερομηνία μετά",
"date_and_time": "Ημερομηνία και ώρα",
"date_before": "Ημερομηνία πριν",
"date_format": "Ε, LLL d, y • h:mm a",
"date_of_birth_saved": "Η ημερομηνία γέννησης αποθηκεύτηκε επιτυχώς",
"date_range": "Εύρος ημερομηνιών",
"day": "Ημέρα",
@@ -1213,7 +1211,6 @@
"features_setting_description": "Διαχειριστείτε τα χαρακτηριστικά της εφαρμογής",
"file_name_or_extension": "Όνομα αρχείου ή επέκταση",
"file_name_text": "Όνομα αρχείου",
"file_name_with_value": "Όνομα αρχείου: {file_name}",
"file_size": "Μέγεθος αρχείου",
"filename": "Ονομασία αρχείου",
"filetype": "Τύπος αρχείου",
@@ -1392,6 +1389,7 @@
"light_theme": "Μετάβαση σε φωτεινό θέμα",
"like": "Μου αρέσει",
"like_deleted": "Το \"μου αρέσει\" διαγράφηκε",
"link": "Σύνδεσμος",
"link_motion_video": "Σύνδεσε βίντεο κίνησης",
"link_to_docs": "Για περισσότερες πληροφορίες, ανατρέξτε στην <link>τεκμηρίωση</link>.",
"link_to_oauth": "Σύνδεση στον OAuth",
@@ -1544,7 +1542,6 @@
"mobile_app_download_onboarding_note": "Κατέβασε την συνοδευτική εφαρμογή για κινητά χρησιμοποιώντας τις παρακάτω επιλογές",
"model": "Μοντέλο",
"month": "Μήνας",
"monthly_title_text_date_format": "ΜΜΜΜ y",
"more": "Περισσότερα",
"move": "Μετακίνηση",
"move_down": "Μετακίνηση προς τα κάτω",
@@ -1562,6 +1559,8 @@
"multiselect_grid_edit_gps_err_read_only": "Δεν είναι δυνατή η επεξεργασία της τοποθεσίας των στοιχείων μόνο για ανάγνωση, παραλείπεται",
"mute_memories": "Σίγαση Αναμνήσεων",
"my_albums": "Τα άλμπουμ μου",
"my_immich_description": "Αντιγραφή της τρέχουσας σελίδας ως σύνδεσμος Το Immich μου",
"my_immich_title": "Σύνδεσμος Το Immich μου",
"name": "Όνομα",
"name_or_nickname": "Όνομα ή ψευδώνυμο",
"name_required": "Απαιτείται όνομα",
@@ -1589,7 +1588,6 @@
"next": "Επόμενο",
"next_memory": "Επόμενη ανάμνηση",
"no": "Όχι",
"no_actions_added": "Δεν έχουν προστεθεί ακόμα ενέργειες",
"no_albums_found": "Δεν βρέθηκαν άλμπουμ",
"no_albums_message": "Δημιουργήστε ένα άλμπουμ για να οργανώσετε τις φωτογραφίες και τα βίντεό σας",
"no_albums_with_name_yet": "Φαίνεται ότι δεν έχετε κανένα άλμπουμ με αυτό το όνομα ακόμα.",
@@ -1606,7 +1604,6 @@
"no_exif_info_available": "Καμία πληροφορία exif διαθέσιμη",
"no_explore_results_message": "Ανεβάστε περισσότερες φωτογραφίες για να περιηγηθείτε στη συλλογή σας.",
"no_favorites_message": "Προσθέστε αγαπημένα για να βρείτε γρήγορα τις καλύτερες φωτογραφίες και τα βίντεό σας",
"no_filters_added": "Δεν έχουν προστεθεί ακόμα φίλτρα",
"no_libraries_message": "Δημιουργήστε μια εξωτερική βιβλιοθήκη για να προβάλετε τις φωτογραφίες και τα βίντεό σας",
"no_local_assets_found": "Δεν βρέθηκαν τοπικά στοιχεία με αυτό το checksum",
"no_location_set": "Η τοποθεσία δεν έχει οριστεί",
@@ -1926,6 +1923,8 @@
"scan_settings": "Ρυθμίσεις Σάρωσης",
"scanning": "Σαρώνεται",
"scanning_for_album": "Σάρωση για άλμπουμ...",
"screencast_mode_description": "Εμφάνιση ενδείξεων συμβάντων πληκτρολογίου και ποντικιού στην οθόνη",
"screencast_mode_title": "Εναλλαγή λειτουργίας καταγραφής οθόνης",
"search": "Αναζήτηση",
"search_albums": "Αναζήτηση άλμπουμ",
"search_by_context": "Αναζήτηση με βάση το πλαίσιο",
@@ -2214,6 +2213,8 @@
"sync_status": "Κατάσταση συγχρονισμού",
"sync_status_subtitle": "Προβολή και διαχείριση του συστήματος συγχρονισμού",
"sync_upload_album_setting_subtitle": "Δημιουργήστε και ανεβάστε τις φωτογραφίες και τα βίντεό σας στα επιλεγμένα άλμπουμ στο Immich",
"system_theme": "Θέμα συστήματος",
"system_theme_command_description": "Χρήση θέματος από το σύστημα ({value})",
"tag": "Ετικέτα",
"tag_assets": "Ετικετοποίηση στοιχείων",
"tag_created": "Δημιουργήθηκε ετικέτα: {tag}",
@@ -2319,7 +2320,6 @@
"unsupported_field_type": "Μη υποστηριζόμενος τύπος πεδίου",
"unsupported_file_type": "Το αρχείο {file} δεν μπορεί να μεταφορτωθεί επειδή ο τύπος αρχείου {type} δεν υποστηρίζεται.",
"untagged": "Χωρίς ετικέτα",
"untitled_workflow": "Νέα ροή εργασίας",
"up_next": "Ακολουθεί",
"update_location_action_prompt": "Ενημέρωση τοποθεσίας για {count} επιλεγμένα στοιχεία με:",
"updated_at": "Ενημερωμένο",
+90 -13
View File
@@ -22,13 +22,12 @@
"add_birthday": "Add a birthday",
"add_endpoint": "Add endpoint",
"add_exclusion_pattern": "Add exclusion pattern",
"add_filter": "Add filter",
"add_filter_description": "Click to add a filter condition",
"add_location": "Add location",
"add_more_users": "Add more users",
"add_partner": "Add partner",
"add_path": "Add path",
"add_photos": "Add photos",
"add_step": "Add step",
"add_tag": "Add tag",
"add_to": "Add to…",
"add_to_album": "Add to album",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Add to shared album",
"add_upload_to_stack": "Add upload to stack",
"add_url": "Add URL",
"add_workflow_step": "Add workflow step",
"added_to_archive": "Added to archive",
"added_to_favorites": "Added to favorites",
"added_to_favorites_count": "Added {count, number} to favorites",
@@ -307,6 +305,8 @@
"refreshing_all_libraries": "Refreshing all libraries",
"registration": "Admin Registration",
"registration_description": "Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative tasks, and additional users will be created by you.",
"release_channel_release_candidate": "Release candidate",
"release_channel_stable": "Stable",
"remove_failed_jobs": "Remove failed jobs",
"require_password_change_on_login": "Require user to change password on first login",
"reset_settings_to_default": "Reset settings to default",
@@ -401,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "Applies only to VAAPI and QSV. Sets the dri node used for hardware transcoding.",
"transcoding_preset_preset": "Preset (-preset)",
"transcoding_preset_preset_description": "Compression speed. Slower presets produce smaller files, and increase quality when targeting a certain bitrate. VP9 ignores speeds above 'faster'.",
"transcoding_realtime": "Real-time Transcoding [EXPERIMENTAL]",
"transcoding_realtime_description": "Allows transcoding to be performed in real-time as the video is being streamed. Enables quality switching, but may cause higher playback latency and stuttering depending on server capabilities.",
"transcoding_realtime_enabled": "Enable real-time transcoding",
"transcoding_realtime_enabled_description": "If disabled, the server will refuse to start new real-time transcoding sessions.",
"transcoding_reference_frames": "Reference frames",
"transcoding_reference_frames_description": "The number of frames to reference when compressing a given frame. Higher values improve compression efficiency, but slow down encoding. 0 sets this value automatically.",
"transcoding_required_description": "Only videos not in an accepted format",
@@ -444,6 +448,8 @@
"user_settings_description": "Manage user settings",
"user_successfully_removed": "User {email} has been successfully removed.",
"users_page_description": "Admin users page",
"version_check_channel": "Release channel",
"version_check_channel_description": "Pick the release channel you want to get version announcements for",
"version_check_enabled_description": "Enable version check",
"version_check_implications": "The version check feature relies on periodic communication with {server}",
"version_check_settings": "Version Check",
@@ -700,6 +706,7 @@
"birthdate_saved": "Date of birth saved successfully",
"birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.",
"blurred_background": "Blurred background",
"browse_templates": "Browse templates",
"bugs_and_feature_requests": "Bugs & Feature Requests",
"build": "Build",
"build_image": "Build Image",
@@ -733,6 +740,7 @@
"cannot_update_the_description": "Cannot update the description",
"cast": "Cast",
"cast_description": "Configure available cast destinations",
"change": "Change",
"change_date": "Change date",
"change_description": "Change description",
"change_display_order": "Change display order",
@@ -761,6 +769,7 @@
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
"check_logs": "Check Logs",
"checksum": "Checksum",
"choose": "Choose",
"choose_matching_people_to_merge": "Choose matching people to merge",
"city": "City",
"cleanup_confirm_description": "Immich found {count} assets (created before {date}) safely backed up to the server. Remove the local copies from this device?",
@@ -778,6 +787,7 @@
"clear": "Clear",
"clear_all": "Clear all",
"clear_all_recent_searches": "Clear all recent searches",
"clear_failed_count": "Clear failed ({count})",
"clear_file_cache": "Clear File Cache",
"clear_message": "Clear message",
"clear_value": "Clear value",
@@ -809,6 +819,7 @@
"comments_are_disabled": "Comments are disabled",
"common_create_new_album": "Create new album",
"completed": "Completed",
"configuration": "Configuration",
"confirm": "Confirm",
"confirm_admin_password": "Confirm Admin Password",
"confirm_delete_face": "Are you sure you want to delete {name} face from the asset?",
@@ -823,6 +834,7 @@
"contain": "Contain",
"context": "Context",
"continue": "Continue",
"control_bottom_app_bar_add_tags": "Add Tags",
"control_bottom_app_bar_create_new_album": "Create new album",
"control_bottom_app_bar_delete_from_immich": "Delete from Immich",
"control_bottom_app_bar_delete_from_local": "Delete from device",
@@ -836,6 +848,7 @@
"copy_error": "Copy error",
"copy_file_path": "Copy file path",
"copy_image": "Copy Image",
"copy_json": "Copy JSON",
"copy_link": "Copy link",
"copy_link_to_clipboard": "Copy link to clipboard",
"copy_password": "Copy password",
@@ -885,17 +898,16 @@
"cutoff_date_description": "Keep photos from the last…",
"cutoff_day": "{count, plural, one {day} other {days}}",
"cutoff_year": "{count, plural, one {year} other {years}}",
"daily_title_text_date": "E, MMM dd",
"daily_title_text_date_year": "E, MMM dd, yyyy",
"dark": "Dark",
"dark_theme": "Switch to dark theme",
"date": "Date",
"date_after": "Date after",
"date_and_time": "Date and Time",
"date_before": "Date before",
"date_format": "E, LLL d, y • h:mm a",
"date_of_birth": "Date of birth",
"date_of_birth_saved": "Date of birth saved successfully",
"date_range": "Date range",
"date_time_original": "Date/Time Original",
"day": "Day",
"days": "Days",
"deduplicate_all": "Deduplicate All",
@@ -974,7 +986,10 @@
"downloading_asset_filename": "Downloading asset {filename}",
"downloading_from_icloud": "Downloading from iCloud",
"downloading_media": "Downloading media",
"drag_to_reorder": "Drag to reorder",
"drop_files_to_upload": "Drop files anywhere to upload",
"duplicate": "Duplicate",
"duplicate_workflow": "Duplicate workflow",
"duplicates": "Duplicates",
"duplicates_description": "Resolve each group by indicating which, if any, are duplicates.",
"duration": "Duration",
@@ -1076,6 +1091,7 @@
"failed_to_remove_product_key": "Failed to remove product key",
"failed_to_reset_pin_code": "Failed to reset PIN code",
"failed_to_stack_assets": "Failed to stack assets",
"failed_to_tag_assets": "Failed to tag assets",
"failed_to_unstack_assets": "Failed to un-stack assets",
"failed_to_update_notification_status": "Failed to update notification status",
"incorrect_email_or_password": "Incorrect email or password",
@@ -1195,11 +1211,13 @@
"export_as_json": "Export as JSON",
"export_database": "Export Database",
"export_database_description": "Export the SQLite database",
"exposure_time": "Exposure Time",
"extension": "Extension",
"external": "External",
"external_libraries": "External Libraries",
"external_network": "External network",
"external_network_sheet_info": "When not on the preferred Wi-Fi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
"f_number": "F-Number",
"face_unassigned": "Unassigned",
"failed": "Failed",
"failed_count": "Failed: {count}",
@@ -1217,7 +1235,6 @@
"features_setting_description": "Manage the app features",
"file_name_or_extension": "File name or extension",
"file_name_text": "File name",
"file_name_with_value": "File name: {file_name}",
"file_size": "File size",
"filename": "Filename",
"filetype": "Filetype",
@@ -1230,6 +1247,7 @@
"find_them_fast": "Find them fast by name with search",
"first": "First",
"fix_incorrect_match": "Fix incorrect match",
"focal_length": "Focal Length",
"folder": "Folder",
"folder_not_found": "Folder not found",
"folders": "Folders",
@@ -1240,6 +1258,7 @@
"free_up_space_description": "Move backed-up photos and videos to your device's trash to free up space. Your copies on the server remain safe.",
"free_up_space_settings_subtitle": "Free up device storage",
"full_path": "Full path: {path}",
"full_path_or_folder": "Full path or folder",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "This feature loads external resources from Google in order to work.",
"general": "General",
@@ -1349,6 +1368,7 @@
"ios_debug_info_no_sync_yet": "No background sync job has run yet",
"ios_debug_info_processes_queued": "{count, plural, one {{count} background process queued} other {{count} background processes queued}}",
"ios_debug_info_processing_ran_at": "Processing ran {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# item} other {# items}}",
"jobs": "Jobs",
"json_editor": "JSON editor",
@@ -1402,6 +1422,7 @@
"link_to_oauth": "Link to OAuth",
"linked_oauth_account": "Linked OAuth account",
"list": "List",
"live": "Live",
"loading": "Loading",
"loading_search_results_failed": "Loading search results failed",
"local": "Local",
@@ -1523,6 +1544,38 @@
"marked_all_as_read": "Marked all as read",
"matches": "Matches",
"matching_assets": "Matching Assets",
"media_chrome": {
"auto": "Auto",
"captions": "Captions",
"captions_off": "Off",
"closed_captions": "closed captions",
"decode_error": "Decode error",
"disable_captions": "Disable captions",
"enable_captions": "Enable captions",
"enter_fullscreen_mode": "Enter fullscreen mode",
"exit_fullscreen_mode": "Exit fullscreen mode",
"loop": "Loop",
"media_error_description": "A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.",
"media_loading": "media loading",
"mute": "Mute",
"network_error": "Network error",
"network_error_description": "A network error caused the media download to fail.",
"not_supported_error": "Source Not Supported",
"playback_rate": "Playback rate",
"playback_rate_current": "current playback rate",
"playback_rate_value": "Playback rate {playbackRate}",
"playback_time": "playback time",
"quality": "Quality",
"second": "second",
"seconds": "seconds",
"time_value_of_total_time": "{currentTime} of {totalTime}",
"time_value_remaining": "{time} remaining",
"unmute": "Unmute",
"unsupported_error_description": "An unsupported error occurred. The server or network failed, or your browser does not support this format.",
"video_not_loaded_unknown_time": "video not loaded, unknown time.",
"video_player": "video player",
"volume": "volume"
},
"media_type": "Media type",
"memories": "Memories",
"memories_all_caught_up": "All caught up",
@@ -1539,6 +1592,8 @@
"merge_people_prompt": "Do you want to merge these people? This action is irreversible.",
"merge_people_successfully": "Merge people successfully",
"merged_people_count": "Merged {count, plural, one {# person} other {# people}}",
"minFaces": "Minimum faces",
"minFaces_description": "The minimum number of recognized faces for a person to be displayed",
"minimize": "Minimize",
"minute": "Minute",
"minutes": "Minutes",
@@ -1548,9 +1603,10 @@
"mobile_app": "Mobile App",
"mobile_app_download_onboarding_note": "Download the companion mobile app using the following options",
"model": "Model",
"modify_date": "Modify Date",
"month": "Month",
"monthly_title_text_date_format": "MMMM y",
"more": "More",
"motion": "Motion",
"move": "Move",
"move_down": "Move down",
"move_off_locked_folder": "Move out of locked folder",
@@ -1596,7 +1652,6 @@
"next": "Next",
"next_memory": "Next memory",
"no": "No",
"no_actions_added": "No actions added yet",
"no_albums_found": "No albums found",
"no_albums_message": "Create an album to organize your photos and videos",
"no_albums_with_name_yet": "It looks like you do not have any albums with this name yet.",
@@ -1613,7 +1668,6 @@
"no_exif_info_available": "No exif info available",
"no_explore_results_message": "Upload more photos to explore your collection.",
"no_favorites_message": "Add favorites to quickly find your best pictures and videos",
"no_filters_added": "No filters added yet",
"no_libraries_message": "Create an external library to view your photos and videos",
"no_local_assets_found": "No local assets found with this checksum",
"no_location_set": "No location set",
@@ -1626,6 +1680,7 @@
"no_results": "No results",
"no_results_description": "Try a synonym or more general keyword",
"no_shared_albums_message": "Create an album to share photos and videos with people in your network",
"no_steps": "No steps added yet",
"no_uploads_in_progress": "No uploads in progress",
"none": "None",
"not_allowed": "Not allowed",
@@ -1671,6 +1726,7 @@
"organize_into_albums": "Organize into albums",
"organize_into_albums_description": "Put existing photos into albums using current sync settings",
"organize_your_library": "Organize your library",
"orientation": "Orientation",
"original": "original",
"other": "Other",
"other_devices": "Other devices",
@@ -1761,8 +1817,9 @@
"play_original_video": "Play original video",
"play_original_video_setting_description": "Prefer playback of original videos rather than transcoded videos. If original asset is not compatible it may not playback correctly.",
"play_transcoded_video": "Play transcoded video",
"playback_speed": "Playback speed",
"please_auth_to_access": "Please authenticate to access",
"plugin_method_filter_type": "Filter",
"plugin_method_filter_type_description": "This method can filter events and conditionally prevent subsequent steps from running",
"port": "Port",
"preferences_settings_subtitle": "Manage the app's preferences",
"preferences_settings_title": "Preferences",
@@ -1784,6 +1841,7 @@
"profile_drawer_readonly_mode": "Read-only mode enabled. Long-press the user avatar icon to exit.",
"profile_image_of_user": "Profile image of {user}",
"profile_picture_set": "Profile picture set.",
"projection_type": "Projection Type",
"public_album": "Public album",
"public_share": "Public Share",
"purchase_account_info": "Supporter",
@@ -1861,6 +1919,7 @@
"remove_assets_title": "Remove assets?",
"remove_custom_date_range": "Remove custom date range",
"remove_deleted_assets": "Remove Deleted Assets",
"remove_filter": "Remove filter",
"remove_from_album": "Remove from album",
"remove_from_album_action_prompt": "{count} removed from the album",
"remove_from_favorites": "Remove from favorites",
@@ -1943,6 +2002,8 @@
"search_by_description_example": "Hiking day in Sapa",
"search_by_filename": "Search by file name or extension",
"search_by_filename_example": "i.e. IMG_1234.JPG or PNG",
"search_by_full_path": "Search by full path or folder",
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - you can search for Projects, 3D, Printing, 2026 etc.",
"search_by_ocr": "Search by OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Search lens model...",
@@ -2150,7 +2211,9 @@
"show_in_timeline": "Show in timeline",
"show_in_timeline_setting_description": "Show photos and videos from this user in your timeline",
"show_keyboard_shortcuts": "Show keyboard shortcuts",
"show_less": "Show less",
"show_metadata": "Show metadata",
"show_more_fields": "{count, plural, one {Show # more field} other {Show # more fields}}",
"show_or_hide_info": "Show or hide info",
"show_password": "Show password",
"show_person_options": "Show person options",
@@ -2158,6 +2221,7 @@
"show_schema": "Show schema",
"show_search_options": "Show search options",
"show_shared_links": "Show shared links",
"show_slideshow_metadata_overlay": "Show image info overlay",
"show_slideshow_transition": "Show slideshow transition",
"show_supporter_badge": "Supporter badge",
"show_supporter_badge_description": "Show a supporter badge",
@@ -2173,9 +2237,13 @@
"skip_to_folders": "Skip to folders",
"skip_to_tags": "Skip to tags",
"slideshow": "Slideshow",
"slideshow_metadata_overlay_mode": "Overlay content",
"slideshow_metadata_overlay_mode_description_only": "Description only",
"slideshow_metadata_overlay_mode_full": "Full",
"slideshow_repeat": "Repeat slideshow",
"slideshow_repeat_description": "Loop back to beginning when slideshow ends",
"slideshow_settings": "Slideshow settings",
"smart_album": "Smart album",
"sort_albums_by": "Sort albums by...",
"sort_created": "Date created",
"sort_items": "Number of items",
@@ -2198,6 +2266,11 @@
"start_date_before_end_date": "Start date must be before end date",
"state": "State",
"status": "Status",
"step_delete": "Delete step",
"step_delete_confirm": "Are you sure you want to delete this step?",
"step_details": "Step details",
"steps": "Steps",
"steps_count": "{count, plural, one {# step} other {# steps}}",
"stop_casting": "Stop casting",
"stop_motion_photo": "Stop Motion Photo",
"stop_photo_sharing": "Stop sharing your photos?",
@@ -2291,7 +2364,7 @@
"trash_page_title": "Trash ({count})",
"trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.",
"trigger": "Trigger",
"trigger_asset_uploaded": "Asset Uploaded",
"trigger_asset_uploaded": "Asset Upload",
"trigger_asset_uploaded_description": "Triggered when a new asset is uploaded",
"trigger_description": "An event that kicks off the workflow",
"trigger_person_recognized": "Person Recognized",
@@ -2331,7 +2404,6 @@
"unsupported_field_type": "Unsupported field type",
"unsupported_file_type": "File {file} can't be uploaded because its file type {type} is not supported.",
"untagged": "Untagged",
"untitled_workflow": "Untitled workflow",
"up_next": "Up next",
"update_location_action_prompt": "Update the location of {count} selected assets with:",
"updated_at": "Updated",
@@ -2360,6 +2432,7 @@
"use_browser_locale_description": "Format dates, times, and numbers based on your browser locale",
"use_current_connection": "Use current connection",
"use_custom_date_range": "Use custom date range instead",
"use_template": "Use template",
"user": "User",
"user_has_been_deleted": "This user has been deleted.",
"user_id": "User ID",
@@ -2389,6 +2462,7 @@
"video": "Video",
"video_hover_setting": "Play video thumbnail on hover",
"video_hover_setting_description": "Play video thumbnail when mouse is hovering over item. Even when disabled, playback can be started by hovering over the play icon.",
"video_quality": "Video quality",
"videos": "Videos",
"videos_count": "{count, plural, one {# Video} other {# Videos}}",
"videos_only": "Videos only",
@@ -2421,8 +2495,10 @@
"week": "Week",
"welcome": "Welcome",
"welcome_to_immich": "Welcome to Immich",
"when": "When",
"width": "Width",
"wifi_name": "Wi-Fi Name",
"workflow": "Workflow",
"workflow_delete_prompt": "Are you sure you want to delete this workflow?",
"workflow_deleted": "Workflow deleted",
"workflow_description": "Workflow description",
@@ -2432,6 +2508,7 @@
"workflow_name": "Workflow name",
"workflow_navigation_prompt": "Are you sure you want to leave without saving your changes?",
"workflow_summary": "Workflow summary",
"workflow_templates": "Workflow templates",
"workflow_update_success": "Workflow updated successfully",
"workflow_updated": "Workflow updated",
"workflows": "Workflows",
+483 -20
View File
@@ -22,13 +22,12 @@
"add_birthday": "Aldoni naskiĝtagon",
"add_endpoint": "Aldoni finpunkton",
"add_exclusion_pattern": "Aldoni skemon de ekskludo",
"add_filter": "Aldoni filtrilon",
"add_filter_description": "Klaku por aldoni kondiĉon por filtri",
"add_location": "Aldoni lokon",
"add_more_users": "Aldoni pli da uzantoj",
"add_partner": "Aldoni partneron",
"add_path": "Aldoni vojon",
"add_photos": "Aldoni fotojn",
"add_step": "Aldoni paŝon",
"add_tag": "Aldoni etikedon",
"add_to": "Aldoni al…",
"add_to_album": "Aldoni al albumo",
@@ -42,7 +41,6 @@
"add_to_shared_album": "Aldoni al dividita albumo",
"add_upload_to_stack": "Aldoni alŝutitajn elementojn al stako",
"add_url": "Aldoni URL-on",
"add_workflow_step": "Aldoni paŝon al laborfluo",
"added_to_archive": "Aldonita(j) al arĥivo",
"added_to_favorites": "Aldonita(j) al preferataĵoj",
"added_to_favorites_count": "Adonis {count, number} al preferataĵoj",
@@ -65,7 +63,7 @@
"backup_onboarding_footer": "Por pli da informoj pri savkopioj kun Immich, bonvolu legi la <link>dokumentaron</link>.",
"backup_onboarding_parts_title": "Sekur-kopioj laŭ strategio 3-2-1 inkluzivas:",
"backup_onboarding_title": "Savkopioj",
"backup_settings": "Agordoj de kopiado de datumbazo",
"backup_settings": "Agordoj pri kopiado de datumbazo",
"backup_settings_description": "Administri agordojn pri datumbazo-nekropsio.",
"cleared_jobs": "Taskoj forigitaj por: {job}",
"config_set_by_file": "La agordoj estas aktuale regitaj de agordo-dosiero",
@@ -118,7 +116,7 @@
"job_concurrency": "{job}: nombro de samtempaj taskoj",
"job_created": "Tasko kreita",
"job_not_concurrency_safe": "Estas nesekure fari tiun ĉi taskon samtempe kun aliaj.",
"job_settings": "Agordoj pri tasko",
"job_settings": "Agordoj pri taskoj",
"job_settings_description": "Administri samtempajn taskojn",
"jobs_delayed": "{jobCount, plural, other {# prokrastitaj}}",
"jobs_failed": "{jobCount, plural, other {# malsukesis}}",
@@ -212,7 +210,7 @@
"map_enable_description": "Ŝalti map-funkciojn",
"map_gps_settings": "Agordaĵoj pri mapoj kaj GPS",
"map_gps_settings_description": "Administri agordojn pri mapoj kaj GPS",
"map_implications": "Montri mapojn de dependas de ekstera servo (tiles.immich.cloud)",
"map_implications": "Montri mapojn dependas de ekstera servo (tiles.immich.cloud)",
"map_light_style": "Hela stilo",
"map_manage_reverse_geocoding_settings": "Administri agordojn pri <link>inversa geo-kodigo</link>",
"map_reverse_geocoding": "Inversa geo-kodigo",
@@ -267,6 +265,8 @@
"notification_enable_email_notifications": "Ŝalti sciigojn per retmesaĝo",
"notification_settings": "Agordoj pri sciigoj",
"notification_settings_description": "Administri agordojn pri sciigoj, inkluzive tiujn per retmesaĝoj",
"oauth_allow_insecure_requests": "Permesi nesekurajn petojn",
"oauth_allow_insecure_requests_description": "ATENTU: tio ĉi malŝaltas validigon de TLS-atestiloj por OAuth-petoj, kaj lasas vin sendefenda kontraŭ kaŝa interkaptado de komunikado (man-in-the-middle).",
"oauth_auto_launch": "Startigi aŭtomate",
"oauth_auto_launch_description": "Aŭtomate startigi la OAuth-procezon tuj ĉe la ensaluta paĝo",
"oauth_auto_register": "Registri aŭtomate",
@@ -274,9 +274,11 @@
"oauth_button_text": "Teksto de butono",
"oauth_client_secret_description": "Bezonata por privata kliento, aŭ se PKCE (Proof Key for Code Exchange) ne estas subtenata de publika kliento.",
"oauth_enable_description": "Ensaluti per OAuth",
"oauth_end_session_url_description": "Resendi uzanton al tiu ĉi URI post elsaluto.",
"oauth_mobile_redirect_uri": "Resenda URI por poŝ-aparatoj",
"oauth_mobile_redirect_uri_override": "Insisti pri resenda URI por poŝ-aparatoj",
"oauth_mobile_redirect_uri_override_description": "Ŝaltu tion ĉi kiam la provizanto de OAuth ne permesas URI-on por poŝ-aparatoj, kiel \"{callback}\"",
"oauth_prompt_description": "Parametro de invito (ekz. select_account, login, consent)",
"oauth_role_claim": "Petita rolo",
"oauth_role_claim_description": "Aŭtomate doni rolon de administranto laŭ tiu ĉi peto. La peto povas esti aŭ 'user' (uzanto) aŭ 'admin' (administranto).",
"oauth_settings": "OAuth",
@@ -303,6 +305,8 @@
"refreshing_all_libraries": "Aktualigado de ĉiuj bibliotekoj",
"registration": "Registrado de administranto",
"registration_description": "Vi estas la unua uzanto de tiu ĉi sistemo, do vi aŭtomate havos la rolon de administranto. Vi respondecos pri administraj taskoj, kaj vi povos krei pliajn uzantojn.",
"release_channel_release_candidate": "Lanĉkandidato",
"release_channel_stable": "Stabila",
"remove_failed_jobs": "Forigi malsukcesajn taskojn",
"require_password_change_on_login": "Devigi al uzantoj ŝanĝi pasvorton post unua ensaluto",
"reset_settings_to_default": "Restarigi agordaĵojn al defaŭltoj",
@@ -314,7 +318,7 @@
"server_external_domain_settings_description": "Domajno por eksteraj ligiloj",
"server_public_users": "Publikaj uzantoj",
"server_public_users_description": "Nomo kaj retadreso de ĉiuj uzantoj estas listigitaj kiam oni aldonas uzanton al dividita albumo. Kiam malŝaltita, la listo de uzantoj estos videbla nur por administrantoj.",
"server_settings": "Agordoj de servilo",
"server_settings": "Agordoj pri servilo",
"server_settings_description": "Administri agordojn pri servilo",
"server_stats_page_description": "Paĝo de statistikoj pri la servilo",
"server_welcome_message": "Bonvena mesaĝo",
@@ -397,6 +401,10 @@
"transcoding_preferred_hardware_device_description": "Aplikiĝas nur al VAAPI kaj QSV. Indikas la DRI-nodoj uzataj por transkodado per aparato.",
"transcoding_preset_preset": "Antaŭelekto (-preset)",
"transcoding_preset_preset_description": "Rapideco de densigo. Malplia rapideco rezultas je pli malgrandaj dosieroj, kaj plibonigas kvaliton por donita bitrapido. VP9 ignoras rapidecojn pli grandajn ol 'faster'.",
"transcoding_realtime": "Realtempa transkodado [EKSPERIMENTA]",
"transcoding_realtime_description": "Ebligas transkodadon samtempe kun spektado per elsendfluo. Tio ebligas ŝanĝon de kvalito laŭvole, sed povas kaŭzi pli da atendotempo kaj interrompoj, depende de la kapacito de la servilo.",
"transcoding_realtime_enabled": "Ŝalti realtempan transkodadon",
"transcoding_realtime_enabled_description": "Se malŝaltita, la servilo rifuzas komenci novajn sesiojn de realtempa transkodado.",
"transcoding_reference_frames": "Referencaj kadroj",
"transcoding_reference_frames_description": "La nombro da apudaj kadroj uzataj dum densigo de iu kadro. Pli granda valoro rezultas je pli bona densigo, sed malpli rapida laboro. Valoro de 0 indikas aŭtomatan agordon.",
"transcoding_required_description": "Nur videoj kun neakceptataj formatoj",
@@ -436,10 +444,12 @@
"user_password_reset_description": "Bonvolu sendi la dumtempan pasvorton al la uzanto, kaj informu ke ĝi devos esti ŝanĝita je la sekva ensaluto.",
"user_restore_description": "La konto de <b>{user}</b> estos restaŭrita.",
"user_restore_scheduled_removal": "Restaŭri uzanton - forviŝo planita je {date, date, long}",
"user_settings": "Agordoj de uzanto",
"user_settings": "Agordoj pri uzantoj",
"user_settings_description": "Administri agordojn pri uzantoj",
"user_successfully_removed": "La uzanto {email} estas forigita.",
"users_page_description": "Paĝo por administri uzantojn",
"version_check_channel": "Eldono-kanalo",
"version_check_channel_description": "Elektu la eldono-kanalon pri kiu vi volas ricevi anoncojn de novaj versioj",
"version_check_enabled_description": "Ebligi kontrolon de versio",
"version_check_implications": "La funkcio de kontrolado de versio bezonas de temp' al tempan komunikadon kun {server}",
"version_check_settings": "Kontrolo de versio",
@@ -555,8 +565,8 @@
"are_these_the_same_person": "Ĉu la sama homo?",
"are_you_sure_to_do_this": "Ĉu vi certas, ke vi volas fari tion?",
"array_field_not_fully_supported": "Tablaj kampoj postulas permanan redakton de JSON",
"asset_action_delete_err_read_only": "Ne eblas forigi nurlegajn elementojn, ili estos lasitaj senŝanĝaj",
"asset_action_share_err_offline": "Ne eblis repreni nekonektitajn elementojn, ili estos ignoritaj",
"asset_action_delete_err_read_only": "Preterlasas forigon de nurlegaj elementoj, ĉar tio ne eblas",
"asset_action_share_err_offline": "Preterlasas reprenon de nekonektitaj elementoj, ĉar tio ne eblas",
"asset_added_to_album": "Aldonita al albumo",
"asset_adding_to_album": "Aldonas al albumo…",
"asset_created": "Elemento kreita",
@@ -696,9 +706,10 @@
"birthdate_saved": "Naskiĝdato ŝukcese konservita",
"birthdate_set_description": "La naskiĝdato estas uzita por kalkuli la aĝon de la homo je la momento de iu foto.",
"blurred_background": "Malklarigita fono",
"browse_templates": "Foliumi ŝablonojn",
"bugs_and_feature_requests": "Cimoj kaj petoj por novaj funkcioj",
"build": "Versio",
"build_image": "Bildo de la versio",
"build_image": "Pakaĵo por instali tiun ĉi softvaron",
"bulk_delete_duplicates_confirmation": "Ĉu vi certas, ke vi volas amase forigi {count, plural, one {# duoblaĵon} other {# duoblaĵojn}}? Tiel, vi konservos la plej grandan elementon el ĉiu grupo kaj porĉiame forigos duoblaĵojn. Ne eblas malfari tion!",
"bulk_keep_duplicates_confirmation": "Ĉu vi certas, ke vi volas konservi {count, plural, one {# duoblaĵon} other {# duoblaĵojn}}? Tio solvos ĉiujn duoblajn grupojn sen forigi ion ajn.",
"bulk_trash_duplicates_confirmation": "Ĉu vi certas, ke vi volas amase forigi {count, plural, one {# duoblaĵon} other {# duoblaĵojn}}? Tiel, vi konservos la plej grandan elementon el ĉiu grupo kaj porĉiame forigos duoblaĵojn.",
@@ -729,6 +740,7 @@
"cannot_update_the_description": "Ne eblas ĝisdatigi la priskribon",
"cast": "Elsendi",
"cast_description": "Agordi disponeblajn celojn por elsendoj",
"change": "Ŝanĝi",
"change_date": "Ŝanĝi daton",
"change_description": "Ŝanĝi priskribon",
"change_display_order": "Ŝanĝi vicordon de vidigo",
@@ -757,6 +769,7 @@
"check_corrupt_asset_backup_description": "Fari tiun ĉi kontrolon nur per vifio kaj post kiam ĉiuj elementoj havas savkopion. La kontrolo povas daŭri kelkajn minutojn.",
"check_logs": "Kontroli protokolojn",
"checksum": "Kontrolsumo",
"choose": "Elekti",
"choose_matching_people_to_merge": "Elekti duobligitajn homojn por kunfandi",
"city": "Urbo",
"cleanup_confirm_description": "Immich trovis savkopion en la servilo de {count} elementoj (kreitajn antaŭ {date}). Ĉu vi volas forigi la kopiojn de el tiu ĉi aparato?",
@@ -805,6 +818,7 @@
"comments_are_disabled": "Komentoj estas malebligitaj",
"common_create_new_album": "Krei novan albumon",
"completed": "Finfarita",
"configuration": "Konfiguro",
"confirm": "Konfirmi",
"confirm_admin_password": "Konfirmi administran pasvorton",
"confirm_delete_face": "Ĉu vi certas ke vi volas forigi la vizaĝon de {name} de tiu elemento?",
@@ -819,6 +833,7 @@
"contain": "Alĝustigi",
"context": "Kunteksto",
"continue": "Daŭrigi",
"control_bottom_app_bar_add_tags": "Aldoni etikedojn",
"control_bottom_app_bar_create_new_album": "Krei novan albumon",
"control_bottom_app_bar_delete_from_immich": "Forigi el Immich",
"control_bottom_app_bar_delete_from_local": "Forigi el aparato",
@@ -832,6 +847,7 @@
"copy_error": "Kopii eraron",
"copy_file_path": "Kopii dosiervojon",
"copy_image": "Kopii bildon",
"copy_json": "Kopii JSON-on",
"copy_link": "Kopii ligilon",
"copy_link_to_clipboard": "Kopii ligilon al tondujo",
"copy_password": "Kopii pasvorton",
@@ -851,7 +867,7 @@
"create_new": "KREI NOVAN",
"create_new_face": "Krei novan vizaĝon",
"create_new_person": "Krei novan homon",
"create_new_person_hint": "Atribui elektitajn elementojn al nova homo",
"create_new_person_hint": "Konekti elektitajn elementojn al nova homo",
"create_new_user": "Krei novan uzanton",
"create_person": "Krei homon",
"create_person_subtitle": "Aldoni nomon al la elektita vizaĝo por krei kaj etikedi novan homon",
@@ -881,17 +897,16 @@
"cutoff_date_description": "Konservi fotojn el la lastaj…",
"cutoff_day": "{count, plural, one {tago} other {tagoj}}",
"cutoff_year": "{count, plural, one {jaro} other {jaroj}}",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Malhela",
"dark_theme": "Ŝanĝi al hela reĝimo",
"dark_theme": "Ŝanĝi al malhela reĝimo",
"date": "Dato",
"date_after": "Dato post",
"date_and_time": "Dato kaj horo",
"date_before": "Dato antaŭ",
"date_format": "E, LLL d, y • h:mm a",
"date_of_birth": "Naskiĝdato",
"date_of_birth_saved": "Naskiĝdato sukcese registrita",
"date_range": "Dato-intervalo",
"date_time_original": "Originalaj dato/horo",
"day": "Tago",
"days": "Tagoj",
"deduplicate_all": "Senduoblaĵigi ĉion",
@@ -970,7 +985,10 @@
"downloading_asset_filename": "Elŝutado de elemento {filename}",
"downloading_from_icloud": "Elŝutado el iCloud",
"downloading_media": "Elŝutado de elementoj",
"drag_to_reorder": "Ŝovi por reordigi",
"drop_files_to_upload": "Demetu dosierojn ĉi tien por alŝuti",
"duplicate": "Duobligi",
"duplicate_workflow": "Duobligi laborfluon",
"duplicates": "Duoblaĵoj",
"duplicates_description": "Solvu ĉiun grupon indikante tiujn, kiuj estas eventualaj duoblaĵoj.",
"duration": "Daŭro",
@@ -1072,6 +1090,7 @@
"failed_to_remove_product_key": "Malsukcesis forigi var-ŝalosilon",
"failed_to_reset_pin_code": "Malsukcesis restarigi PIN-kodon",
"failed_to_stack_assets": "Malsukcesis staki elementojn",
"failed_to_tag_assets": "Malsukesis etikedi elementojn",
"failed_to_unstack_assets": "Malsukcesis malstaki elementojn",
"failed_to_update_notification_status": "Malsukcesis ĝisdatigi statuson de sciigoj",
"incorrect_email_or_password": "Neĝusta retadreso aŭ pasvorto",
@@ -1088,41 +1107,403 @@
"unable_to_add_partners": "Ne eblas aldoni partnerojn",
"unable_to_add_remove_archive": "Ne eblas {archived, select, true {forigi elementon de} other {aldoni elementon al}} la arĥivo",
"unable_to_add_remove_favorites": "Ne eblas {favorite, select, true {aldoni elementon al} other {forigi elementon de}} preferataĵoj",
"unable_to_archive_unarchive": "Ne eblis {archived, select, true {enarĥivigi} other {elarĥivigi}}",
"unable_to_change_album_user_role": "Ne eblis ŝanĝi la rolon de la album-uzanto",
"unable_to_change_date": "Ne eblis ŝanĝi daton",
"unable_to_change_description": "Ne eblis ŝanĝi priskribon",
"unable_to_change_favorite": "Ne eblas ŝanĝi preferon por tiu elemento",
"unable_to_change_location": "Ne eblis ŝanĝi lokon",
"unable_to_change_password": "Ne eblis ŝanĝi pasvorton",
"unable_to_change_visibility": "Ne eblis ŝanĝi la videblecon por {count, plural, one {# homo} other {# homoj}}",
"unable_to_complete_oauth_login": "Ne eblis fini la ensaluto per OAuth",
"unable_to_connect": "Ne eblis konektiĝi",
"unable_to_copy_to_clipboard": "Ne eblas kopii al la tondujo; kontrolu ĉu vi konektiĝas per https",
"unable_to_create": "Ne eblis krei laborfluon",
"unable_to_create_admin_account": "Ne eblis krei konton de administranto",
"unable_to_create_api_key": "Ne eblis krei novan API-ŝlosilon",
"unable_to_create_library": "Ne eblis krei bibliotekon",
"unable_to_create_user": "Ne eblis krei uzanton",
"unable_to_delete_album": "Ne eblis forigi albumon",
"unable_to_delete_asset": "Ne eblis forigi elementon",
"unable_to_delete_assets": "Eraro okazis dum forigo de elementoj",
"unable_to_delete_exclusion_pattern": "Ne eblas forigi skemon de ekskludo",
"unable_to_delete_shared_link": "Ne eblis forigi dividitan ligilon",
"unable_to_delete_user": "Ne eblis forigi uzanton",
"unable_to_delete_workflow": "Ne eblis forigi laborfluon",
"unable_to_download_files": "Ne eblis elŝuti dosierojn",
"unable_to_edit_exclusion_pattern": "Ne eblas redakti skemon de ekskludo",
"unable_to_empty_trash": "Ne eblis malplenigi rubujon",
"unable_to_enter_fullscreen": "Ne eblis ŝalti plenekranan reĝimon",
"unable_to_exit_fullscreen": "Ne eblis eliĝi el plenekrana reĝimo",
"unable_to_get_comments_number": "Ne eblis trovi nombron da komentoj",
"unable_to_get_shared_link": "Ne eblis ekhavi dividitan ligilon",
"unable_to_hide_person": "Ne eblis kaŝi tiun homon",
"unable_to_link_motion_video": "Ne eblis ligi videon",
"unable_to_link_oauth_account": "Ne eblis ligi al OAuth-konto",
"unable_to_log_out_all_devices": "Ne eblis elsaluti el ĉiuj aparatoj",
"unable_to_log_out_device": "Ne eblis elsaluti el tiu aparato",
"unable_to_login_with_oauth": "Ne eblis ensaluti per OAuth",
"unable_to_play_video": "Ne eblis ludi videon",
"unable_to_reassign_assets_existing_person": "Ne eblis rekonekti elementojn al {name, select, null {ekzistanta homo} other {{name}}}",
"unable_to_reassign_assets_new_person": "Ne eblis konekti elementojn al nova homo",
"unable_to_refresh_user": "Ne eblis renovigi uzanton",
"unable_to_remove_album_users": "Ne eblis forigi uzantojn de albumo",
"unable_to_remove_api_key": "Ne eblis forigi API-ŝlosilo",
"unable_to_remove_assets_from_shared_link": "Ne eblis forigi elementojn el dividita ligilo",
"unable_to_remove_library": "Ne eblis forigi bibliotekon",
"unable_to_remove_partner": "Ne eblis forigi partneron",
"unable_to_remove_reaction": "Ne eblis forigi reagon",
"unable_to_reset_password": "Ne eblis restarigi pasvorton",
"unable_to_reset_pin_code": "Ne eblis restarigi PIN-kodon",
"unable_to_resolve_duplicate": "Ne eblis solvi tiun ĉi duoblaĵon",
"unable_to_restore_assets": "Ne eblis restaŭri elementojn",
"unable_to_restore_trash": "Ne eblis restaŭri rubaĵojn",
"unable_to_restore_user": "Ne eblis restaŭri uzanton",
"unable_to_save_album": "Ne eblis konservi albumon",
"unable_to_save_api_key": "Ne eblis konservi API-ŝlosilon",
"unable_to_save_date_of_birth": "Ne eblis konservi naskiĝdaton",
"unable_to_save_name": "Ne eblis konservi nomon",
"unable_to_save_profile": "Ne eblis konservi profilon",
"unable_to_save_settings": "Ne eblis konservi agordojn",
"unable_to_scan_libraries": "Ne eblas analizi biblitekojn",
"unable_to_scan_library": "Ne eblas analizi biblitekon",
"unable_to_update_workflow": "Ne eblis ĝisdatigi laborfluon"
"unable_to_set_feature_photo": "Ne eblis agordi ĉap-foton",
"unable_to_set_profile_picture": "Ne eblis agordi profilbildon",
"unable_to_set_rating": "Ne eblis konservi pritakson",
"unable_to_submit_job": "Ne eblis plenumi taskon",
"unable_to_trash_asset": "Ne eblis forigi elementon",
"unable_to_unlink_account": "Ne eblis malligi konton",
"unable_to_unlink_motion_video": "Ne eblis malligi movbildon",
"unable_to_update_album_cover": "Ne eblis ŝanĝi kovrilon de albumo",
"unable_to_update_album_info": "Ne eblis ŝanĝi informojn pri albumo",
"unable_to_update_library": "Ne eblis ĝisdatigi bibliotekon",
"unable_to_update_location": "Ne eblis ŝanĝi lokon",
"unable_to_update_settings": "Ne eblis ĝisdatigi agordojn",
"unable_to_update_timeline_display_status": "Ne eblis ŝanĝi tiun agordon por la partnero",
"unable_to_update_user": "Ne eblis ĝisdatigi uzanton",
"unable_to_update_workflow": "Ne eblis ĝisdatigi laborfluon",
"unable_to_upload_file": "Ne eblis alŝuti dosieron"
},
"errors_text": "Eraroj",
"exclusion_pattern": "Skemo de ekskludo",
"exif": "Exif",
"exif_bottom_sheet_description": "Aldoni priskribon...",
"exif_bottom_sheet_description_error": "Eraro dum ĝisdatigo de priskribo",
"exif_bottom_sheet_details": "DETALOJ",
"exif_bottom_sheet_location": "LOKO",
"exif_bottom_sheet_no_description": "Neniu priskribo",
"exif_bottom_sheet_people": "HOMOJ",
"exif_bottom_sheet_person_add_person": "Aldoni nomon",
"exit_slideshow": "Fini bildserion",
"expand": "Etendi",
"expand_all": "Etendi ĉiujn",
"experimental_settings_new_asset_list_subtitle": "Prilaborataĵoj",
"experimental_settings_new_asset_list_title": "Ŝalti eksperimentan foto-kradon",
"experimental_settings_subtitle": "Uzu je propra risko!",
"experimental_settings_title": "Eksperimenta",
"expire_after": "Eksvalidigi post",
"expired": "Eksvalida",
"expires_date": "Eksvalidiĝos je {date}",
"explore": "Esplori",
"explorer": "Foliumilo",
"export": "Eksporti",
"export_as_json": "Eksporti kiel JSON",
"export_database": "Eksporti datumbazon",
"export_database_description": "Eksporti la SQLite-datumbazon",
"exposure_time": "Ekspono-tempo",
"extension": "Sufikso",
"external": "Ekstera",
"external_libraries": "Eksteraj bibliotekoj",
"external_network": "Ekstera reto",
"external_network_sheet_info": "Kiam la preferata vifio estas netrovebla, la apo provos konektiĝi al la servilo per la ĉi-suba listo de URL-oj, ekde la unua",
"f_number": "F-numero",
"face_unassigned": "Ne konektitaj",
"failed": "Malsukcesis",
"failed_count": "Malsukcesis: {count}",
"failed_to_authenticate": "Malsukcesis ensaluti",
"failed_to_load_assets": "Malsukcesis ŝargi elementojn",
"failed_to_load_folder": "Malsukcesis ŝargi dosierujon",
"favorite": "Preferataĵo",
"favorite_action_prompt": "{count} aldonita(j) al Preferataĵoj",
"favorite_or_unfavorite_photo": "Aldoni/forigi foton al/de preferataĵoj",
"favorites": "Preferataĵoj",
"favorites_page_no_favorites": "Neniuj preferataj elementoj trovitaj",
"feature_photo_updated": "Ĉap-foto sukcese ŝanĝita",
"features": "Funkcioj",
"features_in_development": "Funkcioj ankoraŭ prilaborataj",
"features_setting_description": "Administri funkciojn de la apo",
"file_name_or_extension": "Dosiernomo aŭ sufikso",
"file_name_text": "Dosiernomo",
"file_size": "Grandeco de dosiero",
"filename": "Dosiernomo",
"filetype": "Tipo de dosiero",
"filter": "Filtri",
"filter_description": "Kondiĉoj por trovi la celitajn elementojn",
"filter_people": "Filtri laŭ homoj",
"filter_places": "Filtri laŭ lokoj",
"filter_tags": "Filtri laŭ etikedoj",
"filters": "Filtriloj",
"find_them_fast": "Rapide retrovi la homon per ties nomo",
"first": "Unua",
"fix_incorrect_match": "Korekti malĝustan kongruiĝon",
"focal_length": "Interfokusa distanco",
"folder": "Dosierujo",
"folder_not_found": "Dosierujo netrovita",
"folders": "Dosierujoj",
"folders_feature_description": "Foliumado en dosierujoj por la fotoj kaj videoj en la sistemo",
"forgot_pin_code_question": "Ĉu vi forgesis vian PIN-kodon?",
"forward": "Antaŭen",
"free_up_space": "Liberigi spacon",
"free_up_space_description": "Vi forigos fotojn kaj/aŭ videojn, kiuj havas savkopiojn en la servilo, por liberigi spacon en via aparato. La kopioj en la servilo restos.",
"free_up_space_settings_subtitle": "Liberigi spacon en aparato",
"full_path": "Plena dosiervojo: {path}",
"full_path_or_folder": "Plena vojo aŭ dosierujo",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Tiu ĉi funkcio ŝargas eksterajn rimedojn de Google por sia funkciado.",
"general": "Ĝeneralaj",
"home_page_favorite_err_local": "Ankoraŭ ne eblas aldoni lokajn elementojn al Preferataĵoj; ignorita(j)",
"home_page_favorite_err_partner": "Ankoraŭ ne eblas aldoni elementojn de partnero al Preferataĵoj; ignorita(j)",
"geolocation_instruction_location": "Elektu elementon kun GPS-koordinatoj por uzi ĝian lokon, aŭ elektu lokon rekte sur la mapo",
"get_help": "Trovi helpon",
"get_people_error": "Eraro dum serĉo de homoj",
"get_wifiname_error": "Ne eblis trovi nomon de vifio. Kontrolu, ke vi donis bezonatan permeson, kaj estas konektita al vifia reto",
"getting_started": "Unuaj paŝoj",
"go_back": "Reiri",
"go_to_folder": "Vidigi dosierujon",
"go_to_search": "Serĉilo",
"gps": "GPS",
"gps_missing": "Neniu GPS",
"grant_permission": "Doni permeson",
"group_albums_by": "Grupigi albumojn laŭ...",
"group_country": "Grupigi laŭ lando",
"group_no": "Neniu grupigo",
"group_owner": "Grupigi laŭ posedanto",
"group_places_by": "Grupigi lokojn laŭ...",
"group_year": "Grupigi laŭ jaro",
"haptic_feedback_switch": "Ŝalti tuŝ-retrokuplon",
"haptic_feedback_title": "Tuŝ-retrokuplo",
"has_quota": "Kvoto",
"hash_asset": "Haketi elementon",
"hashed_assets": "Haketitaj elementoj",
"hashing": "Haketado",
"header_settings_add_header_tip": "Aldoni kapon",
"header_settings_field_validator_msg": "Ne eblas lasi tion malplena",
"header_settings_header_name_input": "Nomo de kapo",
"header_settings_header_value_input": "Valoro de kapo",
"headers_settings_tile_title": "Propraj kapoj de prokurilo",
"height": "Alto",
"hi_user": "Saluton {name} ({email})",
"hide_all_people": "Kaŝi ĉiujn homojn",
"hide_gallery": "Kaŝi galerion",
"hide_named_person": "Kaŝi homon {name}",
"hide_password": "Kaŝi pasvorton",
"hide_person": "Kaŝi homon",
"hide_schema": "Kaŝi skemon",
"hide_text_recognition": "Kaŝi rekonadon de teksto",
"hide_unnamed_people": "Kaŝi nenomitajn homojn",
"home_page_add_to_album_conflicts": "Aldonis {added} elementojn al la albumo {album}. {failed} elementoj jam estis en la albumo.",
"home_page_add_to_album_err_local": "Preterlasas aldonon de lokaj elementoj al albumo, ĉar tio ankoraŭ ne eblas",
"home_page_add_to_album_success": "Aldonis {added} elementojn al la albumo {album}.",
"home_page_album_err_partner": "Preterlasas aldonon de partneraj elementoj al albumo, ĉar tio ankoraŭ ne eblas",
"home_page_archive_err_local": "Preterlasas enarĥivigon de lokaj elementoj, ĉar tio ankoraŭ ne eblas",
"home_page_archive_err_partner": "Preterlasas enarĥivigon de partneraj elementoj, ĉar tio ne eblas",
"home_page_building_timeline": "Konstruado de tempolinio",
"home_page_delete_err_partner": "Preterlasas forigon de partneraj elementoj, ĉar tio ne eblas",
"home_page_delete_remote_err_local": "Preterlasas forigon de lokaj elementoj dum malloka forigado, ĉar tio ne eblas",
"home_page_favorite_err_local": "Preterlasas aldonon de lokaj elementoj al Preferataĵoj, ĉar tio ankoraŭ ne eblas",
"home_page_favorite_err_partner": "Preterlasas aldonon de partneraj elementoj al Preferataĵoj, ĉar tio ankoraŭ ne eblas",
"home_page_first_time_notice": "Se vi nun unuafoje uzas la apon, ne forgesu elekti savkopian albumon por ke la tempolinio povu tie kreiĝu per viaj fotoj kaj videoj",
"home_page_locked_error_local": "Preterlasas movon de lokaj elementoj al ŝlosita dosierujo, ĉar tio ne eblas",
"home_page_locked_error_partner": "Preterlasas aldonon de partneraj elementoj al ŝlosita dosierujo, ĉar tio ne eblas",
"home_page_share_err_local": "Preterlasas dividon de lokaj elementoj per ligilo, ĉar tio ne eblas",
"home_page_upload_err_limit": "Preterlasas alŝuto de pli ol 30 elementoj samtempe, ĉar tio ne eblas",
"host": "Gastiganto",
"hour": "Horo",
"hours": "Horoj",
"id": "ID",
"idle": "Senokupa",
"ignore_icloud_photos": "Ignori fotojn el iCloud",
"ignore_icloud_photos_description": "Fotoj stokitaj en iCloud ne estos alŝutitaj al la servilo de Immich",
"image": "Bildo",
"image_alt_text_date": "{isVideo, select, true {Video} other {Image}} farita je {date}",
"image_alt_text_date_1_person": "{isVideo, select, true {Video} other {Image}} farita kun {person1} je {date}",
"image_alt_text_date_2_people": "{isVideo, select, true {Video} other {Image}} farita kun {person1} kaj {person2} je {date}",
"image_alt_text_date_3_people": "{isVideo, select, true {Video} other {Image}} farita kun {person1}, {person2}, kaj {person3} je {date}",
"image_alt_text_date_4_or_more_people": "{isVideo, select, true {Video} other {Image}} farita kun {person1}, {person2}, kaj {additionalCount, number} aliaj homoj je {date}",
"image_alt_text_date_place": "{isVideo, select, true {Video} other {Image}} farita en {city}, {country} je {date}",
"image_alt_text_date_place_1_person": "{isVideo, select, true {Video} other {Image}} farita en {city}, {country} kun {person1} je {date}",
"image_alt_text_date_place_2_people": "{isVideo, select, true {Video} other {Image}} farita en {city}, {country} kun {person1} kaj {person2} je {date}",
"image_alt_text_date_place_3_people": "{isVideo, select, true {Video} other {Image}} farita en {city}, {country} kun {person1}, {person2} kaj {person3} je {date}",
"image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Video} other {Image}} farita en {city}, {country} kun {person1}, {person2}, kaj {additionalCount, number} aliaj homoj je {date}",
"image_saved_successfully": "Bildo konservita",
"image_viewer_page_state_provider_download_started": "Elŝuto komencita",
"image_viewer_page_state_provider_download_success": "Elŝuto sukcesis",
"image_viewer_page_state_provider_share_error": "Eraro dum divido",
"immich_logo": "Bildsimbolo de Immich",
"immich_web_interface": "Interfaco de Immich",
"import_from_json": "Importi el JSON-dosiero",
"in_albums": "En {count, plural, one {# albumo} other {# albumoj}}",
"in_archive": "En arĥivo",
"in_year": "En {year}",
"in_year_selector": "En",
"include_archived": "Inkluzivi elementojn el arĥivo",
"include_shared_albums": "Inkluzivi dividitajn albumojn",
"include_shared_partner_assets": "Inkluzivi elementojn dividitajn de partnero",
"individual_share": "Divido de unuopa elemento",
"individual_shares": "Dividoj de unuopaj elementoj",
"info": "Informoj",
"interval": {
"day_at_onepm": "Ĉiutage je 13:00",
"hours": "{hours, plural, one {ĉiuhore} other {ĉiujn {hours, number} horojn}}",
"night_at_midnight": "Ĉiunokte je noktomezo",
"night_at_twoam": "Ĉiunokte je 02:00"
},
"invalid_date": "Nevalida dato",
"invalid_date_format": "Nevalida dat-formato",
"invite_people": "Inviti homojn",
"invite_to_album": "Inviti al albumo",
"ios_debug_info_fetch_ran_at": "Venigo okazis je {dateTime}",
"ios_debug_info_last_sync_at": "Lasta sinkronigo {dateTime}",
"ios_debug_info_no_processes_queued": "Neniu atendovico de fonaj procezo",
"ios_debug_info_no_sync_yet": "Neniu fona sinkronado ĝis nun okazis",
"ios_debug_info_processes_queued": "{count, plural, one {{count} fona procezo envicigita} other {{count} fonaj procezoj envicigitaj}}",
"ios_debug_info_processing_ran_at": "Procezo okazis je {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# elemento} other {# elementoj}}",
"jobs": "Taskoj",
"json_editor": "Redaktilo de JSON",
"json_error": "Eraro de JSON",
"keep": "Konservi",
"keep_albums": "Konservi albumojn",
"keep_albums_count": "Konserviĝas: {count} {count, plural, one {albumo} other {albumoj}}",
"keep_all": "Konservi ĉion",
"keep_description": "Elektu tion, kio konserviĝos en via aparato kiam vi liberigas spacon.",
"keep_favorites": "Konservi preferataĵojn",
"keep_on_device": "Konservi en aparato",
"keep_on_device_hint": "Elektu elementojn por konservi en tiu ĉi aparato",
"keep_this_delete_others": "Konservi tion ĉi, forigi aliajn",
"keeping": "Konserviĝas: {items}",
"kept_this_deleted_others": "Konservi tiun ĉi elementon kune kun {count, plural, one {# forigita elemento} other {# forigitaj elementoj}}",
"keyboard_shortcuts": "Fulmoklavoj",
"language": "Lingvo",
"language_no_results_subtitle": "Provu serĉi denove per aliaj vortoj",
"language_no_results_title": "Neniuj lingvoj trovitaj",
"language_search_hint": "Serĉi lingvojn...",
"language_setting_description": "Elektu preferatan lingvon",
"large_files": "Grandaj dosieroj",
"last": "Lasta",
"last_months": "{count, plural, one {Lasta monato} other {Lastaj # monatoj}}",
"last_seen": "Lastfoje vidita",
"latest_version": "Lasta versio",
"latitude": "Latitudo",
"leave_album": "Foriri el albumo",
"lens_model": "Tipo de objektivo",
"let_others_respond": "Permesi ke aliaj homoj respondu",
"level": "Nivelo",
"library": "Bibliteko",
"library_add_folder": "Aldoni dosierujon",
"library_edit_folder": "Redakti dosierujon",
"library_options": "Agordoj pri biblioteko",
"library_page_device_albums": "Albumoj en tiu ĉi aparato",
"library_page_new_album": "Nova albumo",
"library_page_sort_asset_count": "Nombro da elementoj",
"library_page_sort_created": "Dato de kreo",
"library_page_sort_last_modified": "Laste modifita",
"library_page_sort_title": "Album-titolo",
"licenses": "Permesiloj",
"light": "Hela",
"light_theme": "Ŝanĝi al hela reĝimo",
"like": "Mi ŝatas",
"like_deleted": "Reago \"mi ŝatas\" forigita",
"link": "Ligilo",
"link_motion_video": "Ligi videon",
"link_to_docs": "Por pli da informoj, vidu la <link>dokumentaron</link>.",
"link_to_oauth": "Ligi al OAuth",
"linked_oauth_account": "Ligita OAuth-konto",
"list": "Listo",
"loading": "Ŝargado",
"loading_search_results_failed": "Malsukcesis ŝargi rezultojn de serĉo",
"local": "Loka",
"local_asset_cast_failed": "Ne eblas elsendi elementon, kiu ne troviĝas en la servilo",
"local_assets": "Lokaj elementoj",
"local_id": "Loka ID",
"local_media_summary": "Resumo de lokaj elementoj",
"local_network": "Loka reto",
"local_network_sheet_info": "La apo uzas tiun ĉi URL-on por konekti al la servilo kiam ĝi estas konektita al la nomita vifia reto",
"location": "Loko",
"location_permission": "Permeso pri lokado",
"location_permission_content": "Por povi aŭtomate uzi la ĝustan URL-on, Immich bezonas permeson uzi precizan lokon, por ke ĝi povu vidi la nomon de la aktuala vifia reto",
"location_picker_choose_on_map": "Elekti per mapo",
"location_picker_latitude_error": "Tajpu validan latitudon",
"location_picker_latitude_hint": "Tajpu vian latitudon ĉi tie",
"location_picker_longitude_error": "Tajpu validan longitudon",
"location_picker_longitude_hint": "Tajpu vian longitudon ĉi tie",
"lock": "Ŝlosi",
"locked_folder": "Ŝlosita dosierujo",
"log_detail_title": "Detala protokolado",
"log_out": "Elsaluti",
"log_out_all_devices": "Elsalutigi ĉiujn aparatojn",
"logged_in_as": "Ensalutita kiel {user}",
"logged_out_all_devices": "Ĉiuj aparatoj elsalutigitaj",
"login": "Ensaluti",
"login_disabled": "Ensalutado malebligita",
"login_form_api_exception": "Eraro de API. Bonvolu kontroli la URL-on de la servilo, kaj reprovi.",
"login_form_back_button_text": "Reen",
"login_form_email_hint": "via_adreso@example.com",
"login_form_endpoint_hint": "http://ip-adreso-de-via-servilo:porda_numero",
"login_form_endpoint_url": "URL de finpunkto de servilo",
"login_form_err_http": "Bonvolu precizigi http:// aŭ https://",
"login_form_err_invalid_email": "Nevalida retadreso",
"login_form_err_invalid_url": "Nevalida URL-o",
"login_form_err_leading_whitespace": "Antaŭa blankspaco",
"login_form_err_trailing_whitespace": "Posta blankspaco",
"login_form_failed_get_oauth_server_config": "Eraro de protokolado kun OAuth, bonvolu kontroli la URL-on de la servilo",
"login_form_failed_get_oauth_server_disable": "La OAuth-funkcio estas nedisponebla ĉe tiu ĉi servilo",
"login_form_failed_login": "Eraro dum ensaluto, bonvolu kontroli la URL-on de la servilo, la retadreson kaj pasvorton",
"login_form_handshake_exception": "Okazis eraro de kvitanco (\"handshake\") kun la servilo. Ŝaltu la agordaĵon por memsubskribitaj atestiloj, se tian vi uzas.",
"login_form_password_hint": "pasvorto",
"login_form_save_login": "Resti ensalutita",
"login_form_server_empty": "Tajpu la URL-on de la servilo.",
"login_form_server_error": "Ne eblis konektiĝi al la servilo.",
"login_has_been_disabled": "Ensalutado malebligita.",
"login_password_changed_error": "Okazis eraro dum ŝanĝo de via pasvorto",
"login_password_changed_success": "Pasvorto sukcese ŝanĝita",
"logout_all_device_confirmation": "Ĉu vi certas, ke vi volas elsalutigi ĉiujn aparatojn?",
"logout_this_device_confirmation": "Ĉu vi certas, ke vi volas elsalutigi tiun ĉi aparaton?",
"logs": "Protokoloj",
"longitude": "Longitudo",
"look": "Aspekto",
"loop_videos": "Aŭtomate ripeti videojn",
"maintenance_action_restore": "Restaŭrado de datumbazo",
"maintenance_restore_from_backup": "Restaŭri el savkopio",
"maintenance_restore_library": "Restaŭri vian bibliotekon",
"maintenance_restore_library_confirm": "Se tio ŝajne bona, daŭrigu kaj restaŭru savkopion!",
"maintenance_restore_library_description": "Restaŭrado de datumbazo",
"maintenance_restore_library_folder_has_files": "{folder} enhavas {count} dosiero(j)n",
"maintenance_restore_library_folder_no_files": "{folder} ne enhavas ajnan dosieron!",
"maintenance_restore_library_folder_pass": "legebla(j) kaj skribebla(j)",
"maintenance_restore_library_folder_read_fail": "nelegebla(j)",
"maintenance_restore_library_folder_write_fail": "ne skribebla(j)",
"maintenance_restore_library_hint_missing_files": "Povus esti, ke mankas gravaj dosieroj",
"maintenance_restore_library_hint_regenerate_later": "Eblas poste regeneri ilin en Agordoj",
"maintenance_restore_library_hint_storage_template_missing_files": "Ĉu vi uzas ŝablonojn de stokado? Povus esti, ke mankas dosieroj",
"maintenance_restore_library_loading": "Ŝargiĝas heŭristikoj kaj kontroloj de integreco…",
"maintenance_task_restore": "Restaŭrado de elektita savkopio…",
"maintenance_task_rollback": "Malsukcesis la restaŭrado; malfariĝas la ŝanĝoj…",
"manage_media_access_settings": "Malfermi agordaĵaron",
"manage_shared_links": "Administri dividitajn ligilojn",
"manage_the_app_settings": "Agordi la apon",
"map_settings_only_show_favorites": "Montri nur preferataĵojn",
"missing": "Netraktitaj",
"mobile_app": "Apo por poŝtelefono",
"mobile_app_download_onboarding_note": "Elŝutu la poŝtelefonan apon de Immich per tiuj ebloj",
"multiselect_grid_edit_date_time_err_read_only": "Preterlasas ŝanĝon de dato de nurlegaj elementoj, ĉar tio ne eblas",
"multiselect_grid_edit_gps_err_read_only": "Preterlasas ŝanĝon de loko de nurlegaj elementoj, ĉar tio ne eblas",
"networking_subtitle": "Administri agordojn pri finpunktoj de la servilo",
"no_devices": "Neniuj aprobitaj aparatoj",
"no_explore_results_message": "Alŝutu pli da fotoj por esplori vian kolekton.",
"no_favorites_message": "Aldoni al Preferataĵoj por rapide retrovi viajn plej bonajn bildojn kaj videojn",
"no_notifications": "Neniuj sciigoj",
"no_results_description": "Provu sinonimon aŭ pli ĝeneralan ŝlosilvorton",
"no_shared_albums_message": "Krei albumon por dividi fotojn kaj videojn kun konatoj",
"notification_permission_dialog_content": "Por ŝalti sciigojn, iru al Agordoj kaj elektu 'permesi'.",
"notification_permission_list_tile_content": "Donu permeson por ŝalti sciigojn.",
"notification_permission_list_tile_enable_button": "Ŝalti sciigojn",
@@ -1130,12 +1511,28 @@
"notification_toggle_setting_description": "Ŝalti sciigojn per retmesaĝo",
"notifications": "Sciigoj",
"notifications_setting_description": "Administri sciigojn",
"onboarding_privacy_description": "La ĉi-subaj (nedevigaj) funkcioj dependas de eksteraj servoj. Vi povas (mal)ŝalti ilin iam ajn.",
"only_favorites": "Nur preferataĵoj",
"owned": "Propraj",
"partner_page_empty_message": "Viaj fotoj ankoraŭ ne estas dividitaj kun ajna partnero.",
"partner_page_shared_to_title": "Dividita(j) kun",
"photo_shared_all_users": "Ŝajne vi dividis viajn fotojn kun ĉiuj uzantoj, aŭ povus esti ke ne ekzistas aliaj uzantoj.",
"preferences_settings_subtitle": "Administri agordojn pri la apo",
"purchase_settings_server_activated": "La administranto respondecas pri la ŝlosilo de aŭtentikeco por la servilo",
"rating_clear": "Forviŝi pritakson",
"refresh": "Denove",
"refresh_encoded_videos": "Renovigi koditajn videojn",
"refresh_faces": "Renovigi vizaĝojn",
"refresh_metadata": "Renovigi metadatumojn",
"refresh_thumbnails": "Renovigi bildetojn",
"refreshed": "Renovigita(j)",
"refreshes_every_file": "Re-legas ĉiujn ekzistantajn kaj novajn dosierojn",
"refreshing_encoded_video": "Renovigado de koditaj videoj",
"refreshing_faces": "Renovigado de vizaĝoj",
"refreshing_metadata": "Renovigado de metadatumoj",
"remove_assets_shared_link_confirmation": "Ĉu vi certas, ke vi volas forigi {count, plural, one {# elementon} other {# elementojn}} de tiu dividita ligilo?",
"remove_from_favorites": "Forigi el preferataĵoj",
"remove_from_shared_link": "Forigi el dividita ligilo",
"removed_from_favorites": "Forigita(j) el preferataĵoj",
"removed_from_favorites_count": "{count, plural, other {Forigis #}} el Preferataĵoj",
"rescan": "Reanalizi",
@@ -1144,6 +1541,11 @@
"reset_sqlite_confirmation": "Ĉu vi certas, ke vi volas forviŝi la datumojn de la apo? Tio forigos ĉiujn agordojn kaj elsalutigos vin.",
"reset_sqlite_confirmation_note": "Noto: vi devos relanĉi la apon por la forviŝo.",
"reset_sqlite_done": "Datumoj de la apo estas forviŝitaj. Bonvolu relanĉi Immich kaj ensalutu denove.",
"restore": "Restaŭri",
"restore_all": "Restaŭri ĉiujn",
"restore_trash_action_prompt": "{count} restaŭrita(j) el rubujo",
"restore_user": "Restaŭri uzanton",
"restored_asset": "Restaŭri elementon",
"scaffold_body_error_unrecoverable": "Neriparebla eraro okazis. Bonvolu sendi al ni la eraron kaj la stakspuron per Discord aŭ per Github por ke ni povu helpi. Vi povas forviŝi la ĉi-subajn datumojn de la apo se vi volas.",
"scan": "Analizi",
"scan_all_libraries": "Analizi ĉiujn bibliotekojn",
@@ -1152,18 +1554,78 @@
"scanning": "Analizado",
"scanning_for_album": "Serĉado de albumo...",
"search_suggestion_list_smart_search_hint_1": "Inteligenta serĉado defaŭlte estas ŝaltita. Por serĉi metadatumojn, uzu sintakson tiel ",
"server_privacy": "Privateco de servilo",
"server_restarting_description": "La paĝo baldaŭ reŝargiĝos.",
"setting_notifications_subtitle": "Redakti viajn preferojn pri sciigoj",
"share_action_prompt": "Dividis {count} elementojn",
"shared": "Dividitaj",
"shared_album_activities_input_disable": "Komentado estas malŝaltita",
"shared_album_activity_remove_content": "Ĉu vi volas forigi tiun ĉi agon?",
"shared_album_activity_remove_title": "Forigi agon",
"shared_album_section_people_action_error": "Okazis eraro dum forigo el la albumo",
"shared_album_section_people_action_leave": "Forigi uzanton de albumo",
"shared_album_section_people_action_remove_user": "Forigi uzanton de albumo",
"shared_album_section_people_title": "HOMOJ",
"shared_by": "Dividita de",
"shared_by_user": "Dividita de {user}",
"shared_by_you": "Dividita de vi",
"shared_from_partner": "Fotoj de {partner}",
"shared_intent_upload_button_progress_text": "{current} el {total} alŝutitaj",
"shared_link_app_bar_title": "Dividitaj ligiloj",
"shared_link_clipboard_copied_massage": "Kopiita al tondujo",
"shared_link_clipboard_text": "Ligilo: {link}\nPasvorto: {password}",
"shared_link_create_error": "Okazis eraro dum kreo de dividita ligilo",
"shared_link_custom_url_description": "Atingi la dividita ligilo per propra URL-o",
"shared_link_edit_description_hint": "Tajpu priskribon de la dividaĵaro",
"shared_link_edit_expire_after_option_day": "1 tago",
"shared_link_edit_expire_after_option_days": "{count} tagoj",
"shared_link_edit_expire_after_option_hour": "1 horo",
"shared_link_edit_expire_after_option_hours": "{count} horoj",
"shared_link_edit_expire_after_option_minute": "1 minuto",
"shared_link_edit_expire_after_option_minutes": "{count} minutoj",
"shared_link_edit_expire_after_option_months": "{count} monatoj",
"shared_link_edit_expire_after_option_year": "{count} jaro",
"shared_link_edit_password_hint": "Tajpu pasvorton por la dividaĵaro",
"shared_link_edit_submit_button": "Ĝisdatigi ligilon",
"shared_link_error_server_url_fetch": "Ne eblis trovi la URL-on de la servilo",
"shared_link_expires_day": "Eksvalidiĝos post {count} tago",
"shared_link_expires_days": "Eksvalidiĝos post {count} tagoj",
"shared_link_expires_hour": "Eksvalidiĝos post {count} horo",
"shared_link_expires_hours": "Eksvalidiĝos post {count} horoj",
"shared_link_expires_minute": "Eksvalidiĝos post {count} minuto",
"shared_link_expires_minutes": "Eksvalidiĝos post {count} minutoj",
"shared_link_expires_never": "Neniam eksvalidiĝos",
"shared_link_expires_second": "Eksvalidiĝos post {count} sekundo",
"shared_link_expires_seconds": "Eksvalidiĝos post {count} sekundoj",
"shared_link_info_chip_metadata": "EXIF",
"shared_link_manage_links": "Administri dividitajn ligilojn",
"shared_link_options": "Agordoj pri dividitaj ligiloj",
"shared_link_password_description": "Devigi uzon de pasvorto por uzi la ligilon",
"shared_links": "Dividitaj ligiloj",
"shared_links_description": "Dividi fotojn kaj videojn per ligilo",
"shared_photos_and_videos_count": "{assetCount, plural, other {# dividitaj fotoj kaj videoj.}}",
"shared_with_me": "Dividitaj kun mi",
"shared_with_partner": "Dividitaj kun {partner}",
"sharing_page_album": "Dividitaj albumoj",
"sharing_page_description": "Krei dividitajn albumojn por dividi fotojn kaj videojn kun konatoj.",
"sharing_silver_appbar_create_shared_album": "Nova dividita albumo",
"show_shared_links": "Montri dividitajn ligilojn",
"start_date": "Komenca dato",
"start_date_before_end_date": "Komenca dato devas esti antaŭ fina dato",
"to_favorite": "Aldoni al preferataĵoj",
"trash_page_restore_all": "Restaŭri ĉiujn",
"trigger_description": "Evento, kiu ekfunkciigas la laborfluon",
"unfavorite": "Forigi el preferataĵoj",
"unfavorite_action_prompt": "{count} forigita(j) el Preferataĵoj",
"untitled_workflow": "Sentitola laborfluo",
"upload_concurrency": "Nombro da samtempaj alŝutoj",
"upload_errors": "Alŝuto finita kun {count, plural, one {# eraro} other {# eraroj}}. Reŝargu la paĝon por vidi novajn elementojn.",
"upload_success": "Alŝuto sukcese finita. Reŝargu la paĝon por vidi novajn elementojn.",
"user_pin_code_settings_description": "Administri vian PIN-kodon",
"user_privacy": "Privateco de uzanto",
"user_purchase_settings_description": "Administri vian aĉeton",
"view_links": "Vidi ligilojn",
"waiting": "En atendovico",
"waiting_count": "En atendovico: {count}",
"week": "Semajno",
"wifi_name": "Nomo de Vifireto",
"workflow_delete_prompt": "Ĉu vi certas, ke vi volas forigi tiun ĉi laborfluon?",
@@ -1181,5 +1643,6 @@
"workflows_help_text": "Laborfluo aŭtomatigas agojn pri elementoj, laŭ ekigiloj kaj filtriloj",
"year": "Jaro",
"yes": "Jes",
"you_dont_have_any_shared_links": "Vi ne havas ajnan dividitan ligilon",
"zero_to_clear_rating": "tuŝu 0 por forviŝi la pritakson de la elemento"
}

Some files were not shown because too many files have changed in this diff Show More