Compare commits

...

252 Commits

Author SHA1 Message Date
Alex The Bot
cd7fc7e026 Version v1.57.0 2023-05-23 02:03:49 +00:00
Alex
b4d312efb6 fix(web): revert justify layout - improve gallery view load time (#2522)
* fix(web): revert justify layout - improve gallery view load time

* Remove package
2023-05-22 21:01:32 -05:00
Mert
e9722710ac feat(server): transcode bitrate and thread settings (#2488)
* support for two-pass transcoding

* added max bitrate and thread to transcode api

* admin page setting desc+bitrate and thread options

* Update web/src/lib/components/admin-page/settings/setting-input-field.svelte

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* Update web/src/lib/components/admin-page/settings/setting-input-field.svelte

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* two-pass slider, `crf` and `threads` as numbers

* updated and added transcode tests

* refactored `getFfmpegOptions`

* default `threads`, `maxBitrate` now 0, more tests

* vp9 constant quality mode

* fixed nullable `crf` and `threads`

* fixed two-pass slider, added apiproperty

* optional `desc` for `SettingSelect`

* disable two-pass if settings are incompatible

* fixed test

* transcode interface

---------

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
2023-05-22 13:07:43 -05:00
Michel Heusschen
f1384fea58 feat(server): pagination for asset queries in jobs (#2516)
* feat(server): pagination for asset queries in jobs

* default mock value for getAll

* remove live photo name correction

* order paginated results by createdAt

* change log level

* move usePagination to domain
2023-05-22 13:05:06 -05:00
Alex
feadc45e75 chore(server): Remove dist directory in command script (#2518) 2023-05-22 10:27:08 -05:00
Jason Rasmussen
eefe5266a8 chore(server): remove unused filename (#2517) 2023-05-22 10:26:56 -05:00
Jason Rasmussen
74353193f8 feat(web,server): user storage label (#2418)
* feat: user storage label

* chore: open api

* fix: checks

* fix: api update validation and tests

* feat: default admin storage label

* fix: linting

* fix: user create/update dto

* fix: delete library with custom label
2023-05-21 23:18:10 -04:00
Jason Rasmussen
0ccb73cf2b feat(server): add missing thumbnail check to nightly jobs (#2510) 2023-05-21 21:24:21 -05:00
Mert
356f4424df chore(server): queue handlers shouldn't increase concurrency (#2508) 2023-05-21 21:11:26 -05:00
Michel Heusschen
85c6cf4309 fix(web): context menu overlap + outclick types (#2506) 2023-05-21 11:01:08 -05:00
Michel Heusschen
96fb68135e fix(nginx): enable gzip and show error logs (#2504) 2023-05-21 08:23:46 -05:00
Michel Heusschen
a7b9adc692 feat(web+server): map improvements (#2498)
* feat(web+server): map improvements

* add number format double to fix mobile
2023-05-21 01:26:06 -05:00
Jason Rasmussen
e028cf9002 fix(server): reverse geocoding crash loop (#2489) 2023-05-20 21:39:12 -05:00
Jason Rasmussen
f984be8ea0 docs: update contributing pages (#2503) 2023-05-20 20:46:09 -05:00
Jason Rasmussen
3d426b55d3 chore(server): auth request type (#2502) 2023-05-20 20:44:26 -05:00
Fynn Petersen-Frey
02b8b2c125 chore(mobile): remove hive (#2497) 2023-05-20 20:42:19 -05:00
Fynn Petersen-Frey
dc7b0f75bb chore(mobile): use Record instead of custom pair+triple (#2483) 2023-05-20 20:41:34 -05:00
Jason Rasmussen
a089d9891d feat: confirm before deleting all faces and people (#2496) 2023-05-20 20:40:53 -05:00
Alex The Bot
a1183f4b4b Version v1.56.2 2023-05-20 03:53:45 +00:00
Alex
84cfa38510 chore(ml): load models on start up (#2487)
* chore(ml): load models on start up

* Download correct model
2023-05-19 22:37:01 -05:00
Fynn Petersen-Frey
89edbcacfa chore(mobile): remove obsolete files (#2482) 2023-05-19 22:06:39 -05:00
Alex The Bot
c8e649f190 Version v1.56.1 2023-05-19 04:01:36 +00:00
Alex
790e43dd6e chore(server): Enhancement for query to get assets for each recognized person (#2475) 2023-05-18 22:59:57 -05:00
Alex
59f6b2ff2e [Localizely] Translations update (#2471) 2023-05-18 15:10:22 -05:00
Alex Tran
829defbf61 docs: update RAM requirement 2023-05-18 15:04:21 -05:00
martin
70a0f4ae48 chore: update to node 18 and alpine 3.17 (#2430)
* chore: update to node 18 and alpine 3.17

Signed-off-by: martin <martin.labat92@gmail.com>

* chore: fix sharp version

Signed-off-by: martin <martin.labat92@gmail.com>

* chore(server): use vips-dev

Signed-off-by: martin <martin.labat92@gmail.com>

* update checkDiskUsage

Signed-off-by: martin <martin.labat92@gmail.com>

* fix: use vips-heif instead of libheif

Signed-off-by: martin <martin.labat92@gmail.com>

* fix: use vips instead of vips-cpp

Signed-off-by: martin <martin.labat92@gmail.com>

* fix: ensure vips installation

Signed-off-by: martin <martin.labat92@gmail.com>

---------

Signed-off-by: martin <martin.labat92@gmail.com>
2023-05-18 10:56:33 -05:00
Michel Heusschen
c7c0ef6abc chore(web): switch to eslint-plugin-svelte package (#2467) 2023-05-18 10:43:09 -05:00
Jason Rasmussen
2fc8a0db92 docs: add new features (#2441)
* chore: add new features

* Add facial recognition to docs site

* Added partner sharing to the docs site

* update developer docs

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-05-18 09:48:43 -05:00
Alex
b50c621be8 chore: update changelog for android 2023-05-18 09:47:12 -05:00
Alex The Bot
126f5857c3 Version v1.56.0 2023-05-18 14:03:48 +00:00
Alex Tran
8b3e1764a8 fix(web): asset count z-index 2023-05-17 21:39:34 -05:00
Alex
b776461297 fix(web): unable to change person name (#2458)
* fix(web): unable to change person name

* name changed

* chore: strongly-typed dispatcher

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2023-05-17 21:13:54 -05:00
Jason Rasmussen
4a0052026f feat(web): improve page header + scrolling (#2453)
* fix: line to edge of screen

* refactor: user layout page
2023-05-17 14:45:16 -05:00
Alex
35c4887e4a fix return update asset with new update time (#2457) 2023-05-17 14:28:58 -05:00
Mark Monteiro
f5b87833f8 Add comment about Docker secrets to example.env (#2454)
Add a comment to indicate the support for Docker secrets added in https://github.com/immich-app/immich/pull/1254
2023-05-17 17:36:44 +00:00
Fynn Petersen-Frey
0dde76bbbc feat(mobile): lazy loading of assets (#2413) 2023-05-17 12:36:02 -05:00
Jason Rasmussen
93863b0629 feat: facial recognition (#2180) 2023-05-17 12:07:17 -05:00
Michel Heusschen
115a47d4c6 fix(web): layout spacing when zooming (#2452) 2023-05-17 10:44:15 -05:00
martin
308c63df16 fix(web): use correct favicon sizes (#2446)
* fix(web): use correct favicon sizes

Signed-off-by: martin <martin.labat92@gmail.com>

* fix: format

Signed-off-by: martin <martin.labat92@gmail.com>

---------

Signed-off-by: martin <martin.labat92@gmail.com>
2023-05-17 09:20:32 -05:00
Michel Heusschen
ab86d0a18d refactor(web): asset select actions (#2444)
* refactor(web): asset select actions

* remaining pages/components + data flow changes

* fix check
2023-05-16 09:13:20 -05:00
Jason Rasmussen
3ec74444b0 docs: remove roadmap link (#2442) 2023-05-15 18:25:46 +00:00
Michel Heusschen
1979c84ea8 chore(web): update eslint and prettier packages (#2437)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-05-15 17:58:35 +00:00
Trenton H
f4aefcb18b chore(ci): versions the Docker cleaning action to latest released (#2438) 2023-05-15 12:45:03 -05:00
Sergey Kondrikov
7f2fa23179 feat (server, web): Share with partner (#2388)
* feat(server, web): implement share with partner

* chore: regenerate api

* chore: regenerate api

* Pass userId to getAssetCountByTimeBucket and getAssetByTimeBucket

* chore: regenerate api

* Use AssetGrid to view partner's assets

* Remove disableNavBarActions flag

* Check access to buckets

* Apply suggestions from code review

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>

* Remove exception rethrowing

* Simplify partner access check

* Create new PartnerController

* chore api:generate

* Use partnerApi

* Remove id from PartnerResponseDto

* Refactor PartnerEntity

* Rename args

* Remove duplicate code in getAll

* Create composite primary keys for partners table

* Move asset access check into PartnerCore

* Remove redundant getUserAssets call

* Remove unused getUserAssets method

* chore: regenerate api

* Simplify getAll

* Replace ?? with ||

* Simplify PartnerRepository.create

* Introduce PartnerIds interface

* Replace two database migrations with one

* Simplify getAll

* Change PartnerResponseDto to include UserResponseDto

* Move partner sharing endpoints to PartnerController

* Rename ShareController to SharedLinkController

* chore: regenerate api after rebase

* refactor: shared link remove return type

* refactor: return user response dto

* chore: regenerate open api

* refactor: partner getAll

* refactor: partner settings event typing

* chore: remove unused code

* refactor: add partners modal trigger

* refactor: update url for viewing partner photos

* feat: update partner sharing title

* refactor: rename service method names

* refactor: http exception logic to service, PartnerIds interface

* chore: regenerate open api

* test: coverage for domain code

* fix: addPartner => createPartner

* fix: missed rename

* refactor: more code cleanup

* chore: alphabetize settings order

* feat: stop sharing confirmation modal

* Enhance contrast of the email in dark mode

* Replace button with CircleIconButton

* Fix linter warning

* Fix date types for PartnerEntity

* Fix PartnerEntity creation

* Reset assetStore state

* Change layout of the partner's assets page

* Add bulk download action for partner's assets

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2023-05-15 12:30:53 -05:00
Michel Heusschen
4524aa0d06 refactor(web): use ImmichApi to create urls (#2435) 2023-05-13 21:52:29 -05:00
Michel Heusschen
15fa8250cb fix(web): profile image load (#2434) 2023-05-13 09:16:14 -05:00
Alex
4dff129949 feat(web): Replicate albums view for sharing view (#2433)
* replicate album view for sharing view

* Remove unused file

* fix test

* correct title
2023-05-13 09:05:30 -05:00
Alex
43951ec208 chore(mobile): Upgrade to Flutter 3.10 (#2429)
* update dependencies

* resolve dependency and update code for Flutter 3.10

* update github action flutter version

* update test version

* iOS deployment

* pump intl package

* list tile fix
2023-05-12 09:21:13 -05:00
Alex
f961acdf0c feat(web): album card hover styling (#2424)
* feat(web): album card hover styling

* feedback

* fix delete button not shown

* better color
2023-05-11 11:50:48 -05:00
Alex
2c7821e5e6 chore: update api (#2428) 2023-05-11 10:49:28 -05:00
Alex
d25ddfc46b chore: update screenshots for readme and docs (#2425)
* update screenshot

* better quality for docs
2023-05-10 23:33:32 -05:00
Alex
8cc9b08c06 chore(ml): use official pytorch channel (#2416) 2023-05-10 07:09:33 -05:00
Michel Heusschen
98b9d815a6 chore(web): update svelte related packages (#2419) 2023-05-10 04:58:53 -05:00
Jason Rasmussen
a808b9403e feat(web,server): logout all devices (#2415)
* feat: logout all devices

* chore: regenerate openapi

* chore: add test

* chore: logout vs log out
2023-05-09 14:34:17 -05:00
Jason Rasmussen
c956eee919 chore: fix backup dumper formatting (#2414) 2023-05-09 13:44:50 -05:00
Alex The Bot
aa97ca9ccf Version v1.55.1 2023-05-09 15:29:06 +00:00
faupau
98bb3de8da fix(web) small UI improvements (#2369)
* small changes in asset viewer navigation

* add conditional wrapper and scroll only content

* fix formatting

* update conditional wrapper

* remove emptz title attribute

* remove conditional-wrapper as it is not needed

* remove isTimeline

* fix map over sidebar

* fix overlap

* fix conflict

* revert z-index

* add relative z index

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-05-09 10:10:13 -05:00
Michel Heusschen
cd43edf074 feat(mobile): improve localization (#2405) 2023-05-09 08:58:27 -05:00
Michel Heusschen
dffd992304 fix(web): remove global style from map marker (#2408) 2023-05-09 08:57:17 -05:00
bo0tzz
f1b70e13a1 Revert "Bump local-reverse-geocoder to 0.15.2 / Fix Corrupted Reverse Geocoding CSV File (#2396)" (#2409)
This reverts commit b5a4aef829.
2023-05-09 08:56:31 -05:00
Alex Tran
d91247dc35 chore: post release 2023-05-08 22:27:55 -05:00
Alex The Bot
25f55ee6bb Version v1.55.0 2023-05-09 02:08:01 +00:00
Alex
c2e9fe0aac feat(web): improve map styling and interaction (#2399)
* improve map styling and interaction

* Update style
2023-05-08 21:05:06 -05:00
Atul Mehla
5885ec8e65 Add text notifying user that no asset is found (#2400) 2023-05-08 19:37:06 -05:00
Alex
053104fc50 fix(web): timeline distortion when scrolling due to rerender of scrollbar bucket and thumbnail size (#2398)
* fix(web): timeline distortion when scrolling due to rerender of scrollbar bucket and thumbnail size

* fix: test
2023-05-08 14:59:33 -05:00
Steffen Auer
861de7f8b3 chore(web/mobile): use Heart Icon & small icon changes (#2397) 2023-05-08 14:01:39 -05:00
Szymon Sakowicz
b5a4aef829 Bump local-reverse-geocoder to 0.15.2 / Fix Corrupted Reverse Geocoding CSV File (#2396)
* Bump local-reverse-geocoder to 0.15.1

* Bump to fixed release

* Sync package.json with package-lock

---------

Co-authored-by: Szymon Sakowicz <s.sakowicz@tidio.net>
2023-05-08 09:09:05 -05:00
Skyler Mäntysaari
54b4f8afbd chore(docs): Update FAQ on how to disable typsense and ml (#2384) 2023-05-06 07:43:24 -05:00
Matthias Rupp
65daf342df feat(web): Global map showing all assets with geo information (#2355)
* First crude implementation of the global asset map in web

* Use single DOM element for all markers

* Minor layout changes

* Refactor

* Add asset viewer

* Add API endpoint that returns only assets with location information (Thanks @EPP100)

* Remove sidebar icon flip

* Add dark theme support

* Center map to most recent asset

* Allow cluster viewing

* Fix linter errors

* Add newlines

* Fix ts errors

* Fix eslint error

* Run prettier

* Server code style

* Fix openapi mobile code generation issues

* Map markers test

* fix: Support video thumbnails

* Update API

* Review suggestions

* Review suggestions

* Linter error

* Chage mapMarker endpoint to map-marker

* Clean up leaflet imports
2023-05-05 20:33:30 -05:00
Michel Heusschen
15a498fd60 feat(server): add api key to openapi spec (#2362)
* feat(server): add api key to openapi spec

* regenerate api
2023-05-04 11:41:29 -05:00
Jason Rasmussen
af7da9d2c9 chore: standardize process method names (#2363) 2023-05-04 11:40:34 -05:00
Jason Rasmussen
91ad584064 chore: regenerate open api (#2374) 2023-05-03 14:27:57 -05:00
bo0tzz
b6b9f51bd7 chore(ml): Fix entrypoint path (#2373) 2023-05-03 14:27:35 -05:00
Jason Rasmussen
6acfb55dcc fix: correct npx path (#2354) 2023-04-28 21:28:35 -05:00
Jason Rasmussen
ce42b84430 build: improve pump script (#2351) 2023-04-28 21:10:32 -05:00
Jason Rasmussen
59d93138d3 fix: linting (#2353) 2023-04-28 21:10:20 -05:00
Jason Rasmussen
78de189d56 ci: simplify server npm steps (#2352) 2023-04-28 21:10:01 -05:00
Covalent
b21c99eb12 add auto postgress dump docs (#2349)
* add auto postgress dump docs

* add link to repo for auto db dumps

---------

Co-authored-by: Luke McCarthy <mail@lukehmcc.com>
2023-04-28 15:22:00 -05:00
Jason Rasmussen
e22cdea485 chore(server,mobile): remove device info entity (#1527)
* chore(server): remove unused device info code

* chore: generate open api

* remove any DeviceTypeEnum usage from mobile

* chore: coverage

* fix: drop device info table

---------

Co-authored-by: Fynn Petersen-Frey <zody22@gmail.com>
2023-04-28 15:01:03 -05:00
Jason Rasmussen
1e97407025 chore: microservices debugger (#2345)
* chore: microservices debugger

* Update launch.json
2023-04-28 13:21:01 -05:00
Jason Rasmussen
c4f5dc6d01 fix(server): oauth mobile callback url (#2339)
* fix(server): mobile redirect uri

* chore: add test
2023-04-26 15:39:18 -05:00
Jason Rasmussen
c329a17975 feat(web): organize user settings (#2340) 2023-04-26 12:25:36 -05:00
Trenton H
2a88cc74bf chore(ci): Implement a cleanup of Docker images (#2302)
This adds a workflow to clean containers when the pull request closes
and remove untagged images generated as tags are updated
2023-04-26 05:50:31 -05:00
Alex
7e965cb6d4 chore(ml): move to fastAPI (#2336) 2023-04-26 05:39:24 -05:00
faupau
6631b286c1 fix(web): asset viewer navbar overlapping with details tab and context menu not closing on button press (except in album viewer) (#2323)
* fix overlapping of asset-viewer-nav-bar
with details tab

* fix contextmenu not closing on button press

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-25 21:30:19 -05:00
Jason Rasmussen
b8313abfa8 feat(web,server): manage authorized devices (#2329)
* feat: manage authorized devices

* chore: open api

* get header from mobile app

* write header from mobile app

* styling

* fix unit test

* feat: use relative time

* feat: update access time

* fix: tests

* chore: confirm wording

* chore: bump test coverage thresholds

* feat: add some icons

* chore: icon tweaks

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-25 21:19:23 -05:00
Jason Rasmussen
aa91b946fa fix(server): use current schema for search/explore (#2331) 2023-04-25 12:21:07 -05:00
Jason Rasmussen
82af2c5717 docs: backup and restore (#2326) 2023-04-24 21:14:21 -05:00
Jason Rasmussen
4cdc59e51c ci: doc format check (#2325)
* ci: doc format check

* chore: linting
2023-04-24 12:49:20 -05:00
Jason Rasmussen
d34585e4b0 chore: update readme (#2324) 2023-04-24 10:16:40 -05:00
faupau
d565a684a1 feat(web): immich as webapp, add apple icons and manifest file (#2310)
* add apple specific icons
so it can be added to homescreen

* remove jpg icons

* change background color to white

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-23 20:30:38 -05:00
Alex
13f178dca8 fix(web): correct color sidebar button when selected in dark mode (#2322) 2023-04-23 16:12:45 -05:00
Alex Tran
f8ba33e81c pump openapi version 2023-04-22 21:40:33 -05:00
Alex The Bot
3d251f51fc Version v1.54.1 2023-04-23 02:36:09 +00:00
Alex
57704522cd feat(web): smaller thumbnails on timeline mobile (#2316) 2023-04-22 21:13:15 -05:00
faupau
787926c111 feat(web): show asset count in sharing tab and album viewer (#2311)
* show asset count in sharing tab

* add asset count to album-viewer

* remove duplicate font size

* fix test

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-22 13:38:45 -05:00
Alex Tran
08b424b3df update gitignore 2023-04-22 13:31:42 -05:00
Jason Rasmussen
736a946101 fix(web): justified layout (#2313) 2023-04-21 16:24:25 -05:00
Alex
6f6f847ee2 feat(web): Add action button to search result page (#2303)
* feat(web): Add action button to search result page

* fix test

* rename

* pr feedback

* better condition

* fix test
2023-04-21 10:10:08 -05:00
Fynn Petersen-Frey
13be271df7 chore(Android): update gradle, kotlin, configure glide (#2306) 2023-04-21 05:31:44 -05:00
Jason Rasmussen
b423852fad chore: flip album icon (#2300) 2023-04-20 13:23:03 -05:00
Alex
fe3d6b870a feat(web): add button to archive and unarchive in detail viewer (#2296) 2023-04-20 09:09:27 -05:00
Alex
14be63039f chore(doc): update FAQ for Photo Stream on iOS (#2295) 2023-04-19 18:54:19 -05:00
Alex
d339d4c8dd post release note 2023-04-18 14:38:46 -05:00
Alex The Bot
b0d5cb62fa Version v1.54.0 2023-04-18 16:34:37 +00:00
Alex
975d23ee5c fix(web): empty album is not auto deleted (#2283)
* fix(web): empty album is not auto deleted

* regenerate api

* fix test
2023-04-18 11:26:04 -05:00
Michel Heusschen
8a421831ab fix(web): noscript message (#2278) 2023-04-18 11:24:17 -05:00
Alex
c8d3faec6d fix(mobile): video player disposes early (#2275)
* fix(mobile): video player disposes early

* fixed show download button based on asset state

* style icon size

* disable screensleep on video player

* better position for video

* better scroll physics on iOS
2023-04-18 11:23:56 -05:00
faupau
8a45c258c5 feat(web): smaller thumbnail in explore so at least 2 photos are in a row (#2277)
* image view in explore tab more responsive

* center photo

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-18 10:35:28 -05:00
faupau
d45ff72c9c fix(web): accountinfopanel not closing on button press (#2276)
* fix accountinfopanel not closing on button press

* remove overcomplicated logic
replace with simpler logic and only one outside listener

* remove keydown

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-18 10:02:51 -05:00
faupau
137d246d6a fix(web): show noscript message when js not enabled (#2274)
* show noscript message when js not enabled

* remove comment

* fix typo

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-18 06:06:59 -05:00
Fynn Petersen-Frey
e80d37bf8f refactor(mobile): add AssetState and proper asset updating (#2270)
* refactor(mobile): add AssetState and proper asset updating

* generate files

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-18 04:47:24 -05:00
faupau
b970a40b4e feat(web): small responsivness improvements regarding mobile use (#2255)
* make sidebar load more fluid
use css before js kicks in
added xs breakpoint in tailwind config

* fix sidebar hr still showing if opened

* make share tab not overflow on mobile

* make user management tab responsive

* make jobs panel responsive

* fix format in tailwind config

* fix full width on large screens
use md breakpoint for w-[800px]

* show accessible name for all screens

* replace grid with flex-col

* replace all xs with sm

* remove isCollapsed completly
using only tailwinds group feature and sm and md breakpoints

* remove leftovers of isCollapsed
and make the settings content less stretched

* remove isCollapsed in layout and side-bar

* fix code style

---------

Co-authored-by: faupau03 <paul.paffe@gmx.net>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-04-17 11:18:49 -05:00
Jason Rasmussen
1e32a5fffd chore: remove stats job (#2268) 2023-04-17 10:30:26 -05:00
Alex
2e5cd986dd feat(mobile): Archive feature on mobile (#2258)
* update asset to include isArchive property

* Not display archived assets on timeline

* replace share button to archive button

* Added archive page

* Add bottom nav bar

* clean up homepage

* remove deadcode

* improve on sync is archive

* show archive asset correctly

* better merge condition

* Added back renderList to re-rendering don't jump around

* Better way to handle showing archive assets

* complete ArchiveSelectionNotifier

* toggle archive

* remove deadcode

* fix unit tests

* update assets in DB when changing assets

* update asset state to reflect archived status

* allow to archive assets via multi-select from timeline

* fixed logic

* Add options to bulk unarchive

* regenerate api

* Change position of toast message

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
2023-04-17 00:02:07 -05:00
David
635eee9e5e Update in-page sample .env contents and clarify process (#2252)
* Update .env example and clarify process

Update .env contents, and add a little clarification about commands being run. On Windows, for example, you might not have wget, but you'd need to be in the directory with the docker-compose.yml and .env files to run the docker-compose up -d command successfully. (Took me a while to figure out at first)

* Fix some formatting/wording

* Put log level back in and add typesense settings to address PR comments
2023-04-16 22:53:17 -05:00
faupau
ae3ea9e531 fix(web): fix search 400 error when only entering m: (#2261)
Co-authored-by: faupau03 <paul.paffe@gmx.net>
2023-04-16 14:37:28 -05:00
bo0tzz
5b241f0b64 feat(web): Allow closing modals with Escape key (#2257) 2023-04-15 11:51:56 -05:00
Fynn Petersen-Frey
1a64075027 fix(mobile): fix asset removal edge cases (#2251)
Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-04-14 20:50:58 -05:00
faupau
100866be37 More responsive web frontend (#2245)
* collapsable menu in web, more mobile friendly

* finished sidebar collapsing

* make navigation bar more responsive

* make search bar and admin button more responsive

* fix administration small button coloring

* fix upload button over opened search bar

* open search directly on small devices

* make admin sidebar more responsive

* add small edge to admin content

* server stats more responsive

* fix eslint errors

* server stats flex wrap

* Delete .env

* Revert change in hooks.server.ts

* Revert change in vite.config.js

* little clean up, replace {``} with ""

* remove package-lock.json in root folder

* revert upload button to linkbutton

* show extended sidebar also on focus

* combine changes in side-bar.svelte and
+layout.svelte to side-bar-section

* fix navigation-bar cog color in light theme

---------

Co-authored-by: Paul Paffe <paul.paffe@gmx.net>
2023-04-14 20:41:52 -05:00
Fynn Petersen-Frey
2179530084 fix(mobile): consistent handling of DateTime in SyncService (#2249)
Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-04-14 09:14:14 -05:00
Fynn Petersen-Frey
d500ef77cf feature(mobile): configurable log level (#2248)
* feature(mobile): configurable log level

* increase maxLogEntries to 500

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
2023-04-14 08:50:46 -05:00
TruongSinh Tran-Nguyen
4952b3a2d6 fix(proxy): turn off nginx_proxy_buffer (#2246)
* Refactor poxy_* directives

Move from location to server context, as they are identical

* Disable proxy_request_buffering

proxy_buffering is already off, no reason to have proxy_request_buffering on. In fact, leaving it on can cause nginx to (temporarily) use a lot of disk space during uploads
2023-04-13 15:38:49 -05:00
Alex
a9859bc029 feat: Add description (#2237)
* Added dto, logic to insert description and web implementation

* create text field and update on remote database

* Update description and save changes

* styling

* fix web test

* fix server test

* preserve description on metadata extraction job run

* handle exif info is null situation

* pr feedback

* format openapi spec

* update createAssetDto

* refactor logic to service

* move files

* only owner can update description

* Render description correctly in shared album

* Render description correctly in shared link

* disable description edit for not owner of asset on mobile

* localization and clean up

* fix test

* Uses providers for description text (#2244)

* uses providers for description text

* comments

* fixes initial data setting

* fixes notifier

---------

Co-authored-by: martyfuhry <martyfuhry@gmail.com>
2023-04-13 10:22:06 -05:00
dependabot[bot]
561b208508 chore(deps): bump class-validator from 0.13.2 to 0.14.0 in /server (#2240)
Bumps [class-validator](https://github.com/typestack/class-validator) from 0.13.2 to 0.14.0.
- [Release notes](https://github.com/typestack/class-validator/releases)
- [Changelog](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/typestack/class-validator/compare/v0.13.2...v0.14.0)

---
updated-dependencies:
- dependency-name: class-validator
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-12 20:56:07 +00:00
Zack Pollard
de59d02ad7 ci: set ghcr write permissions explicitely for dependabot PRs (#2241) 2023-04-12 21:52:01 +01:00
Zack Pollard
017a34fc10 ci: always run all code checks regardless of failures (#2239) 2023-04-12 15:17:27 -05:00
Sergey Kondrikov
d314805caf feat (server, web): Implement Archive (#2225)
* feat (server, web): add archive

* chore: generate api

* feat (web): add empty placeholder for archive page

* chore: remove title on favorites page

Duplicates sidebar selection. Two pages (Archive and Favorites)
are consistent now

* refactor (web): create EmptyPlaceholder component for empty pages

* fixed menu close button not close:

* fix (web): remove not necessary store call

* test (web): simplify asset tests code

* test (web): simplify asset tests code

* chore (server): remove isArchived while uploading

* chore (server): remove isArchived from typesense schema

* chore: generate api

* fix (web): delete asset from archive page

* chore: change archive asset count endpoint

old endpoint: /asset/archived-count-by-user-id
new endpoint: /asset/stat/archive

* chore: generate api

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-12 10:37:52 -05:00
Alex
eb9481b668 fix(server): generate thumbnail job uses stale path (#2236)
* fix(server): generate thumbnail job' using stale path

* add query for webp generation

* revert query for webp because it happens after files are moved

* Add log info
2023-04-11 20:28:25 -05:00
Alex
1564807aa0 feat(mobile): add trobleshooting toggle (#2235)
* Added troubleshooting settings

* Added asset detail info in debug mode

* lint
2023-04-11 12:21:00 -05:00
Alex
dd8d113334 fix(server): jobs using stale path (#2233)
* fix(server): jobs using stale path

* fixed test

* pr feedback
2023-04-11 08:56:52 -05:00
Alex
258bc328e0 chore(server): better logging for error message (#2230)
* chore(server): better logging for error message

* pr feedback
2023-04-11 08:53:42 -05:00
Alex
c0de3aa35c chore: update pr template (#2234) 2023-04-11 06:03:54 -05:00
Alex
a1a62b00a0 feat(server): add originalFileName to asset table (#2231) 2023-04-11 05:23:39 -05:00
Alex
db628cec11 fix(server): cannot delete an asset if presented in album (#2223)
* fix(server): cannot delete an asset if presented in album

* added migration

* preserve correct migration
2023-04-09 21:48:01 -05:00
Alex
6f7071b12d [Localizely] Translations update (#2220) 2023-04-08 22:23:26 -05:00
Alex
e9c171f7ab fix(web): show OAuth login button when disabled (#2219)
* fix(web): show OAuth login button when disable

* update api
2023-04-08 22:18:22 -05:00
Michel Heusschen
983abf5e14 chore(server): update openapi (#2205) 2023-04-08 21:26:09 -05:00
Alex
91e27affeb feat(web): add justify layout for GalleryViewer (#2207)
* Implemented justify layout

* Fixed issue with asset selection does not show style for selected assets

* pr feedback

* PR feedback

* fix test

* Added flip animation
2023-04-08 20:40:37 -05:00
Skyler Mäntysaari
d76b3c8f78 chore(server): remove unneeded debug logging (#2203)
* chore(server): commented out debug log line for codecs

* chore(server): removed debug log line for codecs as it's not needed

* Prettier run

* Make the log more useful and move it to verbose level
2023-04-08 20:35:54 -05:00
Skyler Mäntysaari
fb42a736f1 fix(server): expand tests and add avi, mov to mimetypes. (#2213) 2023-04-08 20:35:27 -05:00
Skyler Mäntysaari
a68fbcc520 chore(server): redis error handling (#2212)
* chore(server): bull error handler

* chore(server): redis error handling

* Let's not touch bull
2023-04-08 20:35:08 -05:00
Alex
9fc70fc24e fix(mobile): fix null check operator on null value (#2204) 2023-04-07 21:21:29 -05:00
Jason Rasmussen
1f17720be2 chore: run web (only) with remote backend (#2196) 2023-04-07 20:44:56 -05:00
Michel Heusschen
ab5b92ae68 refactor(web): centralize buttons (#2200) 2023-04-07 11:45:00 -05:00
Alex
767410959a [Localizely] Translations update (#2197) 2023-04-06 14:03:08 -05:00
Vegard Fladby
e3b043e0e1 Update Norwegian locale to ICU standard (#2195)
* Update Norwegian locale to ICU standard

Don't know if this is the only place this should be edited.
But the Norwegian locale is not working on the Android app (still in English), And it seems like it should be 'nb-NO' and not 'no-NO'.

https://www.localeplanet.com/icu/nb-NO/index.html

* fix norweigian locale in other places

* fix norweigian locale in other places

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-06 14:00:24 -05:00
martyfuhry
0979906933 adds bottom safe area to video player (#2194) 2023-04-06 12:51:52 -05:00
martyfuhry
e241fd0418 don't show transparent bar for sdk < 26 (#2193) 2023-04-06 12:51:32 -05:00
Michel Heusschen
8e3a7caebd feat(server): improve validation of albums (#2188)
* feat(server): improve validation of albums

* regenerate openapi + fix downloadArchive for web
2023-04-06 12:50:55 -05:00
Michel Heusschen
b03ce897c7 fix(web): search page navigation and asset select (#2191) 2023-04-06 12:50:44 -05:00
Alex
d7c1005a50 Add PR template (#2192) 2023-04-06 12:23:06 -05:00
Michel Heusschen
1111c15f77 feat(web): allow admin to update email of users (#2189) 2023-04-06 11:56:27 -05:00
Alex Tran
fc12a9f751 chore: pump openapi gen files 2023-04-06 00:23:59 -05:00
Alex The Bot
cfcae39699 Version v1.53.0 2023-04-06 04:56:28 +00:00
Alex Tran
4c923bae7d chore(mobile): Add changelog 2023-04-05 23:55:23 -05:00
Zack Pollard
a5a6bebf0b feat(all): transcoding improvements (#2171)
* test: rename some fixtures and add text for vertical video conversion

* feat: transcode video asset when audio or container don't match target

* chore: add niceness to the ffmpeg command to allow other processes to be prioritised

* chore: change video conversion queue to one concurrency

* feat: add transcode disabled preset to completely turn off transcoding

* linter

* Change log level and remove unused await

* opps forgot to save

* better logging

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-05 22:32:59 -05:00
Michel Heusschen
6f1d0a3caa fix(web): remove search bar focus after searching (#2177) 2023-04-05 11:43:52 -05:00
Michel Heusschen
2b5484539d fix(web): hide assets when selecting album cover (#2176) 2023-04-05 11:41:27 -05:00
Michel Heusschen
5d21dc95ea fix(web): small gap in navbar (#2175) 2023-04-05 11:40:27 -05:00
Michel Heusschen
e32b6c98df chore(web): update svelte related packages (#2174) 2023-04-05 11:40:00 -05:00
Michel Heusschen
7b9248c10a chore(server): update typeorm (#2173) 2023-04-05 13:23:03 +01:00
Alex
4853240de9 fix(server): Revert alpine version to fix Sharp dependencies not installed correctly (#2172) 2023-04-05 02:57:30 +00:00
Michel Heusschen
d5f2e3e45c refactor(server): more consistent param validation (#2166) 2023-04-04 17:24:08 -05:00
martyfuhry
ad680b6a35 fix(mobile): Fixed hero animation re-enabling on immich asset grid (#2169)
* fixed hero animation re-enabling on immich asset grid

* comments
2023-04-04 17:23:47 -05:00
Jason Rasmussen
4cb74f0fe4 refactor(server): reverse geocoding (#2167)
* refactor(server): reverse geocoding

* fix: nullable results
2023-04-04 17:23:07 -05:00
Alex
333ab1124b fix(mobile): shared page does not get all shared albums (#2160) 2023-04-04 13:40:23 -05:00
Jason Rasmussen
48393c215b refactor(server): video transcode processor (#2163)
* refactor(server): video transcode processor

* refactor: rename shouldRotate to isVideoVertical, remove unnecessary await

* refactor: rename getOptions to getFfmpegOptions to be clearer in that context

* fix: optimal preset converting vertical videos already smaller than target resolution

---------

Co-authored-by: Zack Pollard <zackpollard@ymail.com>
2023-04-04 10:48:02 -04:00
Jason Rasmussen
ec6a7ae97c fix(server): do not link live photos across users (#2162) 2023-04-03 23:48:05 -05:00
Zack Pollard
808d6423be feat(all): ffmpeg quality options improvements (#2161)
* feat: change target scaling to resolution in ffmpeg config

* feat(microservices): scale vertical video correctly, only scale if video is larger than target
2023-04-03 20:42:53 -05:00
Mauro Molin
9076f3e69e Fix bulk upload example commands to work with paths with spaces (#2159)
The examples commands didn't work when the result of the subcommand $(pwd) contained spaces. This commit adds the proper escaping for them to work. This change also fixes the behavior of the alias allowing the correct current directory to be passed when it is placed inside the .bashrc file.
2023-04-03 20:19:10 -05:00
Sergey Kondrikov
7e526f87b4 feat(server): enhanced thumbnails generation code (#2147)
* Add size parameter to extractVideoThumbnail

* Ensure minimum dimension of webp thumbnail
2023-04-03 20:18:27 -05:00
Skyler Mäntysaari
fc585bffcc feat(server): Support TypeSense High-Availibility configuration (#2146)
* feat(server): Support TypeSense High-Availibility configuration.

* Lint fixes

* Address comments.
2023-04-03 20:16:45 -05:00
Alex
d6f2ca6aaa feat(mobile): improved logging page experience (#2158)
* feat(mobile): improve logging page

* Use new API for share file

* removed unused code

* Better safe area on the home screen

* Added preparing share dialog to home screen
2023-04-03 16:43:46 -05:00
Devin Buhl
2dcccb37a0 chore(docker): Default NODE_ENV to production for server image and update alpine version (#2157)
* default NODE_ENV to production for server image

* update node image to use 3.17 alpine in server

* update web docker image to use alpine 3.17

* remove NODE_ENV from production docker-compose

* NODE_ENV is also needed default in machine-learning
2023-04-03 15:05:29 -05:00
Michel Heusschen
c584791b65 feat(server): improve validation in controllers (#2149)
* feat(server): improve validation in controllers

* set ValidationPipe config with decorator
2023-04-02 23:24:18 -05:00
bo0tzz
ed551500e7 chore: Simplify install script (#2148)
We can directly access the artifacts from the latest release, rather than needing to get the tag from the API first.
2023-04-02 14:13:24 -05:00
AndreAle94
94b2ea9b5f Add timezone to exif entity (#1894)
* Add timezone to exif entity

* Refactor logging

---------

Co-authored-by: Andrea Alemani <andrea.alemani94@gmail.com>
2023-04-02 14:11:24 -05:00
Alex
8b001b87d2 chores(doc): Update documentation (#2145)
* Update app architecture with typesense

* Update readme

* Added local search

* replace diagram

* Update search page
2023-04-01 21:22:16 -05:00
Michel Heusschen
b06ddec2d5 feat(server/web): jobs clear button + queue status (#2144)
* feat(server/web): jobs clear button + queue status

* adjust design and colors

* Adjust some styling

* show status next to buttons instead of on top

* Update rounded corner for badge

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-04-01 15:46:07 -05:00
Alex
d04f340b5b fix(server): user update (#2143)
* fix(server): user update

* update dto

* generate api

* improve validation

* add e2e tests for updating user

---------

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
2023-04-01 11:43:45 -05:00
Michel Heusschen
aaaf1a6cf8 feat(web): pause and resume jobs (#2125)
* feat(web): pause and resume jobs

* add bg color to status instead of using badge

* styling

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-31 23:53:20 -05:00
Skyler Mäntysaari
23e4449f27 feat(server): redis sentinel support (#2141)
* feat(server): redis sentinel initial support

* feat(server): Lint fixes

* Include example for Redis Sentinel.

* Address PR comments
2023-03-31 15:33:21 -05:00
Michel Heusschen
51785a1ead feat(server): apply ValidationPipe on controllers (#2137) 2023-03-31 10:14:01 -05:00
Jason Rasmussen
49f66be8af chore(server): use ioredis (#2116) 2023-03-31 09:36:08 -05:00
Michel Heusschen
009b6e3ca5 feat(server): add faststart to ffmpeg options (#2138) 2023-03-31 09:34:54 -05:00
Thomas
c011b06bea docs: use correct helm chart url (#2133) 2023-03-31 05:25:53 -05:00
Jason Rasmussen
34d300d1da refactor(server): flatten infra folders (#2120)
* refactor: flatten infra folders

* fix: database migrations

* fix: test related import

* fix: github actions workflow

* chore: rename schemas to typesense-schemas
2023-03-30 14:38:55 -05:00
Jason Rasmussen
468e620372 chore: remove unused config (#2121) 2023-03-30 12:22:25 -05:00
manuke42
e05153d7bb add fdroid isar build script (#2100)
Co-authored-by: Manuel K <manuel@kerk-net.de>
2023-03-30 10:31:44 +02:00
Alex Tran
4aa4a3b597 chore: pump openapi gen files 2023-03-29 13:18:09 -05:00
Alex The Bot
b1d17302bc Version v1.52.1 2023-03-29 17:37:33 +00:00
Alex
cc3ffcbb84 fix(server): incorrect video file path to serve for mobile vs web (#2118) 2023-03-29 12:36:18 -05:00
Michel Heusschen
eda9e580c9 fix(server): add paused property to JobCountsDto (#2112) 2023-03-29 10:33:03 -05:00
Alex Tran
76a07a3ebc chore: add change logs 2023-03-28 17:19:10 -05:00
Alex Tran
abe87686a2 chore: post release openapi update 2023-03-28 15:49:21 -05:00
Alex Tran
6371c11fc5 Merge branch 'main' of github.com:immich-app/immich 2023-03-28 15:48:50 -05:00
Alex The Bot
d5596cf6a2 Version v1.52.0 2023-03-28 20:33:08 +00:00
Alex Tran
2f64af9cb2 Merge branch 'main' of github.com:immich-app/immich 2023-03-28 15:07:53 -05:00
Jason Rasmussen
b0d5c7035b feat(server): apply storage migration after exif completes (#2093)
* feat(server): apply storage migraiton after exif completes

* feat: same for videos

* fix: migration for live photos
2023-03-28 15:04:11 -05:00
Alex Tran
0c61521521 Merge branch 'main' of github.com:immich-app/immich 2023-03-28 14:47:51 -05:00
Jason Rasmussen
3497a0de54 chore: cleanup template variables (#2107) 2023-03-28 14:27:36 -05:00
Alex
117f2fa00d chore(ci): update prepare release action to bypass branch check (#2106)
* chore: fix api

* chore(ci): update prepare release action to bypass branch check
2023-03-28 14:26:55 -05:00
Sergey Kondrikov
2c67090e3c feat(server): add transcode presets (#2084)
* feat: add transcode presets

* Add migration

* chore: generate api

* refactor: use enum type instead of string for transcode option

* chore: generate api

* refactor: enhance readability of runVideoEncode method

* refactor: reuse SettingSelect for transcoding presets

* refactor: simplify return statement

* chore: regenerate api

* fix: correct label attribute

* Update import

* fix test

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-03-28 14:03:43 -05:00
Alex Tran
10ccbeab35 Merge branch 'main' of github.com:immich-app/immich 2023-03-28 13:45:53 -05:00
Parikshit Misra
b49f66bbc9 feat(mobile): uploading files in chunk (#2101) 2023-03-28 13:41:55 -05:00
Jason Rasmussen
9adbbd42be feat(server): resume queues (#2104)
* feat(server): resume queues

* chore: regenerate open-api
2023-03-28 13:25:22 -05:00
Jason Rasmussen
8563bd463c fix(cli): clean up set intervals (#2103) 2023-03-28 13:24:14 -05:00
Jason Rasmussen
da5a6d2272 fix(cli): missing dep in immich cli (#2094)
* fix: missing dep in immich cli

* fix: imports
2023-03-28 11:29:20 -05:00
Alex
0854737be2 feat(mobile): improve explore page and allow metadata search (#2097) 2023-03-28 15:34:06 +00:00
Alex Tran
6f3f8b0a48 Merge branch 'main' of github.com:immich-app/immich 2023-03-28 09:57:08 -05:00
Michel Heusschen
f0e272d0f2 feat(server): change clipembedding entity type (#2091) 2023-03-28 09:53:35 -05:00
Alex Tran
5e207aa7c1 Merge branch 'main' of github.com:immich-app/immich 2023-03-27 22:07:15 -05:00
Jason Rasmussen
e0b80f49b6 fix(server): increase typesense start-up settings (#2095) 2023-03-27 14:00:32 -05:00
Alex Tran
97bbe42599 Merge branch 'main' of github.com:immich-app/immich 2023-03-27 10:41:24 -05:00
Michel Heusschen
089dbdbd7e feat(server): require auth for more endpoints (#2092)
* feat(server): require auth for more endpoints

* dev: add authorization header to profile image on mobile

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2023-03-27 09:38:54 -05:00
Alex Tran
833c099025 Merge branch 'main' of github.com:immich-app/immich 2023-03-27 08:45:12 -05:00
Michel Heusschen
4e526dfaae feat(web): improve and refactor thumbnails (#2087)
* feat(web): improve and refactor thumbnails

* only play live photos on icon hover
2023-03-26 22:53:35 -05:00
Fynn Petersen-Frey
cae37657e9 feature(mobile): Hardening synchronization mechanism + Pull to refresh (#2085)
* fix(mobile): allow syncing duplicate local IDs

* enable to run isar unit tests on CI

* serialize sync operations, add pull to refresh on timeline

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
2023-03-26 21:35:52 -05:00
Zeyad Tamimi
1a94530935 [ Mobile ] Fixed mobile app not reporting webm MIME type (#2090) 2023-03-27 00:38:23 +00:00
Alex Tran
75d28d3c58 Merge branch 'main' of github.com:immich-app/immich 2023-03-26 10:43:52 -05:00
Alex
cd59f7aad6 fix(server) get all query does not respect asset type (#2089)
* chore: fix api

* fix(server) get all query does not respect asset type
2023-03-26 10:41:55 -05:00
Alex Tran
2f9fcd96c7 Merge branch 'main' of github.com:immich-app/immich 2023-03-25 21:51:10 -05:00
Michel Heusschen
c74fba483d feat(server): improve and refactor get all albums (#2048)
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-25 21:46:48 -05:00
Alex Tran
193dd01e06 Merge branch 'main' of github.com:immich-app/immich 2023-03-25 10:15:48 -05:00
Jason Rasmussen
2400004f41 feat(server): split generated content into a separate folder (#2047)
* feat: organize media folders

* fix: tests
2023-03-25 09:50:57 -05:00
Alex
b862c20e8e chore: fix api (#2079) 2023-03-25 04:22:02 +00:00
Alex Tran
c0ed623d26 chore: fix api 2023-03-24 23:17:40 -05:00
martyfuhry
501b96baf7 feat(mobile): Explore favorites, recently added, videos, and motion photos (#2076)
* Added placeholder for search explore

* refactor immich asset grid to use ref and provider

* all videos page

* got favorites, recently added, videos, and motion videos all using the immich grid

* Fixed issue with hero animations

* theming

* localization

* delete empty file

* style text

* Styling icons

* more styling

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-24 22:44:53 -05:00
Jonathan Jogenfors
d2600e0ddd Documentation: Add FAQ items for reverse proxy and rpi performance (#2070)
* Add FAQ items for reverse proxy and rpi performance

* Fix wording
2023-03-24 09:36:44 -05:00
Michel Heusschen
7d799b785e fix(web): remove protocol header (#2068) 2023-03-24 07:20:06 -05:00
Jason Rasmussen
e36b620020 refactor(server): cron jobs (#2067) 2023-03-24 07:19:48 -05:00
Jason Rasmussen
1efc74dabc refactor(server): common (#2066) 2023-03-23 23:55:15 -05:00
Jason Rasmussen
54f98053a8 chore(server): cleanup controllers (#2065) 2023-03-23 23:53:56 -05:00
Jason Rasmussen
6745826f35 refactor(server): media service (#2051)
* refactor(server): media service

* merge main

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-23 21:40:46 -05:00
Jason Rasmussen
bbd897b8ff refactor(server): asset serve files (#2052) 2023-03-23 21:40:30 -05:00
Alex Tran
586590e9ec fix(web): unused variables 2023-03-23 21:13:28 -05:00
Alex
4bf50a0b46 feat(web): better search bar (#2062) 2023-03-23 17:57:49 -05:00
Fynn Petersen-Frey
40832f0ea7 refactor(mobile): store backup settings on device (#2054)
Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-23 10:25:58 -05:00
martyfuhry
32a065afc7 feat(mobile): Use new search API and GridView for Places / Locations (#2043)
* Use new search API and GridView for Places / Locations

* Fixes search service by adding clip: true

* Rebased from master, uses view all explore grid now

* localized view all button

* adds empty

* style text

* Fix issue with horizontal Things not render due to missing height info

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-03-23 10:08:14 -05:00
Michel Heusschen
4dafc74223 fix(server): invalid video duration format (#2058) 2023-03-23 09:27:29 -05:00
bo0tzz
8adf1231a3 fix(server): Do not change file ext case on upload (#2056) 2023-03-23 09:06:40 -05:00
Michel Heusschen
c00624f209 chore: bump openapi version to v1.51.2 (#2059) 2023-03-23 06:42:33 -05:00
Fynn Petersen-Frey
eccde8fa07 refactor(mobile): migrate all Hive boxes to Isar database (#2036) 2023-03-22 20:36:44 -05:00
Skyler Mäntysaari
0616a66b05 feat(server): Allow .mkv, .wmv, .flv, .mpg videos to be uploaded. (#2045) 2023-03-22 18:34:13 -05:00
Immich Release Bot
67453d18ff Version v1.51.2 2023-03-22 21:12:45 +00:00
Michel Heusschen
792a87e407 fix(nginx): x-forwarded-* headers (#2019)
* fix(nginx): x-forwarded-* headers

* change category / add link to nginx config
2023-03-22 15:46:30 -05:00
Skyler Mäntysaari
6da50626e1 fix(server): Return the original path for gif playback (#2022)
* fix(server): Return the original path for gifs.

Usually browser is able to play them directly.

* fix(server): Better place for the condition.

* fix(server): gif viewing works properly.
2023-03-22 14:56:00 -05:00
Jason Rasmussen
6239b3b309 fix: import assets on new install (#2044) 2023-03-22 00:36:32 -05:00
Jason Rasmussen
b9bc621e2a refactor: server-info (#2038) 2023-03-21 21:49:19 -05:00
Jason Rasmussen
e10bbfa933 chore: always restart typesense (#2042) 2023-03-21 21:41:19 -05:00
Jason Rasmussen
2dd301e292 feat: show current/saved template in preset dropdown (#2040) 2023-03-21 15:19:47 -05:00
1028 changed files with 36368 additions and 19504 deletions

View File

@@ -0,0 +1,2 @@
blank_issues_enabled: false
blank_pull_request_template_enabled: false

View File

@@ -0,0 +1,22 @@
## Description
<!--- Describe your changes in detail -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
Fixes # (issue)
## How Has This Been Tested?
<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration -->
- [ ] Test A
- [ ] Test B
## Screenshots (if appropriate):
## Checklist:
- [ ] I have performed a self-review of my own code
- [ ] I have made corresponding changes to the documentation if applicable

View File

@@ -45,7 +45,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.7.3"
flutter-version: "3.10.0"
cache: true
- name: Create the Keystore

79
.github/workflows/docker-cleanup.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
# This workflow runs on certain conditions to check for and potentially
# delete container images from the GHCR which no longer have an associated
# code branch.
# Requires a PAT with the correct scope set in the secrets.
#
# This workflow will not trigger runs on forked repos.
name: Cleanup Old Docker Images
on:
pull_request:
types:
- "closed"
push:
paths:
- ".github/workflows/docker-cleanup.yml"
concurrency:
group: registry-tags-cleanup
cancel-in-progress: false
jobs:
cleanup-images:
name: Cleanup Stale Images Tags for ${{ matrix.primary-name }}
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- primary-name: "immich-server"
- primary-name: "immich-machine-learning"
- primary-name: "immich-web"
- primary-name: "immich-proxy"
env:
# Requires a personal access token with the OAuth scope delete:packages
TOKEN: ${{ secrets.PACKAGE_DELETE_TOKEN }}
steps:
-
name: Clean temporary images
if: "${{ env.TOKEN != '' }}"
uses: stumpylog/image-cleaner-action/ephemeral@v0.1.0
with:
token: "${{ env.TOKEN }}"
owner: "immich-app"
is_org: "true"
do_delete: "true"
package_name: "${{ matrix.primary-name }}"
scheme: "pull_request"
repo_name: "immich"
match_regex: '^pr-(\d+)$|^(\d+)$'
cleanup-untagged-images:
name: Cleanup Untagged Images Tags for ${{ matrix.primary-name }}
runs-on: ubuntu-22.04
needs:
- cleanup-images
strategy:
fail-fast: false
matrix:
include:
- primary-name: "immich-server"
- primary-name: "immich-machine-learning"
- primary-name: "immich-web"
- primary-name: "immich-proxy"
- primary-name: "immich-build-cache"
env:
# Requires a personal access token with the OAuth scope delete:packages
TOKEN: ${{ secrets.PACKAGE_DELETE_TOKEN }}
steps:
-
name: Clean untagged images
if: "${{ env.TOKEN != '' }}"
uses: stumpylog/image-cleaner-action/untagged@v0.1.0
with:
token: "${{ env.TOKEN }}"
owner: "immich-app"
do_delete: "true"
is_org: "true"
package_name: "${{ matrix.primary-name }}"

View File

@@ -13,6 +13,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
packages: write
jobs:
build_and_push:
runs-on: ubuntu-latest

View File

@@ -1,23 +0,0 @@
name: github-repo-stats
on:
schedule:
# Run this once per day, towards the end of the day for keeping the most
# recent data point most meaningful (hours are interpreted in UTC).
- cron: "0 23 * * *"
workflow_dispatch: # Allow for running this manually.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
j1:
name: github-repo-stats
runs-on: ubuntu-latest
steps:
- name: run-ghrs
# Use latest release.
uses: jgehrcke/github-repo-stats@RELEASE
with:
ghtoken: ${{ secrets.GHRS_GITHUB_API_TOKEN }}

View File

@@ -41,8 +41,9 @@ jobs:
id: push-tag
uses: EndBug/add-and-commit@v9
with:
author_name: Immich Release Bot
author_email: bot@immich.app
author_name: Alex The Bot
author_email: alex.tran1502@gmail.com
default_author: user_info
message: "Version ${{ env.IMMICH_VERSION }}"
tag: ${{ env.IMMICH_VERSION }}
push: true

View File

@@ -22,8 +22,8 @@ jobs:
- name: Setup Flutter SDK
uses: subosito/flutter-action@v2
with:
channel: 'stable'
flutter-version: '3.7.3'
channel: "stable"
flutter-version: "3.10.0"
- name: Install dependencies
run: dart pub get
@@ -32,4 +32,3 @@ jobs:
- name: Run dart analyze
run: dart analyze --fatal-infos
working-directory: ./mobile

View File

@@ -12,7 +12,6 @@ concurrency:
jobs:
e2e-tests:
name: Run end-to-end test suites
runs-on: ubuntu-latest
steps:
@@ -22,27 +21,87 @@ jobs:
- name: Run Immich Server E2E Test
run: docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --abort-on-container-exit --exit-code-from immich-server-test
server-unit-tests:
name: Run server unit test suites and checks
doc-tests:
name: Run documentation checks
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./docs
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run tests
run: cd server && npm ci && npm run check:all
- name: Run npm install
run: npm ci
- name: Run formatter
run: npm run format
if: ${{ !cancelled() }}
- name: Run tsc
run: npm run check
if: ${{ !cancelled() }}
server-unit-tests:
name: Run server unit test suites and checks
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./server
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run npm install
run: npm ci
- name: Run linter
run: npm run lint
if: ${{ !cancelled() }}
- name: Run formatter
run: npm run format
if: ${{ !cancelled() }}
- name: Run tsc
run: npm run check
if: ${{ !cancelled() }}
- name: Run unit tests & coverage
run: npm run test:cov
if: ${{ !cancelled() }}
web-unit-tests:
name: Run web unit test suites and checks
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./web
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run tests
run: cd web && npm ci && npm run check:all
- name: Run npm install
run: npm ci
- name: Run linter
run: npm run lint
if: ${{ !cancelled() }}
- name: Run formatter
run: npm run format
if: ${{ !cancelled() }}
- name: Run svelte checks
run: npm run check
if: ${{ !cancelled() }}
- name: Run unit tests & coverage
run: npm run test:cov
if: ${{ !cancelled() }}
mobile-unit-tests:
name: Run mobile unit tests
@@ -53,10 +112,10 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.7.3"
flutter-version: "3.10.0"
- name: Run tests
working-directory: ./mobile
run: flutter test
run: flutter test -j 1
generated-api-up-to-date:
name: Check generated files are up-to-date
@@ -64,7 +123,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Run API generation
run: cd server && npm ci && npm run api:generate
run: npm --prefix server run api:generate
- name: Find file changes
uses: tj-actions/verify-changed-files@v13.1
id: verify-changed-files
@@ -99,24 +158,18 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install server dependencies
run: |
cd server
npm ci
run: npm --prefix server ci
- name: Run existing migrations
run: |
cd server
npm run typeorm:migrations:run
run: npm --prefix server run typeorm:migrations:run
- name: Generate new migrations
continue-on-error: true
run: |
cd server
npm run typeorm:migrations:generate ./libs/infra/src/db/migrations/TestMigration
run: npm --prefix server run typeorm:migrations:generate ./libs/infra/src/migrations/TestMigration
- name: Find file changes
uses: tj-actions/verify-changed-files@v13.1
id: verify-changed-files
with:
files: |
server/libs/infra/src/db/migrations/
server/libs/infra/src/migrations/
- name: Verify files have not changed
if: steps.verify-changed-files.outputs.files_changed == 'true'
run: |

9
.vscode/launch.json vendored
View File

@@ -9,6 +9,15 @@
"name": "Immich Server",
"remoteRoot": "/usr/src/app",
"localRoot": "${workspaceFolder}/server"
},
{
"type": "node",
"request": "attach",
"restart": true,
"port": 9231,
"name": "Immich Microservices",
"remoteRoot": "/usr/src/app",
"localRoot": "${workspaceFolder}/server"
}
]
}

View File

@@ -1,17 +1,17 @@
dev:
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --remove-orphans
docker-compose -f ./docker/docker-compose.dev.yml up --remove-orphans
dev-new:
rm -rf ./server/dist && docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
dev-new-update:
rm -rf ./server/dist && docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
dev-update:
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
dev-scale:
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
stage:
docker-compose -f ./docker/docker-compose.staging.yml up --build -V --remove-orphans

View File

@@ -1,17 +0,0 @@
# Deployment checklist for iOS/Android/Server
[ ] Up version in [mobile/pubspec.yml](/mobile/pubspec.yaml)
[ ] Up version in [docker/docker-compose.yml](/docker/docker-compose.yml) for `immich_server` service
[ ] Up version in [docker/docker-compose.gpu.yml](/docker/docker-compose.gpu.yml) for `immich_server` service
[ ] Up version in [docker/docker-compose.dev.yml](/docker/docker-compose.dev.yml) for `immich_server` service
[ ] Up version in [server/src/constants/server_version.constant.ts](/server/src/constants/server_version.constant.ts)
[ ] Up version in iOS Fastlane [/mobile/ios/fastlane/Fastfile](/mobile/ios/fastlane/Fastfile)
[ ] Add changelog to [Android Fastlane F-droid folder](/mobile/android/fastlane/metadata/android/en-US/changelogs)
All of the version should be the same.

View File

@@ -37,7 +37,6 @@
- [Installation](https://immich.app/docs/install/requirements)
- [Contribution Guidelines](https://immich.app/docs/overview/support-the-project)
- [Support The Project](#support-the-project)
- [Known Issues](#known-issues)
## Documentation
@@ -61,25 +60,30 @@ Spec: Free-tier Oracle VM - Amsterdam - 2.4Ghz quad-core ARM64 CPU, 24GB RAM
# Features
| Features | Mobile | Web |
| ------------------------------------------- | ------ | --- |
| Upload and view videos and photos | Yes | Yes |
| Auto backup when the app is opened | Yes | N/A |
| Selective album(s) for backup | Yes | N/A |
| Download photos and videos to local device | Yes | Yes |
| Multi-user support | Yes | Yes |
| Album and Shared albums | Yes | Yes |
| Scrubbable/draggable scrollbar | Yes | Yes |
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes |
| Metadata view (EXIF, map) | Yes | Yes |
| Search by metadata, objects and image tags | Yes | No |
| Administrative functions (user management) | N/A | Yes |
| Background backup | Yes | N/A |
| Virtual scroll | Yes | Yes |
| OAuth support | Yes | Yes |
| LivePhoto backup and playback | iOS | Yes |
| User-defined storage structure | Yes | Yes |
| Public Sharing | N/A | Yes |
| Features | Mobile | Web |
| -------------------------------------------- | ------ | --- |
| Upload and view videos and photos | Yes | Yes |
| Auto backup when the app is opened | Yes | N/A |
| Selective album(s) for backup | Yes | N/A |
| Download photos and videos to local device | Yes | Yes |
| Multi-user support | Yes | Yes |
| Album and Shared albums | Yes | Yes |
| Scrubbable/draggable scrollbar | Yes | Yes |
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes |
| Metadata view (EXIF, map) | Yes | Yes |
| Search by metadata, objects, faces, and CLIP | Yes | Yes |
| Administrative functions (user management) | No | Yes |
| Background backup | Yes | N/A |
| Virtual scroll | Yes | Yes |
| OAuth support | Yes | Yes |
| API Keys | N/A | Yes |
| LivePhoto backup and playback | iOS | Yes |
| User-defined storage structure | Yes | Yes |
| Public Sharing | No | Yes |
| Archive and Favorites | Yes | Yes |
| Global Map | No | Yes |
| Partner Sharing | No | Yes |
| Facial recognition and clustering | No | Yes |
# Support the project
@@ -96,11 +100,3 @@ If you feel like this is the right cause and the app is something you are seeing
- [Librepay](https://liberapay.com/alex.tran1502/)
- [buymeacoffee](https://www.buymeacoffee.com/altran1502)
- Bitcoin: 1FvEp6P6NM8EZEkpGUFAN2LqJ1gxusNxZX
# Known Issues
## immich-machine-learning fails to start
Symptoms: the container logs `illegal instruction core dump` and restarts
Solution: https://immich.app/docs/install/requirements#hardware

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -1,32 +0,0 @@
# Development Setup
## Lint / format extensions
Setting these in the IDE give a better developer experience auto-formatting code on save and providing instant feedback on lint issues.
### VSCode
Install Prettier, ESLint and Svelte extensions.
in User `settings.json` (`cmd + shift + p` and search for Open User Settings JSON) add the following:
```json
{
"editor.formatOnSave": true,
"[javascript][typescript][css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2,
"editor.formatOnSave": true
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode",
"editor.tabSize": 2
},
"svelte.enable-ts-plugin": true,
"eslint.validate": ["javascript", "svelte"]
}
```
## Running tests / checks
In both server and web:
`npm run check:all`

View File

@@ -53,13 +53,15 @@ services:
context: ../server
dockerfile: Dockerfile
target: builder
command: npm run start:dev microservices
command: npm run start:debug microservices
volumes:
- ../server:/usr/src/app
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /usr/src/app/node_modules
env_file:
- .env
ports:
- 9231:9230
environment:
- NODE_ENV=development
depends_on:
@@ -133,8 +135,6 @@ services:
dockerfile: Dockerfile
ports:
- 2283:8080
logging:
driver: none
depends_on:
- immich-server
restart: always

View File

@@ -4,13 +4,11 @@ services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:release
entrypoint: [ "/bin/sh", "./start-server.sh" ]
entrypoint: ["/bin/sh", "./start-server.sh"]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
env_file:
- .env
environment:
- NODE_ENV=production
depends_on:
- redis
- database
@@ -20,13 +18,11 @@ services:
immich-microservices:
container_name: immich_microservices
image: ghcr.io/immich-app/immich-server:release
entrypoint: [ "/bin/sh", "./start-microservices.sh" ]
entrypoint: ["/bin/sh", "./start-microservices.sh"]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
env_file:
- .env
environment:
- NODE_ENV=production
depends_on:
- redis
- database
@@ -41,14 +37,12 @@ services:
- model-cache:/cache
env_file:
- .env
environment:
- NODE_ENV=production
restart: always
immich-web:
container_name: immich_web
image: ghcr.io/immich-app/immich-web:release
entrypoint: [ "/bin/sh", "./entrypoint.sh" ]
entrypoint: ["/bin/sh", "./entrypoint.sh"]
env_file:
- .env
restart: always
@@ -63,6 +57,7 @@ services:
driver: none
volumes:
- tsdata:/data
restart: always
redis:
container_name: immich_redis
@@ -92,8 +87,6 @@ services:
- IMMICH_WEB_URL
ports:
- 2283:8080
logging:
driver: none
depends_on:
- immich-server
restart: always

View File

@@ -2,6 +2,8 @@
# Database
###################################################################################
# NOTE: The following four database variables support Docker secrets by adding a *_FILE suffix to the variable name
# See the docker-compose documentation on secrets for additional details: https://docs.docker.com/compose/compose-file/compose-file-v3/#secrets
DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_PASSWORD=postgres
@@ -16,6 +18,11 @@ DB_DATABASE_NAME=immich
REDIS_HOSTNAME=immich_redis
# REDIS_URL will be used to pass custom options to ioredis.
# Example for Sentinel
# {"sentinels":[{"host":"redis-sentinel-node-0","port":26379},{"host":"redis-sentinel-node-1","port":26379},{"host":"redis-sentinel-node-2","port":26379}],"name":"redis-sentinel"}
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJyZWRpcy1zZW50aW5lbDEiLCJwb3J0IjoyNjM3OX0seyJob3N0IjoicmVkaXMtc2VudGluZWwyIiwicG9ydCI6MjYzNzl9XSwibmFtZSI6Im15bWFzdGVyIn0=
# Optional Redis settings:
# Note: these parameters are not automatically passed to the Redis Container
@@ -24,6 +31,7 @@ REDIS_HOSTNAME=immich_redis
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_USERNAME=
# REDIS_PASSWORD=
# REDIS_SOCKET=
@@ -41,6 +49,14 @@ UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_ba
###################################################################################
TYPESENSE_API_KEY=some-random-text
# TYPESENSE_ENABLED=false
# TYPESENSE_URL uses base64 encoding for the nodes json.
# Example JSON that was used:
# [
# { 'host': 'typesense-1.example.net', 'port': '443', 'protocol': 'https' },
# { 'host': 'typesense-2.example.net', 'port': '443', 'protocol': 'https' },
# { 'host': 'typesense-3.example.net', 'port': '443', 'protocol': 'https' },
# ]
# TYPESENSE_URL=ha://WwogICAgeyAnaG9zdCc6ICd0eXBlc2Vuc2UtMS5leGFtcGxlLm5ldCcsICdwb3J0JzogJzQ0MycsICdwcm90b2NvbCc6ICdodHRwcycgfSwKICAgIHsgJ2hvc3QnOiAndHlwZXNlbnNlLTIuZXhhbXBsZS5uZXQnLCAncG9ydCc6ICc0NDMnLCAncHJvdG9jb2wnOiAnaHR0cHMnIH0sCiAgICB7ICdob3N0JzogJ3R5cGVzZW5zZS0zLmV4YW1wbGUubmV0JywgJ3BvcnQnOiAnNDQzJywgJ3Byb3RvY29sJzogJ2h0dHBzJyB9LApd
###################################################################################
# Reverse Geocoding

2
docs/.prettierignore Normal file
View File

@@ -0,0 +1,2 @@
build/
.docusaurus/

6
docs/.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"semi": true
}

View File

@@ -33,9 +33,8 @@ The motion part will now be uploaded and can be played on the mobile app and the
src="https://media.giphy.com/media/fTrGceZd7t1ewi8ESc/giphy.gif"
width="100%"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
borderRadius: '10px',
boxShadow: 'rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px',
}}
title="LivePhoto playback on the web"
/>
@@ -73,9 +72,8 @@ The web will have the option to sign in with OAuth.
width="50%"
title="Web Sign in with OAuth"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
borderRadius: '10px',
boxShadow: 'rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px',
}}
/>
@@ -86,9 +84,8 @@ sign-in button.
src="https://media.giphy.com/media/3iy3SaNkVYtlkEiw06/giphy.gif"
title="Mobile sign in with OAuth"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
borderRadius: '10px',
boxShadow: 'rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px',
}}
/>
@@ -98,9 +95,8 @@ sign-in button.
src="https://media.giphy.com/media/LStqgGESXW8XnuCv5y/giphy.gif"
width="300"
style={{
borderRadius: "10px",
boxShadow:
"rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px",
borderRadius: '10px',
boxShadow: 'rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px',
}}
title="Support the project"
/>

View File

@@ -14,29 +14,49 @@ sidebar_position: 7
### How can I sync an existing directory with Immich's server?
Immich doesn't have the mechanism to sync an existing directory with the server. There is however, a helper CLI tool to help you bulk upload the existing photos and videos to the server. You can find the guide to use the CLI tool [here](/docs/features/bulk-upload.md).
Immich doesn't have two-way synchronization ([yet](https://github.com/immich-app/immich/discussions/1006)), but the [command line tool](/docs/features/bulk-upload.md) can bulk upload items from a directory to Immich.
### Why doesn't Immich watch an existing photo gallery directory?
The initial approach of Immich is to become a backup tool, primarily for mobile device usage. Thus, all the assets must be uploaded from the mobile client. The app was architectured to perform that job well.
### Why does my uploaded photo show up with the wrong date or time in Immich?
When a photo is initially uploaded Immich uses the create date of the file to determine where it belongs in the timeline. After that, background jobs will run that extract [exif metadata](https://en.wikipedia.org/wiki/Exif), including the CreateDate, to provide a more accurate date for the photo. If that is not available it will fallback to the modified date. If you want to ensure your photo has the right date, check the exif metadata before uploading.
When a photo is initially uploaded Immich uses the create date of the file to determine where it belongs in the timeline. After that, background jobs will run that extract [exif metadata](https://en.wikipedia.org/wiki/Exif), including the CreateDate, to provide a more accurate date for the photo. If that is not available it will fallback to the modified date. If you want to ensure your photo has the right date, check the exif metadata before uploading.
If the timezone is incorrect in an uploaded photo, check the ``DateTimeOriginal`` exif field of the uploaded file. Immich uses the very competent library [exiftool-vendored.js](https://github.com/photostructure/exiftool-vendored.js#dates) to handle timezone parsing, but in some cases (like photos taken with DSLR cameras) it has to fallback on the local timezone. If you are using docker, this fallback will be UTC. (Note that even the photo backup app that can't be named [has the same bug!](https://photo.stackexchange.com/a/126978)) In Immich, it is possible to change this assumed fallback timezone system-wide by setting the timezone in the microservices docker container. You might need to run the "Extract Metadata" job after to effect the change.
If the timezone is incorrect in an uploaded photo, check the `DateTimeOriginal` exif field of the uploaded file. Immich uses the very competent library [exiftool-vendored.js](https://github.com/photostructure/exiftool-vendored.js#dates) to handle timezone parsing, but in some cases (like photos taken with DSLR cameras) it has to fallback on the local timezone. If you are using docker, this fallback will be UTC. (Note that even the photo backup app that can't be named [has the same bug!](https://photo.stackexchange.com/a/126978)) In Immich, it is possible to change this assumed fallback timezone system-wide by setting the timezone in the microservices docker container. You might need to run the "Extract Metadata" job after to effect the change.
As an example, the following modification of ```docker-compose.yml``` will set the timezone of the microservices container to be ``Europe/Stockholm``
As an example, the following modification of `docker-compose.yml` will set the timezone of the microservices container to be `Europe/Stockholm`
```
environment:
- TZ=Europe/Stockholm # <---- Add this line in the microservices config
```
### Why doesn't Immich watch an existing photo gallery directory?
### Why are only photos and not videos being uploaded to Immich?
The initial approach of Immich is to become a backup tool, primarily for mobile device usage. Thus, all the assets must be uploaded from the mobile client. The app was architectured to perform that job well.
This often happens when using a reverse proxy or cloudflare tunnel in front of Immich. Make sure to set your reverse proxy to allow large POST requests. In `nginx`, set `client_max_body_size 50000M;` or similar. Cloudflare tunnels are limited to 100 mb file sizes.
### Why is Immich slow on low-memory systems like the Raspberry Pi?
Immich uses optional machine-learning features to enhance search results. This feature, however, can be too heavy to run on a Raspberry Pi. To disable machine learning, comment out the `immich-machine-learning` section of your docker-compose.yml and set `IMMICH_MACHINE_LEARNING_URL=false` in your .env file.
### How to disable machine-learning and TypeSense?
:::warning
Disabling both will result in poor search experience and typesense utilizes CLIP embeddings which are generated by machine-learning.
:::
These features can be disabled by commenting out `immich-typesense` and `immich-machine-learning` sections of the docker-compose.yml and setting `IMMICH_MACHINE_LEARNING_URL=false` & `TYPESENSE_ENABLED=false` in your .env file.
### What happens to existing files after I choose a new [Storage Template](/docs/administration/storage-template.mdx)?
Template changes will only apply to new assets. To retroactively apply the template to previously uploaded assets, run the Storage Migration Job, available on the [Jobs](/docs/administration/jobs.md) page.
### In the uploads folder, why are photos stored in the wrong date?
This is fixed by running the storage migration job.
### Why is object detection not very good?
The model we used for machine learning is a prebuilt model, so the accuracy is not very good. It will hopefully be replaced with a better solution in the future.
@@ -57,6 +77,10 @@ The non-root user/group needs read/write access to the volume mounts, including
The admin password can be reset by running the [reset-admin-password](/docs/administration/server-commands.md) command on the immich-server.
### How can I backup data from Immich?
See [backup and restore](/docs/administration/backup-and-restore.md).
### How can I **purge** data from Immich?
Data for Immich comes in two forms:
@@ -71,3 +95,7 @@ docker-compose down -v
```
After removing the the containers and volumes, the **Files** can be cleaned up (if necessary) from the `UPLOAD_LOCATION` by simply deleting an unwanted files or folders.
### Why iOS app shows duplicate photos on the timeline while the web doesn't?
If you are using `My Photo Stream`, the Photos app temporarily creates duplicates of photos taken in the last 30 days. These photos are included in the `Recents` album and thus shown up twice. To fix this, you can disable `My Photo Stream` in the native Photos app or choose a different album in the backup screen in Immich.

View File

@@ -1,5 +1,4 @@
{
"label": "Administration",
"position": 4
}
"label": "Administration",
"position": 4
}

View File

@@ -0,0 +1,55 @@
# Backup and Restore
## Database
:::info
Refer to the official [postgres documentation](https://www.postgresql.org/docs/current/backup.html) for details about backing up and restoring a postgres database.
:::
The recommended way to backup and restore the Immich database is to use the `pg_dumpall` command.
```bash title='Backup'
docker exec -t immich_postgres pg_dumpall -c -U postgres | gzip > "/path/to/backup/dump.sql.gz"
```
```bash title='Restore'
gunzip < /path/to/backup/dump.sql.gz | docker exec -i immich_postgres psql -U postgres -d immich
```
The database dumps can also be automated (using [this image](https://github.com/prodrigestivill/docker-postgres-backup-local)) by editing the docker compose file to match the following:
```yaml
services:
...
backup:
container_name: immich_db_dumper
image: prodrigestivill/postgres-backup-local
env_file:
- .env
environment:
POSTGRES_HOST: database
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
SCHEDULE: "@daily"
BACKUP_NUM_KEEP: 7
BACKUP_DIR: /db_dumps
volumes:
- ./db_dumps:/db_dumps
depends_on:
- database
```
Then you can restore with the same command but pointed at the latest dump.
```bash title='Automated Restore'
gunzip < db_dumps/last/immich-latest.sql.gz | docker exec -i immich_postgres psql -U postgres -d immich
```
## Filesystem
Immich stores two types of content in the filesystem: (1) original, unmodified content, and (2) generated content. Only the original content needs to be backed-up, which includes the following folders:
1. `UPLOAD_LOCATION/library`
1. `UPLOAD_LOCATION/upload`
1. `UPLOAD_LOCATION/profile`

View File

@@ -0,0 +1,22 @@
# Reverse Proxy
When deploying Immich it is important to understand that a reverse proxy is required in front of the server and web container. The reverse proxy acts as an intermediary between the user and container, forwarding requests to the correct container based on the URL path.
## Default Reverse Proxy
Immich provides a default nginx reverse proxy preconfigured to perform the correct routing and set the necessary headers for the server and web container to use. These headers are crucial to redirect to the correct URL and determine the client's IP address.
## Using a Different Reverse Proxy
While the reverse proxy provided by Immich works well for basic deployments, some users may want to use a different reverse proxy. Fortunately, Immich is flexible enough to accommodate different reverse proxies. Users can either:
1. Add another reverse proxy on top of Immich's reverse proxy
2. Completely replace the default reverse proxy
## Adding a Custom Reverse Proxy
Users can deploy a custom reverse proxy that forwards requests to Immich's reverse proxy. This way, the new reverse proxy can handle TLS termination, load balancing, or other advanced features, while still delegating routing decisions to Immich's reverse proxy. All reverse proxies between Immich and the user must forward all headers and set the `Host`, `X-Forwarded-Host`, `X-Forwarded-Proto` and `X-Forwarded-For` headers to their appropriate values. By following these practices, you ensure that all custom reverse proxies are fully compatible with Immich.
## Replacing the Default Reverse Proxy
Replacing Immich's default reverse proxy is an advanced deployment and support may be limited. When replacing Immich's default proxy it is important to ensure that requests to `/api/*` are routed to the server container and all other requests to the web container. Additionally, the previously mentioned headers should be configured accordingly. You may find our [nginx configuration file](https://github.com/immich-app/immich/blob/main/nginx/templates/default.conf.template) a helpful reference.

View File

@@ -20,7 +20,7 @@ Immich is a full-stack [TypeScript](https://www.typescriptlang.org/) application
### Web
- [SvelteKit](https://kit.svelte.dev/)
- [tailwindcss](https://tailwindcss.com/)
- [Tailwindcss](https://tailwindcss.com/)
### Server
@@ -34,6 +34,7 @@ Immich is a full-stack [TypeScript](https://www.typescriptlang.org/) application
- [PostgreSQL](https://www.postgresql.org/)
- [Redis](https://redis.io/) for job queuing.
- [Typesense](https://typesense.org/) for search.
### Web Server

View File

@@ -0,0 +1,14 @@
# Database Migrations
After making any changes in the `server/libs/database/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
1. Run the command
```bash
npm run typeorm:migrations:generate ./libs/infra/src/<migration-name>
```
2. Check if the migration file makes sense.
3. Move the migration file to folder `server/libs/database/src/migrations` in your code editor.
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 570 KiB

View File

@@ -1,7 +1,17 @@
---
sidebar_position: 5
---
# Open API
Immich uses the [Open API](https://swagger.io/specification/) standard to generate API documentation. To view the published docs see [here](/docs/api).
## Generator
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the command below to update the client SDK.
```bash
npm run api:generate # Run from the `server/` directory
```
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
:::tip
This can also be run via `make api` from the project root directory (not in the `server` folder)
:::

View File

@@ -1,16 +1,8 @@
---
sidebar_position: 3
---
# Contributing
Contributions are welcome!
## PR Checklist
# PR Checklist
When contributing code through a pull request, please check the following:
### Web Checks
## Web Checks
- [ ] `npm run lint` (linting via ESLint)
- [ ] `npm run format` (formatting via Prettier)
@@ -21,7 +13,7 @@ When contributing code through a pull request, please check the following:
Run all web checks with `npm run check:all`
:::
### Server Checks
## Server Checks
- [ ] `npm run lint` (linting via ESLint)
- [ ] `npm run format` (formatting via Prettier)
@@ -32,12 +24,10 @@ Run all web checks with `npm run check:all`
Run all server checks with `npm run check:all`
:::
### Open API
## Open API
The Open API client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file.
The Open API client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file. See [Open API](/docs/developer/open-api.md) for more details.
- [ ] `npm run api:generate`
## Database Migrations
:::tip
This can also be run via `make api` from the project root directory (not in the `server` folder)
:::
A database migration needs to be generated whenever there are changes to `server/libs/infra/src/entities`. See [Database Migration](/docs/developer/database-migrations.md) for more details.

View File

@@ -43,6 +43,18 @@ The mobile app `(/mobile)` will required Flutter toolchain to be installed on yo
Please refer to the [Flutter's official documentation](https://flutter.dev/docs/get-started/install) for more information on setting up the toolchain on your machine.
### Connect to a remote backend
If you only want to do web development connected to an existing, remote backend, follow these steps:
1. Enter the web directory - `cd web/`
2. Install web dependencies - `npm i`
3. Start the web development server
```
PUBLIC_IMMICH_SERVER_URL=https://demo.immich.app/api npm run dev
```
## IDE setup
### Lint / format extensions
@@ -80,27 +92,3 @@ in User `settings.json` (`cmd + shift + p` and search for `Open User Settings JS
}
}
```
## OpenAPI generator
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the command below to update the client SDK.
```bash
npm run api:generate # Run from the `server` directory
```
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
## Database migrations
After making any changes in the `server/libs/database/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
1. Attached to the server container shell.
2. Run
```bash
npm run typeorm -- migration:generate ./libs/infra/src/db/<migration-name> -d ./libs/infra/src/db/config/database.config.ts
```
3. Check if the migration file makes sense.
4. Move the migration file to folder `server/libs/database/src/migrations` in your code editor.

View File

@@ -14,17 +14,19 @@ Background backup is available thanks to the contribution effort of [@zoodyy](ht
If background backup is enabled. The app will periodically check if there are any new photos or videos in the selected album(s) to be uploaded to the cloud. If there are, it will upload them to the cloud in the background.
:::info Note
#### General
- The app must be in the background for the backup worker to start running.
- If you reopen the app and the first page you see is the backup page, the counts will not reflect the background uploaded result. You have to navigate out of the page and come back to see the updated counts.
#### Android
- It is a well-known problem that some Android models are very strict with battery optimization settings, which can cause a problem with the background worker. Please visit [Don't kill my app](https://dontkillmyapp.com/) for a guide on disabling this setting on your phone.
#### iOS
- You must enable **Background App Refresh** for the app to work in the background. You can enable it in the Settings app under General > Background App Refresh.
<div style={{textAlign: 'center'}}>

View File

@@ -49,7 +49,6 @@ The API key can be obtained in the user setting panel on the web interface.
![Obtain Api Key](./img/obtain-api-key.png)
### Run via Docker
You can run the CLI inside of a docker container to avoid needing to install anything.
@@ -60,27 +59,29 @@ Be aware that as this runs inside a container, you need to mount the folder from
```bash title="Upload current directory"
cd /DIRECTORY/WITH/IMAGES
docker run -it --rm -v $(pwd):/import ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://192.168.1.216:2283/api
docker run -it --rm -v "$(pwd):/import" ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://192.168.1.216:2283/api
```
```bash title="Upload target directory"
docker run -it --rm -v /DIRECTORY/WITH/IMAGES:/import ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://192.168.1.216:2283/api
docker run -it --rm -v "/DIRECTORY/WITH/IMAGES:/import" ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://192.168.1.216:2283/api
```
```bash title="Create an alias"
alias immich="docker run -it --rm -v $(pwd):/import ghcr.io/immich-app/immich-cli:latest"
alias immich='docker run -it --rm -v "$(pwd):/import" ghcr.io/immich-app/immich-cli:latest'
immich upload --key HFEJ38DNSDUEG --server http://192.168.1.216:2283/api
```
:::tip Internal networking
If you are running the CLI container on the same machine as your Immich server, you may not be able to reach the external address. In that case, try the following steps:
1. Find the internal Docker network used by Immich via `docker network ls`.
2. Adapt the above command to pass the `--network <immich_network>` argument to `docker run`, substituting `<immich_network>` with the result from step 1.
3. Use `--server http://immich-server:3001/` for the upload command instead of the external address.
```bash title="Upload to internal address"
docker run --network immich_default -it --rm -v $(pwd):/import ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://immich-server:3001/
docker run --network immich_default -it --rm -v "$(pwd):/import" ghcr.io/immich-app/immich-cli:latest upload --key HFEJ38DNSDUEG --server http://immich-server:3001/
```
:::
### Run from source

View File

@@ -0,0 +1,15 @@
# Facial Recognition
Immich recognizes faces in your photos and videos and groups them together. You can then assign names to the faces and search for them.
The list of people is shown in the Explore page.
<img src={require('./img/facial-recognition-1.png').default} title='Facial Recognition 1' />
Upon clicking on a person, a list of assets that contain their face will be shown.
<img src={require('./img/facial-recognition-2.png').default} title='Facial Recognition 2' />
The asset detail view will also show the faces that are recognized in the asset.
<img src={require('./img/facial-recognition-3.png').default} title='Facial Recognition 3' />

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -0,0 +1,17 @@
# Partner Sharing
Immich allows you to share your library with other users. They can then view your library and download the assets.
You can manage one or multiple users to have access to your library from the [User Settings](docs/features/user-settings.md) page.
<img src={require('./img/partner-sharing-1.png').default} title='Partner Sharing 1' />
<img src={require('./img/partner-sharing-2.png').default} title='Partner Sharing 2' />
Accessing the shared library can be done from the Sharing page.
<img src={require('./img/partner-sharing-3.png').default} title='Partner Sharing 3' />
:::tip Sharing specific assets
For sharing a specific set of assets, you can use the shared album feature of Immich.
:::

View File

@@ -4,7 +4,7 @@ Immich supports [Reverse Geocoding](https://en.wikipedia.org/wiki/Reverse_geocod
## Extraction
During Exif Extraction, assets with latitudes and longitudes are reverse geocoded to determine their City, State, and Country.
During Exif Extraction, assets with latitudes and longitudes are reverse geocoded to determine their City, State, and Country.
## Usage

View File

@@ -1,16 +1,20 @@
# Search
:::warning Work In Progress
Search is work-in-progress and subject to change. Stay tuned!
:::
Immich uses Typesense as the primary search database to enable high performance search mechanism.
## Search by Place
Typesense is a powerful search engine that can be integrated with popular natural language processing (NLP) models like CLIP and SBERT to provide highly accurate and relevant search results. Here are some benefits of using Typesense integrated search for CLIP and SBERT:
:::info
Searching is currently only implemented in the [Mobile App](/docs/features/mobile-app.mdx)
:::
Improved Search Accuracy: Typesense uses a combination of indexing, querying, and ranking algorithms to quickly and accurately retrieve relevant search results. When integrated with CLIP and SBERT, Typesense can leverage the semantic understanding and deep learning capabilities of these models to further improve the accuracy of search results.
Searching by the name of a city, state, or country is possible for assets with geolocation data and successful [Reverse Geocoding](/docs/features/reverse-geocoding.md).
Faster Search Response Times: Typesense is optimized for lightning-fast search response times, making it ideal for applications that require near-instantaneous search results. By integrating with CLIP and SBERT, Typesense can reduce the time required to process complex search queries, making it even faster and more efficient.
<img src={require('./img/reverse-geocoding-mobile1.png').default} width='33%' title='Reverse Geocoding' />
<img src={require('./img/reverse-geocoding-mobile2.png').default} width='33%' title='Reverse Geocoding' />
Enhanced Semantic Search Capabilities: CLIP and SBERT are powerful NLP models that can extract the semantic meaning from text, enabling more nuanced search queries. By integrating with Typesense, these models can help to improve the accuracy of semantic search, enabling users to find the most relevant results based on the true meaning of their query.
Greater Search Flexibility: Typesense provides flexible search capabilities, including fuzzy search, partial search, enabling users to find the information they need quickly and easily. When integrated with CLIP and SBERT, Typesense can offer even greater flexibility, allowing users to refine their search queries using natural language and providing more accurate and relevant results.
(Generated by Chat-GPT4)
Some search examples:
<img src={require('./img/search-ex-2.webp').default} title='Search Example 1' />
<img src={require('./img/search-ex-3.webp').default} title='Search Example 2' />

View File

@@ -10,7 +10,7 @@ View your User ID and email, and update your first and last name.
## Change Password
Users can change their own passwords.
Users can change their own passwords.
![Change Password](./img/user-change-password.png)

View File

@@ -8,9 +8,14 @@ Docker Compose is the recommended method to run Immich in production. Below are
### Step 1 - Download the required files
Download [`docker-compose.yml`][compose-file] [`example.env`][env-file].
Create a directory of your choice (e.g. `./immich-app`) to hold the `docker-compose.yml` and `.env` files.
From a directory of your choice (e.g. `./immich-app`) run the following commands:
```bash title="Move to the directory you created"
mkdir ./immich-app
cd ./immich-app
```
Download [`docker-compose.yml`][compose-file] and [`example.env`][env-file], either by running the following commands:
```bash title="Get docker-compose.yml file"
wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
@@ -20,6 +25,10 @@ wget https://github.com/immich-app/immich/releases/latest/download/docker-compos
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
```
or by downloading from your browser and moving the files to the directory that you created.
Note: If you downloaded the files from your browser, also ensure that you rename `example.env` to `.env`.
### Step 2 - Populate the .env file with custom values
<details>
@@ -57,23 +66,32 @@ REDIS_HOSTNAME=immich_redis
# REDIS_SOCKET=
###################################################################################
# Upload File Config
# Upload File Location
#
# This is the location where uploaded files are stored.
###################################################################################
UPLOAD_LOCATION=absolute_location_on_your_machine_where_you_want_to_store_the_backup
###################################################################################
# Log message level - [simple|verbose]
###################################################################################
LOG_LEVEL=simple
###################################################################################
# Typesense
###################################################################################
# TYPESENSE_ENABLED=false
TYPESENSE_API_KEY=some-random-text
# TYPESENSE_HOST: typesense
# TYPESENSE_PORT: 8108
# TYPESENSE_PROTOCOL: http
###################################################################################
# Reverse Geocoding
####################################################################################
# DISABLE_REVERSE_GEOCODING=false
#
# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
@@ -81,28 +99,58 @@ LOG_LEVEL=simple
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM
####################################################################################
# DISABLE_REVERSE_GEOCODING=false
# REVERSE_GEOCODING_PRECISION=3
####################################################################################
# WEB - Optional
#
# Custom message on the login page, should be written in HTML form.
# For example:
# PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
####################################################################################
# Custom message on the login page, should be written in HTML form.
# For example PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
PUBLIC_LOGIN_PAGE_MESSAGE="My Family Photos and Videos Backup Server"
####################################################################################
# Alternative Service Addresses - Optional
#
# This is an advanced feature for users who may be running their immich services on different hosts.
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
# Note: immich-microservices is bound to 3002, but no references are made
####################################################################################
IMMICH_WEB_URL=http://immich-web:3000
IMMICH_SERVER_URL=http://immich-server:3001
IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003
####################################################################################
# Alternative API's External Address - Optional
#
# This is an advanced feature used to control the public server endpoint returned to clients during Well-known discovery.
# You should only use this if you want mobile apps to access the immich API over a custom URL. Do not include trailing slash.
# NOTE: At this time, the web app will not be affected by this setting and will continue to use the relative path: /api
# Examples: http://localhost:3001, http://immich-api.example.com, etc
####################################################################################
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
```
</details>
- Populate custom database information if necessary.
- Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
- Consider changing `DB_PASSWORD` to something randomly generated
- Consider changing `TYPESENSE_API_KEY` to something randomly generated
### Step 3 - Start the containers
From the directory you created in Step 1, (which should now contain your customized `docker-compose.yml` and `.env` files) run `docker-compose up -d`.
```bash title="Start the containers using docker compose command"
docker-compose up -d # or `docker compose up -d` based on your docker-compose version
docker-compose up -d # or `docker compose up -d` based on your docker-compose version
```
:::tip
@@ -114,7 +162,7 @@ For more information on how to use the application, please refer to the [Post In
When a new version of Immich is [released](https://github.com/immich-app/immich/releases), the application can be upgraded with the following commands, run in the directory with the `docker-compose.yml` file:
```bash title="Upgrade Immich"
docker-compose pull && docker-compose up -d # Or `docker compose`
docker-compose pull && docker-compose up -d # Or `docker compose up -d`
```
:::caution Automatic Updates

View File

@@ -4,12 +4,12 @@ sidebar_position: 40
# Kubernetes
You can deploy Immich on Kubernetes using [the official Helm chart](https://github.com/immich-app/immich-charts/tree/main/charts/apps/immich).
You can deploy Immich on Kubernetes using [the official Helm chart](https://github.com/immich-app/immich-charts/tree/main/charts/immich).
If you want examples of how other people run Immich on Kubernetes, using the official chart or otherwise, you can find them at https://nanne.dev/k8s-at-home-search/#/immich.
:::caution DNS in Alpine containers
Immich makes use of Alpine container images. These can encounter [a DNS resolution bug](https://stackoverflow.com/a/65593511) on Kubernetes clusters if the host
Immich makes use of Alpine container images. These can encounter [a DNS resolution bug](https://stackoverflow.com/a/65593511) on Kubernetes clusters if the host
nodes have a search domain set, like:
```
@@ -18,7 +18,7 @@ search home.lan
nameserver 192.168.1.1
```
When you encounter this bug, it will cause the immich-microservices to crash on startup because it cannot download
the geocoder data. This can be solved in one of two ways: Either reconfigure your nodes to remove the searchdomain from
When you encounter this bug, it will cause the immich-microservices to crash on startup because it cannot download
the geocoder data. This can be solved in one of two ways: Either reconfigure your nodes to remove the searchdomain from
`resolv.conf`, or set the `DISABLE_REVERSE_GEOCODING` environment variable for Immich to `true` to disable the geocoder.
:::
:::

View File

@@ -13,37 +13,36 @@ Install Immich using Portainer's Stack feature.
5. Replace `.env` with `stack.env` for all containers that need to use environment variables in the web editor.
<img
src={require('./img/dot-env.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
src={require('./img/dot-env.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
8. Click on "**Advanced Mode**" in the **Environment Variables** section.
<img
src={require('./img/env-1.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
src={require('./img/env-1.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
9. Copy the content of the `example.env` file from the [GitHub repository](https://github.com/immich-app/immich/releases/latest/download/example.env) and paste into the editor.
10. Switch back to "**Simple Mode**".
<img
src={require('./img/env-2.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
src={require('./img/env-2.png').default}
width="50%"
style={{border: '1px solid #ddd'}}
alt="Dot Env Example"
/>
* Populate custom database information if necessary.
* Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
- Populate custom database information if necessary.
- Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
11. Click on "**Deploy the stack**".
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/install/post-install.mdx) guide.
:::

View File

@@ -2,8 +2,8 @@
sidebar_position: 10
---
# Requirements
Hardware and software requirements for Immich
## Software
@@ -18,5 +18,5 @@ You can also use Podman to run the application. However, additional configuratio
## Hardware
- **OS**: Preferred unix-based operating system (Ubuntu, Debian, MacOS, etc). Windows works too, with [Docker Desktop on Windows](https://docs.docker.com/desktop/install/windows-install/)
- **RAM**: At least 2GB, preferred 4GB.
- **RAM**: At least 4GB, preferred 6GB.
- **CPU**: At least 2 cores, preferred 4 cores.

View File

@@ -5,6 +5,7 @@ sidebar_position: 60
# Unraid
Immich can easily be installed and updated on Unraid via:
1. [Docker Compose Manager](https://forums.unraid.net/topic/114415-plugin-docker-compose-manager/) plugin from the Unraid Community Apps
2. Community made template on the Unraid Community Apps
@@ -20,7 +21,7 @@ In order to install Immich from the Unraid CA, you will need an existing Redis a
Once you have Redis and PostgreSQL running, search for Immich on the Unraid CA, choose either of the templates listed and fill out the example variables.
For more information about setting up the community image see [here](https://github.com/imagegenius/docker-immich#application-setup)
For more information about setting up the community image see [here](https://github.com/imagegenius/docker-immich#application-setup)
## Docker-Compose Method (Official)

View File

@@ -4,7 +4,7 @@ sidebar_position: 1
# Introduction
<img src={require('./img/feature-panel.png').default} alt='Immich' />
<img src={require('./img/feature-panel.png').default} alt="Immich" />
## Welcome!

View File

@@ -18,7 +18,6 @@ If you feel like this is the right cause and the app is something you see yourse
- [buymeacoffee](https://www.buymeacoffee.com/altran1502)
- Bitcoin: 1FvEp6P6NM8EZEkpGUFAN2LqJ1gxusNxZX
## Contributing
There are lots of non-monetary ways to contribute to Immich as well.

View File

@@ -1,70 +1,70 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const lightCodeTheme = require("prism-react-renderer/themes/github");
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Immich",
tagline:
"High performance self-hosted photo and video backup solution directly from your mobile phone",
url: "https://documentation.immich.app",
baseUrl: "/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
favicon: "img/favicon.png",
title: 'Immich',
tagline: 'High performance self-hosted photo and video backup solution directly from your mobile phone',
url: 'https://documentation.immich.app',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.png',
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: "immich-app", // Usually your GitHub org/user name.
projectName: "immich", // Usually your repo name.
deploymentBranch: "main",
organizationName: 'immich-app', // Usually your GitHub org/user name.
projectName: 'immich', // Usually your repo name.
deploymentBranch: 'main',
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
i18n: {
defaultLocale: "en",
locales: ["en"],
defaultLocale: 'en',
locales: ['en'],
},
plugins: [
async function myPlugin(context, options) {
return {
name: "docusaurus-tailwindcss",
name: 'docusaurus-tailwindcss',
configurePostCss(postcssOptions) {
// Appends TailwindCSS and AutoPrefixer.
postcssOptions.plugins.push(require("tailwindcss"));
postcssOptions.plugins.push(require("autoprefixer"));
postcssOptions.plugins.push(require('tailwindcss'));
postcssOptions.plugins.push(require('autoprefixer'));
return postcssOptions;
},
};
},
require.resolve('docusaurus-lunr-search'),
],
presets: [
[
"docusaurus-preset-openapi",
'docusaurus-preset-openapi',
/** @type {import('docusaurus-preset-openapi').Options} */
({
docs: {
showLastUpdateAuthor: true,
showLastUpdateTime: true,
sidebarPath: require.resolve("./sidebars.js"),
sidebarPath: require.resolve('./sidebars.js'),
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl: "https://github.com/immich-app/immich/tree/main/docs/",
editUrl: 'https://github.com/immich-app/immich/tree/main/docs/',
},
api: {
path: "../server/immich-openapi-specs.json",
routeBasePath: "/docs/api",
path: '../server/immich-openapi-specs.json',
routeBasePath: '/docs/api',
},
// blog: {
// showReadingTime: true,
// editUrl: "https://github.com/immich-app/immich/tree/main/docs/",
// },
theme: {
customCss: require.resolve("./src/css/custom.css"),
customCss: require.resolve('./src/css/custom.css'),
},
}),
],
@@ -74,13 +74,13 @@ const config = {
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
colorMode: {
defaultMode: "dark",
defaultMode: 'dark',
},
announcementBar: {
id: "site_announcement_immich",
id: 'site_announcement_immich',
content: `⚠️ The project is under <strong>very active</strong> development. Expect bugs and changes. Do not use it as <strong>the only way</strong> to store your photos and videos!`,
backgroundColor: "#593f00",
textColor: "#ffefc9",
backgroundColor: '#593f00',
textColor: '#ffefc9',
isCloseable: false,
},
docs: {
@@ -90,72 +90,63 @@ const config = {
},
navbar: {
logo: {
alt: "Immich University Logo",
src: "img/color-logo.png",
srcDark: "img/logo.png",
alt: 'Immich University Logo',
src: 'img/color-logo.png',
srcDark: 'img/logo.png',
},
items: [
{
to: "/docs/overview/introduction",
position: "right",
label: "Docs",
to: '/docs/overview/introduction',
position: 'right',
label: 'Docs',
},
{
to: "/docs/api",
position: "right",
label: "API",
to: '/docs/api',
position: 'right',
label: 'API',
},
{
href: "https://github.com/immich-app/immich",
label: "GitHub",
position: "right",
},
{
href: "https://github.com/orgs/immich-app/projects/1",
label: "Roadmap",
position: "right",
href: 'https://github.com/immich-app/immich',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: "light",
style: 'light',
links: [
{
title: "Overview",
title: 'Overview',
items: [
{
label: "Welcome",
to: "/docs/overview/introduction",
label: 'Welcome',
to: '/docs/overview/introduction',
},
{
label: "Installation",
to: "/docs/install/requirements",
label: 'Installation',
to: '/docs/install/requirements',
},
],
},
{
title: "Community",
title: 'Community',
items: [
{
label: "Discord",
href: "https://discord.com/invite/D8JsnBEuKb",
label: 'Discord',
href: 'https://discord.com/invite/D8JsnBEuKb',
},
],
},
{
title: "Links",
title: 'Links',
items: [
// {
// label: "Blog",
// to: "/blog",
// },
{
label: "GitHub",
href: "https://github.com/immich-app/immich",
},
{
label: "Roadmap",
href: "https://github.com/orgs/immich-app/projects/1",
label: 'GitHub',
href: 'https://github.com/immich-app/immich',
},
],
},
@@ -166,7 +157,7 @@ const config = {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
image: "overview/img/feature-panel.png",
image: 'overview/img/feature-panel.png',
}),
};

613
docs/package-lock.json generated
View File

@@ -13,6 +13,7 @@
"@mdx-js/react": "^1.6.22",
"autoprefixer": "^10.4.13",
"clsx": "^1.2.1",
"docusaurus-lunr-search": "^2.3.2",
"docusaurus-preset-openapi": "^0.6.3",
"postcss": "^8.4.20",
"prism-react-renderer": "^1.3.5",
@@ -24,6 +25,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "2.1.0",
"@tsconfig/docusaurus": "^1.0.5",
"prettier": "^2.8.8",
"typescript": "^4.7.4"
},
"engines": {
@@ -3634,6 +3636,11 @@
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
},
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -3903,6 +3910,11 @@
"node": ">= 8"
}
},
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
},
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@@ -3957,6 +3969,14 @@
"node": ">= 4.0.0"
}
},
"node_modules/autocomplete.js": {
"version": "0.37.1",
"resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.37.1.tgz",
"integrity": "sha512-PgSe9fHYhZEsm/9jggbjtVsGXJkPLvd+9mC7gZJ662vVL5CRWEtm/mIrrzCx0MrNxHVwxD5d00UOn6NsmL2LUQ==",
"dependencies": {
"immediate": "^3.2.3"
}
},
"node_modules/autoprefixer": {
"version": "10.4.13",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz",
@@ -4148,6 +4168,15 @@
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw=="
},
"node_modules/bcp-47-match": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz",
"integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -4583,6 +4612,11 @@
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz",
"integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw=="
},
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
@@ -4743,6 +4777,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"bin": {
"color-support": "bin.js"
}
},
"node_modules/colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
@@ -4887,6 +4929,11 @@
"resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
"integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw=="
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
"node_modules/content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
@@ -5278,6 +5325,11 @@
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-selector-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
"integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g=="
},
"node_modules/css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
@@ -5664,6 +5716,18 @@
"node": ">=8"
}
},
"node_modules/direction": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz",
"integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==",
"bin": {
"direction": "cli.js"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -5685,6 +5749,53 @@
"node": ">=6"
}
},
"node_modules/docusaurus-lunr-search": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-2.3.2.tgz",
"integrity": "sha512-Ngvm2kXwliWThqAThXI1912rOKHlFL7BjIc+OVNUfzkjpk5ar4TFEh+EUaaMOLw4V0BBko3CW0Ym7prqqm3jLQ==",
"dependencies": {
"autocomplete.js": "^0.37.0",
"classnames": "^2.2.6",
"gauge": "^3.0.0",
"hast-util-select": "^4.0.0",
"hast-util-to-text": "^2.0.0",
"hogan.js": "^3.0.2",
"lunr": "^2.3.8",
"lunr-languages": "^1.4.0",
"minimatch": "^3.0.4",
"object-assign": "^4.1.1",
"rehype-parse": "^7.0.1",
"to-vfile": "^6.1.0",
"unified": "^9.0.0",
"unist-util-is": "^4.0.2"
},
"engines": {
"node": ">= 8.10.0"
},
"peerDependencies": {
"@docusaurus/core": "^2.0.0-alpha.60 || ^2.0.0",
"react": "^16.8.4 || ^17",
"react-dom": "^16.8.4 || ^17"
}
},
"node_modules/docusaurus-lunr-search/node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"node_modules/docusaurus-lunr-search/node_modules/rehype-parse": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz",
"integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==",
"dependencies": {
"hast-util-from-parse5": "^6.0.0",
"parse5": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/docusaurus-plugin-openapi": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi/-/docusaurus-plugin-openapi-0.6.3.tgz",
@@ -6689,6 +6800,43 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/gauge/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/gauge/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -6994,6 +7142,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"node_modules/has-yarn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
@@ -7037,6 +7190,24 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-has-property": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz",
"integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-is-element": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz",
"integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
@@ -7072,6 +7243,31 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"node_modules/hast-util-select": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-4.0.2.tgz",
"integrity": "sha512-8EEG2//bN5rrzboPWD2HdS3ugLijNioS1pqOTIolXNf67xxShYw4SQEmVXd3imiBG+U2bC2nVTySr/iRAA7Cjg==",
"dependencies": {
"bcp-47-match": "^1.0.0",
"comma-separated-tokens": "^1.0.0",
"css-selector-parser": "^1.0.0",
"direction": "^1.0.0",
"hast-util-has-property": "^1.0.0",
"hast-util-is-element": "^1.0.0",
"hast-util-to-string": "^1.0.0",
"hast-util-whitespace": "^1.0.0",
"not": "^0.1.0",
"nth-check": "^2.0.0",
"property-information": "^5.0.0",
"space-separated-tokens": "^1.0.0",
"unist-util-visit": "^2.0.0",
"zwitch": "^1.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-to-parse5": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz",
@@ -7088,6 +7284,38 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-to-string": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz",
"integrity": "sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-to-text": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz",
"integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==",
"dependencies": {
"hast-util-is-element": "^1.0.0",
"repeat-string": "^1.0.0",
"unist-util-find-after": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-whitespace": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz",
"integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hastscript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
@@ -7133,6 +7361,18 @@
"value-equal": "^1.0.1"
}
},
"node_modules/hogan.js": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz",
"integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==",
"dependencies": {
"mkdirp": "0.3.0",
"nopt": "1.0.10"
},
"bin": {
"hulk": "bin/hulk"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -7435,6 +7675,11 @@
"node": ">=14.0.0"
}
},
"node_modules/immediate": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
},
"node_modules/immer": {
"version": "9.0.16",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz",
@@ -8232,6 +8477,16 @@
"node": ">=10"
}
},
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"node_modules/lunr-languages": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.10.0.tgz",
"integrity": "sha512-BBjKKcwrieJlzwwc9M5H/MRXGJ2qyOSDx/NXYiwkuKjiLOOoouh0WsDzeqcLoUWcX31y7i8sb8IgsZKObdUCkw=="
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -8538,6 +8793,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mkdirp": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
"integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==",
"deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
"engines": {
"node": "*"
}
},
"node_modules/monaco-editor": {
"version": "0.31.1",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.31.1.tgz",
@@ -8657,6 +8921,20 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
},
"node_modules/nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": "*"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -8684,6 +8962,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/not": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz",
"integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA=="
},
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -10256,6 +10539,21 @@
"node": ">=4"
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-error": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
@@ -12774,6 +13072,19 @@
"node": ">=8.0"
}
},
"node_modules/to-vfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz",
"integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==",
"dependencies": {
"is-buffer": "^2.0.0",
"vfile": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -12989,6 +13300,18 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-find-after": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz",
"integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==",
"dependencies": {
"unist-util-is": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-generated": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz",
@@ -13943,6 +14266,32 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q=="
},
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/wide-align/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/wide-align/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/widest-line": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
@@ -16831,6 +17180,11 @@
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
},
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -17031,6 +17385,11 @@
"picomatch": "^2.0.4"
}
},
"aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
},
"arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@@ -17076,6 +17435,14 @@
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
},
"autocomplete.js": {
"version": "0.37.1",
"resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.37.1.tgz",
"integrity": "sha512-PgSe9fHYhZEsm/9jggbjtVsGXJkPLvd+9mC7gZJ662vVL5CRWEtm/mIrrzCx0MrNxHVwxD5d00UOn6NsmL2LUQ==",
"requires": {
"immediate": "^3.2.3"
}
},
"autoprefixer": {
"version": "10.4.13",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz",
@@ -17206,6 +17573,11 @@
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
"integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw=="
},
"bcp-47-match": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz",
"integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w=="
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -17502,6 +17874,11 @@
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz",
"integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw=="
},
"classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clean-css": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
@@ -17624,6 +18001,11 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
},
"colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
@@ -17744,6 +18126,11 @@
"resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
"integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw=="
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
@@ -18000,6 +18387,11 @@
"nth-check": "^2.0.1"
}
},
"css-selector-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
"integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g=="
},
"css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
@@ -18268,6 +18660,11 @@
"path-type": "^4.0.0"
}
},
"direction": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz",
"integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ=="
},
"dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -18286,6 +18683,43 @@
"@leichtgewicht/ip-codec": "^2.0.1"
}
},
"docusaurus-lunr-search": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-2.3.2.tgz",
"integrity": "sha512-Ngvm2kXwliWThqAThXI1912rOKHlFL7BjIc+OVNUfzkjpk5ar4TFEh+EUaaMOLw4V0BBko3CW0Ym7prqqm3jLQ==",
"requires": {
"autocomplete.js": "^0.37.0",
"classnames": "^2.2.6",
"gauge": "^3.0.0",
"hast-util-select": "^4.0.0",
"hast-util-to-text": "^2.0.0",
"hogan.js": "^3.0.2",
"lunr": "^2.3.8",
"lunr-languages": "^1.4.0",
"minimatch": "^3.0.4",
"object-assign": "^4.1.1",
"rehype-parse": "^7.0.1",
"to-vfile": "^6.1.0",
"unified": "^9.0.0",
"unist-util-is": "^4.0.2"
},
"dependencies": {
"parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"rehype-parse": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz",
"integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==",
"requires": {
"hast-util-from-parse5": "^6.0.0",
"parse5": "^6.0.0"
}
}
}
},
"docusaurus-plugin-openapi": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/docusaurus-plugin-openapi/-/docusaurus-plugin-openapi-0.6.3.tgz",
@@ -19036,6 +19470,39 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"requires": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
"dependencies": {
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
}
}
},
"gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -19266,6 +19733,11 @@
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"has-yarn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
@@ -19298,6 +19770,16 @@
"web-namespaces": "^1.0.0"
}
},
"hast-util-has-property": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz",
"integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg=="
},
"hast-util-is-element": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz",
"integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ=="
},
"hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
@@ -19327,6 +19809,27 @@
}
}
},
"hast-util-select": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-4.0.2.tgz",
"integrity": "sha512-8EEG2//bN5rrzboPWD2HdS3ugLijNioS1pqOTIolXNf67xxShYw4SQEmVXd3imiBG+U2bC2nVTySr/iRAA7Cjg==",
"requires": {
"bcp-47-match": "^1.0.0",
"comma-separated-tokens": "^1.0.0",
"css-selector-parser": "^1.0.0",
"direction": "^1.0.0",
"hast-util-has-property": "^1.0.0",
"hast-util-is-element": "^1.0.0",
"hast-util-to-string": "^1.0.0",
"hast-util-whitespace": "^1.0.0",
"not": "^0.1.0",
"nth-check": "^2.0.0",
"property-information": "^5.0.0",
"space-separated-tokens": "^1.0.0",
"unist-util-visit": "^2.0.0",
"zwitch": "^1.0.0"
}
},
"hast-util-to-parse5": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz",
@@ -19339,6 +19842,26 @@
"zwitch": "^1.0.0"
}
},
"hast-util-to-string": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz",
"integrity": "sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w=="
},
"hast-util-to-text": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz",
"integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==",
"requires": {
"hast-util-is-element": "^1.0.0",
"repeat-string": "^1.0.0",
"unist-util-find-after": "^3.0.0"
}
},
"hast-util-whitespace": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz",
"integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A=="
},
"hastscript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
@@ -19374,6 +19897,15 @@
"value-equal": "^1.0.1"
}
},
"hogan.js": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz",
"integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==",
"requires": {
"mkdirp": "0.3.0",
"nopt": "1.0.10"
}
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -19589,6 +20121,11 @@
"queue": "6.0.2"
}
},
"immediate": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
},
"immer": {
"version": "9.0.16",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz",
@@ -20162,6 +20699,16 @@
"yallist": "^4.0.0"
}
},
"lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"lunr-languages": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.10.0.tgz",
"integrity": "sha512-BBjKKcwrieJlzwwc9M5H/MRXGJ2qyOSDx/NXYiwkuKjiLOOoouh0WsDzeqcLoUWcX31y7i8sb8IgsZKObdUCkw=="
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -20374,6 +20921,11 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
},
"mkdirp": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
"integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew=="
},
"monaco-editor": {
"version": "0.31.1",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.31.1.tgz",
@@ -20461,6 +21013,14 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
},
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"requires": {
"abbrev": "1"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -20476,6 +21036,11 @@
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
},
"not": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz",
"integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA=="
},
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -21537,6 +22102,12 @@
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
"integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA=="
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true
},
"pretty-error": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
@@ -23447,6 +24018,15 @@
"is-number": "^7.0.0"
}
},
"to-vfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz",
"integrity": "sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw==",
"requires": {
"is-buffer": "^2.0.0",
"vfile": "^4.0.0"
}
},
"toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -23588,6 +24168,14 @@
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",
"integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw=="
},
"unist-util-find-after": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz",
"integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==",
"requires": {
"unist-util-is": "^4.0.0"
}
},
"unist-util-generated": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz",
@@ -24241,6 +24829,31 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q=="
},
"wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"requires": {
"string-width": "^1.0.2 || 2 || 3 || 4"
},
"dependencies": {
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
}
}
},
"widest-line": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",

View File

@@ -4,6 +4,8 @@
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"format": "prettier --check .",
"format:fix": "prettier --write .",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
@@ -12,7 +14,7 @@
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
"check": "tsc"
},
"dependencies": {
"@docusaurus/core": "2.1.0",
@@ -20,6 +22,7 @@
"@mdx-js/react": "^1.6.22",
"autoprefixer": "^10.4.13",
"clsx": "^1.2.1",
"docusaurus-lunr-search": "^2.3.2",
"docusaurus-preset-openapi": "^0.6.3",
"postcss": "^8.4.20",
"prism-react-renderer": "^1.3.5",
@@ -31,6 +34,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "2.1.0",
"@tsconfig/docusaurus": "^1.0.5",
"prettier": "^2.8.8",
"typescript": "^4.7.4"
},
"browserslist": {

View File

@@ -14,7 +14,7 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }],
// But you can create a sidebar manually
/*

View File

@@ -14,8 +14,8 @@ const FeatureList: FeatureItem[] = [
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
Docusaurus was designed from the ground up to be easily installed and used to get your website up and running
quickly.
</>
),
},
@@ -24,8 +24,8 @@ const FeatureList: FeatureItem[] = [
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go ahead and move your docs into the{' '}
<code>docs</code> directory.
</>
),
},
@@ -34,14 +34,14 @@ const FeatureList: FeatureItem[] = [
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
Extend or customize your website layout by reusing React. Docusaurus can be extended while reusing the same
header and footer.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
function Feature({ title, Svg, description }: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">

View File

@@ -7,12 +7,12 @@
@tailwind components;
@tailwind utilities;
@import url("https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Snowburst+One&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Snowburst+One&display=swap');
html,
button {
font-family: "Overpass", sans-serif;
font-family: 'Overpass', sans-serif;
}
/* You can override the default Infima variables here. */
@@ -29,7 +29,7 @@ button {
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme="dark"] {
[data-theme='dark'] {
--ifm-color-primary: #adcbfa;
--ifm-color-primary-dark: #85b2f8;
--ifm-color-primary-darker: #71a5f6;

View File

@@ -1,6 +1,6 @@
import React from "react";
import Link from "@docusaurus/Link";
import Layout from "@theme/Layout";
import React from 'react';
import Link from '@docusaurus/Link';
import Layout from '@theme/Layout';
function HomepageHeader() {
return (
@@ -31,7 +31,7 @@ function HomepageHeader() {
</Link>
</div>
<img src="/img/immich-screenshots.webp" alt="logo" />
<img src="/img/immich-screenshots.png" alt="logo" />
</section>
</header>
);

View File

@@ -0,0 +1,256 @@
import Hogan from 'hogan.js';
import LunrSearchAdapter from './lunar-search';
import autocomplete from 'autocomplete.js';
import templates from './templates';
import utils from './utils';
import $ from 'autocomplete.js/zepto';
class DocSearch {
constructor({
searchDocs,
searchIndex,
inputSelector,
debug = false,
baseUrl = '/',
queryDataCallback = null,
autocompleteOptions = {
debug: false,
hint: false,
autoselect: true,
},
transformData = false,
queryHook = false,
handleSelected = false,
enhancedSearchInput = false,
layout = 'collumns',
}) {
this.input = DocSearch.getInputFromSelector(inputSelector);
this.queryDataCallback = queryDataCallback || null;
const autocompleteOptionsDebug =
autocompleteOptions && autocompleteOptions.debug ? autocompleteOptions.debug : false;
// eslint-disable-next-line no-param-reassign
autocompleteOptions.debug = debug || autocompleteOptionsDebug;
this.autocompleteOptions = autocompleteOptions;
this.autocompleteOptions.cssClasses = this.autocompleteOptions.cssClasses || {};
this.autocompleteOptions.cssClasses.prefix = this.autocompleteOptions.cssClasses.prefix || 'ds';
const inputAriaLabel = this.input && typeof this.input.attr === 'function' && this.input.attr('aria-label');
this.autocompleteOptions.ariaLabel = this.autocompleteOptions.ariaLabel || inputAriaLabel || 'search input';
this.isSimpleLayout = layout === 'simple';
this.client = new LunrSearchAdapter(searchDocs, searchIndex, baseUrl);
if (enhancedSearchInput) {
this.input = DocSearch.injectSearchBox(this.input);
}
this.autocomplete = autocomplete(this.input, autocompleteOptions, [
{
source: this.getAutocompleteSource(transformData, queryHook),
templates: {
suggestion: DocSearch.getSuggestionTemplate(this.isSimpleLayout),
footer: templates.footer,
empty: DocSearch.getEmptyTemplate(),
},
},
]);
const customHandleSelected = handleSelected;
this.handleSelected = customHandleSelected || this.handleSelected;
// We prevent default link clicking if a custom handleSelected is defined
if (customHandleSelected) {
$('.algolia-autocomplete').on('click', '.ds-suggestions a', (event) => {
event.preventDefault();
});
}
this.autocomplete.on('autocomplete:selected', this.handleSelected.bind(null, this.autocomplete.autocomplete));
this.autocomplete.on('autocomplete:shown', this.handleShown.bind(null, this.input));
if (enhancedSearchInput) {
DocSearch.bindSearchBoxEvent();
}
}
static injectSearchBox(input) {
input.before(templates.searchBox);
const newInput = input.prev().prev().find('input');
input.remove();
return newInput;
}
static bindSearchBoxEvent() {
$('.searchbox [type="reset"]').on('click', function () {
$('input#docsearch').focus();
$(this).addClass('hide');
autocomplete.autocomplete.setVal('');
});
$('input#docsearch').on('keyup', () => {
const searchbox = document.querySelector('input#docsearch');
const reset = document.querySelector('.searchbox [type="reset"]');
reset.className = 'searchbox__reset';
if (searchbox.value.length === 0) {
reset.className += ' hide';
}
});
}
/**
* Returns the matching input from a CSS selector, null if none matches
* @function getInputFromSelector
* @param {string} selector CSS selector that matches the search
* input of the page
* @returns {void}
*/
static getInputFromSelector(selector) {
const input = $(selector).filter('input');
return input.length ? $(input[0]) : null;
}
/**
* Returns the `source` method to be passed to autocomplete.js. It will query
* the Algolia index and call the callbacks with the formatted hits.
* @function getAutocompleteSource
* @param {function} transformData An optional function to transform the hits
* @param {function} queryHook An optional function to transform the query
* @returns {function} Method to be passed as the `source` option of
* autocomplete
*/
getAutocompleteSource(transformData, queryHook) {
return (query, callback) => {
if (queryHook) {
// eslint-disable-next-line no-param-reassign
query = queryHook(query) || query;
}
this.client.search(query).then((hits) => {
if (this.queryDataCallback && typeof this.queryDataCallback == 'function') {
this.queryDataCallback(hits);
}
if (transformData) {
hits = transformData(hits) || hits;
}
callback(DocSearch.formatHits(hits));
});
};
}
// Given a list of hits returned by the API, will reformat them to be used in
// a Hogan template
static formatHits(receivedHits) {
const clonedHits = utils.deepClone(receivedHits);
const hits = clonedHits.map((hit) => {
if (hit._highlightResult) {
// eslint-disable-next-line no-param-reassign
hit._highlightResult = utils.mergeKeyWithParent(hit._highlightResult, 'hierarchy');
}
return utils.mergeKeyWithParent(hit, 'hierarchy');
});
// Group hits by category / subcategory
let groupedHits = utils.groupBy(hits, 'lvl0');
$.each(groupedHits, (level, collection) => {
const groupedHitsByLvl1 = utils.groupBy(collection, 'lvl1');
const flattenedHits = utils.flattenAndFlagFirst(groupedHitsByLvl1, 'isSubCategoryHeader');
groupedHits[level] = flattenedHits;
});
groupedHits = utils.flattenAndFlagFirst(groupedHits, 'isCategoryHeader');
// Translate hits into smaller objects to be send to the template
return groupedHits.map((hit) => {
const url = DocSearch.formatURL(hit);
const category = utils.getHighlightedValue(hit, 'lvl0');
const subcategory = utils.getHighlightedValue(hit, 'lvl1') || category;
const displayTitle = utils
.compact([
utils.getHighlightedValue(hit, 'lvl2') || subcategory,
utils.getHighlightedValue(hit, 'lvl3'),
utils.getHighlightedValue(hit, 'lvl4'),
utils.getHighlightedValue(hit, 'lvl5'),
utils.getHighlightedValue(hit, 'lvl6'),
])
.join('<span class="aa-suggestion-title-separator" aria-hidden="true"> </span>');
const text = utils.getSnippetedValue(hit, 'content');
const isTextOrSubcategoryNonEmpty = (subcategory && subcategory !== '') || (displayTitle && displayTitle !== '');
const isLvl1EmptyOrDuplicate = !subcategory || subcategory === '' || subcategory === category;
const isLvl2 = displayTitle && displayTitle !== '' && displayTitle !== subcategory;
const isLvl1 = !isLvl2 && subcategory && subcategory !== '' && subcategory !== category;
const isLvl0 = !isLvl1 && !isLvl2;
return {
isLvl0,
isLvl1,
isLvl2,
isLvl1EmptyOrDuplicate,
isCategoryHeader: hit.isCategoryHeader,
isSubCategoryHeader: hit.isSubCategoryHeader,
isTextOrSubcategoryNonEmpty,
category,
subcategory,
title: displayTitle,
text,
url,
};
});
}
static formatURL(hit) {
const { url, anchor } = hit;
if (url) {
const containsAnchor = url.indexOf('#') !== -1;
if (containsAnchor) return url;
else if (anchor) return `${hit.url}#${hit.anchor}`;
return url;
} else if (anchor) return `#${hit.anchor}`;
/* eslint-disable */
console.warn('no anchor nor url for : ', JSON.stringify(hit));
/* eslint-enable */
return null;
}
static getEmptyTemplate() {
return (args) => Hogan.compile(templates.empty).render(args);
}
static getSuggestionTemplate(isSimpleLayout) {
const stringTemplate = isSimpleLayout ? templates.suggestionSimple : templates.suggestion;
const template = Hogan.compile(stringTemplate);
return (suggestion) => template.render(suggestion);
}
handleSelected(input, event, suggestion, datasetNumber, context = {}) {
// Do nothing if click on the suggestion, as it's already a <a href>, the
// browser will take care of it. This allow Ctrl-Clicking on results and not
// having the main window being redirected as well
if (context.selectionMethod === 'click') {
return;
}
input.setVal('');
window.location.assign(suggestion.url);
}
handleShown(input) {
const middleOfInput = input.offset().left + input.width() / 2;
let middleOfWindow = $(document).width() / 2;
if (isNaN(middleOfWindow)) {
middleOfWindow = 900;
}
const alignClass = middleOfInput - middleOfWindow >= 0 ? 'algolia-autocomplete-right' : 'algolia-autocomplete-left';
const otherAlignClass =
middleOfInput - middleOfWindow < 0 ? 'algolia-autocomplete-right' : 'algolia-autocomplete-left';
const autocompleteWrapper = $('.algolia-autocomplete');
if (!autocompleteWrapper.hasClass(alignClass)) {
autocompleteWrapper.addClass(alignClass);
}
if (autocompleteWrapper.hasClass(otherAlignClass)) {
autocompleteWrapper.removeClass(otherAlignClass);
}
}
}
export default DocSearch;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,111 @@
import React, { useRef, useCallback, useState } from 'react';
import classnames from 'classnames';
import { useHistory } from '@docusaurus/router';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import { usePluginData } from '@docusaurus/useGlobalData';
import useIsBrowser from '@docusaurus/useIsBrowser';
const Search = (props) => {
const initialized = useRef(false);
const searchBarRef = useRef(null);
const [indexReady, setIndexReady] = useState(false);
const history = useHistory();
const { siteConfig = {} } = useDocusaurusContext();
const isBrowser = useIsBrowser();
const { baseUrl } = siteConfig;
const initAlgolia = (searchDocs, searchIndex, DocSearch) => {
new DocSearch({
searchDocs,
searchIndex,
baseUrl,
inputSelector: '#search_input_react',
// Override algolia's default selection event, allowing us to do client-side
// navigation and avoiding a full page refresh.
handleSelected: (_input, _event, suggestion) => {
const url = suggestion.url || '/';
// Use an anchor tag to parse the absolute url into a relative url
// Alternatively, we can use new URL(suggestion.url) but its not supported in IE
const a = document.createElement('a');
a.href = url;
// Algolia use closest parent element id #__docusaurus when a h1 page title does not have an id
// So, we can safely remove it. See https://github.com/facebook/docusaurus/issues/1828 for more details.
history.push(url);
},
});
};
const pluginData = usePluginData('docusaurus-lunr-search');
const getSearchDoc = () =>
process.env.NODE_ENV === 'production'
? fetch(`${baseUrl}${pluginData.fileNames.searchDoc}`).then((content) => content.json())
: Promise.resolve([]);
const getLunrIndex = () =>
process.env.NODE_ENV === 'production'
? fetch(`${baseUrl}${pluginData.fileNames.lunrIndex}`).then((content) => content.json())
: Promise.resolve([]);
const loadAlgolia = () => {
if (!initialized.current) {
Promise.all([getSearchDoc(), getLunrIndex(), import('./DocSearch'), import('./algolia.css')]).then(
([searchDocs, searchIndex, { default: DocSearch }]) => {
if (searchDocs.length === 0) {
return;
}
initAlgolia(searchDocs, searchIndex, DocSearch);
setIndexReady(true);
},
);
initialized.current = true;
}
};
const toggleSearchIconClick = useCallback(
(e) => {
if (!searchBarRef.current.contains(e.target)) {
searchBarRef.current.focus();
}
props.handleSearchBarToggle && props.handleSearchBarToggle(!props.isSearchBarExpanded);
},
[props.isSearchBarExpanded],
);
if (isBrowser) {
loadAlgolia();
}
return (
<div className="navbar__search" key="search-box">
<span
aria-label="expand searchbar"
role="button"
className={classnames('search-icon', {
'search-icon-hidden': props.isSearchBarExpanded,
})}
onClick={toggleSearchIconClick}
onKeyDown={toggleSearchIconClick}
tabIndex={0}
/>
<input
id="search_input_react"
type="search"
placeholder={indexReady ? 'Search' : 'Loading...'}
aria-label="Search"
className={classnames(
'navbar__search-input',
{ 'search-bar-expanded': props.isSearchBarExpanded },
{ 'search-bar': !props.isSearchBarExpanded },
)}
onClick={loadAlgolia}
onMouseOver={loadAlgolia}
onFocus={toggleSearchIconClick}
onBlur={toggleSearchIconClick}
ref={searchBarRef}
disabled={!indexReady}
/>
</div>
);
};
export default Search;

View File

@@ -0,0 +1,161 @@
import lunr from '@generated/lunr.client';
lunr.tokenizer.separator = /[\s\-/]+/;
class LunrSearchAdapter {
constructor(searchDocs, searchIndex, baseUrl = '/') {
this.searchDocs = searchDocs;
this.lunrIndex = lunr.Index.load(searchIndex);
this.baseUrl = baseUrl;
}
getLunrResult(input) {
return this.lunrIndex.query(function (query) {
const tokens = lunr.tokenizer(input);
query.term(tokens, {
boost: 10,
});
query.term(tokens, {
wildcard: lunr.Query.wildcard.TRAILING,
});
});
}
getHit(doc, formattedTitle, formattedContent) {
return {
hierarchy: {
lvl0: doc.pageTitle || doc.title,
lvl1: doc.type === 0 ? null : doc.title,
},
url: doc.url,
_snippetResult: formattedContent
? {
content: {
value: formattedContent,
matchLevel: 'full',
},
}
: null,
_highlightResult: {
hierarchy: {
lvl0: {
value: doc.type === 0 ? formattedTitle || doc.title : doc.pageTitle,
},
lvl1:
doc.type === 0
? null
: {
value: formattedTitle || doc.title,
},
},
},
};
}
getTitleHit(doc, position, length) {
const start = position[0];
const end = position[0] + length;
let formattedTitle =
doc.title.substring(0, start) +
'<span class="algolia-docsearch-suggestion--highlight">' +
doc.title.substring(start, end) +
'</span>' +
doc.title.substring(end, doc.title.length);
return this.getHit(doc, formattedTitle);
}
getKeywordHit(doc, position, length) {
const start = position[0];
const end = position[0] + length;
let formattedTitle =
doc.title +
'<br /><i>Keywords: ' +
doc.keywords.substring(0, start) +
'<span class="algolia-docsearch-suggestion--highlight">' +
doc.keywords.substring(start, end) +
'</span>' +
doc.keywords.substring(end, doc.keywords.length) +
'</i>';
return this.getHit(doc, formattedTitle);
}
getContentHit(doc, position) {
const start = position[0];
const end = position[0] + position[1];
let previewStart = start;
let previewEnd = end;
let ellipsesBefore = true;
let ellipsesAfter = true;
for (let k = 0; k < 3; k++) {
const nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
const nextDot = doc.content.lastIndexOf('.', previewStart - 2);
if (nextDot > 0 && nextDot > nextSpace) {
previewStart = nextDot + 1;
ellipsesBefore = false;
break;
}
if (nextSpace < 0) {
previewStart = 0;
ellipsesBefore = false;
break;
}
previewStart = nextSpace + 1;
}
for (let k = 0; k < 10; k++) {
const nextSpace = doc.content.indexOf(' ', previewEnd + 1);
const nextDot = doc.content.indexOf('.', previewEnd + 1);
if (nextDot > 0 && nextDot < nextSpace) {
previewEnd = nextDot;
ellipsesAfter = false;
break;
}
if (nextSpace < 0) {
previewEnd = doc.content.length;
ellipsesAfter = false;
break;
}
previewEnd = nextSpace;
}
let preview = doc.content.substring(previewStart, start);
if (ellipsesBefore) {
preview = '... ' + preview;
}
preview += '<span class="algolia-docsearch-suggestion--highlight">' + doc.content.substring(start, end) + '</span>';
preview += doc.content.substring(end, previewEnd);
if (ellipsesAfter) {
preview += ' ...';
}
return this.getHit(doc, null, preview);
}
search(input) {
return new Promise((resolve, rej) => {
const results = this.getLunrResult(input);
const hits = [];
results.length > 5 && (results.length = 5);
this.titleHitsRes = [];
this.contentHitsRes = [];
results.forEach((result) => {
const doc = this.searchDocs[result.ref];
const { metadata } = result.matchData;
for (let i in metadata) {
if (metadata[i].title) {
if (!this.titleHitsRes.includes(result.ref)) {
const position = metadata[i].title.position[0];
hits.push(this.getTitleHit(doc, position, input.length));
this.titleHitsRes.push(result.ref);
}
} else if (metadata[i].content) {
const position = metadata[i].content.position[0];
hits.push(this.getContentHit(doc, position));
} else if (metadata[i].keywords) {
const position = metadata[i].keywords.position[0];
hits.push(this.getKeywordHit(doc, position, input.length));
this.titleHitsRes.push(result.ref);
}
}
});
hits.length > 5 && (hits.length = 5);
resolve(hits);
});
}
}
export default LunrSearchAdapter;

View File

@@ -0,0 +1,33 @@
.search-icon {
background-image: var(--ifm-navbar-search-input-icon);
height: auto;
width: 24px;
cursor: pointer;
padding: 8px;
line-height: 32px;
background-repeat: no-repeat;
background-position: center;
display: none;
}
.search-icon-hidden {
visibility: hidden;
}
@media (max-width: 360px) {
.search-bar {
width: 0 !important;
background: none !important;
padding: 0 !important;
transition: none !important;
}
.search-bar-expanded {
width: 9rem !important;
}
.search-icon {
display: inline;
vertical-align: sub;
}
}

View File

@@ -0,0 +1,112 @@
const prefix = 'algolia-docsearch';
const suggestionPrefix = `${prefix}-suggestion`;
const footerPrefix = `${prefix}-footer`;
const templates = {
suggestion: `
<a class="${suggestionPrefix}
{{#isCategoryHeader}}${suggestionPrefix}__main{{/isCategoryHeader}}
{{#isSubCategoryHeader}}${suggestionPrefix}__secondary{{/isSubCategoryHeader}}
"
aria-label="Link to the result"
href="{{{url}}}"
>
<div class="${suggestionPrefix}--category-header">
<span class="${suggestionPrefix}--category-header-lvl0">{{{category}}}</span>
</div>
<div class="${suggestionPrefix}--wrapper">
<div class="${suggestionPrefix}--subcategory-column">
<span class="${suggestionPrefix}--subcategory-column-text">{{{subcategory}}}</span>
</div>
{{#isTextOrSubcategoryNonEmpty}}
<div class="${suggestionPrefix}--content">
<div class="${suggestionPrefix}--subcategory-inline">{{{subcategory}}}</div>
<div class="${suggestionPrefix}--title">{{{title}}}</div>
{{#text}}<div class="${suggestionPrefix}--text">{{{text}}}</div>{{/text}}
</div>
{{/isTextOrSubcategoryNonEmpty}}
</div>
</a>
`,
suggestionSimple: `
<div class="${suggestionPrefix}
{{#isCategoryHeader}}${suggestionPrefix}__main{{/isCategoryHeader}}
{{#isSubCategoryHeader}}${suggestionPrefix}__secondary{{/isSubCategoryHeader}}
suggestion-layout-simple
">
<div class="${suggestionPrefix}--category-header">
{{^isLvl0}}
<span class="${suggestionPrefix}--category-header-lvl0 ${suggestionPrefix}--category-header-item">{{{category}}}</span>
{{^isLvl1}}
{{^isLvl1EmptyOrDuplicate}}
<span class="${suggestionPrefix}--category-header-lvl1 ${suggestionPrefix}--category-header-item">
{{{subcategory}}}
</span>
{{/isLvl1EmptyOrDuplicate}}
{{/isLvl1}}
{{/isLvl0}}
<div class="${suggestionPrefix}--title ${suggestionPrefix}--category-header-item">
{{#isLvl2}}
{{{title}}}
{{/isLvl2}}
{{#isLvl1}}
{{{subcategory}}}
{{/isLvl1}}
{{#isLvl0}}
{{{category}}}
{{/isLvl0}}
</div>
</div>
<div class="${suggestionPrefix}--wrapper">
{{#text}}
<div class="${suggestionPrefix}--content">
<div class="${suggestionPrefix}--text">{{{text}}}</div>
</div>
{{/text}}
</div>
</div>
`,
footer: `
<div class="${footerPrefix}">
</div>
`,
empty: `
<div class="${suggestionPrefix}">
<div class="${suggestionPrefix}--wrapper">
<div class="${suggestionPrefix}--content ${suggestionPrefix}--no-results">
<div class="${suggestionPrefix}--title">
<div class="${suggestionPrefix}--text">
No results found for query <b>"{{query}}"</b>
</div>
</div>
</div>
</div>
</div>
`,
searchBox: `
<form novalidate="novalidate" onsubmit="return false;" class="searchbox">
<div role="search" class="searchbox__wrapper">
<input id="docsearch" type="search" name="search" placeholder="Search the docs" autocomplete="off" required="required" class="searchbox__input"/>
<button type="submit" title="Submit your search query." class="searchbox__submit" >
<svg width=12 height=12 role="img" aria-label="Search">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-search-13"></use>
</svg>
</button>
<button type="reset" title="Clear the search query." class="searchbox__reset hide">
<svg width=12 height=12 role="img" aria-label="Reset">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-clear-3"></use>
</svg>
</button>
</div>
</form>
<div class="svg-icons" style="height: 0; width: 0; position: absolute; visibility: hidden">
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="sbx-icon-clear-3" viewBox="0 0 40 40"><path d="M16.228 20L1.886 5.657 0 3.772 3.772 0l1.885 1.886L20 16.228 34.343 1.886 36.228 0 40 3.772l-1.886 1.885L23.772 20l14.342 14.343L40 36.228 36.228 40l-1.885-1.886L20 23.772 5.657 38.114 3.772 40 0 36.228l1.886-1.885L16.228 20z" fill-rule="evenodd"></symbol>
<symbol id="sbx-icon-search-13" viewBox="0 0 40 40"><path d="M26.806 29.012a16.312 16.312 0 0 1-10.427 3.746C7.332 32.758 0 25.425 0 16.378 0 7.334 7.333 0 16.38 0c9.045 0 16.378 7.333 16.378 16.38 0 3.96-1.406 7.593-3.746 10.426L39.547 37.34c.607.608.61 1.59-.004 2.203a1.56 1.56 0 0 1-2.202.004L26.807 29.012zm-10.427.627c7.322 0 13.26-5.938 13.26-13.26 0-7.324-5.938-13.26-13.26-13.26-7.324 0-13.26 5.936-13.26 13.26 0 7.322 5.936 13.26 13.26 13.26z" fill-rule="evenodd"></symbol>
</svg>
</div>
`,
};
export default templates;

View File

@@ -0,0 +1,266 @@
import $ from 'autocomplete.js/zepto';
const utils = {
/*
* Move the content of an object key one level higher.
* eg.
* {
* name: 'My name',
* hierarchy: {
* lvl0: 'Foo',
* lvl1: 'Bar'
* }
* }
* Will be converted to
* {
* name: 'My name',
* lvl0: 'Foo',
* lvl1: 'Bar'
* }
* @param {Object} object Main object
* @param {String} property Main object key to move up
* @return {Object}
* @throws Error when key is not an attribute of Object or is not an object itself
*/
mergeKeyWithParent(object, property) {
if (object[property] === undefined) {
return object;
}
if (typeof object[property] !== 'object') {
return object;
}
const newObject = $.extend({}, object, object[property]);
delete newObject[property];
return newObject;
},
/*
* Group all objects of a collection by the value of the specified attribute
* If the attribute is a string, use the lowercase form.
*
* eg.
* groupBy([
* {name: 'Tim', category: 'dev'},
* {name: 'Vincent', category: 'dev'},
* {name: 'Ben', category: 'sales'},
* {name: 'Jeremy', category: 'sales'},
* {name: 'AlexS', category: 'dev'},
* {name: 'AlexK', category: 'sales'}
* ], 'category');
* =>
* {
* 'devs': [
* {name: 'Tim', category: 'dev'},
* {name: 'Vincent', category: 'dev'},
* {name: 'AlexS', category: 'dev'}
* ],
* 'sales': [
* {name: 'Ben', category: 'sales'},
* {name: 'Jeremy', category: 'sales'},
* {name: 'AlexK', category: 'sales'}
* ]
* }
* @param {array} collection Array of objects to group
* @param {String} property The attribute on which apply the grouping
* @return {array}
* @throws Error when one of the element does not have the specified property
*/
groupBy(collection, property) {
const newCollection = {};
$.each(collection, (index, item) => {
if (item[property] === undefined) {
throw new Error(`[groupBy]: Object has no key ${property}`);
}
let key = item[property];
if (typeof key === 'string') {
key = key.toLowerCase();
}
// fix #171 the given data type of docsearch hits might be conflict with the properties of the native Object,
// such as the constructor, so we need to do this check.
if (!Object.prototype.hasOwnProperty.call(newCollection, key)) {
newCollection[key] = [];
}
newCollection[key].push(item);
});
return newCollection;
},
/*
* Return an array of all the values of the specified object
* eg.
* values({
* foo: 42,
* bar: true,
* baz: 'yep'
* })
* =>
* [42, true, yep]
* @param {object} object Object to extract values from
* @return {array}
*/
values(object) {
return Object.keys(object).map((key) => object[key]);
},
/*
* Flattens an array
* eg.
* flatten([1, 2, [3, 4], [5, 6]])
* =>
* [1, 2, 3, 4, 5, 6]
* @param {array} array Array to flatten
* @return {array}
*/
flatten(array) {
const results = [];
array.forEach((value) => {
if (!Array.isArray(value)) {
results.push(value);
return;
}
value.forEach((subvalue) => {
results.push(subvalue);
});
});
return results;
},
/*
* Flatten all values of an object into an array, marking each first element of
* each group with a specific flag
* eg.
* flattenAndFlagFirst({
* 'devs': [
* {name: 'Tim', category: 'dev'},
* {name: 'Vincent', category: 'dev'},
* {name: 'AlexS', category: 'dev'}
* ],
* 'sales': [
* {name: 'Ben', category: 'sales'},
* {name: 'Jeremy', category: 'sales'},
* {name: 'AlexK', category: 'sales'}
* ]
* , 'isTop');
* =>
* [
* {name: 'Tim', category: 'dev', isTop: true},
* {name: 'Vincent', category: 'dev', isTop: false},
* {name: 'AlexS', category: 'dev', isTop: false},
* {name: 'Ben', category: 'sales', isTop: true},
* {name: 'Jeremy', category: 'sales', isTop: false},
* {name: 'AlexK', category: 'sales', isTop: false}
* ]
* @param {object} object Object to flatten
* @param {string} flag Flag to set to true on first element of each group
* @return {array}
*/
flattenAndFlagFirst(object, flag) {
const values = this.values(object).map((collection) =>
collection.map((item, index) => {
// eslint-disable-next-line no-param-reassign
item[flag] = index === 0;
return item;
}),
);
return this.flatten(values);
},
/*
* Removes all empty strings, null, false and undefined elements array
* eg.
* compact([42, false, null, undefined, '', [], 'foo']);
* =>
* [42, [], 'foo']
* @param {array} array Array to compact
* @return {array}
*/
compact(array) {
const results = [];
array.forEach((value) => {
if (!value) {
return;
}
results.push(value);
});
return results;
},
/*
* Returns the highlighted value of the specified key in the specified object.
* If no highlighted value is available, will return the key value directly
* eg.
* getHighlightedValue({
* _highlightResult: {
* text: {
* value: '<mark>foo</mark>'
* }
* },
* text: 'foo'
* }, 'text');
* =>
* '<mark>foo</mark>'
* @param {object} object Hit object returned by the Algolia API
* @param {string} property Object key to look for
* @return {string}
**/
getHighlightedValue(object, property) {
if (
object._highlightResult &&
object._highlightResult.hierarchy_camel &&
object._highlightResult.hierarchy_camel[property] &&
object._highlightResult.hierarchy_camel[property].matchLevel &&
object._highlightResult.hierarchy_camel[property].matchLevel !== 'none' &&
object._highlightResult.hierarchy_camel[property].value
) {
return object._highlightResult.hierarchy_camel[property].value;
}
if (
object._highlightResult &&
object._highlightResult &&
object._highlightResult[property] &&
object._highlightResult[property].value
) {
return object._highlightResult[property].value;
}
return object[property];
},
/*
* Returns the snippeted value of the specified key in the specified object.
* If no highlighted value is available, will return the key value directly.
* Will add starting and ending ellipsis (…) if we detect that a sentence is
* incomplete
* eg.
* getSnippetedValue({
* _snippetResult: {
* text: {
* value: '<mark>This is an unfinished sentence</mark>'
* }
* },
* text: 'This is an unfinished sentence'
* }, 'text');
* =>
* '<mark>This is an unfinished sentence</mark>…'
* @param {object} object Hit object returned by the Algolia API
* @param {string} property Object key to look for
* @return {string}
**/
getSnippetedValue(object, property) {
if (!object._snippetResult || !object._snippetResult[property] || !object._snippetResult[property].value) {
return object[property];
}
let snippet = object._snippetResult[property].value;
if (snippet[0] !== snippet[0].toUpperCase()) {
snippet = `${snippet}`;
}
if (['.', '!', '?'].indexOf(snippet[snippet.length - 1]) === -1) {
snippet = `${snippet}`;
}
return snippet;
},
/*
* Deep clone an object.
* Note: This will not clone functions and dates
* @param {object} object Object to clone
* @return {object}
*/
deepClone(object) {
return JSON.parse(JSON.stringify(object));
},
};
export default utils;

BIN
docs/static/img/immich-screenshots.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

View File

@@ -4,25 +4,25 @@ module.exports = {
corePlugins: {
preflight: false, // disable Tailwind's reset
},
content: ["./src/**/*.{js,jsx,ts,tsx}", "../docs/**/*.mdx"], // my markdown stuff is in ../docs, not /src
darkMode: ["class", '[data-theme="dark"]'], // hooks into docusaurus' dark mode settigns
content: ['./src/**/*.{js,jsx,ts,tsx}', '../docs/**/*.mdx'], // my markdown stuff is in ../docs, not /src
darkMode: ['class', '[data-theme="dark"]'], // hooks into docusaurus' dark mode settigns
theme: {
extend: {
colors: {
// Light Theme
"immich-primary": "#4250af",
"immich-bg": "white",
"immich-fg": "black",
"immich-gray": "#F6F6F4",
'immich-primary': '#4250af',
'immich-bg': 'white',
'immich-fg': 'black',
'immich-gray': '#F6F6F4',
// Dark Theme
"immich-dark-primary": "#adcbfa",
"immich-dark-bg": "black",
"immich-dark-fg": "#e5e7eb",
"immich-dark-gray": "#212121",
'immich-dark-primary': '#adcbfa',
'immich-dark-bg': 'black',
'immich-dark-fg': '#e5e7eb',
'immich-dark-gray': '#212121',
},
fontFamily: {
"immich-title": ["Snowburst One", "cursive"],
'immich-title': ['Snowburst One', 'cursive'],
},
},
},

View File

@@ -22,6 +22,7 @@
{ "source": "/docs/features/password-login", "destination": "/docs/administration/password-login" },
{ "source": "/docs/features/server-commands", "destination": "/docs/administration/server-commands" },
{ "source": "/docs/features/storage-template", "destination": "/docs/administration/storage-template" },
{ "source": "/docs/features/user-management", "destination": "/docs/administration/user-management" }
{ "source": "/docs/features/user-management", "destination": "/docs/administration/user-management" },
{ "source": "/docs/developer/contributing", "destination": "/docs/developer/pr-checklist" }
]
}

View File

@@ -2,19 +2,10 @@ echo "Starting Immich installation..."
ip_address=$(hostname -I | awk '{print $1}')
release_version=$(curl --silent "https://api.github.com/repos/immich-app/immich/releases/latest" |
grep '"tag_name":' |
sed -E 's/.*"([^"]+)".*/\1/')
RED='\033[0;31m'
GREEN='\032[0;31m'
NC='\033[0m' # No Color
get_release_version() {
curl --silent "https://api.github.com/repos/immich-app/immich/releases/latest" | # Get latest release from GitHub api
grep '"tag_name":' | # Get tag line
sed -E 's/.*"([^"]+)".*/\1/' # Pluck JSON value
}
create_immich_directory() {
echo "Creating Immich directory..."
mkdir -p ./immich-app/immich-data
@@ -23,12 +14,12 @@ create_immich_directory() {
download_docker_compose_file() {
echo "Downloading docker-compose.yml..."
curl -L https://raw.githubusercontent.com/immich-app/immich/$release_version/docker/docker-compose.yml -o ./docker-compose.yml >/dev/null 2>&1
curl -L https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml -o ./docker-compose.yml >/dev/null 2>&1
}
download_dot_env_file() {
echo "Downloading .env file..."
curl -L https://raw.githubusercontent.com/immich-app/immich/$release_version/docker/example.env -o ./.env >/dev/null 2>&1
curl -L https://github.com/immich-app/immich/releases/latest/download/example.env -o ./.env >/dev/null 2>&1
}
replace_env_value() {
@@ -69,7 +60,7 @@ start_docker_compose() {
show_friendly_message() {
echo "Succesfully deployed Immich!"
echo "You can access the website at http://$ip_address:2283 and the server URL for the mobile app is http://$ip_address:2283/api"
echo "The backup (or upload) location is $upload_location"
echo "The library location is $upload_location"
echo "---------------------------------------------------"
echo "If you want to configure custom information of the server, including the database, Redis information, or the backup (or upload) location, etc.

View File

@@ -44,5 +44,5 @@ download:
locale_code: ru-RU
- file: mobile/assets/i18n/cs-CZ.json
locale_code: cs-CZ
- file: mobile/assets/i18n/no-NO.json
locale_code: no-NO
- file: mobile/assets/i18n/nb-NO.json
locale_code: nb-NO

View File

@@ -1 +1,3 @@
venv/
venv/
*.zip
*.onnx

View File

@@ -1,4 +1,172 @@
*.zip
*.onnx
upload/
venv/
__pycache__/
model-cache/
model-cache/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
*.onnx
*.zip

View File

@@ -1,25 +1,29 @@
FROM python:3.10 as builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=true
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=true
RUN python -m venv /opt/venv
RUN /opt/venv/bin/pip install --pre torch -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
RUN /opt/venv/bin/pip install transformers tqdm numpy scikit-learn scipy nltk sentencepiece flask Pillow gunicorn
RUN /opt/venv/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
RUN /opt/venv/bin/pip install transformers tqdm numpy scikit-learn scipy nltk sentencepiece fastapi Pillow uvicorn[standard]
RUN /opt/venv/bin/pip install --no-deps sentence-transformers
# Facial Recognition Stuff
RUN /opt/venv/bin/pip install insightface onnxruntime
FROM python:3.10-slim
ENV NODE_ENV=production
COPY --from=builder /opt/venv /opt/venv
ENV TRANSFORMERS_CACHE=/cache \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH="/opt/venv/bin:$PATH"
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH="/opt/venv/bin:$PATH"
WORKDIR /usr/src/app
COPY . .
CMD ["gunicorn", "src.main:server"]
ENV PYTHONPATH=`pwd`
CMD ["python", "src/main.py"]

View File

@@ -1,29 +0,0 @@
"""
Gunicorn configuration options.
https://docs.gunicorn.org/en/stable/settings.html
"""
import os
# Set the bind address based on the env
port = os.getenv("MACHINE_LEARNING_PORT") or "3003"
listen_ip = os.getenv("MACHINE_LEARNING_IP") or "0.0.0.0"
bind = [f"{listen_ip}:{port}"]
# Preload the Flask app / models etc. before starting the server
preload_app = True
# Logging settings - log to stdout and set log level
accesslog = "-"
loglevel = os.getenv("MACHINE_LEARNING_LOG_LEVEL") or "info"
# Worker settings
# ----------------------
# It is important these are chosen carefully as per
# https://pythonspeed.com/articles/gunicorn-in-docker/
# Otherwise we get workers failing to respond to heartbeat checks,
# especially as requests take a long time to complete.
workers = 2
threads = 4
worker_tmp_dir = "/dev/shm"
timeout = 60

View File

@@ -1,73 +1,158 @@
import os
from flask import Flask, request
import numpy as np
import cv2 as cv
import uvicorn
from insightface.app import FaceAnalysis
from transformers import pipeline
from sentence_transformers import SentenceTransformer, util
from sentence_transformers import SentenceTransformer
from PIL import Image
from fastapi import FastAPI
from pydantic import BaseModel
is_dev = os.getenv('NODE_ENV') == 'development'
server_port = os.getenv('MACHINE_LEARNING_PORT', 3003)
server_host = os.getenv('MACHINE_LEARNING_HOST', '0.0.0.0')
classification_model = os.getenv('MACHINE_LEARNING_CLASSIFICATION_MODEL', 'microsoft/resnet-50')
object_model = os.getenv('MACHINE_LEARNING_OBJECT_MODEL', 'hustvl/yolos-tiny')
clip_image_model = os.getenv('MACHINE_LEARNING_CLIP_IMAGE_MODEL', 'clip-ViT-B-32')
clip_text_model = os.getenv('MACHINE_LEARNING_CLIP_TEXT_MODEL', 'clip-ViT-B-32')
class MlRequestBody(BaseModel):
thumbnailPath: str
class ClipRequestBody(BaseModel):
text: str
classification_model = os.getenv(
"MACHINE_LEARNING_CLASSIFICATION_MODEL", "microsoft/resnet-50"
)
object_model = os.getenv("MACHINE_LEARNING_OBJECT_MODEL", "hustvl/yolos-tiny")
clip_image_model = os.getenv("MACHINE_LEARNING_CLIP_IMAGE_MODEL", "clip-ViT-B-32")
clip_text_model = os.getenv("MACHINE_LEARNING_CLIP_TEXT_MODEL", "clip-ViT-B-32")
facial_recognition_model = os.getenv(
"MACHINE_LEARNING_FACIAL_RECOGNITION_MODEL", "buffalo_l"
)
cache_folder = os.getenv("MACHINE_LEARNING_CACHE_FOLDER", "/cache")
_model_cache = {}
def _get_model(model, task=None):
global _model_cache
key = '|'.join([model, str(task)])
if key not in _model_cache:
if task:
_model_cache[key] = pipeline(model=model, task=task)
else:
_model_cache[key] = SentenceTransformer(model)
return _model_cache[key]
server = Flask(__name__)
app = FastAPI()
@server.route("/ping")
@app.on_event("startup")
async def startup_event():
# Get all models
_get_model(object_model, "object-detection")
_get_model(classification_model, "image-classification")
_get_model(clip_image_model)
_get_model(clip_text_model)
_get_model(facial_recognition_model, "facial-recognition")
@app.get("/")
async def root():
return {"message": "Immich ML"}
@app.get("/ping")
def ping():
return "pong"
@server.route("/object-detection/detect-object", methods=['POST'])
def object_detection():
model = _get_model(object_model, 'object-detection')
assetPath = request.json['thumbnailPath']
return run_engine(model, assetPath), 200
@server.route("/image-classifier/tag-image", methods=['POST'])
def image_classification():
model = _get_model(classification_model, 'image-classification')
assetPath = request.json['thumbnailPath']
return run_engine(model, assetPath), 200
@app.post("/object-detection/detect-object", status_code=200)
def object_detection(payload: MlRequestBody):
model = _get_model(object_model, "object-detection")
assetPath = payload.thumbnailPath
return run_engine(model, assetPath)
@server.route("/sentence-transformer/encode-image", methods=['POST'])
def clip_encode_image():
@app.post("/image-classifier/tag-image", status_code=200)
def image_classification(payload: MlRequestBody):
model = _get_model(classification_model, "image-classification")
assetPath = payload.thumbnailPath
return run_engine(model, assetPath)
@app.post("/sentence-transformer/encode-image", status_code=200)
def clip_encode_image(payload: MlRequestBody):
model = _get_model(clip_image_model)
assetPath = request.json['thumbnailPath']
return model.encode(Image.open(assetPath)).tolist(), 200
assetPath = payload.thumbnailPath
return model.encode(Image.open(assetPath)).tolist()
@server.route("/sentence-transformer/encode-text", methods=['POST'])
def clip_encode_text():
@app.post("/sentence-transformer/encode-text", status_code=200)
def clip_encode_text(payload: ClipRequestBody):
model = _get_model(clip_text_model)
text = request.json['text']
return model.encode(text).tolist(), 200
text = payload.text
return model.encode(text).tolist()
@app.post("/facial-recognition/detect-faces", status_code=200)
def facial_recognition(payload: MlRequestBody):
model = _get_model(facial_recognition_model, "facial-recognition")
assetPath = payload.thumbnailPath
img = cv.imread(assetPath)
height, width, _ = img.shape
results = []
faces = model.get(img)
for face in faces:
if face.det_score < 0.7:
continue
x1, y1, x2, y2 = face.bbox
results.append(
{
"imageWidth": width,
"imageHeight": height,
"boundingBox": {
"x1": round(x1),
"y1": round(y1),
"x2": round(x2),
"y2": round(y2),
},
"score": face.det_score.item(),
"embedding": face.normed_embedding.tolist(),
}
)
return results
def run_engine(engine, path):
result = []
predictions = engine(path)
for index, pred in enumerate(predictions):
tags = pred['label'].split(', ')
if (pred['score'] > 0.9):
tags = pred["label"].split(", ")
if pred["score"] > 0.9:
result = [*result, *tags]
if (len(result) > 1):
if len(result) > 1:
result = list(set(result))
return result
def _get_model(model, task=None):
global _model_cache
key = "|".join([model, str(task)])
if key not in _model_cache:
if task:
if task == "facial-recognition":
face_model = FaceAnalysis(
name=model,
root=cache_folder,
allowed_modules=["detection", "recognition"],
)
face_model.prepare(ctx_id=0, det_size=(640, 640))
_model_cache[key] = face_model
else:
_model_cache[key] = pipeline(model=model, task=task)
else:
_model_cache[key] = SentenceTransformer(model, cache_folder=cache_folder)
return _model_cache[key]
if __name__ == "__main__":
server.run(debug=is_dev, host=server_host, port=server_port)
host = os.getenv("MACHINE_LEARNING_HOST", "0.0.0.0")
port = int(os.getenv("MACHINE_LEARNING_PORT", 3003))
is_dev = os.getenv("NODE_ENV") == "development"
uvicorn.run("main:app", host=host, port=port, reload=is_dev, workers=1)

View File

@@ -61,26 +61,17 @@ fi
if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
npm --prefix server version $SERVER_PUMP
npm --prefix server run api:generate
fi
if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then
echo "Pumping Mobile: $CURRENT_MOBILE => $NEXT_MOBILE"
fi
sed -i "s/^ \"version\": \"$CURRENT_SERVER\",$/ \"version\": \"$NEXT_SERVER\",/" server/package.json
sed -i "s/^ \"version\": \"$CURRENT_SERVER\",$/ \"version\": \"$NEXT_SERVER\",/" server/package-lock.json
sed -i "s/\"version\": \"$CURRENT_SERVER\",$/\"version\": \"$NEXT_SERVER\",/" server/immich-openapi-specs.json
sed -i "s/\"android\.injected\.version\.name\" => \"$CURRENT_SERVER\",/\"android\.injected\.version\.name\" => \"$NEXT_SERVER\",/" mobile/android/fastlane/Fastfile
sed -i "s/version_number: \"$CURRENT_SERVER\"$/version_number: \"$NEXT_SERVER\"/" mobile/ios/fastlane/Fastfile
sed -i "s/\"android\.injected\.version\.code\" => $CURRENT_MOBILE,/\"android\.injected\.version\.code\" => $NEXT_MOBILE,/" mobile/android/fastlane/Fastfile
sed -i "s/^version: $CURRENT_SERVER+$CURRENT_MOBILE$/version: $NEXT_SERVER+$NEXT_MOBILE/" mobile/pubspec.yaml
# OpenApi Generated Files
sed -i "s/API version: $CURRENT_SERVER,$/API version: $NEXT_SERVER/" mobile/openapi/README.md
sed -i "s/OpenAPI document: $CURRENT_SERVER,$/OpenAPI document: $NEXT_SERVER/" web/src/api/open-api/api.ts
sed -i "s/OpenAPI document: $CURRENT_SERVER,$/OpenAPI document: $NEXT_SERVER/" web/src/api/open-api/base.ts
sed -i "s/OpenAPI document: $CURRENT_SERVER,$/OpenAPI document: $NEXT_SERVER/" web/src/api/open-api/common.ts
sed -i "s/OpenAPI document: $CURRENT_SERVER,$/OpenAPI document: $NEXT_SERVER/" web/src/api/open-api/configuration.ts
sed -i "s/OpenAPI document: $CURRENT_SERVER,$/OpenAPI document: $NEXT_SERVER/" web/src/api/open-api/index.ts
echo "IMMICH_VERSION=v$NEXT_SERVER" >>$GITHUB_ENV

View File

@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.7.0",
"flutterSdkVersion": "3.10.0",
"flavors": {}
}
}

View File

@@ -23,6 +23,7 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
@@ -86,4 +87,6 @@ dependencies {
implementation "androidx.work:work-runtime-ktx:$work_version"
implementation "androidx.concurrent:concurrent-futures:$concurrent_version"
implementation "com.google.guava:guava:$guava_version"
implementation "com.github.bumptech.glide:glide:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
}

View File

@@ -59,6 +59,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries>
<intent>

View File

@@ -0,0 +1,7 @@
package app.alextran.immich
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
@GlideModule
class AppGlideModule : AppGlideModule()

View File

@@ -1,15 +1,16 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.8.20'
ext.work_version = '2.7.1'
ext.concurrent_version = '1.1.0'
ext.guava_version = '31.0.1-android'
ext.glide_version = '4.14.2'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@@ -29,6 +30,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@@ -35,8 +35,8 @@ platform :android do
task: 'bundle',
build_type: 'Release',
properties: {
"android.injected.version.code" => 74,
"android.injected.version.name" => "1.51.1",
"android.injected.version.code" => 80,
"android.injected.version.name" => "1.57.0",
}
)
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')

View File

@@ -0,0 +1,8 @@
* refactor: migrate all Hive boxes to Isar database.
* feat: Use new search API and GridView for Places / Locations.
* refactor: store backup settings on device.
* feat: Explore favorites, recently added, videos, and motion photos.
* fix: Fixed mobile app not reporting webm MIME type.
* feature: Hardening synchronization mechanism + Pull to refresh.
* feat: improve explore page and allow metadata search.
* feat: Allow headers to upload large file in chunk.

View File

@@ -0,0 +1,3 @@
* Improved logging page experience
* Fixed shared page does not get all shared albums
* Fixed hero animation re-enabling on immich asset grid

View File

@@ -0,0 +1,10 @@
* Fixes white navigation bar in Android 8.
* Add bottom safe area to video player controls.
* Fix null check operator on null value.
* Add troubleshooting toggle.
* Configurable log level.
* Consistent handling of DateTime in SyncService.
* Fix asset removal edge cases.
* Archive feature on mobile.
* Add AssetState and proper asset updating.
* Video player disposes early.

View File

@@ -0,0 +1 @@
* Minor UI improvement

View File

@@ -0,0 +1,2 @@
* Upgrade to Flutter 3.10
* Lazy loading of timeline

View File

@@ -5,19 +5,19 @@
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000232">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.00032">
</testcase>
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="70.685298">
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="29.247439">
</testcase>
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="33.624781">
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="22.794249">
<failure message="/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:229:in `chdir&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:229:in `execute_action&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing&apos;&#10;Fastfile:42:in `block (2 levels) in parsing_binding&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/lane.rb:33:in `call&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:49:in `block in execute&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:45:in `chdir&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/runner.rb:45:in `execute&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/commands_generator.rb:354:in `run&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/commands_generator.rb:43:in `start&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/gems/fastlane-2.212.0/bin/fastlane:23:in `&lt;top (required)&gt;&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/bin/fastlane:25:in `load&apos;&#10;/opt/homebrew/Cellar/fastlane/2.212.0/libexec/bin/fastlane:25:in `&lt;main&gt;&apos;&#10;&#10;Google Api Error: Invalid request - The release created has notes in language en-US with length 508, which is too long (max: 500)." />
<failure message="/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:229:in `chdir&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:229:in `execute_action&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing&apos;&#10;Fastfile:42:in `block (2 levels) in parsing_binding&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane.rb:33:in `call&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:49:in `block in execute&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `chdir&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `execute&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:354:in `run&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:43:in `start&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/bin/fastlane:23:in `&lt;top (required)&gt;&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `load&apos;&#10;/usr/local/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `&lt;main&gt;&apos;&#10;&#10;Google Api Error: Invalid request - APK specifies a version code that has already been used." />
</testcase>

View File

@@ -1,7 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionSha256Sum=cd5c2958a107ee7f0722004a12d0f8559b4564c34daad7df06cffd4d12a426d0
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
distributionSha256Sum=518a863631feb7452b8f1b3dc2aaee5f388355cc3421bbd0275fbeadd77e84b2

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Přidáno do {album}",
"add_to_album_bottom_sheet_already_exists": "Již v {album}",
"advanced_settings_tile_subtitle": "Pokročilé uživatelské nastavení",
"advanced_settings_tile_title": "Pokročilé",
"advanced_settings_troubleshooting_subtitle": "Povolit dodatečné funkce pro řešení problémů",
"advanced_settings_troubleshooting_title": "Řešení problémů",
"album_info_card_backup_album_excluded": "VYLOUČENO",
"album_info_card_backup_album_included": "ZAHRNUTO",
"album_thumbnail_card_item": "1 položka",
"album_thumbnail_card_items": "{} položky",
"album_thumbnail_card_items": "{} položek",
"album_thumbnail_card_shared": "Sdíleno",
"album_thumbnail_owned": "Vlastněno",
"album_thumbnail_shared_by": "Sdílené od {}",
"album_viewer_appbar_share_delete": "Odstranit album",
"album_viewer_appbar_share_err_delete": "Nepodařilo se odstranit album",
"album_viewer_appbar_share_err_leave": "Nepodařilo se ukončit album",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Opustit album",
"album_viewer_appbar_share_remove": "Odstranit z alba",
"album_viewer_page_share_add_users": "Přidat uživatele",
"all_videos_page_title": "Videa",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archív ({})",
"asset_list_layout_settings_dynamic_layout_title": "Dynamické rozložení",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Seskupit položky podle",
"asset_list_layout_settings_group_by_month": "Měsíc",
"asset_list_layout_settings_group_by_month_day": "Měsíc + den",
@@ -35,11 +45,11 @@
"backup_background_service_in_progress_notification": "Vytvářím kopii vašich médií...",
"backup_background_service_upload_failure_notification": "Nepodařilo se nahrát {}",
"backup_controller_page_albums": "Zálohovaná alba",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_app_refresh_disabled_content": "Povolte obnovení aplikace na pozadí v Nastavení > Obecné > Obnovení aplikace na pozadí, abyste mohli používat zálohování na pozadí.",
"backup_controller_page_background_app_refresh_disabled_title": " Obnovování aplikací na pozadí je vypnuté",
"backup_controller_page_background_app_refresh_enable_button_text": "Přejít do nastavení",
"backup_controller_page_background_battery_info_link": "Ukaž mi jak",
"backup_controller_page_background_battery_info_message": "Chcete-li dosáhnout nejlepších výsledků při zálohování na pozadí, vypněte všechny optimalizace baterie, které omezují aktivitu na pozadí pro Immich ve vašem zařízení. Jelikož to závisí na zařízení, zkontrolujte požadované informace pro výrobce vašeho zařízení.",
"backup_controller_page_background_battery_info_message": "Chcete-li dosáhnout nejlepších výsledků při zálohování na pozadí, vypněte všechny optimalizace baterie, které omezují aktivitu na pozadí pro Immich ve vašem zařízení. \n\nJelikož je to závis na typu zařízení, vyhledejte požadované informace pro výrobce vašeho zařízení.",
"backup_controller_page_background_battery_info_ok": "OK",
"backup_controller_page_background_battery_info_title": "Optimalizace baterie",
"backup_controller_page_background_charging": "Pouze během nabíjení",
@@ -48,13 +58,13 @@
"backup_controller_page_background_description": "Povolte službu na pozadí pro automatické zálohování všech nových aktiv bez nutnosti otevření aplikace",
"backup_controller_page_background_is_off": "Automatické zálohování na pozadí je vypnuto",
"backup_controller_page_background_is_on": "Automatické zálohování na pozadí je zapnuto",
"backup_controller_page_background_turn_off": "Zakázat službu na pozadí",
"backup_controller_page_background_turn_on": "Povolit službu na pozadí",
"backup_controller_page_background_turn_off": "Vypnout zálohování na pozadí",
"backup_controller_page_background_turn_on": "Povolit zálohování na pozadí",
"backup_controller_page_background_wifi": "Jen na WiFi",
"backup_controller_page_backup": "Zálohováno",
"backup_controller_page_backup": "Zálohování",
"backup_controller_page_backup_selected": "Vybrané: ",
"backup_controller_page_backup_sub": "Zálohované fotografie a videa",
"backup_controller_page_cancel": "Zrušit",
"backup_controller_page_cancel": "Zastavit",
"backup_controller_page_created": "Vytvořeno: {}",
"backup_controller_page_desc_backup": "Zapněte zálohování na popředí, aby se nové položky automaticky nahrávaly na server při otevření aplikace.",
"backup_controller_page_excluded": "Vyloučeno: ",
@@ -64,7 +74,7 @@
"backup_controller_page_info": "Informace o zálohování",
"backup_controller_page_none_selected": "Žádné vybrané",
"backup_controller_page_remainder": "Zůstává",
"backup_controller_page_remainder_sub": "Zbývající fotografie a alba, která se mají zálohovat z výběru",
"backup_controller_page_remainder_sub": "Zbývající fotografie a videa, která se mají zálohovat z vybraných alb",
"backup_controller_page_select": "Vybrat",
"backup_controller_page_server_storage": "Serverové úložiště",
"backup_controller_page_start_backup": "Spustit zálohování",
@@ -74,9 +84,9 @@
"backup_controller_page_to_backup": "Alba, která mají být zálohována",
"backup_controller_page_total": "Celkem",
"backup_controller_page_total_sub": "Všechny jedinečné fotografie a videa z vybraných alb",
"backup_controller_page_turn_off": "Zakázat zálohování na popředí",
"backup_controller_page_turn_off": "Vypnout zálohování na popředí",
"backup_controller_page_turn_on": "Povolit zálohování na popředí",
"backup_controller_page_uploading_file_info": "Informace o nahrávaném souboru",
"backup_controller_page_uploading_file_info": "Nahrávaný soubor",
"backup_err_only_album": "Nelze odstranit jediné vybrané album",
"backup_info_card_assets": "položek",
"cache_settings_album_thumbnails": "Náhledy stránek knihovny (položek {})",
@@ -93,26 +103,31 @@
"cache_settings_thumbnail_size": "Velikost vyrovnávací paměti náhledů (položek {})",
"cache_settings_title": "Nastavení vyrovnávací paměti",
"change_password_form_confirm_password": "Potvrďte heslo",
"change_password_form_description": "Dobrý den, {firstName} {lastName},\n\nJe to buď poprvé, co se přihlašujete do systému, nebo byl podán požadavek na změnu hesla. Níže prosím zadejte nové heslo.",
"change_password_form_description": "Dobrý den, {firstName} {lastName},\n\nJe to buď poprvé, co se přihlašujete do systému, nebo byl vytvořen požadavek na změnu hesla. Zadejte níže, prosím, nové heslo.",
"change_password_form_new_password": "Nové heslo",
"change_password_form_password_mismatch": "Hesla se neshodují",
"change_password_form_reenter_new_password": "Znovu zadejte nové heslo",
"common_add_to_album": "Přidat do alba",
"common_change_password": "Změnit heslo",
"common_create_new_album": "Vytvořit nové album",
"common_server_error": "Zkontrolujte připojení k internetu. Ujistěte se, že server je dostupný a aplikace/server jsou v kompatibilní verzi.",
"common_shared": "Sdílené",
"control_bottom_app_bar_add_to_album": "Přidat do alba",
"control_bottom_app_bar_album_info": "{} položky",
"control_bottom_app_bar_album_info": "{} položek",
"control_bottom_app_bar_album_info_shared": "{} položky - sdílené",
"control_bottom_app_bar_archive": "Archív",
"control_bottom_app_bar_create_new_album": "Vytvořit nové album",
"control_bottom_app_bar_delete": "Vymazat",
"control_bottom_app_bar_favorite": "Oblíbené",
"control_bottom_app_bar_share": "Sdílet",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Bez názvu",
"create_shared_album_page_create": "Vytvořit",
"create_shared_album_page_share": "Sdílet",
"create_shared_album_page_share_add_assets": "PŘIDAT",
"create_shared_album_page_share_select_photos": "Vybrat fotografie",
"curated_location_page_title": "Místa",
"curated_object_page_title": "Věci",
"daily_title_text_date": "EEEE, d. MMMM",
"daily_title_text_date_year": "EEEE, d. MMMM y",
"date_format": "EEEE, d. MMMM y • H:mm",
@@ -120,28 +135,35 @@
"delete_dialog_cancel": "Zrušit",
"delete_dialog_ok": "Vymazat",
"delete_dialog_title": "Vymazat trvale",
"description_input_hint_text": "Přidat popis...",
"description_input_submit_error": "Chyba aktualizace popisu, další podrobnosti najdete v logu",
"exif_bottom_sheet_description": "Přidat popis...",
"exif_bottom_sheet_details": "PODROBNOSTI",
"exif_bottom_sheet_location": "LOKALITA",
"experimental_settings_new_asset_list_subtitle": "Probíhající práce",
"experimental_settings_new_asset_list_subtitle": "Zpracovávám",
"experimental_settings_new_asset_list_title": "Povolení experimentální mřížky fotografií",
"experimental_settings_subtitle": "Používejte na vlastní riziko!",
"experimental_settings_title": "Experimentální",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Oblíbené",
"home_page_add_to_album_conflicts": "Přidány {added} položky do alba {album}. {failed} položky jsou již v albu.",
"home_page_add_to_album_conflicts": "Přidáno {added} položek do alba {album}. {failed} položek již je v albu.",
"home_page_add_to_album_err_local": "Zatím není možné přidat lokální média do alb, přeskakuje se",
"home_page_add_to_album_success": "Přidány položky {added} do alba {album}.",
"home_page_building_timeline": "Vytváraní časové osy",
"home_page_archive_err_local": "Zatím nemohu archivovat lokální média, přeskakuji",
"home_page_building_timeline": "Vytváření časové osy",
"home_page_favorite_err_local": "Zatím není možné zařadit lokální média mezi oblíbená, přeskakuje se",
"home_page_first_time_notice": "Pokud aplikaci používáte poprvé, nezapomeňte si vybrat zálohovaná alba, aby se na časové ose mohly nacházet fotografie a videa z vybraných albech.",
"image_viewer_page_state_provider_download_error": "Chyba stahování",
"image_viewer_page_state_provider_download_success": "Stahování bylo úspěšné",
"library_page_albums": "Alba",
"library_page_archive": "Archív",
"library_page_device_albums": "Alba v zařízení",
"library_page_favorites": "Oblíbené",
"library_page_new_album": "Nové album",
"library_page_sharing": "Sdílení",
"library_page_sort_created": "Naposledy vytvořené",
"library_page_sort_title": "Podle názvu alba",
"login_form_api_exception": "Výjimka API. Zkontrolujte URL serveru a zkuste to znovu.",
"login_form_button_text": "Přihlásit se",
"login_form_email_hint": "tvůjmail@email.com",
"login_form_endpoint_hint": "http://ip-tvého-serveru:port/api",
@@ -156,32 +178,57 @@
"login_form_failed_login": "Chyba přihlášení, zkontrolujte url adresu serveru, e-mail a heslo.",
"login_form_label_email": "E-mail",
"login_form_label_password": "Heslo",
"login_form_next_button": "Další",
"login_form_password_hint": "heslo",
"login_form_save_login": "Zůstat přihlášen",
"login_form_server_empty": "Zadejte URL serveru.",
"login_form_server_error": "Není možné se připojit k serveru.",
"monthly_title_text_date_format": "LLLL y",
"motion_photos_page_title": "Pohyblivé fotky",
"notification_permission_dialog_cancel": "Zrušit",
"notification_permission_dialog_content": "Chcete-li povolit oznámení, přejděte do Nastavení a vyberte možnost Povolit.",
"notification_permission_dialog_content": "Chcete-li povolit oznámení, přejděte do Nastavení a vyberte možnost povolit.",
"notification_permission_dialog_settings": "Nastavení",
"notification_permission_list_tile_content": "Udělte oprávnění k aktivaci oznámení.",
"notification_permission_list_tile_enable_button": "Povolit oznámení",
"notification_permission_list_tile_title": "Povolení oznámení",
"permission_onboarding_continue_anyway": "Přesto pokračovat",
"permission_onboarding_get_started": "Začít",
"permission_onboarding_go_to_settings": "Přejít do nastavení",
"permission_onboarding_grant_permission": "Povolit přístup",
"permission_onboarding_log_out": "Odhlásit se",
"permission_onboarding_permission_denied": "Přístup odepřen. Pro používání Immich, je nutné povolit přístup k fotkám a videím v nastavení.",
"permission_onboarding_permission_granted": "Přístup povolen! Vše je připraveno.",
"permission_onboarding_permission_limited": "Přístup omezen. Chcete-li používat Immich k zálohování a správě celé vaší kolekci galerií, povolte přístup k fotkám a videím v Nastavení.",
"permission_onboarding_request": "Immich potřebuje přístup k zobrazení vašich fotek a videí.",
"profile_drawer_app_logs": "Logy",
"profile_drawer_client_server_up_to_date": "Klient a server jsou aktuální",
"profile_drawer_settings": "Nastavení",
"profile_drawer_sign_out": "Odhlásit se",
"recently_added_page_title": "Nedávno přidané",
"search_bar_hint": "Prohledejte své obrázky",
"search_page_no_objects": "Žádné informace o objektech",
"search_page_no_places": "Žádné informace o místě",
"search_page_categories": "Kategorie",
"search_page_favorites": "Oblíbené",
"search_page_motion_photos": "Pohyblivé fotky",
"search_page_no_objects": "Informace o objektech nejsou k dispozici",
"search_page_no_places": "Informace o místě nejsou k dispozici",
"search_page_places": "Místa",
"search_page_recently_added": "Nedávno přidané",
"search_page_screenshots": "Snímky obrazovky",
"search_page_selfies": "Selfie",
"search_page_things": "Věci",
"search_page_videos": "Videa",
"search_page_view_all_button": "Zobrazit vše",
"search_page_your_activity": "Vaše aktivita",
"search_result_page_new_search_hint": "Nové vyhledávání",
"search_suggestion_list_smart_search_hint_1": "Ve výchozím nastavení je chytré vyhledávání zapnuto, pro vyhledávání metadat použijte syntaxi ",
"search_suggestion_list_smart_search_hint_2": "m:vaše-vyhledávaná-fráze",
"select_additional_user_for_sharing_page_suggestions": "Návrhy",
"select_user_for_sharing_page_err_album": "Nepodařilo se vytvořit album",
"select_user_for_sharing_page_share_suggestions": "Návrhy",
"server_info_box_app_version": "Verze aplikace",
"server_info_box_server_version": "Verze serveru",
"setting_image_viewer_help": "V prohlížeči detailů se nejprve načte malá miniatura, poté se načte náhled střední velikosti (je-li povolen) a nakonec se načte originál (je-li povolen).",
"setting_image_viewer_original_subtitle": "Umožňuje načíst původní obrázek v plném rozlišení (velký!). Zakázat pro snížení používání dat (v síti iv mezipaměti zařízení).",
"setting_image_viewer_original_subtitle": "Umožňuje načíst původní obrázek v plném rozlišení (velký!). Zakázat pro snížení využití dat (v síti i v mezipaměti zařízení).",
"setting_image_viewer_original_title": "Načíst původní obrázek",
"setting_image_viewer_preview_subtitle": "Umožňuje načíst obrázek se středním rozlišením. Zakažte, pokud chcete přímo načíst originál nebo použít pouze miniaturu.",
"setting_image_viewer_preview_title": "Načíst náhled obrázku",
@@ -195,7 +242,7 @@
"setting_notifications_single_progress_title": "Zobrazit průběh detailů zálohování na pozadí",
"setting_notifications_subtitle": "Přizpůsobení předvoleb oznámení",
"setting_notifications_title": "Oznámení",
"setting_notifications_total_progress_subtitle": "Celkový průběh nahrávání (hotové/celkové položky)",
"setting_notifications_total_progress_subtitle": "Celkový průběh nahrávání (nahraných/celkově)",
"setting_notifications_total_progress_title": "Zobrazit celkový průběh zálohování na pozadí",
"setting_pages_app_bar_settings": "Nastavení",
"settings_require_restart": "Pro použití tohoto nastavení restartujte Immich",
@@ -205,9 +252,9 @@
"share_create_album": "Vytvořit album",
"share_dialog_preparing": "Připravuji...",
"share_invite": "Pozvat do alba",
"sharing_page_album": "Shared albums",
"sharing_page_album": "Sdílená alba",
"sharing_page_description": "Vytvářejte sdílená alba a sdílejte fotografie a videa s lidmi ve vaší síti.",
"sharing_page_empty_list": "Prázdný dopis",
"sharing_page_empty_list": "PRÁZDNÝ SEZNAM",
"sharing_silver_appbar_create_shared_album": "Vytvořit sdílené album",
"sharing_silver_appbar_share_partner": "Sdílet s partnerem",
"tab_controller_nav_library": "Knihovna",
@@ -217,7 +264,7 @@
"theme_setting_asset_list_storage_indicator_title": "Zobrazit indikátor úložiště na dlaždicích položek",
"theme_setting_asset_list_tiles_per_row_title": "Počet položek na řádek ({})",
"theme_setting_dark_mode_switch": "Tmavé téma",
"theme_setting_image_viewer_quality_subtitle": "Přizpůsobení kvality prohlížeče detailů",
"theme_setting_image_viewer_quality_subtitle": "Přizpůsobení kvality detailů prohlížeče obrázků",
"theme_setting_image_viewer_quality_title": "Kvalita prohlížeče obrázků",
"theme_setting_system_theme_switch": "Automaticky (podle systemového nastavení)",
"theme_setting_theme_subtitle": "Vyberte nastavení tématu aplikace",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_album_bottom_sheet_added": "Tilføjet til {album}",
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
"advanced_settings_tile_subtitle": "Avancerede brugerindstillinger",
"advanced_settings_tile_title": "Arkivér",
"advanced_settings_troubleshooting_subtitle": "Slå ekstra funktioner for fejlsøgning til",
"advanced_settings_troubleshooting_title": "Fejlsøgning",
"album_info_card_backup_album_excluded": "EKSKLUDERET",
"album_info_card_backup_album_included": "INKLUDERET",
"album_thumbnail_card_item": "1 genstand",
"album_thumbnail_card_items": "{} genstande",
"album_thumbnail_card_shared": ". Delt",
"album_thumbnail_owned": "Ejet",
"album_thumbnail_shared_by": "Delt af {}",
"album_viewer_appbar_share_delete": "Slet album",
"album_viewer_appbar_share_err_delete": "Fejlede sletning af album",
"album_viewer_appbar_share_err_leave": "Fejlede i at forlade album",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Forlad album",
"album_viewer_appbar_share_remove": "Fjern fra album",
"album_viewer_page_share_add_users": "Tilføj brugere",
"all_videos_page_title": "Videoer",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Arkivér ({})",
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Gruppér elementer pr. ",
"asset_list_layout_settings_group_by_month": "Måned",
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
@@ -33,11 +43,11 @@
"backup_background_service_default_notification": "Søger efter nye elementer...",
"backup_background_service_error_title": "Fejl med backup",
"backup_background_service_in_progress_notification": "Tager backup af dine elementer...",
"backup_background_service_upload_failure_notification": "Failed to upload {}",
"backup_background_service_upload_failure_notification": "Fejlede med uploade af {}",
"backup_controller_page_albums": "Sikkerhedskopiér albummer",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_app_refresh_disabled_content": "Slå baggrundsopdatering af applikationen til i Indstillinger > Generelt > Baggrundsopdatering af applikationer, for at bruge baggrundsbackup.",
"backup_controller_page_background_app_refresh_disabled_title": "Baggrundsopdatering af app er slået fra",
"backup_controller_page_background_app_refresh_enable_button_text": "Gå til indstillinger",
"backup_controller_page_background_battery_info_link": "Vis mig hvordan",
"backup_controller_page_background_battery_info_message": "For den bedste oplevelse med baggrundsbackup, bør du slå batterioptimering, der begrænder baggrundsaktivitet, fra.\n\nSiden dette er afhængigt af enheden, bør du undersøge denne information leveret af din enheds producent.",
"backup_controller_page_background_battery_info_ok": "OK",
@@ -92,27 +102,32 @@
"cache_settings_subtitle": "Håndter cache-adfærden for Immich-appen.",
"cache_settings_thumbnail_size": "Størrelse af miniaturebillede cache ({} elementer)",
"cache_settings_title": "Cache-indstillinger",
"change_password_form_confirm_password": "Confirm Password",
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
"change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password",
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"change_password_form_confirm_password": "Bekræft kodeord",
"change_password_form_description": "Hej {firstName} {lastName},\n\nDette er enten første gang du logger ind eller også er der lavet en anmodning om at ændre dit kodeord. Indtast venligst et nyt kodeord nedenfor.",
"change_password_form_new_password": "Nyt kodeord",
"change_password_form_password_mismatch": "Kodeord er ikke ens",
"change_password_form_reenter_new_password": "Gentag nyt kodeord",
"common_add_to_album": "Tilføj til album",
"common_change_password": "Skift kodeord",
"common_create_new_album": "Opret et nyt album",
"common_server_error": "Tjek din internetforbindelse, sørg for at serveren er tilgængelig og at app- og serversioner er kompatible.",
"common_shared": "Delt",
"control_bottom_app_bar_add_to_album": "Tilføj til album",
"control_bottom_app_bar_album_info": "{} genstande",
"control_bottom_app_bar_album_info_shared": "{} genstande • Delt",
"control_bottom_app_bar_archive": "Arkiv",
"control_bottom_app_bar_create_new_album": "Opret nyt album",
"control_bottom_app_bar_delete": "Slet",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_favorite": "Favorit",
"control_bottom_app_bar_share": "Del",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Uden titel",
"create_shared_album_page_create": "Opret",
"create_shared_album_page_share": "Del",
"create_shared_album_page_share_add_assets": "TILFØJ ELEMENT",
"create_shared_album_page_share_select_photos": "Vælg billeder",
"curated_location_page_title": "Steder",
"curated_object_page_title": "Ting",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"date_format": "E d. LLL y • hh:mm",
@@ -120,6 +135,8 @@
"delete_dialog_cancel": "Annuller",
"delete_dialog_ok": "Slet",
"delete_dialog_title": "Slet permanent",
"description_input_hint_text": "Tilføj en beskrivelse...",
"description_input_submit_error": "Fejl med at opdatere beskrivelsen. Tjek loggen for flere detaljer",
"exif_bottom_sheet_description": "Tilføj beskrivelse...",
"exif_bottom_sheet_details": "DETALJER",
"exif_bottom_sheet_location": "LOKATION",
@@ -127,21 +144,26 @@
"experimental_settings_new_asset_list_title": "Aktiver eksperimentelt fotogitter",
"experimental_settings_subtitle": "Brug på eget ansvar!",
"experimental_settings_title": "Eksperimentelle",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Favoritter",
"home_page_add_to_album_conflicts": "Tilføjede {added} elementer til album {album}. {failed} elementer er allerede i albummet.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_err_local": "Kan endnu ikke tilføje lokale elementer til album. Springer over..",
"home_page_add_to_album_success": "Tilføjede {added} elementer til album {album}.",
"home_page_archive_err_local": "Kan ikke arkivere lokalt element endnu.. Springer over",
"home_page_building_timeline": "Bygger tidslinjen",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_favorite_err_local": "Kan endnu ikke gøre lokale elementer til favoritter. Springer over..",
"home_page_first_time_notice": "Hvis dette er din første gang i appen, bedes du vælge en backup af albummer så tidlinjen kan blive fyldt med billeder og videoer fra albummerne.",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"image_viewer_page_state_provider_download_error": "Fejl ved download",
"image_viewer_page_state_provider_download_success": "Download succesfuld",
"library_page_albums": "Albummer",
"library_page_archive": "Arkiv",
"library_page_device_albums": "Albummer på enhed",
"library_page_favorites": "Favoritter",
"library_page_new_album": "Nyt album",
"library_page_sharing": "Delte",
"library_page_sort_created": "Senest oprettet",
"library_page_sort_title": "Albumtitel",
"login_form_api_exception": "API-undtagelse. Tjek serverens URL og prøv igen. ",
"login_form_button_text": "Log ind",
"login_form_email_hint": "din-e-mail@e-mail.com",
"login_form_endpoint_hint": "http://din-server-ip:port/api",
@@ -156,30 +178,55 @@
"login_form_failed_login": "Der opstod en vejl ved at logge ind. Tjek server webadressen, e-mailen og kodeordet",
"login_form_label_email": "E-mail",
"login_form_label_password": "Kodeord",
"login_form_next_button": "Næste",
"login_form_password_hint": "kodeord",
"login_form_save_login": "Forbliv logget ind",
"login_form_server_empty": "Indtast server-URL.",
"login_form_server_error": "Kunne ikke forbinde til serveren.",
"monthly_title_text_date_format": "MMMM y",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"motion_photos_page_title": "Bevægelsesbilleder",
"notification_permission_dialog_cancel": "Annuller",
"notification_permission_dialog_content": "Gå til indstillinger for at slå notifikationer til.",
"notification_permission_dialog_settings": "Indstillinger",
"notification_permission_list_tile_content": "Tillad at bruge notifikationer.",
"notification_permission_list_tile_enable_button": "Slå notifikationer til",
"notification_permission_list_tile_title": "Notifikationstilladelser",
"permission_onboarding_continue_anyway": "Fortsæt alligevel",
"permission_onboarding_get_started": "Kom i gang",
"permission_onboarding_go_to_settings": "Gå til indstillinger",
"permission_onboarding_grant_permission": "Giv tilladelse",
"permission_onboarding_log_out": "Log ud",
"permission_onboarding_permission_denied": "Tilladelse afvist. For at bruge Immich, skal der gives tilladelse til at se billeder og videoer i indstillinger.",
"permission_onboarding_permission_granted": "Tilladelse givet! Du er nu klar.",
"permission_onboarding_permission_limited": "Tilladelse begrænset. For at lade Immich lave backup og styre hele dit galleri, skal der gives tilladelse til billeder og videoer i indstillinger.",
"permission_onboarding_request": "Immich kræver tilliadelse til at se dine billeder og videoer.",
"profile_drawer_app_logs": "Log",
"profile_drawer_client_server_up_to_date": "Klient og server er ajour",
"profile_drawer_settings": "Indstillinger",
"profile_drawer_sign_out": "Log ud",
"recently_added_page_title": "Nyligt tilføjet",
"search_bar_hint": "Søg i dine billeder",
"search_page_categories": "Kategorier",
"search_page_favorites": "Favoritter",
"search_page_motion_photos": "Bevægelsesbilleder",
"search_page_no_objects": "Ingen elementer er tilgængelige",
"search_page_no_places": "Ingen placeringsinformation er tilgængelig",
"search_page_places": "Steder",
"search_page_recently_added": "Nyligt tilføjet",
"search_page_screenshots": "Skærmbilleder",
"search_page_selfies": "Selfier",
"search_page_things": "Ting",
"search_page_videos": "Videoer",
"search_page_view_all_button": "Vis alt",
"search_page_your_activity": "Din aktivitet",
"search_result_page_new_search_hint": "Ny søgning",
"search_suggestion_list_smart_search_hint_1": "Smart søgnining er slået til som standard. For at søge efter metadata brug syntaksen",
"search_suggestion_list_smart_search_hint_2": "m:dit-søgeord",
"select_additional_user_for_sharing_page_suggestions": "Anbefalinger",
"select_user_for_sharing_page_err_album": "Fejlede i at oprette et nyt album",
"select_user_for_sharing_page_share_suggestions": "Anbefalinger",
"server_info_box_app_version": "App Version",
"server_info_box_server_version": "Server Version",
"server_info_box_app_version": "Applikationsversion",
"server_info_box_server_version": "Serverversion ",
"setting_image_viewer_help": "Detaljeret visning indlæser miniaturebilleder først. Herefter indlæses mediumstørrelse forhåndsvisning af billedet (hvis dette er slået til), for til sidst at vise originalen (hvis dette er slået til).",
"setting_image_viewer_original_subtitle": "Slå indlæsning af originalbillede i fuld størrelse til (stort!). Deaktiver for at reducere dataforbruget (både på netværket og for enhedscache).",
"setting_image_viewer_original_title": "Indlæs originalbillede",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_album_bottom_sheet_added": "Zu {album} hinzugefügt",
"add_to_album_bottom_sheet_already_exists": "Bereits in {album}",
"advanced_settings_tile_subtitle": "Erweiterte Benutzereinstellungen",
"advanced_settings_tile_title": "Sonstige",
"advanced_settings_troubleshooting_subtitle": "Aktiviere erweiterte Funktionen zur Fehlersuche",
"advanced_settings_troubleshooting_title": "Fehlersuche",
"album_info_card_backup_album_excluded": "AUSGESCHLOSSEN",
"album_info_card_backup_album_included": "EINGESCHLOSSEN",
"album_thumbnail_card_item": "1 Element",
"album_thumbnail_card_items": "{} Elemente",
"album_thumbnail_card_shared": " · Geteilt",
"album_thumbnail_owned": "Owned",
"album_thumbnail_shared_by": "Geteilt von {}",
"album_viewer_appbar_share_delete": "Album löschen",
"album_viewer_appbar_share_err_delete": "Album konnte nicht gelöscht werden",
"album_viewer_appbar_share_err_leave": "Album konnte nicht verlassen werden",
@@ -14,12 +20,16 @@
"album_viewer_appbar_share_leave": "Album verlassen",
"album_viewer_appbar_share_remove": "Entferne vom Album",
"album_viewer_page_share_add_users": "Nutzer hinzufügen",
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
"asset_list_layout_settings_group_by": "Group assets by",
"asset_list_layout_settings_group_by_month": "Month",
"asset_list_layout_settings_group_by_month_day": "Month + day",
"asset_list_settings_subtitle": "Photo grid layout settings",
"asset_list_settings_title": "Photo Grid",
"all_videos_page_title": "Videos",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archive ({})",
"asset_list_layout_settings_dynamic_layout_title": "Dynamisches Layout",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Gruppiere Elemente nach",
"asset_list_layout_settings_group_by_month": "Monat",
"asset_list_layout_settings_group_by_month_day": "Monat + Tag",
"asset_list_settings_subtitle": "Einstellungen für das Fotogitter-Layout",
"asset_list_settings_title": "Fotogitter",
"backup_album_selection_page_albums_device": "Alben auf dem Gerät ({})",
"backup_album_selection_page_albums_tap": "Tippen um einzuschließen, doppelt tippen um zu entfernen",
"backup_album_selection_page_assets_scatter": "Elemente können sich über mehrere Alben verteilen. Daher können diese vor der Sicherung eingeschlossen oder ausgeschlossen werden",
@@ -28,21 +38,21 @@
"backup_album_selection_page_total_assets": "Elemente",
"backup_all": "Alle",
"backup_background_service_backup_failed_message": "Failed to backup assets. Retrying…",
"backup_background_service_connection_failed_message": "Failed to connect to the server. Retrying…",
"backup_background_service_current_upload_notification": "Uploading {}",
"backup_background_service_default_notification": "Suche nach neuen assets…",
"backup_background_service_error_title": "Backup error",
"backup_background_service_in_progress_notification": "Backing up your assets…",
"backup_background_service_upload_failure_notification": "Failed to upload {}",
"backup_background_service_connection_failed_message": "Konnte keine Verbindung zum Server herstellen. Neuer Versuch...",
"backup_background_service_current_upload_notification": "Lädt {} hoch",
"backup_background_service_default_notification": "Suche nach neuen Elementen…",
"backup_background_service_error_title": "Fehler bei der Sicherung",
"backup_background_service_in_progress_notification": "Elemente werden gesichert...",
"backup_background_service_upload_failure_notification": "Konnte {} nicht hochladen",
"backup_controller_page_albums": "Gesicherte Alben",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_battery_info_link": "Show me how",
"backup_controller_page_background_app_refresh_disabled_content": "Aktiviere Hintergrundaktualisierungen in Einstellungen -> Allgemein -> Hintergrundaktualisierungen um Sicherungen im Hintergrund zu ermöglichen. ",
"backup_controller_page_background_app_refresh_disabled_title": "Hintergrundaktualisierungen sind deaktiviert.",
"backup_controller_page_background_app_refresh_enable_button_text": "Gehe zu Einstellungen",
"backup_controller_page_background_battery_info_link": "Zeige mir wie",
"backup_controller_page_background_battery_info_message": "For the best background backup experience, please disable any battery optimizations restricting background activity for Immich.\n\nSince this is device-specific, please lookup the required information for your device manufacturer.",
"backup_controller_page_background_battery_info_ok": "OK",
"backup_controller_page_background_battery_info_title": "Battery optimizations",
"backup_controller_page_background_charging": "Only while charging",
"backup_controller_page_background_battery_info_title": "Batterieoptimierungen",
"backup_controller_page_background_charging": "Nur während des Ladens",
"backup_controller_page_background_configure_error": "Failed to configure the background service",
"backup_controller_page_background_delay": "Delay new assets backup: {}",
"backup_controller_page_background_description": "Turn on the background service to automatically backup any new assets without needing to open the app",
@@ -50,7 +60,7 @@
"backup_controller_page_background_is_on": "Automatic background backup is on",
"backup_controller_page_background_turn_off": "Turn off background service",
"backup_controller_page_background_turn_on": "Turn on background service",
"backup_controller_page_background_wifi": "Only on WiFi",
"backup_controller_page_background_wifi": "Nur im WLAN",
"backup_controller_page_backup": "Sicherung",
"backup_controller_page_backup_selected": "Ausgewählt: ",
"backup_controller_page_backup_sub": "Gesicherte Fotos und Videos",
@@ -80,39 +90,44 @@
"backup_err_only_album": "Das einzige Album kann nicht entfernt werden",
"backup_info_card_assets": "Elemente",
"cache_settings_album_thumbnails": "Library page thumbnails ({} assets)",
"cache_settings_clear_cache_button": "Clear cache",
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
"cache_settings_clear_cache_button": "Zwischenspeicher löschen",
"cache_settings_clear_cache_button_title": "Löscht den Zwischenspeicher der App. Dies wird die Leistungsfähigkeit der App deutlich einschränken, bis der Zwischenspeicher wieder aufgebaut wurde.",
"cache_settings_image_cache_size": "Image cache size ({} assets)",
"cache_settings_statistics_album": "Library thumbnails",
"cache_settings_statistics_assets": "{} assets ({})",
"cache_settings_statistics_full": "Full images",
"cache_settings_statistics_shared": "Shared album thumbnails",
"cache_settings_statistics_thumbnail": "Vorschaubilder",
"cache_settings_statistics_title": "Cache usage",
"cache_settings_statistics_title": "Zwischenspeicher Nutzung",
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
"cache_settings_thumbnail_size": "Thumbnail cache size ({} assets)",
"cache_settings_title": "Caching Settings",
"change_password_form_confirm_password": "Confirm Password",
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
"change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password",
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"control_bottom_app_bar_add_to_album": "Add to album",
"control_bottom_app_bar_album_info": "{} items",
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
"cache_settings_title": "Zwischenspeicher Einstellungen",
"change_password_form_confirm_password": "Passwort bestätigen",
"change_password_form_description": "Hallo {firstName} {lastName}\n\nDas ist entweder das erste Mal dass du dich einloggst oder eine Anfrage zur Änderung deines Passwortes wurde gestellt. Bitte gebe das neue Passwort ein.",
"change_password_form_new_password": "Neues Passwort",
"change_password_form_password_mismatch": "Passwörter stimmen nicht überein",
"change_password_form_reenter_new_password": "Passwort erneut eingeben",
"common_add_to_album": "Zu Album hinzufügen",
"common_change_password": "Passwort ändern",
"common_create_new_album": "Erstelle ein neues Album",
"common_server_error": "Bitte überprüfe Deine Netzwerkverbindung und stelle sicher, dass die App und Server Versionen kompatibel sind.",
"common_shared": "Geteilt",
"control_bottom_app_bar_add_to_album": "Zu Album hinzufügen",
"control_bottom_app_bar_album_info": "{} Elemente",
"control_bottom_app_bar_album_info_shared": "{} Elemente · geteilt",
"control_bottom_app_bar_archive": "Archiv",
"control_bottom_app_bar_create_new_album": "Neues Album erstellen",
"control_bottom_app_bar_delete": "Löschen",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_favorite": "Favorit",
"control_bottom_app_bar_share": "Teilen",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Unbenannt",
"create_shared_album_page_create": "Erstellen",
"create_shared_album_page_share": "Teilen",
"create_shared_album_page_share_add_assets": "ELEMENTE HINZUFÜGEN",
"create_shared_album_page_share_select_photos": "Fotos auswählen",
"curated_location_page_title": "Orte",
"curated_object_page_title": "Dinge",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"date_format": "E d. LLL y • hh:mm",
@@ -120,83 +135,115 @@
"delete_dialog_cancel": "Abbrechen",
"delete_dialog_ok": "Löschen",
"delete_dialog_title": "Für immer löschen",
"description_input_hint_text": "Beschreibung hinzufügen...",
"description_input_submit_error": "Beschreibung konnte nicht geändert werden, bitte im Log für mehr Details nachsehen.",
"exif_bottom_sheet_description": "Beschreibung hinzufügen...",
"exif_bottom_sheet_details": "DETAILS",
"exif_bottom_sheet_location": "STANDORT",
"experimental_settings_new_asset_list_subtitle": "In Arbeit",
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
"experimental_settings_subtitle": "Use at your own risk!",
"experimental_settings_new_asset_list_title": "Experimentelle Fotogitter aktivieren",
"experimental_settings_subtitle": "Benutzung auf eigene Gefahr!",
"experimental_settings_title": "Experimentell",
"favorites_page_title": "Favorites",
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
"home_page_building_timeline": "Building the timeline",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Favoriten",
"home_page_add_to_album_conflicts": "{added} Elemente zu {album} hinzugefügt. {failed} Elemente sind bereits vorhanden.",
"home_page_add_to_album_err_local": "Kann lokale Elemente noch nicht zu Alben hinzufügen, überspringe",
"home_page_add_to_album_success": "{added} Elemente zu {album} hinzugefügt.",
"home_page_archive_err_local": "Kann lokale Elemente nicht archvieren, überspringe",
"home_page_building_timeline": "Zeitachse wird erstellt.",
"home_page_favorite_err_local": "Kann lokale Elemente noch nicht favorisieren, überspringe",
"home_page_first_time_notice": "Wenn dies das erste Mal ist dass Du Immich nutzt, stelle bitte sicher, dass mindestens ein Album zur Sicherung ausgewählt ist, sodass die Zeitachse mit Fotos und Videos gefüllt werden kann.",
"image_viewer_page_state_provider_download_error": "Fehler beim Herunterladen",
"image_viewer_page_state_provider_download_success": "Erfolgreich heruntergeladen",
"library_page_albums": "Alben",
"library_page_favorites": "Favorites",
"library_page_archive": "Archiv",
"library_page_device_albums": "Alben auf dem Gerät.",
"library_page_favorites": "Favoriten",
"library_page_new_album": "Neues Album",
"library_page_sharing": "Sharing",
"library_page_sort_created": "Most recently created",
"library_page_sort_title": "Album title",
"library_page_sharing": "Teilen",
"library_page_sort_created": "Zuletzt erstellt",
"library_page_sort_title": "Albumtitel",
"login_form_api_exception": "API Fehler. Bitte die Serveradresse überprüfen und erneut versuchen.",
"login_form_button_text": "Anmelden",
"login_form_email_hint": "deine@email.de",
"login_form_endpoint_hint": "http://deine-server-ip:port/api",
"login_form_endpoint_url": "Server URL",
"login_form_err_http": "Bitte gebe http:// oder https:// an",
"login_form_err_invalid_email": "Ungültige E-Mail",
"login_form_err_invalid_url": "Invalid URL",
"login_form_err_invalid_url": "Ungültige URL",
"login_form_err_leading_whitespace": "Führendes Leerzichen",
"login_form_err_trailing_whitespace": "Folgendes Leerzeichen",
"login_form_failed_get_oauth_server_config": "Error logging using OAuth, check server URL",
"login_form_failed_get_oauth_server_disable": "OAuth feature is not available on this server",
"login_form_failed_get_oauth_server_config": "Fehler beim Login per OAuth, Server-URL überprüfen",
"login_form_failed_get_oauth_server_disable": "OAuth-Funktion nicht verfügbar auf diesem Server.",
"login_form_failed_login": "Error logging you in, check server url, email and password",
"login_form_label_email": "E-Mail",
"login_form_label_password": "Passwort",
"login_form_next_button": "Weiter",
"login_form_password_hint": "password",
"login_form_save_login": "Angemeldet bleiben",
"login_form_server_empty": "Serveradresse eingeben.",
"login_form_server_error": "Konnte nicht mit Server verbinden.",
"monthly_title_text_date_format": "MMMM y",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"motion_photos_page_title": "Live Photos",
"notification_permission_dialog_cancel": "Abbrechen",
"notification_permission_dialog_content": "Um Benachrichtigungen zu aktivieren, navigiere zu Einstellungen und klicke \"Erlauben\"",
"notification_permission_dialog_settings": "Einstellungen",
"notification_permission_list_tile_content": "Erlaube Berechtigung für Benachrichtigungen",
"notification_permission_list_tile_enable_button": "Aktiviere Benachrichtigungen",
"notification_permission_list_tile_title": "Benachrichtigungs-Berechtigung",
"permission_onboarding_continue_anyway": "Trotzdem fortfahren",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Gehe zu Einstellungen",
"permission_onboarding_grant_permission": "Berechtigung erteilen",
"permission_onboarding_log_out": "Abmelden",
"permission_onboarding_permission_denied": "Berechtigungen verweigert. Um Immich zu benutzen, Zugriff auf Fotos und Videos in Einstellungen erlauben.",
"permission_onboarding_permission_granted": "Berechtigung erteilt! Du bist startklar.",
"permission_onboarding_permission_limited": "Berechtigungen unzureichend. Um Immich das Sichern von ganzen Sammlungen zu ermöglichen, muss der Zugriff auf alle Fotos und Videos in den Einstellungen erlaubt werden.",
"permission_onboarding_request": "Immich benötigt Berechtigung um auf deine Fotos und Videos zuzugreifen.",
"profile_drawer_app_logs": "Logs",
"profile_drawer_client_server_up_to_date": "App und Server sind aktuell",
"profile_drawer_settings": "Einstellungen",
"profile_drawer_sign_out": "Abmelden",
"recently_added_page_title": "Zuletzt hinzugefügt",
"search_bar_hint": "Durchsuche deine Fotos",
"search_page_categories": "Kategorien",
"search_page_favorites": "Favoriten",
"search_page_motion_photos": "Live Photos",
"search_page_no_objects": "Keine Objektinformationen verfügbar",
"search_page_no_places": "Keine Informationen über Orte verfügbar",
"search_page_places": "Orte",
"search_page_recently_added": "Zuletzt hinzugefügt",
"search_page_screenshots": "Bildschirmfotos",
"search_page_selfies": "Selfies",
"search_page_things": "Dinge",
"search_page_videos": "Videos",
"search_page_view_all_button": "Alle anzeigen",
"search_page_your_activity": "Deine Aktivität",
"search_result_page_new_search_hint": "Neue Suche",
"search_suggestion_list_smart_search_hint_1": "Intelligente Suche ist standardmäßig aktiviert; um nach Metadaten zu suchen Syntax benutzen",
"search_suggestion_list_smart_search_hint_2": "m:dein-suchbegriff",
"select_additional_user_for_sharing_page_suggestions": "Vorschläge",
"select_user_for_sharing_page_err_album": "Album konnte nicht erstellt werden",
"select_user_for_sharing_page_share_suggestions": "Suggestions",
"server_info_box_app_version": "App Version",
"server_info_box_server_version": "Server Version",
"setting_image_viewer_help": "The detail viewer loads the small thumbnail first, then loads the medium-size preview (if enabled), finally loads the original (if enabled).",
"setting_image_viewer_original_subtitle": "Enable to load the original full-resolution image (large!). Disable to reduce data usage (both network and on device cache).",
"setting_image_viewer_original_title": "Load original image",
"setting_image_viewer_preview_subtitle": "Enable to load a medium-resolution image. Disable to either directly load the original or only use the thumbnail.",
"setting_image_viewer_preview_title": "Load preview image",
"setting_image_viewer_help": "Der Detailviewer lädt zuerst die kleine Miniaturansicht, dann die Vorschau in mittlerer Größe (falls aktiviert) und schließlich das Original (falls aktiviert).",
"setting_image_viewer_original_subtitle": "Aktivieren, um das Originalbild in voller Auflösung (groß!) zu laden. Deaktivieren, um den Datenverbrauch zu reduzieren (sowohl im Netzwerk als auch im Gerätespeicher).",
"setting_image_viewer_original_title": "Original laden",
"setting_image_viewer_preview_subtitle": "Aktivieren, um ein Bild mit mittlerer Auflösung zu laden. Deaktivieren, um entweder das Original direkt zu laden oder nur die Miniaturansicht zu verwenden.",
"setting_image_viewer_preview_title": "Vorschaubild laden",
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
"setting_notifications_notify_hours": "{} hours",
"setting_notifications_notify_immediately": "immediately",
"setting_notifications_notify_minutes": "{} minutes",
"setting_notifications_notify_never": "never",
"setting_notifications_notify_seconds": "{} seconds",
"setting_notifications_notify_hours": "{} Stunden",
"setting_notifications_notify_immediately": "sofort",
"setting_notifications_notify_minutes": "{} Minuten",
"setting_notifications_notify_never": "niemals",
"setting_notifications_notify_seconds": "{} Sekunden",
"setting_notifications_single_progress_subtitle": "Detaillierte Upload Informationen für jedes Element.",
"setting_notifications_single_progress_title": "Show background backup detail progress",
"setting_notifications_single_progress_title": "Zeige Hintergrund-Sicherungs Detailfortschritt",
"setting_notifications_subtitle": "Adjust your notification preferences",
"setting_notifications_title": "Notifications",
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
"setting_notifications_total_progress_title": "Show background backup total progress",
"setting_notifications_title": "Benachrichtigungen",
"setting_notifications_total_progress_subtitle": "Gesamter Upload-Fortschritt (abgeschlossen/Anzahl Elemente)",
"setting_notifications_total_progress_title": "Zeige Hintergrundsicherungsfortschritt",
"setting_pages_app_bar_settings": "Einstellungen",
"settings_require_restart": "Bitte starte Immich neu, um diese Einstellung anzuwenden.",
"share_add": "Hinzufügen",
@@ -214,8 +261,8 @@
"tab_controller_nav_photos": "Fotos",
"tab_controller_nav_search": "Suche",
"tab_controller_nav_sharing": "Teilen",
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})",
"theme_setting_asset_list_storage_indicator_title": "Zeige Sicherungsstatus auf Miniaturbild",
"theme_setting_asset_list_tiles_per_row_title": "Anzahl der Elemente pro Reihe ({})",
"theme_setting_dark_mode_switch": "Dunkler Modus",
"theme_setting_image_viewer_quality_subtitle": "Einstellen der Qualität des Detailbildbetrachters",
"theme_setting_image_viewer_quality_title": "Qualität des Bildbetrachters",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"advanced_settings_tile_subtitle": "Advanced user's settings",
"advanced_settings_tile_title": "Advanced",
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
"advanced_settings_troubleshooting_title": "Troubleshooting",
"album_info_card_backup_album_excluded": "EXCLUDED",
"album_info_card_backup_album_included": "INCLUDED",
"album_thumbnail_card_item": "1 item",
"album_thumbnail_card_items": "{} items",
"album_thumbnail_card_shared": " · Shared",
"album_thumbnail_owned": "Owned",
"album_thumbnail_shared_by": "Shared by {}",
"album_viewer_appbar_share_delete": "Delete album",
"album_viewer_appbar_share_err_delete": "Failed to delete album",
"album_viewer_appbar_share_err_leave": "Failed to leave album",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Leave album",
"album_viewer_appbar_share_remove": "Remove from album",
"album_viewer_page_share_add_users": "Add users",
"all_videos_page_title": "Videos",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archive ({})",
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Group assets by",
"asset_list_layout_settings_group_by_month": "Month",
"asset_list_layout_settings_group_by_month_day": "Month + day",
@@ -100,20 +110,24 @@
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
"common_shared": "Shared",
"control_bottom_app_bar_add_to_album": "Add to album",
"control_bottom_app_bar_album_info": "{} items",
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
"control_bottom_app_bar_archive": "Archive",
"control_bottom_app_bar_create_new_album": "Create new album",
"control_bottom_app_bar_delete": "Delete",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_share": "Share",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Untitled",
"create_shared_album_page_create": "Create",
"create_shared_album_page_share": "Share",
"create_shared_album_page_share_add_assets": "ADD ASSETS",
"create_shared_album_page_share_select_photos": "Select Photos",
"curated_location_page_title": "Places",
"curated_object_page_title": "Things",
"daily_title_text_date": "E, MMM dd",
"daily_title_text_date_year": "E, MMM dd, yyyy",
"date_format": "E, LLL d, y • h:mm a",
@@ -121,6 +135,8 @@
"delete_dialog_cancel": "Cancel",
"delete_dialog_ok": "Delete",
"delete_dialog_title": "Delete Permanently",
"description_input_hint_text": "Add description...",
"description_input_submit_error": "Error updating description, check the log for more details",
"exif_bottom_sheet_description": "Add Description...",
"exif_bottom_sheet_details": "DETAILS",
"exif_bottom_sheet_location": "LOCATION",
@@ -128,22 +144,26 @@
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
"experimental_settings_subtitle": "Use at your own risk!",
"experimental_settings_title": "Experimental",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Favorites",
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
"home_page_building_timeline": "Building the timeline",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"library_page_albums": "Albums",
"library_page_archive": "Archive",
"library_page_device_albums": "Albums on Device",
"library_page_favorites": "Favorites",
"library_page_new_album": "New album",
"library_page_sharing": "Sharing",
"library_page_sort_created": "Most recently created",
"library_page_sort_title": "Album title",
"library_page_device_albums": "Albums on Device",
"login_form_api_exception": "API exception. Please check the server URL and try again.",
"login_form_button_text": "Login",
"login_form_email_hint": "youremail@email.com",
"login_form_endpoint_hint": "http://your-server-ip:port/api",
@@ -158,28 +178,50 @@
"login_form_failed_login": "Error logging you in, check server URL, email and password",
"login_form_label_email": "Email",
"login_form_label_password": "Password",
"login_form_password_hint": "Password",
"login_form_next_button": "Next",
"login_form_password_hint": "password",
"login_form_save_login": "Stay logged in",
"login_form_server_empty": "Enter a server URL.",
"login_form_server_error": "Could not connect to server.",
"login_form_api_exception": "API exception. Please check the server URL and try again.",
"monthly_title_text_date_format": "MMMM y",
"motion_photos_page_title": "Motion Photos",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"permission_onboarding_continue_anyway": "Continue anyway",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Go to settings",
"permission_onboarding_grant_permission": "Grant permission",
"permission_onboarding_log_out": "Log out",
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
"profile_drawer_app_logs": "Logs",
"profile_drawer_client_server_up_to_date": "Client and Server are up-to-date",
"profile_drawer_settings": "Settings",
"profile_drawer_sign_out": "Sign Out",
"recently_added_page_title": "Recently Added",
"search_bar_hint": "Search your photos",
"search_page_categories": "Categories",
"search_page_favorites": "Favorites",
"search_page_motion_photos": "Motion Photos",
"search_page_no_objects": "No Objects Info Available",
"search_page_no_places": "No Places Info Available",
"search_page_places": "Places",
"search_page_recently_added": "Recently added",
"search_page_screenshots": "Screenshots",
"search_page_selfies": "Selfies",
"search_page_things": "Things",
"search_page_videos": "Videos",
"search_page_view_all_button": "View all",
"search_page_your_activity": "Your activity",
"search_result_page_new_search_hint": "New Search",
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
"select_additional_user_for_sharing_page_suggestions": "Suggestions",
"select_user_for_sharing_page_err_album": "Failed to create album",
"select_user_for_sharing_page_share_suggestions": "Suggestions",
@@ -234,17 +276,5 @@
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
"version_announcement_overlay_text_2": "please take your time to visit the ",
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
"permission_onboarding_grant_permission": "Grant permission",
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Go to settings",
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
"permission_onboarding_continue_anyway": "Continue anyway",
"permission_onboarding_log_out": "Log out",
"login_form_next_button": "Next",
"album_thumbnail_shared_by": "Shared by {}",
"album_thumbnail_owned": "Owned"
}
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89"
}

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"advanced_settings_tile_subtitle": "Advanced user's settings",
"advanced_settings_tile_title": "Advanced",
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
"advanced_settings_troubleshooting_title": "Troubleshooting",
"album_info_card_backup_album_excluded": "EXCLUIDOS",
"album_info_card_backup_album_included": "INCLUIDOS",
"album_thumbnail_card_item": "1 item",
"album_thumbnail_card_items": "{} items",
"album_thumbnail_card_shared": " · Shared",
"album_thumbnail_owned": "Owned",
"album_thumbnail_shared_by": "Shared by {}",
"album_viewer_appbar_share_delete": "Eliminar álbum ",
"album_viewer_appbar_share_err_delete": "No ha podido eliminar el álbum",
"album_viewer_appbar_share_err_leave": "No ha podido dejar el álbum",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Abandonar álbum ",
"album_viewer_appbar_share_remove": "Eliminar del álbum ",
"album_viewer_page_share_add_users": "Añadir usuarios",
"all_videos_page_title": "Videos",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archive ({})",
"asset_list_layout_settings_dynamic_layout_title": "Disposición dinámica",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Agrupar recursos por",
"asset_list_layout_settings_group_by_month": "Mes",
"asset_list_layout_settings_group_by_month_day": "Mes + día",
@@ -100,19 +110,24 @@
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
"common_shared": "Shared",
"control_bottom_app_bar_add_to_album": "Añadir al álbum",
"control_bottom_app_bar_album_info": "{} elementos",
"control_bottom_app_bar_album_info_shared": "{} elementos · Compartido",
"control_bottom_app_bar_archive": "Archive",
"control_bottom_app_bar_create_new_album": "Crear nuevo álbum",
"control_bottom_app_bar_delete": "Eliminar",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_share": "Share",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Untitled",
"create_shared_album_page_create": "Create",
"create_shared_album_page_share": "Compartir",
"create_shared_album_page_share_add_assets": "AÑADIR ACTIVOS",
"create_shared_album_page_share_select_photos": "Seleccionar Fotos",
"curated_location_page_title": "Places",
"curated_object_page_title": "Things",
"daily_title_text_date": "E dd, MMM",
"daily_title_text_date_year": "E dd de MMM, yyyy",
"date_format": "E d, LLL y • h:mm a",
@@ -120,6 +135,8 @@
"delete_dialog_cancel": "Cancelar",
"delete_dialog_ok": "Eliminar",
"delete_dialog_title": "Eliminar Permanentemente",
"description_input_hint_text": "Add description...",
"description_input_submit_error": "Error updating description, check the log for more details",
"exif_bottom_sheet_description": "Añadir Descripción...",
"exif_bottom_sheet_details": "DETALLES",
"exif_bottom_sheet_location": "LOCALZACIÓN",
@@ -127,21 +144,26 @@
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
"experimental_settings_subtitle": "Use at your own risk!",
"experimental_settings_title": "Experimental",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Favoritos",
"home_page_add_to_album_conflicts": "Añadidos {added} elementos al álbum {album}. {failed} elementos ya están añadidos.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_success": "Añadidos {added} elementos al álbum {album}.",
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
"home_page_building_timeline": "Construyendo la línea de tiempo",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_first_time_notice": "Si esta es la primera vez que usas la app, por favor, asegúrate de elegir un álbum de respaldo para que la línea de tiempo pueda cargar fotos y videos en los álbumes.",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"library_page_albums": "Albums",
"library_page_archive": "Archive",
"library_page_device_albums": "Albums on Device",
"library_page_favorites": "Favoritos",
"library_page_new_album": "New album",
"library_page_sharing": "Compartiendo",
"library_page_sort_created": "Creado más recientemente",
"library_page_sort_title": "Título del álbum",
"login_form_api_exception": "API exception. Please check the server URL and try again.",
"login_form_button_text": "Iniciar Sesión",
"login_form_email_hint": "tucorreo@correo.com",
"login_form_endpoint_hint": "http://tu-ip-de-servidor:puerto/api",
@@ -156,25 +178,50 @@
"login_form_failed_login": "Error logging you in, check server URL, email and password",
"login_form_label_email": "Correo",
"login_form_label_password": "Contraseña",
"login_form_next_button": "Next",
"login_form_password_hint": "contraseña",
"login_form_save_login": "Mantener la sesión iniciada",
"login_form_server_empty": "Enter a server URL.",
"login_form_server_error": "Could not connect to server.",
"monthly_title_text_date_format": "MMMM y",
"motion_photos_page_title": "Motion Photos",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"permission_onboarding_continue_anyway": "Continue anyway",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Go to settings",
"permission_onboarding_grant_permission": "Grant permission",
"permission_onboarding_log_out": "Log out",
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
"profile_drawer_app_logs": "Logs",
"profile_drawer_client_server_up_to_date": "El Cliente y el Servidor están actualizados",
"profile_drawer_settings": "Settings",
"profile_drawer_sign_out": "Cerrar Sesión",
"recently_added_page_title": "Recently Added",
"search_bar_hint": "Busca tus fotos",
"search_page_categories": "Categories",
"search_page_favorites": "Favorites",
"search_page_motion_photos": "Motion Photos",
"search_page_no_objects": "No Objects Info Available",
"search_page_no_places": "No hay información de lugares disponibles",
"search_page_places": "Lugares",
"search_page_recently_added": "Recently added",
"search_page_screenshots": "Screenshots",
"search_page_selfies": "Selfies",
"search_page_things": "Cosas",
"search_page_videos": "Videos",
"search_page_view_all_button": "View all",
"search_page_your_activity": "Your activity",
"search_result_page_new_search_hint": "Nueva Busqueda",
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
"select_additional_user_for_sharing_page_suggestions": "Sugerencias",
"select_user_for_sharing_page_err_album": "Fallo al crear el álbum",
"select_user_for_sharing_page_share_suggestions": "Suggestions",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_album_bottom_sheet_added": "Lisätty albumiin {album}",
"add_to_album_bottom_sheet_already_exists": "Kohde on jo albumissa {album}",
"advanced_settings_tile_subtitle": "Edistyneen käyttäjän asetukset",
"advanced_settings_tile_title": "Edistyneet",
"advanced_settings_troubleshooting_subtitle": "Kytke vianetsinnän lisäominaisuudet päälle",
"advanced_settings_troubleshooting_title": "Vianetsintä",
"album_info_card_backup_album_excluded": "JÄTETTY POIS",
"album_info_card_backup_album_included": "SISÄLLYTETTY",
"album_thumbnail_card_item": "1 kohde",
"album_thumbnail_card_items": "{} kohdetta",
"album_thumbnail_card_shared": "Jaettu",
"album_thumbnail_owned": "Omistettu",
"album_thumbnail_shared_by": "Jakanut {}",
"album_viewer_appbar_share_delete": "Poista albumi",
"album_viewer_appbar_share_err_delete": "Albumin poistaminen epäonnistui",
"album_viewer_appbar_share_err_leave": "Albumista poistuminen epäonnistui",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Poistu albumista",
"album_viewer_appbar_share_remove": "Poista albumista",
"album_viewer_page_share_add_users": "Lisää käyttäjiä",
"all_videos_page_title": "Videot",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Arkisto ({})",
"asset_list_layout_settings_dynamic_layout_title": "Dynaaminen asetelma",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Ryhmittele",
"asset_list_layout_settings_group_by_month": "Kuukauden mukaan",
"asset_list_layout_settings_group_by_month_day": "Kuukauden ja päivän mukaan",
@@ -35,9 +45,9 @@
"backup_background_service_in_progress_notification": "Varmuuskopioidaan kohteita...",
"backup_background_service_upload_failure_notification": "Lähetys palvelimelle epäonnistui {}",
"backup_controller_page_albums": "Varmuuskopioi albumit",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_app_refresh_disabled_content": "Salli sovelluksen päivittäminen taustalla suorittaaksesi varmuuskopiointia taustalla: Asetukset > Yleiset > Appien päivitys taustalla",
"backup_controller_page_background_app_refresh_disabled_title": "Sovelluksen päivittäminen taustalla on pois päältä",
"backup_controller_page_background_app_refresh_enable_button_text": "Siirry asetuksiin",
"backup_controller_page_background_battery_info_link": "Näytä minulle miten",
"backup_controller_page_background_battery_info_message": "Kytke pois päältä kaikki Immichin taustatyöskentelyyn liittyvät akun optimoinnit, jotta varmistat taustavarmuuskopioinnin parhaan mahdollisen toiminnan.\n\nKoska tämä on laitekohtaista, tarkista tarvittavat toimet laitevalmistajan ohjeista.",
"backup_controller_page_background_battery_info_ok": "OK",
@@ -92,27 +102,32 @@
"cache_settings_subtitle": "Hallitse Immich-mobiilisovelluksen välimuistin käyttöä",
"cache_settings_thumbnail_size": "Esikatselukuvien välimuistin koko ({} kohdetta)",
"cache_settings_title": "Välimuistin asetukset",
"change_password_form_confirm_password": "Confirm Password",
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
"change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password",
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"change_password_form_confirm_password": "Vahvista salasana",
"change_password_form_description": "Hei {firstName} {lastName},\n\nTämä on joko ensimmäinen kirjautumisesi järjestelmään tai salasanan vaihtaminen vaihtaminen on pakotettu. Ole hyvä ja syötä uusi salasana alle.",
"change_password_form_new_password": "Uusi salasana",
"change_password_form_password_mismatch": "Salasanat eivät täsmää",
"change_password_form_reenter_new_password": "Uusi salasana uudelleen",
"common_add_to_album": "Lisää albumiin",
"common_change_password": "Vaihda salasana",
"common_create_new_album": "Luo uusi albumi",
"common_server_error": "Tarkista internet-yhteytesi. Varmista että palvelin on saavutettavissa ja sovellus-/palvelinversiot ovat yhteensopivia.",
"common_shared": "Jaettu",
"control_bottom_app_bar_add_to_album": "Lisää albumiin",
"control_bottom_app_bar_album_info": "{} kohdetta",
"control_bottom_app_bar_album_info_shared": "{} kohdetta · Jaettu",
"control_bottom_app_bar_archive": "Arkistoi",
"control_bottom_app_bar_create_new_album": "Luo uusi albumi",
"control_bottom_app_bar_delete": "Poista",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_favorite": "Suosikki",
"control_bottom_app_bar_share": "Jaa",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Nimetön",
"create_shared_album_page_create": "Luo",
"create_shared_album_page_share": "Jaa",
"create_shared_album_page_share_add_assets": "LISÄÄ KOHTEITA",
"create_shared_album_page_share_select_photos": "Valitse kuvat",
"curated_location_page_title": "Paikat",
"curated_object_page_title": "Asiat",
"daily_title_text_date": "E, MMM dd",
"daily_title_text_date_year": "E, MMM dd, yyyy",
"date_format": "E, LLL d, y • h:mm a",
@@ -120,6 +135,8 @@
"delete_dialog_cancel": "Peruuta",
"delete_dialog_ok": "Poista",
"delete_dialog_title": "Poista pysyvästi",
"description_input_hint_text": "Lisää kuvaus...",
"description_input_submit_error": "Virhe kuvauksen päivittämisessä, tarkista lisätiedot lokista",
"exif_bottom_sheet_description": "Lisää kuvaus…",
"exif_bottom_sheet_details": "TIEDOT",
"exif_bottom_sheet_location": "SIJAINTI",
@@ -127,21 +144,26 @@
"experimental_settings_new_asset_list_title": "Ota käyttöön kokeellinen kuvaruudukko",
"experimental_settings_subtitle": "Käyttö omalla vastuulla!",
"experimental_settings_title": "Kokeellinen",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Suosikit",
"home_page_add_to_album_conflicts": "Lisätty {added} kohdetta albumiin {album}. {failed} kohdetta on jo albumissa.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_err_local": "Paikallisten kohteiden lisääminen albumeihin ei ole mahdollista, ohitetaan",
"home_page_add_to_album_success": "Lisätty {added} kohdetta albumiin {album}.",
"home_page_archive_err_local": "Paikallisten kohteiden arkistointi ei ole mahdollista, ohitetaan",
"home_page_building_timeline": "Rakennetaan aikajanaa",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_favorite_err_local": "Paikallisten kohteiden lisääminen suosikkeihin ei ole mahdollista, ohitetaan",
"home_page_first_time_notice": "Jos käytät sovellusta ensimmäistä kertaa, muista valita varmuuskopioitavat albumi(t), jotta aikajanalla voi olla kuvia ja videoita.",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"image_viewer_page_state_provider_download_error": "Lataus epäonnistui",
"image_viewer_page_state_provider_download_success": "Lataus onnistui",
"library_page_albums": "Albumit",
"library_page_archive": "Arkisto",
"library_page_device_albums": "Laitteen albumit",
"library_page_favorites": "Suosikit",
"library_page_new_album": "Uusi albumi",
"library_page_sharing": "Jakaminen",
"library_page_sort_created": "Viimeisin luotu",
"library_page_sort_title": "Albumin otsikko",
"login_form_api_exception": "API-virhe. Tarkista palvelimen URL-osoite ja yritä uudelleen.",
"login_form_button_text": "Kirjaudu",
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti/api",
@@ -156,30 +178,55 @@
"login_form_failed_login": "Virhe kirjautumisessa. Tarkista palvelimen URL, sähköpostiosoite ja salasana.",
"login_form_label_email": "Sähköposti",
"login_form_label_password": "Salasana",
"login_form_next_button": "Seuraava",
"login_form_password_hint": "salasana",
"login_form_save_login": "Pysy kirjautuneena",
"login_form_server_empty": "Syötä palvelimen URL-osoite.",
"login_form_server_error": "Palvelimeen ei saatu yhteyttä.",
"monthly_title_text_date_format": "MMMM y",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"motion_photos_page_title": "Liikekuvat",
"notification_permission_dialog_cancel": "Peruuta",
"notification_permission_dialog_content": "Ottaaksesi ilmoitukset käyttöön, siirry asetuksiin ja valitse 'salli'.",
"notification_permission_dialog_settings": "Asetukset",
"notification_permission_list_tile_content": "Myönnä käyttöoikeus ottaaksesi ilmoitukset käyttöön.",
"notification_permission_list_tile_enable_button": "Ota ilmoitukset käyttöön",
"notification_permission_list_tile_title": "Ilmoitusten käyttöoikeus",
"permission_onboarding_continue_anyway": "Jatka silti",
"permission_onboarding_get_started": "Aloittaminen",
"permission_onboarding_go_to_settings": "Siirry asetuksiin",
"permission_onboarding_grant_permission": "Käyttöoikeuden myöntäminen",
"permission_onboarding_log_out": "Kirjaudu ulos",
"permission_onboarding_permission_denied": "Kielletty käyttöoikeus. Käyttääksesi Immichiä, myönnä oikeus kuviin ja videoihin asetuksista.",
"permission_onboarding_permission_granted": "Käyttöoikeus myönnetty! Kaikki valmista.",
"permission_onboarding_permission_limited": "Rajoitettu käyttöoikeus. Salliaksesi Immichin varmuuskopioida ja hallita koko kuvakirjastoasi, myönnä oikeus kuviin ja videoihin asetuksista.",
"permission_onboarding_request": "Immich vaatii käyttöoikeuden kuvien ja videoiden käyttämiseen.",
"profile_drawer_app_logs": "Lokit",
"profile_drawer_client_server_up_to_date": "Asiakassovellus ja palvelin ovat ajan tasalla",
"profile_drawer_settings": "Asetukset",
"profile_drawer_sign_out": "Kirjaudu ulos",
"recently_added_page_title": "Viimeksi lisätyt",
"search_bar_hint": "Etsi kuvia",
"search_page_categories": "Kategoriat",
"search_page_favorites": "Suosikit",
"search_page_motion_photos": "Liikekuvat",
"search_page_no_objects": "Objektitietoja ei ole saatavilla",
"search_page_no_places": "Paikkatietoja ei ole saatavilla",
"search_page_places": "Paikat",
"search_page_recently_added": "Viimeksi lisätyt",
"search_page_screenshots": "Näyttökuvat",
"search_page_selfies": "Selfiet",
"search_page_things": "Asiat",
"search_page_videos": "Videot",
"search_page_view_all_button": "Näytä kaikki",
"search_page_your_activity": "Toimintasi",
"search_result_page_new_search_hint": "Uusi haku",
"search_suggestion_list_smart_search_hint_1": "Älykäs haku on oletuksena käytössä. Käytä metatietojen etsimiseen syntaksia",
"search_suggestion_list_smart_search_hint_2": "m:hakusana",
"select_additional_user_for_sharing_page_suggestions": "Ehdotukset",
"select_user_for_sharing_page_err_album": "Albumin luonti epäonnistui",
"select_user_for_sharing_page_share_suggestions": "Ehdotukset",
"server_info_box_app_version": "App Version",
"server_info_box_server_version": "Server Version",
"server_info_box_app_version": "Sovelluksen versio",
"server_info_box_server_version": "Palvelimen versio",
"setting_image_viewer_help": "Sovellus lataa ensin pienen esikatselukuvan, toisena keskitarkkuuksisen kuvan (jos käytössä) ja kolmantena alkuperäisen täysitarkkuuksisen kuvan (jos käytössä)",
"setting_image_viewer_original_subtitle": "Ota käyttöön ladataksesi alkuperäinen täysitarkkuuksinen kuva (suuri!). Poista käytöstä vähentääksesi datan käyttöä (sekä verkossa että laitteen välimuistissa).",
"setting_image_viewer_original_title": "Lataa alkuperäinen kuva",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_album_bottom_sheet_added": "Ajouté à {album}",
"add_to_album_bottom_sheet_already_exists": "Déjà dans {album}",
"advanced_settings_tile_subtitle": "Advanced user's settings",
"advanced_settings_tile_title": "Advanced",
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
"advanced_settings_troubleshooting_title": "Troubleshooting",
"album_info_card_backup_album_excluded": "EXCLU",
"album_info_card_backup_album_included": "INCLUS",
"album_thumbnail_card_item": "1 élément",
"album_thumbnail_card_items": "{} éléments",
"album_thumbnail_card_shared": " · Partagé",
"album_thumbnail_owned": "Owned",
"album_thumbnail_shared_by": "Shared by {}",
"album_viewer_appbar_share_delete": "Supprimer l'album",
"album_viewer_appbar_share_err_delete": "Échec de la suppression de l'album",
"album_viewer_appbar_share_err_leave": "Impossible de quitter l'album",
@@ -14,7 +20,11 @@
"album_viewer_appbar_share_leave": "Quitter l'album",
"album_viewer_appbar_share_remove": "Retirer de l'album",
"album_viewer_page_share_add_users": "Ajouter des utilisateurs",
"all_videos_page_title": "Videos",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archive ({})",
"asset_list_layout_settings_dynamic_layout_title": "Affichage dynamique",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Grouper les éléments par",
"asset_list_layout_settings_group_by_month": "Mois",
"asset_list_layout_settings_group_by_month_day": "Mois + jour",
@@ -35,9 +45,9 @@
"backup_background_service_in_progress_notification": "Sauvegarde de vos éléments...",
"backup_background_service_upload_failure_notification": "Impossible de transférer {}",
"backup_controller_page_albums": "Sauvegarder les albums",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_app_refresh_disabled_content": "Activez le rafraîchissement de l'application en arrière-plan dans Paramètres > Général > Rafraîchissement de l'application en arrière-plan afin d'utiliser la sauvegarde en arrière-plan.",
"backup_controller_page_background_app_refresh_disabled_title": "Rafraîchissement de l'application en arrière-plan désactivé",
"backup_controller_page_background_app_refresh_enable_button_text": "Aller aux paramètres",
"backup_controller_page_background_battery_info_link": "Montrez-moi comment",
"backup_controller_page_background_battery_info_message": "Pour une expérience optimale de la sauvegarde en arrière-plan, veuillez désactiver toute optimisation de la batterie limitant l'activité en arrière-plan pour Immich.\n\nÉtant donné que cela est spécifique à chaque appareil, veuillez consulter les informations requises pour le fabricant de votre appareil.",
"backup_controller_page_background_battery_info_ok": "OK",
@@ -92,27 +102,32 @@
"cache_settings_subtitle": "Contrôler le comportement de mise en cache de l'application mobile Immich",
"cache_settings_thumbnail_size": "Taille du cache des miniatures ({} éléments)",
"cache_settings_title": "Paramètres de mise en cache",
"change_password_form_confirm_password": "Confirm Password",
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
"change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password",
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"change_password_form_confirm_password": "Confirmez le mot de passe",
"change_password_form_description": "Bonjour {firstName} {lastName},\n\nC'est la première fois que vous vous connectez au système ou vous avez demandé à changer votre mot de passe. Veuillez saisir le nouveau mot de passe ci-dessous.",
"change_password_form_new_password": "Nouveau mot de passe",
"change_password_form_password_mismatch": "Les mots de passe ne correspondent pas",
"change_password_form_reenter_new_password": "Saisissez à nouveau le nouveau mot de passe",
"common_add_to_album": "Ajouter à l'album",
"common_change_password": "Modifier le mot de passe",
"common_create_new_album": "Créer un nouvel album",
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
"common_shared": "Partagé",
"control_bottom_app_bar_add_to_album": "Ajouter à l'album",
"control_bottom_app_bar_album_info": "{} éléments",
"control_bottom_app_bar_album_info_shared": "{} éléments - Partagés",
"control_bottom_app_bar_archive": "Archive",
"control_bottom_app_bar_create_new_album": "Créer un nouvel album",
"control_bottom_app_bar_delete": "Supprimer",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_favorite": "Favoris",
"control_bottom_app_bar_share": "Partager",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Sans titre",
"create_shared_album_page_create": "Créer",
"create_shared_album_page_share": "Partager",
"create_shared_album_page_share_add_assets": "AJOUTER DES ÉLÉMENTS",
"create_shared_album_page_share_select_photos": "Sélectionner les photos",
"curated_location_page_title": "Places",
"curated_object_page_title": "Things",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"date_format": "E, LLL d, y • h:mm a",
@@ -120,28 +135,35 @@
"delete_dialog_cancel": "Annuler",
"delete_dialog_ok": "Supprimer",
"delete_dialog_title": "Supprimer définitivement",
"description_input_hint_text": "Add description...",
"description_input_submit_error": "Error updating description, check the log for more details",
"exif_bottom_sheet_description": "Ajouter une description...",
"exif_bottom_sheet_details": "DÉTAILS",
"exif_bottom_sheet_location": "LOCALISATION",
"experimental_settings_new_asset_list_subtitle": "En cours de développement",
"experimental_settings_new_asset_list_title": "Activez la grille de photos expérimentale",
"experimental_settings_new_asset_list_title": "Activer la grille de photos expérimentale",
"experimental_settings_subtitle": "Utilisez à vos dépends !",
"experimental_settings_title": "Expérimental",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Favoris",
"home_page_add_to_album_conflicts": "{added} éléments ajoutés à l'album {album}. Les éléments {failed} sont déjà dans l'album.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_err_local": "Impossible d'ajouter des éléments locaux aux albums pour le moment, étape ignorée",
"home_page_add_to_album_success": "{added} éléments ajoutés à l'album {album}.",
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
"home_page_building_timeline": "Construction de la chronologie",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_favorite_err_local": "Impossible d'ajouter des éléments locaux aux favoris pour le moment, étape ignorée",
"home_page_first_time_notice": "Si c'est la première fois que vous utilisez l'application, veillez à choisir un ou plusieurs albums de sauvegarde afin que la chronologie puisse alimenter les photos et les vidéos de cet ou ces albums.",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"image_viewer_page_state_provider_download_error": "Erreur de téléchargement",
"image_viewer_page_state_provider_download_success": "Téléchargement réussi",
"library_page_albums": "Albums",
"library_page_archive": "Archive",
"library_page_device_albums": "Albums on Device",
"library_page_favorites": "Favoris",
"library_page_new_album": "Nouvel album",
"library_page_sharing": "Partage",
"library_page_sort_created": "Créations les plus récentes",
"library_page_sort_title": "Titre de l'album",
"login_form_api_exception": "API exception. Please check the server URL and try again.",
"login_form_button_text": "Connexion",
"login_form_email_hint": "votreemail@email.com",
"login_form_endpoint_hint": "http://adresse-ip-serveur:port/api",
@@ -156,30 +178,55 @@
"login_form_failed_login": "Erreur de connexion, vérifiez l'url du serveur, l'email et le mot de passe",
"login_form_label_email": "Email",
"login_form_label_password": "Mot de passe",
"login_form_next_button": "Next",
"login_form_password_hint": "mot de passe",
"login_form_save_login": "Rester connecté",
"login_form_server_empty": "Enter a server URL.",
"login_form_server_error": "Could not connect to server.",
"monthly_title_text_date_format": "MMMM y",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"motion_photos_page_title": "Motion Photos",
"notification_permission_dialog_cancel": "Annuler",
"notification_permission_dialog_content": "Pour activer les notifications, allez dans Paramètres et sélectionnez Autoriser.",
"notification_permission_dialog_settings": "Paramètres",
"notification_permission_list_tile_content": "Accordez la permission d'activer les notifications.",
"notification_permission_list_tile_enable_button": "Activer les notifications",
"notification_permission_list_tile_title": "Permission de notification",
"permission_onboarding_continue_anyway": "Continue anyway",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Go to settings",
"permission_onboarding_grant_permission": "Grant permission",
"permission_onboarding_log_out": "Log out",
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
"profile_drawer_app_logs": "Journaux",
"profile_drawer_client_server_up_to_date": "Le client et le serveur sont à jour",
"profile_drawer_settings": "Paramètres",
"profile_drawer_sign_out": "Se déconnecter",
"recently_added_page_title": "Recently Added",
"search_bar_hint": "Rechercher vos photos",
"search_page_categories": "Categories",
"search_page_favorites": "Favorites",
"search_page_motion_photos": "Motion Photos",
"search_page_no_objects": "Aucune information disponible sur les objets",
"search_page_no_places": "Aucune information disponible sur la localisation",
"search_page_places": "Lieux",
"search_page_recently_added": "Recently added",
"search_page_screenshots": "Screenshots",
"search_page_selfies": "Selfies",
"search_page_things": "Objets",
"search_page_videos": "Videos",
"search_page_view_all_button": "View all",
"search_page_your_activity": "Your activity",
"search_result_page_new_search_hint": "Nouvelle recherche",
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
"select_additional_user_for_sharing_page_suggestions": "Suggestions",
"select_user_for_sharing_page_err_album": "Échec de la création de l'album",
"select_user_for_sharing_page_share_suggestions": "Suggestions",
"server_info_box_app_version": "App Version",
"server_info_box_server_version": "Server Version",
"server_info_box_app_version": "Version de l'application",
"server_info_box_server_version": "Version du serveur",
"setting_image_viewer_help": "Le visualiseur de détails charge d'abord la petite miniature, puis l'aperçu de taille moyenne (s'il est activé), enfin l'original (s'il est activé).",
"setting_image_viewer_original_subtitle": "Activez cette option pour charger l'image en résolution originale (volumineux !). Désactiver pour réduire l'utilisation des données (réseau et cache de l'appareil).",
"setting_image_viewer_original_title": "Charger l'image originale",

View File

@@ -1,11 +1,17 @@
{
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_album_bottom_sheet_added": "Aggiunto in {album}",
"add_to_album_bottom_sheet_already_exists": "Già presente in {album}",
"advanced_settings_tile_subtitle": "Advanced user's settings",
"advanced_settings_tile_title": "Advanced",
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
"advanced_settings_troubleshooting_title": "Troubleshooting",
"album_info_card_backup_album_excluded": "ESCLUSI",
"album_info_card_backup_album_included": "INCLUSI",
"album_thumbnail_card_item": "1 elemento ",
"album_thumbnail_card_items": "{} elementi",
"album_thumbnail_card_shared": "Condiviso",
"album_thumbnail_owned": "Owned",
"album_thumbnail_shared_by": "Shared by {}",
"album_viewer_appbar_share_delete": "Elimina album ",
"album_viewer_appbar_share_err_delete": "Impossibile cancellare l'album ",
"album_viewer_appbar_share_err_leave": "Impossibile lasciare l'album ",
@@ -14,10 +20,14 @@
"album_viewer_appbar_share_leave": "Lascia album",
"album_viewer_appbar_share_remove": "Rimuovere dall'album ",
"album_viewer_page_share_add_users": "Aggiungi utenti",
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
"asset_list_layout_settings_group_by": "Group assets by",
"asset_list_layout_settings_group_by_month": "Month",
"asset_list_layout_settings_group_by_month_day": "Month + day",
"all_videos_page_title": "Videos",
"archive_page_no_archived_assets": "No archived assets found",
"archive_page_title": "Archive ({})",
"asset_list_layout_settings_dynamic_layout_title": "Layout dinamico",
"asset_list_layout_settings_group_automatically": "Automatic",
"asset_list_layout_settings_group_by": "Raggruppa le immagini per",
"asset_list_layout_settings_group_by_month": "Mese",
"asset_list_layout_settings_group_by_month_day": "Mese + giorno",
"asset_list_settings_subtitle": "Impostazion del layout della griglia delle foto",
"asset_list_settings_title": "Griglia foto",
"backup_album_selection_page_albums_device": "Albums sul device ({})",
@@ -35,9 +45,9 @@
"backup_background_service_in_progress_notification": "Backing dei tuoi contenuti…",
"backup_background_service_upload_failure_notification": "Impossibile caricare {}",
"backup_controller_page_albums": "Backup Album",
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
"backup_controller_page_background_app_refresh_disabled_content": "Attiva background app refresh dalle Impostazioni > Generale > Background App Refresh per utilizzare backup in background.",
"backup_controller_page_background_app_refresh_disabled_title": "Backup in background è disattivo",
"backup_controller_page_background_app_refresh_enable_button_text": "Vai alle impostazioni",
"backup_controller_page_background_battery_info_link": "Mostrami come",
"backup_controller_page_background_battery_info_message": "Per una migliore esperienza di backup, disabilita le ottimizzazioni della batteria per l'app Immich.\n\nDal momento che è una funzionalità specifica del dispositivo, per favore consulta il manuale del produttore.",
"backup_controller_page_background_battery_info_ok": "OK",
@@ -82,7 +92,7 @@
"cache_settings_album_thumbnails": "Anteprime pagine librerie ({} assets)",
"cache_settings_clear_cache_button": "Cancella cache",
"cache_settings_clear_cache_button_title": "Cancella la cache dell'app. Questo impatterà significativamente le prestazioni dell''app fino a quando la cache non sarà rigenerata.",
"cache_settings_image_cache_size": "Dimensione cache foto ({} assets)",
"cache_settings_image_cache_size": "Dimensione cache delle foto ({} assets)",
"cache_settings_statistics_album": "Anteprime librerie",
"cache_settings_statistics_assets": "{} contenuti ({})",
"cache_settings_statistics_full": "Immagini complete",
@@ -90,29 +100,34 @@
"cache_settings_statistics_thumbnail": "Anteprime",
"cache_settings_statistics_title": "Uso della cache",
"cache_settings_subtitle": "Controlla il comportamento della cache dell'applicazione mobile immich",
"cache_settings_thumbnail_size": "Dimensione cache anteprime ({} assets)",
"cache_settings_thumbnail_size": "Dimensione cache dei thumbnail ({} assets)",
"cache_settings_title": "Impostazioni della Cache",
"change_password_form_confirm_password": "Confirm Password",
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
"change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password",
"common_add_to_album": "Add to album",
"common_change_password": "Change Password",
"common_create_new_album": "Create new album",
"common_shared": "Shared",
"change_password_form_confirm_password": "Conferma Password ",
"change_password_form_description": "Ciao {firstName} {lastName},\n\nQuesto è la prima volta che accedi al sistema oppure è stato fatto una richiesta di cambiare la password. Per favore inserisca la nuova password qui sotto",
"change_password_form_new_password": "Nuova Password",
"change_password_form_password_mismatch": "Le password non coincidono",
"change_password_form_reenter_new_password": "Inserisci ancora la nuova password ",
"common_add_to_album": "Aggiungi all'album",
"common_change_password": "Cambia Password",
"common_create_new_album": "Crea nuovo Album",
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
"common_shared": "Condivisi",
"control_bottom_app_bar_add_to_album": "Aggiungi all'album",
"control_bottom_app_bar_album_info": "{} elementi",
"control_bottom_app_bar_album_info_shared": "{} elementi · Condivisi",
"control_bottom_app_bar_archive": "Archive",
"control_bottom_app_bar_create_new_album": "Crea nuovo album",
"control_bottom_app_bar_delete": "Elimina",
"control_bottom_app_bar_favorite": "Favorite",
"control_bottom_app_bar_favorite": "Preferiti",
"control_bottom_app_bar_share": "Condividi",
"control_bottom_app_bar_unarchive": "Unarchive",
"create_album_page_untitled": "Senza titolo",
"create_shared_album_page_create": "Crea",
"create_shared_album_page_share": "Condividi",
"create_shared_album_page_share_add_assets": "AGGIUNGI OGGETTI",
"create_shared_album_page_share_select_photos": "Seleziona foto",
"curated_location_page_title": "Places",
"curated_object_page_title": "Things",
"daily_title_text_date": "E, dd MMM",
"daily_title_text_date_year": "E, dd MMM, yyyy",
"date_format": "E, d LLL, y • hh:mm",
@@ -120,6 +135,8 @@
"delete_dialog_cancel": "Annulla",
"delete_dialog_ok": "Elimina",
"delete_dialog_title": "Cancella definitivamente",
"description_input_hint_text": "Add description...",
"description_input_submit_error": "Error updating description, check the log for more details",
"exif_bottom_sheet_description": "Aggiungi una descrizione...",
"exif_bottom_sheet_details": "DETTAGLI",
"exif_bottom_sheet_location": "POSIZIONE",
@@ -127,28 +144,33 @@
"experimental_settings_new_asset_list_title": "Attiva griglia di foto sperimentale",
"experimental_settings_subtitle": "Usalo a tuo rischio!",
"experimental_settings_title": "Sperimentale",
"favorites_page_title": "Favorites",
"favorites_page_no_favorites": "No favorite assets found",
"favorites_page_title": "Preferiti",
"home_page_add_to_album_conflicts": "Aggiunti {added} elementi all'album {album}. {failed} elementi erano già presenti nell'album.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
"home_page_add_to_album_err_local": "Non puoi aggiungere negli album foto ancora non caricate",
"home_page_add_to_album_success": "Aggiunti {added} elementi all'album {album}",
"home_page_building_timeline": "Building the timeline",
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
"image_viewer_page_state_provider_download_error": "Download Error",
"image_viewer_page_state_provider_download_success": "Download Success",
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
"home_page_building_timeline": "Costruendo il Timeline",
"home_page_favorite_err_local": "Non puoi aggiungere tra i preferiti le foto ancora non caricate",
"home_page_first_time_notice": "Se è la prima volta che usi l'app, assicurati di scegliere gli album per avere il Timeline con immagini e video",
"image_viewer_page_state_provider_download_error": "Errore nel Download",
"image_viewer_page_state_provider_download_success": "Download con successo",
"library_page_albums": "Album",
"library_page_favorites": "Favorites",
"library_page_archive": "Archive",
"library_page_device_albums": "Albums on Device",
"library_page_favorites": "Preferiti",
"library_page_new_album": "Nuovo Album",
"library_page_sharing": "Sharing",
"library_page_sort_created": "Most recently created",
"library_page_sort_title": "Album title",
"library_page_sharing": "Condividendo",
"library_page_sort_created": "Creato il più recente",
"library_page_sort_title": "Titolo album",
"login_form_api_exception": "API exception. Please check the server URL and try again.",
"login_form_button_text": "Login",
"login_form_email_hint": "tuaemail@email.com",
"login_form_endpoint_hint": "http://ip-del-tuo-server:port/api",
"login_form_endpoint_url": "Server Endpoint URL",
"login_form_err_http": "Per favore specificare http:// o https://",
"login_form_err_invalid_email": "Email non valida",
"login_form_err_invalid_url": "Invalid URL",
"login_form_err_invalid_url": "URL invalido",
"login_form_err_leading_whitespace": "Whitespace all'inizio ",
"login_form_err_trailing_whitespace": "Whitespace alla fine",
"login_form_failed_get_oauth_server_config": "Errore di login usando OAuth, controlla l'URL del server",
@@ -156,30 +178,55 @@
"login_form_failed_login": "Errore nel login, controlla URL del server e le credenziali (email e password)",
"login_form_label_email": "Email",
"login_form_label_password": "Password",
"login_form_next_button": "Next",
"login_form_password_hint": "password ",
"login_form_save_login": "Rimani connesso ",
"login_form_server_empty": "Enter a server URL.",
"login_form_server_error": "Could not connect to server.",
"monthly_title_text_date_format": "MMMM y",
"notification_permission_dialog_cancel": "Cancel",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_dialog_settings": "Settings",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
"notification_permission_list_tile_title": "Notification Permission",
"motion_photos_page_title": "Motion Photos",
"notification_permission_dialog_cancel": "Annulla",
"notification_permission_dialog_content": "Per attivare le notifiche, vai alle Impostazioni e seleziona concedi",
"notification_permission_dialog_settings": "Impostazioni",
"notification_permission_list_tile_content": "Concedi i permessi per attivare le notifiche",
"notification_permission_list_tile_enable_button": "Attiva notifiche",
"notification_permission_list_tile_title": "Permessi delle Notifiche",
"permission_onboarding_continue_anyway": "Continue anyway",
"permission_onboarding_get_started": "Get started",
"permission_onboarding_go_to_settings": "Go to settings",
"permission_onboarding_grant_permission": "Grant permission",
"permission_onboarding_log_out": "Log out",
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
"profile_drawer_app_logs": "Logs",
"profile_drawer_client_server_up_to_date": "Client e server sono aggiornati",
"profile_drawer_settings": "Impostazioni ",
"profile_drawer_sign_out": "Logout",
"recently_added_page_title": "Recently Added",
"search_bar_hint": "Cerca le tue foto",
"search_page_categories": "Categories",
"search_page_favorites": "Favorites",
"search_page_motion_photos": "Motion Photos",
"search_page_no_objects": "Nessuna informazione relativa all'oggetto disponibile",
"search_page_no_places": "Nessun informazione sul luogo disponibile",
"search_page_places": "Luoghi",
"search_page_recently_added": "Recently added",
"search_page_screenshots": "Screenshots",
"search_page_selfies": "Selfies",
"search_page_things": "Oggetti",
"search_page_videos": "Videos",
"search_page_view_all_button": "View all",
"search_page_your_activity": "Your activity",
"search_result_page_new_search_hint": "Nuova ricerca ",
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
"select_additional_user_for_sharing_page_suggestions": "Suggerimenti ",
"select_user_for_sharing_page_err_album": "Impossibile nel creare l'album ",
"select_user_for_sharing_page_share_suggestions": "Suggerimenti",
"server_info_box_app_version": "App Version",
"server_info_box_server_version": "Server Version",
"server_info_box_app_version": "Versione App",
"server_info_box_server_version": "Versione Server",
"setting_image_viewer_help": "Il visualizzatore dettagliato carica una piccola thumbnail per prima, per poi caricare un immagine di media grandezza (se abilitato). Ed infine carica l'originale (se abilitato).",
"setting_image_viewer_original_subtitle": "Abilita per caricare l'immagine originale a risoluzione massima (grande!). Disabilita per ridurre l'utilizzo di banda (sia sul network che nella cache del dispositivo).",
"setting_image_viewer_original_title": "Carica l'immagine originale",

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