Compare commits
341 Commits
feat/group
...
chore/temp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2344939b7d | ||
|
|
f7d9215464 | ||
|
|
9af44fbd69 | ||
|
|
170306af1a | ||
|
|
417d3bbf50 | ||
|
|
e239b8d2fa | ||
|
|
2c7b980eed | ||
|
|
9a5a3c0a1d | ||
|
|
027dab1487 | ||
|
|
e18e4c5962 | ||
|
|
67a8cab286 | ||
|
|
39eee6a634 | ||
|
|
ee98e69097 | ||
|
|
41c1d4d44b | ||
|
|
b21084b851 | ||
|
|
8bf45eb718 | ||
|
|
9d3ca3ad3f | ||
|
|
0090b9db4a | ||
|
|
bee0ae430a | ||
|
|
cc08ebdf80 | ||
|
|
71578b76a7 | ||
|
|
8e5d52abbb | ||
|
|
e52cc259d5 | ||
|
|
00c88b2636 | ||
|
|
e95096d14f | ||
|
|
4c918254b9 | ||
|
|
b97d73d7a7 | ||
|
|
2801b0953d | ||
|
|
7a1c45c364 | ||
|
|
5acd6b70d0 | ||
|
|
edaedca03f | ||
|
|
7b3e1037b6 | ||
|
|
27bc8eba7b | ||
|
|
23fb2e0fae | ||
|
|
59accbf32a | ||
|
|
059a0e8aa8 | ||
|
|
6a55c36762 | ||
|
|
c0bff4b493 | ||
|
|
fd4c2acde8 | ||
|
|
5acf909235 | ||
|
|
fb1458c720 | ||
|
|
255dabc239 | ||
|
|
27751f8fd4 | ||
|
|
72ffa37dd9 | ||
|
|
5a7042364b | ||
|
|
db0ea0f3a8 | ||
|
|
88c0243a20 | ||
|
|
3a29522df6 | ||
|
|
50eae23f3a | ||
|
|
95419750bb | ||
|
|
5fb858a865 | ||
|
|
18084a49ec | ||
|
|
f107cb044a | ||
|
|
f4e7ea47a6 | ||
|
|
8747fc4935 | ||
|
|
287fa79d75 | ||
|
|
bcfb5bee1f | ||
|
|
538263dc38 | ||
|
|
51aec1e93d | ||
|
|
53825cc3d6 | ||
|
|
6e7c2817a3 | ||
|
|
7bd79b551c | ||
|
|
5fe954b3c9 | ||
|
|
7f81a5bd6f | ||
|
|
37a79292c0 | ||
|
|
bf6211776f | ||
|
|
6c178a04dc | ||
|
|
036d314cb6 | ||
|
|
1fc5da398a | ||
|
|
4d84338086 | ||
|
|
0ac49b00ee | ||
|
|
e427778a96 | ||
|
|
b82e29fbb4 | ||
|
|
ff19aea4ac | ||
|
|
28179a3a1d | ||
|
|
af1e18d07e | ||
|
|
270a0ff986 | ||
|
|
9d3f10372d | ||
|
|
2f1385a236 | ||
|
|
183a285584 | ||
|
|
5ce946bb5b | ||
|
|
674faf2e57 | ||
|
|
4f7702c6bf | ||
|
|
28edf5664d | ||
|
|
ec2f94cae8 | ||
|
|
873f7921da | ||
|
|
f06b054087 | ||
|
|
0df910c0cd | ||
|
|
5b8d72e91a | ||
|
|
e7b0a47be2 | ||
|
|
60af3a4003 | ||
|
|
6a4b6699e3 | ||
|
|
7d57fd1320 | ||
|
|
bbc1c8186c | ||
|
|
b76d69c0e5 | ||
|
|
fd2b7a344c | ||
|
|
03dafba522 | ||
|
|
f15376a107 | ||
|
|
32955915dd | ||
|
|
aacb27ea5f | ||
|
|
d6b8c0926f | ||
|
|
225af973c1 | ||
|
|
b3372064e0 | ||
|
|
303307e1ac | ||
|
|
f75c9dfe37 | ||
|
|
f5954f4c9b | ||
|
|
147accd957 | ||
|
|
9487241481 | ||
|
|
460e1d4715 | ||
|
|
b6223af5ca | ||
|
|
8853079c54 | ||
|
|
662d44536e | ||
|
|
80fa5ec198 | ||
|
|
0df88fc22b | ||
|
|
e78144ea31 | ||
|
|
227789225a | ||
|
|
1298a74230 | ||
|
|
a3808c26ce | ||
|
|
e2169f5316 | ||
|
|
f65dabd43a | ||
|
|
a5841a8bf4 | ||
|
|
dc6ac3aaec | ||
|
|
ae104ad7cc | ||
|
|
868d5f56e2 | ||
|
|
88072910da | ||
|
|
25a94bd117 | ||
|
|
76eaee3657 | ||
|
|
d5fec0edab | ||
|
|
a7821a0b79 | ||
|
|
73e67ebfea | ||
|
|
0eaa054218 | ||
|
|
2024d06cb7 | ||
|
|
204299d500 | ||
|
|
70e59c00d5 | ||
|
|
5405810a38 | ||
|
|
e67265cef2 | ||
|
|
19c53609e1 | ||
|
|
0d0bb0e2d9 | ||
|
|
8f1b505ba0 | ||
|
|
d04675fb41 | ||
|
|
acfd40b77a | ||
|
|
840e43430c | ||
|
|
a3e0c6cef5 | ||
|
|
63088b22e0 | ||
|
|
d9d8beb92f | ||
|
|
38a8a67be9 | ||
|
|
7531ffcbfb | ||
|
|
d5f3629c49 | ||
|
|
be5b4cb1d1 | ||
|
|
5fb8d651ec | ||
|
|
c2313f7a99 | ||
|
|
59627e2b4c | ||
|
|
530bf059ad | ||
|
|
b44d2a241d | ||
|
|
1af10ded74 | ||
|
|
3f1e11afcc | ||
|
|
28dce2d0df | ||
|
|
605764f226 | ||
|
|
44e1c83c84 | ||
|
|
0729887c9c | ||
|
|
3bfa8b7575 | ||
|
|
3138048b96 | ||
|
|
f8b41ea8aa | ||
|
|
1d33ed6bed | ||
|
|
2be1a58c5b | ||
|
|
03e7922589 | ||
|
|
801af34d9a | ||
|
|
bedaa729e9 | ||
|
|
13c8a6e61d | ||
|
|
01edf6533b | ||
|
|
30d0bea4df | ||
|
|
571504aa5e | ||
|
|
65fafcab37 | ||
|
|
2fe0d17fe1 | ||
|
|
b6a91746d8 | ||
|
|
89533a858f | ||
|
|
dc5a0f8c33 | ||
|
|
c443ab854c | ||
|
|
379c73818a | ||
|
|
73bb05c5f9 | ||
|
|
b69470c69e | ||
|
|
34255453b1 | ||
|
|
4e03b06ff7 | ||
|
|
9bb211f56f | ||
|
|
6f4f79d8cc | ||
|
|
ed3997d844 | ||
|
|
fb59fa343d | ||
|
|
ab2849781a | ||
|
|
66c657ca8a | ||
|
|
c245208106 | ||
|
|
99d6673503 | ||
|
|
9ff37b6870 | ||
|
|
0e7816130b | ||
|
|
a1beb0a87d | ||
|
|
c4ac2e345f | ||
|
|
f422b341d1 | ||
|
|
90538d2535 | ||
|
|
abc7bfa0ba | ||
|
|
60a809d7b4 | ||
|
|
cda7249a6a | ||
|
|
47566c1a4a | ||
|
|
f08002d48f | ||
|
|
7186914531 | ||
|
|
d38ab93484 | ||
|
|
845b0f2073 | ||
|
|
acb1e513a7 | ||
|
|
4d4e54967d | ||
|
|
e2dcebfe6c | ||
|
|
d4f2b43f64 | ||
|
|
f343b0e58f | ||
|
|
a8b4a5e856 | ||
|
|
e7e030279b | ||
|
|
9ff664ed36 | ||
|
|
e00556a34a | ||
|
|
a313e4338e | ||
|
|
257b0c74af | ||
|
|
3d515f5072 | ||
|
|
ec01db5c8b | ||
|
|
cd6d8fcdfe | ||
|
|
1198311d64 | ||
|
|
1a4eab9655 | ||
|
|
1926c90780 | ||
|
|
4d5975b717 | ||
|
|
8cbd6b29c4 | ||
|
|
8c1b630a2b | ||
|
|
c961d2aaf7 | ||
|
|
41c75dc93e | ||
|
|
f92247c99b | ||
|
|
53f9fc2d1c | ||
|
|
bede19a3ca | ||
|
|
aefa62b234 | ||
|
|
b3fb831994 | ||
|
|
0d60199514 | ||
|
|
54960157c0 | ||
|
|
244d097d01 | ||
|
|
adb55f3726 | ||
|
|
5d2777a5c6 | ||
|
|
24db881c14 | ||
|
|
f09bed9ad2 | ||
|
|
e29cc66361 | ||
|
|
669b765662 | ||
|
|
e7060dc292 | ||
|
|
03a8b6cb38 | ||
|
|
f317cbe221 | ||
|
|
d6d31c6695 | ||
|
|
4b9019e762 | ||
|
|
13563fc507 | ||
|
|
2ce4f8dd3b | ||
|
|
538d5c81ea | ||
|
|
9ecaa3fa9d | ||
|
|
b1aacfdbd9 | ||
|
|
cfbc24579d | ||
|
|
1d4d8e7a9a | ||
|
|
7b83b7b2d5 | ||
|
|
a896c5a4dd | ||
|
|
c74989d304 | ||
|
|
1283491cc2 | ||
|
|
89522daaac | ||
|
|
011a667314 | ||
|
|
df2525ee08 | ||
|
|
01a9f735c8 | ||
|
|
af10c3bc2f | ||
|
|
395f2e155d | ||
|
|
10cbed55c4 | ||
|
|
325d5f7ba9 | ||
|
|
746252fe39 | ||
|
|
f36efd128b | ||
|
|
f1c494ef97 | ||
|
|
9c8c52874a | ||
|
|
68b617130a | ||
|
|
89292fecb4 | ||
|
|
1193a23282 | ||
|
|
bbfff64927 | ||
|
|
c5c9a522c1 | ||
|
|
3cd7f5ab90 | ||
|
|
f2067221c5 | ||
|
|
89598cf0be | ||
|
|
0121043d7d | ||
|
|
1ca46fbd98 | ||
|
|
6ddef3a7e4 | ||
|
|
0d9ebdc46a | ||
|
|
fa26d0de33 | ||
|
|
a5760129f0 | ||
|
|
d430b869ac | ||
|
|
4179c8a17d | ||
|
|
0a9cbf01d2 | ||
|
|
9567a2a560 | ||
|
|
58dd6f094c | ||
|
|
02381343ff | ||
|
|
09a5963eee | ||
|
|
a573a23c83 | ||
|
|
7118dca559 | ||
|
|
13d43e193e | ||
|
|
7a7843467c | ||
|
|
9e6fee4064 | ||
|
|
9680f1290d | ||
|
|
ce2ea98926 | ||
|
|
5c76cc34e1 | ||
|
|
eb2f4c866e | ||
|
|
2a370087e8 | ||
|
|
272c8a5812 | ||
|
|
08fe549ed8 | ||
|
|
ae15efdf2a | ||
|
|
8e003f95db | ||
|
|
3e92e837f1 | ||
|
|
081307ced2 | ||
|
|
a91bb399f0 | ||
|
|
42b78c59b5 | ||
|
|
750d21aeba | ||
|
|
990d9ba9a8 | ||
|
|
4d0c9172e5 | ||
|
|
094e3a2757 | ||
|
|
278668b8c5 | ||
|
|
10141504a2 | ||
|
|
67736c8fce | ||
|
|
b56a272f64 | ||
|
|
5901c2e963 | ||
|
|
be85832b20 | ||
|
|
c8f9a72d3e | ||
|
|
3d633a81c4 | ||
|
|
4efbf36d82 | ||
|
|
e2c3c39597 | ||
|
|
007ba1d9ef | ||
|
|
4d5cd1a6b5 | ||
|
|
8108f50c4e | ||
|
|
1b8354ed36 | ||
|
|
9242afb4b0 | ||
|
|
c5f14adff0 | ||
|
|
1378f22368 | ||
|
|
4bd465e752 | ||
|
|
a07531be3b | ||
|
|
3cdc6844a1 | ||
|
|
c3263e50fc | ||
|
|
7391ea6ff9 | ||
|
|
f972b8d514 | ||
|
|
6b50d958f4 | ||
|
|
27c456eb75 | ||
|
|
e7d051db3c | ||
|
|
86d31d7d29 | ||
|
|
f416342eff | ||
|
|
d73335ecbc |
@@ -5,7 +5,8 @@
|
|||||||
"immich-server",
|
"immich-server",
|
||||||
"redis",
|
"redis",
|
||||||
"database",
|
"database",
|
||||||
"immich-machine-learning"
|
"immich-machine-learning",
|
||||||
|
"init"
|
||||||
],
|
],
|
||||||
"dockerComposeFile": [
|
"dockerComposeFile": [
|
||||||
"../docker/docker-compose.dev.yml",
|
"../docker/docker-compose.dev.yml",
|
||||||
|
|||||||
@@ -49,10 +49,11 @@ fix_permissions() {
|
|||||||
|
|
||||||
log "Fixing permissions for ${IMMICH_WORKSPACE}"
|
log "Fixing permissions for ${IMMICH_WORKSPACE}"
|
||||||
|
|
||||||
run_cmd sudo find "${IMMICH_WORKSPACE}/server/upload" -not -path "${IMMICH_WORKSPACE}/server/upload/postgres/*" -not -path "${IMMICH_WORKSPACE}/server/upload/postgres" -exec chown node {} +
|
|
||||||
|
|
||||||
# Change ownership for directories that exist
|
# Change ownership for directories that exist
|
||||||
for dir in "${IMMICH_WORKSPACE}/.vscode" \
|
for dir in "${IMMICH_WORKSPACE}/.vscode" \
|
||||||
|
"${IMMICH_WORKSPACE}/server/upload" \
|
||||||
|
"${IMMICH_WORKSPACE}/.pnpm-store" \
|
||||||
|
"${IMMICH_WORKSPACE}/.github/node_modules" \
|
||||||
"${IMMICH_WORKSPACE}/cli/node_modules" \
|
"${IMMICH_WORKSPACE}/cli/node_modules" \
|
||||||
"${IMMICH_WORKSPACE}/e2e/node_modules" \
|
"${IMMICH_WORKSPACE}/e2e/node_modules" \
|
||||||
"${IMMICH_WORKSPACE}/open-api/typescript-sdk/node_modules" \
|
"${IMMICH_WORKSPACE}/open-api/typescript-sdk/node_modules" \
|
||||||
|
|||||||
@@ -8,21 +8,27 @@ services:
|
|||||||
- IMMICH_SERVER_URL=http://127.0.0.1:2283/
|
- IMMICH_SERVER_URL=http://127.0.0.1:2283/
|
||||||
volumes: !override
|
volumes: !override
|
||||||
- ..:/workspaces/immich
|
- ..:/workspaces/immich
|
||||||
- cli_node_modules:/workspaces/immich/cli/node_modules
|
|
||||||
- e2e_node_modules:/workspaces/immich/e2e/node_modules
|
|
||||||
- open_api_node_modules:/workspaces/immich/open-api/typescript-sdk/node_modules
|
|
||||||
- server_node_modules:/workspaces/immich/server/node_modules
|
|
||||||
- web_node_modules:/workspaces/immich/web/node_modules
|
|
||||||
- ${UPLOAD_LOCATION:-upload1-devcontainer-volume}${UPLOAD_LOCATION:+/photos}:/data
|
- ${UPLOAD_LOCATION:-upload1-devcontainer-volume}${UPLOAD_LOCATION:+/photos}:/data
|
||||||
- ${UPLOAD_LOCATION:-upload2-devcontainer-volume}${UPLOAD_LOCATION:+/photos/upload}:/data/upload
|
- ${UPLOAD_LOCATION:-upload2-devcontainer-volume}${UPLOAD_LOCATION:+/photos/upload}:/data/upload
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- pnpm-store:/usr/src/app/.pnpm-store
|
||||||
|
- server-node_modules:/usr/src/app/server/node_modules
|
||||||
|
- web-node_modules:/usr/src/app/web/node_modules
|
||||||
|
- github-node_modules:/usr/src/app/.github/node_modules
|
||||||
|
- cli-node_modules:/usr/src/app/cli/node_modules
|
||||||
|
- docs-node_modules:/usr/src/app/docs/node_modules
|
||||||
|
- e2e-node_modules:/usr/src/app/e2e/node_modules
|
||||||
|
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
|
||||||
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
|
- coverage:/usr/src/app/web/coverage
|
||||||
immich-web:
|
immich-web:
|
||||||
env_file: !reset []
|
env_file: !reset []
|
||||||
|
init:
|
||||||
|
env_file: !reset []
|
||||||
|
command: sh -c 'find /data -maxdepth 1 ! -path "/data/postgres" -type d -exec chown ${UID:-1000}:${GID:-1000} {} + 2>/dev/null || true; for path in /usr/src/app/.pnpm-store /usr/src/app/server/node_modules /usr/src/app/server/dist /usr/src/app/.github/node_modules /usr/src/app/cli/node_modules /usr/src/app/docs/node_modules /usr/src/app/e2e/node_modules /usr/src/app/open-api/typescript-sdk/node_modules /usr/src/app/web/.svelte-kit /usr/src/app/web/coverage /usr/src/app/node_modules /usr/src/app/web/node_modules; do [ -e "$$path" ] && chown -R ${UID:-1000}:${GID:-1000} "$$path" || true; done'
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
env_file: !reset []
|
env_file: !reset []
|
||||||
|
|
||||||
database:
|
database:
|
||||||
env_file: !reset []
|
env_file: !reset []
|
||||||
environment: !override
|
environment: !override
|
||||||
@@ -33,17 +39,10 @@ services:
|
|||||||
POSTGRES_HOST_AUTH_METHOD: md5
|
POSTGRES_HOST_AUTH_METHOD: md5
|
||||||
volumes:
|
volumes:
|
||||||
- ${UPLOAD_LOCATION:-postgres-devcontainer-volume}${UPLOAD_LOCATION:+/postgres}:/var/lib/postgresql/data
|
- ${UPLOAD_LOCATION:-postgres-devcontainer-volume}${UPLOAD_LOCATION:+/postgres}:/var/lib/postgresql/data
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
env_file: !reset []
|
env_file: !reset []
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# Node modules for each service to avoid conflicts and ensure consistent dependencies
|
# Node modules for each service to avoid conflicts and ensure consistent dependencies
|
||||||
cli_node_modules:
|
|
||||||
e2e_node_modules:
|
|
||||||
open_api_node_modules:
|
|
||||||
server_node_modules:
|
|
||||||
web_node_modules:
|
|
||||||
upload1-devcontainer-volume:
|
upload1-devcontainer-volume:
|
||||||
upload2-devcontainer-volume:
|
upload2-devcontainer-volume:
|
||||||
postgres-devcontainer-volume:
|
postgres-devcontainer-volume:
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source /immich-devcontainer/container-common.sh
|
source /immich-devcontainer/container-common.sh
|
||||||
|
|
||||||
|
log "Preparing Immich Nest API Server"
|
||||||
|
log ""
|
||||||
|
export CI=1
|
||||||
|
run_cmd pnpm --filter immich install
|
||||||
|
|
||||||
log "Starting Nest API Server"
|
log "Starting Nest API Server"
|
||||||
log ""
|
log ""
|
||||||
cd "${IMMICH_WORKSPACE}/server" || (
|
cd "${IMMICH_WORKSPACE}/server" || (
|
||||||
@@ -11,7 +16,7 @@ cd "${IMMICH_WORKSPACE}/server" || (
|
|||||||
)
|
)
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
run_cmd node ./node_modules/.bin/nest start --debug "0.0.0.0:9230" --watch
|
run_cmd pnpm --filter immich exec nest start --debug "0.0.0.0:9230" --watch
|
||||||
log "Nest API Server crashed with exit code $?. Respawning in 3s ..."
|
log "Nest API Server crashed with exit code $?. Respawning in 3s ..."
|
||||||
sleep 3
|
sleep 3
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source /immich-devcontainer/container-common.sh
|
source /immich-devcontainer/container-common.sh
|
||||||
|
|
||||||
|
export CI=1
|
||||||
|
log "Preparing Immich Web Frontend"
|
||||||
|
log ""
|
||||||
|
run_cmd pnpm --filter @immich/sdk install
|
||||||
|
run_cmd pnpm --filter @immich/sdk build
|
||||||
|
run_cmd pnpm --filter immich-web install
|
||||||
|
|
||||||
log "Starting Immich Web Frontend"
|
log "Starting Immich Web Frontend"
|
||||||
log ""
|
log ""
|
||||||
cd "${IMMICH_WORKSPACE}/web" || (
|
cd "${IMMICH_WORKSPACE}/web" || (
|
||||||
@@ -16,7 +23,7 @@ until curl --output /dev/null --silent --head --fail "http://127.0.0.1:${IMMICH_
|
|||||||
done
|
done
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
run_cmd node ./node_modules/.bin/vite dev --host 0.0.0.0 --port "${DEV_PORT}"
|
run_cmd pnpm --filter immich-web exec vite dev --host 0.0.0.0 --port "${DEV_PORT}"
|
||||||
log "Web crashed with exit code $?. Respawning in 3s ..."
|
log "Web crashed with exit code $?. Respawning in 3s ..."
|
||||||
sleep 3
|
sleep 3
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ source /immich-devcontainer/container-common.sh
|
|||||||
log "Setting up Immich dev container..."
|
log "Setting up Immich dev container..."
|
||||||
fix_permissions
|
fix_permissions
|
||||||
|
|
||||||
log "Installing npm dependencies (node_modules)..."
|
|
||||||
install_dependencies
|
|
||||||
|
|
||||||
log "Setup complete, please wait while backend and frontend services automatically start"
|
log "Setup complete, please wait while backend and frontend services automatically start"
|
||||||
log
|
log
|
||||||
log "If necessary, the services may be manually started using"
|
log "If necessary, the services may be manually started using"
|
||||||
|
|||||||
2
.github/.nvmrc
vendored
@@ -1 +1 @@
|
|||||||
22.17.1
|
22.19.0
|
||||||
|
|||||||
5
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -64,6 +64,11 @@ body:
|
|||||||
- label: Web
|
- label: Web
|
||||||
- label: Mobile
|
- label: Mobile
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Device make and model
|
||||||
|
placeholder: Samsung S25 Android 16
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
28
.github/package-lock.json
generated
vendored
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": ".github",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"devDependencies": {
|
|
||||||
"prettier": "^3.5.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/prettier": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"prettier": "bin/prettier.cjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
.github/pull_request_template.md
vendored
@@ -34,3 +34,7 @@ The `/api/something` endpoint is now `/api/something-else`
|
|||||||
- [ ] I have followed naming conventions/patterns in the surrounding code
|
- [ ] I have followed naming conventions/patterns in the surrounding code
|
||||||
- [ ] All code in `src/services/` uses repositories implementations for database calls, filesystem operations, etc.
|
- [ ] All code in `src/services/` uses repositories implementations for database calls, filesystem operations, etc.
|
||||||
- [ ] All code in `src/repositories/` is pretty basic/simple and does not have any immich specific logic (that belongs in `src/services/`)
|
- [ ] All code in `src/repositories/` is pretty basic/simple and does not have any immich specific logic (that belongs in `src/services/`)
|
||||||
|
|
||||||
|
## Please describe to which degree, if any, an LLM was used in creating this pull request.
|
||||||
|
|
||||||
|
...
|
||||||
|
|||||||
10
.github/workflows/build-mobile.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ jobs:
|
|||||||
runs-on: mich
|
runs-on: mich
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.ref || github.sha }}
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Restore Gradle Cache
|
- name: Restore Gradle Cache
|
||||||
id: cache-gradle-restore
|
id: cache-gradle-restore
|
||||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4
|
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
~/.gradle/caches
|
||||||
@@ -106,7 +106,7 @@ jobs:
|
|||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
|
||||||
- name: Generate translation file
|
- name: Generate translation file
|
||||||
run: make translation
|
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
|
|
||||||
- name: Generate platform APIs
|
- name: Generate platform APIs
|
||||||
@@ -136,7 +136,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Save Gradle Cache
|
- name: Save Gradle Cache
|
||||||
id: cache-gradle-save
|
id: cache-gradle-save
|
||||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4
|
uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
2
.github/workflows/cache-cleanup.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
actions: write
|
actions: write
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|||||||
33
.github/workflows/cli.yml
vendored
@@ -29,25 +29,28 @@ jobs:
|
|||||||
working-directory: ./cli
|
working-directory: ./cli
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
# Setup .npmrc file to publish to npm
|
- name: Setup pnpm
|
||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Prepare SDK
|
- name: Setup typescript-sdk
|
||||||
run: npm ci --prefix ../open-api/typescript-sdk/
|
run: pnpm install && pnpm run build
|
||||||
- name: Build SDK
|
working-directory: ./open-api/typescript-sdk
|
||||||
run: npm run build --prefix ../open-api/typescript-sdk/
|
|
||||||
- run: npm ci
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: npm run build
|
- run: pnpm build
|
||||||
- run: npm publish
|
- run: pnpm publish
|
||||||
if: ${{ github.event_name == 'release' }}
|
if: ${{ github.event_name == 'release' }}
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
@@ -62,7 +65,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -73,7 +76,7 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -88,7 +91,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: metadata
|
id: metadata
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=false
|
latest=false
|
||||||
|
|||||||
107
.github/workflows/close-duplicates.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
discussion:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
name: Close likely duplicates
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
should_run:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
should_run: ${{ steps.should_run.outputs.run }}
|
||||||
|
steps:
|
||||||
|
- id: should_run
|
||||||
|
run: echo "run=${{ github.event_name == 'issues' || github.event.discussion.category.name == 'Feature Request' }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
get_body:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: should_run
|
||||||
|
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
||||||
|
env:
|
||||||
|
EVENT: ${{ toJSON(github.event) }}
|
||||||
|
outputs:
|
||||||
|
body: ${{ steps.get_body.outputs.body }}
|
||||||
|
steps:
|
||||||
|
- id: get_body
|
||||||
|
run: |
|
||||||
|
BODY=$(echo """$EVENT""" | jq -r '.issue // .discussion | .body' | base64 -w 0)
|
||||||
|
echo "body=$BODY" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
get_checkbox_json:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [get_body, should_run]
|
||||||
|
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
||||||
|
container:
|
||||||
|
image: yshavit/mdq:0.9.0@sha256:4399483ca857fb1a7ed28a596f754c7373e358647de31ce14b79a27c91e1e35e
|
||||||
|
outputs:
|
||||||
|
checked: ${{ steps.get_checkbox.outputs.checked }}
|
||||||
|
steps:
|
||||||
|
- id: get_checkbox
|
||||||
|
env:
|
||||||
|
BODY: ${{ needs.get_body.outputs.body }}
|
||||||
|
run: |
|
||||||
|
CHECKED=$(echo "$BODY" | base64 -d | /mdq --output json '# I have searched | - [?] Yes' | jq '.items[0].list[0].checked // false')
|
||||||
|
echo "checked=$CHECKED" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
close_and_comment:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [get_checkbox_json, should_run]
|
||||||
|
if: ${{ needs.should_run.outputs.should_run == 'true' && needs.get_checkbox_json.outputs.checked != 'true' }}
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
discussions: write
|
||||||
|
steps:
|
||||||
|
- name: Close issue
|
||||||
|
if: ${{ github.event_name == 'issues' }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
NODE_ID: ${{ github.event.issue.node_id }}
|
||||||
|
run: |
|
||||||
|
gh api graphql \
|
||||||
|
-f issueId="$NODE_ID" \
|
||||||
|
-f body="This issue has automatically been closed as it is likely a duplicate. We get a lot of duplicate threads each day, which is why we ask you in the template to confirm that you searched for duplicates before opening one. If you're sure this is not a duplicate, please leave a comment and we will reopen the thread if necessary." \
|
||||||
|
-f query='
|
||||||
|
mutation CommentAndCloseIssue($issueId: ID!, $body: String!) {
|
||||||
|
addComment(input: {
|
||||||
|
subjectId: $issueId,
|
||||||
|
body: $body
|
||||||
|
}) {
|
||||||
|
__typename
|
||||||
|
}
|
||||||
|
|
||||||
|
closeIssue(input: {
|
||||||
|
issueId: $issueId,
|
||||||
|
stateReason: DUPLICATE
|
||||||
|
}) {
|
||||||
|
__typename
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
|
||||||
|
- name: Close discussion
|
||||||
|
if: ${{ github.event_name == 'discussion' && github.event.discussion.category.name == 'Feature Request' }}
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
NODE_ID: ${{ github.event.discussion.node_id }}
|
||||||
|
run: |
|
||||||
|
gh api graphql \
|
||||||
|
-f discussionId="$NODE_ID" \
|
||||||
|
-f body="This discussion has automatically been closed as it is likely a duplicate. We get a lot of duplicate threads each day, which is why we ask you in the template to confirm that you searched for duplicates before opening one. If you're sure this is not a duplicate, please leave a comment and we will reopen the thread if necessary." \
|
||||||
|
-f query='
|
||||||
|
mutation CommentAndCloseDiscussion($discussionId: ID!, $body: String!) {
|
||||||
|
addDiscussionComment(input: {
|
||||||
|
discussionId: $discussionId,
|
||||||
|
body: $body
|
||||||
|
}) {
|
||||||
|
__typename
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDiscussion(input: {
|
||||||
|
discussionId: $discussionId,
|
||||||
|
reason: DUPLICATE
|
||||||
|
}) {
|
||||||
|
__typename
|
||||||
|
}
|
||||||
|
}'
|
||||||
8
.github/workflows/codeql-analysis.yml
vendored
@@ -44,13 +44,13 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
|
uses: github/codeql-action/init@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -63,7 +63,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
|
uses: github/codeql-action/autobuild@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -76,6 +76,6 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
|
uses: github/codeql-action/analyze@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
|
|||||||
6
.github/workflows/docker.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
|
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
|
||||||
steps:
|
steps:
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -89,7 +89,7 @@ jobs:
|
|||||||
suffix: ['']
|
suffix: ['']
|
||||||
steps:
|
steps:
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
|
|||||||
19
.github/workflows/docs-build.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.found_paths.outputs.open-api == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.found_paths.outputs.open-api == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
@@ -51,25 +51,28 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './docs/.nvmrc'
|
node-version-file: './docs/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run npm install
|
- name: Run install
|
||||||
run: npm ci
|
run: pnpm install
|
||||||
|
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
|
|
||||||
- name: Run build
|
- name: Run build
|
||||||
run: npm run build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Upload build output
|
- name: Upload build output
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
|
|||||||
10
.github/workflows/docs-deploy.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
run: echo 'The triggering workflow did not succeed' && exit 1
|
run: echo 'The triggering workflow did not succeed' && exit 1
|
||||||
- name: Get artifact
|
- name: Get artifact
|
||||||
id: get-artifact
|
id: get-artifact
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
return { found: true, id: matchArtifact.id };
|
return { found: true, id: matchArtifact.id };
|
||||||
- name: Determine deploy parameters
|
- name: Determine deploy parameters
|
||||||
id: parameters
|
id: parameters
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
env:
|
env:
|
||||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||||
with:
|
with:
|
||||||
@@ -108,13 +108,13 @@ jobs:
|
|||||||
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Load parameters
|
- name: Load parameters
|
||||||
id: parameters
|
id: parameters
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
env:
|
env:
|
||||||
PARAM_JSON: ${{ needs.checks.outputs.parameters }}
|
PARAM_JSON: ${{ needs.checks.outputs.parameters }}
|
||||||
with:
|
with:
|
||||||
@@ -125,7 +125,7 @@ jobs:
|
|||||||
core.setOutput("shouldDeploy", parameters.shouldDeploy);
|
core.setOutput("shouldDeploy", parameters.shouldDeploy);
|
||||||
|
|
||||||
- name: Download artifact
|
- name: Download artifact
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
env:
|
env:
|
||||||
ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
|
ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/docs-destroy.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|||||||
10
.github/workflows/fix-format.yml
vendored
@@ -16,13 +16,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: 'Checkout'
|
- name: 'Checkout'
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.ref }}
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
@@ -32,8 +32,8 @@ jobs:
|
|||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Fix formatting
|
- name: Fix formatting
|
||||||
run: make install-all && make format-all
|
run: make install-all && make format-all
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
message: 'chore: fix formatting'
|
message: 'chore: fix formatting'
|
||||||
|
|
||||||
- name: Remove label
|
- name: Remove label
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
|
|||||||
99
.github/workflows/merge-translations.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
name: Merge translations
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
env:
|
||||||
|
WEBLATE_HOST: 'https://hosted.weblate.org'
|
||||||
|
WEBLATE_COMPONENT: 'immich/immich'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Find translation PR
|
||||||
|
id: find_pr
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PR=$(gh pr list --repo $GITHUB_REPOSITORY --author weblate --json number,mergeable)
|
||||||
|
echo "$PR"
|
||||||
|
|
||||||
|
PR_NUMBER=$(echo "$PR" | jq '
|
||||||
|
if length == 1 then
|
||||||
|
.[0].number
|
||||||
|
else
|
||||||
|
error("Expected exactly 1 entry, got \(length)")
|
||||||
|
end
|
||||||
|
' 2>&1) || exit 1
|
||||||
|
|
||||||
|
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||||
|
echo "Selected PR $PR_NUMBER"
|
||||||
|
|
||||||
|
if ! echo "$PR" | jq -e '.[0].mergeable == "MERGEABLE"'; then
|
||||||
|
echo "PR is not mergeable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Generate a token
|
||||||
|
id: generate_token
|
||||||
|
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
|
- name: Lock weblate
|
||||||
|
env:
|
||||||
|
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=true
|
||||||
|
|
||||||
|
- name: Commit translations
|
||||||
|
env:
|
||||||
|
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=commit
|
||||||
|
curl -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/repository/" -d operation=push
|
||||||
|
|
||||||
|
- name: Merge PR
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }}
|
||||||
|
run: |
|
||||||
|
REVIEW_ID=$(gh api -X POST "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews" --field event='APPROVE' --field body='Automatically merging translations PR' \
|
||||||
|
| jq '.id')
|
||||||
|
echo "REVIEW_ID=$REVIEW_ID" >> $GITHUB_OUTPUT
|
||||||
|
gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --auto --squash
|
||||||
|
|
||||||
|
- name: Wait for PR to merge
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }}
|
||||||
|
REVIEW_ID: ${{ steps.merge_pr.outputs.REVIEW_ID }}
|
||||||
|
run: |
|
||||||
|
for i in {1..10}; do
|
||||||
|
if gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json merged | jq -e '.merged == true'; then
|
||||||
|
echo "PR merged"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "PR not merged yet, waiting..."
|
||||||
|
sleep 6
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "PR did not merge in time"
|
||||||
|
gh api -X PUT "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/reviews/$REVIEW_ID/dismissals" --field message='Merge attempt timed out' --field event='DISMISS'
|
||||||
|
gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --disable-auto
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Unlock weblate
|
||||||
|
env:
|
||||||
|
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=false
|
||||||
18
.github/workflows/prepare-release.yml
vendored
@@ -32,13 +32,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
persist-credentials: true
|
persist-credentials: true
|
||||||
@@ -46,6 +46,16 @@ jobs:
|
|||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
|
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
|
with:
|
||||||
|
node-version-file: './server/.nvmrc'
|
||||||
|
cache: 'pnpm'
|
||||||
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Bump version
|
- name: Bump version
|
||||||
env:
|
env:
|
||||||
SERVER_BUMP: ${{ inputs.serverBump }}
|
SERVER_BUMP: ${{ inputs.serverBump }}
|
||||||
@@ -83,13 +93,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|||||||
16
.github/workflows/preview-label.yaml
vendored
@@ -20,11 +20,11 @@ jobs:
|
|||||||
|
|
||||||
remove-label:
|
remove-label:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'preview') }}
|
if: ${{ (github.event.action == 'closed' || github.event.pull_request.head.repo.fork) && contains(github.event.pull_request.labels.*.name, 'preview') }}
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
- uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.issues.removeLabel({
|
github.rest.issues.removeLabel({
|
||||||
@@ -33,3 +33,15 @@ jobs:
|
|||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
name: 'preview'
|
name: 'preview'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
|
||||||
|
if: ${{ github.event.pull_request.head.repo.fork }}
|
||||||
|
with:
|
||||||
|
message-id: 'preview-status'
|
||||||
|
message: 'PRs from forks cannot have preview environments.'
|
||||||
|
|
||||||
|
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
|
||||||
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
|
with:
|
||||||
|
message-id: 'preview-status'
|
||||||
|
message: 'Preview environment has been removed.'
|
||||||
|
|||||||
15
.github/workflows/sdk.yml
vendored
@@ -16,22 +16,25 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
|
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './open-api/typescript-sdk/.nvmrc'
|
node-version-file: './open-api/typescript-sdk/.nvmrc'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: pnpm build
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: npm publish
|
run: pnpm publish
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|||||||
10
.github/workflows/static_analysis.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
@@ -47,7 +47,7 @@ jobs:
|
|||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
|
|
||||||
- name: Generate translation file
|
- name: Generate translation file
|
||||||
run: make translation
|
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||||
|
|
||||||
- name: Run Build Runner
|
- name: Run Build Runner
|
||||||
run: make build
|
run: make build
|
||||||
@@ -116,7 +116,7 @@ jobs:
|
|||||||
actions: read
|
actions: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ jobs:
|
|||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Upload SARIF file
|
- name: Upload SARIF file
|
||||||
uses: github/codeql-action/upload-sarif@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4
|
uses: github/codeql-action/upload-sarif@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
category: zizmor
|
category: zizmor
|
||||||
|
|||||||
498
.github/workflows/test.yml
vendored
@@ -4,13 +4,10 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-job:
|
pre-job:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -29,10 +26,9 @@ jobs:
|
|||||||
should_run_.github: ${{ steps.found_paths.outputs['.github'] == 'true' || steps.should_force.outputs.should_force == 'true' }} # redundant to have should_force but if someone changes the trigger then this won't have to be changed
|
should_run_.github: ${{ steps.found_paths.outputs['.github'] == 'true' || steps.should_force.outputs.should_force == 'true' }} # redundant to have should_force but if someone changes the trigger then this won't have to be changed
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||||
with:
|
with:
|
||||||
@@ -58,11 +54,9 @@ jobs:
|
|||||||
- '.github/workflows/test.yml'
|
- '.github/workflows/test.yml'
|
||||||
.github:
|
.github:
|
||||||
- '.github/**'
|
- '.github/**'
|
||||||
|
|
||||||
- name: Check if we should force jobs to run
|
- name: Check if we should force jobs to run
|
||||||
id: should_force
|
id: should_force
|
||||||
run: echo "should_force=${{ steps.found_paths.outputs.workflow == 'true' || github.event_name == 'workflow_dispatch' }}" >> "$GITHUB_OUTPUT"
|
run: echo "should_force=${{ steps.found_paths.outputs.workflow == 'true' || github.event_name == 'workflow_dispatch' }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
server-unit-tests:
|
server-unit-tests:
|
||||||
name: Test & Lint Server
|
name: Test & Lint Server
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -73,39 +67,33 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./server
|
working-directory: ./server
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
- name: Run package manager install
|
||||||
- name: Run npm install
|
run: pnpm install
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run linter
|
- name: Run linter
|
||||||
run: npm run lint
|
run: pnpm lint
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: npm run check
|
run: pnpm check
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run small tests & coverage
|
- name: Run small tests & coverage
|
||||||
run: npm test
|
run: pnpm test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
cli-unit-tests:
|
cli-unit-tests:
|
||||||
name: Unit Test CLI
|
name: Unit Test CLI
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -116,43 +104,36 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./cli
|
working-directory: ./cli
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Setup typescript-sdk
|
- name: Setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install && pnpm run build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: npm ci
|
run: pnpm install
|
||||||
|
|
||||||
- name: Run linter
|
- name: Run linter
|
||||||
run: npm run lint
|
run: pnpm lint
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: npm run check
|
run: pnpm check
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run unit tests & coverage
|
- name: Run unit tests & coverage
|
||||||
run: npm run test
|
run: pnpm test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
cli-unit-tests-win:
|
cli-unit-tests-win:
|
||||||
name: Unit Test CLI (Windows)
|
name: Unit Test CLI (Windows)
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -163,36 +144,31 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./cli
|
working-directory: ./cli
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Setup typescript-sdk
|
- name: Setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
# Skip linter & formatter in Windows test.
|
# Skip linter & formatter in Windows test.
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: npm run check
|
run: pnpm check
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run unit tests & coverage
|
- name: Run unit tests & coverage
|
||||||
run: npm run test
|
run: pnpm test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
web-lint:
|
web-lint:
|
||||||
name: Lint Web
|
name: Lint Web
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -203,39 +179,33 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./web
|
working-directory: ./web
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run setup typescript-sdk
|
- name: Run setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
|
- name: Run pnpm install
|
||||||
- name: Run npm install
|
run: pnpm rebuild && pnpm install --frozen-lockfile
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run linter
|
- name: Run linter
|
||||||
run: npm run lint:p
|
run: pnpm lint:p
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run svelte checks
|
- name: Run svelte checks
|
||||||
run: npm run check:svelte
|
run: pnpm check:svelte
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
web-unit-tests:
|
web-unit-tests:
|
||||||
name: Test Web
|
name: Test Web
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -246,35 +216,30 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./web
|
working-directory: ./web
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run setup typescript-sdk
|
- name: Run setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
|
|
||||||
- name: Run npm install
|
- name: Run npm install
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: npm run check:typescript
|
run: pnpm check:typescript
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run unit tests & coverage
|
- name: Run unit tests & coverage
|
||||||
run: npm run test
|
run: pnpm test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
i18n-tests:
|
i18n-tests:
|
||||||
name: Test i18n
|
name: Test i18n
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -284,30 +249,27 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm --prefix=web ci
|
run: pnpm --filter=immich-web install --frozen-lockfile
|
||||||
|
|
||||||
- name: Format
|
- name: Format
|
||||||
run: npm --prefix=web run format:i18n
|
run: pnpm --filter=immich-web format:i18n
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
i18n/**
|
i18n/**
|
||||||
|
|
||||||
- name: Verify files have not changed
|
- name: Verify files have not changed
|
||||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||||
env:
|
env:
|
||||||
@@ -316,7 +278,6 @@ jobs:
|
|||||||
echo "ERROR: i18n files not up to date!"
|
echo "ERROR: i18n files not up to date!"
|
||||||
echo "Changed files: ${CHANGED_FILES}"
|
echo "Changed files: ${CHANGED_FILES}"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
e2e-tests-lint:
|
e2e-tests-lint:
|
||||||
name: End-to-End Lint
|
name: End-to-End Lint
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -327,41 +288,35 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./e2e
|
working-directory: ./e2e
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run setup typescript-sdk
|
- name: Run setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run linter
|
- name: Run linter
|
||||||
run: npm run lint
|
run: pnpm lint
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: npm run check
|
run: pnpm check
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
server-medium-tests:
|
server-medium-tests:
|
||||||
name: Medium Tests (Server)
|
name: Medium Tests (Server)
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -372,27 +327,24 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./server
|
working-directory: ./server
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
- name: Run pnpm install
|
||||||
- name: Run npm install
|
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run medium tests
|
- name: Run medium tests
|
||||||
run: npm run test:medium
|
run: pnpm test:medium
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
e2e-tests-server-cli:
|
e2e-tests-server-cli:
|
||||||
name: End-to-End Tests (Server & CLI)
|
name: End-to-End Tests (Server & CLI)
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -406,43 +358,41 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run setup typescript-sdk
|
- name: Run setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
- name: Run setup web
|
||||||
|
run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync
|
||||||
|
working-directory: ./web
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
- name: Run setup cli
|
- name: Run setup cli
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./cli
|
working-directory: ./cli
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Docker build
|
- name: Docker build
|
||||||
run: docker compose build
|
run: docker compose build
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run e2e tests (api & cli)
|
- name: Run e2e tests (api & cli)
|
||||||
run: npm run test
|
run: pnpm test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
e2e-tests-web:
|
e2e-tests-web:
|
||||||
name: End-to-End Tests (Web)
|
name: End-to-End Tests (Web)
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -456,42 +406,36 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Run setup typescript-sdk
|
- name: Run setup typescript-sdk
|
||||||
run: npm ci && npm run build
|
run: pnpm install --frozen-lockfile && pnpm build
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: pnpm install --frozen-lockfile
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: npx playwright install chromium --only-shell
|
run: npx playwright install chromium --only-shell
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Docker build
|
- name: Docker build
|
||||||
run: docker compose build
|
run: docker compose build
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run e2e tests (web)
|
- name: Run e2e tests (web)
|
||||||
run: npx playwright test
|
run: npx playwright test
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
success-check-e2e:
|
success-check-e2e:
|
||||||
name: End-to-End Tests Success
|
name: End-to-End Tests Success
|
||||||
needs: [e2e-tests-server-cli, e2e-tests-web]
|
needs: [e2e-tests-server-cli, e2e-tests-web]
|
||||||
@@ -502,7 +446,6 @@ jobs:
|
|||||||
- uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4
|
- uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4
|
||||||
with:
|
with:
|
||||||
needs: ${{ toJSON(needs) }}
|
needs: ${{ toJSON(needs) }}
|
||||||
|
|
||||||
mobile-unit-tests:
|
mobile-unit-tests:
|
||||||
name: Unit Test Mobile
|
name: Unit Test Mobile
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -511,24 +454,20 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Setup Flutter SDK
|
- name: Setup Flutter SDK
|
||||||
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
|
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
|
||||||
with:
|
with:
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
flutter-version-file: ./mobile/pubspec.yaml
|
flutter-version-file: ./mobile/pubspec.yaml
|
||||||
|
|
||||||
- name: Generate translation file
|
- name: Generate translation file
|
||||||
run: make translation
|
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
run: flutter test -j 1
|
run: flutter test -j 1
|
||||||
|
|
||||||
ml-unit-tests:
|
ml-unit-tests:
|
||||||
name: Unit Test ML
|
name: Unit Test ML
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -540,10 +479,9 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
working-directory: ./machine-learning
|
working-directory: ./machine-learning
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
|
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
@@ -566,7 +504,6 @@ jobs:
|
|||||||
- name: Run tests and coverage
|
- name: Run tests and coverage
|
||||||
run: |
|
run: |
|
||||||
uv run pytest --cov=immich_ml --cov-report term-missing
|
uv run pytest --cov=immich_ml --cov-report term-missing
|
||||||
|
|
||||||
github-files-formatting:
|
github-files-formatting:
|
||||||
name: .github Files Formatting
|
name: .github Files Formatting
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -577,45 +514,38 @@ jobs:
|
|||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./.github
|
working-directory: ./.github
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './.github/.nvmrc'
|
node-version-file: './.github/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
- name: Run pnpm install
|
||||||
- name: Run npm install
|
run: pnpm install --frozen-lockfile
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: npm run format
|
run: pnpm format
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
shellcheck:
|
shellcheck:
|
||||||
name: ShellCheck
|
name: ShellCheck
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Run ShellCheck
|
- name: Run ShellCheck
|
||||||
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0
|
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0
|
||||||
with:
|
with:
|
||||||
ignore_paths: >-
|
ignore_paths: >-
|
||||||
**/open-api/**
|
**/open-api/** **/openapi** **/node_modules/**
|
||||||
**/openapi**
|
|
||||||
**/node_modules/**
|
|
||||||
|
|
||||||
generated-api-up-to-date:
|
generated-api-up-to-date:
|
||||||
name: OpenAPI Clients
|
name: OpenAPI Clients
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -623,26 +553,24 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Install server dependencies
|
- name: Install server dependencies
|
||||||
run: npm --prefix=server ci
|
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich install --frozen-lockfile
|
||||||
|
|
||||||
- name: Build the app
|
- name: Build the app
|
||||||
run: npm --prefix=server run build
|
run: pnpm --filter immich build
|
||||||
|
|
||||||
- name: Run API generation
|
- name: Run API generation
|
||||||
run: make open-api
|
run: ./bin/generate-open-api.sh
|
||||||
|
working-directory: open-api
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
@@ -651,7 +579,6 @@ jobs:
|
|||||||
mobile/openapi
|
mobile/openapi
|
||||||
open-api/typescript-sdk
|
open-api/typescript-sdk
|
||||||
open-api/immich-openapi-specs.json
|
open-api/immich-openapi-specs.json
|
||||||
|
|
||||||
- name: Verify files have not changed
|
- name: Verify files have not changed
|
||||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||||
env:
|
env:
|
||||||
@@ -660,7 +587,6 @@ jobs:
|
|||||||
echo "ERROR: Generated files not up to date!"
|
echo "ERROR: Generated files not up to date!"
|
||||||
echo "Changed files: ${CHANGED_FILES}"
|
echo "Changed files: ${CHANGED_FILES}"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
sql-schema-up-to-date:
|
sql-schema-up-to-date:
|
||||||
name: SQL Schema Checks
|
name: SQL Schema Checks
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -668,51 +594,42 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3@sha256:ec713143dca1a426eba2e03707c319e2ec3cc9d304ef767f777f8e297dee820c
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3@sha256:4f7ee144d4738ad02f6d9376defed7a767b748d185d47eba241578c26a63064b
|
||||||
env:
|
env:
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
POSTGRES_DB: immich
|
POSTGRES_DB: immich
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd pg_isready
|
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: ./server
|
working-directory: ./server
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'npm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
- name: Install server dependencies
|
- name: Install server dependencies
|
||||||
run: npm ci
|
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Build the app
|
- name: Build the app
|
||||||
run: npm run build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Run existing migrations
|
- name: Run existing migrations
|
||||||
run: npm run migrations:run
|
run: pnpm migrations:run
|
||||||
|
|
||||||
- name: Test npm run schema:reset command works
|
- name: Test npm run schema:reset command works
|
||||||
run: npm run schema:reset
|
run: pnpm schema:reset
|
||||||
|
|
||||||
- name: Generate new migrations
|
- name: Generate new migrations
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: npm run migrations:generate src/TestMigration
|
run: pnpm migrations:generate src/TestMigration
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
@@ -728,19 +645,16 @@ jobs:
|
|||||||
echo "Changed files: ${CHANGED_FILES}"
|
echo "Changed files: ${CHANGED_FILES}"
|
||||||
cat ./src/*-TestMigration.ts
|
cat ./src/*-TestMigration.ts
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
- name: Run SQL generation
|
- name: Run SQL generation
|
||||||
run: npm run sync:sql
|
run: pnpm sync:sql
|
||||||
env:
|
env:
|
||||||
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||||
id: verify-changed-sql-files
|
id: verify-changed-sql-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
server/src/queries
|
server/src/queries
|
||||||
|
|
||||||
- name: Verify SQL files have not changed
|
- name: Verify SQL files have not changed
|
||||||
if: steps.verify-changed-sql-files.outputs.files_changed == 'true'
|
if: steps.verify-changed-sql-files.outputs.files_changed == 'true'
|
||||||
env:
|
env:
|
||||||
@@ -751,77 +665,77 @@ jobs:
|
|||||||
git diff
|
git diff
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
# mobile-integration-tests:
|
# mobile-integration-tests:
|
||||||
# name: Run mobile end-to-end integration tests
|
# name: Run mobile end-to-end integration tests
|
||||||
# runs-on: macos-latest
|
# runs-on: macos-latest
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
# - uses: actions/setup-java@v3
|
# - uses: actions/setup-java@v3
|
||||||
# with:
|
# with:
|
||||||
# distribution: 'zulu'
|
# distribution: 'zulu'
|
||||||
# java-version: '12.x'
|
# java-version: '12.x'
|
||||||
# cache: 'gradle'
|
# cache: 'gradle'
|
||||||
# - name: Cache android SDK
|
# - name: Cache android SDK
|
||||||
# uses: actions/cache@v3
|
# uses: actions/cache@v3
|
||||||
# id: android-sdk
|
# id: android-sdk
|
||||||
# with:
|
# with:
|
||||||
# key: android-sdk
|
# key: android-sdk
|
||||||
# path: |
|
# path: |
|
||||||
# /usr/local/lib/android/
|
# /usr/local/lib/android/
|
||||||
# ~/.android
|
# ~/.android
|
||||||
# - name: Cache Gradle
|
# - name: Cache Gradle
|
||||||
# uses: actions/cache@v3
|
# uses: actions/cache@v3
|
||||||
# with:
|
# with:
|
||||||
# path: |
|
# path: |
|
||||||
# ./mobile/build/
|
# ./mobile/build/
|
||||||
# ./mobile/android/.gradle/
|
# ./mobile/android/.gradle/
|
||||||
# key: ${{ runner.os }}-flutter-${{ hashFiles('**/*.gradle*', 'pubspec.lock') }}
|
# key: ${{ runner.os }}-flutter-${{ hashFiles('**/*.gradle*', 'pubspec.lock') }}
|
||||||
# - name: Setup Android SDK
|
# - name: Setup Android SDK
|
||||||
# if: steps.android-sdk.outputs.cache-hit != 'true'
|
# if: steps.android-sdk.outputs.cache-hit != 'true'
|
||||||
# uses: android-actions/setup-android@v2
|
# uses: android-actions/setup-android@v2
|
||||||
# - name: AVD cache
|
# - name: AVD cache
|
||||||
# uses: actions/cache@v3
|
# uses: actions/cache@v3
|
||||||
# id: avd-cache
|
# id: avd-cache
|
||||||
# with:
|
# with:
|
||||||
# path: |
|
# path: |
|
||||||
# ~/.android/avd/*
|
# ~/.android/avd/*
|
||||||
# ~/.android/adb*
|
# ~/.android/adb*
|
||||||
# key: avd-29
|
# key: avd-29
|
||||||
# - name: create AVD and generate snapshot for caching
|
# - name: create AVD and generate snapshot for caching
|
||||||
# if: steps.avd-cache.outputs.cache-hit != 'true'
|
# if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
# uses: reactivecircus/android-emulator-runner@v2.27.0
|
# uses: reactivecircus/android-emulator-runner@v2.27.0
|
||||||
# with:
|
# with:
|
||||||
# working-directory: ./mobile
|
# working-directory: ./mobile
|
||||||
# cores: 2
|
# cores: 2
|
||||||
# api-level: 29
|
# api-level: 29
|
||||||
# arch: x86_64
|
# arch: x86_64
|
||||||
# profile: pixel
|
# profile: pixel
|
||||||
# target: default
|
# target: default
|
||||||
# force-avd-creation: false
|
# force-avd-creation: false
|
||||||
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
# disable-animations: false
|
# disable-animations: false
|
||||||
# script: echo "Generated AVD snapshot for caching."
|
# script: echo "Generated AVD snapshot for caching."
|
||||||
# - name: Setup Flutter SDK
|
# - name: Setup Flutter SDK
|
||||||
# uses: subosito/flutter-action@v2
|
# uses: subosito/flutter-action@v2
|
||||||
# with:
|
# with:
|
||||||
# channel: 'stable'
|
# channel: 'stable'
|
||||||
# flutter-version: '3.7.3'
|
# flutter-version: '3.7.3'
|
||||||
# cache: true
|
# cache: true
|
||||||
# - name: Run integration tests
|
# - name: Run integration tests
|
||||||
# uses: Wandalen/wretry.action@master
|
# uses: Wandalen/wretry.action@master
|
||||||
# with:
|
# with:
|
||||||
# action: reactivecircus/android-emulator-runner@v2.27.0
|
# action: reactivecircus/android-emulator-runner@v2.27.0
|
||||||
# with: |
|
# with: |
|
||||||
# working-directory: ./mobile
|
# working-directory: ./mobile
|
||||||
# cores: 2
|
# cores: 2
|
||||||
# api-level: 29
|
# api-level: 29
|
||||||
# arch: x86_64
|
# arch: x86_64
|
||||||
# profile: pixel
|
# profile: pixel
|
||||||
# target: default
|
# target: default
|
||||||
# force-avd-creation: false
|
# force-avd-creation: false
|
||||||
# emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
# emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
# disable-animations: true
|
# disable-animations: true
|
||||||
# script: |
|
# script: |
|
||||||
# flutter pub get
|
# flutter pub get
|
||||||
# flutter test integration_test
|
# flutter test integration_test
|
||||||
# attempt_limit: 3
|
# attempt_limit: 3
|
||||||
|
|||||||
25
.github/workflows/weblate-lock.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: Weblate checks
|
name: Weblate checks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
pull_request_review:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
@@ -12,10 +13,10 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
outputs:
|
outputs:
|
||||||
should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}
|
should_run: ${{ steps.found_paths.outputs.i18n == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
@@ -32,19 +33,15 @@ jobs:
|
|||||||
permissions: {}
|
permissions: {}
|
||||||
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check weblate lock
|
- name: Bot review status
|
||||||
|
env:
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number || github.event.pull_request_review.pull_request.number }}
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
if [[ "false" = $(curl https://hosted.weblate.org/api/components/immich/immich/lock/ | jq .locked) ]]; then
|
# Then check for APPROVED by the bot, if absent fail
|
||||||
exit 1
|
gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json reviews | jq -e '.reviews | map(select(.author.login == "github-actions[bot]" and .state == "APPROVED")) | length > 0' \
|
||||||
fi
|
|| (echo "The push-o-matic bot has not approved this PR yet" && exit 1)
|
||||||
- name: Find Pull Request
|
|
||||||
uses: juliangruber/find-pull-request-action@952b3bb1ddb2dcc0aa3479e98bb1c2d1a922f096 # v1.10.0
|
|
||||||
id: find-pr
|
|
||||||
with:
|
|
||||||
branch: chore/translations
|
|
||||||
- name: Fail if existing weblate PR
|
|
||||||
if: ${{ steps.find-pr.outputs.number }}
|
|
||||||
run: exit 1
|
|
||||||
success-check-lock:
|
success-check-lock:
|
||||||
name: Weblate Lock Check Success
|
name: Weblate Lock Check Success
|
||||||
needs: [enforce-lock]
|
needs: [enforce-lock]
|
||||||
|
|||||||
2
.gitignore
vendored
@@ -25,3 +25,5 @@ mobile/ios/fastlane/report.xml
|
|||||||
|
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
|
.devcontainer/library
|
||||||
|
.devcontainer/.env*
|
||||||
|
|||||||
18
.pnpmfile.cjs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
hooks: {
|
||||||
|
readPackage: (pkg) => {
|
||||||
|
if (!pkg.name) {
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
if (pkg.name === "exiftool-vendored") {
|
||||||
|
if (pkg.optionalDependencies["exiftool-vendored.pl"]) {
|
||||||
|
// make exiftool-vendored.pl a regular dependency
|
||||||
|
pkg.dependencies["exiftool-vendored.pl"] =
|
||||||
|
pkg.optionalDependencies["exiftool-vendored.pl"];
|
||||||
|
delete pkg.optionalDependencies["exiftool-vendored.pl"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pkg;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
3
.vscode/settings.json
vendored
@@ -56,7 +56,8 @@
|
|||||||
"explorer.fileNesting.enabled": true,
|
"explorer.fileNesting.enabled": true,
|
||||||
"explorer.fileNesting.patterns": {
|
"explorer.fileNesting.patterns": {
|
||||||
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
||||||
"*.ts": "${capture}.spec.ts,${capture}.mock.ts"
|
"*.ts": "${capture}.spec.ts,${capture}.mock.ts",
|
||||||
|
"package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, bun.lock, pnpm-workspace.yaml, .pnpmfile.cjs"
|
||||||
},
|
},
|
||||||
"svelte.enable-ts-plugin": true,
|
"svelte.enable-ts-plugin": true,
|
||||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||||
|
|||||||
143
Makefile
@@ -1,18 +1,21 @@
|
|||||||
dev:
|
dev: prepare-volumes
|
||||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
||||||
|
|
||||||
dev-down:
|
dev-down:
|
||||||
docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans
|
docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans
|
||||||
|
|
||||||
dev-update:
|
dev-update: prepare-volumes
|
||||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
dev-scale:
|
dev-scale: prepare-volumes
|
||||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
|
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
|
||||||
|
|
||||||
|
dev-docs:
|
||||||
|
npm --prefix docs run start
|
||||||
|
|
||||||
.PHONY: e2e
|
.PHONY: e2e
|
||||||
e2e:
|
e2e:
|
||||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
|
||||||
|
|
||||||
e2e-update:
|
e2e-update:
|
||||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
||||||
@@ -30,17 +33,17 @@ prod-scale:
|
|||||||
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
|
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
|
||||||
|
|
||||||
.PHONY: open-api
|
.PHONY: open-api
|
||||||
open-api:
|
open-api: prepare-volumes
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh
|
cd ./open-api && bash ./bin/generate-open-api.sh
|
||||||
|
|
||||||
open-api-dart:
|
open-api-dart: prepare-volumes
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh dart
|
cd ./open-api && bash ./bin/generate-open-api.sh dart
|
||||||
|
|
||||||
open-api-typescript:
|
open-api-typescript: prepare-volumes
|
||||||
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
||||||
|
|
||||||
sql:
|
sql: prepare-volumes
|
||||||
npm --prefix server run sync:sql
|
pnpm --filter immich run sync:sql
|
||||||
|
|
||||||
attach-server:
|
attach-server:
|
||||||
docker exec -it docker_immich-server_1 sh
|
docker exec -it docker_immich-server_1 sh
|
||||||
@@ -48,33 +51,87 @@ attach-server:
|
|||||||
renovate:
|
renovate:
|
||||||
LOG_LEVEL=debug npx renovate --platform=local --repository-cache=reset
|
LOG_LEVEL=debug npx renovate --platform=local --repository-cache=reset
|
||||||
|
|
||||||
|
# Directories that need to be created for volumes or build output
|
||||||
|
VOLUME_DIRS = \
|
||||||
|
./.pnpm-store \
|
||||||
|
./web/.svelte-kit \
|
||||||
|
./web/node_modules \
|
||||||
|
./web/coverage \
|
||||||
|
./e2e/node_modules \
|
||||||
|
./docs/node_modules \
|
||||||
|
./server/node_modules \
|
||||||
|
./open-api/typescript-sdk/node_modules \
|
||||||
|
./.github/node_modules \
|
||||||
|
./node_modules \
|
||||||
|
./cli/node_modules
|
||||||
|
|
||||||
|
# Include .env file if it exists
|
||||||
|
-include docker/.env
|
||||||
|
|
||||||
|
# Helper function to chown, on error suggest remediation and exit
|
||||||
|
define safe_chown
|
||||||
|
if chown $(2) $(or $(UID),1000):$(or $(GID),1000) "$(1)" 2>/dev/null; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
STATUS=$$?; echo "Exit code: $$STATUS $(1)"; \
|
||||||
|
echo "$$STATUS $(1)"; \
|
||||||
|
echo "Permission denied when changing owner of volumes and upload location. Try running 'sudo make prepare-volumes' first."; \
|
||||||
|
exit 1; \
|
||||||
|
fi;
|
||||||
|
endef
|
||||||
|
# create empty directories and chown
|
||||||
|
prepare-volumes:
|
||||||
|
@$(foreach dir,$(VOLUME_DIRS),mkdir -p $(dir);)
|
||||||
|
@$(foreach dir,$(VOLUME_DIRS),$(call safe_chown,$(dir),-R))
|
||||||
|
ifneq ($(UPLOAD_LOCATION),)
|
||||||
|
ifeq ($(filter /%,$(UPLOAD_LOCATION)),)
|
||||||
|
@mkdir -p "docker/$(UPLOAD_LOCATION)/photos/upload"
|
||||||
|
@$(call safe_chown,docker/$(UPLOAD_LOCATION),)
|
||||||
|
@$(call safe_chown,docker/$(UPLOAD_LOCATION)/photos,-R)
|
||||||
|
else
|
||||||
|
@mkdir -p "$(UPLOAD_LOCATION)/photos/upload"
|
||||||
|
@$(call safe_chown,$(UPLOAD_LOCATION),)
|
||||||
|
@$(call safe_chown,$(UPLOAD_LOCATION)/photos,-R)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
MODULES = e2e server web cli sdk docs .github
|
MODULES = e2e server web cli sdk docs .github
|
||||||
|
|
||||||
|
# directory to package name mapping function
|
||||||
|
# cli = @immich/cli
|
||||||
|
# docs = documentation
|
||||||
|
# e2e = immich-e2e
|
||||||
|
# open-api/typescript-sdk = @immich/sdk
|
||||||
|
# server = immich
|
||||||
|
# web = immich-web
|
||||||
|
map-package = $(subst sdk,@immich/sdk,$(subst cli,@immich/cli,$(subst docs,documentation,$(subst e2e,immich-e2e,$(subst server,immich,$(subst web,immich-web,$1))))))
|
||||||
|
|
||||||
audit-%:
|
audit-%:
|
||||||
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) audit fix
|
pnpm --filter $(call map-package,$*) audit fix
|
||||||
install-%:
|
install-%:
|
||||||
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) i
|
pnpm --filter $(call map-package,$*) install $(if $(FROZEN),--frozen-lockfile) $(if $(OFFLINE),--offline)
|
||||||
ci-%:
|
|
||||||
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) ci
|
|
||||||
build-cli: build-sdk
|
build-cli: build-sdk
|
||||||
build-web: build-sdk
|
build-web: build-sdk
|
||||||
build-%: install-%
|
build-%: install-%
|
||||||
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) run build
|
pnpm --filter $(call map-package,$*) run build
|
||||||
format-%:
|
format-%:
|
||||||
npm --prefix $* run format:fix
|
pnpm --filter $(call map-package,$*) run format:fix
|
||||||
lint-%:
|
lint-%:
|
||||||
npm --prefix $* run lint:fix
|
pnpm --filter $(call map-package,$*) run lint:fix
|
||||||
|
lint-web:
|
||||||
|
pnpm --filter $(call map-package,$*) run lint:p
|
||||||
check-%:
|
check-%:
|
||||||
npm --prefix $* run check
|
pnpm --filter $(call map-package,$*) run check
|
||||||
check-web:
|
check-web:
|
||||||
npm --prefix web run check:typescript
|
pnpm --filter immich-web run check:typescript
|
||||||
npm --prefix web run check:svelte
|
pnpm --filter immich-web run check:svelte
|
||||||
test-%:
|
test-%:
|
||||||
npm --prefix $* run test
|
pnpm --filter $(call map-package,$*) run test
|
||||||
test-e2e:
|
test-e2e:
|
||||||
docker compose -f ./e2e/docker-compose.yml build
|
docker compose -f ./e2e/docker-compose.yml build
|
||||||
npm --prefix e2e run test
|
pnpm --filter immich-e2e run test
|
||||||
npm --prefix e2e run test:web
|
pnpm --filter immich-e2e run test:web
|
||||||
test-medium:
|
test-medium:
|
||||||
docker run \
|
docker run \
|
||||||
--rm \
|
--rm \
|
||||||
@@ -84,27 +141,39 @@ test-medium:
|
|||||||
-v ./server/tsconfig.json:/usr/src/app/tsconfig.json \
|
-v ./server/tsconfig.json:/usr/src/app/tsconfig.json \
|
||||||
-e NODE_ENV=development \
|
-e NODE_ENV=development \
|
||||||
immich-server:latest \
|
immich-server:latest \
|
||||||
-c "npm ci && npm run test:medium -- --run"
|
-c "pnpm test:medium -- --run"
|
||||||
test-medium-dev:
|
test-medium-dev:
|
||||||
docker exec -it immich_server /bin/sh -c "npm run test:medium"
|
docker exec -it immich_server /bin/sh -c "pnpm run test:medium"
|
||||||
|
|
||||||
build-all: $(foreach M,$(filter-out e2e .github,$(MODULES)),build-$M) ;
|
install-all:
|
||||||
install-all: $(foreach M,$(MODULES),install-$M) ;
|
pnpm -r --filter '!documentation' install
|
||||||
ci-all: $(foreach M,$(filter-out .github,$(MODULES)),ci-$M) ;
|
|
||||||
check-all: $(foreach M,$(filter-out sdk cli docs .github,$(MODULES)),check-$M) ;
|
build-all: $(foreach M,$(filter-out e2e docs .github,$(MODULES)),build-$M) ;
|
||||||
lint-all: $(foreach M,$(filter-out sdk docs .github,$(MODULES)),lint-$M) ;
|
|
||||||
format-all: $(foreach M,$(filter-out sdk,$(MODULES)),format-$M) ;
|
check-all:
|
||||||
audit-all: $(foreach M,$(MODULES),audit-$M) ;
|
pnpm -r --filter '!documentation' run "/^(check|check\:svelte|check\:typescript)$/"
|
||||||
hygiene-all: lint-all format-all check-all sql audit-all;
|
lint-all:
|
||||||
test-all: $(foreach M,$(filter-out sdk docs .github,$(MODULES)),test-$M) ;
|
pnpm -r --filter '!documentation' run lint:fix
|
||||||
|
format-all:
|
||||||
|
pnpm -r --filter '!documentation' run format:fix
|
||||||
|
audit-all:
|
||||||
|
pnpm -r --filter '!documentation' audit fix
|
||||||
|
hygiene-all: audit-all
|
||||||
|
pnpm -r --filter '!documentation' run "/(format:fix|check|check:svelte|check:typescript|sql)/"
|
||||||
|
|
||||||
|
test-all:
|
||||||
|
pnpm -r --filter '!documentation' run "/^test/"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
find . -name "node_modules" -type d -prune -exec rm -rf {} +
|
find . -name "node_modules" -type d -prune -exec rm -rf {} +
|
||||||
find . -name "dist" -type d -prune -exec rm -rf '{}' +
|
find . -name "dist" -type d -prune -exec rm -rf '{}' +
|
||||||
find . -name "build" -type d -prune -exec rm -rf '{}' +
|
find . -name "build" -type d -prune -exec rm -rf '{}' +
|
||||||
find . -name "svelte-kit" -type d -prune -exec rm -rf '{}' +
|
find . -name ".svelte-kit" -type d -prune -exec rm -rf '{}' +
|
||||||
command -v docker >/dev/null 2>&1 && docker compose -f ./docker/docker-compose.dev.yml rm -v -f || true
|
find . -name "coverage" -type d -prune -exec rm -rf '{}' +
|
||||||
command -v docker >/dev/null 2>&1 && docker compose -f ./e2e/docker-compose.yml rm -v -f || true
|
find . -name ".pnpm-store" -type d -prune -exec rm -rf '{}' +
|
||||||
|
command -v docker >/dev/null 2>&1 && docker compose -f ./docker/docker-compose.dev.yml down -v --remove-orphans || true
|
||||||
|
command -v docker >/dev/null 2>&1 && docker compose -f ./e2e/docker-compose.yml down -v --remove-orphans || true
|
||||||
|
|
||||||
|
|
||||||
setup-server-dev: install-server
|
setup-server-dev: install-server
|
||||||
setup-web-dev: install-sdk build-sdk install-web
|
setup-web-dev: install-sdk build-sdk install-web
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
22.17.1
|
22.19.0
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
FROM node:22.16.0-alpine3.20@sha256:2289fb1fba0f4633b08ec47b94a89c7e20b829fc5679f9b7b298eaa2f1ed8b7e AS core
|
FROM node:22.16.0-alpine3.20@sha256:2289fb1fba0f4633b08ec47b94a89c7e20b829fc5679f9b7b298eaa2f1ed8b7e AS core
|
||||||
|
|
||||||
WORKDIR /usr/src/open-api/typescript-sdk
|
|
||||||
COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./
|
|
||||||
RUN npm ci
|
|
||||||
COPY open-api/typescript-sdk/ ./
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
COPY package* pnpm* .pnpmfile.cjs ./
|
||||||
COPY cli/package.json cli/package-lock.json ./
|
COPY ./cli ./cli/
|
||||||
RUN npm ci
|
COPY ./open-api/typescript-sdk ./open-api/typescript-sdk/
|
||||||
|
RUN corepack enable pnpm && \
|
||||||
COPY cli .
|
pnpm install --filter @immich/sdk --filter @immich/cli --frozen-lockfile && \
|
||||||
RUN npm run build
|
pnpm --filter @immich/sdk build && \
|
||||||
|
pnpm --filter @immich/cli build
|
||||||
|
|
||||||
WORKDIR /import
|
WORKDIR /import
|
||||||
|
|
||||||
ENTRYPOINT ["node", "/usr/src/app/dist"]
|
ENTRYPOINT ["node", "/usr/src/app/cli/dist"]
|
||||||
|
|||||||
4632
cli/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.73",
|
"version": "2.2.88",
|
||||||
"description": "Command Line Interface (CLI) for Immich",
|
"description": "Command Line Interface (CLI) for Immich",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
"cli"
|
"cli"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.1.0",
|
|
||||||
"@eslint/js": "^9.8.0",
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@types/byte-size": "^8.1.0",
|
"@types/byte-size": "^8.1.0",
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/micromatch": "^4.0.9",
|
"@types/micromatch": "^4.0.9",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/node": "^22.16.5",
|
"@types/node": "^22.18.0",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
"byte-size": "^9.0.0",
|
"byte-size": "^9.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
@@ -29,7 +28,7 @@
|
|||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^59.0.0",
|
"eslint-plugin-unicorn": "^60.0.0",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
@@ -69,6 +68,6 @@
|
|||||||
"micromatch": "^4.0.8"
|
"micromatch": "^4.0.8"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "22.17.1"
|
"node": "22.19.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,37 +2,37 @@
|
|||||||
# Manual edits may be lost in future updates.
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||||
version = "4.52.1"
|
version = "4.52.3"
|
||||||
constraints = "4.52.1"
|
constraints = "4.52.3"
|
||||||
hashes = [
|
hashes = [
|
||||||
"h1:2lHvafwGbLdmc9lYkuJFw3nsInaQjRpjX/JfIRKmq/M=",
|
"h1:3jU62KY4Oj3xzMwkTQWon1nlIvFkgTCqI93IzUGaa0c=",
|
||||||
"h1:596JomwjrtUrOSreq9NNCS+rj70+jOV+0pfja5MXiTI=",
|
"h1:BWimtYXrvbzbbuoVcyobjQnXjjOb9X69JFTw+GuPxfk=",
|
||||||
"h1:7mBOA5TVAIt3qAwPXKCtE0RSYeqij9v30mnksuBbpEg=",
|
"h1:C/KvLEm8dVQ6zG2X4asLDtmw2JW/xu7E8MddtaXniO0=",
|
||||||
"h1:ELVgzh4kHKBCYdL+2A8JjWS0E1snLUN3Mmz3Vo6qSfw=",
|
"h1:Doo0xcLFf+CnfDWjsA7G1NvSLURuwcgyVy8k0NF1gJA=",
|
||||||
"h1:FGGM5yLFf72g3kSXM3LAN64Gf/AkXr5WCmhixgnP+l4=",
|
"h1:Gc3FGDtR8lUWsi9VImnnE5/USDXiIwYsv4Hbl+d2lwY=",
|
||||||
"h1:JupkJbQALcIVoMhHImrLeLDsQR1ET7VJLGC7ONxjqGU=",
|
"h1:HsDY6s1gup5fW9TeuTUy85QMIld1nDOUFlwsfxIq1ig=",
|
||||||
"h1:KsaE4JNq+1uV1nJsuTcYar/8lyY6zKS5UBEpfYg3wvc=",
|
"h1:MnHkB56E4b/kT6WZigsZJnB5rgnCfDVbrLBNxIsEXPY=",
|
||||||
"h1:NHZ5RJIzQDLhie/ykl3uI6UPfNQR9Lu5Ti7JPR6X904=",
|
"h1:O/FUQEqhtknJNdsaMbIBi2pLWBds2VvN5FsTVVntzb0=",
|
||||||
"h1:NfAuMbn6LQPLDtJhbzO1MX9JMIGLMa8K6CpekvtsuX8=",
|
"h1:OKQBynkp0J5DIf5FOl/NR3S2rvh89pY+t5wevYxdTJs=",
|
||||||
"h1:e+vNKokamDsp/kJvFr2pRudzwEz2r49iZ/oSggw+1LY=",
|
"h1:On+vPsYV8U/J/8wFZPXjeAgNJqFFQj42vNOKuNKURkY=",
|
||||||
"h1:jnb4VdfNZ79I3yj7Q8x+JmOT+FxbfjjRfrF0dL0yCW8=",
|
"h1:SPkrMRJahxK0uum7FnUugbGN/JepHMH8M71DBtYrvG0=",
|
||||||
"h1:kmF//O539d7NuHU7qIxDj7Wz4eJmLKFiI5glwQivldU=",
|
"h1:bEh1ASPMiin3F36+hTfjMQTBnuDl2DzjzSCdova3JEM=",
|
||||||
"h1:s6XriaKwOgV4jvKAGPXkrxhhOQxpNU5dceZwi9Z/1k8=",
|
"h1:dtIK+x5Q1sh5SMPaHBHXhL9XDIqbRW0EBmVZ+KHQB8E=",
|
||||||
"h1:wt3WBEBAeSGTlC9OlnTlAALxRiK4SQgLy0KgBIS7qzs=",
|
"h1:kZcwWfODMWWyauZ66oaO/X+xXkqBtrbYwfUFEtspwEc=",
|
||||||
"zh:2fb95e1d3229b9b6c704e1a413c7481c60f139780d9641f657b6eb9b633b90f2",
|
"zh:53946fce4a631f1d98c61550821c88edede9169dfe5cc254e09a2ab207f76b3f",
|
||||||
"zh:379c7680983383862236e9e6e720c3114195c40526172188e88d0ffcf50dfe2e",
|
"zh:61654a21f1dd4331492d4ef77e9ebff066bc01e1281f92b925e5697c9138d681",
|
||||||
"zh:55533beb6cfc02d22ffda8cba8027bc2c841bb172cd637ed0d28323d41395f8f",
|
"zh:6a54e9d129b276f052a2f1b73ad0b8735fe6a7403c6a8f6aa111e525eeefaf35",
|
||||||
"zh:5abd70760e4eb1f37a1c307cbd2989ea7c9ba0afb93818c67c1d363a31f75703",
|
"zh:7692374e655c346a630b5a7cd776c5e0b2388900dcd7ab69a3af85d0c31c6c43",
|
||||||
"zh:699f1c8cd66129176fe659ebf0e6337632a8967a28d2630b6ae5948665c0c2ae",
|
|
||||||
"zh:69c15acd73c451e89de6477059cda2f3ec200b48ae4b9ff3646c4d389fd3205e",
|
|
||||||
"zh:6e02b687de21b844f8266dff99e93e7c61fc8eb688f4bbb23803caceb251839e",
|
|
||||||
"zh:7a51d17b87ed87b7bebf2ad9fc7c3a74f16a1b44eee92c779c08eb89258c0496",
|
|
||||||
"zh:88ad84436837b0f55302f22748505972634e87400d6902260fd6b7ba1610f937",
|
|
||||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||||
"zh:8d46c3d9f4f7ad20ac6ef01daa63f4e30a2d16dcb1bb5c7c7ee3dc6be38e9ca1",
|
"zh:8fe5b792a4d2b1c3a0e573649642962494faa00299baa6aaf813b9a43203dc02",
|
||||||
"zh:913d64e72a4929dae1d4793e2004f4f9a58b138ea337d9d94fa35cafbf06550a",
|
"zh:a0f403a4862df90f09de65c6e939d6cfd069a8dda2dd33f82948bf6f5f1124ef",
|
||||||
"zh:c8d93cf86e2e49f6cec665cfe78b82c144cce15a8b2e30f343385fadd1251849",
|
"zh:a25dc3eb60777b600f8f125d321fe7c50b811c5302b58e9a727ceb749a04e35d",
|
||||||
"zh:cc4f69397d9bc34a528a5609a024c3a48f54f21616c0008792dd417297add955",
|
"zh:a2f2ac7dc703c69d2e8c67c9cb5620b5348cb4fd6b98515fbe3f478517b56602",
|
||||||
"zh:df99cdb8b064aad35ffea77e645cf6541d0b1b2ebc51b6d26c42031de60ab69e",
|
"zh:d452e7bd24445ee14166470cf50f3aca566d46cab5f26f1c5c988c0f3106b697",
|
||||||
|
"zh:e10a52b0294735659eb3f0821ad2006ec097918efe58d31d37a5e3c47efef5f6",
|
||||||
|
"zh:e28dd0954cef9f05adf4d4b440d6f134f605344dfa56307181996675e6550af2",
|
||||||
|
"zh:f1e3b2f43a472280442f01ba71a3c06c9167432e553381132ea5c4a77e0b6dd5",
|
||||||
|
"zh:f71fd63718d38fd43829861e91fe79e16d7b4c7c3d508ae3d077368d89b8e5a0",
|
||||||
|
"zh:faf8d3da4b819c4ae8e565d2b1a684c6a948a086cb299189a5e7b30b2178409d",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ terraform {
|
|||||||
required_providers {
|
required_providers {
|
||||||
cloudflare = {
|
cloudflare = {
|
||||||
source = "cloudflare/cloudflare"
|
source = "cloudflare/cloudflare"
|
||||||
version = "4.52.1"
|
version = "4.52.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,37 +2,37 @@
|
|||||||
# Manual edits may be lost in future updates.
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||||
version = "4.52.1"
|
version = "4.52.3"
|
||||||
constraints = "4.52.1"
|
constraints = "4.52.3"
|
||||||
hashes = [
|
hashes = [
|
||||||
"h1:2lHvafwGbLdmc9lYkuJFw3nsInaQjRpjX/JfIRKmq/M=",
|
"h1:3jU62KY4Oj3xzMwkTQWon1nlIvFkgTCqI93IzUGaa0c=",
|
||||||
"h1:596JomwjrtUrOSreq9NNCS+rj70+jOV+0pfja5MXiTI=",
|
"h1:BWimtYXrvbzbbuoVcyobjQnXjjOb9X69JFTw+GuPxfk=",
|
||||||
"h1:7mBOA5TVAIt3qAwPXKCtE0RSYeqij9v30mnksuBbpEg=",
|
"h1:C/KvLEm8dVQ6zG2X4asLDtmw2JW/xu7E8MddtaXniO0=",
|
||||||
"h1:ELVgzh4kHKBCYdL+2A8JjWS0E1snLUN3Mmz3Vo6qSfw=",
|
"h1:Doo0xcLFf+CnfDWjsA7G1NvSLURuwcgyVy8k0NF1gJA=",
|
||||||
"h1:FGGM5yLFf72g3kSXM3LAN64Gf/AkXr5WCmhixgnP+l4=",
|
"h1:Gc3FGDtR8lUWsi9VImnnE5/USDXiIwYsv4Hbl+d2lwY=",
|
||||||
"h1:JupkJbQALcIVoMhHImrLeLDsQR1ET7VJLGC7ONxjqGU=",
|
"h1:HsDY6s1gup5fW9TeuTUy85QMIld1nDOUFlwsfxIq1ig=",
|
||||||
"h1:KsaE4JNq+1uV1nJsuTcYar/8lyY6zKS5UBEpfYg3wvc=",
|
"h1:MnHkB56E4b/kT6WZigsZJnB5rgnCfDVbrLBNxIsEXPY=",
|
||||||
"h1:NHZ5RJIzQDLhie/ykl3uI6UPfNQR9Lu5Ti7JPR6X904=",
|
"h1:O/FUQEqhtknJNdsaMbIBi2pLWBds2VvN5FsTVVntzb0=",
|
||||||
"h1:NfAuMbn6LQPLDtJhbzO1MX9JMIGLMa8K6CpekvtsuX8=",
|
"h1:OKQBynkp0J5DIf5FOl/NR3S2rvh89pY+t5wevYxdTJs=",
|
||||||
"h1:e+vNKokamDsp/kJvFr2pRudzwEz2r49iZ/oSggw+1LY=",
|
"h1:On+vPsYV8U/J/8wFZPXjeAgNJqFFQj42vNOKuNKURkY=",
|
||||||
"h1:jnb4VdfNZ79I3yj7Q8x+JmOT+FxbfjjRfrF0dL0yCW8=",
|
"h1:SPkrMRJahxK0uum7FnUugbGN/JepHMH8M71DBtYrvG0=",
|
||||||
"h1:kmF//O539d7NuHU7qIxDj7Wz4eJmLKFiI5glwQivldU=",
|
"h1:bEh1ASPMiin3F36+hTfjMQTBnuDl2DzjzSCdova3JEM=",
|
||||||
"h1:s6XriaKwOgV4jvKAGPXkrxhhOQxpNU5dceZwi9Z/1k8=",
|
"h1:dtIK+x5Q1sh5SMPaHBHXhL9XDIqbRW0EBmVZ+KHQB8E=",
|
||||||
"h1:wt3WBEBAeSGTlC9OlnTlAALxRiK4SQgLy0KgBIS7qzs=",
|
"h1:kZcwWfODMWWyauZ66oaO/X+xXkqBtrbYwfUFEtspwEc=",
|
||||||
"zh:2fb95e1d3229b9b6c704e1a413c7481c60f139780d9641f657b6eb9b633b90f2",
|
"zh:53946fce4a631f1d98c61550821c88edede9169dfe5cc254e09a2ab207f76b3f",
|
||||||
"zh:379c7680983383862236e9e6e720c3114195c40526172188e88d0ffcf50dfe2e",
|
"zh:61654a21f1dd4331492d4ef77e9ebff066bc01e1281f92b925e5697c9138d681",
|
||||||
"zh:55533beb6cfc02d22ffda8cba8027bc2c841bb172cd637ed0d28323d41395f8f",
|
"zh:6a54e9d129b276f052a2f1b73ad0b8735fe6a7403c6a8f6aa111e525eeefaf35",
|
||||||
"zh:5abd70760e4eb1f37a1c307cbd2989ea7c9ba0afb93818c67c1d363a31f75703",
|
"zh:7692374e655c346a630b5a7cd776c5e0b2388900dcd7ab69a3af85d0c31c6c43",
|
||||||
"zh:699f1c8cd66129176fe659ebf0e6337632a8967a28d2630b6ae5948665c0c2ae",
|
|
||||||
"zh:69c15acd73c451e89de6477059cda2f3ec200b48ae4b9ff3646c4d389fd3205e",
|
|
||||||
"zh:6e02b687de21b844f8266dff99e93e7c61fc8eb688f4bbb23803caceb251839e",
|
|
||||||
"zh:7a51d17b87ed87b7bebf2ad9fc7c3a74f16a1b44eee92c779c08eb89258c0496",
|
|
||||||
"zh:88ad84436837b0f55302f22748505972634e87400d6902260fd6b7ba1610f937",
|
|
||||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||||
"zh:8d46c3d9f4f7ad20ac6ef01daa63f4e30a2d16dcb1bb5c7c7ee3dc6be38e9ca1",
|
"zh:8fe5b792a4d2b1c3a0e573649642962494faa00299baa6aaf813b9a43203dc02",
|
||||||
"zh:913d64e72a4929dae1d4793e2004f4f9a58b138ea337d9d94fa35cafbf06550a",
|
"zh:a0f403a4862df90f09de65c6e939d6cfd069a8dda2dd33f82948bf6f5f1124ef",
|
||||||
"zh:c8d93cf86e2e49f6cec665cfe78b82c144cce15a8b2e30f343385fadd1251849",
|
"zh:a25dc3eb60777b600f8f125d321fe7c50b811c5302b58e9a727ceb749a04e35d",
|
||||||
"zh:cc4f69397d9bc34a528a5609a024c3a48f54f21616c0008792dd417297add955",
|
"zh:a2f2ac7dc703c69d2e8c67c9cb5620b5348cb4fd6b98515fbe3f478517b56602",
|
||||||
"zh:df99cdb8b064aad35ffea77e645cf6541d0b1b2ebc51b6d26c42031de60ab69e",
|
"zh:d452e7bd24445ee14166470cf50f3aca566d46cab5f26f1c5c988c0f3106b697",
|
||||||
|
"zh:e10a52b0294735659eb3f0821ad2006ec097918efe58d31d37a5e3c47efef5f6",
|
||||||
|
"zh:e28dd0954cef9f05adf4d4b440d6f134f605344dfa56307181996675e6550af2",
|
||||||
|
"zh:f1e3b2f43a472280442f01ba71a3c06c9167432e553381132ea5c4a77e0b6dd5",
|
||||||
|
"zh:f71fd63718d38fd43829861e91fe79e16d7b4c7c3d508ae3d077368d89b8e5a0",
|
||||||
|
"zh:faf8d3da4b819c4ae8e565d2b1a684c6a948a086cb299189a5e7b30b2178409d",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ terraform {
|
|||||||
required_providers {
|
required_providers {
|
||||||
cloudflare = {
|
cloudflare = {
|
||||||
source = "cloudflare/cloudflare"
|
source = "cloudflare/cloudflare"
|
||||||
version = "4.52.1"
|
version = "4.52.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,18 +21,28 @@ services:
|
|||||||
# extends:
|
# extends:
|
||||||
# file: hwaccel.transcoding.yml
|
# file: hwaccel.transcoding.yml
|
||||||
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
||||||
|
user: '${UID:-1000}:${GID:-1000}'
|
||||||
build:
|
build:
|
||||||
context: ../
|
context: ../
|
||||||
dockerfile: server/Dockerfile
|
dockerfile: server/Dockerfile
|
||||||
target: dev
|
target: dev
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ../server:/usr/src/app/server
|
- ..:/usr/src/app
|
||||||
- ../open-api:/usr/src/app/open-api
|
|
||||||
- ${UPLOAD_LOCATION}/photos:/data
|
- ${UPLOAD_LOCATION}/photos:/data
|
||||||
- ${UPLOAD_LOCATION}/photos/upload:/data/upload
|
- ${UPLOAD_LOCATION}/photos/upload:/data/upload
|
||||||
- /usr/src/app/server/node_modules
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- pnpm-store:/usr/src/app/.pnpm-store
|
||||||
|
- server-node_modules:/usr/src/app/server/node_modules
|
||||||
|
- web-node_modules:/usr/src/app/web/node_modules
|
||||||
|
- github-node_modules:/usr/src/app/.github/node_modules
|
||||||
|
- cli-node_modules:/usr/src/app/cli/node_modules
|
||||||
|
- docs-node_modules:/usr/src/app/docs/node_modules
|
||||||
|
- e2e-node_modules:/usr/src/app/e2e/node_modules
|
||||||
|
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
|
||||||
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
|
- coverage:/usr/src/app/web/coverage
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
@@ -58,8 +68,12 @@ services:
|
|||||||
- 9231:9231
|
- 9231:9231
|
||||||
- 2283:2283
|
- 2283:2283
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
redis:
|
||||||
- database
|
condition: service_started
|
||||||
|
database:
|
||||||
|
condition: service_started
|
||||||
|
init:
|
||||||
|
condition: service_completed_successfully
|
||||||
healthcheck:
|
healthcheck:
|
||||||
disable: false
|
disable: false
|
||||||
|
|
||||||
@@ -68,9 +82,11 @@ services:
|
|||||||
image: immich-web-dev:latest
|
image: immich-web-dev:latest
|
||||||
# Needed for rootless docker setup, see https://github.com/moby/moby/issues/45919
|
# Needed for rootless docker setup, see https://github.com/moby/moby/issues/45919
|
||||||
# user: 0:0
|
# user: 0:0
|
||||||
|
user: '${UID:-1000}:${GID:-1000}'
|
||||||
build:
|
build:
|
||||||
context: ../
|
context: ../
|
||||||
dockerfile: web/Dockerfile
|
dockerfile: server/Dockerfile
|
||||||
|
target: dev
|
||||||
command: ['immich-web']
|
command: ['immich-web']
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
@@ -78,18 +94,28 @@ services:
|
|||||||
- 3000:3000
|
- 3000:3000
|
||||||
- 24678:24678
|
- 24678:24678
|
||||||
volumes:
|
volumes:
|
||||||
- ../web:/usr/src/app/web
|
- ..:/usr/src/app
|
||||||
- ../i18n:/usr/src/app/i18n
|
- pnpm-store:/usr/src/app/.pnpm-store
|
||||||
- ../open-api/:/usr/src/app/open-api/
|
- server-node_modules:/usr/src/app/server/node_modules
|
||||||
# - ../../ui:/usr/ui
|
- web-node_modules:/usr/src/app/web/node_modules
|
||||||
- /usr/src/app/web/node_modules
|
- github-node_modules:/usr/src/app/.github/node_modules
|
||||||
|
- cli-node_modules:/usr/src/app/cli/node_modules
|
||||||
|
- docs-node_modules:/usr/src/app/docs/node_modules
|
||||||
|
- e2e-node_modules:/usr/src/app/e2e/node_modules
|
||||||
|
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
|
||||||
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
|
- coverage:/usr/src/app/web/coverage
|
||||||
ulimits:
|
ulimits:
|
||||||
nofile:
|
nofile:
|
||||||
soft: 1048576
|
soft: 1048576
|
||||||
hard: 1048576
|
hard: 1048576
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- immich-server
|
immich-server:
|
||||||
|
condition: service_started
|
||||||
|
init:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
@@ -117,13 +143,13 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:facc1d2c3462975c34e10fccb167bfa92b0e0dbd992fc282c29a61c3243afb11
|
image: docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
|
|
||||||
database:
|
database:
|
||||||
container_name: immich_postgres
|
container_name: immich_postgres
|
||||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:8d292bdb796aa58bbbaa47fe971c8516f6f57d6a47e7172e62754feb6ed4e7b0
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
@@ -157,7 +183,37 @@ services:
|
|||||||
# volumes:
|
# volumes:
|
||||||
# - grafana-data:/var/lib/grafana
|
# - grafana-data:/var/lib/grafana
|
||||||
|
|
||||||
|
init:
|
||||||
|
container_name: init
|
||||||
|
image: busybox@sha256:ab33eacc8251e3807b85bb6dba570e4698c3998eca6f0fc2ccb60575a563ea74
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
user: 0:0
|
||||||
|
command: sh -c 'find /data -maxdepth 1 -type d -exec chown ${UID:-1000}:${GID:-1000} {} + 2>/dev/null || true; for path in /usr/src/app/.pnpm-store /usr/src/app/server/node_modules /usr/src/app/server/dist /usr/src/app/.github/node_modules /usr/src/app/cli/node_modules /usr/src/app/docs/node_modules /usr/src/app/e2e/node_modules /usr/src/app/open-api/typescript-sdk/node_modules /usr/src/app/web/.svelte-kit /usr/src/app/web/coverage /usr/src/app/node_modules /usr/src/app/web/node_modules; do [ -e "$$path" ] && chown -R ${UID:-1000}:${GID:-1000} "$$path" || true; done'
|
||||||
|
volumes:
|
||||||
|
- pnpm-store:/usr/src/app/.pnpm-store
|
||||||
|
- server-node_modules:/usr/src/app/server/node_modules
|
||||||
|
- web-node_modules:/usr/src/app/web/node_modules
|
||||||
|
- github-node_modules:/usr/src/app/.github/node_modules
|
||||||
|
- cli-node_modules:/usr/src/app/cli/node_modules
|
||||||
|
- docs-node_modules:/usr/src/app/docs/node_modules
|
||||||
|
- e2e-node_modules:/usr/src/app/e2e/node_modules
|
||||||
|
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
|
||||||
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
|
- coverage:/usr/src/app/web/coverage
|
||||||
volumes:
|
volumes:
|
||||||
model-cache:
|
model-cache:
|
||||||
prometheus-data:
|
prometheus-data:
|
||||||
grafana-data:
|
grafana-data:
|
||||||
|
pnpm-store:
|
||||||
|
server-node_modules:
|
||||||
|
web-node_modules:
|
||||||
|
github-node_modules:
|
||||||
|
cli-node_modules:
|
||||||
|
docs-node_modules:
|
||||||
|
e2e-node_modules:
|
||||||
|
sdk-node_modules:
|
||||||
|
app-node_modules:
|
||||||
|
sveltekit:
|
||||||
|
coverage:
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:facc1d2c3462975c34e10fccb167bfa92b0e0dbd992fc282c29a61c3243afb11
|
image: docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
database:
|
database:
|
||||||
container_name: immich_postgres
|
container_name: immich_postgres
|
||||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:8d292bdb796aa58bbbaa47fe971c8516f6f57d6a47e7172e62754feb6ed4e7b0
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
@@ -95,7 +95,7 @@ services:
|
|||||||
command: ['./run.sh', '-disable-reporting']
|
command: ['./run.sh', '-disable-reporting']
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
image: grafana/grafana:12.0.2-ubuntu@sha256:0512d81cdeaaff0e370a9aa66027b465d1f1f04379c3a9c801a905fabbdbc7a5
|
image: grafana/grafana:12.1.1-ubuntu@sha256:d1da838234ff2de93e0065ee1bf0e66d38f948dcc5d718c25fa6237e14b4424a
|
||||||
volumes:
|
volumes:
|
||||||
- grafana-data:/var/lib/grafana
|
- grafana-data:/var/lib/grafana
|
||||||
|
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:facc1d2c3462975c34e10fccb167bfa92b0e0dbd992fc282c29a61c3243afb11
|
image: docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
database:
|
database:
|
||||||
container_name: immich_postgres
|
container_name: immich_postgres
|
||||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:8d292bdb796aa58bbbaa47fe971c8516f6f57d6a47e7172e62754feb6ed4e7b0
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
POSTGRES_USER: ${DB_USERNAME}
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
|||||||
2
docs/.gitignore
vendored
@@ -19,3 +19,5 @@ npm-debug.log*
|
|||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
|
/static/openapi.json
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
22.17.1
|
22.19.0
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati
|
|||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm install
|
$ pnpm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Local Development
|
### Local Development
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm run start
|
$ pnpm run start
|
||||||
```
|
```
|
||||||
|
|
||||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||||
@@ -19,7 +19,7 @@ This command starts a local development server and opens up a browser window. Mo
|
|||||||
### Build
|
### Build
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm run build
|
$ pnpm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||||
@@ -29,13 +29,13 @@ This command generates static content into the `build` directory and can be serv
|
|||||||
Using SSH:
|
Using SSH:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ USE_SSH=true npm run deploy
|
$ USE_SSH=true pnpm run deploy
|
||||||
```
|
```
|
||||||
|
|
||||||
Not using SSH:
|
Not using SSH:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ GIT_USER=<Your GitHub username> npm run deploy
|
$ GIT_USER=<Your GitHub username> pnpm run deploy
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
|
## Commercial Guidelines
|
||||||
|
|
||||||
|
### Are you open to commercial partnerships and collaborations?
|
||||||
|
|
||||||
|
We are working to commercialize Immich and we'd love for you to help us by making Immich better. FUTO is dedicated to developing sustainable models for developing open source software for our customers. We want our customers to be delighted by the products our engineers deliver, and we want our engineers to be paid when they succeed.
|
||||||
|
|
||||||
|
If you wish to use Immich in a commercial product not owned by FUTO, we have the following requirements:
|
||||||
|
|
||||||
|
- Plugin Integrations: Integrations for other platforms are typically approved, provided proper notification is given.
|
||||||
|
|
||||||
|
- Reseller Partnerships: Must adhere to the guidelines outlined below regarding trademark usage, and proper representation.
|
||||||
|
|
||||||
|
- Strategic Collaborations: We welcome discussions about mutually beneficial partnerships that enhance the value proposition for both organizations.
|
||||||
|
|
||||||
|
### What are your guidelines for resellers and trademark usage?
|
||||||
|
|
||||||
|
For organizations seeking to resell Immich, we have established the following guidelines to protect our brand integrity and ensure proper representation.
|
||||||
|
|
||||||
|
- We request that resellers do not display our trademarks on their websites or marketing materials. If such usage is discovered, we will contact you to request removal.
|
||||||
|
|
||||||
|
- Do not misrepresent your reseller site or services as being officially affiliated with or endorsed by Immich or our development team.
|
||||||
|
|
||||||
|
- For small resellers who wish to contribute financially to Immich's development, we recommend directing your customers to purchase licenses directy from us rather than attempting to broker revenue-sharing arrangements. We ask that you refrain from misrepresenting reseller activities as directly supporting our development work.
|
||||||
|
|
||||||
|
When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app
|
||||||
|
|
||||||
## User
|
## User
|
||||||
|
|
||||||
### How can I reset the admin password?
|
### How can I reset the admin password?
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Unable to set `app.immich:///oauth-callback` as a valid redirect URI? See [Mobil
|
|||||||
|
|
||||||
Immich supports 3rd party authentication via [OpenID Connect][oidc] (OIDC), an identity layer built on top of OAuth2. OIDC is supported by most identity providers, including:
|
Immich supports 3rd party authentication via [OpenID Connect][oidc] (OIDC), an identity layer built on top of OAuth2. OIDC is supported by most identity providers, including:
|
||||||
|
|
||||||
- [Authentik](https://goauthentik.io/integrations/sources/oauth/#openid-connect)
|
- [Authentik](https://integrations.goauthentik.io/media/immich/)
|
||||||
- [Authelia](https://www.authelia.com/integration/openid-connect/immich/)
|
- [Authelia](https://www.authelia.com/integration/openid-connect/immich/)
|
||||||
- [Okta](https://www.okta.com/openid-connect/)
|
- [Okta](https://www.okta.com/openid-connect/)
|
||||||
- [Google](https://developers.google.com/identity/openid-connect/openid-connect)
|
- [Google](https://developers.google.com/identity/openid-connect/openid-connect)
|
||||||
@@ -64,7 +64,7 @@ Once you have a new OAuth client application configured, Immich can be configure
|
|||||||
| Storage Label Claim | string | preferred_username | Claim mapping for the user's storage label**¹** |
|
| Storage Label Claim | string | preferred_username | Claim mapping for the user's storage label**¹** |
|
||||||
| Role Claim | string | immich_role | Claim mapping for the user's role. (should return "user" or "admin")**¹** |
|
| Role Claim | string | immich_role | Claim mapping for the user's role. (should return "user" or "admin")**¹** |
|
||||||
| Storage Quota Claim | string | immich_quota | Claim mapping for the user's storage**¹** |
|
| Storage Quota Claim | string | immich_quota | Claim mapping for the user's storage**¹** |
|
||||||
| Default Storage Quota (GiB) | number | 0 | Default quota for user without storage quota claim (Enter 0 for unlimited quota) |
|
| Default Storage Quota (GiB) | number | 0 | Default quota for user without storage quota claim (empty for unlimited quota) |
|
||||||
| Button Text | string | Login with OAuth | Text for the OAuth button on the web |
|
| Button Text | string | Login with OAuth | Text for the OAuth button on the web |
|
||||||
| Auto Register | boolean | true | When true, will automatically register a user the first time they sign in |
|
| Auto Register | boolean | true | When true, will automatically register a user the first time they sign in |
|
||||||
| [Auto Launch](#auto-launch) | boolean | false | When true, will skip the login page and automatically start the OAuth login process |
|
| [Auto Launch](#auto-launch) | boolean | false | When true, will skip the login page and automatically start the OAuth login process |
|
||||||
@@ -88,7 +88,7 @@ The `.well-known/openid-configuration` part of the url is optional and will be a
|
|||||||
## Auto Launch
|
## Auto Launch
|
||||||
|
|
||||||
When Auto Launch is enabled, the login page will automatically redirect the user to the OAuth authorization url, to login with OAuth. To access the login screen again, use the browser's back button, or navigate directly to `/auth/login?autoLaunch=0`.
|
When Auto Launch is enabled, the login page will automatically redirect the user to the OAuth authorization url, to login with OAuth. To access the login screen again, use the browser's back button, or navigate directly to `/auth/login?autoLaunch=0`.
|
||||||
Auto Launch can also be enabled on a per-request basis by navigating to `/auth/login?authLaunch=1`, this can be useful in situations where Immich is called from e.g. Nextcloud using the _External sites_ app and the _oidc_ app so as to enable users to directly interact with a logged-in instance of Immich.
|
Auto Launch can also be enabled on a per-request basis by navigating to `/auth/login?autoLaunch=1`, this can be useful in situations where Immich is called from e.g. Nextcloud using the _External sites_ app and the _oidc_ app so as to enable users to directly interact with a logged-in instance of Immich.
|
||||||
|
|
||||||
## Mobile Redirect URI
|
## Mobile Redirect URI
|
||||||
|
|
||||||
@@ -106,6 +106,89 @@ Immich has a route (`/api/oauth/mobile-redirect`) that is already configured to
|
|||||||
|
|
||||||
## Example Configuration
|
## Example Configuration
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Authelia Example</summary>
|
||||||
|
|
||||||
|
### Authelia Example
|
||||||
|
|
||||||
|
Here's an example of OAuth configured for Authelia:
|
||||||
|
|
||||||
|
This assumes there exist an attribute `immichquota` in the user schema, which is used to set the user's storage quota in Immich.
|
||||||
|
The configuration concerning the quota is optional.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
authentication_backend:
|
||||||
|
ldap:
|
||||||
|
# The LDAP server configuration goes here.
|
||||||
|
# See: https://www.authelia.com/c/ldap
|
||||||
|
attributes:
|
||||||
|
extra:
|
||||||
|
immichquota: # The attribute name from LDAP
|
||||||
|
name: 'immich_quota'
|
||||||
|
multi_valued: false
|
||||||
|
value_type: 'integer'
|
||||||
|
identity_providers:
|
||||||
|
oidc:
|
||||||
|
## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
|
||||||
|
## See: https://www.authelia.com/c/oidc
|
||||||
|
claims_policies:
|
||||||
|
immich_policy:
|
||||||
|
custom_claims:
|
||||||
|
immich_quota:
|
||||||
|
attribute: 'immich_quota'
|
||||||
|
scopes:
|
||||||
|
immich_scope:
|
||||||
|
claims:
|
||||||
|
- 'immich_quota'
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- client_id: 'immich'
|
||||||
|
client_name: 'Immich'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/frequently-asked-questions/#how-do-i-generate-a-client-identifier-or-client-secret
|
||||||
|
client_secret: $pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'
|
||||||
|
public: false
|
||||||
|
require_pkce: false
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://example.immich.app/auth/login'
|
||||||
|
- 'https://example.immich.app/user-settings'
|
||||||
|
- 'app.immich:///oauth-callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
- 'immich_scope'
|
||||||
|
claims_policy: 'immich_policy'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
id_token_signed_response_alg: 'RS256'
|
||||||
|
userinfo_signed_response_alg: 'RS256'
|
||||||
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration of OAuth in Immich System Settings
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
| ---------------------------------- | ------------------------------------------------------------------- |
|
||||||
|
| Issuer URL | `https://example.immich.app/.well-known/openid-configuration` |
|
||||||
|
| Client ID | immich |
|
||||||
|
| Client Secret | 0v89FXkQOWO\***\*\*\*\*\***\*\*\***\*\*\*\*\***mprbvXD549HH6s1iw... |
|
||||||
|
| Token Endpoint Auth Method | client_secret_post |
|
||||||
|
| Scope | openid email profile immich_scope |
|
||||||
|
| ID Token Signed Response Algorithm | RS256 |
|
||||||
|
| Userinfo Signed Response Algorithm | RS256 |
|
||||||
|
| Storage Label Claim | uid |
|
||||||
|
| Storage Quota Claim | immich_quota |
|
||||||
|
| Default Storage Quota (GiB) | 0 (empty for unlimited quota) |
|
||||||
|
| Button Text | Sign in with Authelia (optional) |
|
||||||
|
| Auto Register | Enabled (optional) |
|
||||||
|
| Auto Launch | Enabled (optional) |
|
||||||
|
| Mobile Redirect URI Override | Disable |
|
||||||
|
| Mobile Redirect URI | |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Authentik Example</summary>
|
<summary>Authentik Example</summary>
|
||||||
|
|
||||||
@@ -128,7 +211,7 @@ Configuration of OAuth in Immich System Settings
|
|||||||
| Signing Algorithm | RS256 |
|
| Signing Algorithm | RS256 |
|
||||||
| Storage Label Claim | preferred_username |
|
| Storage Label Claim | preferred_username |
|
||||||
| Storage Quota Claim | immich_quota |
|
| Storage Quota Claim | immich_quota |
|
||||||
| Default Storage Quota (GiB) | 0 (0 for unlimited quota) |
|
| Default Storage Quota (GiB) | 0 (empty for unlimited quota) |
|
||||||
| Button Text | Sign in with Authentik (optional) |
|
| Button Text | Sign in with Authentik (optional) |
|
||||||
| Auto Register | Enabled (optional) |
|
| Auto Register | Enabled (optional) |
|
||||||
| Auto Launch | Enabled (optional) |
|
| Auto Launch | Enabled (optional) |
|
||||||
@@ -159,7 +242,7 @@ Configuration of OAuth in Immich System Settings
|
|||||||
| Signing Algorithm | RS256 |
|
| Signing Algorithm | RS256 |
|
||||||
| Storage Label Claim | preferred_username |
|
| Storage Label Claim | preferred_username |
|
||||||
| Storage Quota Claim | immich_quota |
|
| Storage Quota Claim | immich_quota |
|
||||||
| Default Storage Quota (GiB) | 0 (0 for unlimited quota) |
|
| Default Storage Quota (GiB) | 0 (empty for unlimited quota) |
|
||||||
| Button Text | Sign in with Google (optional) |
|
| Button Text | Sign in with Google (optional) |
|
||||||
| Auto Register | Enabled (optional) |
|
| Auto Register | Enabled (optional) |
|
||||||
| Auto Launch | Enabled |
|
| Auto Launch | Enabled |
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
Users can deploy a custom reverse proxy that forwards requests to Immich. This way, the reverse proxy can handle TLS termination, load balancing, or other advanced features. All reverse proxies between Immich and the user must forward all headers and set the `Host`, `X-Real-IP`, `X-Forwarded-Proto` and `X-Forwarded-For` headers to their appropriate values. Additionally, your reverse proxy should allow for big enough uploads. By following these practices, you ensure that all custom reverse proxies are fully compatible with Immich.
|
Users can deploy a custom reverse proxy that forwards requests to Immich. This way, the reverse proxy can handle TLS termination, load balancing, or other advanced features. All reverse proxies between Immich and the user must forward all headers and set the `Host`, `X-Real-IP`, `X-Forwarded-Proto` and `X-Forwarded-For` headers to their appropriate values. Additionally, your reverse proxy should allow for big enough uploads. By following these practices, you ensure that all custom reverse proxies are fully compatible with Immich.
|
||||||
|
|
||||||
:::note
|
|
||||||
The Repair page can take a long time to load. To avoid server timeouts or errors, we recommend specifying a timeout of at least 10 minutes on your proxy server.
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
Immich does not support being served on a sub-path such as `location /immich {`. It has to be served on the root path of a (sub)domain.
|
Immich does not support being served on a sub-path such as `location /immich {`. It has to be served on the root path of a (sub)domain.
|
||||||
:::
|
:::
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ After making any changes in the `server/src/schema`, a database migration need t
|
|||||||
1. Run the command
|
1. Run the command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run migrations:generate <migration-name>
|
pnpm run migrations:generate <migration-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Check if the migration file makes sense.
|
2. Check if the migration file makes sense.
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ When the Dev Container starts, it automatically:
|
|||||||
|
|
||||||
1. **Runs post-create script** (`container-server-post-create.sh`):
|
1. **Runs post-create script** (`container-server-post-create.sh`):
|
||||||
- Adjusts file permissions for the `node` user
|
- Adjusts file permissions for the `node` user
|
||||||
- Installs dependencies: `npm install` in all packages
|
- Installs dependencies: `pnpm install` in all packages
|
||||||
- Builds TypeScript SDK: `npm run build` in `open-api/typescript-sdk`
|
- Builds TypeScript SDK: `pnpm run build` in `open-api/typescript-sdk`
|
||||||
|
|
||||||
2. **Starts development servers** via VS Code tasks:
|
2. **Starts development servers** via VS Code tasks:
|
||||||
- `Immich API Server (Nest)` - API server with hot-reloading on port 2283
|
- `Immich API Server (Nest)` - API server with hot-reloading on port 2283
|
||||||
@@ -243,7 +243,7 @@ To connect the mobile app to your Dev Container:
|
|||||||
|
|
||||||
- **Server code** (`/server`): Changes trigger automatic restart
|
- **Server code** (`/server`): Changes trigger automatic restart
|
||||||
- **Web code** (`/web`): Changes trigger hot module replacement
|
- **Web code** (`/web`): Changes trigger hot module replacement
|
||||||
- **Database migrations**: Run `npm run sync:sql` in the server directory
|
- **Database migrations**: Run `pnpm run sync:sql` in the server directory
|
||||||
- **API changes**: Regenerate TypeScript SDK with `make open-api`
|
- **API changes**: Regenerate TypeScript SDK with `make open-api`
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
@@ -273,19 +273,19 @@ make test-medium-dev # End-to-end tests
|
|||||||
```bash
|
```bash
|
||||||
# Server tests
|
# Server tests
|
||||||
cd /workspaces/immich/server
|
cd /workspaces/immich/server
|
||||||
npm test # Run all tests
|
pnpm test # Run all tests
|
||||||
npm run test:watch # Watch mode
|
pnpm run test:watch # Watch mode
|
||||||
npm run test:cov # Coverage report
|
pnpm run test:cov # Coverage report
|
||||||
|
|
||||||
# Web tests
|
# Web tests
|
||||||
cd /workspaces/immich/web
|
cd /workspaces/immich/web
|
||||||
npm test # Run all tests
|
pnpm test # Run all tests
|
||||||
npm run test:watch # Watch mode
|
pnpm run test:watch # Watch mode
|
||||||
|
|
||||||
# E2E tests
|
# E2E tests
|
||||||
cd /workspaces/immich/e2e
|
cd /workspaces/immich/e2e
|
||||||
npm run test # Run API tests
|
pnpm run test # Run API tests
|
||||||
npm run test:web # Run web UI tests
|
pnpm run test:web # Run web UI tests
|
||||||
```
|
```
|
||||||
|
|
||||||
### Code Quality Commands
|
### Code Quality Commands
|
||||||
|
|||||||
@@ -8,34 +8,34 @@ When contributing code through a pull request, please check the following:
|
|||||||
|
|
||||||
## Web Checks
|
## Web Checks
|
||||||
|
|
||||||
- [ ] `npm run lint` (linting via ESLint)
|
- [ ] `pnpm run lint` (linting via ESLint)
|
||||||
- [ ] `npm run format` (formatting via Prettier)
|
- [ ] `pnpm run format` (formatting via Prettier)
|
||||||
- [ ] `npm run check:svelte` (Type checking via SvelteKit)
|
- [ ] `pnpm run check:svelte` (Type checking via SvelteKit)
|
||||||
- [ ] `npm run check:typescript` (check typescript)
|
- [ ] `pnpm run check:typescript` (check typescript)
|
||||||
- [ ] `npm test` (unit tests)
|
- [ ] `pnpm test` (unit tests)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [ ] `npm run format` (formatting via Prettier)
|
- [ ] `pnpm run format` (formatting via Prettier)
|
||||||
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
|
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
|
||||||
|
|
||||||
:::tip AIO
|
:::tip AIO
|
||||||
Run all web checks with `npm run check:all`
|
Run all web checks with `pnpm run check:all`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Server Checks
|
## Server Checks
|
||||||
|
|
||||||
- [ ] `npm run lint` (linting via ESLint)
|
- [ ] `pnpm run lint` (linting via ESLint)
|
||||||
- [ ] `npm run format` (formatting via Prettier)
|
- [ ] `pnpm run format` (formatting via Prettier)
|
||||||
- [ ] `npm run check` (Type checking via `tsc`)
|
- [ ] `pnpm run check` (Type checking via `tsc`)
|
||||||
- [ ] `npm test` (unit tests)
|
- [ ] `pnpm test` (unit tests)
|
||||||
|
|
||||||
:::tip AIO
|
:::tip AIO
|
||||||
Run all server checks with `npm run check:all`
|
Run all server checks with `pnpm run check:all`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::info Auto Fix
|
:::info Auto Fix
|
||||||
You can use `npm run __:fix` to potentially correct some issues automatically for `npm run format` and `lint`.
|
You can use `pnpm run __:fix` to potentially correct some issues automatically for `pnpm run format` and `lint`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Mobile Checks
|
## Mobile Checks
|
||||||
|
|||||||
@@ -54,20 +54,20 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3
|
|||||||
|
|
||||||
If you only want to do web development connected to an existing, remote backend, follow these steps:
|
If you only want to do web development connected to an existing, remote backend, follow these steps:
|
||||||
|
|
||||||
1. Build the Immich SDK - `cd open-api/typescript-sdk && npm i && npm run build && cd -`
|
1. Build the Immich SDK - `cd open-api/typescript-sdk && pnpm i && pnpm run build && cd -`
|
||||||
2. Enter the web directory - `cd web/`
|
2. Enter the web directory - `cd web/`
|
||||||
3. Install web dependencies - `npm i`
|
3. Install web dependencies - `pnpm i`
|
||||||
4. Start the web development server
|
4. Start the web development server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
IMMICH_SERVER_URL=https://demo.immich.app/ npm run dev
|
IMMICH_SERVER_URL=https://demo.immich.app/ pnpm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're using PowerShell on Windows you may need to set the env var separately like so:
|
If you're using PowerShell on Windows you may need to set the env var separately like so:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
|
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
|
||||||
npm run dev
|
pnpm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `@immich/ui`
|
#### `@immich/ui`
|
||||||
@@ -75,12 +75,12 @@ npm run dev
|
|||||||
To see local changes to `@immich/ui` in Immich, do the following:
|
To see local changes to `@immich/ui` in Immich, do the following:
|
||||||
|
|
||||||
1. Install `@immich/ui` as a sibling to `immich/`, for example `/home/user/immich` and `/home/user/ui`
|
1. Install `@immich/ui` as a sibling to `immich/`, for example `/home/user/immich` and `/home/user/ui`
|
||||||
2. Build the `@immich/ui` project via `npm run build`
|
2. Build the `@immich/ui` project via `pnpm run build`
|
||||||
3. Uncomment the corresponding volume in web service of the `docker/docker-compose.dev.yaml` file (`../../ui:/usr/ui`)
|
3. Uncomment the corresponding volume in web service of the `docker/docker-compose.dev.yaml` file (`../../ui:/usr/ui`)
|
||||||
4. Uncomment the corresponding alias in the `web/vite.config.js` file (`'@immich/ui': path.resolve(\_\_dirname, '../../ui')`)
|
4. Uncomment the corresponding alias in the `web/vite.config.js` file (`'@immich/ui': path.resolve(\_\_dirname, '../../ui')`)
|
||||||
5. Uncomment the import statement in `web/src/app.css` file `@import '/usr/ui/dist/theme/default.css';` and comment out `@import '@immich/ui/theme/default.css';`
|
5. Uncomment the import statement in `web/src/app.css` file `@import '/usr/ui/dist/theme/default.css';` and comment out `@import '@immich/ui/theme/default.css';`
|
||||||
6. Start up the stack via `make dev`
|
6. Start up the stack via `make dev`
|
||||||
7. After making changes in `@immich/ui`, rebuild it (`npm run build`)
|
7. After making changes in `@immich/ui`, rebuild it (`pnpm run build`)
|
||||||
|
|
||||||
### Mobile app
|
### Mobile app
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
### Unit tests
|
### Unit tests
|
||||||
|
|
||||||
Unit are run by calling `npm run test` from the `server/` directory.
|
Unit are run by calling `pnpm run test` from the `server/` directory.
|
||||||
You need to run `npm install` (in `server/`) before _once_.
|
You need to run `pnpm install` (in `server/`) before _once_.
|
||||||
|
|
||||||
### End to end tests
|
### End to end tests
|
||||||
|
|
||||||
@@ -17,14 +17,14 @@ make e2e
|
|||||||
|
|
||||||
Before you can run the tests, you need to run the following commands _once_:
|
Before you can run the tests, you need to run the following commands _once_:
|
||||||
|
|
||||||
- `npm install` (in `e2e/`)
|
- `pnpm install` (in `e2e/`)
|
||||||
- `make open-api` (in the project root `/`)
|
- `make open-api` (in the project root `/`)
|
||||||
|
|
||||||
Once the test environment is running, the e2e tests can be run via:
|
Once the test environment is running, the e2e tests can be run via:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd e2e/
|
cd e2e/
|
||||||
npm test
|
pnpm test
|
||||||
```
|
```
|
||||||
|
|
||||||
The tests check various things including:
|
The tests check various things including:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Sometimes, an external library will not scan correctly. This can happen if Immic
|
|||||||
- Are the permissions set correctly?
|
- Are the permissions set correctly?
|
||||||
- Make sure you are using forward slashes (`/`) and not backward slashes.
|
- Make sure you are using forward slashes (`/`) and not backward slashes.
|
||||||
|
|
||||||
To validate that Immich can reach your external library, start a shell inside the container. Run `docker exec -it immich_server bash` to a bash shell. If your import path is `/data/import/photos`, check it with `ls /data/import/photos`. Do the same check for the same in any microservices containers.
|
To validate that Immich can reach your external library, start a shell inside the container. Run `docker exec -it immich_server bash` to a bash shell. If your import path is `/mnt/photos`, check it with `ls /mnt/photos`. If you are using a dedicated microservices container, make sure to add the same mount point and check for availability within the microservices container as well.
|
||||||
|
|
||||||
### Exclusion Patterns
|
### Exclusion Patterns
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ The provided file is just a starting point. There are a ton of ways to configure
|
|||||||
After bringing down the containers with `docker compose down` and back up with `docker compose up -d`, a Prometheus instance will now collect metrics from the immich server and microservices containers. Note that we didn't need to expose any new ports for these containers - the communication is handled in the internal Docker network.
|
After bringing down the containers with `docker compose down` and back up with `docker compose up -d`, a Prometheus instance will now collect metrics from the immich server and microservices containers. Note that we didn't need to expose any new ports for these containers - the communication is handled in the internal Docker network.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
To see exactly what metrics are made available, you can additionally add `8081:8081` to the server container's ports and `8082:8082` to the microservices container's ports.
|
To see exactly what metrics are made available, you can additionally add `8081:8081` (API metrics) and `8082:8082` (microservices metrics) to the immich_server container's ports.
|
||||||
Visiting the `/metrics` endpoint for these services will show the same raw data that Prometheus collects.
|
Visiting the `/metrics` endpoint for these services will show the same raw data that Prometheus collects.
|
||||||
To configure these ports see [`IMMICH_API_METRICS_PORT` & `IMMICH_MICROSERVICES_METRICS_PORT`](/docs/install/environment-variables/#general).
|
To configure these ports see [`IMMICH_API_METRICS_PORT` & `IMMICH_MICROSERVICES_METRICS_PORT`](/docs/install/environment-variables/#general).
|
||||||
:::
|
:::
|
||||||
|
|||||||
@@ -147,7 +147,10 @@ SELECT "key", "value" FROM "system_metadata" WHERE "key" = 'system-config';
|
|||||||
### File properties
|
### File properties
|
||||||
|
|
||||||
```sql title="Without thumbnails"
|
```sql title="Without thumbnails"
|
||||||
SELECT * FROM "asset" WHERE "asset"."previewPath" IS NULL OR "asset"."thumbnailPath" IS NULL;
|
SELECT * FROM "asset"
|
||||||
|
WHERE (NOT EXISTS (SELECT 1 FROM "asset_file" WHERE "asset"."id" = "asset_file"."assetId" AND "asset_file"."type" = 'thumbnail')
|
||||||
|
OR NOT EXISTS (SELECT 1 FROM "asset_file" WHERE "asset"."id" = "asset_file"."assetId" AND "asset_file"."type" = 'preview'))
|
||||||
|
AND "asset"."visibility" = 'timeline';
|
||||||
```
|
```
|
||||||
|
|
||||||
```sql title="Failed file movements"
|
```sql title="Failed file movements"
|
||||||
|
|||||||
BIN
docs/docs/install/img/truenas/truenas00.webp
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
BIN
docs/docs/install/img/truenas/truenas04.webp
Normal file
|
After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
docs/docs/install/img/truenas/truenas06.webp
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
docs/docs/install/img/truenas/truenas07.webp
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/docs/install/img/truenas/truenas08.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/docs/install/img/truenas/truenas09.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/docs/install/img/truenas/truenas10.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
@@ -2,6 +2,9 @@
|
|||||||
sidebar_position: 80
|
sidebar_position: 80
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
# TrueNAS [Community]
|
# TrueNAS [Community]
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
@@ -9,211 +12,324 @@ This is a community contribution and not officially supported by the Immich team
|
|||||||
|
|
||||||
Community support can be found in the dedicated channel on the [Discord Server](https://discord.immich.app/).
|
Community support can be found in the dedicated channel on the [Discord Server](https://discord.immich.app/).
|
||||||
|
|
||||||
**Please report app issues to the corresponding [Github Repository](https://github.com/truenas/apps/tree/master/trains/community/immich).**
|
**Please report app issues to the corresponding [GitHub Repository](https://github.com/truenas/apps/tree/master/trains/community/immich).**
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
This guide covers the installation of Immich on TrueNAS Community Edition 24.10.2.2 (Electric Eel) and later.
|
||||||
|
|
||||||
|
We recommend keeping TrueNAS Community Edition and Immich relatively up to date with the latest versions to avoid any issues.
|
||||||
|
|
||||||
|
If you are using an older version of TrueNAS, we ask that you upgrade to the latest version before installing Immich. Check the [TrueNAS Community Edition Release Notes](https://www.truenas.com/docs/softwarereleases/) for more information on breaking changes, new features, and how to upgrade your system.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Immich can easily be installed on TrueNAS Community Edition via the **Community** train application.
|
Immich can easily be installed on TrueNAS Community Edition via the **Community** train application.
|
||||||
Consider reviewing the TrueNAS [Apps resources](https://apps.truenas.com/getting-started/) if you have not previously configured applications on your system.
|
Consider reviewing the TrueNAS [Apps resources](https://apps.truenas.com/getting-started/) if you have not previously configured applications on your system.
|
||||||
|
|
||||||
TrueNAS Community Edition makes installing and updating Immich easy, but you must use the Immich web portal and mobile app to configure accounts and access libraries.
|
|
||||||
|
|
||||||
## First Steps
|
## First Steps
|
||||||
|
|
||||||
The Immich app in TrueNAS Community Edition installs, completes the initial configuration, then starts the Immich web portal.
|
|
||||||
When updates become available, TrueNAS alerts and provides easy updates.
|
|
||||||
|
|
||||||
Before installing the Immich app in TrueNAS, review the [Environment Variables](#environment-variables) documentation to see if you want to configure any during installation.
|
|
||||||
You may also configure environment variables at any time after deploying the application.
|
|
||||||
|
|
||||||
### Setting up Storage Datasets
|
### Setting up Storage Datasets
|
||||||
|
|
||||||
Before beginning app installation, [create the datasets](https://www.truenas.com/docs/scale/scaletutorials/storage/datasets/datasetsscale/) to use in the **Storage Configuration** section during installation.
|
Before beginning app installation, [create the datasets](https://www.truenas.com/docs/scale/scaletutorials/storage/datasets/datasetsscale/) to use in the **Storage Configuration** section during installation.
|
||||||
Immich requires seven datasets: `library`, `upload`, `thumbs`, `profile`, `video`, `backups`, and `pgData`.
|
|
||||||
You can organize these as one parent with seven child datasets, for example `/mnt/tank/immich/library`, `/mnt/tank/immich/upload`, and so on.
|
In TrueNAS, Immich requires 2 datasets for the application to function correctly: `data` and `pgData`. You can set the datasets to any names to match your naming conventions or preferences.
|
||||||
|
You can organize these as one parent with two child datasets, for example `/mnt/tank/immich/data` and `/mnt/tank/immich/pgData`.
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas12.webp').default}
|
src={require('./img/truenas/truenas00.webp').default}
|
||||||
width="30%"
|
width="40%"
|
||||||
alt="Immich App Widget"
|
alt="Immich App Widget"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
:::info Permissions
|
:::info Datasets Permissions
|
||||||
The **pgData** dataset must be owned by the user `netdata` (UID 999) for postgres to start. The other datasets must be owned by the user `root` (UID 0) or a group that includes the user `root` (UID 0) for immich to have the necessary permissions.
|
|
||||||
|
|
||||||
If the **library** dataset uses ACL it must have [ACL mode](https://www.truenas.com/docs/core/coretutorials/storage/pools/permissions/#access-control-lists) set to `Passthrough` if you plan on using a [storage template](/docs/administration/storage-template.mdx) and the dataset is configured for network sharing (its ACL type is set to `SMB/NFSv4`). When the template is applied and files need to be moved from **upload** to **library**, Immich performs `chmod` internally and needs to be allowed to execute the command. [More info.](https://github.com/immich-app/immich/pull/13017)
|
The **pgData** dataset must be owned by the user `netdata` (UID 999) for Postgres to start.
|
||||||
|
|
||||||
|
The `data` dataset must have given the **_modify_** permission to the user who will run Immich.
|
||||||
|
|
||||||
|
Since TrueNAS Community Edition 24.10.2.2 and later, Immich can be run as any user and group, the default user being `apps` (UID 568) and the default group being `apps` (GID 568). This user, either `apps` or another user you choose, must have **_modify_** permissions on the **data** dataset.
|
||||||
|
|
||||||
|
For an easy setup:
|
||||||
|
|
||||||
|
- Create the parent dataset `immich` keeping the default **Generic** preset.
|
||||||
|
- Select `Dataset Preset` **Apps** instead of **Generic** when creating the `data` dataset. This will automatically give the correct permissions to the dataset. If you want to use another user for Immich, you can keep the **Generic** preset, but you will need to give the **_modify_** permission to that other user.
|
||||||
|
- For the `pgData` dataset, you can keep the default preset **Generic** as permissions can be set during the installation of the Immich app (See [Storage Configuration](#storage-configuration) section).
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
To improve performance, Immich recommends using SSDs for the database. If you have a pool made of SSDs, you can create the `pgData` dataset on that pool.
|
||||||
|
|
||||||
|
Thumbnails can also be stored on the SSDs for faster access. This is an advanced option and not required for Immich to run. More information on how you can use multiple datasets to manage Immich storage in a finer-grained manner can be found in the [Advanced: Multiple Datasets for Immich Storage](#advanced-multiple-datasets-for-immich-storage) section below.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
If you just created the datasets using the **Apps** preset, you can skip this warning section.
|
||||||
|
|
||||||
|
If the **data** dataset uses ACL it must have [ACL mode](https://www.truenas.com/docs/scale/scaletutorials/datasets/permissionsscale/) set to `Passthrough` if you plan on using a [storage template](/docs/administration/storage-template.mdx) and the dataset is configured for network sharing (its ACL type is set to `SMB/NFSv4`). When the template is applied and files need to be moved from **upload** to **library** (internal folder created by Immich within the **data** dataset), Immich performs `chmod` internally and must be allowed to execute the command. [More info.](https://github.com/immich-app/immich/pull/13017)
|
||||||
|
|
||||||
|
To change or verify the ACL mode, go to the **Datasets** screen, select the **library** dataset, click on the **Edit** button next to **Dataset Details**, then click on the **Advanced Options** tab, scroll down to the **ACL Mode** section, and select `Passthrough` from the dropdown menu. Click **Save** to apply the changes. If the option is greyed out, set the **ACL Type** to `SMB/NFSv4` first, then you can change the **ACL Mode** to `Passthrough`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Installing the Immich Application
|
## Installing the Immich Application
|
||||||
|
|
||||||
To install the **Immich** application, go to **Apps**, click **Discover Apps**, either begin typing Immich into the search field or scroll down to locate the **Immich** application widget.
|
To install the **Immich** application, go to **Apps**, click **Discover Apps**, and either begin typing Immich into the search field or scroll down to locate the **Immich** application widget.
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '2rem', border: '1px solid #ccc', padding: '1rem', borderRadius: '8px' }}>
|
||||||
|
|
||||||
|
Click on the widget to open the **Immich** application details screen.
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas01.webp').default}
|
src={require('./img/truenas/truenas01.webp').default}
|
||||||
width="50%"
|
width="50%"
|
||||||
alt="Immich App Widget"
|
alt="Immich App Widget"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Click on the widget to open the **Immich** application details screen.
|
</div>
|
||||||
|
|
||||||
<br/><br/>
|
<div style={{ marginBottom: '2rem', border: '1px solid #ccc', padding: '1rem', borderRadius: '8px' }}>
|
||||||
|
|
||||||
|
Click **Install** to open the Immich application configuration screen.
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas02.webp').default}
|
src={require('./img/truenas/truenas02.webp').default}
|
||||||
width="100%"
|
width="100%"
|
||||||
alt="Immich App Details Screen"
|
alt="Immich App Details Screen"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Click **Install** to open the Immich application configuration screen.
|
</div>
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
Application configuration settings are presented in several sections, each explained below.
|
Application configuration settings are presented in several sections, each explained below.
|
||||||
To find specific fields click in the **Search Input Fields** search field, scroll down to a particular section or click on the section heading on the navigation area in the upper-right corner.
|
To find specific fields, click in the **Search Input Fields** search field, scroll down to a particular section, or click on the section heading on the navigation area in the upper-right corner.
|
||||||
|
|
||||||
### Application Name and Version
|
### Application Name and Version
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas03.webp').default}
|
src={require('./img/truenas/truenas03.webp').default}
|
||||||
width="100%"
|
width="100%"
|
||||||
alt="Install Immich Screen"
|
alt="Install Immich Screen"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl mb-4"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Accept the default value or enter a name in **Application Name** field.
|
Keep the default value or enter a name in the **Application Name** field.
|
||||||
In most cases use the default name, but if adding a second deployment of the application you must change this name.
|
Change it if you’re deploying a second instance.
|
||||||
|
|
||||||
Accept the default version number in **Version**.
|
Immich version within TrueNAS catalog (Different from Immich release version).
|
||||||
When a new version becomes available, the application has an update badge.
|
|
||||||
The **Installed Applications** screen shows the option to update applications.
|
|
||||||
|
|
||||||
### Immich Configuration
|
### Immich Configuration
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas05.webp').default}
|
src={require('./img/truenas/truenas04.webp').default}
|
||||||
width="40%"
|
width="40%"
|
||||||
alt="Configuration Settings"
|
alt="Configuration Settings"
|
||||||
|
className="border rounded-xl mb-4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
The **Timezone** is set to the system default, which usually matches your local timezone. You can change it to another timezone if you prefer.
|
||||||
|
|
||||||
|
**Enable Machine Learning** is enabled by default. It allows Immich to use machine learning features such as face recognition, image search, and smart duplicate detection. Untick this option if you do not want to use these features.
|
||||||
|
|
||||||
|
Select the **Machine Learning Image Type** based on the hardware you have. More details here: [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md)
|
||||||
|
|
||||||
|
**Database Password** should be set to a custom value using only the characters `A-Za-z0-9`. This password is used to secure the Postgres database.
|
||||||
|
|
||||||
|
**Redis Password** should be set to a custom value using only the characters `A-Za-z0-9`. Preferably, use a different password from the database password.
|
||||||
|
|
||||||
|
Keep the **Log Level** to the default `Log` value.
|
||||||
|
|
||||||
|
Leave **Hugging Face Endpoint** blank. (This is used to download ML models from a different source.)
|
||||||
|
|
||||||
|
Set **Database Storage Type** to the type of storage (**HDD** or **SSD**) that the pool where the **pgData** dataset is located uses.
|
||||||
|
|
||||||
|
**Additional Environment Variables** can be left blank.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Advanced users: Adding Environment Variables</summary>
|
||||||
|
|
||||||
|
Environment variables can be set by clicking the **Add** button and filling in the **Name** and **Value** fields.
|
||||||
|
|
||||||
|
<img
|
||||||
|
src={require('./img/truenas/truenas05.webp').default}
|
||||||
|
width="40%"
|
||||||
|
alt="Environment Variables"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Accept the default value in **Timezone** or change to match your local timezone.
|
These are used to add custom configuration options or to enable specific features.
|
||||||
**Timezone** is only used by the Immich `exiftool` microservice if it cannot be determined from the image metadata.
|
More information on available environment variables can be found in the **[environment variables documentation](/docs/install/environment-variables/)**.
|
||||||
|
|
||||||
Untick **Enable Machine Learning** if you will not use face recognition, image search, and smart duplicate detection.
|
:::info
|
||||||
|
Some environment variables are not available for the TrueNAS Community Edition app as they can be configured through GUI options in the [Edit Immich screen](#edit-app-settings).
|
||||||
|
|
||||||
Accept the default option or select the **Machine Learning Image Type** for your hardware based on the [Hardware-Accelerated Machine Learning Supported Backends](/docs/features/ml-hardware-acceleration.md#supported-backends).
|
Some examples are: `IMMICH_VERSION`, `UPLOAD_LOCATION`, `DB_DATA_LOCATION`, `TZ`, `IMMICH_LOG_LEVEL`, `DB_PASSWORD`, `REDIS_PASSWORD`.
|
||||||
|
:::
|
||||||
|
|
||||||
Immich's default is `postgres` but you should consider setting the **Database Password** to a custom value using only the characters `A-Za-z0-9`.
|
</details>
|
||||||
|
|
||||||
The **Redis Password** should be set to a custom value using only the characters `A-Za-z0-9`.
|
### User and Group Configuration
|
||||||
|
|
||||||
Accept the **Log Level** default of **Log**.
|
Application in TrueNAS runs as a specific user and group. Immich uses the default user `apps` (UID 568) and the default group `apps` (GID 568).
|
||||||
|
|
||||||
Leave **Hugging Face Endpoint** blank. (This is for downloading ML models from a different source.)
|
<img
|
||||||
|
src={require('./img/truenas/truenas06.webp').default}
|
||||||
|
width="40%"
|
||||||
|
alt="User and Group Configuration"
|
||||||
|
className="border rounded-xl"
|
||||||
|
/>
|
||||||
|
|
||||||
Leave **Additional Environment Variables** blank or see [Environment Variables](#environment-variables) to set before installing.
|
- **User ID**: Keep the default value `apps` (UID 568) or define a different one if needed.
|
||||||
|
|
||||||
|
- **Group ID**: Keep the default value `apps` (GID 568) or define a different one if needed.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
If you change the user or group, make sure that the datasets you created for Immich data storage have the correct permissions set for that user and group as specified in the [Setting up Storage Datasets](#setting-up-storage-datasets) section above.
|
||||||
|
:::
|
||||||
|
|
||||||
### Network Configuration
|
### Network Configuration
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas06.webp').default}
|
src={require('./img/truenas/truenas07.webp').default}
|
||||||
width="40%"
|
width="40%"
|
||||||
alt="Networking Settings"
|
alt="Networking Settings"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Accept the default port `30041` in **WebUI Port** or enter a custom port number.
|
- **Port Bind Mode**: This lets you expose the port to the host system, allowing you to access Immich from outside the TrueNAS system. Keep the default **_Publish port on the host for external access_** value unless you have a specific reason to change it.
|
||||||
:::info Allowed Port Numbers
|
|
||||||
Only numbers within the range 9000-65535 may be used on TrueNAS versions below TrueNAS Community Edition 24.10 Electric Eel.
|
|
||||||
|
|
||||||
Regardless of version, to avoid port conflicts, don't use [ports on this list](https://www.truenas.com/docs/solutions/optimizations/security/#truenas-default-ports).
|
- **Port Number**: Keep the default port `30041` or enter a custom port number.
|
||||||
:::
|
|
||||||
|
- **Host IPs**: Leave the default blank value.
|
||||||
|
|
||||||
### Storage Configuration
|
### Storage Configuration
|
||||||
|
|
||||||
Immich requires seven storage datasets.
|
:::danger Default Settings (Not recommended)
|
||||||
|
The default setting for datasets is **ixVolume (dataset created automatically by the system)**. This is not recommended as this results in your data being harder to access manually and can result in data loss if you delete the immich app. It is also harder to manage snapshots and replication tasks. It is recommended to use the **Host Path (Path that already exists on the system)** option instead.
|
||||||
<img
|
|
||||||
src={require('./img/truenas07.webp').default}
|
|
||||||
width="20%"
|
|
||||||
alt="Configure Storage ixVolumes"
|
|
||||||
className="border rounded-xl"
|
|
||||||
/>
|
|
||||||
|
|
||||||
:::note Default Setting (Not recommended)
|
|
||||||
The default setting for datasets is **ixVolume (dataset created automatically by the system)** but this results in your data being harder to access manually and can result in data loss if you delete the immich app. (Not recommended)
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
For each Storage option select **Host Path (Path that already exists on the system)** and then select the matching dataset [created before installing the app](#setting-up-storage-datasets): **Immich Library Storage**: `library`, **Immich Uploads Storage**: `upload`, **Immich Thumbs Storage**: `thumbs`, **Immich Profile Storage**: `profile`, **Immich Video Storage**: `video`, **Immich Backups Storage**: `backups`, **Postgres Data Storage**: `pgData`.
|
The storage configuration section allows you to set up the storage locations for Immich data. You can select the datasets created in the previous step.
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas08.webp').default}
|
src={require('./img/truenas/truenas08.webp').default}
|
||||||
width="40%"
|
width="40%"
|
||||||
alt="Configure Storage Host Paths"
|
alt="Configure Storage Volumes"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
The image above has example values.
|
|
||||||
|
|
||||||
<br/>
|
For the Data Storage, select **Host Path (Path that already exists on the system)** and then select the dataset you created for Immich data storage, for example, `data`.
|
||||||
|
|
||||||
### Additional Storage [(External Libraries)](/docs/features/libraries)
|
The Machine Learning cache can be left with default _Temporary_
|
||||||
|
|
||||||
|
For the Postgres Data Storage, select **Host Path (Path that already exists on the system)** and then select the dataset you created for Postgres data storage, for example, `pgData`.
|
||||||
|
|
||||||
|
:::info
|
||||||
|
**Postgres Data Storage**
|
||||||
|
Once **Host Path** is selected, a checkbox appears with **_Automatic Permissions_**. If you have not set the ownership of the **pgData** dataset to `netdata` (UID 999), tick this box as it will set the user ownership to `netdata` (UID 999) and the group ownership to `docker` (GID 999) automatically. If you have set the ownership of the **pgData** dataset to `netdata` (UID 999), you can leave this box unticked.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Additional Storage (Advanced Users)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>External Libraries</summary>
|
||||||
|
|
||||||
:::danger Advanced Users Only
|
:::danger Advanced Users Only
|
||||||
This feature should only be used by advanced users. If this is your first time installing Immich, then DO NOT mount an external library until you have a working setup. Also, your mount path MUST be something unique and should NOT be your library or upload location or a Linux directory like `/lib`. The picture below shows a valid example.
|
This feature should only be used by advanced users. If this is your first time installing Immich, then DO NOT mount an external library until you have a working setup.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas10.webp').default}
|
src={require('./img/truenas/truenas09.webp').default}
|
||||||
width="40%"
|
width="40%"
|
||||||
alt="Configure Storage Host Paths"
|
alt="Add External Libraries with Additional Storage"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
You may configure [External Libraries](/docs/features/libraries) by mounting them using **Additional Storage**.
|
You may configure [external libraries](/docs/features/libraries) by mounting them using **Additional Storage**.
|
||||||
The **Mount Path** is the location you will need to copy and paste into the External Library settings within Immich.
|
|
||||||
The **Host Path** is the location on the TrueNAS Community Edition server where your external library is located.
|
|
||||||
|
|
||||||
<!-- A section for Labels would go here but I don't know what they do. -->
|
The dataset that contains your external library files must at least give **read** access to the user running Immich (Default: `apps` (UID 568), `apps` (GID 568)).
|
||||||
|
If you want to be able to delete files or edit metadata in the external library using Immich, you will need to give the **modify** permission to the user running Immich.
|
||||||
|
|
||||||
|
- **Mount Path** is the location you will need to copy and paste into the external library settings within Immich.
|
||||||
|
- **Host Path** is the location on the TrueNAS Community Edition server where your external library is located.
|
||||||
|
- **Read Only** is a checkbox that you can tick if you want to prevent Immich from modifying the files in the external library. This is useful if you want to use Immich to view and search your external library without modifying it.
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Each mount path MUST be something unique and should NOT be your library or upload location or a Linux directory like `/lib`.
|
||||||
|
|
||||||
|
A general recommendation is to mount any external libraries to a path beginning with `/mnt` or `/media` followed by a unique name, such as `/mnt/external-libraries` or `/media/my-external-libraries`. If you plan to mount multiple external libraries, you can use paths like `/mnt/external-libraries/library1`, `/mnt/external-libraries/library2`, etc.
|
||||||
|
:::
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Multiple Datasets for Immich Storage</summary>
|
||||||
|
|
||||||
|
:::danger Advanced Users Only
|
||||||
|
This feature should only be used by advanced users.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Immich can use multiple datasets for its storage, allowing you to manage your data more granularly, similar to the old storage configuration. This is useful if you want to separate your data into different datasets for performance or organizational reasons. There is a general guide for this [here](/docs/guides/custom-locations), but read on for the TrueNAS guide.
|
||||||
|
|
||||||
|
Each additional dataset has to give the permission **_modify_** to the user who will run Immich (Default: `apps` (UID 568), `apps` (GID 568))
|
||||||
|
As described in the [Setting up Storage Datasets](#setting-up-storage-datasets) section above, you have to create the datasets with the **Apps** preset to ensure the correct permissions are set, or you can set the permissions manually after creating the datasets.
|
||||||
|
|
||||||
|
Immich uses 6 folders for its storage: `library`, `upload`, `thumbs`, `profile`, `encoded-video`, and `backups`. You can create a dataset for each of these folders or only for some of them.
|
||||||
|
|
||||||
|
To mount these datasets:
|
||||||
|
|
||||||
|
1. Add an **Additional Storage** entry for each dataset you want to use.
|
||||||
|
2. Select **Type** as **Host Path (Path that already exists on the system)**.
|
||||||
|
3. Enter the **Mount Path** with `/data/<folder-name>`. The `<folder-name>` is the name of the folder you want to mount, for example, `library`, `upload`, `thumbs`, `profile`, `encoded-video`, or `backups`.
|
||||||
|
:::danger Important
|
||||||
|
You have to write the full path, including `/data/`, as Immich expects the data to be in that location.
|
||||||
|
If you do not include this path, Immich will not be able to find the data and will not write the data to the location you specified.
|
||||||
|
:::
|
||||||
|
4. Select the **Host Path** as the dataset you created for that folder, for example, `/mnt/tank/immich/library`, `/mnt/tank/immich/upload`, etc.
|
||||||
|
|
||||||
|
<img
|
||||||
|
src={require('./img/truenas/truenas10.webp').default}
|
||||||
|
width="40%"
|
||||||
|
alt="Use Multiple Datasets for Immich Storage with Additional Storage"
|
||||||
|
className="border rounded-xl"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<!-- A section for Labels could be added, but I don't think it is needed as they are of no use for Immich. -->
|
||||||
|
|
||||||
### Resources Configuration
|
### Resources Configuration
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas09.webp').default}
|
src={require('./img/truenas/truenas11.webp').default}
|
||||||
width="40%"
|
width="40%"
|
||||||
alt="Resource Limits"
|
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Accept the default **CPU** limit of `2` threads or specify the number of threads (CPUs with Multi-/Hyper-threading have 2 threads per core).
|
- **CPU**: Depending on your system resources, you can keep the default value of `2` threads or specify a different number. Immich recommends at least `8` threads.
|
||||||
|
|
||||||
Specify the **Memory** limit in MB of RAM. Immich recommends at least 6000 MB (6GB). If you selected **Enable Machine Learning** in **Immich Configuration**, you should probably set this above 8000 MB.
|
- **Memory**: Limit in MB of RAM. Immich recommends at least 6000 MB (6GB). If you selected **Enable Machine Learning** in **Immich Configuration**, you should probably set this above 8000 MB.
|
||||||
|
|
||||||
:::info Older TrueNAS Versions
|
Both **CPU** and **Memory** are limits, not reservations. This means that Immich can use up to the specified amount of CPU threads and RAM, but it will not reserve that amount of resources at all times. The system will allocate resources as needed, and Immich will use less than the specified amount most of the time.
|
||||||
Before TrueNAS Community Edition version 24.10 Electric Eel:
|
|
||||||
|
|
||||||
The **CPU** value was specified in a different format with a default of `4000m` which is 4 threads.
|
- Enable **GPU Configuration** options if you have a GPU or CPU with integrated graphics that you will use for [Hardware Transcoding](/docs/features/hardware-transcoding) and/or [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md).
|
||||||
|
|
||||||
The **Memory** value was specified in a different format with a default of `8Gi` which is 8 GiB of RAM. The value was specified in bytes or a number with a measurement suffix. Examples: `129M`, `123Mi`, `1000000000`
|
The process for NVIDIA GPU passthrough requires additional steps.
|
||||||
:::
|
More details here: [GPU Passthrough Docs for TrueNAS Apps](https://apps.truenas.com/managing-apps/installing-apps/#gpu-passthrough)
|
||||||
|
|
||||||
Enable **GPU Configuration** options if you have a GPU that you will use for [Hardware Transcoding](/docs/features/hardware-transcoding) and/or [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md). More info: [GPU Passthrough Docs for TrueNAS Apps](https://apps.truenas.com/managing-apps/installing-apps/#gpu-passthrough)
|
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|
||||||
Finally, click **Install**.
|
Finally, click **Install**.
|
||||||
The system opens the **Installed Applications** screen with the Immich app in the **Deploying** state.
|
The system opens the **Installed Applications** screen with the Immich app in the **Deploying** state.
|
||||||
When the installation completes it changes to **Running**.
|
When the installation completes, it changes to **Running**.
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={require('./img/truenas04.webp').default}
|
src={require('./img/truenas/truenas12.webp').default}
|
||||||
width="100%"
|
width="100%"
|
||||||
alt="Immich Installed"
|
alt="Immich Installed"
|
||||||
className="border rounded-xl"
|
className="border rounded-xl"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Click **Web Portal** on the **Application Info** widget to open the Immich web interface to set up your account and begin uploading photos.
|
Click **Web Portal** on the **Application Info** widget, or go to the URL `http://<your-truenas-ip>:30041` in your web browser to open the Immich web interface. This will show you the onboarding process to set up your first user account, which will be an administrator account.
|
||||||
|
|
||||||
|
After that, you can start using Immich to upload and manage your photos and videos.
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
For more information on how to use the application once installed, please refer to the [Post Install](/docs/install/post-install.mdx) guide.
|
For more information on how to use the application once installed, please refer to the [Post Install](/docs/install/post-install.mdx) guide.
|
||||||
@@ -228,23 +344,6 @@ For more information on how to use the application once installed, please refer
|
|||||||
- Click **Update** at the very bottom of the page to save changes.
|
- Click **Update** at the very bottom of the page to save changes.
|
||||||
- TrueNAS automatically updates, recreates, and redeploys the Immich container with the updated settings.
|
- TrueNAS automatically updates, recreates, and redeploys the Immich container with the updated settings.
|
||||||
|
|
||||||
## Environment Variables
|
|
||||||
|
|
||||||
You can set [Environment Variables](/docs/install/environment-variables) by clicking **Add** on the **Additional Environment Variables** option and filling in the **Name** and **Value**.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={require('./img/truenas11.webp').default}
|
|
||||||
width="40%"
|
|
||||||
alt="Environment Variables"
|
|
||||||
className="border rounded-xl"
|
|
||||||
/>
|
|
||||||
|
|
||||||
:::info
|
|
||||||
Some Environment Variables are not available for the TrueNAS Community Edition app. This is mainly because they can be configured through GUI options in the [Edit Immich screen](#edit-app-settings).
|
|
||||||
|
|
||||||
Some examples are: `IMMICH_VERSION`, `UPLOAD_LOCATION`, `DB_DATA_LOCATION`, `TZ`, `IMMICH_LOG_LEVEL`, `DB_PASSWORD`, `REDIS_PASSWORD`.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Updating the App
|
## Updating the App
|
||||||
|
|
||||||
:::danger
|
:::danger
|
||||||
@@ -261,3 +360,116 @@ To update the app to the latest version:
|
|||||||
- You may view the Changelog.
|
- You may view the Changelog.
|
||||||
- Click **Upgrade** to begin the process and open a counter dialog that shows the upgrade progress.
|
- Click **Upgrade** to begin the process and open a counter dialog that shows the upgrade progress.
|
||||||
- When complete, the update badge and buttons disappear and the application Update state on the Installed screen changes from Update Available to Up to date.
|
- When complete, the update badge and buttons disappear and the application Update state on the Installed screen changes from Update Available to Up to date.
|
||||||
|
|
||||||
|
## Migration
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
Perform a backup of your Immich data before proceeding with the migration steps below. This is crucial to prevent any data loss if something goes wrong during the migration process.
|
||||||
|
|
||||||
|
The migration should also be performed when the Immich app is not running to ensure no data is being written while you are copying the data.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Migration from Old Storage Configuration
|
||||||
|
|
||||||
|
There are two ways to migrate from the old storage configuration to the new one, depending on whether you want to keep the old multiple datasets or if you want to move to a double dataset configuration with a single dataset for Immich data storage and a single dataset for Postgres data storage.
|
||||||
|
|
||||||
|
:::note Old TrueNAS Versions Permissions
|
||||||
|
If you were using an older version of TrueNAS (before 24.10.2.2), the datasets, except the one for **pgData** had only to be owned by the `root` user (UID 0). You might have to add the **modify** permission to the `apps` user (UID 568) or the user you want to run Immich as, to all of them, except **pgData**. The steps to add or change ACL permissions are described in the [TrueNAS documentation](https://www.truenas.com/docs/scale/scaletutorials/datasets/permissionsscale/).
|
||||||
|
:::
|
||||||
|
|
||||||
|
<Tabs groupId="truenas-migration-tabs">
|
||||||
|
<TabItem value="migrate-new-dataset" label="Migrate data to a new dataset (recommended)" default>
|
||||||
|
|
||||||
|
To migrate from the old storage configuration to the new one, you will need to create a new dataset for the Immich data storage and copy the data from the old datasets to the new ones. The steps are as follows:
|
||||||
|
|
||||||
|
1. **Stop the Immich app** from the TrueNAS web interface to ensure no data is being written while you are copying the data.
|
||||||
|
2. **Create a new dataset** for the Immich data storage, for example, `data`. As described in the [Setting up Storage Datasets](#setting-up-storage-datasets) section above, create the dataset with the **Apps** preset to ensure the correct permissions are set.
|
||||||
|
3. **Copy the data** from the old datasets to the new dataset. We advise using the `rsync` command to copy the data, as it will preserve the permissions and ownership of the files. The following commands are examples:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -av /mnt/tank/immich/library/ /mnt/tank/immich/data/library/
|
||||||
|
rsync -av /mnt/tank/immich/upload/ /mnt/tank/immich/data/upload/
|
||||||
|
rsync -av /mnt/tank/immich/thumbs/ /mnt/tank/immich/data/thumbs/
|
||||||
|
rsync -av /mnt/tank/immich/profile/ /mnt/tank/immich/data/profile/
|
||||||
|
rsync -av /mnt/tank/immich/video/ /mnt/tank/immich/data/encoded-video/
|
||||||
|
rsync -av /mnt/tank/immich/backups/ /mnt/tank/immich/data/backups/
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure to replace `/mnt/tank/immich/` with the correct path to your old datasets and `/mnt/tank/immich/data/` with the correct path to your new dataset.
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
If you were using **ixVolume (dataset created automatically by the system)** for Immich data storage, the path to the data should be `/mnt/.ix-apps/app_mounts/immich/`. You have to use this path instead of `/mnt/tank/immich/` in the `rsync` command above, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -av /mnt/.ix-apps/app_mounts/immich/library/ /mnt/tank/immich/data/library/
|
||||||
|
```
|
||||||
|
|
||||||
|
If you were also using an ixVolume for Postgres data storage, you also should, first create the pgData dataset, as described in the [Setting up Storage Datasets](#setting-up-storage-datasets) section above, and then you can use the following command to copy the Postgres data:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -av /mnt/.ix-apps/app_mounts/immich/pgData/ /mnt/tank/immich/pgData/
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Make sure that for each folder, the `.immich` file is copied as well, as it contains important metadata for Immich. If for some reason the `.immich` file is not copied, you can copy it manually with the `rsync` command, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -av /mnt/tank/immich/library/.immich /mnt/tank/immich/data/library/
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `library` with the name of the folder where you are copying the file.
|
||||||
|
:::
|
||||||
|
|
||||||
|
4. **Update the permissions** as the permissions of the data that have been copied has been preserved, to ensure that the `apps` user (UID 568) has the correct permissions on all the copied data. If you just created the dataset with the **Apps** preset, from the TrueNAS web interface, go to the **Datasets** screen, select the **data** dataset, click on the **Edit** button next to **Permissions**, tick the "Apply permissions recursively" checkbox, and click **Save**. This will apply the correct permissions to all the copied data.
|
||||||
|
5. **Update the Immich app** to use the new dataset:
|
||||||
|
- Go to the **Installed Applications** screen and select Immich from the list of installed applications.
|
||||||
|
- Click **Edit** on the **Application Info** widget.
|
||||||
|
- In the **Storage Configuration** section, untick the **Use Old Storage Configuration (Deprecated)** checkbox.
|
||||||
|
- For the **Data Storage**, select **Host Path (Path that already exists on the system)** and then select the new dataset you created for Immich data storage, for example, `data`.
|
||||||
|
- For the **Postgres Data Storage**, verify that it is still set to the dataset you created for Postgres data storage, for example, `pgData`.
|
||||||
|
- Click **Update** at the bottom of the page to save changes.
|
||||||
|
|
||||||
|
6. **Start the Immich app** from the TrueNAS web interface.
|
||||||
|
|
||||||
|
This will recreate the Immich container with the new storage configuration and start the app.
|
||||||
|
|
||||||
|
If everything went well, you should now be able to access Immich with the new storage configuration. You can verify that the data has been copied correctly by checking the Immich web interface and ensuring that all your photos and videos are still available. You may delete the old datasets, if you no longer need them, using the TrueNAS web interface.
|
||||||
|
|
||||||
|
If you were using **ixVolume (dataset created automatically by the system)** or folders for Immich data storage, you can delete the old datasets using the following commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/library
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/uploads
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/thumbs
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/profile
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/video
|
||||||
|
rm -r /mnt/.ix-apps/app_mounts/immich/backups
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="migrate-old-dataset" label="Keep the existing datasets">
|
||||||
|
|
||||||
|
To migrate from the old storage configuration to the new one without creating new datasets.
|
||||||
|
1. **Stop the Immich app** from the TrueNAS web interface to ensure no data is being written while you are updating the app.
|
||||||
|
2. **Update the datasets permissions**: Ensure that the datasets used for Immich data storage (`library`, `upload`, `thumbs`, `profile`, `video`, `backups`) have the correct permissions set for the user who will run Immich. The user should have ***modify*** permissions on these datasets. The default user for Immich is `apps` (UID 568) and the default group is `apps` (GID 568). If you are using a different user, make sure to set the permissions accordingly. You can do this from the TrueNAS web interface by going to the **Datasets** screen, selecting each dataset, clicking on the **Edit** button next to **Permissions**, and adding the user with ***modify*** permissions.
|
||||||
|
3. **Update the Immich app** to use the existing datasets:
|
||||||
|
- Go to the **Installed Applications** screen and select Immich from the list of installed applications.
|
||||||
|
- Click **Edit** on the **Application Info** widget.
|
||||||
|
- In the **Storage Configuration** section, untick the **Use Old Storage Configuration (Deprecated)** checkbox.
|
||||||
|
- For the **Data Storage**, you can keep the **ixVolume (dataset created automatically by the system)** as no data will be directly written to it. We recommend selecting **Host Path (Path that already exists on the system)** and then select a **new** dataset you created for Immich data storage, for example, `data`.
|
||||||
|
- For the **Postgres Data Storage**, keep **Host Path (Path that already exists on the system)** and then select the existing dataset you used for Postgres data storage, for example, `pgData`.
|
||||||
|
- Following the instructions in the [Multiple Datasets for Immich Storage](#additional-storage-advanced-users) section, you can add, **for each old dataset**, a new Additional Storage with the following settings:
|
||||||
|
- **Type**: `Host Path (Path that already exists on the system)`
|
||||||
|
- **Mount Path**: `/data/<folder-name>` (e.g. `/data/library`)
|
||||||
|
- **Host Path**: `/mnt/<your-pool-name>/<dataset-name>` (e.g. `/mnt/tank/immich/library`)
|
||||||
|
:::danger Ensure using the correct paths names
|
||||||
|
Make sure to replace `<folder-name>` with the actual name of the folder used by Immich: `library`, `upload`, `thumbs`, `profile`, `encoded-video`, and `backups`. Also, replace `<your-pool-name>` and `<dataset-name>` with the actual names of your pool and dataset.
|
||||||
|
:::
|
||||||
|
- **Read Only**: Keep it unticked as Immich needs to write to these datasets.
|
||||||
|
- Click **Update** at the bottom of the page to save changes.
|
||||||
|
4. **Start the Immich app** from the TrueNAS web interface. This will recreate the Immich container with the new storage configuration and start the app. If everything went well, you should now be able to access Immich with the new storage configuration. You can verify that the data is still available by checking the Immich web interface and ensuring that all your photos and videos are still accessible.
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|||||||
@@ -27,3 +27,102 @@ docker image prune
|
|||||||
[watchtower]: https://containrrr.dev/watchtower/
|
[watchtower]: https://containrrr.dev/watchtower/
|
||||||
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
||||||
[releases]: https://github.com/immich-app/immich/releases
|
[releases]: https://github.com/immich-app/immich/releases
|
||||||
|
|
||||||
|
## Migrating to VectorChord
|
||||||
|
|
||||||
|
:::info
|
||||||
|
If you deploy Immich using Docker Compose, see `ghcr.io/immich-app/postgres` in the `docker-compose.yml` file and have not explicitly set the `DB_VECTOR_EXTENSION` environmental variable, your Immich database is already using VectorChord and this section does not apply to you.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::important
|
||||||
|
If you do not deploy Immich using Docker Compose and see a deprecation warning for pgvecto.rs on server startup, you should refer to the maintainers of the Immich distribution for guidance (if using a turnkey solution) or adapt the instructions for your specific setup.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Immich has migrated off of the deprecated pgvecto.rs database extension to its successor, [VectorChord](https://github.com/tensorchord/VectorChord), which comes with performance improvements in almost every aspect. This section will guide you on how to make this change in a Docker Compose setup.
|
||||||
|
|
||||||
|
Before making any changes, please [back up your database](/docs/administration/backup-and-restore). While every effort has been made to make this migration as smooth as possible, there’s always a chance that something can go wrong.
|
||||||
|
|
||||||
|
After making a backup, please modify your `docker-compose.yml` file with the following information.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
[...]
|
||||||
|
|
||||||
|
database:
|
||||||
|
container_name: immich_postgres
|
||||||
|
- image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||||
|
+ image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
|
POSTGRES_INITDB_ARGS: '--data-checksums'
|
||||||
|
+ # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
|
||||||
|
+ # DB_STORAGE_TYPE: 'HDD'
|
||||||
|
volumes:
|
||||||
|
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
|
||||||
|
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||||
|
- healthcheck:
|
||||||
|
- test: >-
|
||||||
|
- pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
|
||||||
|
- Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
|
||||||
|
- --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
|
||||||
|
- echo "checksum failure count is $$Chksum";
|
||||||
|
- [ "$$Chksum" = '0' ] || exit 1
|
||||||
|
- interval: 5m
|
||||||
|
- start_interval: 30s
|
||||||
|
- start_period: 5m
|
||||||
|
- command: >-
|
||||||
|
- postgres
|
||||||
|
- -c shared_preload_libraries=vectors.so
|
||||||
|
- -c 'search_path="$$user", public, vectors'
|
||||||
|
- -c logging_collector=on
|
||||||
|
- -c max_wal_size=2GB
|
||||||
|
- -c shared_buffers=512MB
|
||||||
|
- -c wal_compression=on
|
||||||
|
+ shm_size: 128mb
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::important
|
||||||
|
If you deviated from the defaults of pg14 or pgvectors0.2.0, you must adjust the pg major version and pgvecto.rs version. If you are still using the default `docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0` image, you can just follow the changes above. For example, if the previous image is `docker.io/tensorchord/pgvecto-rs:pg16-v0.3.0`, the new image should be `ghcr.io/immich-app/postgres:16-vectorchord0.3.0-pgvectors0.3.0` instead of the image specified in the diff.
|
||||||
|
:::
|
||||||
|
|
||||||
|
After making these changes, you can start Immich as normal. Immich will make some changes to the DB during startup, which can take seconds to minutes to finish, depending on hardware and library size. In particular, it’s normal for the server logs to be seemingly stuck at `Reindexing clip_index` and `Reindexing face_index`for some time if you have over 100k assets in Immich and/or Immich is on a relatively weak server. If you see these logs and there are no errors, just give it time.
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
After switching to VectorChord, you should not downgrade Immich below 1.133.0.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Please don’t hesitate to contact us on [GitHub](https://github.com/immich-app/immich/discussions) or [Discord](https://discord.immich.app/) if you encounter migration issues.
|
||||||
|
|
||||||
|
### VectorChord FAQ
|
||||||
|
|
||||||
|
#### I have a separate PostgreSQL instance shared with multiple services. How can I switch to VectorChord?
|
||||||
|
|
||||||
|
Please see the [standalone PostgreSQL documentation](/docs/administration/postgres-standalone#migrating-to-vectorchord) for migration instructions. The migration path will be different depending on whether you’re currently using pgvecto.rs or pgvector, as well as whether Immich has superuser DB permissions.
|
||||||
|
|
||||||
|
#### Why are so many lines removed from the `docker-compose.yml` file? Does this mean the health check is removed?
|
||||||
|
|
||||||
|
These lines are now incorporated into the image itself along with some additional tuning.
|
||||||
|
|
||||||
|
#### What does this change mean for my existing DB backups?
|
||||||
|
|
||||||
|
The new DB image includes pgvector and pgvecto.rs in addition to VectorChord, so you can use this image to restore from existing backups that used either of these extensions. However, backups made after switching to VectorChord require an image containing VectorChord to restore successfully.
|
||||||
|
|
||||||
|
#### Do I still need pgvecto.rs installed after migrating to VectorChord?
|
||||||
|
|
||||||
|
pgvecto.rs only needs to be available during the migration, or if you need to restore from a backup that used pgvecto.rs. For a leaner DB and a smaller image, you can optionally switch to an image variant that doesn’t have pgvecto.rs installed after you’ve performed the migration and started Immich: `ghcr.io/immich-app/postgres:14-vectorchord0.4.3`, changing the PostgreSQL version as appropriate.
|
||||||
|
|
||||||
|
#### Why does it matter whether my database is on an SSD or an HDD?
|
||||||
|
|
||||||
|
These storage mediums have different performance characteristics. As a result, the optimal settings for an SSD are not the same as those for an HDD. Either configuration is compatible with SSD and HDD, but using the right configuration will make Immich snappier. As a general tip, we recommend users store the database on an SSD whenever possible.
|
||||||
|
|
||||||
|
#### Can I use the new database image as a general PostgreSQL image outside of Immich?
|
||||||
|
|
||||||
|
It’s a standard PostgreSQL container image that additionally contains the VectorChord, pgvector, and (optionally) pgvecto.rs extensions. If you were using the previous pgvecto.rs image for other purposes, you can similarly do so with this image.
|
||||||
|
|
||||||
|
#### If pgvecto.rs and pgvector still work, why should I switch to VectorChord?
|
||||||
|
|
||||||
|
VectorChord is faster, more stable, uses less RAM, and (with the settings Immich uses) offers higher-quality results than pgvector and pgvecto.rs. This translates to better search and facial recognition experiences. In addition, pgvecto.rs support will be dropped in the future, so changing it sooner will avoid disruption.
|
||||||
|
|||||||
20545
docs/package-lock.json
generated
@@ -7,7 +7,8 @@
|
|||||||
"format": "prettier --check .",
|
"format": "prettier --check .",
|
||||||
"format:fix": "prettier --write .",
|
"format:fix": "prettier --write .",
|
||||||
"start": "docusaurus start --port 3005",
|
"start": "docusaurus start --port 3005",
|
||||||
"build": "docusaurus build",
|
"copy:openapi": "jq -c < ../open-api/immich-openapi-specs.json > ./static/openapi.json || exit 0",
|
||||||
|
"build": "npm run copy:openapi && docusaurus build",
|
||||||
"swizzle": "docusaurus swizzle",
|
"swizzle": "docusaurus swizzle",
|
||||||
"deploy": "docusaurus deploy",
|
"deploy": "docusaurus deploy",
|
||||||
"clear": "docusaurus clear",
|
"clear": "docusaurus clear",
|
||||||
@@ -23,8 +24,6 @@
|
|||||||
"@mdi/react": "^1.6.1",
|
"@mdi/react": "^1.6.1",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"classnames": "^2.3.2",
|
|
||||||
"clsx": "^2.0.0",
|
|
||||||
"docusaurus-lunr-search": "^3.3.2",
|
"docusaurus-lunr-search": "^3.3.2",
|
||||||
"docusaurus-preset-openapi": "^0.7.5",
|
"docusaurus-preset-openapi": "^0.7.5",
|
||||||
"lunr": "^2.3.9",
|
"lunr": "^2.3.9",
|
||||||
@@ -59,6 +58,6 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "22.17.1"
|
"node": "22.19.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ const projects: CommunityProjectProps[] = [
|
|||||||
description: 'Speed up your machine learning by load balancing your requests to multiple computers',
|
description: 'Speed up your machine learning by load balancing your requests to multiple computers',
|
||||||
url: 'https://github.com/apetersson/immich_ml_balancer',
|
url: 'https://github.com/apetersson/immich_ml_balancer',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Immich Drop Uploader',
|
||||||
|
description: 'A tiny, zero-login web app for collecting photos/videos from anyone into your Immich server.',
|
||||||
|
url: 'https://github.com/Nasogaa/immich-drop',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function CommunityProject({ title, description, url }: CommunityProjectProps): JSX.Element {
|
function CommunityProject({ title, description, url }: CommunityProjectProps): JSX.Element {
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ import {
|
|||||||
mdiCloudKeyOutline,
|
mdiCloudKeyOutline,
|
||||||
mdiRegex,
|
mdiRegex,
|
||||||
mdiCodeJson,
|
mdiCodeJson,
|
||||||
|
mdiClockOutline,
|
||||||
|
mdiAccountOutline,
|
||||||
|
mdiRestart,
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -26,6 +29,42 @@ const withLanguage = (date: Date) => (language: string) => date.toLocaleDateStri
|
|||||||
type Item = Omit<TimelineItem, 'done' | 'getDateLabel'> & { date: Date };
|
type Item = Omit<TimelineItem, 'done' | 'getDateLabel'> & { date: Date };
|
||||||
|
|
||||||
const items: Item[] = [
|
const items: Item[] = [
|
||||||
|
{
|
||||||
|
icon: mdiClockOutline,
|
||||||
|
iconColor: 'gray',
|
||||||
|
title: 'setTimeout is cursed',
|
||||||
|
description:
|
||||||
|
'The setTimeout method in JavaScript is cursed when used with small values because the implementation may or may not actually wait the specified time.',
|
||||||
|
link: {
|
||||||
|
url: 'https://github.com/immich-app/immich/pull/20655',
|
||||||
|
text: '#20655',
|
||||||
|
},
|
||||||
|
date: new Date(2025, 7, 4),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAccountOutline,
|
||||||
|
iconColor: '#DAB1DA',
|
||||||
|
title: 'PostgreSQL USER is cursed',
|
||||||
|
description:
|
||||||
|
'The USER keyword in PostgreSQL is cursed because you can select from it like a table, which leads to confusion if you have a table name user as well.',
|
||||||
|
link: {
|
||||||
|
url: 'https://github.com/immich-app/immich/pull/19891',
|
||||||
|
text: '#19891',
|
||||||
|
},
|
||||||
|
date: new Date(2025, 7, 4),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiRestart,
|
||||||
|
iconColor: '#8395e3',
|
||||||
|
title: 'PostgreSQL RESET is cursed',
|
||||||
|
description:
|
||||||
|
'PostgreSQL RESET is cursed because it is impossible to RESET a PostgreSQL extension parameter if the extension has been uninstalled.',
|
||||||
|
link: {
|
||||||
|
url: 'https://github.com/immich-app/immich/pull/19363',
|
||||||
|
text: '#19363',
|
||||||
|
},
|
||||||
|
date: new Date(2025, 5, 20),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: mdiRegex,
|
icon: mdiRegex,
|
||||||
iconColor: 'purple',
|
iconColor: 'purple',
|
||||||
|
|||||||
52
docs/static/archived-versions.json
vendored
@@ -1,4 +1,56 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"label": "v1.141.1",
|
||||||
|
"url": "https://v1.141.1.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.141.0",
|
||||||
|
"url": "https://v1.141.0.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.140.1",
|
||||||
|
"url": "https://v1.140.1.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.140.0",
|
||||||
|
"url": "https://v1.140.0.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.139.4",
|
||||||
|
"url": "https://v1.139.4.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.139.3",
|
||||||
|
"url": "https://v1.139.3.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.139.2",
|
||||||
|
"url": "https://v1.139.2.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.138.1",
|
||||||
|
"url": "https://v1.138.1.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.138.0",
|
||||||
|
"url": "https://v1.138.0.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.137.3",
|
||||||
|
"url": "https://v1.137.3.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.137.2",
|
||||||
|
"url": "https://v1.137.2.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.137.1",
|
||||||
|
"url": "https://v1.137.1.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.137.0",
|
||||||
|
"url": "https://v1.137.0.archive.immich.app"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "v1.136.0",
|
"label": "v1.136.0",
|
||||||
"url": "https://v1.136.0.archive.immich.app"
|
"url": "https://v1.136.0.archive.immich.app"
|
||||||
|
|||||||
1
e2e/.gitignore
vendored
@@ -3,3 +3,4 @@ node_modules/
|
|||||||
/playwright-report/
|
/playwright-report/
|
||||||
/blob-report/
|
/blob-report/
|
||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
|
/dist
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
22.17.1
|
22.19.0
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ services:
|
|||||||
image: redis:6.2-alpine@sha256:7fe72c486b910f6b1a9769c937dad5d63648ddee82e056f47417542dd40825bb
|
image: redis:6.2-alpine@sha256:7fe72c486b910f6b1a9769c937dad5d63648ddee82e056f47417542dd40825bb
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0@sha256:0e763a2383d56f90364fcd72767ac41400cd30d2627f407f7e7960c9f1923c21
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0@sha256:7a4469b9484e37bf2630a60bc2f02f086dae898143b599ecc1c93f619849ef6b
|
||||||
command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf
|
command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: postgres
|
POSTGRES_PASSWORD: postgres
|
||||||
|
|||||||
7451
e2e/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.136.0",
|
"version": "1.141.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -19,23 +19,21 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.1.0",
|
|
||||||
"@eslint/js": "^9.8.0",
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/cli": "file:../cli",
|
"@immich/cli": "file:../cli",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@playwright/test": "^1.44.1",
|
"@playwright/test": "^1.44.1",
|
||||||
"@socket.io/component-emitter": "^3.1.2",
|
"@socket.io/component-emitter": "^3.1.2",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"@types/node": "^22.16.5",
|
"@types/node": "^22.18.0",
|
||||||
"@types/oidc-provider": "^9.0.0",
|
"@types/oidc-provider": "^9.0.0",
|
||||||
"@types/pg": "^8.15.1",
|
"@types/pg": "^8.15.1",
|
||||||
"@types/pngjs": "^6.0.4",
|
"@types/pngjs": "^6.0.4",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^59.0.0",
|
"eslint-plugin-unicorn": "^60.0.0",
|
||||||
"exiftool-vendored": "^28.3.1",
|
"exiftool-vendored": "^28.3.1",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"jose": "^5.6.3",
|
"jose": "^5.6.3",
|
||||||
@@ -45,7 +43,7 @@
|
|||||||
"pngjs": "^7.0.0",
|
"pngjs": "^7.0.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-organize-imports": "^4.0.0",
|
"prettier-plugin-organize-imports": "^4.0.0",
|
||||||
"sharp": "^0.34.0",
|
"sharp": "^0.34.3",
|
||||||
"socket.io-client": "^4.7.4",
|
"socket.io-client": "^4.7.4",
|
||||||
"supertest": "^7.0.0",
|
"supertest": "^7.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
@@ -54,6 +52,6 @@
|
|||||||
"vitest": "^3.0.0"
|
"vitest": "^3.0.0"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "22.17.1"
|
"node": "22.19.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -683,7 +683,7 @@ describe('/albums', () => {
|
|||||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||||
.send({ role: AlbumUserRole.Editor });
|
.send({ role: AlbumUserRole.Editor });
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(204);
|
||||||
|
|
||||||
// Get album to verify the role change
|
// Get album to verify the role change
|
||||||
const { body } = await request(app)
|
const { body } = await request(app)
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ describe('/asset', () => {
|
|||||||
expect(body).toMatchObject({ id: user1Assets[0].id, livePhotoVideoId: null });
|
expect(body).toMatchObject({ id: user1Assets[0].id, livePhotoVideoId: null });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update date time original when sidecar file contains DateTimeOriginal', async () => {
|
it.skip('should update date time original when sidecar file contains DateTimeOriginal', async () => {
|
||||||
const sidecarData = `<?xpacket begin='?' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
const sidecarData = `<?xpacket begin='?' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||||
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 12.40'>
|
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 12.40'>
|
||||||
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
||||||
@@ -854,6 +854,30 @@ describe('/asset', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('PUT /assets', () => {
|
||||||
|
it('should update date time original relatively', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.put(`/assets/`)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||||
|
.send({ ids: [user1Assets[0].id], dateTimeRelative: -1441 });
|
||||||
|
|
||||||
|
expect(body).toEqual({});
|
||||||
|
expect(status).toEqual(204);
|
||||||
|
|
||||||
|
const result = await request(app)
|
||||||
|
.get(`/assets/${user1Assets[0].id}`)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||||
|
.send();
|
||||||
|
|
||||||
|
expect(result.body).toMatchObject({
|
||||||
|
id: user1Assets[0].id,
|
||||||
|
exifInfo: expect.objectContaining({
|
||||||
|
dateTimeOriginal: '2023-11-19T01:10:00+00:00',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('POST /assets', () => {
|
describe('POST /assets', () => {
|
||||||
beforeAll(setupTests, 30_000);
|
beforeAll(setupTests, 30_000);
|
||||||
|
|
||||||
@@ -1442,10 +1466,10 @@ describe('/asset', () => {
|
|||||||
expectedDate: '2023-04-04T04:00:00.000Z',
|
expectedDate: '2023-04-04T04:00:00.000Z',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CreateDate when DateTimeOriginal missing',
|
name: 'CreationDate when DateTimeOriginal missing',
|
||||||
exifData: {
|
exifData: {
|
||||||
CreateDate: '2023:05:05 05:00:00', // TESTABLE
|
CreationDate: '2023:05:05 05:00:00', // TESTABLE
|
||||||
CreationDate: '2023:07:07 07:00:00', // TESTABLE
|
CreateDate: '2023:07:07 07:00:00', // TESTABLE
|
||||||
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
|
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
|
||||||
},
|
},
|
||||||
expectedDate: '2023-05-05T05:00:00.000Z',
|
expectedDate: '2023-05-05T05:00:00.000Z',
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ describe('/partners', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
createPartner({ id: user2.userId }, { headers: asBearerAuth(user1.accessToken) }),
|
createPartner({ partnerCreateDto: { sharedWithId: user2.userId } }, { headers: asBearerAuth(user1.accessToken) }),
|
||||||
createPartner({ id: user1.userId }, { headers: asBearerAuth(user2.accessToken) }),
|
createPartner({ partnerCreateDto: { sharedWithId: user1.userId } }, { headers: asBearerAuth(user2.accessToken) }),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ describe('/partners', () => {
|
|||||||
.delete(`/partners/${user3.userId}`)
|
.delete(`/partners/${user3.userId}`)
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(204);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw a bad request if partner not found', async () => {
|
it('should throw a bad request if partner not found', async () => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
} from '@immich/sdk';
|
} from '@immich/sdk';
|
||||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||||
import { errorDto } from 'src/responses';
|
import { errorDto } from 'src/responses';
|
||||||
import { app, asBearerAuth, shareUrl, utils } from 'src/utils';
|
import { app, asBearerAuth, baseUrl, shareUrl, utils } from 'src/utils';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { beforeAll, describe, expect, it } from 'vitest';
|
import { beforeAll, describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
@@ -78,6 +78,7 @@ describe('/shared-links', () => {
|
|||||||
type: SharedLinkType.Album,
|
type: SharedLinkType.Album,
|
||||||
albumId: metadataAlbum.id,
|
albumId: metadataAlbum.id,
|
||||||
showMetadata: true,
|
showMetadata: true,
|
||||||
|
slug: 'metadata-album',
|
||||||
}),
|
}),
|
||||||
utils.createSharedLink(user1.accessToken, {
|
utils.createSharedLink(user1.accessToken, {
|
||||||
type: SharedLinkType.Album,
|
type: SharedLinkType.Album,
|
||||||
@@ -138,6 +139,17 @@ describe('/shared-links', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('GET /s/:slug', () => {
|
||||||
|
it('should work for slug auth', async () => {
|
||||||
|
const resp = await request(baseUrl).get(`/s/${linkWithMetadata.slug}`);
|
||||||
|
expect(resp.status).toBe(200);
|
||||||
|
expect(resp.header['content-type']).toContain('text/html');
|
||||||
|
expect(resp.text).toContain(
|
||||||
|
`<meta name="description" content="${metadataAlbum.assets.length} shared photos & videos" />`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('GET /shared-links', () => {
|
describe('GET /shared-links', () => {
|
||||||
it('should require authentication', async () => {
|
it('should require authentication', async () => {
|
||||||
const { status, body } = await request(app).get('/shared-links');
|
const { status, body } = await request(app).get('/shared-links');
|
||||||
@@ -473,7 +485,7 @@ describe('/shared-links', () => {
|
|||||||
.delete(`/shared-links/${linkWithAlbum.id}`)
|
.delete(`/shared-links/${linkWithAlbum.id}`)
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ describe('/users', () => {
|
|||||||
const { status } = await request(app)
|
const { status } = await request(app)
|
||||||
.delete(`/users/me/license`)
|
.delete(`/users/me/license`)
|
||||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export const tempDir = tmpdir();
|
|||||||
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
|
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
|
||||||
export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
|
export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
|
||||||
export const immichCli = (args: string[]) =>
|
export const immichCli = (args: string[]) =>
|
||||||
executeCommand('node', ['node_modules/.bin/immich', '-d', `/${tempDir}/immich/`, ...args]).promise;
|
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../cli' }).promise;
|
||||||
export const immichAdmin = (args: string[]) =>
|
export const immichAdmin = (args: string[]) =>
|
||||||
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', `immich-admin ${args.join(' ')}`]);
|
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', `immich-admin ${args.join(' ')}`]);
|
||||||
export const specialCharStrings = ["'", '"', ',', '{', '}', '*'];
|
export const specialCharStrings = ["'", '"', ',', '{', '}', '*'];
|
||||||
@@ -462,7 +462,8 @@ export const utils = {
|
|||||||
updateLibrary: (accessToken: string, id: string, dto: UpdateLibraryDto) =>
|
updateLibrary: (accessToken: string, id: string, dto: UpdateLibraryDto) =>
|
||||||
updateLibrary({ id, updateLibraryDto: dto }, { headers: asBearerAuth(accessToken) }),
|
updateLibrary({ id, updateLibraryDto: dto }, { headers: asBearerAuth(accessToken) }),
|
||||||
|
|
||||||
createPartner: (accessToken: string, id: string) => createPartner({ id }, { headers: asBearerAuth(accessToken) }),
|
createPartner: (accessToken: string, id: string) =>
|
||||||
|
createPartner({ partnerCreateDto: { sharedWithId: id } }, { headers: asBearerAuth(accessToken) }),
|
||||||
|
|
||||||
updateMyPreferences: (accessToken: string, userPreferencesUpdateDto: UserPreferencesUpdateDto) =>
|
updateMyPreferences: (accessToken: string, userPreferencesUpdateDto: UserPreferencesUpdateDto) =>
|
||||||
updateMyPreferences({ userPreferencesUpdateDto }, { headers: asBearerAuth(accessToken) }),
|
updateMyPreferences({ userPreferencesUpdateDto }, { headers: asBearerAuth(accessToken) }),
|
||||||
|
|||||||
112
i18n/ar.json
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"about": "عن",
|
"about": "حَوْل",
|
||||||
"account": "حساب",
|
"account": "حساب",
|
||||||
"account_settings": "إعدادات الحساب",
|
"account_settings": "إعدادات الحساب",
|
||||||
"acknowledge": "أُدرك ذلك",
|
"acknowledge": "أُدرك ذلك",
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"add_a_location": "إضافة موقع",
|
"add_a_location": "إضافة موقع",
|
||||||
"add_a_name": "إضافة إسم",
|
"add_a_name": "إضافة إسم",
|
||||||
"add_a_title": "إضافة عنوان",
|
"add_a_title": "إضافة عنوان",
|
||||||
|
"add_birthday": "أضف تاريخ الميلاد",
|
||||||
"add_endpoint": "اضف نقطة نهاية",
|
"add_endpoint": "اضف نقطة نهاية",
|
||||||
"add_exclusion_pattern": "إضافة نمط إستثناء",
|
"add_exclusion_pattern": "إضافة نمط إستثناء",
|
||||||
"add_import_path": "إضافة مسار الإستيراد",
|
"add_import_path": "إضافة مسار الإستيراد",
|
||||||
@@ -25,8 +26,11 @@
|
|||||||
"add_tag": "اضف علامة",
|
"add_tag": "اضف علامة",
|
||||||
"add_to": "إضافة إلى…",
|
"add_to": "إضافة إلى…",
|
||||||
"add_to_album": "إضافة إلى ألبوم",
|
"add_to_album": "إضافة إلى ألبوم",
|
||||||
"add_to_album_bottom_sheet_added": "تمت الاضافة{album}",
|
"add_to_album_bottom_sheet_added": "تمت الاضافة الى {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "موجودة مسبقا {album}",
|
"add_to_album_bottom_sheet_already_exists": "موجود مسبقا في {album}",
|
||||||
|
"add_to_album_toggle": "تبديل التحديد لـ{album}",
|
||||||
|
"add_to_albums": "إضافة الى البومات",
|
||||||
|
"add_to_albums_count": "إضافه إلى البومات ({count})",
|
||||||
"add_to_shared_album": "إضافة إلى ألبوم مشارك",
|
"add_to_shared_album": "إضافة إلى ألبوم مشارك",
|
||||||
"add_url": "إضافة رابط",
|
"add_url": "إضافة رابط",
|
||||||
"added_to_archive": "أُضيفت للأرشيف",
|
"added_to_archive": "أُضيفت للأرشيف",
|
||||||
@@ -34,16 +38,23 @@
|
|||||||
"added_to_favorites_count": "تم إضافة {count, number} إلى المفضلات",
|
"added_to_favorites_count": "تم إضافة {count, number} إلى المفضلات",
|
||||||
"admin": {
|
"admin": {
|
||||||
"add_exclusion_pattern_description": "إضافة أنماط الاستبعاد. يدعم التمويه باستخدام *، **، و؟. لتجاهل جميع الملفات في أي دليل يسمى \"Raw\"، استخدم \"**/Raw/**\". لتجاهل جميع الملفات التي تنتهي بـ \".tif\"، استخدم \"**/*.tif\". لتجاهل مسار مطلق، استخدم \"/path/to/ignore/**\".",
|
"add_exclusion_pattern_description": "إضافة أنماط الاستبعاد. يدعم التمويه باستخدام *، **، و؟. لتجاهل جميع الملفات في أي دليل يسمى \"Raw\"، استخدم \"**/Raw/**\". لتجاهل جميع الملفات التي تنتهي بـ \".tif\"، استخدم \"**/*.tif\". لتجاهل مسار مطلق، استخدم \"/path/to/ignore/**\".",
|
||||||
"admin_user": "مستخدم مدير",
|
"admin_user": "مستخدم مسؤول",
|
||||||
"asset_offline_description": "لم يعد هذا الأصل الخاص بالمكتبة الخارجية موجودًا على القرص وتم نقله إلى سلة المهملات. إذا تم نقل الملف داخل المكتبة، فتحقق من الجدول الزمني الخاص بك لمعرفة الأصل الجديد المقابل. لاستعادة هذا الأصل، يرجى التأكد من إمكانية الوصول إلى مسار الملف أدناه بواسطة Immich ومن ثم قم بمسح المكتبة.",
|
"asset_offline_description": "لم يعد هذا الأصل الخاص بالمكتبة الخارجية موجودًا على القرص وتم نقله إلى سلة المهملات. إذا تم نقل الملف داخل المكتبة، فتحقق من الجدول الزمني الخاص بك لمعرفة الأصل الجديد المقابل. لاستعادة هذا الأصل، يرجى التأكد من إمكانية الوصول إلى مسار الملف أدناه بواسطة Immich ومن ثم قم بمسح المكتبة.",
|
||||||
"authentication_settings": "إعدادات المصادقة",
|
"authentication_settings": "إعدادات المصادقة",
|
||||||
"authentication_settings_description": "إدارة كلمة المرور وOAuth وإعدادات المصادقة الأُخرى",
|
"authentication_settings_description": "إدارة كلمة المرور وOAuth وإعدادات المصادقة الأُخرى",
|
||||||
"authentication_settings_disable_all": "هل أنت متأكد أنك تريد تعطيل جميع وسائل تسجيل الدخول؟ سيتم تعطيل تسجيل الدخول بالكامل.",
|
"authentication_settings_disable_all": "هل أنت متأكد أنك تريد تعطيل جميع وسائل تسجيل الدخول؟ سيتم تعطيل تسجيل الدخول بالكامل.",
|
||||||
"authentication_settings_reenable": "لإعادة التفعيل، استخدم <link>أمر الخادم</link>.",
|
"authentication_settings_reenable": "لإعادة التفعيل، استخدم <link>أمر الخادم</link>.",
|
||||||
"background_task_job": "المهام الخلفية",
|
"background_task_job": "المهام في الخلفية",
|
||||||
"backup_database": "انشاء تفريغ قاعدة البيانات",
|
"backup_database": "انشاء تفريغ قاعدة البيانات",
|
||||||
"backup_database_enable_description": "تمكين تفريغ قاعدة البيانات",
|
"backup_database_enable_description": "تمكين تفريغ قاعدة البيانات",
|
||||||
"backup_keep_last_amount": "مقدار التفريغات السابقة للاحتفاظ بها",
|
"backup_keep_last_amount": "مقدار التفريغات السابقة للاحتفاظ بها",
|
||||||
|
"backup_onboarding_1_description": "نسخة خارج الموقع في موقع آخر.",
|
||||||
|
"backup_onboarding_2_description": "نسخ محلية على أجهزة مختلفة. يشمل ذلك الملفات الرئيسية ونسخة احتياطية محلية منها.",
|
||||||
|
"backup_onboarding_3_description": "إجمالي نسخ بياناتك، بما في ذلك الملفات الأصلية. يشمل ذلك نسخةً واحدةً خارج الموقع ونسختين محليتين.",
|
||||||
|
"backup_onboarding_description": "يُنصح باتباع <backblaze-link>استراتيجية النسخ الاحتياطي 3-2-1</backblaze-link> لحماية بياناتك. احتفظ بنسخ احتياطية من صورك/فيديوهاتك المحمّلة، بالإضافة إلى قاعدة بيانات Immich، لضمان حل نسخ احتياطي شامل.",
|
||||||
|
"backup_onboarding_footer": "لمزيد من المعلومات حول النسخ الاحتياطي لـ Immich، يرجى الرجوع إلى <link> التعليمات </link>.",
|
||||||
|
"backup_onboarding_parts_title": "يتضمن النسخ الاحتياطي 3-2-1 ما يلي:",
|
||||||
|
"backup_onboarding_title": "النسخ الاحتياطية",
|
||||||
"backup_settings": "إعدادات تفريغ قاعدة البيانات",
|
"backup_settings": "إعدادات تفريغ قاعدة البيانات",
|
||||||
"backup_settings_description": "إدارة إعدادات تفريغ قاعدة البيانات.",
|
"backup_settings_description": "إدارة إعدادات تفريغ قاعدة البيانات.",
|
||||||
"cleared_jobs": "تم إخلاء مهام: {job}",
|
"cleared_jobs": "تم إخلاء مهام: {job}",
|
||||||
@@ -210,6 +221,8 @@
|
|||||||
"oauth_mobile_redirect_uri": "عنوان URI لإعادة التوجيه على الهاتف",
|
"oauth_mobile_redirect_uri": "عنوان URI لإعادة التوجيه على الهاتف",
|
||||||
"oauth_mobile_redirect_uri_override": "تجاوز عنوان URI لإعادة التوجيه على الهاتف",
|
"oauth_mobile_redirect_uri_override": "تجاوز عنوان URI لإعادة التوجيه على الهاتف",
|
||||||
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما لا يسمح موفر OAuth بمعرف URI للجوال، مثل ''{callback}''",
|
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما لا يسمح موفر OAuth بمعرف URI للجوال، مثل ''{callback}''",
|
||||||
|
"oauth_role_claim": "المطالبة بالدور(صلاحيات)",
|
||||||
|
"oauth_role_claim_description": "منح وصول المسؤول تلقائيًا بناءً على وجود هذا الطلب. قد يكون الطلب إما 'مستخدم' أو 'مسؤول'.",
|
||||||
"oauth_settings": "OAuth",
|
"oauth_settings": "OAuth",
|
||||||
"oauth_settings_description": "إدارة إعدادات تسجيل الدخول OAuth",
|
"oauth_settings_description": "إدارة إعدادات تسجيل الدخول OAuth",
|
||||||
"oauth_settings_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <link>الوثائق</link>.",
|
"oauth_settings_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <link>الوثائق</link>.",
|
||||||
@@ -345,6 +358,9 @@
|
|||||||
"trash_number_of_days_description": "عدد أيام الاحتفاظ بالمحتويات في سلة المهملات قبل حذفها نهائيًا",
|
"trash_number_of_days_description": "عدد أيام الاحتفاظ بالمحتويات في سلة المهملات قبل حذفها نهائيًا",
|
||||||
"trash_settings": "إعدادات سلة المهملات",
|
"trash_settings": "إعدادات سلة المهملات",
|
||||||
"trash_settings_description": "إدارة إعدادات سلة المهملات",
|
"trash_settings_description": "إدارة إعدادات سلة المهملات",
|
||||||
|
"unlink_all_oauth_accounts": "ازالة ربط جميع حسابات OAuth",
|
||||||
|
"unlink_all_oauth_accounts_description": "تذكّر ان تزيل ربط جميع حسابات OAuth قبل ان تنقل الى مزود جديد.",
|
||||||
|
"unlink_all_oauth_accounts_prompt": "هل انت متأكد من ازالة ربط جميع حسابات OAuth؟ هذا سيقوم باعادة ضبط الID الخاص بالOAuth لكل مستخدم ولا يمكن التراجع عن العملية.",
|
||||||
"user_cleanup_job": "تنظيف المستخدم",
|
"user_cleanup_job": "تنظيف المستخدم",
|
||||||
"user_delete_delay": "سيتم جدولة حساب <b>{user}</b> ومحتوياته للحذف النهائي في غضون {delay, plural, one {# يوم} other {# أيام}}.",
|
"user_delete_delay": "سيتم جدولة حساب <b>{user}</b> ومحتوياته للحذف النهائي في غضون {delay, plural, one {# يوم} other {# أيام}}.",
|
||||||
"user_delete_delay_settings": "فترة التأخير قبل الحذف",
|
"user_delete_delay_settings": "فترة التأخير قبل الحذف",
|
||||||
@@ -371,13 +387,16 @@
|
|||||||
"admin_password": "كلمة سر المشرف",
|
"admin_password": "كلمة سر المشرف",
|
||||||
"administration": "الإدارة",
|
"administration": "الإدارة",
|
||||||
"advanced": "متقدم",
|
"advanced": "متقدم",
|
||||||
|
"advanced_settings_beta_timeline_subtitle": "جرب تجربة التطبيق الجديدة",
|
||||||
|
"advanced_settings_beta_timeline_title": "الجدول الزمني التجريبي",
|
||||||
"advanced_settings_enable_alternate_media_filter_subtitle": "استخدم هذا الخيار لتصفية الوسائط اثناء المزامنه بناء على معايير بديلة. جرب هذا الخيار فقط كان لديك مشاكل مع التطبيق بالكشف عن جميع الالبومات.",
|
"advanced_settings_enable_alternate_media_filter_subtitle": "استخدم هذا الخيار لتصفية الوسائط اثناء المزامنه بناء على معايير بديلة. جرب هذا الخيار فقط كان لديك مشاكل مع التطبيق بالكشف عن جميع الالبومات.",
|
||||||
"advanced_settings_enable_alternate_media_filter_title": "[تجريبي] استخدم جهاز تصفية مزامنه البومات بديل",
|
"advanced_settings_enable_alternate_media_filter_title": "[تجريبي] استخدم جهاز تصفية مزامنه البومات بديل",
|
||||||
"advanced_settings_log_level_title": "مستوى السجل: {level}",
|
"advanced_settings_log_level_title": "مستوى السجل: {level}",
|
||||||
"advanced_settings_prefer_remote_subtitle": "تكون بعض الأجهزة بطيئة للغاية في تحميل الصور المصغرة من الأصول الموجودة على الجهاز. قم بتنشيط هذا الإعداد لتحميل الصور البعيدة بدلاً من ذلك.",
|
"advanced_settings_prefer_remote_subtitle": "تكون بعض الأجهزة بطيئة للغاية في تحميل الصور المصغرة من الأصول المحلية. قم بتفعيل هذا الخيار لتحميل الصور البعيدة بدلاً من ذلك.",
|
||||||
"advanced_settings_prefer_remote_title": "تفضل الصور البعيدة",
|
"advanced_settings_prefer_remote_title": "تفضل الصور البعيدة",
|
||||||
"advanced_settings_proxy_headers_subtitle": "عرف عناوين الوكيل التي يستخدمها Immich لارسال كل طلب شبكي",
|
"advanced_settings_proxy_headers_subtitle": "عرف عناوين الوكيل التي يستخدمها Immich لارسال كل طلب شبكي",
|
||||||
"advanced_settings_proxy_headers_title": "عناوين الوكيل",
|
"advanced_settings_proxy_headers_title": "عناوين الوكيل",
|
||||||
|
"advanced_settings_readonly_mode_title": "وضع القراءة فقط",
|
||||||
"advanced_settings_self_signed_ssl_subtitle": "تخطي التحقق من شهادة SSL لخادم النقطة النهائي. مكلوب للشهادات الموقعة ذاتيا.",
|
"advanced_settings_self_signed_ssl_subtitle": "تخطي التحقق من شهادة SSL لخادم النقطة النهائي. مكلوب للشهادات الموقعة ذاتيا.",
|
||||||
"advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا",
|
"advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا",
|
||||||
"advanced_settings_sync_remote_deletions_subtitle": "حذف او استعادة تلقائي للاصول على هذا الجهاز عند تنفيذ العملية على الويب",
|
"advanced_settings_sync_remote_deletions_subtitle": "حذف او استعادة تلقائي للاصول على هذا الجهاز عند تنفيذ العملية على الويب",
|
||||||
@@ -507,7 +526,7 @@
|
|||||||
"back_close_deselect": "الرجوع أو الإغلاق أو إلغاء التحديد",
|
"back_close_deselect": "الرجوع أو الإغلاق أو إلغاء التحديد",
|
||||||
"background_location_permission": "اذن الوصول للموقع في الخلفية",
|
"background_location_permission": "اذن الوصول للموقع في الخلفية",
|
||||||
"background_location_permission_content": "للتمكن من تبديل الشبكه بالخلفية، Immich يحتاج*دائما* للحصول على موقع دقيق ليتمكن التطبيق من قرائة اسم شبكة الWi-Fi",
|
"background_location_permission_content": "للتمكن من تبديل الشبكه بالخلفية، Immich يحتاج*دائما* للحصول على موقع دقيق ليتمكن التطبيق من قرائة اسم شبكة الWi-Fi",
|
||||||
"backup": "دعم",
|
"backup": "نسخ احتياطي",
|
||||||
"backup_album_selection_page_albums_device": "الالبومات على الجهاز ({count})",
|
"backup_album_selection_page_albums_device": "الالبومات على الجهاز ({count})",
|
||||||
"backup_album_selection_page_albums_tap": "انقر للتضمين، وانقر نقرًا مزدوجًا للاستثناء",
|
"backup_album_selection_page_albums_tap": "انقر للتضمين، وانقر نقرًا مزدوجًا للاستثناء",
|
||||||
"backup_album_selection_page_assets_scatter": "يمكن أن تنتشر الأصول عبر ألبومات متعددة. وبالتالي، يمكن تضمين الألبومات أو استبعادها أثناء عملية النسخ الاحتياطي.",
|
"backup_album_selection_page_assets_scatter": "يمكن أن تنتشر الأصول عبر ألبومات متعددة. وبالتالي، يمكن تضمين الألبومات أو استبعادها أثناء عملية النسخ الاحتياطي.",
|
||||||
@@ -568,8 +587,10 @@
|
|||||||
"backup_manual_in_progress": "قيد التحميل حاول مره اخرى",
|
"backup_manual_in_progress": "قيد التحميل حاول مره اخرى",
|
||||||
"backup_manual_success": "نجاح",
|
"backup_manual_success": "نجاح",
|
||||||
"backup_manual_title": "حالة التحميل",
|
"backup_manual_title": "حالة التحميل",
|
||||||
|
"backup_options": "خيارات النسخ الاحتياطي",
|
||||||
"backup_options_page_title": "خيارات النسخ الاحتياطي",
|
"backup_options_page_title": "خيارات النسخ الاحتياطي",
|
||||||
"backup_setting_subtitle": "ادارة اعدادات التحميل في الخلفية والمقدمة",
|
"backup_setting_subtitle": "ادارة اعدادات التحميل في الخلفية والمقدمة",
|
||||||
|
"backup_settings_subtitle": "إدارة إعدادات التحميل",
|
||||||
"backward": "الى الوراء",
|
"backward": "الى الوراء",
|
||||||
"beta_sync": "حالة المزامنة التجريبية",
|
"beta_sync": "حالة المزامنة التجريبية",
|
||||||
"beta_sync_subtitle": "ادارة نظام المزامنة الجديد",
|
"beta_sync_subtitle": "ادارة نظام المزامنة الجديد",
|
||||||
@@ -639,6 +660,7 @@
|
|||||||
"clear": "إخلاء",
|
"clear": "إخلاء",
|
||||||
"clear_all": "إخلاء الكل",
|
"clear_all": "إخلاء الكل",
|
||||||
"clear_all_recent_searches": "مسح جميع عمليات البحث الأخيرة",
|
"clear_all_recent_searches": "مسح جميع عمليات البحث الأخيرة",
|
||||||
|
"clear_file_cache": "مسح ذاكرة التخزين المؤقت للملفات",
|
||||||
"clear_message": "إخلاء الرسالة",
|
"clear_message": "إخلاء الرسالة",
|
||||||
"clear_value": "إخلاء القيمة",
|
"clear_value": "إخلاء القيمة",
|
||||||
"client_cert_dialog_msg_confirm": "حسنا",
|
"client_cert_dialog_msg_confirm": "حسنا",
|
||||||
@@ -709,6 +731,7 @@
|
|||||||
"create_new_user": "إنشاء مستخدم جديد",
|
"create_new_user": "إنشاء مستخدم جديد",
|
||||||
"create_shared_album_page_share_add_assets": "إضافة الأصول",
|
"create_shared_album_page_share_add_assets": "إضافة الأصول",
|
||||||
"create_shared_album_page_share_select_photos": "حدد الصور",
|
"create_shared_album_page_share_select_photos": "حدد الصور",
|
||||||
|
"create_shared_link": "انشاء رابط مشترك",
|
||||||
"create_tag": "إنشاء علامة",
|
"create_tag": "إنشاء علامة",
|
||||||
"create_tag_description": "أنشئ علامة جديدة. بالنسبة للعلامات المتداخلة، يرجى إدخال المسار الكامل للعلامة بما في ذلك الخطوط المائلة للأمام.",
|
"create_tag_description": "أنشئ علامة جديدة. بالنسبة للعلامات المتداخلة، يرجى إدخال المسار الكامل للعلامة بما في ذلك الخطوط المائلة للأمام.",
|
||||||
"create_user": "إنشاء مستخدم",
|
"create_user": "إنشاء مستخدم",
|
||||||
@@ -721,6 +744,7 @@
|
|||||||
"current_server_address": "عنوان الخادم الحالي",
|
"current_server_address": "عنوان الخادم الحالي",
|
||||||
"custom_locale": "لغة مخصصة",
|
"custom_locale": "لغة مخصصة",
|
||||||
"custom_locale_description": "تنسيق التواريخ والأرقام بناءً على اللغة والمنطقة",
|
"custom_locale_description": "تنسيق التواريخ والأرقام بناءً على اللغة والمنطقة",
|
||||||
|
"custom_url": "رابط مخصص",
|
||||||
"daily_title_text_date": "E ، MMM DD",
|
"daily_title_text_date": "E ، MMM DD",
|
||||||
"daily_title_text_date_year": "E ، MMM DD ، yyyy",
|
"daily_title_text_date_year": "E ، MMM DD ، yyyy",
|
||||||
"dark": "معتم",
|
"dark": "معتم",
|
||||||
@@ -732,6 +756,7 @@
|
|||||||
"date_of_birth_saved": "تم حفظ تاريخ الميلاد بنجاح",
|
"date_of_birth_saved": "تم حفظ تاريخ الميلاد بنجاح",
|
||||||
"date_range": "نطاق الموعد",
|
"date_range": "نطاق الموعد",
|
||||||
"day": "يوم",
|
"day": "يوم",
|
||||||
|
"days": "ايام",
|
||||||
"deduplicate_all": "إلغاء تكرار الكل",
|
"deduplicate_all": "إلغاء تكرار الكل",
|
||||||
"deduplication_criteria_1": "حجم الصورة بوحدات البايت",
|
"deduplication_criteria_1": "حجم الصورة بوحدات البايت",
|
||||||
"deduplication_criteria_2": "عدد بيانات EXIF",
|
"deduplication_criteria_2": "عدد بيانات EXIF",
|
||||||
@@ -816,8 +841,12 @@
|
|||||||
"edit": "تعديل",
|
"edit": "تعديل",
|
||||||
"edit_album": "تعديل الألبوم",
|
"edit_album": "تعديل الألبوم",
|
||||||
"edit_avatar": "تعديل الصورة الشخصية",
|
"edit_avatar": "تعديل الصورة الشخصية",
|
||||||
|
"edit_birthday": "تعديل تاريخ الميلاد",
|
||||||
"edit_date": "تعديل التاريخ",
|
"edit_date": "تعديل التاريخ",
|
||||||
"edit_date_and_time": "تعديل التاريخ والوقت",
|
"edit_date_and_time": "تعديل التاريخ والوقت",
|
||||||
|
"edit_date_and_time_action_prompt": "تم تعديل التاريخ والوقت ل{count} ملف(ات)",
|
||||||
|
"edit_date_and_time_by_offset": "تعديل التاريخ حسب قيمة ازاحة معينة",
|
||||||
|
"edit_date_and_time_by_offset_interval": "نطاق التاريخ الجديد: {from} - {to}",
|
||||||
"edit_description": "تعديل الوصف",
|
"edit_description": "تعديل الوصف",
|
||||||
"edit_description_prompt": "الرجاء اختيار وصف جديد:",
|
"edit_description_prompt": "الرجاء اختيار وصف جديد:",
|
||||||
"edit_exclusion_pattern": "تعديل نمط الاستبعاد",
|
"edit_exclusion_pattern": "تعديل نمط الاستبعاد",
|
||||||
@@ -890,6 +919,7 @@
|
|||||||
"failed_to_load_notifications": "فشل تحميل الإشعارات",
|
"failed_to_load_notifications": "فشل تحميل الإشعارات",
|
||||||
"failed_to_load_people": "فشل تحميل الأشخاص",
|
"failed_to_load_people": "فشل تحميل الأشخاص",
|
||||||
"failed_to_remove_product_key": "تعذر إزالة مفتاح المنتج",
|
"failed_to_remove_product_key": "تعذر إزالة مفتاح المنتج",
|
||||||
|
"failed_to_reset_pin_code": "فشل اعادة تعيين رمز الPIN",
|
||||||
"failed_to_stack_assets": "فشل في تكديس المحتويات",
|
"failed_to_stack_assets": "فشل في تكديس المحتويات",
|
||||||
"failed_to_unstack_assets": "فشل في فصل المحتويات",
|
"failed_to_unstack_assets": "فشل في فصل المحتويات",
|
||||||
"failed_to_update_notification_status": "فشل في تحديث حالة الإشعار",
|
"failed_to_update_notification_status": "فشل في تحديث حالة الإشعار",
|
||||||
@@ -898,6 +928,7 @@
|
|||||||
"paths_validation_failed": "فشل في التحقق من {paths, plural, one {# مسار} other {# مسارات}}",
|
"paths_validation_failed": "فشل في التحقق من {paths, plural, one {# مسار} other {# مسارات}}",
|
||||||
"profile_picture_transparent_pixels": "لا يمكن أن تحتوي صور الملف الشخصي على أجزاء/بكسلات شفافة. يرجى التكبير و/أو تحريك الصورة.",
|
"profile_picture_transparent_pixels": "لا يمكن أن تحتوي صور الملف الشخصي على أجزاء/بكسلات شفافة. يرجى التكبير و/أو تحريك الصورة.",
|
||||||
"quota_higher_than_disk_size": "لقد قمت بتعيين حصة نسبية أعلى من حجم القرص",
|
"quota_higher_than_disk_size": "لقد قمت بتعيين حصة نسبية أعلى من حجم القرص",
|
||||||
|
"something_went_wrong": "حدث خطأ ما",
|
||||||
"unable_to_add_album_users": "تعذر إضافة مستخدمين إلى الألبوم",
|
"unable_to_add_album_users": "تعذر إضافة مستخدمين إلى الألبوم",
|
||||||
"unable_to_add_assets_to_shared_link": "تعذر إضافة المحتويات إلى الرابط المشترك",
|
"unable_to_add_assets_to_shared_link": "تعذر إضافة المحتويات إلى الرابط المشترك",
|
||||||
"unable_to_add_comment": "تعذر إضافة التعليق",
|
"unable_to_add_comment": "تعذر إضافة التعليق",
|
||||||
@@ -983,13 +1014,11 @@
|
|||||||
},
|
},
|
||||||
"exif": "Exif (صيغة ملف صوري قابل للتبادل)",
|
"exif": "Exif (صيغة ملف صوري قابل للتبادل)",
|
||||||
"exif_bottom_sheet_description": "اضف وصفا...",
|
"exif_bottom_sheet_description": "اضف وصفا...",
|
||||||
|
"exif_bottom_sheet_description_error": "خطأ في تحديث الوصف",
|
||||||
"exif_bottom_sheet_details": "تفاصيل",
|
"exif_bottom_sheet_details": "تفاصيل",
|
||||||
"exif_bottom_sheet_location": "موقع",
|
"exif_bottom_sheet_location": "موقع",
|
||||||
"exif_bottom_sheet_people": "الناس",
|
"exif_bottom_sheet_people": "الناس",
|
||||||
"exif_bottom_sheet_person_add_person": "اضف اسما",
|
"exif_bottom_sheet_person_add_person": "اضف اسما",
|
||||||
"exif_bottom_sheet_person_age_months": "العمر {months} اشهر",
|
|
||||||
"exif_bottom_sheet_person_age_year_months": "العمر ١ سنة،{months} اشهر",
|
|
||||||
"exif_bottom_sheet_person_age_years": "العمر {years}",
|
|
||||||
"exit_slideshow": "خروج من العرض التقديمي",
|
"exit_slideshow": "خروج من العرض التقديمي",
|
||||||
"expand_all": "توسيع الكل",
|
"expand_all": "توسيع الكل",
|
||||||
"experimental_settings_new_asset_list_subtitle": "أعمال جارية",
|
"experimental_settings_new_asset_list_subtitle": "أعمال جارية",
|
||||||
@@ -1031,11 +1060,13 @@
|
|||||||
"filter_people": "تصفية الاشخاص",
|
"filter_people": "تصفية الاشخاص",
|
||||||
"filter_places": "تصفية الاماكن",
|
"filter_places": "تصفية الاماكن",
|
||||||
"find_them_fast": "يمكنك العثور عليها بسرعة بالاسم من خلال البحث",
|
"find_them_fast": "يمكنك العثور عليها بسرعة بالاسم من خلال البحث",
|
||||||
|
"first": "الاول",
|
||||||
"fix_incorrect_match": "إصلاح المطابقة غير الصحيحة",
|
"fix_incorrect_match": "إصلاح المطابقة غير الصحيحة",
|
||||||
"folder": "مجلد",
|
"folder": "مجلد",
|
||||||
"folder_not_found": "لم يتم العثور على المجلد",
|
"folder_not_found": "لم يتم العثور على المجلد",
|
||||||
"folders": "المجلدات",
|
"folders": "المجلدات",
|
||||||
"folders_feature_description": "تصفح عرض المجلد للصور ومقاطع الفيديو الموجودة على نظام الملفات",
|
"folders_feature_description": "تصفح عرض المجلد للصور ومقاطع الفيديو الموجودة على نظام الملفات",
|
||||||
|
"forgot_pin_code_question": "هل نسيت رمز الPIN الخاص بك؟",
|
||||||
"forward": "إلى الأمام",
|
"forward": "إلى الأمام",
|
||||||
"gcast_enabled": "كوكل كاست",
|
"gcast_enabled": "كوكل كاست",
|
||||||
"gcast_enabled_description": "تقوم هذه الميزة بتحميل الموارد الخارجية من Google حتى تعمل.",
|
"gcast_enabled_description": "تقوم هذه الميزة بتحميل الموارد الخارجية من Google حتى تعمل.",
|
||||||
@@ -1056,6 +1087,9 @@
|
|||||||
"haptic_feedback_switch": "تمكين ردود الفعل اللمسية",
|
"haptic_feedback_switch": "تمكين ردود الفعل اللمسية",
|
||||||
"haptic_feedback_title": "ردود فعل لمسية",
|
"haptic_feedback_title": "ردود فعل لمسية",
|
||||||
"has_quota": "محدد بحصة",
|
"has_quota": "محدد بحصة",
|
||||||
|
"hash_asset": "عمل Hash للأصل (للملف)",
|
||||||
|
"hashed_assets": "أصول (ملفات) تم عمل Hash لها",
|
||||||
|
"hashing": "يتم عمل Hash",
|
||||||
"header_settings_add_header_tip": "اضاف راس",
|
"header_settings_add_header_tip": "اضاف راس",
|
||||||
"header_settings_field_validator_msg": "القيمة لا يمكن ان تكون فارغة",
|
"header_settings_field_validator_msg": "القيمة لا يمكن ان تكون فارغة",
|
||||||
"header_settings_header_name_input": "اسم الرأس",
|
"header_settings_header_name_input": "اسم الرأس",
|
||||||
@@ -1069,9 +1103,9 @@
|
|||||||
"hide_password": "اخفاء كلمة المرور",
|
"hide_password": "اخفاء كلمة المرور",
|
||||||
"hide_person": "اخفاء الشخص",
|
"hide_person": "اخفاء الشخص",
|
||||||
"hide_unnamed_people": "إخفاء الأشخاص بدون إسم",
|
"hide_unnamed_people": "إخفاء الأشخاص بدون إسم",
|
||||||
"home_page_add_to_album_conflicts": "تمت إضافة {تمت إضافة} الأصول إلى الألبوم {الألبوم}.{فشل} الأصول موجودة بالفعل في الألبوم.",
|
"home_page_add_to_album_conflicts": "تمت إضافة {added} أصول إلى الألبوم {album}. {failed} أصول موجودة بالفعل في الألبوم.",
|
||||||
"home_page_add_to_album_err_local": "لا يمكن إضافة الأصول المحلية إلى الألبومات حتى الآن ، سوف يتخطى",
|
"home_page_add_to_album_err_local": "لا يمكن إضافة الأصول المحلية إلى الألبومات حتى الآن ، سوف يتخطى",
|
||||||
"home_page_add_to_album_success": "تمت إضافة {تمت إضافة} الأصول إلى الألبوم {الألبوم}.",
|
"home_page_add_to_album_success": "تمت إضافة {added} أصول إلى الألبوم {album}.",
|
||||||
"home_page_album_err_partner": "لا يمكن إضافة أصول شريكة إلى ألبوم حتى الآن ، سوف يتخطى",
|
"home_page_album_err_partner": "لا يمكن إضافة أصول شريكة إلى ألبوم حتى الآن ، سوف يتخطى",
|
||||||
"home_page_archive_err_local": "لا يمكن أرشفة الأصول المحلية حتى الآن ، سوف يتخطى",
|
"home_page_archive_err_local": "لا يمكن أرشفة الأصول المحلية حتى الآن ، سوف يتخطى",
|
||||||
"home_page_archive_err_partner": "لا يمكن أرشفة الأصول الشريكة ، سوف يتخطى",
|
"home_page_archive_err_partner": "لا يمكن أرشفة الأصول الشريكة ، سوف يتخطى",
|
||||||
@@ -1087,7 +1121,9 @@
|
|||||||
"home_page_upload_err_limit": "لا يمكن إلا تحميل 30 أحد الأصول في وقت واحد ، سوف يتخطى",
|
"home_page_upload_err_limit": "لا يمكن إلا تحميل 30 أحد الأصول في وقت واحد ، سوف يتخطى",
|
||||||
"host": "المضيف",
|
"host": "المضيف",
|
||||||
"hour": "ساعة",
|
"hour": "ساعة",
|
||||||
|
"hours": "ساعات",
|
||||||
"id": "المعرف",
|
"id": "المعرف",
|
||||||
|
"idle": "خامل",
|
||||||
"ignore_icloud_photos": "تجاهل صور iCloud",
|
"ignore_icloud_photos": "تجاهل صور iCloud",
|
||||||
"ignore_icloud_photos_description": "الصور المخزنة في Cloud لن يتم تحميلها إلى خادم Immich",
|
"ignore_icloud_photos_description": "الصور المخزنة في Cloud لن يتم تحميلها إلى خادم Immich",
|
||||||
"image": "صورة",
|
"image": "صورة",
|
||||||
@@ -1145,10 +1181,13 @@
|
|||||||
"language_no_results_title": "لم يتم العثور على لغات",
|
"language_no_results_title": "لم يتم العثور على لغات",
|
||||||
"language_search_hint": "البحث عن لغات...",
|
"language_search_hint": "البحث عن لغات...",
|
||||||
"language_setting_description": "اختر لغتك المفضلة",
|
"language_setting_description": "اختر لغتك المفضلة",
|
||||||
|
"large_files": "ملفات كبيرة",
|
||||||
|
"last": "الاخير",
|
||||||
"last_seen": "اخر ظهور",
|
"last_seen": "اخر ظهور",
|
||||||
"latest_version": "احدث اصدار",
|
"latest_version": "احدث اصدار",
|
||||||
"latitude": "خط العرض",
|
"latitude": "خط العرض",
|
||||||
"leave": "مغادرة",
|
"leave": "مغادرة",
|
||||||
|
"leave_album": "اترك الالبوم",
|
||||||
"lens_model": "نموذج العدسات",
|
"lens_model": "نموذج العدسات",
|
||||||
"let_others_respond": "دع الآخرين يستجيبون",
|
"let_others_respond": "دع الآخرين يستجيبون",
|
||||||
"level": "المستوى",
|
"level": "المستوى",
|
||||||
@@ -1160,7 +1199,9 @@
|
|||||||
"library_page_sort_created": "تاريخ الإنشاء",
|
"library_page_sort_created": "تاريخ الإنشاء",
|
||||||
"library_page_sort_last_modified": "آخر تعديل",
|
"library_page_sort_last_modified": "آخر تعديل",
|
||||||
"library_page_sort_title": "عنوان الألبوم",
|
"library_page_sort_title": "عنوان الألبوم",
|
||||||
|
"licenses": "رُخَص",
|
||||||
"light": "المضيئ",
|
"light": "المضيئ",
|
||||||
|
"like": "اعجاب",
|
||||||
"like_deleted": "تم حذف الإعجاب",
|
"like_deleted": "تم حذف الإعجاب",
|
||||||
"link_motion_video": "رابط فيديو الحركة",
|
"link_motion_video": "رابط فيديو الحركة",
|
||||||
"link_to_oauth": "الربط مع OAuth",
|
"link_to_oauth": "الربط مع OAuth",
|
||||||
@@ -1168,7 +1209,9 @@
|
|||||||
"list": "قائمة",
|
"list": "قائمة",
|
||||||
"loading": "تحميل",
|
"loading": "تحميل",
|
||||||
"loading_search_results_failed": "فشل تحميل نتائج البحث",
|
"loading_search_results_failed": "فشل تحميل نتائج البحث",
|
||||||
|
"local": "محلّي",
|
||||||
"local_asset_cast_failed": "غير قادر على بث أصل لم يتم تحميله إلى الخادم",
|
"local_asset_cast_failed": "غير قادر على بث أصل لم يتم تحميله إلى الخادم",
|
||||||
|
"local_assets": "أُصول (ملفات) محلية",
|
||||||
"local_network": "شبكة محلية",
|
"local_network": "شبكة محلية",
|
||||||
"local_network_sheet_info": "سيتصل التطبيق بالخادم من خلال عنوان URL هذا عند استخدام شبكة Wi-Fi المحددة",
|
"local_network_sheet_info": "سيتصل التطبيق بالخادم من خلال عنوان URL هذا عند استخدام شبكة Wi-Fi المحددة",
|
||||||
"location_permission": "اذن الموقع",
|
"location_permission": "اذن الموقع",
|
||||||
@@ -1225,7 +1268,7 @@
|
|||||||
"manage_your_devices": "إدارة الأجهزة التي تم تسجيل الدخول إليها",
|
"manage_your_devices": "إدارة الأجهزة التي تم تسجيل الدخول إليها",
|
||||||
"manage_your_oauth_connection": "إدارة اتصال OAuth الخاص بك",
|
"manage_your_oauth_connection": "إدارة اتصال OAuth الخاص بك",
|
||||||
"map": "الخريطة",
|
"map": "الخريطة",
|
||||||
"map_assets_in_bounds": "{count} صور",
|
"map_assets_in_bounds": "{count, plural, =0 {لايوجد صور في هذه المنطقة} one {# صورة} other {# صور}}",
|
||||||
"map_cannot_get_user_location": "لا يمكن الحصول على موقع المستخدم",
|
"map_cannot_get_user_location": "لا يمكن الحصول على موقع المستخدم",
|
||||||
"map_location_dialog_yes": "نعم",
|
"map_location_dialog_yes": "نعم",
|
||||||
"map_location_picker_page_use_location": "استخدم هذا الموقع",
|
"map_location_picker_page_use_location": "استخدم هذا الموقع",
|
||||||
@@ -1233,7 +1276,6 @@
|
|||||||
"map_location_service_disabled_title": "خدمة الموقع معطل",
|
"map_location_service_disabled_title": "خدمة الموقع معطل",
|
||||||
"map_marker_for_images": "علامة الخريطة للصور الملتقطة في {city}، {country}",
|
"map_marker_for_images": "علامة الخريطة للصور الملتقطة في {city}، {country}",
|
||||||
"map_marker_with_image": "علامة الخريطة مع الصورة",
|
"map_marker_with_image": "علامة الخريطة مع الصورة",
|
||||||
"map_no_assets_in_bounds": "لا توجد صور في هذا المجال",
|
|
||||||
"map_no_location_permission_content": "هناك حاجة إلى إذن الموقع لعرض الأصول من موقعك الحالي.هل تريد السماح به الآن؟",
|
"map_no_location_permission_content": "هناك حاجة إلى إذن الموقع لعرض الأصول من موقعك الحالي.هل تريد السماح به الآن؟",
|
||||||
"map_no_location_permission_title": "تم رفض إذن الموقع",
|
"map_no_location_permission_title": "تم رفض إذن الموقع",
|
||||||
"map_settings": "إعدادات الخريطة",
|
"map_settings": "إعدادات الخريطة",
|
||||||
@@ -1270,6 +1312,7 @@
|
|||||||
"merged_people_count": "دمج {count, plural, one {شخص واحد} other {# أشخاص}}",
|
"merged_people_count": "دمج {count, plural, one {شخص واحد} other {# أشخاص}}",
|
||||||
"minimize": "تصغير",
|
"minimize": "تصغير",
|
||||||
"minute": "دقيقة",
|
"minute": "دقيقة",
|
||||||
|
"minutes": "دقائق",
|
||||||
"missing": "المفقودة",
|
"missing": "المفقودة",
|
||||||
"model": "نموذج",
|
"model": "نموذج",
|
||||||
"month": "شهر",
|
"month": "شهر",
|
||||||
@@ -1289,6 +1332,9 @@
|
|||||||
"my_albums": "ألبوماتي",
|
"my_albums": "ألبوماتي",
|
||||||
"name": "الاسم",
|
"name": "الاسم",
|
||||||
"name_or_nickname": "الاسم أو اللقب",
|
"name_or_nickname": "الاسم أو اللقب",
|
||||||
|
"network_requirement_photos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية للصور",
|
||||||
|
"network_requirement_videos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية لمقاطع الفيديو",
|
||||||
|
"network_requirements_updated": "تم تغيير متطلبات الشبكة، يتم إعادة تعيين قائمة انتظار النسخ الاحتياطي",
|
||||||
"networking_settings": "الشبكات",
|
"networking_settings": "الشبكات",
|
||||||
"networking_subtitle": "إدارة إعدادات نقطة الخادم النهائية",
|
"networking_subtitle": "إدارة إعدادات نقطة الخادم النهائية",
|
||||||
"never": "أبداً",
|
"never": "أبداً",
|
||||||
@@ -1324,6 +1370,7 @@
|
|||||||
"no_results": "لا يوجد نتائج",
|
"no_results": "لا يوجد نتائج",
|
||||||
"no_results_description": "جرب كلمة رئيسية مرادفة أو أكثر عمومية",
|
"no_results_description": "جرب كلمة رئيسية مرادفة أو أكثر عمومية",
|
||||||
"no_shared_albums_message": "قم بإنشاء ألبوم لمشاركة الصور ومقاطع الفيديو مع الأشخاص في شبكتك",
|
"no_shared_albums_message": "قم بإنشاء ألبوم لمشاركة الصور ومقاطع الفيديو مع الأشخاص في شبكتك",
|
||||||
|
"no_uploads_in_progress": "لا يوجد اي ملفات قيد الرفع",
|
||||||
"not_in_any_album": "ليست في أي ألبوم",
|
"not_in_any_album": "ليست في أي ألبوم",
|
||||||
"not_selected": "لم يختار",
|
"not_selected": "لم يختار",
|
||||||
"note_apply_storage_label_to_previously_uploaded assets": "ملاحظة: لتطبيق سمة التخزين على المحتويات التي تم رفعها مسبقًا، قم بتشغيل",
|
"note_apply_storage_label_to_previously_uploaded assets": "ملاحظة: لتطبيق سمة التخزين على المحتويات التي تم رفعها مسبقًا، قم بتشغيل",
|
||||||
@@ -1339,6 +1386,7 @@
|
|||||||
"oauth": "OAuth",
|
"oauth": "OAuth",
|
||||||
"official_immich_resources": "الموارد الرسمية لشركة Immich",
|
"official_immich_resources": "الموارد الرسمية لشركة Immich",
|
||||||
"offline": "غير متصل",
|
"offline": "غير متصل",
|
||||||
|
"offset": "ازاحة",
|
||||||
"ok": "نعم",
|
"ok": "نعم",
|
||||||
"oldest_first": "الأقدم أولا",
|
"oldest_first": "الأقدم أولا",
|
||||||
"on_this_device": "على هذا الجهاز",
|
"on_this_device": "على هذا الجهاز",
|
||||||
@@ -1361,6 +1409,7 @@
|
|||||||
"original": "أصلي",
|
"original": "أصلي",
|
||||||
"other": "أخرى",
|
"other": "أخرى",
|
||||||
"other_devices": "أجهزة أخرى",
|
"other_devices": "أجهزة أخرى",
|
||||||
|
"other_entities": "كيانات أخرى",
|
||||||
"other_variables": "متغيرات أخرى",
|
"other_variables": "متغيرات أخرى",
|
||||||
"owned": "مملوكة",
|
"owned": "مملوكة",
|
||||||
"owner": "المالك",
|
"owner": "المالك",
|
||||||
@@ -1415,7 +1464,10 @@
|
|||||||
"permission_onboarding_permission_limited": "إذن محدود. للسماح بالنسخ الاحتياطي للتطبيق وإدارة مجموعة المعرض بالكامل، امنح أذونات الصور والفيديو في الإعدادات.",
|
"permission_onboarding_permission_limited": "إذن محدود. للسماح بالنسخ الاحتياطي للتطبيق وإدارة مجموعة المعرض بالكامل، امنح أذونات الصور والفيديو في الإعدادات.",
|
||||||
"permission_onboarding_request": "يتطلب التطبيق إذنًا لعرض الصور ومقاطع الفيديو الخاصة بك.",
|
"permission_onboarding_request": "يتطلب التطبيق إذنًا لعرض الصور ومقاطع الفيديو الخاصة بك.",
|
||||||
"person": "شخص",
|
"person": "شخص",
|
||||||
"person_birthdate": "تاريخ الميلاد {التاريخ}",
|
"person_age_months": "{months, plural, one {# شهر} other {# اشهر}} من العمر",
|
||||||
|
"person_age_year_months": "1 عام, {months, plural, one {# شهر} other {# اشهر}} من العمر",
|
||||||
|
"person_age_years": "{years, plural, other {# اعوام}} من العمر",
|
||||||
|
"person_birthdate": "ولد في {date}",
|
||||||
"person_hidden": "{name}{hidden, select, true { (مخفي)} other {}}",
|
"person_hidden": "{name}{hidden, select, true { (مخفي)} other {}}",
|
||||||
"photo_shared_all_users": "يبدو أنك شاركت صورك مع جميع المستخدمين أو ليس لديك أي مستخدم للمشاركة معه.",
|
"photo_shared_all_users": "يبدو أنك شاركت صورك مع جميع المستخدمين أو ليس لديك أي مستخدم للمشاركة معه.",
|
||||||
"photos": "الصور",
|
"photos": "الصور",
|
||||||
@@ -1492,6 +1544,7 @@
|
|||||||
"purchase_server_description_2": "حالة الداعم",
|
"purchase_server_description_2": "حالة الداعم",
|
||||||
"purchase_server_title": "الخادم",
|
"purchase_server_title": "الخادم",
|
||||||
"purchase_settings_server_activated": "يتم إدارة مفتاح منتج الخادم من قبل مدير النظام",
|
"purchase_settings_server_activated": "يتم إدارة مفتاح منتج الخادم من قبل مدير النظام",
|
||||||
|
"queue_status": "يتم الاضافة الى قائمة انتظار النسخ الاحتياطي {count}/{total}",
|
||||||
"rating": "تقييم نجمي",
|
"rating": "تقييم نجمي",
|
||||||
"rating_clear": "مسح التقييم",
|
"rating_clear": "مسح التقييم",
|
||||||
"rating_count": "{count, plural, one {# نجمة} other {# نجوم}}",
|
"rating_count": "{count, plural, one {# نجمة} other {# نجوم}}",
|
||||||
@@ -1520,6 +1573,8 @@
|
|||||||
"refreshing_faces": "جاري تحديث الوجوه",
|
"refreshing_faces": "جاري تحديث الوجوه",
|
||||||
"refreshing_metadata": "جارٍ تحديث البيانات الوصفية",
|
"refreshing_metadata": "جارٍ تحديث البيانات الوصفية",
|
||||||
"regenerating_thumbnails": "جارٍ تجديد الصور المصغرة",
|
"regenerating_thumbnails": "جارٍ تجديد الصور المصغرة",
|
||||||
|
"remote": "بعيد",
|
||||||
|
"remote_assets": "الأُصول البعيدة",
|
||||||
"remove": "إزالة",
|
"remove": "إزالة",
|
||||||
"remove_assets_album_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من الألبوم ؟",
|
"remove_assets_album_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من الألبوم ؟",
|
||||||
"remove_assets_shared_link_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من رابط المشاركة هذا؟",
|
"remove_assets_shared_link_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من رابط المشاركة هذا؟",
|
||||||
@@ -1527,6 +1582,7 @@
|
|||||||
"remove_custom_date_range": "إزالة النطاق الزمني المخصص",
|
"remove_custom_date_range": "إزالة النطاق الزمني المخصص",
|
||||||
"remove_deleted_assets": "إزالة الملفات الغير متصلة",
|
"remove_deleted_assets": "إزالة الملفات الغير متصلة",
|
||||||
"remove_from_album": "إزالة من الألبوم",
|
"remove_from_album": "إزالة من الألبوم",
|
||||||
|
"remove_from_album_action_prompt": "تم ازالة {count} من الالبوم",
|
||||||
"remove_from_favorites": "إزالة من المفضلة",
|
"remove_from_favorites": "إزالة من المفضلة",
|
||||||
"remove_from_lock_folder_action_prompt": "{count} أويل من المجلد المقفل",
|
"remove_from_lock_folder_action_prompt": "{count} أويل من المجلد المقفل",
|
||||||
"remove_from_locked_folder": "ازالة من المجلد المقفل",
|
"remove_from_locked_folder": "ازالة من المجلد المقفل",
|
||||||
@@ -1556,19 +1612,28 @@
|
|||||||
"reset_password": "إعادة تعيين كلمة المرور",
|
"reset_password": "إعادة تعيين كلمة المرور",
|
||||||
"reset_people_visibility": "إعادة ضبط ظهور الأشخاص",
|
"reset_people_visibility": "إعادة ضبط ظهور الأشخاص",
|
||||||
"reset_pin_code": "اعادة تعيين رمز PIN",
|
"reset_pin_code": "اعادة تعيين رمز PIN",
|
||||||
|
"reset_pin_code_description": "اذا نسيت رمز الPIN الخاص بك، بامكانك التواصل مع مدير الخادم لديك لاعادة تعيينه",
|
||||||
|
"reset_pin_code_success": "تم اعادة تعيين رمز الPIN بنجاح",
|
||||||
|
"reset_pin_code_with_password": "يمكنك دائما اعادة تعيين رمز الPIN الخاص بك عن طريق كلمة المرور الخاصة بك",
|
||||||
|
"reset_sqlite": "إعادة تعيين قاعدة بيانات SQLite",
|
||||||
|
"reset_sqlite_confirmation": "هل أنت متأكد من رغبتك في إعادة ضبط قاعدة بيانات SQLite؟ ستحتاج إلى تسجيل الخروج ثم تسجيل الدخول مرة أخرى لإعادة مزامنة البيانات",
|
||||||
|
"reset_sqlite_success": "تم إعادة تعيين قاعدة بيانات SQLite بنجاح",
|
||||||
"reset_to_default": "إعادة التعيين إلى الافتراضي",
|
"reset_to_default": "إعادة التعيين إلى الافتراضي",
|
||||||
"resolve_duplicates": "معالجة النسخ المكررة",
|
"resolve_duplicates": "معالجة النسخ المكررة",
|
||||||
"resolved_all_duplicates": "تم حل جميع التكرارات",
|
"resolved_all_duplicates": "تم حل جميع التكرارات",
|
||||||
"restore": "الاستعاده من سلة المهملات",
|
"restore": "الاستعاده من سلة المهملات",
|
||||||
"restore_all": "استعادة الكل",
|
"restore_all": "استعادة الكل",
|
||||||
|
"restore_trash_action_prompt": "تم استعادة {count} من المهملات",
|
||||||
"restore_user": "استعادة المستخدم",
|
"restore_user": "استعادة المستخدم",
|
||||||
"restored_asset": "المحتويات المستعادة",
|
"restored_asset": "المحتويات المستعادة",
|
||||||
"resume": "استئناف",
|
"resume": "استئناف",
|
||||||
"retry_upload": "أعد محاولة الرفع",
|
"retry_upload": "أعد محاولة الرفع",
|
||||||
"review_duplicates": "مراجعة التكرارات",
|
"review_duplicates": "مراجعة التكرارات",
|
||||||
|
"review_large_files": "مراجعة الملفات الكبيرة",
|
||||||
"role": "الدور",
|
"role": "الدور",
|
||||||
"role_editor": "المحرر",
|
"role_editor": "المحرر",
|
||||||
"role_viewer": "العارض",
|
"role_viewer": "العارض",
|
||||||
|
"running": "قيد التشغيل",
|
||||||
"save": "حفظ",
|
"save": "حفظ",
|
||||||
"save_to_gallery": "حفظ الى المعرض",
|
"save_to_gallery": "حفظ الى المعرض",
|
||||||
"saved_api_key": "تم حفظ مفتاح الـ API",
|
"saved_api_key": "تم حفظ مفتاح الـ API",
|
||||||
@@ -1700,6 +1765,7 @@
|
|||||||
"settings_saved": "تم حفظ الإعدادات",
|
"settings_saved": "تم حفظ الإعدادات",
|
||||||
"setup_pin_code": "تحديد رمز PIN",
|
"setup_pin_code": "تحديد رمز PIN",
|
||||||
"share": "مشاركة",
|
"share": "مشاركة",
|
||||||
|
"share_action_prompt": "تم مشاركة {count} أصل (ملف)",
|
||||||
"share_add_photos": "إضافة الصور",
|
"share_add_photos": "إضافة الصور",
|
||||||
"share_assets_selected": "اختيار {count}",
|
"share_assets_selected": "اختيار {count}",
|
||||||
"share_dialog_preparing": "تحضير...",
|
"share_dialog_preparing": "تحضير...",
|
||||||
@@ -1721,6 +1787,7 @@
|
|||||||
"shared_link_clipboard_copied_massage": "نسخ إلى الحافظة",
|
"shared_link_clipboard_copied_massage": "نسخ إلى الحافظة",
|
||||||
"shared_link_clipboard_text": "رابط: {link}\nكلمة المرور: {password}",
|
"shared_link_clipboard_text": "رابط: {link}\nكلمة المرور: {password}",
|
||||||
"shared_link_create_error": "خطأ أثناء إنشاء رابط مشترك",
|
"shared_link_create_error": "خطأ أثناء إنشاء رابط مشترك",
|
||||||
|
"shared_link_custom_url_description": "الوصول إلى هذا الرابط المشترك باستخدام عنوان URL مخصص",
|
||||||
"shared_link_edit_description_hint": "أدخل وصف المشاركة",
|
"shared_link_edit_description_hint": "أدخل وصف المشاركة",
|
||||||
"shared_link_edit_expire_after_option_day": "يوم 1",
|
"shared_link_edit_expire_after_option_day": "يوم 1",
|
||||||
"shared_link_edit_expire_after_option_days": "{count} ايام",
|
"shared_link_edit_expire_after_option_days": "{count} ايام",
|
||||||
@@ -1746,6 +1813,7 @@
|
|||||||
"shared_link_info_chip_metadata": "EXIF",
|
"shared_link_info_chip_metadata": "EXIF",
|
||||||
"shared_link_manage_links": "إدارة الروابط المشتركة",
|
"shared_link_manage_links": "إدارة الروابط المشتركة",
|
||||||
"shared_link_options": "خيارات الرابط المشترك",
|
"shared_link_options": "خيارات الرابط المشترك",
|
||||||
|
"shared_link_password_description": "طلب كلمة مرور للوصول إلى هذا الرابط المشترك",
|
||||||
"shared_links": "روابط مشتركة",
|
"shared_links": "روابط مشتركة",
|
||||||
"shared_links_description": "وصف الروابط المشتركة",
|
"shared_links_description": "وصف الروابط المشتركة",
|
||||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# الصور ومقاطع الفيديو المُشارَكة.}}",
|
"shared_photos_and_videos_count": "{assetCount, plural, other {# الصور ومقاطع الفيديو المُشارَكة.}}",
|
||||||
@@ -1795,12 +1863,14 @@
|
|||||||
"sort_created": "تاريخ الإنشاء",
|
"sort_created": "تاريخ الإنشاء",
|
||||||
"sort_items": "عدد العناصر",
|
"sort_items": "عدد العناصر",
|
||||||
"sort_modified": "تم تعديل التاريخ",
|
"sort_modified": "تم تعديل التاريخ",
|
||||||
|
"sort_newest": "احدث صورة",
|
||||||
"sort_oldest": "أقدم صورة",
|
"sort_oldest": "أقدم صورة",
|
||||||
"sort_people_by_similarity": "رتب الأشخاص حسب التشابه",
|
"sort_people_by_similarity": "رتب الأشخاص حسب التشابه",
|
||||||
"sort_recent": "أحدث صورة",
|
"sort_recent": "أحدث صورة",
|
||||||
"sort_title": "العنوان",
|
"sort_title": "العنوان",
|
||||||
"source": "المصدر",
|
"source": "المصدر",
|
||||||
"stack": "تجميع",
|
"stack": "تجميع",
|
||||||
|
"stack_action_prompt": "{count} مكدسة",
|
||||||
"stack_duplicates": "تجميع النسخ المكررة",
|
"stack_duplicates": "تجميع النسخ المكررة",
|
||||||
"stack_select_one_photo": "حدد صورة رئيسية واحدة للمجموعة",
|
"stack_select_one_photo": "حدد صورة رئيسية واحدة للمجموعة",
|
||||||
"stack_selected_photos": "كدس الصور المحددة",
|
"stack_selected_photos": "كدس الصور المحددة",
|
||||||
@@ -1820,6 +1890,7 @@
|
|||||||
"storage_quota": "حصة الخزن",
|
"storage_quota": "حصة الخزن",
|
||||||
"storage_usage": "{used} من {available} مُستخْدم",
|
"storage_usage": "{used} من {available} مُستخْدم",
|
||||||
"submit": "إرسال",
|
"submit": "إرسال",
|
||||||
|
"success": "تم بنجاح",
|
||||||
"suggestions": "اقتراحات",
|
"suggestions": "اقتراحات",
|
||||||
"sunrise_on_the_beach": "شروق الشمس على الشاطئ",
|
"sunrise_on_the_beach": "شروق الشمس على الشاطئ",
|
||||||
"support": "الدعم",
|
"support": "الدعم",
|
||||||
@@ -1829,6 +1900,8 @@
|
|||||||
"sync": "مزامنة",
|
"sync": "مزامنة",
|
||||||
"sync_albums": "مزامنة الالبومات",
|
"sync_albums": "مزامنة الالبومات",
|
||||||
"sync_albums_manual_subtitle": "مزامنة جميع الفديوهات والصور المرفوعة الى البومات الخزن الاحتياطي المختارة",
|
"sync_albums_manual_subtitle": "مزامنة جميع الفديوهات والصور المرفوعة الى البومات الخزن الاحتياطي المختارة",
|
||||||
|
"sync_local": "مزامنة الملفات المحلية",
|
||||||
|
"sync_remote": "مزامنة الملفات البعيدة",
|
||||||
"sync_upload_album_setting_subtitle": "انشئ و ارفع صورك و فديوهاتك الالبومات المختارة في Immich",
|
"sync_upload_album_setting_subtitle": "انشئ و ارفع صورك و فديوهاتك الالبومات المختارة في Immich",
|
||||||
"tag": "العلامة",
|
"tag": "العلامة",
|
||||||
"tag_assets": "أصول العلامة",
|
"tag_assets": "أصول العلامة",
|
||||||
@@ -1839,6 +1912,7 @@
|
|||||||
"tag_updated": "تم تحديث العلامة: {tag}",
|
"tag_updated": "تم تحديث العلامة: {tag}",
|
||||||
"tagged_assets": "تم وضع علامة {count, plural, one {# asset} other {# assets}}",
|
"tagged_assets": "تم وضع علامة {count, plural, one {# asset} other {# assets}}",
|
||||||
"tags": "العلامات",
|
"tags": "العلامات",
|
||||||
|
"tap_to_run_job": "انقر لتشغيل المهمة",
|
||||||
"template": "النموذج",
|
"template": "النموذج",
|
||||||
"theme": "مظهر",
|
"theme": "مظهر",
|
||||||
"theme_selection": "اختيار السمة",
|
"theme_selection": "اختيار السمة",
|
||||||
@@ -1911,15 +1985,20 @@
|
|||||||
"unselect_all_duplicates": "إلغاء تحديد كافة النسخ المكررة",
|
"unselect_all_duplicates": "إلغاء تحديد كافة النسخ المكررة",
|
||||||
"unselect_all_in": "إلغاء تحديد الكل في {group}",
|
"unselect_all_in": "إلغاء تحديد الكل في {group}",
|
||||||
"unstack": "فك الكومه",
|
"unstack": "فك الكومه",
|
||||||
|
"unstack_action_prompt": "تم ازالة تكديس {count}",
|
||||||
"unstacked_assets_count": "تم إخراج {count, plural, one {# الأصل} other {# الأصول}} من التكديس",
|
"unstacked_assets_count": "تم إخراج {count, plural, one {# الأصل} other {# الأصول}} من التكديس",
|
||||||
|
"untagged": "غير مُعَلَّم",
|
||||||
"up_next": "التالي",
|
"up_next": "التالي",
|
||||||
"updated_at": "تم التحديث",
|
"updated_at": "تم التحديث",
|
||||||
"updated_password": "تم تحديث كلمة المرور",
|
"updated_password": "تم تحديث كلمة المرور",
|
||||||
"upload": "رفع",
|
"upload": "رفع",
|
||||||
|
"upload_action_prompt": "{count} ملف في قائمة الانتظار للرفع",
|
||||||
"upload_concurrency": "الرفع المتزامن",
|
"upload_concurrency": "الرفع المتزامن",
|
||||||
|
"upload_details": "تفاصيل الرفع",
|
||||||
"upload_dialog_info": "هل تريد النسخ الاحتياطي للأصول (الأصول) المحددة إلى الخادم؟",
|
"upload_dialog_info": "هل تريد النسخ الاحتياطي للأصول (الأصول) المحددة إلى الخادم؟",
|
||||||
"upload_dialog_title": "تحميل الأصول",
|
"upload_dialog_title": "تحميل الأصول",
|
||||||
"upload_errors": "إكتمل الرفع مع {count, plural, one {# خطأ} other {# أخطاء}}, قم بتحديث الصفحة لرؤية المحتويات الجديدة التي تم رفعها.",
|
"upload_errors": "إكتمل الرفع مع {count, plural, one {# خطأ} other {# أخطاء}}, قم بتحديث الصفحة لرؤية المحتويات الجديدة التي تم رفعها.",
|
||||||
|
"upload_finished": "تم الانتهاء من الرفع",
|
||||||
"upload_progress": "متبقية {remaining, number} - معالجة {processed, number}/{total, number}",
|
"upload_progress": "متبقية {remaining, number} - معالجة {processed, number}/{total, number}",
|
||||||
"upload_skipped_duplicates": "تم تخطي {count, plural, one {# محتوى مكرر} other {# محتويات مكررة }}",
|
"upload_skipped_duplicates": "تم تخطي {count, plural, one {# محتوى مكرر} other {# محتويات مكررة }}",
|
||||||
"upload_status_duplicates": "التكرارات",
|
"upload_status_duplicates": "التكرارات",
|
||||||
@@ -1928,6 +2007,7 @@
|
|||||||
"upload_success": "تم الرفع بنجاح، قم بتحديث الصفحة لرؤية المحتويات المرفوعة الجديدة.",
|
"upload_success": "تم الرفع بنجاح، قم بتحديث الصفحة لرؤية المحتويات المرفوعة الجديدة.",
|
||||||
"upload_to_immich": "الرفع الىImmich ({count})",
|
"upload_to_immich": "الرفع الىImmich ({count})",
|
||||||
"uploading": "جاري الرفع",
|
"uploading": "جاري الرفع",
|
||||||
|
"uploading_media": "رفع الوسائط",
|
||||||
"url": "عنوان URL",
|
"url": "عنوان URL",
|
||||||
"usage": "الاستخدام",
|
"usage": "الاستخدام",
|
||||||
"use_biometric": "استخدم البايومتري",
|
"use_biometric": "استخدم البايومتري",
|
||||||
@@ -1948,6 +2028,7 @@
|
|||||||
"user_usage_stats_description": "عرض إحصائيات استخدام الحساب",
|
"user_usage_stats_description": "عرض إحصائيات استخدام الحساب",
|
||||||
"username": "اسم المستخدم",
|
"username": "اسم المستخدم",
|
||||||
"users": "المستخدمين",
|
"users": "المستخدمين",
|
||||||
|
"users_added_to_album_count": "تم اضافة{count, plural, one {# مستخدم} other {# مستخدمين}} الى الالبوم",
|
||||||
"utilities": "أدوات",
|
"utilities": "أدوات",
|
||||||
"validate": "تحقْق",
|
"validate": "تحقْق",
|
||||||
"validate_endpoint_error": "الرجاء ادخال عنوان URL صالح",
|
"validate_endpoint_error": "الرجاء ادخال عنوان URL صالح",
|
||||||
@@ -1966,6 +2047,7 @@
|
|||||||
"view_album": "عرض الألبوم",
|
"view_album": "عرض الألبوم",
|
||||||
"view_all": "عرض الكل",
|
"view_all": "عرض الكل",
|
||||||
"view_all_users": "عرض كافة المستخدمين",
|
"view_all_users": "عرض كافة المستخدمين",
|
||||||
|
"view_details": "رؤية التفاصيل",
|
||||||
"view_in_timeline": "عرض في الجدول الزمني",
|
"view_in_timeline": "عرض في الجدول الزمني",
|
||||||
"view_link": "عرض الرابط",
|
"view_link": "عرض الرابط",
|
||||||
"view_links": "عرض الروابط",
|
"view_links": "عرض الروابط",
|
||||||
|
|||||||
29
i18n/az.json
@@ -1,37 +1,53 @@
|
|||||||
{
|
{
|
||||||
"about": "Haqqinda",
|
"about": "Haqqında",
|
||||||
"account": "Hesab",
|
"account": "Hesab",
|
||||||
"account_settings": "Hesab parametrləri",
|
"account_settings": "Hesab parametrləri",
|
||||||
"acknowledge": "Təsdiq et",
|
"acknowledge": "Təsdiq et",
|
||||||
"action": "Əməliyyat",
|
"action": "Əməliyyat",
|
||||||
|
"action_common_update": "Yenilə",
|
||||||
"actions": "Əməliyyatlar",
|
"actions": "Əməliyyatlar",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
"activity": "Fəaliyyət",
|
"activity": "Fəaliyyət",
|
||||||
|
"activity_changed": "Fəaliyyət {enabled, select, true {aktivdir} other {aktiv deyil}}",
|
||||||
"add": "Əlavə et",
|
"add": "Əlavə et",
|
||||||
"add_a_description": "Təsviri əlavə et",
|
"add_a_description": "Təsviri əlavə et",
|
||||||
"add_a_location": "Məkan əlavə et",
|
"add_a_location": "Məkan əlavə et",
|
||||||
"add_a_name": "Ad əlavə et",
|
"add_a_name": "Ad əlavə et",
|
||||||
"add_a_title": "Başlıq əlavə et",
|
"add_a_title": "Başlıq əlavə et",
|
||||||
|
"add_birthday": "Doğum günü əlavə et",
|
||||||
|
"add_endpoint": "Son nöqtə əlavə et",
|
||||||
"add_exclusion_pattern": "İstisna nümunəsi əlavə et",
|
"add_exclusion_pattern": "İstisna nümunəsi əlavə et",
|
||||||
"add_import_path": "Import yolunu əlavə et",
|
"add_import_path": "Import yolunu əlavə et",
|
||||||
"add_location": "Məkanı əlavə et",
|
"add_location": "Məkan əlavə et",
|
||||||
"add_more_users": "Daha çox istifadəçi əlavə et",
|
"add_more_users": "Daha çox istifadəçi əlavə et",
|
||||||
"add_partner": "Partnyor əlavə et",
|
"add_partner": "Partnyor əlavə et",
|
||||||
"add_path": "Yol əlavə et",
|
"add_path": "Yol əlavə et",
|
||||||
"add_photos": "Şəkilləri əlavə et",
|
"add_photos": "Şəkillər əlavə et",
|
||||||
"add_to": "... əlavə et",
|
"add_tag": "Etiket əlavə et",
|
||||||
|
"add_to": "Bura əlavə et…",
|
||||||
"add_to_album": "Albom əlavə et",
|
"add_to_album": "Albom əlavə et",
|
||||||
|
"add_to_album_bottom_sheet_added": "{album} albomuna əlavə edildi",
|
||||||
|
"add_to_album_bottom_sheet_already_exists": "Artıq {album} albomunda var",
|
||||||
|
"add_to_album_toggle": "{album} üçün seçimi dəyişin",
|
||||||
|
"add_to_albums": "Albomlara əlavə et",
|
||||||
|
"add_to_albums_count": "Albomlara əlavə et ({count})",
|
||||||
"add_to_shared_album": "Paylaşılan alboma əlavə et",
|
"add_to_shared_album": "Paylaşılan alboma əlavə et",
|
||||||
|
"add_url": "URL əlavə et",
|
||||||
"added_to_archive": "Arxivə əlavə edildi",
|
"added_to_archive": "Arxivə əlavə edildi",
|
||||||
"added_to_favorites": "Sevimlilələrə əlavə edildi",
|
"added_to_favorites": "Sevimlilələrə əlavə edildi",
|
||||||
"added_to_favorites_count": "{count, number} şəkil sevimlilələrə əlavə edildi",
|
"added_to_favorites_count": "{count, number} şəkil sevimlilələrə əlavə edildi",
|
||||||
"admin": {
|
"admin": {
|
||||||
|
"add_exclusion_pattern_description": "İstisna şablonlarını əlavə edin. *, ** və ? ilə Globbing dəstəklənir. Məs.: \"Raw\" adlanan hər hansısa bir qovluqda bütün faylları saymamaq üçün \"**/Raw/**\"-dan istifadə edin. \".tif\" ilə bitən bütün faylları saymamaq üçün \"**/*.tif\"-dən istifadə edin. Faylı mütləq yoldan istifadə etməklə saymamaq istəyirsinizsə \"/path/to/ignore/**\"-dan istifadə edin.",
|
||||||
|
"admin_user": "Admin İstifadəçi",
|
||||||
|
"asset_offline_description": "Bu xarici kitabxana varlığı diskdə artıq tapılmadı və zibil qutusuna köçürüldü. Əgər fayl kitabxana içərisində köçürülübsə, zaman şkalanızı yeni uyğun gələn varlıq üçün yoxlayın. Varlığı yenidən qaytarmaq üçün aşağıda verilmiş fayl yolunun Immich tərəfindən əlçatan olduğundan əmin olduqdan sonra kitabxananı skan edin.",
|
||||||
"authentication_settings": "Səlahiyyətləndirmə parametrləri",
|
"authentication_settings": "Səlahiyyətləndirmə parametrləri",
|
||||||
"authentication_settings_description": "Şifrə, OAuth və digər səlahiyyətləndirmə parametrləri",
|
"authentication_settings_description": "Şifrə, OAuth və digər səlahiyyətləndirmə parametrləri",
|
||||||
"authentication_settings_disable_all": "Bütün giriş etmə metodlarını söndürmək istədiyinizdən əminsinizmi? Giriş etmə funksiyası tamamilə söndürüləcəkdir.",
|
"authentication_settings_disable_all": "Bütün giriş etmə metodlarını söndürmək istədiyinizdən əminsinizmi? Giriş etmə funksiyası tamamilə söndürüləcəkdir.",
|
||||||
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link> -ni istifadə edin.",
|
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link> -ni istifadə edin.",
|
||||||
"background_task_job": "Arxa plan tapşırıqları",
|
"background_task_job": "Arxa plan tapşırıqları",
|
||||||
"backup_database_enable_description": "Verilənlər bazasının ehtiyat nüsxələrini aktiv et",
|
"backup_database": "Verilənlər bazasının dump-ını yaradın",
|
||||||
|
"backup_database_enable_description": "Verilənlər bazasının artıq nüsxələrini aktiv et",
|
||||||
|
"backup_keep_last_amount": "Tutulması gərəkən nüsxələrin sayı",
|
||||||
"backup_settings": "Ehtiyat Nüsxə Parametrləri",
|
"backup_settings": "Ehtiyat Nüsxə Parametrləri",
|
||||||
"backup_settings_description": "Verilənlər bazasının ehtiyat nüsxə parametrlərini idarə et",
|
"backup_settings_description": "Verilənlər bazasının ehtiyat nüsxə parametrlərini idarə et",
|
||||||
"config_set_by_file": "Konfiqurasiya hal-hazırda konfiqurasiya faylı ilə təyin olunub",
|
"config_set_by_file": "Konfiqurasiya hal-hazırda konfiqurasiya faylı ilə təyin olunub",
|
||||||
@@ -84,5 +100,6 @@
|
|||||||
"machine_learning_facial_recognition": "Üz Tanıma",
|
"machine_learning_facial_recognition": "Üz Tanıma",
|
||||||
"machine_learning_facial_recognition_description": "Şəkillərdəki üzləri aşkarla, tanı və qruplaşdır",
|
"machine_learning_facial_recognition_description": "Şəkillərdəki üzləri aşkarla, tanı və qruplaşdır",
|
||||||
"machine_learning_facial_recognition_model": "Üz tanıma modeli"
|
"machine_learning_facial_recognition_model": "Üz tanıma modeli"
|
||||||
}
|
},
|
||||||
|
"timeline": "Zaman şkalası"
|
||||||
}
|
}
|
||||||
|
|||||||
44
i18n/be.json
@@ -14,6 +14,7 @@
|
|||||||
"add_a_location": "Дадаць месца",
|
"add_a_location": "Дадаць месца",
|
||||||
"add_a_name": "Дадаць імя",
|
"add_a_name": "Дадаць імя",
|
||||||
"add_a_title": "Дадаць загаловак",
|
"add_a_title": "Дадаць загаловак",
|
||||||
|
"add_birthday": "Дадаць дзень нараджэння",
|
||||||
"add_endpoint": "Дадаць кропку доступу",
|
"add_endpoint": "Дадаць кропку доступу",
|
||||||
"add_exclusion_pattern": "Дадаць шаблон выключэння",
|
"add_exclusion_pattern": "Дадаць шаблон выключэння",
|
||||||
"add_import_path": "Дадаць шлях імпарту",
|
"add_import_path": "Дадаць шлях імпарту",
|
||||||
@@ -44,6 +45,10 @@
|
|||||||
"backup_database": "Стварыць рэзервовую копію базы даных",
|
"backup_database": "Стварыць рэзервовую копію базы даных",
|
||||||
"backup_database_enable_description": "Уключыць рэзерваванне базы даных",
|
"backup_database_enable_description": "Уключыць рэзерваванне базы даных",
|
||||||
"backup_keep_last_amount": "Колькасць папярэдніх рэзервовых копій для захавання",
|
"backup_keep_last_amount": "Колькасць папярэдніх рэзервовых копій для захавання",
|
||||||
|
"backup_onboarding_1_description": "зняшняя копія ў воблаку або ў іншым фізічным месцы.",
|
||||||
|
"backup_onboarding_2_description": "лакальныя копіі на іншых прыладах. Гэта ўключае ў сябе асноўныя файлы і лакальную рэзервовую копію гэтых файлаў.",
|
||||||
|
"backup_onboarding_parts_title": "Рэзервовая копія «3-2-1» уключае ў сябе:",
|
||||||
|
"backup_onboarding_title": "Рэзервовыя копіі",
|
||||||
"backup_settings": "Налады рэзервовага капіявання",
|
"backup_settings": "Налады рэзервовага капіявання",
|
||||||
"backup_settings_description": "Кіраванне наладамі рэзервавання базы даных.",
|
"backup_settings_description": "Кіраванне наладамі рэзервавання базы даных.",
|
||||||
"cleared_jobs": "Ачышчаны заданні для: {job}",
|
"cleared_jobs": "Ачышчаны заданні для: {job}",
|
||||||
@@ -56,14 +61,14 @@
|
|||||||
"confirm_user_pin_code_reset": "Вы ўпэўнены ў тым, што жадаеце скінуць PIN-код {user}?",
|
"confirm_user_pin_code_reset": "Вы ўпэўнены ў тым, што жадаеце скінуць PIN-код {user}?",
|
||||||
"create_job": "Стварыць заданне",
|
"create_job": "Стварыць заданне",
|
||||||
"cron_expression": "Выраз Cron",
|
"cron_expression": "Выраз Cron",
|
||||||
"cron_expression_description": "Усталюйце інтэрвал сканавання, выкарыстоўваючы фармат cron. Для атрымання дадатковай інфармацыі, калі ласка, звярніцеся, напрыклад, да <link>Crontab Guru</link>",
|
"cron_expression_description": "Задайце інтэрвал сканавання, выкарыстоўваючы фармат cron. Для атрымання дадатковай інфармацыі, звярніцеся, напрыклад, да <link>Crontab Guru</link>",
|
||||||
"cron_expression_presets": "Прадустаноўкі выразаў Cron",
|
"cron_expression_presets": "Прадустаноўкі выразаў Cron",
|
||||||
"disable_login": "Адключыць уваход",
|
"disable_login": "Адключыць уваход",
|
||||||
"duplicate_detection_job_description": "Запусціць машыннае навучанне на актывах для выяўлення падобных выяў. Залежыць ад Smart Search",
|
"duplicate_detection_job_description": "Запусціць машыннае навучанне на актывах для выяўлення падобных выяў. Залежыць ад Smart Search",
|
||||||
"exclusion_pattern_description": "Шаблоны выключэння дазваляюць ігнараваць файлы і папкі пры сканаванні вашай бібліятэкі. Гэта карысна, калі ў вас ёсць папкі, якія змяшчаюць файлы, якія вы не хочаце імпартаваць, напрыклад, файлы RAW.",
|
"exclusion_pattern_description": "Шаблоны выключэння дазваляюць ігнараваць файлы і папкі пры сканаванні вашай бібліятэкі. Гэта карысна, калі ў вас ёсць папкі, якія змяшчаюць файлы, якія вы не хочаце імпартаваць, напрыклад, файлы RAW.",
|
||||||
"external_library_management": "Кіраванне знешняй бібліятэкай",
|
"external_library_management": "Кіраванне знешняй бібліятэкай",
|
||||||
"face_detection": "Выяўленне твараў",
|
"face_detection": "Выяўленне твараў",
|
||||||
"face_detection_description": "Выяўляць твары на фотаздымках і відэа з дапамогай машыннага навучання. Для відэа ўлічваецца толькі мініяцюра. \"Абнавіць\" (пера)апрацоўвае ўсе медыя. \"Скінуць\" дадаткова ачышчае ўсе бягучыя дадзеныя пра твары. \"Адсутнічае\" ставіць у чаргу медыя, якія яшчэ не былі апрацаваныя. Выяўленыя твары будуць пастаўлены ў чаргу для распазнавання асоб пасля завяршэння выяўлення твараў, з групаваннем іх па існуючых або новых людзях.",
|
"face_detection_description": "Выяўляць твары на фотаздымках і відэа з дапамогай машыннага навучання. Для відэа ўлічваецца толькі мініяцюра. \"Абнавіць\" (пера)апрацоўвае ўсе медыя. \"Скінуць\" дадаткова ачышчае ўсе бягучыя даныя пра твары. \"Адсутнічае\" ставіць у чаргу медыя, якія яшчэ не былі апрацаваныя. Выяўленыя твары будуць пастаўлены ў чаргу для распазнавання асоб пасля завяршэння выяўлення твараў, з групаваннем іх па існуючых або новых людзях.",
|
||||||
"facial_recognition_job_description": "Групаваць выяўленыя твары па асобах. Гэты этап выконваецца пасля завяршэння выяўлення твараў. \"Скінуць\" (паўторна) перагрупоўвае ўсе твары. \"Адсутнічае\" ставіць у чаргу твары, якія яшчэ не прыпісаныя да якой-небудзь асобы.",
|
"facial_recognition_job_description": "Групаваць выяўленыя твары па асобах. Гэты этап выконваецца пасля завяршэння выяўлення твараў. \"Скінуць\" (паўторна) перагрупоўвае ўсе твары. \"Адсутнічае\" ставіць у чаргу твары, якія яшчэ не прыпісаныя да якой-небудзь асобы.",
|
||||||
"failed_job_command": "Каманда {command} не выканалася для задання: {job}",
|
"failed_job_command": "Каманда {command} не выканалася для задання: {job}",
|
||||||
"force_delete_user_warning": "ПАПЯРЭДЖАННЕ: Гэта дзеянне неадкладна выдаліць карыстальніка і ўсе аб'екты. Гэта дзеянне не можа быць адроблена і файлы немагчыма будзе аднавіць.",
|
"force_delete_user_warning": "ПАПЯРЭДЖАННЕ: Гэта дзеянне неадкладна выдаліць карыстальніка і ўсе аб'екты. Гэта дзеянне не можа быць адроблена і файлы немагчыма будзе аднавіць.",
|
||||||
@@ -75,17 +80,39 @@
|
|||||||
"image_fullsize_quality_description": "Якасць выявы ў поўным памеры ад 1 да 100. Больш высокае значэнне лепшае, але прыводзіць да павелічэння памеру файла.",
|
"image_fullsize_quality_description": "Якасць выявы ў поўным памеры ад 1 да 100. Больш высокае значэнне лепшае, але прыводзіць да павелічэння памеру файла.",
|
||||||
"image_fullsize_title": "Налады выявы ў поўным памеры",
|
"image_fullsize_title": "Налады выявы ў поўным памеры",
|
||||||
"image_prefer_embedded_preview": "Аддаваць перавагу ўбудаванай праяве",
|
"image_prefer_embedded_preview": "Аддаваць перавагу ўбудаванай праяве",
|
||||||
"image_prefer_embedded_preview_setting_description": "Выкарыстоўваць убудаваныя праявы ў RAW-фотаздымках ў якасці ўваходных дадзеных для апрацоўкі малюнкаў, калі магчыма. Гэта дазваляе атрымаць больш дакладныя колеры для некаторых відарысаў, але ж якасць праяў залежыць ад камеры, і на відарысе можа быць больш артэфактаў сціску.",
|
"image_prefer_embedded_preview_setting_description": "Выкарыстоўваць убудаваныя праявы ў RAW-фотаздымках ў якасці ўваходных даных для апрацоўкі малюнкаў, калі магчыма. Гэта дазваляе атрымаць больш дакладныя колеры для некаторых відарысаў, але ж якасць праяў залежыць ад камеры, і на відарысе можа быць больш артэфактаў сціску.",
|
||||||
"image_prefer_wide_gamut": "Аддаць перавагу шырокай гаме",
|
"image_prefer_wide_gamut": "Аддаць перавагу шырокай гаме",
|
||||||
"image_preview_description": "Відарыс сярэдняга памеру з выдаленымі метададзенымі, выкарыстоўваецца пры праглядзе асобнага рэсурсу і для машыннага навучання",
|
"image_preview_description": "Відарыс сярэдняга памеру з выдаленымі метаданымі, выкарыстоўваецца пры праглядзе асобнага рэсурсу і для машыннага навучання",
|
||||||
"image_preview_quality_description": "Якасць праявы ад 1 да 100. Чым вышэй, тым лепш, але пры гэтым ствараюцца файлы большага памеру і можа знізіцца хуткасць водгуку прыкладання. Ўстаноўка нізкага значэння можа паўплываць на якасць машыннага навучання.",
|
"image_preview_quality_description": "Якасць праявы ад 1 да 100. Чым вышэй, тым лепш, але пры гэтым ствараюцца файлы большага памеру і можа знізіцца хуткасць водгуку прыкладання. Ўстаноўка нізкага значэння можа паўплываць на якасць машыннага навучання.",
|
||||||
"image_preview_title": "Налады папярэдняга прагляду",
|
"image_preview_title": "Налады папярэдняга прагляду",
|
||||||
"image_quality": "Якасць",
|
"image_quality": "Якасць",
|
||||||
"image_resolution": "Раздзяляльнасць",
|
"image_resolution": "Раздзяляльнасць",
|
||||||
"image_settings": "Налады відарыса",
|
"image_settings": "Налады відарыса",
|
||||||
"image_settings_description": "Кіруйце якасцю і раздзяляльнасцю сгенерыраваных відарысаў",
|
"image_settings_description": "Кіруйце якасцю і раздзяляльнасцю сгенерыраваных відарысаў",
|
||||||
|
"image_thumbnail_title": "Налады мініяцюр",
|
||||||
|
"job_concurrency": "{job} канкурэнтнасць",
|
||||||
|
"job_created": "Заданне створана",
|
||||||
|
"job_not_concurrency_safe": "Гэта заданне небяспечнае для канкурэнтнага(адначасовага, паралельнага) выканання.",
|
||||||
|
"job_settings": "Налады заданняў",
|
||||||
|
"job_settings_description": "Кіраваць наладамі адначасовага (паралельнага) выканання задання",
|
||||||
|
"job_status": "Становішча задання",
|
||||||
"library_created": "Створана бібліятэка: {library}",
|
"library_created": "Створана бібліятэка: {library}",
|
||||||
"library_deleted": "Бібліятэка выдалена",
|
"library_deleted": "Бібліятэка выдалена",
|
||||||
|
"library_scanning": "Сканаванне па раскладзе",
|
||||||
|
"library_scanning_description": "Наладзьце параметры сканавання вашай бібліятэкі",
|
||||||
|
"library_scanning_enable_description": "Уключыць сканаванне бібліятэкі па раскладзе",
|
||||||
|
"library_settings": "Знешняя бібліятэка",
|
||||||
|
"library_settings_description": "Наладзьце параметры знешняй бібліятэкі",
|
||||||
|
"library_tasks_description": "Сканаваць знешнія бібліятэкі на наяўнасць новых і/або змененых рэсурсаў",
|
||||||
|
"library_watching_enable_description": "Назіраць за зменамі файлаў у знешніх бібліятэках",
|
||||||
|
"library_watching_settings": "Сачыць за бібліятэкай (эксперыментальны)",
|
||||||
|
"library_watching_settings_description": "Аўтаматычна сачыць за зменамі ў файлах",
|
||||||
|
"logging_enable_description": "Уключыць вядзенне журнала",
|
||||||
|
"logging_level_description": "Калі уключана, які ўзровень журналявання выкарыстоўваць.",
|
||||||
|
"logging_settings": "Вядзенне журнала",
|
||||||
|
"machine_learning_clip_model": "CLIP мадэль",
|
||||||
|
"machine_learning_clip_model_description": "Назва CLIP мадэлі паказана <link>тут</link>. Звярніце ўвагу, што пры змене мадэлі неабходна паўторна запусціць заданне \"Smart Search\" для ўсіх відарысаў.",
|
||||||
|
"machine_learning_duplicate_detection": "Выяўленне падобных",
|
||||||
"map_dark_style": "Цёмны стыль",
|
"map_dark_style": "Цёмны стыль",
|
||||||
"map_enable_description": "Уключыць функцыі карты",
|
"map_enable_description": "Уключыць функцыі карты",
|
||||||
"map_gps_settings": "Налады карты і GPS",
|
"map_gps_settings": "Налады карты і GPS",
|
||||||
@@ -133,7 +160,7 @@
|
|||||||
"user_settings_description": "Кіраванне наладамі карыстальніка",
|
"user_settings_description": "Кіраванне наладамі карыстальніка",
|
||||||
"user_successfully_removed": "Карыстальнік {email} быў паспяхова выдалены.",
|
"user_successfully_removed": "Карыстальнік {email} быў паспяхова выдалены.",
|
||||||
"version_check_enabled_description": "Уключыць праверку версіі",
|
"version_check_enabled_description": "Уключыць праверку версіі",
|
||||||
"version_check_implications": "Функцыі праверкі версіі перыядычна звяртаецца да github.com",
|
"version_check_implications": "Функцыя праверкі версіі перыядычна звяртаецца да github.com",
|
||||||
"version_check_settings": "Праверка версіі",
|
"version_check_settings": "Праверка версіі",
|
||||||
"version_check_settings_description": "Уключыць/адключыць апавяшчэнні аб новай версіі"
|
"version_check_settings_description": "Уключыць/адключыць апавяшчэнні аб новай версіі"
|
||||||
},
|
},
|
||||||
@@ -206,7 +233,10 @@
|
|||||||
"asset_skipped_in_trash": "У сметніцы",
|
"asset_skipped_in_trash": "У сметніцы",
|
||||||
"asset_uploaded": "Запампавана",
|
"asset_uploaded": "Запампавана",
|
||||||
"asset_uploading": "Запампоўванне…",
|
"asset_uploading": "Запампоўванне…",
|
||||||
|
"assets_were_part_of_albums_count": "{count, plural, one {Актыў ужо быў} other {Актывы ужо былі}} часткай альбому",
|
||||||
"authorized_devices": "Аўтарызаваныя прылады",
|
"authorized_devices": "Аўтарызаваныя прылады",
|
||||||
|
"automatic_endpoint_switching_subtitle": "Падключацца лакальна па вылучаным Wi-Fi, калі гэта магчыма, і выкарыстоўваць альтэрнатыўныя падключэння ў іншых месцах",
|
||||||
|
"automatic_endpoint_switching_title": "Аўтаматычнае пераключэнне URL",
|
||||||
"back": "Назад",
|
"back": "Назад",
|
||||||
"backup_album_selection_page_albums_device": "Альбомы на прыладзе ({count})",
|
"backup_album_selection_page_albums_device": "Альбомы на прыладзе ({count})",
|
||||||
"backup_all": "Усе",
|
"backup_all": "Усе",
|
||||||
@@ -369,6 +399,8 @@
|
|||||||
"purchase_button_buy": "Купіць",
|
"purchase_button_buy": "Купіць",
|
||||||
"purchase_button_buy_immich": "Купіць Immich",
|
"purchase_button_buy_immich": "Купіць Immich",
|
||||||
"purchase_button_select": "Выбраць",
|
"purchase_button_select": "Выбраць",
|
||||||
|
"readonly_mode_enabled": "Уключаны рэжым толькі для чытання",
|
||||||
|
"reassign": "Перапрызначыць",
|
||||||
"remove": "Выдаліць",
|
"remove": "Выдаліць",
|
||||||
"remove_from_album": "Выдаліць з альбома",
|
"remove_from_album": "Выдаліць з альбома",
|
||||||
"remove_from_favorites": "Выдаліць з абраных",
|
"remove_from_favorites": "Выдаліць з абраных",
|
||||||
@@ -457,7 +489,7 @@
|
|||||||
"view_all_users": "Праглядзець усех карыстальнікаў",
|
"view_all_users": "Праглядзець усех карыстальнікаў",
|
||||||
"view_in_timeline": "Паглядзець хроніку",
|
"view_in_timeline": "Паглядзець хроніку",
|
||||||
"view_links": "Праглядзець спасылкі",
|
"view_links": "Праглядзець спасылкі",
|
||||||
"view_name": "Прагледзець",
|
"view_name": "Прагляд",
|
||||||
"view_next_asset": "Паказаць наступны аб'ект",
|
"view_next_asset": "Паказаць наступны аб'ект",
|
||||||
"view_previous_asset": "Праглядзець папярэдні аб'ект",
|
"view_previous_asset": "Праглядзець папярэдні аб'ект",
|
||||||
"view_stack": "Прагляд стэка",
|
"view_stack": "Прагляд стэка",
|
||||||
|
|||||||
133
i18n/bg.json
@@ -13,20 +13,24 @@
|
|||||||
"add_a_description": "Добави описание",
|
"add_a_description": "Добави описание",
|
||||||
"add_a_location": "Добави местоположение",
|
"add_a_location": "Добави местоположение",
|
||||||
"add_a_name": "Добави име",
|
"add_a_name": "Добави име",
|
||||||
"add_a_title": "Добавете заглавие",
|
"add_a_title": "Добaви заглавие",
|
||||||
|
"add_birthday": "Добави дата на раждане",
|
||||||
"add_endpoint": "Добави крайна точка",
|
"add_endpoint": "Добави крайна точка",
|
||||||
"add_exclusion_pattern": "Добави модел за изключване",
|
"add_exclusion_pattern": "Добави модел за изключване",
|
||||||
"add_import_path": "Добави път за импортиране",
|
"add_import_path": "Добави път за импортиране",
|
||||||
"add_location": "Добавете местоположение",
|
"add_location": "Дoбави местоположение",
|
||||||
"add_more_users": "Добавете още потребители",
|
"add_more_users": "Добави още потребители",
|
||||||
"add_partner": "Добавете партньор",
|
"add_partner": "Добави партньор",
|
||||||
"add_path": "Добави път",
|
"add_path": "Добави път",
|
||||||
"add_photos": "Добавете снимки",
|
"add_photos": "Добави снимки",
|
||||||
"add_tag": "Добави маркер",
|
"add_tag": "Добави маркер",
|
||||||
"add_to": "Добави към…",
|
"add_to": "Добави към…",
|
||||||
"add_to_album": "Добави към албум",
|
"add_to_album": "Добави към албум",
|
||||||
"add_to_album_bottom_sheet_added": "Добавено в {album}",
|
"add_to_album_bottom_sheet_added": "Добавено в {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Вече е в {album}",
|
"add_to_album_bottom_sheet_already_exists": "Вече е в {album}",
|
||||||
|
"add_to_album_toggle": "Сменете избора за {album}",
|
||||||
|
"add_to_albums": "Добавяне в албуми",
|
||||||
|
"add_to_albums_count": "Добавяне в албуми ({count})",
|
||||||
"add_to_shared_album": "Добави към споделен албум",
|
"add_to_shared_album": "Добави към споделен албум",
|
||||||
"add_url": "Добави URL",
|
"add_url": "Добави URL",
|
||||||
"added_to_archive": "Добавено към архива",
|
"added_to_archive": "Добавено към архива",
|
||||||
@@ -44,6 +48,13 @@
|
|||||||
"backup_database": "Създай резервна база данни",
|
"backup_database": "Създай резервна база данни",
|
||||||
"backup_database_enable_description": "Разреши резервни копия на базата данни",
|
"backup_database_enable_description": "Разреши резервни копия на базата данни",
|
||||||
"backup_keep_last_amount": "Брой запазени резервни копия",
|
"backup_keep_last_amount": "Брой запазени резервни копия",
|
||||||
|
"backup_onboarding_1_description": "копие на облака или друго физическо място.",
|
||||||
|
"backup_onboarding_2_description": "локални копия на различни устройства. Това включва основните файлове и локални архиви на тези файлове.",
|
||||||
|
"backup_onboarding_3_description": "общо копия на вашите данни, включитено оригиналните файлове. Това включва 1 копие извън системата и 2 локални копия.",
|
||||||
|
"backup_onboarding_description": "За надеждна защита препоръчваме стратегията <backblaze-link>3-2-1</backblaze-link>. Правете архивни копия както на качените снимки/видеа, така и на базата данни на Immich.",
|
||||||
|
"backup_onboarding_footer": "За подробна информация относно архивирането в Immich, моля вижте в <link>документацията</link>.",
|
||||||
|
"backup_onboarding_parts_title": "Стратегията 3-2-1 включва:",
|
||||||
|
"backup_onboarding_title": "Резервни копия",
|
||||||
"backup_settings": "Настройка на резервни копия на базата данни",
|
"backup_settings": "Настройка на резервни копия на базата данни",
|
||||||
"backup_settings_description": "Управление на настройките за резервно копие на базата данни.",
|
"backup_settings_description": "Управление на настройките за резервно копие на базата данни.",
|
||||||
"cleared_jobs": "Изчистени задачи от тип: {job}",
|
"cleared_jobs": "Изчистени задачи от тип: {job}",
|
||||||
@@ -347,6 +358,9 @@
|
|||||||
"trash_number_of_days_description": "Брой дни, в които файловете да се съхраняват на боклука, преди да бъдат окончателно премахнати",
|
"trash_number_of_days_description": "Брой дни, в които файловете да се съхраняват на боклука, преди да бъдат окончателно премахнати",
|
||||||
"trash_settings": "Настройки на кошчето",
|
"trash_settings": "Настройки на кошчето",
|
||||||
"trash_settings_description": "Управление на настройките на кошчето",
|
"trash_settings_description": "Управление на настройките на кошчето",
|
||||||
|
"unlink_all_oauth_accounts": "Прекрати вписването на всички OAuth профили",
|
||||||
|
"unlink_all_oauth_accounts_description": "Не забравяйте да прекратите вписването на всички OAuth профили преди да мигрирате към нов доставчик.",
|
||||||
|
"unlink_all_oauth_accounts_prompt": "Сигурни ли сте, че искате да отпишете всички OAuth профили? Това ще нулира OAuth ID за всеки потребител и не може да бъде отменено.",
|
||||||
"user_cleanup_job": "Почистване на потребители",
|
"user_cleanup_job": "Почистване на потребители",
|
||||||
"user_delete_delay": "<b>{user}</b> aкаунтът и файловете на потребителя ще бъдат планирани за постоянно изтриване след {delay, plural, one {# ден} other {# дни}}.",
|
"user_delete_delay": "<b>{user}</b> aкаунтът и файловете на потребителя ще бъдат планирани за постоянно изтриване след {delay, plural, one {# ден} other {# дни}}.",
|
||||||
"user_delete_delay_settings": "Забавяне на изтриване",
|
"user_delete_delay_settings": "Забавяне на изтриване",
|
||||||
@@ -382,6 +396,8 @@
|
|||||||
"advanced_settings_prefer_remote_title": "Предпочитай изображенията на сървъра",
|
"advanced_settings_prefer_remote_title": "Предпочитай изображенията на сървъра",
|
||||||
"advanced_settings_proxy_headers_subtitle": "Дефиниране на прокси хедъри, които Immich трябва да изпраща с всяка мрежова заявка",
|
"advanced_settings_proxy_headers_subtitle": "Дефиниране на прокси хедъри, които Immich трябва да изпраща с всяка мрежова заявка",
|
||||||
"advanced_settings_proxy_headers_title": "Прокси хедъри",
|
"advanced_settings_proxy_headers_title": "Прокси хедъри",
|
||||||
|
"advanced_settings_readonly_mode_subtitle": "Активира режима \"само за четене\", при който снимките могат да бъдат разглеждани, но неща като избор на няколко изображения, споделяне, изтриване са забранени. Активиране/деактивиране на режима само за четене става от картинката-аватар на потребителя от основния екран",
|
||||||
|
"advanced_settings_readonly_mode_title": "Режим само за четене",
|
||||||
"advanced_settings_self_signed_ssl_subtitle": "Пропуска проверката на SSL-сертификата на сървъра. Изисква се при самоподписани сертификати.",
|
"advanced_settings_self_signed_ssl_subtitle": "Пропуска проверката на SSL-сертификата на сървъра. Изисква се при самоподписани сертификати.",
|
||||||
"advanced_settings_self_signed_ssl_title": "Разреши самоподписани SSL сертификати",
|
"advanced_settings_self_signed_ssl_title": "Разреши самоподписани SSL сертификати",
|
||||||
"advanced_settings_sync_remote_deletions_subtitle": "Автоматично изтрии или възстанови обект на това устройство, когато действието е извършено през уеб-интерфейса",
|
"advanced_settings_sync_remote_deletions_subtitle": "Автоматично изтрии или възстанови обект на това устройство, когато действието е извършено през уеб-интерфейса",
|
||||||
@@ -397,6 +413,7 @@
|
|||||||
"album_cover_updated": "Обложката на албума е актуализирана",
|
"album_cover_updated": "Обложката на албума е актуализирана",
|
||||||
"album_delete_confirmation": "Сигурни ли сте, че искате да изтриете албума {album}?",
|
"album_delete_confirmation": "Сигурни ли сте, че искате да изтриете албума {album}?",
|
||||||
"album_delete_confirmation_description": "Ако този албум е споделен, други потребители вече няма да имат достъп до него.",
|
"album_delete_confirmation_description": "Ако този албум е споделен, други потребители вече няма да имат достъп до него.",
|
||||||
|
"album_deleted": "Албума е изтрит",
|
||||||
"album_info_card_backup_album_excluded": "ИЗКЛЮЧЕН",
|
"album_info_card_backup_album_excluded": "ИЗКЛЮЧЕН",
|
||||||
"album_info_card_backup_album_included": "ВКЛЮЧЕН",
|
"album_info_card_backup_album_included": "ВКЛЮЧЕН",
|
||||||
"album_info_updated": "Информацията за албума е актуализирана",
|
"album_info_updated": "Информацията за албума е актуализирана",
|
||||||
@@ -406,6 +423,7 @@
|
|||||||
"album_options": "Настройки на албума",
|
"album_options": "Настройки на албума",
|
||||||
"album_remove_user": "Премахване на потребител?",
|
"album_remove_user": "Премахване на потребител?",
|
||||||
"album_remove_user_confirmation": "Сигурни ли сте, че искате да премахнете {user}?",
|
"album_remove_user_confirmation": "Сигурни ли сте, че искате да премахнете {user}?",
|
||||||
|
"album_search_not_found": "Няма намерени албуми, отговарящи на търсенето ви",
|
||||||
"album_share_no_users": "Изглежда, че сте споделили този албум с всички потребители или нямате друг потребител, с когото да го споделите.",
|
"album_share_no_users": "Изглежда, че сте споделили този албум с всички потребители или нямате друг потребител, с когото да го споделите.",
|
||||||
"album_updated": "Албумът е актуализиран",
|
"album_updated": "Албумът е актуализиран",
|
||||||
"album_updated_setting_description": "Получавайте известие по имейл, когато споделен албум има нови файлове",
|
"album_updated_setting_description": "Получавайте известие по имейл, когато споделен албум има нови файлове",
|
||||||
@@ -425,6 +443,7 @@
|
|||||||
"albums_default_sort_order": "Ред по подразбиране за сортиране на албуми",
|
"albums_default_sort_order": "Ред по подразбиране за сортиране на албуми",
|
||||||
"albums_default_sort_order_description": "Първоначален ред на сортиране при създаване на нов албум.",
|
"albums_default_sort_order_description": "Първоначален ред на сортиране при създаване на нов албум.",
|
||||||
"albums_feature_description": "Колекции от обекти, които могат да бъдат споделяни с други поребители.",
|
"albums_feature_description": "Колекции от обекти, които могат да бъдат споделяни с други поребители.",
|
||||||
|
"albums_on_device_count": "Албуми на устройството ({count})",
|
||||||
"all": "Всички",
|
"all": "Всички",
|
||||||
"all_albums": "Всички албуми",
|
"all_albums": "Всички албуми",
|
||||||
"all_people": "Всички хора",
|
"all_people": "Всички хора",
|
||||||
@@ -444,6 +463,7 @@
|
|||||||
"app_bar_signout_dialog_title": "Излез от профила",
|
"app_bar_signout_dialog_title": "Излез от профила",
|
||||||
"app_settings": "Настройки ма приложението",
|
"app_settings": "Настройки ма приложението",
|
||||||
"appears_in": "Излиза в",
|
"appears_in": "Излиза в",
|
||||||
|
"apply_count": "Приложи ({count, number})",
|
||||||
"archive": "Архив",
|
"archive": "Архив",
|
||||||
"archive_action_prompt": "{count} са добавени в Архива",
|
"archive_action_prompt": "{count} са добавени в Архива",
|
||||||
"archive_or_unarchive_photo": "Архивиране или деархивиране на снимка",
|
"archive_or_unarchive_photo": "Архивиране или деархивиране на снимка",
|
||||||
@@ -483,7 +503,9 @@
|
|||||||
"assets": "Елементи",
|
"assets": "Елементи",
|
||||||
"assets_added_count": "Добавено {count, plural, one {# asset} other {# assets}}",
|
"assets_added_count": "Добавено {count, plural, one {# asset} other {# assets}}",
|
||||||
"assets_added_to_album_count": "Добавен(и) са {count, plural, one {# актив} other {# актива}} в албума",
|
"assets_added_to_album_count": "Добавен(и) са {count, plural, one {# актив} other {# актива}} в албума",
|
||||||
|
"assets_added_to_albums_count": "{assetTotal, plural, one {# обект е добавен} other {# обекта са добавени}} в {albumTotal, plural, one {# албум} other {# албума}}",
|
||||||
"assets_cannot_be_added_to_album_count": "{count, plural, one {Обекта не може да се добави} other {Обектите не може да се добавят}} в албума",
|
"assets_cannot_be_added_to_album_count": "{count, plural, one {Обекта не може да се добави} other {Обектите не може да се добавят}} в албума",
|
||||||
|
"assets_cannot_be_added_to_albums": "{count, plural, one {обект не може да бъде добавен} other {обекта не могат да бъдат добавени}} в никой от албумите",
|
||||||
"assets_count": "{count, plural, one {# актив} other {# актива}}",
|
"assets_count": "{count, plural, one {# актив} other {# актива}}",
|
||||||
"assets_deleted_permanently": "{count} обекта са изтрити завинаги",
|
"assets_deleted_permanently": "{count} обекта са изтрити завинаги",
|
||||||
"assets_deleted_permanently_from_server": "{count} обекта са изтити от Immich сървъра завинаги",
|
"assets_deleted_permanently_from_server": "{count} обекта са изтити от Immich сървъра завинаги",
|
||||||
@@ -500,6 +522,7 @@
|
|||||||
"assets_trashed_count": "Възстановен(и) са {count, plural, one {# файл} other {# файла}}",
|
"assets_trashed_count": "Възстановен(и) са {count, plural, one {# файл} other {# файла}}",
|
||||||
"assets_trashed_from_server": "{count} обекта са преместени в коша на Immich сървъра",
|
"assets_trashed_from_server": "{count} обекта са преместени в коша на Immich сървъра",
|
||||||
"assets_were_part_of_album_count": "{count, plural, one {Файлът е} other {Файловете са}} вече част от албума",
|
"assets_were_part_of_album_count": "{count, plural, one {Файлът е} other {Файловете са}} вече част от албума",
|
||||||
|
"assets_were_part_of_albums_count": "{count, plural, one {обект вече е} other {обекта вече са}} част от албумите",
|
||||||
"authorized_devices": "Удостоверени устройства",
|
"authorized_devices": "Удостоверени устройства",
|
||||||
"automatic_endpoint_switching_subtitle": "Когато е достъпна, използвай посочената Wi-Fi мрежа, иначе използвай алтернативни връзки",
|
"automatic_endpoint_switching_subtitle": "Когато е достъпна, използвай посочената Wi-Fi мрежа, иначе използвай алтернативни връзки",
|
||||||
"automatic_endpoint_switching_title": "Автоматично превключване на URL",
|
"automatic_endpoint_switching_title": "Автоматично превключване на URL",
|
||||||
@@ -569,9 +592,13 @@
|
|||||||
"backup_manual_in_progress": "Върви архивиране. Опитай след малко",
|
"backup_manual_in_progress": "Върви архивиране. Опитай след малко",
|
||||||
"backup_manual_success": "Успешно",
|
"backup_manual_success": "Успешно",
|
||||||
"backup_manual_title": "Състояние на архивирането",
|
"backup_manual_title": "Състояние на архивирането",
|
||||||
|
"backup_options": "Опции за архивиране",
|
||||||
"backup_options_page_title": "Настройки за архивиране",
|
"backup_options_page_title": "Настройки за архивиране",
|
||||||
"backup_setting_subtitle": "Управлявай настройките за архивиране в активен и фонов режим",
|
"backup_setting_subtitle": "Управлявай настройките за архивиране в активен и фонов режим",
|
||||||
|
"backup_settings_subtitle": "Управление на настройките за качване",
|
||||||
"backward": "Назад",
|
"backward": "Назад",
|
||||||
|
"beta_sync": "Статус на бета синхронизацията",
|
||||||
|
"beta_sync_subtitle": "Управление на новата система за синхронизация",
|
||||||
"biometric_auth_enabled": "Включена биометрично удостоверяване",
|
"biometric_auth_enabled": "Включена биометрично удостоверяване",
|
||||||
"biometric_locked_out": "Няма достъп до биометрично удостоверяване",
|
"biometric_locked_out": "Няма достъп до биометрично удостоверяване",
|
||||||
"biometric_no_options": "Няма биометрична автентикация",
|
"biometric_no_options": "Няма биометрична автентикация",
|
||||||
@@ -589,7 +616,7 @@
|
|||||||
"cache_settings_clear_cache_button": "Изчисти кеша",
|
"cache_settings_clear_cache_button": "Изчисти кеша",
|
||||||
"cache_settings_clear_cache_button_title": "Изчиства кеша на приложението. Това ще повлияе производителността на приложението докато кеша не бъде създаден отново.",
|
"cache_settings_clear_cache_button_title": "Изчиства кеша на приложението. Това ще повлияе производителността на приложението докато кеша не бъде създаден отново.",
|
||||||
"cache_settings_duplicated_assets_clear_button": "ИЗЧИСТИ",
|
"cache_settings_duplicated_assets_clear_button": "ИЗЧИСТИ",
|
||||||
"cache_settings_duplicated_assets_subtitle": "Снимки и видеа, които са в Черния списък на приложението",
|
"cache_settings_duplicated_assets_subtitle": "Снимки и видеа, които са в Списъка за игнориране от приложението",
|
||||||
"cache_settings_duplicated_assets_title": "Дублирани обекти ({count})",
|
"cache_settings_duplicated_assets_title": "Дублирани обекти ({count})",
|
||||||
"cache_settings_statistics_album": "Библиотека с миниатюри",
|
"cache_settings_statistics_album": "Библиотека с миниатюри",
|
||||||
"cache_settings_statistics_full": "Пълни изображения",
|
"cache_settings_statistics_full": "Пълни изображения",
|
||||||
@@ -606,6 +633,7 @@
|
|||||||
"cancel": "Откажи",
|
"cancel": "Откажи",
|
||||||
"cancel_search": "Отмени търсенето",
|
"cancel_search": "Отмени търсенето",
|
||||||
"canceled": "Отменено",
|
"canceled": "Отменено",
|
||||||
|
"canceling": "Анулиране",
|
||||||
"cannot_merge_people": "Не може да обединява хора",
|
"cannot_merge_people": "Не може да обединява хора",
|
||||||
"cannot_undo_this_action": "Не можете да отмените това действие!",
|
"cannot_undo_this_action": "Не можете да отмените това действие!",
|
||||||
"cannot_update_the_description": "Описанието не може да бъде актуализирано",
|
"cannot_update_the_description": "Описанието не може да бъде актуализирано",
|
||||||
@@ -637,6 +665,7 @@
|
|||||||
"clear": "Изчисти",
|
"clear": "Изчисти",
|
||||||
"clear_all": "Изчисти всичко",
|
"clear_all": "Изчисти всичко",
|
||||||
"clear_all_recent_searches": "Изчистете всички скорошни търсения",
|
"clear_all_recent_searches": "Изчистете всички скорошни търсения",
|
||||||
|
"clear_file_cache": "Изчистване на кеша на файловете",
|
||||||
"clear_message": "Изчисти съобщението",
|
"clear_message": "Изчисти съобщението",
|
||||||
"clear_value": "Изчисти стойността",
|
"clear_value": "Изчисти стойността",
|
||||||
"client_cert_dialog_msg_confirm": "ОК",
|
"client_cert_dialog_msg_confirm": "ОК",
|
||||||
@@ -707,6 +736,7 @@
|
|||||||
"create_new_user": "Създаване на нов потребител",
|
"create_new_user": "Създаване на нов потребител",
|
||||||
"create_shared_album_page_share_add_assets": "ДОБАВИ ОБЕКТИ",
|
"create_shared_album_page_share_add_assets": "ДОБАВИ ОБЕКТИ",
|
||||||
"create_shared_album_page_share_select_photos": "Избери снимки",
|
"create_shared_album_page_share_select_photos": "Избери снимки",
|
||||||
|
"create_shared_link": "Създай линк за споделяне",
|
||||||
"create_tag": "Създай таг",
|
"create_tag": "Създай таг",
|
||||||
"create_tag_description": "Създайте нов таг. За вложени тагове, моля, въведете пълния път на тага, включително наклонените черти.",
|
"create_tag_description": "Създайте нов таг. За вложени тагове, моля, въведете пълния път на тага, включително наклонените черти.",
|
||||||
"create_user": "Създай потребител",
|
"create_user": "Създай потребител",
|
||||||
@@ -719,6 +749,7 @@
|
|||||||
"current_server_address": "Настоящ адрес на сървъра",
|
"current_server_address": "Настоящ адрес на сървъра",
|
||||||
"custom_locale": "Персонализиран локал",
|
"custom_locale": "Персонализиран локал",
|
||||||
"custom_locale_description": "Форматиране на дати и числа в зависимост от езика и региона",
|
"custom_locale_description": "Форматиране на дати и числа в зависимост от езика и региона",
|
||||||
|
"custom_url": "Персонализиран URL адрес",
|
||||||
"daily_title_text_date": "E, dd MMM",
|
"daily_title_text_date": "E, dd MMM",
|
||||||
"daily_title_text_date_year": "E, dd MMM yyyy",
|
"daily_title_text_date_year": "E, dd MMM yyyy",
|
||||||
"dark": "Тъмен",
|
"dark": "Тъмен",
|
||||||
@@ -730,6 +761,7 @@
|
|||||||
"date_of_birth_saved": "Дата на раждане е записана успешно",
|
"date_of_birth_saved": "Дата на раждане е записана успешно",
|
||||||
"date_range": "Период от време",
|
"date_range": "Период от време",
|
||||||
"day": "Ден",
|
"day": "Ден",
|
||||||
|
"days": "Дни",
|
||||||
"deduplicate_all": "Дедупликиране на всички",
|
"deduplicate_all": "Дедупликиране на всички",
|
||||||
"deduplication_criteria_1": "Размер на снимката в байтове",
|
"deduplication_criteria_1": "Размер на снимката в байтове",
|
||||||
"deduplication_criteria_2": "Брой EXIF данни",
|
"deduplication_criteria_2": "Брой EXIF данни",
|
||||||
@@ -738,7 +770,8 @@
|
|||||||
"default_locale": "Локализация по подразбиране",
|
"default_locale": "Локализация по подразбиране",
|
||||||
"default_locale_description": "Форматиране на дати и числа в зависимост от езиковата настройка на браузъра",
|
"default_locale_description": "Форматиране на дати и числа в зависимост от езиковата настройка на браузъра",
|
||||||
"delete": "Изтрий",
|
"delete": "Изтрий",
|
||||||
"delete_action_prompt": "{count} са изтрити завинаги",
|
"delete_action_confirmation_message": "Сигурни ли сте, че искате да изтриете този обект? Следва преместване на обекта в коша за отпадъци на сървъра и ще получите предложение обекта да бъде изтрит локално",
|
||||||
|
"delete_action_prompt": "{count} са изтрити",
|
||||||
"delete_album": "Изтрий албум",
|
"delete_album": "Изтрий албум",
|
||||||
"delete_api_key_prompt": "Сигурни ли сте, че искате да изтриете този API ключ?",
|
"delete_api_key_prompt": "Сигурни ли сте, че искате да изтриете този API ключ?",
|
||||||
"delete_dialog_alert": "Тези обекти ще бъдат изтрити завинаги и от Immich сървъра и от устройството",
|
"delete_dialog_alert": "Тези обекти ще бъдат изтрити завинаги и от Immich сървъра и от устройството",
|
||||||
@@ -756,6 +789,8 @@
|
|||||||
"delete_local_dialog_ok_backed_up_only": "Изтрий локално само архивираните",
|
"delete_local_dialog_ok_backed_up_only": "Изтрий локално само архивираните",
|
||||||
"delete_local_dialog_ok_force": "Въпреки това изтрий",
|
"delete_local_dialog_ok_force": "Въпреки това изтрий",
|
||||||
"delete_others": "Изтрий останалите",
|
"delete_others": "Изтрий останалите",
|
||||||
|
"delete_permanently": "Изтрий за постоянно",
|
||||||
|
"delete_permanently_action_prompt": "{count} изтрити за постоянно",
|
||||||
"delete_shared_link": "Изтриване на споделен линк",
|
"delete_shared_link": "Изтриване на споделен линк",
|
||||||
"delete_shared_link_dialog_title": "Изтрий споделената връзка",
|
"delete_shared_link_dialog_title": "Изтрий споделената връзка",
|
||||||
"delete_tag": "Изтрий таг",
|
"delete_tag": "Изтрий таг",
|
||||||
@@ -766,6 +801,7 @@
|
|||||||
"description": "Описание",
|
"description": "Описание",
|
||||||
"description_input_hint_text": "Добави описание...",
|
"description_input_hint_text": "Добави описание...",
|
||||||
"description_input_submit_error": "Неуспешно обновяване на описанието. За подробности вижте в дневника",
|
"description_input_submit_error": "Неуспешно обновяване на описанието. За подробности вижте в дневника",
|
||||||
|
"deselect_all": "Премахни избора от всички",
|
||||||
"details": "Детайли",
|
"details": "Детайли",
|
||||||
"direction": "Посока",
|
"direction": "Посока",
|
||||||
"disabled": "Изключено",
|
"disabled": "Изключено",
|
||||||
@@ -810,8 +846,12 @@
|
|||||||
"edit": "Редактиране",
|
"edit": "Редактиране",
|
||||||
"edit_album": "Редактиране на албум",
|
"edit_album": "Редактиране на албум",
|
||||||
"edit_avatar": "Редактиране на аватар",
|
"edit_avatar": "Редактиране на аватар",
|
||||||
|
"edit_birthday": "Редактиране на рожден ден",
|
||||||
"edit_date": "Редактиране на дата",
|
"edit_date": "Редактиране на дата",
|
||||||
"edit_date_and_time": "Редактиране на дата и час",
|
"edit_date_and_time": "Редактиране на дата и час",
|
||||||
|
"edit_date_and_time_action_prompt": "{count} дата и време са редактирани",
|
||||||
|
"edit_date_and_time_by_offset": "Промяна на датата чрез отместване",
|
||||||
|
"edit_date_and_time_by_offset_interval": "Нов период от време: {from} - {to}",
|
||||||
"edit_description": "Редактирай описание",
|
"edit_description": "Редактирай описание",
|
||||||
"edit_description_prompt": "Моля, избери ново описание:",
|
"edit_description_prompt": "Моля, избери ново описание:",
|
||||||
"edit_exclusion_pattern": "Редактиране на шаблон за изключване",
|
"edit_exclusion_pattern": "Редактиране на шаблон за изключване",
|
||||||
@@ -840,6 +880,7 @@
|
|||||||
"empty_trash": "Изпразване на кош",
|
"empty_trash": "Изпразване на кош",
|
||||||
"empty_trash_confirmation": "Сигурни ли сте, че искате да изпразните кошчето? Това ще премахне всичко в кошчето за постоянно от Immich.\nНе можете да отмените това действие!",
|
"empty_trash_confirmation": "Сигурни ли сте, че искате да изпразните кошчето? Това ще премахне всичко в кошчето за постоянно от Immich.\nНе можете да отмените това действие!",
|
||||||
"enable": "Включване",
|
"enable": "Включване",
|
||||||
|
"enable_backup": "Включи резервното копиране",
|
||||||
"enable_biometric_auth_description": "Въведете вашия PIN код, за да разрешите биометрично удостоверяване",
|
"enable_biometric_auth_description": "Въведете вашия PIN код, за да разрешите биометрично удостоверяване",
|
||||||
"enabled": "Включено",
|
"enabled": "Включено",
|
||||||
"end_date": "Крайна дата",
|
"end_date": "Крайна дата",
|
||||||
@@ -874,7 +915,7 @@
|
|||||||
"error_selecting_all_assets": "Грешка при избора на всички файлове",
|
"error_selecting_all_assets": "Грешка при избора на всички файлове",
|
||||||
"exclusion_pattern_already_exists": "Този модел за изключване вече съществува.",
|
"exclusion_pattern_already_exists": "Този модел за изключване вече съществува.",
|
||||||
"failed_to_create_album": "Неуспешно създаване на албум",
|
"failed_to_create_album": "Неуспешно създаване на албум",
|
||||||
"failed_to_create_shared_link": "Неуспешно създаване на споделена връзка",
|
"failed_to_create_shared_link": "Неуспешно създаване на спoделена връзка",
|
||||||
"failed_to_edit_shared_link": "Неуспешно редактиране на споделена връзка",
|
"failed_to_edit_shared_link": "Неуспешно редактиране на споделена връзка",
|
||||||
"failed_to_get_people": "Неуспешно зареждане на хора",
|
"failed_to_get_people": "Неуспешно зареждане на хора",
|
||||||
"failed_to_keep_this_delete_others": "Неуспешно запазване на този обект и изтриване на останалите обекти",
|
"failed_to_keep_this_delete_others": "Неуспешно запазване на този обект и изтриване на останалите обекти",
|
||||||
@@ -883,6 +924,7 @@
|
|||||||
"failed_to_load_notifications": "Неуспешно зареждане на известия",
|
"failed_to_load_notifications": "Неуспешно зареждане на известия",
|
||||||
"failed_to_load_people": "Неуспешно зареждане на хора",
|
"failed_to_load_people": "Неуспешно зареждане на хора",
|
||||||
"failed_to_remove_product_key": "Неуспешно премахване на продуктовия ключ",
|
"failed_to_remove_product_key": "Неуспешно премахване на продуктовия ключ",
|
||||||
|
"failed_to_reset_pin_code": "Неуспешно нулиране на ПИН кода",
|
||||||
"failed_to_stack_assets": "Неуспешно подреждане на обекти",
|
"failed_to_stack_assets": "Неуспешно подреждане на обекти",
|
||||||
"failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти",
|
"failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти",
|
||||||
"failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията",
|
"failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията",
|
||||||
@@ -891,6 +933,7 @@
|
|||||||
"paths_validation_failed": "{paths, plural, one {# път} other {# пътища}} не преминаха валидация",
|
"paths_validation_failed": "{paths, plural, one {# път} other {# пътища}} не преминаха валидация",
|
||||||
"profile_picture_transparent_pixels": "Профилните снимки не могат да имат прозрачни пиксели. Моля, увеличете и/или преместете изображението.",
|
"profile_picture_transparent_pixels": "Профилните снимки не могат да имат прозрачни пиксели. Моля, увеличете и/или преместете изображението.",
|
||||||
"quota_higher_than_disk_size": "Зададена е квота, по-голяма от размера на диска",
|
"quota_higher_than_disk_size": "Зададена е квота, по-голяма от размера на диска",
|
||||||
|
"something_went_wrong": "Нещо се обърка",
|
||||||
"unable_to_add_album_users": "Неуспешно добавяне на потребители в албум",
|
"unable_to_add_album_users": "Неуспешно добавяне на потребители в албум",
|
||||||
"unable_to_add_assets_to_shared_link": "Неуспешно добавяне на обекти в споделен линк",
|
"unable_to_add_assets_to_shared_link": "Неуспешно добавяне на обекти в споделен линк",
|
||||||
"unable_to_add_comment": "Неуспешно добавяне на коментар",
|
"unable_to_add_comment": "Неуспешно добавяне на коментар",
|
||||||
@@ -976,13 +1019,11 @@
|
|||||||
},
|
},
|
||||||
"exif": "Exif",
|
"exif": "Exif",
|
||||||
"exif_bottom_sheet_description": "Добави Описание...",
|
"exif_bottom_sheet_description": "Добави Описание...",
|
||||||
|
"exif_bottom_sheet_description_error": "Неуспешно обновяване на описание",
|
||||||
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
|
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
|
||||||
"exif_bottom_sheet_location": "МЯСТО",
|
"exif_bottom_sheet_location": "МЯСТО",
|
||||||
"exif_bottom_sheet_people": "ХОРА",
|
"exif_bottom_sheet_people": "ХОРА",
|
||||||
"exif_bottom_sheet_person_add_person": "Добави име",
|
"exif_bottom_sheet_person_add_person": "Добави име",
|
||||||
"exif_bottom_sheet_person_age_months": "Възраст {months} месеца",
|
|
||||||
"exif_bottom_sheet_person_age_year_months": "Възраст 1 година и {months} месеца",
|
|
||||||
"exif_bottom_sheet_person_age_years": "Възраст {years}",
|
|
||||||
"exit_slideshow": "Изход от слайдшоуто",
|
"exit_slideshow": "Изход от слайдшоуто",
|
||||||
"expand_all": "Разшири всички",
|
"expand_all": "Разшири всички",
|
||||||
"experimental_settings_new_asset_list_subtitle": "В развитие",
|
"experimental_settings_new_asset_list_subtitle": "В развитие",
|
||||||
@@ -996,6 +1037,8 @@
|
|||||||
"explorer": "Преглед",
|
"explorer": "Преглед",
|
||||||
"export": "Експорт",
|
"export": "Експорт",
|
||||||
"export_as_json": "Експортиране като JSON",
|
"export_as_json": "Експортиране като JSON",
|
||||||
|
"export_database": "Експорт на базата данни",
|
||||||
|
"export_database_description": "Експорт на базата данни SQLite",
|
||||||
"extension": "Разширение",
|
"extension": "Разширение",
|
||||||
"external": "Външно",
|
"external": "Външно",
|
||||||
"external_libraries": "Външни библиотеки",
|
"external_libraries": "Външни библиотеки",
|
||||||
@@ -1022,21 +1065,29 @@
|
|||||||
"filter_people": "Филтриране на хора",
|
"filter_people": "Филтриране на хора",
|
||||||
"filter_places": "Филтър по място",
|
"filter_places": "Филтър по място",
|
||||||
"find_them_fast": "Намерете ги бързо по име с търсене",
|
"find_them_fast": "Намерете ги бързо по име с търсене",
|
||||||
|
"first": "Първи",
|
||||||
"fix_incorrect_match": "Поправяне на неправилно съвпадение",
|
"fix_incorrect_match": "Поправяне на неправилно съвпадение",
|
||||||
"folder": "Папка",
|
"folder": "Папка",
|
||||||
"folder_not_found": "Папката не е намерена",
|
"folder_not_found": "Папката не е намерена",
|
||||||
"folders": "Папки",
|
"folders": "Папки",
|
||||||
"folders_feature_description": "Преглеждане на папката за снимките и видеоклиповете в файловата система",
|
"folders_feature_description": "Преглеждане на папката за снимките и видеоклиповете в файловата система",
|
||||||
|
"forgot_pin_code_question": "Забравили сте своя ПИН код?",
|
||||||
"forward": "Напред",
|
"forward": "Напред",
|
||||||
"gcast_enabled": "Google Cast",
|
"gcast_enabled": "Google Cast",
|
||||||
"gcast_enabled_description": "За да работи тази функция зарежда външни ресурси от Google.",
|
"gcast_enabled_description": "За да работи тази функция зарежда външни ресурси от Google.",
|
||||||
"general": "Общи",
|
"general": "Общи",
|
||||||
|
"geolocation_instruction_all_have_location": "Всички обекти от тази дата вече имат данни за местоположение. Опитайте да включите показване на всички обекти или изберете друга дата",
|
||||||
|
"geolocation_instruction_location": "Изберете обект с GPS координати за да използвате тях или изберете място директно от картата",
|
||||||
|
"geolocation_instruction_no_date": "Изберете дата за да управлявате данните за локация на снимките и видеата от тази дата",
|
||||||
|
"geolocation_instruction_no_photos": "Не са намерени снимки или видеа от тази дата. Изберете друга дата",
|
||||||
"get_help": "Помощ",
|
"get_help": "Помощ",
|
||||||
"get_wifiname_error": "Неуспешно получаване името на Wi-Fi мрежата. Моля, убедете се, че са предоставени нужните разрешения на приложението и има връзка с Wi-Fi",
|
"get_wifiname_error": "Неуспешно получаване името на Wi-Fi мрежата. Моля, убедете се, че са предоставени нужните разрешения на приложението и има връзка с Wi-Fi",
|
||||||
"getting_started": "Как да започнем",
|
"getting_started": "Как да започнем",
|
||||||
"go_back": "Връщане назад",
|
"go_back": "Връщане назад",
|
||||||
"go_to_folder": "Отиди в папката",
|
"go_to_folder": "Отиди в папката",
|
||||||
"go_to_search": "Преминаване към търсене",
|
"go_to_search": "Преминаване към търсене",
|
||||||
|
"gps": "GPS координати",
|
||||||
|
"gps_missing": "Няма GPS координати",
|
||||||
"grant_permission": "Дай разрешение",
|
"grant_permission": "Дай разрешение",
|
||||||
"group_albums_by": "Групирай албум по...",
|
"group_albums_by": "Групирай албум по...",
|
||||||
"group_country": "Групирай по държава",
|
"group_country": "Групирай по държава",
|
||||||
@@ -1047,6 +1098,9 @@
|
|||||||
"haptic_feedback_switch": "Включи тактилна обратна връзка",
|
"haptic_feedback_switch": "Включи тактилна обратна връзка",
|
||||||
"haptic_feedback_title": "Тактилна обратна връзка",
|
"haptic_feedback_title": "Тактилна обратна връзка",
|
||||||
"has_quota": "Лимит",
|
"has_quota": "Лимит",
|
||||||
|
"hash_asset": "Обект с хеш",
|
||||||
|
"hashed_assets": "Хеширани обекти",
|
||||||
|
"hashing": "Хеширане",
|
||||||
"header_settings_add_header_tip": "Добави заглавие",
|
"header_settings_add_header_tip": "Добави заглавие",
|
||||||
"header_settings_field_validator_msg": "Недопустимо е да няма стойност",
|
"header_settings_field_validator_msg": "Недопустимо е да няма стойност",
|
||||||
"header_settings_header_name_input": "Име на заглавието",
|
"header_settings_header_name_input": "Име на заглавието",
|
||||||
@@ -1078,7 +1132,9 @@
|
|||||||
"home_page_upload_err_limit": "Може да качвате максимум 30 обекта едновременно, пропускане",
|
"home_page_upload_err_limit": "Може да качвате максимум 30 обекта едновременно, пропускане",
|
||||||
"host": "Хост",
|
"host": "Хост",
|
||||||
"hour": "Час",
|
"hour": "Час",
|
||||||
|
"hours": "Часа",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
|
"idle": "Бездействие",
|
||||||
"ignore_icloud_photos": "Пропусни снимки от iCloud",
|
"ignore_icloud_photos": "Пропусни снимки от iCloud",
|
||||||
"ignore_icloud_photos_description": "Снимки, които са запазени в iCloud няма да се качват в Immich сървъра",
|
"ignore_icloud_photos_description": "Снимки, които са запазени в iCloud няма да се качват в Immich сървъра",
|
||||||
"image": "Изображение",
|
"image": "Изображение",
|
||||||
@@ -1136,10 +1192,13 @@
|
|||||||
"language_no_results_title": "Не са намерени езици",
|
"language_no_results_title": "Не са намерени езици",
|
||||||
"language_search_hint": "Търсене на езици...",
|
"language_search_hint": "Търсене на езици...",
|
||||||
"language_setting_description": "Изберете предпочитан език",
|
"language_setting_description": "Изберете предпочитан език",
|
||||||
|
"large_files": "Големи файлове",
|
||||||
|
"last": "Последен",
|
||||||
"last_seen": "Последно видяно",
|
"last_seen": "Последно видяно",
|
||||||
"latest_version": "Последна версия",
|
"latest_version": "Последна версия",
|
||||||
"latitude": "Ширина",
|
"latitude": "Ширина",
|
||||||
"leave": "Излез",
|
"leave": "Излез",
|
||||||
|
"leave_album": "Напускане на албума",
|
||||||
"lens_model": "Модел леща",
|
"lens_model": "Модел леща",
|
||||||
"let_others_respond": "Позволете на другите да отговорят",
|
"let_others_respond": "Позволете на другите да отговорят",
|
||||||
"level": "Ниво",
|
"level": "Ниво",
|
||||||
@@ -1153,6 +1212,7 @@
|
|||||||
"library_page_sort_title": "Заглавие на албума",
|
"library_page_sort_title": "Заглавие на албума",
|
||||||
"licenses": "Лицензи",
|
"licenses": "Лицензи",
|
||||||
"light": "Светло",
|
"light": "Светло",
|
||||||
|
"like": "Харесайте",
|
||||||
"like_deleted": "Като изтрит",
|
"like_deleted": "Като изтрит",
|
||||||
"link_motion_video": "Линк към видео",
|
"link_motion_video": "Линк към видео",
|
||||||
"link_to_oauth": "Линк към OAuth",
|
"link_to_oauth": "Линк към OAuth",
|
||||||
@@ -1160,7 +1220,9 @@
|
|||||||
"list": "Лист",
|
"list": "Лист",
|
||||||
"loading": "Зареждане",
|
"loading": "Зареждане",
|
||||||
"loading_search_results_failed": "Зареждането на резултатите от търсенето е неуспешно",
|
"loading_search_results_failed": "Зареждането на резултатите от търсенето е неуспешно",
|
||||||
|
"local": "Локално",
|
||||||
"local_asset_cast_failed": "Не може да се предава обект, който още не е качен на сървъра",
|
"local_asset_cast_failed": "Не може да се предава обект, който още не е качен на сървъра",
|
||||||
|
"local_assets": "Локални обекти",
|
||||||
"local_network": "Локална мрежа",
|
"local_network": "Локална мрежа",
|
||||||
"local_network_sheet_info": "Приложението ще се свърже със сървъра на този URL, когато устройството е свързано към зададената Wi-Fi мрежа",
|
"local_network_sheet_info": "Приложението ще се свърже със сървъра на този URL, когато устройството е свързано към зададената Wi-Fi мрежа",
|
||||||
"location_permission": "Разрешение за местоположение",
|
"location_permission": "Разрешение за местоположение",
|
||||||
@@ -1209,6 +1271,7 @@
|
|||||||
"main_branch_warning": "Използвате версия за разработчици, силно препоръчваме да използвате официална версия!",
|
"main_branch_warning": "Използвате версия за разработчици, силно препоръчваме да използвате официална версия!",
|
||||||
"main_menu": "Главно меню",
|
"main_menu": "Главно меню",
|
||||||
"make": "Марка",
|
"make": "Марка",
|
||||||
|
"manage_geolocation": "Управление на местоположенията",
|
||||||
"manage_shared_links": "Управление на споделени връзки",
|
"manage_shared_links": "Управление на споделени връзки",
|
||||||
"manage_sharing_with_partners": "Управление на споделянето с партньори",
|
"manage_sharing_with_partners": "Управление на споделянето с партньори",
|
||||||
"manage_the_app_settings": "Управление на настройките на приложението",
|
"manage_the_app_settings": "Управление на настройките на приложението",
|
||||||
@@ -1217,7 +1280,7 @@
|
|||||||
"manage_your_devices": "Управление на влезлите в системата устройства",
|
"manage_your_devices": "Управление на влезлите в системата устройства",
|
||||||
"manage_your_oauth_connection": "Управление на OAuth връзката",
|
"manage_your_oauth_connection": "Управление на OAuth връзката",
|
||||||
"map": "Карта",
|
"map": "Карта",
|
||||||
"map_assets_in_bounds": "{count} снимки",
|
"map_assets_in_bounds": "{count, plural, =0 {Няма снимки} one {# снимка} other {# снимки}}",
|
||||||
"map_cannot_get_user_location": "Не можах да получа местоположението",
|
"map_cannot_get_user_location": "Не можах да получа местоположението",
|
||||||
"map_location_dialog_yes": "Да",
|
"map_location_dialog_yes": "Да",
|
||||||
"map_location_picker_page_use_location": "Използвай това местоположение",
|
"map_location_picker_page_use_location": "Използвай това местоположение",
|
||||||
@@ -1225,7 +1288,6 @@
|
|||||||
"map_location_service_disabled_title": "Услугата за местоположение е изключена",
|
"map_location_service_disabled_title": "Услугата за местоположение е изключена",
|
||||||
"map_marker_for_images": "Маркери на картата за снимки направени в {city}, {country}",
|
"map_marker_for_images": "Маркери на картата за снимки направени в {city}, {country}",
|
||||||
"map_marker_with_image": "Маркер на картата с изображение",
|
"map_marker_with_image": "Маркер на картата с изображение",
|
||||||
"map_no_assets_in_bounds": "Няма снимки от този район",
|
|
||||||
"map_no_location_permission_content": "За да се показват обектите от текущото място, трябва разрешение за определяне на местоположението. Искате ли да предоставите разрешение сега?",
|
"map_no_location_permission_content": "За да се показват обектите от текущото място, трябва разрешение за определяне на местоположението. Искате ли да предоставите разрешение сега?",
|
||||||
"map_no_location_permission_title": "Отказан достъп до местоположение",
|
"map_no_location_permission_title": "Отказан достъп до местоположение",
|
||||||
"map_settings": "Настройки на картата",
|
"map_settings": "Настройки на картата",
|
||||||
@@ -1262,6 +1324,7 @@
|
|||||||
"merged_people_count": "Слят {count, plural, one {# човек} other {# човека}}",
|
"merged_people_count": "Слят {count, plural, one {# човек} other {# човека}}",
|
||||||
"minimize": "Минимизиране",
|
"minimize": "Минимизиране",
|
||||||
"minute": "Минута",
|
"minute": "Минута",
|
||||||
|
"minutes": "Минути",
|
||||||
"missing": "Липсващи",
|
"missing": "Липсващи",
|
||||||
"model": "Модел",
|
"model": "Модел",
|
||||||
"month": "Месец",
|
"month": "Месец",
|
||||||
@@ -1281,6 +1344,9 @@
|
|||||||
"my_albums": "Мои албуми",
|
"my_albums": "Мои албуми",
|
||||||
"name": "Име",
|
"name": "Име",
|
||||||
"name_or_nickname": "Име или прякор",
|
"name_or_nickname": "Име или прякор",
|
||||||
|
"network_requirement_photos_upload": "Използвай мобилни данни за архивиране на снимки",
|
||||||
|
"network_requirement_videos_upload": "Използвай мобилни данни за архивиране на видео",
|
||||||
|
"network_requirements_updated": "Мрежовите настройки са променени, нулиране на опашката за архивиране",
|
||||||
"networking_settings": "Мрежа",
|
"networking_settings": "Мрежа",
|
||||||
"networking_subtitle": "Управление на настройките за връзка със сървъра",
|
"networking_subtitle": "Управление на настройките за връзка със сървъра",
|
||||||
"never": "Никога",
|
"never": "Никога",
|
||||||
@@ -1316,6 +1382,7 @@
|
|||||||
"no_results": "Няма резултати",
|
"no_results": "Няма резултати",
|
||||||
"no_results_description": "Опитайте със синоним или по-обща ключова дума",
|
"no_results_description": "Опитайте със синоним или по-обща ключова дума",
|
||||||
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
|
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
|
||||||
|
"no_uploads_in_progress": "Няма качване в момента",
|
||||||
"not_in_any_album": "Не е в никой албум",
|
"not_in_any_album": "Не е в никой албум",
|
||||||
"not_selected": "Не е избрано",
|
"not_selected": "Не е избрано",
|
||||||
"note_apply_storage_label_to_previously_uploaded assets": "Забележка: За да приложите етикета за съхранение към предварително качени активи, стартирайте",
|
"note_apply_storage_label_to_previously_uploaded assets": "Забележка: За да приложите етикета за съхранение към предварително качени активи, стартирайте",
|
||||||
@@ -1331,6 +1398,7 @@
|
|||||||
"oauth": "OAuth",
|
"oauth": "OAuth",
|
||||||
"official_immich_resources": "Официална информация за Immich",
|
"official_immich_resources": "Официална информация за Immich",
|
||||||
"offline": "Офлайн",
|
"offline": "Офлайн",
|
||||||
|
"offset": "Отместване",
|
||||||
"ok": "Добре",
|
"ok": "Добре",
|
||||||
"oldest_first": "Най-старите първи",
|
"oldest_first": "Най-старите първи",
|
||||||
"on_this_device": "На това устройство",
|
"on_this_device": "На това устройство",
|
||||||
@@ -1353,6 +1421,7 @@
|
|||||||
"original": "оригинал",
|
"original": "оригинал",
|
||||||
"other": "Други",
|
"other": "Други",
|
||||||
"other_devices": "Други устройства",
|
"other_devices": "Други устройства",
|
||||||
|
"other_entities": "Други обекти",
|
||||||
"other_variables": "Други променливи",
|
"other_variables": "Други променливи",
|
||||||
"owned": "Моите",
|
"owned": "Моите",
|
||||||
"owner": "Собственик",
|
"owner": "Собственик",
|
||||||
@@ -1407,6 +1476,9 @@
|
|||||||
"permission_onboarding_permission_limited": "Ограничен достъп. За да може Immich да архивира и управлява галерията, предоставете достъп до снимки и видео в настройките.",
|
"permission_onboarding_permission_limited": "Ограничен достъп. За да може Immich да архивира и управлява галерията, предоставете достъп до снимки и видео в настройките.",
|
||||||
"permission_onboarding_request": "Immich се нуждае от разрешение за преглед на снимки и видео.",
|
"permission_onboarding_request": "Immich се нуждае от разрешение за преглед на снимки и видео.",
|
||||||
"person": "Човек",
|
"person": "Човек",
|
||||||
|
"person_age_months": "{months, plural, one {# месец} other {# месеца}}",
|
||||||
|
"person_age_year_months": "1 година и {months, plural, one {# месец} other {# месеца}}",
|
||||||
|
"person_age_years": "{years, plural, other {# години}}",
|
||||||
"person_birthdate": "Дата на раждане {date}",
|
"person_birthdate": "Дата на раждане {date}",
|
||||||
"person_hidden": "{name}{hidden, select, true { (скрит)} other {}}",
|
"person_hidden": "{name}{hidden, select, true { (скрит)} other {}}",
|
||||||
"photo_shared_all_users": "Изглежда, че сте споделили снимките си с всички потребители или нямате потребители, с които да споделяте.",
|
"photo_shared_all_users": "Изглежда, че сте споделили снимките си с всички потребители или нямате потребители, с които да споделяте.",
|
||||||
@@ -1446,6 +1518,7 @@
|
|||||||
"profile_drawer_client_out_of_date_minor": "Мобилното приложение е остаряло. Моля, актуализирай до най-новата версия.",
|
"profile_drawer_client_out_of_date_minor": "Мобилното приложение е остаряло. Моля, актуализирай до най-новата версия.",
|
||||||
"profile_drawer_client_server_up_to_date": "Клиента и сървъра са обновени",
|
"profile_drawer_client_server_up_to_date": "Клиента и сървъра са обновени",
|
||||||
"profile_drawer_github": "GitHub",
|
"profile_drawer_github": "GitHub",
|
||||||
|
"profile_drawer_readonly_mode": "Режима само за четене е активиран. С двоен клик върху картиката-аватар на потребителя ще деактивирате само за четене.",
|
||||||
"profile_drawer_server_out_of_date_major": "Версията на сървъра е остаряла. Моля, актуализирай поне до последната главна версия.",
|
"profile_drawer_server_out_of_date_major": "Версията на сървъра е остаряла. Моля, актуализирай поне до последната главна версия.",
|
||||||
"profile_drawer_server_out_of_date_minor": "Версията на сървъра е остаряла. Моля, актуализирай до последната версия.",
|
"profile_drawer_server_out_of_date_minor": "Версията на сървъра е остаряла. Моля, актуализирай до последната версия.",
|
||||||
"profile_image_of_user": "Профилна снимка на {user}",
|
"profile_image_of_user": "Профилна снимка на {user}",
|
||||||
@@ -1484,12 +1557,15 @@
|
|||||||
"purchase_server_description_2": "Статус на поддръжник",
|
"purchase_server_description_2": "Статус на поддръжник",
|
||||||
"purchase_server_title": "Сървър",
|
"purchase_server_title": "Сървър",
|
||||||
"purchase_settings_server_activated": "Продуктовият ключ на сървъра се управлява от администратора",
|
"purchase_settings_server_activated": "Продуктовият ключ на сървъра се управлява от администратора",
|
||||||
|
"queue_status": "В опашка {count} от {total}",
|
||||||
"rating": "Оценка със звезди",
|
"rating": "Оценка със звезди",
|
||||||
"rating_clear": "Изчисти оценката",
|
"rating_clear": "Изчисти оценката",
|
||||||
"rating_count": "{count, plural, one {# звезда} other {# звезди}}",
|
"rating_count": "{count, plural, one {# звезда} other {# звезди}}",
|
||||||
"rating_description": "Покажи EXIF оценката в панела с информация",
|
"rating_description": "Покажи EXIF оценката в панела с информация",
|
||||||
"reaction_options": "Избор на реакция",
|
"reaction_options": "Избор на реакция",
|
||||||
"read_changelog": "Прочети промените",
|
"read_changelog": "Прочети промените",
|
||||||
|
"readonly_mode_disabled": "Режима само за четене е деактивиран",
|
||||||
|
"readonly_mode_enabled": "Режима само за четене е активиран",
|
||||||
"reassign": "Преназначаване",
|
"reassign": "Преназначаване",
|
||||||
"reassigned_assets_to_existing_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на {name, select, null {съществуващ човек} other {{name}}}",
|
"reassigned_assets_to_existing_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на {name, select, null {съществуващ човек} other {{name}}}",
|
||||||
"reassigned_assets_to_new_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на нов човек",
|
"reassigned_assets_to_new_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на нов човек",
|
||||||
@@ -1512,6 +1588,8 @@
|
|||||||
"refreshing_faces": "Опресняване на лицата",
|
"refreshing_faces": "Опресняване на лицата",
|
||||||
"refreshing_metadata": "Опресняване на метаданните",
|
"refreshing_metadata": "Опресняване на метаданните",
|
||||||
"regenerating_thumbnails": "Пресъздаване на миниатюрите",
|
"regenerating_thumbnails": "Пресъздаване на миниатюрите",
|
||||||
|
"remote": "На сървъра",
|
||||||
|
"remote_assets": "Обекти на сървъра",
|
||||||
"remove": "Премахни",
|
"remove": "Премахни",
|
||||||
"remove_assets_album_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от албума?",
|
"remove_assets_album_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от албума?",
|
||||||
"remove_assets_shared_link_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от този споеделен линк?",
|
"remove_assets_shared_link_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от този споеделен линк?",
|
||||||
@@ -1549,19 +1627,28 @@
|
|||||||
"reset_password": "Нулиране на паролата",
|
"reset_password": "Нулиране на паролата",
|
||||||
"reset_people_visibility": "Нулиране на видимостта на хората",
|
"reset_people_visibility": "Нулиране на видимостта на хората",
|
||||||
"reset_pin_code": "Нулирай PIN кода",
|
"reset_pin_code": "Нулирай PIN кода",
|
||||||
|
"reset_pin_code_description": "Ако сте си забравили ПИН кода, може да се обърнете към администратора на сървъра за да го нулира",
|
||||||
|
"reset_pin_code_success": "Успешно нулиран ПИН код",
|
||||||
|
"reset_pin_code_with_password": "С вашата парола можете винаги да нулирате своя ПИН код",
|
||||||
|
"reset_sqlite": "Нулиране на базата данни SQLite",
|
||||||
|
"reset_sqlite_confirmation": "Наистина ли искате да нулирате базата данни SQLite? Ще трябва да излезете от системата и да се впишете отново за нова синхронизация на данните",
|
||||||
|
"reset_sqlite_success": "Успешно нулиране на базата данни SQLite",
|
||||||
"reset_to_default": "Връщане на фабрични настройки",
|
"reset_to_default": "Връщане на фабрични настройки",
|
||||||
"resolve_duplicates": "Реши дубликатите",
|
"resolve_duplicates": "Реши дубликатите",
|
||||||
"resolved_all_duplicates": "Всички дубликати са решени",
|
"resolved_all_duplicates": "Всички дубликати са решени",
|
||||||
"restore": "Възстановяване",
|
"restore": "Възстановяване",
|
||||||
"restore_all": "Възстанови всички",
|
"restore_all": "Възстанови всички",
|
||||||
|
"restore_trash_action_prompt": "{count} възстановени от коша",
|
||||||
"restore_user": "Възстанови потребител",
|
"restore_user": "Възстанови потребител",
|
||||||
"restored_asset": "Възстановен елемент",
|
"restored_asset": "Възстановен елемент",
|
||||||
"resume": "Продължаване",
|
"resume": "Продължаване",
|
||||||
"retry_upload": "Опитай качването отново",
|
"retry_upload": "Опитай качването отново",
|
||||||
"review_duplicates": "Разгледай дубликатите",
|
"review_duplicates": "Разгледай дубликатите",
|
||||||
|
"review_large_files": "Преглед на големи файлове",
|
||||||
"role": "Роля",
|
"role": "Роля",
|
||||||
"role_editor": "Редактор",
|
"role_editor": "Редактор",
|
||||||
"role_viewer": "Зрител",
|
"role_viewer": "Зрител",
|
||||||
|
"running": "Изпълняване",
|
||||||
"save": "Запази",
|
"save": "Запази",
|
||||||
"save_to_gallery": "Запази в галерията",
|
"save_to_gallery": "Запази в галерията",
|
||||||
"saved_api_key": "Запазен API Key",
|
"saved_api_key": "Запазен API Key",
|
||||||
@@ -1648,6 +1735,7 @@
|
|||||||
"select_user_for_sharing_page_err_album": "Създаването на албум не бе успешно",
|
"select_user_for_sharing_page_err_album": "Създаването на албум не бе успешно",
|
||||||
"selected": "Избрано",
|
"selected": "Избрано",
|
||||||
"selected_count": "{count, plural, other {# избрани}}",
|
"selected_count": "{count, plural, other {# избрани}}",
|
||||||
|
"selected_gps_coordinates": "избрани GPS координати",
|
||||||
"send_message": "Изпратете съобщение",
|
"send_message": "Изпратете съобщение",
|
||||||
"send_welcome_email": "Изпратете имейл за добре дошли",
|
"send_welcome_email": "Изпратете имейл за добре дошли",
|
||||||
"server_endpoint": "Адрес на сървъра",
|
"server_endpoint": "Адрес на сървъра",
|
||||||
@@ -1715,6 +1803,7 @@
|
|||||||
"shared_link_clipboard_copied_massage": "Копирано в клипборда",
|
"shared_link_clipboard_copied_massage": "Копирано в клипборда",
|
||||||
"shared_link_clipboard_text": "Връзка: {link}\nПарола: {password}",
|
"shared_link_clipboard_text": "Връзка: {link}\nПарола: {password}",
|
||||||
"shared_link_create_error": "Грешка при създаване на споделена връзка",
|
"shared_link_create_error": "Грешка при създаване на споделена връзка",
|
||||||
|
"shared_link_custom_url_description": "Достъпете споделения линк с персонализиран URL адрес",
|
||||||
"shared_link_edit_description_hint": "Въведи описание на споделеното",
|
"shared_link_edit_description_hint": "Въведи описание на споделеното",
|
||||||
"shared_link_edit_expire_after_option_day": "1 ден",
|
"shared_link_edit_expire_after_option_day": "1 ден",
|
||||||
"shared_link_edit_expire_after_option_days": "{count} дни",
|
"shared_link_edit_expire_after_option_days": "{count} дни",
|
||||||
@@ -1740,6 +1829,7 @@
|
|||||||
"shared_link_info_chip_metadata": "EXIF",
|
"shared_link_info_chip_metadata": "EXIF",
|
||||||
"shared_link_manage_links": "Управление на споделените връзки",
|
"shared_link_manage_links": "Управление на споделените връзки",
|
||||||
"shared_link_options": "Опции за споделена връзка",
|
"shared_link_options": "Опции за споделена връзка",
|
||||||
|
"shared_link_password_description": "Изискване на парола за достъп до споделения линк",
|
||||||
"shared_links": "Споделени връзки",
|
"shared_links": "Споделени връзки",
|
||||||
"shared_links_description": "Сподели снимки и видеа с линк",
|
"shared_links_description": "Сподели снимки и видеа с линк",
|
||||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# споделени снимки и видеа.}}",
|
"shared_photos_and_videos_count": "{assetCount, plural, other {# споделени снимки и видеа.}}",
|
||||||
@@ -1756,8 +1846,10 @@
|
|||||||
"shift_to_permanent_delete": "Натиснете ⇧, за да изтриете завинаги елемента",
|
"shift_to_permanent_delete": "Натиснете ⇧, за да изтриете завинаги елемента",
|
||||||
"show_album_options": "Показване опции за албум",
|
"show_album_options": "Показване опции за албум",
|
||||||
"show_albums": "Покажи албуми",
|
"show_albums": "Покажи албуми",
|
||||||
|
"show_all_assets": "Покажи всичко",
|
||||||
"show_all_people": "Покажи всички хора",
|
"show_all_people": "Покажи всички хора",
|
||||||
"show_and_hide_people": "Показване и скриване на хора",
|
"show_and_hide_people": "Показване и скриване на хора",
|
||||||
|
"show_assets_without_location": "Покажи обекти без координати",
|
||||||
"show_file_location": "Покажи местоположението на файла",
|
"show_file_location": "Покажи местоположението на файла",
|
||||||
"show_gallery": "Покажи галерия",
|
"show_gallery": "Покажи галерия",
|
||||||
"show_hidden_people": "Показване на скритите хора",
|
"show_hidden_people": "Показване на скритите хора",
|
||||||
@@ -1789,6 +1881,7 @@
|
|||||||
"sort_created": "Дата на създаване",
|
"sort_created": "Дата на създаване",
|
||||||
"sort_items": "Брой елементи",
|
"sort_items": "Брой елементи",
|
||||||
"sort_modified": "Дата на промяна",
|
"sort_modified": "Дата на промяна",
|
||||||
|
"sort_newest": "Най-нови снимки",
|
||||||
"sort_oldest": "Най-старата снимка",
|
"sort_oldest": "Най-старата снимка",
|
||||||
"sort_people_by_similarity": "Сортиране на хора по прилика",
|
"sort_people_by_similarity": "Сортиране на хора по прилика",
|
||||||
"sort_recent": "Най-новата снимка",
|
"sort_recent": "Най-новата снимка",
|
||||||
@@ -1815,6 +1908,7 @@
|
|||||||
"storage_quota": "Квота на хранилището",
|
"storage_quota": "Квота на хранилището",
|
||||||
"storage_usage": "Използвани {used} от {available}",
|
"storage_usage": "Използвани {used} от {available}",
|
||||||
"submit": "Изпращане",
|
"submit": "Изпращане",
|
||||||
|
"success": "Успешно",
|
||||||
"suggestions": "Предложения",
|
"suggestions": "Предложения",
|
||||||
"sunrise_on_the_beach": "Изгрев на плажа",
|
"sunrise_on_the_beach": "Изгрев на плажа",
|
||||||
"support": "Поддръжка",
|
"support": "Поддръжка",
|
||||||
@@ -1824,6 +1918,8 @@
|
|||||||
"sync": "Синхронизиране",
|
"sync": "Синхронизиране",
|
||||||
"sync_albums": "Синхронизиране на албуми",
|
"sync_albums": "Синхронизиране на албуми",
|
||||||
"sync_albums_manual_subtitle": "Синхронизирай всички заредени видеа и снимки в избраните архивни албуми",
|
"sync_albums_manual_subtitle": "Синхронизирай всички заредени видеа и снимки в избраните архивни албуми",
|
||||||
|
"sync_local": "Локална синхронизация",
|
||||||
|
"sync_remote": "Синхронизация със сървъра",
|
||||||
"sync_upload_album_setting_subtitle": "Създавайте и зареждайте снимки и видеа в избрани албуми в Immich",
|
"sync_upload_album_setting_subtitle": "Създавайте и зареждайте снимки и видеа в избрани албуми в Immich",
|
||||||
"tag": "Таг",
|
"tag": "Таг",
|
||||||
"tag_assets": "Тагни елементи",
|
"tag_assets": "Тагни елементи",
|
||||||
@@ -1834,6 +1930,7 @@
|
|||||||
"tag_updated": "Актуализиран етикет: {tag}",
|
"tag_updated": "Актуализиран етикет: {tag}",
|
||||||
"tagged_assets": "Тагнати {count, plural, one {# елемент} other {# елементи}}",
|
"tagged_assets": "Тагнати {count, plural, one {# елемент} other {# елементи}}",
|
||||||
"tags": "Етикет",
|
"tags": "Етикет",
|
||||||
|
"tap_to_run_job": "Докоснете, за да стартирате задачата",
|
||||||
"template": "Шаблон",
|
"template": "Шаблон",
|
||||||
"theme": "Тема",
|
"theme": "Тема",
|
||||||
"theme_selection": "Избор на тема",
|
"theme_selection": "Избор на тема",
|
||||||
@@ -1860,7 +1957,9 @@
|
|||||||
"to_change_password": "Промяна на паролата",
|
"to_change_password": "Промяна на паролата",
|
||||||
"to_favorite": "Любим",
|
"to_favorite": "Любим",
|
||||||
"to_login": "Вписване",
|
"to_login": "Вписване",
|
||||||
|
"to_multi_select": "за избор на няколко",
|
||||||
"to_parent": "Отиди към родителския елемент",
|
"to_parent": "Отиди към родителския елемент",
|
||||||
|
"to_select": "за избор",
|
||||||
"to_trash": "Кошче",
|
"to_trash": "Кошче",
|
||||||
"toggle_settings": "Превключване на настройките",
|
"toggle_settings": "Превключване на настройките",
|
||||||
"total": "Общо",
|
"total": "Общо",
|
||||||
@@ -1910,13 +2009,17 @@
|
|||||||
"unstacked_assets_count": "Разкачени {count, plural, one {# елемент} other {# елементи}}",
|
"unstacked_assets_count": "Разкачени {count, plural, one {# елемент} other {# елементи}}",
|
||||||
"untagged": "Немаркирани",
|
"untagged": "Немаркирани",
|
||||||
"up_next": "Следващ",
|
"up_next": "Следващ",
|
||||||
|
"update_location_action_prompt": "Обнови координатите на {count} избрани обекта с:",
|
||||||
"updated_at": "Обновено",
|
"updated_at": "Обновено",
|
||||||
"updated_password": "Паролата е актуализирана",
|
"updated_password": "Паролата е актуализирана",
|
||||||
"upload": "Качване",
|
"upload": "Качване",
|
||||||
|
"upload_action_prompt": "{count} на опашка за качване",
|
||||||
"upload_concurrency": "Успоредни качвания",
|
"upload_concurrency": "Успоредни качвания",
|
||||||
|
"upload_details": "Детайли за качването",
|
||||||
"upload_dialog_info": "Искате ли да архивирате на сървъра избраните обекти?",
|
"upload_dialog_info": "Искате ли да архивирате на сървъра избраните обекти?",
|
||||||
"upload_dialog_title": "Качи обект",
|
"upload_dialog_title": "Качи обект",
|
||||||
"upload_errors": "Качването е завъшено с {count, plural, one {# грешка} other {# грешки}}, обновете страницата за да видите новите елементи.",
|
"upload_errors": "Качването е завъшено с {count, plural, one {# грешка} other {# грешки}}, обновете страницата за да видите новите елементи.",
|
||||||
|
"upload_finished": "Качването завърши",
|
||||||
"upload_progress": "Остават {remaining, number} - Обработени {processed, number}/{total, number}",
|
"upload_progress": "Остават {remaining, number} - Обработени {processed, number}/{total, number}",
|
||||||
"upload_skipped_duplicates": "Прескочени {count, plural, one {# дублиран елемент} other {# дублирани елементи}}",
|
"upload_skipped_duplicates": "Прескочени {count, plural, one {# дублиран елемент} other {# дублирани елементи}}",
|
||||||
"upload_status_duplicates": "Дубликати",
|
"upload_status_duplicates": "Дубликати",
|
||||||
@@ -1925,11 +2028,13 @@
|
|||||||
"upload_success": "Качването е успешно, опреснете страницата, за да видите новите файлове.",
|
"upload_success": "Качването е успешно, опреснете страницата, за да видите новите файлове.",
|
||||||
"upload_to_immich": "Казване в Immich ({count})",
|
"upload_to_immich": "Казване в Immich ({count})",
|
||||||
"uploading": "Качваме",
|
"uploading": "Качваме",
|
||||||
|
"uploading_media": "Качване на медийни файлове",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"usage": "Потребление",
|
"usage": "Потребление",
|
||||||
"use_biometric": "Използвай биометрия",
|
"use_biometric": "Използвай биометрия",
|
||||||
"use_current_connection": "използвай текущата връзка",
|
"use_current_connection": "използвай текущата връзка",
|
||||||
"use_custom_date_range": "Използвайте собствен диапазон от дати вместо това",
|
"use_custom_date_range": "Използвайте собствен диапазон от дати вместо това",
|
||||||
|
"use_this_location": "Избери това място",
|
||||||
"user": "Потребител",
|
"user": "Потребител",
|
||||||
"user_has_been_deleted": "Този потребител е премахнат.",
|
"user_has_been_deleted": "Този потребител е премахнат.",
|
||||||
"user_id": "Потребител ИД",
|
"user_id": "Потребител ИД",
|
||||||
@@ -1945,6 +2050,7 @@
|
|||||||
"user_usage_stats_description": "Преглед на статистиката за използването на акаунта",
|
"user_usage_stats_description": "Преглед на статистиката за използването на акаунта",
|
||||||
"username": "Потребителско име",
|
"username": "Потребителско име",
|
||||||
"users": "Потребители",
|
"users": "Потребители",
|
||||||
|
"users_added_to_album_count": "{count, plural, one {Добавен е # потребител} other {Добавени са # потребителя}} на албума",
|
||||||
"utilities": "Инструменти",
|
"utilities": "Инструменти",
|
||||||
"validate": "Валидиране",
|
"validate": "Валидиране",
|
||||||
"validate_endpoint_error": "Моля, въведи правилен URL",
|
"validate_endpoint_error": "Моля, въведи правилен URL",
|
||||||
@@ -1963,6 +2069,7 @@
|
|||||||
"view_album": "Разгледай албума",
|
"view_album": "Разгледай албума",
|
||||||
"view_all": "Преглед на всички",
|
"view_all": "Преглед на всички",
|
||||||
"view_all_users": "Преглед на всички потребители",
|
"view_all_users": "Преглед на всички потребители",
|
||||||
|
"view_details": "Подробности за изгледа",
|
||||||
"view_in_timeline": "Покажи във времева линия",
|
"view_in_timeline": "Покажи във времева линия",
|
||||||
"view_link": "Преглед на връзката",
|
"view_link": "Преглед на връзката",
|
||||||
"view_links": "Преглед на връзките",
|
"view_links": "Преглед на връзките",
|
||||||
|
|||||||
@@ -14,5 +14,10 @@
|
|||||||
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
|
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
|
||||||
"add_import_path": "Putem wan pat blo import",
|
"add_import_path": "Putem wan pat blo import",
|
||||||
"add_location": "Putem wan place blo hem",
|
"add_location": "Putem wan place blo hem",
|
||||||
"add_more_users": "Putem mor man"
|
"add_more_users": "Putem mor man",
|
||||||
|
"readonly_mode_enabled": "Mod blo yu no save janjem i on",
|
||||||
|
"reassigned_assets_to_new_person": "Janjem{count, plural, one {# asset} other {# assets}} blo nu man",
|
||||||
|
"reassing_hint": "janjem ol sumtin yu bin joos i go blo wan man",
|
||||||
|
"recent-albums": "album i no old tu mas",
|
||||||
|
"recent_searches": "lukabout wea i no old tu mas"
|
||||||
}
|
}
|
||||||
|
|||||||
42
i18n/bn.json
@@ -14,6 +14,7 @@
|
|||||||
"add_a_location": "একটি অবস্থান যোগ করুন",
|
"add_a_location": "একটি অবস্থান যোগ করুন",
|
||||||
"add_a_name": "একটি নাম যোগ করুন",
|
"add_a_name": "একটি নাম যোগ করুন",
|
||||||
"add_a_title": "একটি শিরোনাম যোগ করুন",
|
"add_a_title": "একটি শিরোনাম যোগ করুন",
|
||||||
|
"add_birthday": "একটি জন্মদিন যোগ করুন",
|
||||||
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
|
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
|
||||||
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
|
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
|
||||||
"add_import_path": "ইমপোর্ট করার পাথ যুক্ত করুন",
|
"add_import_path": "ইমপোর্ট করার পাথ যুক্ত করুন",
|
||||||
@@ -27,6 +28,9 @@
|
|||||||
"add_to_album": "এলবাম এ যোগ করুন",
|
"add_to_album": "এলবাম এ যোগ করুন",
|
||||||
"add_to_album_bottom_sheet_added": "{album} এ যোগ করা হয়েছে",
|
"add_to_album_bottom_sheet_added": "{album} এ যোগ করা হয়েছে",
|
||||||
"add_to_album_bottom_sheet_already_exists": "{album} এ আগে থেকেই আছে",
|
"add_to_album_bottom_sheet_already_exists": "{album} এ আগে থেকেই আছে",
|
||||||
|
"add_to_album_toggle": "{album} - এর নির্বাচন পরিবর্তন করুন",
|
||||||
|
"add_to_albums": "অ্যালবামে যোগ করুন",
|
||||||
|
"add_to_albums_count": "অ্যালবামে যোগ করুন ({count})",
|
||||||
"add_to_shared_album": "শেয়ার করা অ্যালবামে যোগ করুন",
|
"add_to_shared_album": "শেয়ার করা অ্যালবামে যোগ করুন",
|
||||||
"add_url": "লিঙ্ক যোগ করুন",
|
"add_url": "লিঙ্ক যোগ করুন",
|
||||||
"added_to_archive": "আর্কাইভ এ যোগ করা হয়েছে",
|
"added_to_archive": "আর্কাইভ এ যোগ করা হয়েছে",
|
||||||
@@ -44,6 +48,13 @@
|
|||||||
"backup_database": "ডাটাবেস ডাম্প তৈরি করুন",
|
"backup_database": "ডাটাবেস ডাম্প তৈরি করুন",
|
||||||
"backup_database_enable_description": "ডাটাবেস ডাম্প সক্রিয় করুন",
|
"backup_database_enable_description": "ডাটাবেস ডাম্প সক্রিয় করুন",
|
||||||
"backup_keep_last_amount": "আগের ডাম্পের পরিমাণ রাখা হবে",
|
"backup_keep_last_amount": "আগের ডাম্পের পরিমাণ রাখা হবে",
|
||||||
|
"backup_onboarding_1_description": "অফসাইট কপি ক্লাউডে অথবা অন্য কোনও ভৌত স্থানে।",
|
||||||
|
"backup_onboarding_2_description": "বিভিন্ন ডিভাইসে স্থানীয় কপি। এর মধ্যে রয়েছে প্রধান ফাইল এবং স্থানীয়ভাবে সেই ফাইলগুলির ব্যাকআপ।",
|
||||||
|
"backup_onboarding_3_description": "মূল ফাইল সহ আপনার ডেটার মোট কপি। এর মধ্যে রয়েছে ১টি অফসাইট কপি এবং ২টি স্থানীয় কপি।",
|
||||||
|
"backup_onboarding_description": "আপনার ডেটা সুরক্ষিত রাখার জন্য একটি <backblaze-link>3-2-1 ব্যাকআপ কৌশল</backblaze-link> সুপারিশ করা হয়। একটি বিস্তৃত ব্যাকআপ সমাধানের জন্য আপনার আপলোড করা ফটো/ভিডিওগুলির কপি এবং Immich ডাটাবেস রাখা উচিত।",
|
||||||
|
"backup_onboarding_footer": "Immich এর ব্যাকআপ নেওয়ার বিষয়ে আরও তথ্যের জন্য, অনুগ্রহ করে <link>ডকুমেন্টেশন</link> দেখুন।",
|
||||||
|
"backup_onboarding_parts_title": "৩-২-১ ব্যাকআপের মধ্যে রয়েছে:",
|
||||||
|
"backup_onboarding_title": "ব্যাকআপ",
|
||||||
"backup_settings": "ডাটাবেস ডাম্প সেটিংস",
|
"backup_settings": "ডাটাবেস ডাম্প সেটিংস",
|
||||||
"backup_settings_description": "ডাটাবেস ডাম্প সেটিংস পরিচালনা করুন।",
|
"backup_settings_description": "ডাটাবেস ডাম্প সেটিংস পরিচালনা করুন।",
|
||||||
"cleared_jobs": "{job} এর জন্য jobs খালি করা হয়েছে",
|
"cleared_jobs": "{job} এর জন্য jobs খালি করা হয়েছে",
|
||||||
@@ -64,7 +75,7 @@
|
|||||||
"external_library_management": "বহিরাগত গ্রন্থাগার ব্যবস্থাপনা",
|
"external_library_management": "বহিরাগত গ্রন্থাগার ব্যবস্থাপনা",
|
||||||
"face_detection": "মুখ সনাক্তকরণ",
|
"face_detection": "মুখ সনাক্তকরণ",
|
||||||
"face_detection_description": "মেশিন লার্নিং ব্যবহার করে অ্যাসেটে থাকা মুখ/চেহারা গুলি সনাক্ত করুন। ভিডিও গুলির জন্য, শুধুমাত্র থাম্বনেইল বিবেচনা করা হয়। \"রিফ্রেশ\" (পুনরায়) সমস্ত অ্যাসেট প্রক্রিয়া করে। \"রিসেট\" করার মাধ্যমে অতিরিক্তভাবে সমস্ত বর্তমান মুখের ডেটা সাফ করে। \"অনুপস্থিত\" অ্যাসেটগুলিকে সারিবদ্ধ করে যা এখনও প্রক্রিয়া করা হয়নি। সনাক্ত করা মুখগুলিকে ফেসিয়াল রিকগনিশনের জন্য সারিবদ্ধ করা হবে, ফেসিয়াল ডিটেকশন সম্পূর্ণ হওয়ার পরে, বিদ্যমান বা নতুন ব্যক্তিদের মধ্যে গোষ্ঠীবদ্ধ করে।",
|
"face_detection_description": "মেশিন লার্নিং ব্যবহার করে অ্যাসেটে থাকা মুখ/চেহারা গুলি সনাক্ত করুন। ভিডিও গুলির জন্য, শুধুমাত্র থাম্বনেইল বিবেচনা করা হয়। \"রিফ্রেশ\" (পুনরায়) সমস্ত অ্যাসেট প্রক্রিয়া করে। \"রিসেট\" করার মাধ্যমে অতিরিক্তভাবে সমস্ত বর্তমান মুখের ডেটা সাফ করে। \"অনুপস্থিত\" অ্যাসেটগুলিকে সারিবদ্ধ করে যা এখনও প্রক্রিয়া করা হয়নি। সনাক্ত করা মুখগুলিকে ফেসিয়াল রিকগনিশনের জন্য সারিবদ্ধ করা হবে, ফেসিয়াল ডিটেকশন সম্পূর্ণ হওয়ার পরে, বিদ্যমান বা নতুন ব্যক্তিদের মধ্যে গোষ্ঠীবদ্ধ করে।",
|
||||||
"facial_recognition_job_description": "শনাক্ত করা মুখগুলিকে মানুষের মধ্যে গোষ্ঠীভুক্ত করুন। মুখ সনাক্তকরণ সম্পূর্ণ হওয়ার পরে এই ধাপটি চলে। \"রিসেট\" (পুনরায়) সমস্ত মুখকে ক্লাস্টার করে। \"অনুপস্থিত\" মুখগুলিকে সারিতে রাখে যেখানে কোনও ব্যক্তিকে বরাদ্দ করা হয়নি।",
|
"facial_recognition_job_description": "শনাক্ত করা মুখগুলিকে মানুষের মধ্যে গোষ্ঠীভুক্ত/গ্রুপ করুন। মুখ সনাক্তকরণ সম্পূর্ণ হওয়ার পরে এই ধাপটি চলে। \"রিসেট\" (পুনরায়) সমস্ত মুখকে ক্লাস্টার করে। \"অনুপস্থিত/মিসিং\" মুখগুলিকে সারিতে রাখে যেগুলো কোনও ব্যক্তিকে এসাইন/বরাদ্দ করা হয়নি।",
|
||||||
"failed_job_command": "কমান্ড {command} কাজের জন্য ব্যর্থ হয়েছে: {job}",
|
"failed_job_command": "কমান্ড {command} কাজের জন্য ব্যর্থ হয়েছে: {job}",
|
||||||
"force_delete_user_warning": "সতর্কতা: এটি ব্যবহারকারী এবং সমস্ত সম্পদ অবিলম্বে সরিয়ে ফেলবে। এটি পূর্বাবস্থায় ফেরানো যাবে না এবং ফাইলগুলি পুনরুদ্ধার করা যাবে না।",
|
"force_delete_user_warning": "সতর্কতা: এটি ব্যবহারকারী এবং সমস্ত সম্পদ অবিলম্বে সরিয়ে ফেলবে। এটি পূর্বাবস্থায় ফেরানো যাবে না এবং ফাইলগুলি পুনরুদ্ধার করা যাবে না।",
|
||||||
"image_format": "ফরম্যাট",
|
"image_format": "ফরম্যাট",
|
||||||
@@ -75,9 +86,9 @@
|
|||||||
"image_fullsize_quality_description": "পূর্ণ-আকারের ছবির মান ১-১০০। উচ্চতর হলে ভালো, কিন্তু আরও বড় ফাইল তৈরি হয়।",
|
"image_fullsize_quality_description": "পূর্ণ-আকারের ছবির মান ১-১০০। উচ্চতর হলে ভালো, কিন্তু আরও বড় ফাইল তৈরি হয়।",
|
||||||
"image_fullsize_title": "পূর্ণ-আকারের চিত্র সেটিংস",
|
"image_fullsize_title": "পূর্ণ-আকারের চিত্র সেটিংস",
|
||||||
"image_prefer_embedded_preview": "এম্বেড করা প্রিভিউ পছন্দ করুন",
|
"image_prefer_embedded_preview": "এম্বেড করা প্রিভিউ পছন্দ করুন",
|
||||||
"image_prefer_embedded_preview_setting_description": "ছবি প্রক্রিয়াকরণের জন্য এবং যখনই উপলব্ধ থাকবে তখন RAW ফটোতে এমবেডেড প্রিভিউ ব্যবহার করুন। এটি কিছু ছবির জন্য আরও সঠিক রঙ তৈরি করতে পারে, তবে প্রিভিউয়ের মান ক্যামেরা-নির্ভর এবং ছবিতে আরও কম্প্রেশন আর্টিফ্যাক্ট থাকতে পারে।",
|
"image_prefer_embedded_preview_setting_description": "যদি পাওয়া যায়, RAW ছবির ভেতরে থাকা প্রিভিউ ব্যবহার করুন। এতে কিছু ছবির রঙ আরও সঠিক দেখা যেতে পারে, তবে মান ক্যামেরার ওপর নির্ভর করে এবং ছবিতে বাড়তি কমপ্রেশন আর্টিফ্যাক্ট দেখা যেতে পারে।",
|
||||||
"image_prefer_wide_gamut": "প্রশস্ত পরিসর পছন্দ করুন",
|
"image_prefer_wide_gamut": "প্রশস্ত পরিসর পছন্দ করুন",
|
||||||
"image_prefer_wide_gamut_setting_description": "থাম্বনেইলের জন্য ডিসপ্লে P3 ব্যবহার করুন। এটি প্রশস্ত রঙের স্থান সহ ছবির প্রাণবন্ততা আরও ভালভাবে সংরক্ষণ করে, তবে পুরানো ব্রাউজার সংস্করণ সহ পুরানো ডিভাইসগুলিতে ছবিগুলি ভিন্নভাবে প্রদর্শিত হতে পারে। রঙের পরিবর্তন এড়াতে sRGB ছবিগুলিকে sRGB হিসাবে রাখা হয়।",
|
"image_prefer_wide_gamut_setting_description": "থাম্বনেইলের জন্য Display P3 ব্যবহার করুন। এটি ওয়াইড কালারস্পেস ছবির উজ্জ্বলতা ও প্রাণবন্ত রঙ ভালোভাবে ধরে রাখে, তবে পুরনো ডিভাইস বা ব্রাউজারে ছবিগুলো ভিন্নভাবে দেখা যেতে পারে। sRGB ছবিগুলো রঙের পরিবর্তন এড়াতে sRGB হিসেবেই রাখা হবে।",
|
||||||
"image_preview_description": "স্ট্রিপড মেটাডেটা সহ মাঝারি আকারের ছবি, একটি একক সম্পদ দেখার সময় এবং মেশিন লার্নিংয়ের জন্য ব্যবহৃত হয়",
|
"image_preview_description": "স্ট্রিপড মেটাডেটা সহ মাঝারি আকারের ছবি, একটি একক সম্পদ দেখার সময় এবং মেশিন লার্নিংয়ের জন্য ব্যবহৃত হয়",
|
||||||
"image_preview_quality_description": "১-১০০ এর মধ্যে প্রিভিউ কোয়ালিটি। বেশি হলে ভালো, কিন্তু বড় ফাইল তৈরি হয় এবং অ্যাপের প্রতিক্রিয়াশীলতা কমাতে পারে। কম মান সেট করলে মেশিন লার্নিং কোয়ালিটির উপর প্রভাব পড়তে পারে।",
|
"image_preview_quality_description": "১-১০০ এর মধ্যে প্রিভিউ কোয়ালিটি। বেশি হলে ভালো, কিন্তু বড় ফাইল তৈরি হয় এবং অ্যাপের প্রতিক্রিয়াশীলতা কমাতে পারে। কম মান সেট করলে মেশিন লার্নিং কোয়ালিটির উপর প্রভাব পড়তে পারে।",
|
||||||
"image_preview_title": "প্রিভিউ সেটিংস",
|
"image_preview_title": "প্রিভিউ সেটিংস",
|
||||||
@@ -91,9 +102,30 @@
|
|||||||
"image_thumbnail_title": "থাম্বনেল সেটিংস",
|
"image_thumbnail_title": "থাম্বনেল সেটিংস",
|
||||||
"job_concurrency": "{job} কনকারেন্সি",
|
"job_concurrency": "{job} কনকারেন্সি",
|
||||||
"job_created": "Job তৈরি হয়েছে",
|
"job_created": "Job তৈরি হয়েছে",
|
||||||
"job_not_concurrency_safe": "এই কাজটি সমকালীন-নিরাপদ নয়।",
|
"job_not_concurrency_safe": "এই কাজটি সমান্তরালভাবে চালানো নিরাপদ নয়",
|
||||||
"job_settings": "কাজের সেটিংস",
|
"job_settings": "কাজের সেটিংস",
|
||||||
"job_settings_description": "কাজের সমান্তরালতা পরিচালনা করুন",
|
"job_settings_description": "কাজের সমান্তরালতা পরিচালনা করুন",
|
||||||
"job_status": "চাকরির অবস্থা"
|
"job_status": "চাকরির অবস্থা",
|
||||||
|
"jobs_delayed": "{jobCount, plural, other {# বিলম্বিত}}",
|
||||||
|
"jobs_failed": "{jobCount, plural, other {# ব্যর্থ}}",
|
||||||
|
"library_created": "লাইব্রেরি তৈরি করা হয়েছেঃ {library}",
|
||||||
|
"library_deleted": "লাইব্রেরি মুছে ফেলা হয়েছে",
|
||||||
|
"library_import_path_description": "ইম্পোর্ট/যোগ করার জন্য একটি ফোল্ডার নির্দিষ্ট করুন। সাবফোল্ডার সহ এই ফোল্ডারটি ছবি এবং ভিডিওর জন্য স্ক্যান করা হবে।",
|
||||||
|
"library_scanning": "পর্যায়ক্রমিক স্ক্যানিং",
|
||||||
|
"library_scanning_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং কনফিগার করুন",
|
||||||
|
"library_scanning_enable_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং সক্ষম করুন",
|
||||||
|
"library_settings": "বহিরাগত লাইব্রেরি",
|
||||||
|
"library_settings_description": "বহিরাগত লাইব্রেরি সেটিংস পরিচালনা করুন",
|
||||||
|
"library_tasks_description": "নতুন এবং/অথবা পরিবর্তিত সম্পদের জন্য বহিরাগত লাইব্রেরি স্ক্যান করুন",
|
||||||
|
"library_watching_enable_description": "ফাইল পরিবর্তনের জন্য বহিরাগত লাইব্রেরিগুলি দেখুন",
|
||||||
|
"library_watching_settings": "লাইব্রেরি দেখা (পরীক্ষামূলক)",
|
||||||
|
"library_watching_settings_description": "পরিবর্তিত ফাইলগুলির জন্য স্বয়ংক্রিয়ভাবে নজর রাখুন",
|
||||||
|
"logging_enable_description": "লগিং এনাবল/সক্ষম করুন",
|
||||||
|
"logging_level_description": "সক্রিয় থাকাকালীন, কোন লগ স্তর ব্যবহার করতে হবে।",
|
||||||
|
"logging_settings": "লগিং",
|
||||||
|
"machine_learning_clip_model": "CLIP মডেল",
|
||||||
|
"machine_learning_clip_model_description": "<link>এখানে</link> তালিকাভুক্ত একটি CLIP মডেলের নাম। মনে রাখবেন, মডেল পরিবর্তনের পর সব ছবির জন্য অবশ্যই ‘Smart Search’ কাজটি আবার চালাতে হবে।",
|
||||||
|
"machine_learning_duplicate_detection": "পুনরাবৃত্তি সনাক্তকরণ",
|
||||||
|
"machine_learning_duplicate_detection_enabled": "পুনরাবৃত্তি শনাক্তকরণ চালু করুন"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
145
i18n/ca.json
@@ -2,7 +2,7 @@
|
|||||||
"about": "Quant a",
|
"about": "Quant a",
|
||||||
"account": "Compte",
|
"account": "Compte",
|
||||||
"account_settings": "Configuració del compte",
|
"account_settings": "Configuració del compte",
|
||||||
"acknowledge": "D'acord",
|
"acknowledge": "Base de coneixement",
|
||||||
"action": "Acció",
|
"action": "Acció",
|
||||||
"action_common_update": "Actualitzar",
|
"action_common_update": "Actualitzar",
|
||||||
"actions": "Accions",
|
"actions": "Accions",
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"add_a_location": "Afegiu una ubicació",
|
"add_a_location": "Afegiu una ubicació",
|
||||||
"add_a_name": "Afegir un nom",
|
"add_a_name": "Afegir un nom",
|
||||||
"add_a_title": "Afegir un títol",
|
"add_a_title": "Afegir un títol",
|
||||||
|
"add_birthday": "Afegeix la data de naixement",
|
||||||
"add_endpoint": "afegir endpoint",
|
"add_endpoint": "afegir endpoint",
|
||||||
"add_exclusion_pattern": "Afegir un patró d'exclusió",
|
"add_exclusion_pattern": "Afegir un patró d'exclusió",
|
||||||
"add_import_path": "Afegir una ruta d'importació",
|
"add_import_path": "Afegir una ruta d'importació",
|
||||||
@@ -27,6 +28,9 @@
|
|||||||
"add_to_album": "Afegir a un l'àlbum",
|
"add_to_album": "Afegir a un l'àlbum",
|
||||||
"add_to_album_bottom_sheet_added": "Afegit a {album}",
|
"add_to_album_bottom_sheet_added": "Afegit a {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Ja està a {album}",
|
"add_to_album_bottom_sheet_already_exists": "Ja està a {album}",
|
||||||
|
"add_to_album_toggle": "Commutar selecció de {album}",
|
||||||
|
"add_to_albums": "Afegir als àlbums",
|
||||||
|
"add_to_albums_count": "Afegir als àlbums ({count})",
|
||||||
"add_to_shared_album": "Afegir a un àlbum compartit",
|
"add_to_shared_album": "Afegir a un àlbum compartit",
|
||||||
"add_url": "Afegir URL",
|
"add_url": "Afegir URL",
|
||||||
"added_to_archive": "Afegit als arxivats",
|
"added_to_archive": "Afegit als arxivats",
|
||||||
@@ -44,6 +48,13 @@
|
|||||||
"backup_database": "Fer un bolcat de la base de dades",
|
"backup_database": "Fer un bolcat de la base de dades",
|
||||||
"backup_database_enable_description": "Habilitar bolcat de la base de dades",
|
"backup_database_enable_description": "Habilitar bolcat de la base de dades",
|
||||||
"backup_keep_last_amount": "Quantitat de bolcats anteriors per conservar",
|
"backup_keep_last_amount": "Quantitat de bolcats anteriors per conservar",
|
||||||
|
"backup_onboarding_1_description": "còpia externa al núvol o en una altra ubicació física.",
|
||||||
|
"backup_onboarding_2_description": "còpies locals en diferents dispositius. Això inclou els fitxers principals i una còpia de seguretat d'aquests fitxers localment.",
|
||||||
|
"backup_onboarding_3_description": "còpies totals de les vostres dades, inclosos els fitxers originals. Això inclou 1 còpia externa i 2 còpies locals.",
|
||||||
|
"backup_onboarding_description": "Es recomana una <backblaze-link>estratègia de còpia de seguretat 3-2-1</backblaze-link> per protegir les vostres dades. Hauríeu de conservar còpies de les vostres fotos/vídeos penjats, així com de la base de dades Immich per obtenir una solució de còpia de seguretat completa.",
|
||||||
|
"backup_onboarding_footer": "Per obtenir més informació sobre com fer còpies de seguretat d'Immich, consulteu la <link>documentation</link>.",
|
||||||
|
"backup_onboarding_parts_title": "Una còpia de seguretat 3-2-1 inclou:",
|
||||||
|
"backup_onboarding_title": "Còpies de seguretat",
|
||||||
"backup_settings": "Configuració dels bolcats",
|
"backup_settings": "Configuració dels bolcats",
|
||||||
"backup_settings_description": "Gestionar la configuració de bolcats de la base de dades. Nota: els treballs no es monitoritzen ni es notifiquen els errors.",
|
"backup_settings_description": "Gestionar la configuració de bolcats de la base de dades. Nota: els treballs no es monitoritzen ni es notifiquen els errors.",
|
||||||
"cleared_jobs": "Tasques esborrades per a: {job}",
|
"cleared_jobs": "Tasques esborrades per a: {job}",
|
||||||
@@ -166,10 +177,20 @@
|
|||||||
"metadata_settings_description": "Administrar la configuració de les metadades",
|
"metadata_settings_description": "Administrar la configuració de les metadades",
|
||||||
"migration_job": "Migració",
|
"migration_job": "Migració",
|
||||||
"migration_job_description": "Migra les miniatures d'elements i cares cap a la nova estructura de carpetes",
|
"migration_job_description": "Migra les miniatures d'elements i cares cap a la nova estructura de carpetes",
|
||||||
|
"nightly_tasks_cluster_faces_setting_description": "Executar el reconeixement facial en cares recentment detectades",
|
||||||
"nightly_tasks_cluster_new_faces_setting": "Agrupa cares noves",
|
"nightly_tasks_cluster_new_faces_setting": "Agrupa cares noves",
|
||||||
"nightly_tasks_database_cleanup_setting": "Tasques de neteja de la base de dades",
|
"nightly_tasks_database_cleanup_setting": "Tasques de neteja de la base de dades",
|
||||||
"nightly_tasks_database_cleanup_setting_description": "Netegeu les dades antigues i caducades de la base de dades",
|
"nightly_tasks_database_cleanup_setting_description": "Netegeu les dades antigues i caducades de la base de dades",
|
||||||
|
"nightly_tasks_generate_memories_setting": "Generar memòries",
|
||||||
|
"nightly_tasks_generate_memories_setting_description": "Crear nous records a partir de les fotos penjades",
|
||||||
"nightly_tasks_missing_thumbnails_setting": "Generar les miniatures restants",
|
"nightly_tasks_missing_thumbnails_setting": "Generar les miniatures restants",
|
||||||
|
"nightly_tasks_missing_thumbnails_setting_description": "Posar en cua les fotos penjades sense miniatures per a la generació de la seva miniatura",
|
||||||
|
"nightly_tasks_settings": "Configuració de les tasques nocturnes",
|
||||||
|
"nightly_tasks_settings_description": "Gestionar les tasques nocturnes",
|
||||||
|
"nightly_tasks_start_time_setting": "Hora d'inici",
|
||||||
|
"nightly_tasks_start_time_setting_description": "Hora en què el servidor comença a executar les tasques nocturnes",
|
||||||
|
"nightly_tasks_sync_quota_usage_setting": "Sincronitzar l'ús de la quota",
|
||||||
|
"nightly_tasks_sync_quota_usage_setting_description": "Actualitzar la quota d'emmagatzematge de l'usuari segons l'ús actual",
|
||||||
"no_paths_added": "No s'ha afegit cap ruta",
|
"no_paths_added": "No s'ha afegit cap ruta",
|
||||||
"no_pattern_added": "Cap patró aplicat",
|
"no_pattern_added": "Cap patró aplicat",
|
||||||
"note_apply_storage_label_previous_assets": "Nota: Per aplicar l'etiquetatge d'emmagatzematge a elements pujats prèviament, executeu la",
|
"note_apply_storage_label_previous_assets": "Nota: Per aplicar l'etiquetatge d'emmagatzematge a elements pujats prèviament, executeu la",
|
||||||
@@ -337,6 +358,9 @@
|
|||||||
"trash_number_of_days_description": "Nombre de dies per mantenir els recursos a la paperera abans de suprimir-los permanentment",
|
"trash_number_of_days_description": "Nombre de dies per mantenir els recursos a la paperera abans de suprimir-los permanentment",
|
||||||
"trash_settings": "Configuració de la paperera",
|
"trash_settings": "Configuració de la paperera",
|
||||||
"trash_settings_description": "Gestiona la configuració de la paperera",
|
"trash_settings_description": "Gestiona la configuració de la paperera",
|
||||||
|
"unlink_all_oauth_accounts": "Desvincula tots els comptes d'OAuth",
|
||||||
|
"unlink_all_oauth_accounts_description": "Recorda desvincular tots els comptes d'OAuth abans de migrar a un proveïdor nou.",
|
||||||
|
"unlink_all_oauth_accounts_prompt": "Estàs segur que vols desvincular tots els comptes d'OAuth? Això restablirà l'identificador d'OAuth per a cada usuari i no es pot tornar enrere.",
|
||||||
"user_cleanup_job": "Neteja d'usuari",
|
"user_cleanup_job": "Neteja d'usuari",
|
||||||
"user_delete_delay": "El compte i els recursos de <b>{user}</b> es programaran per a la supressió permanent en {delay, plural, one {# dia} other {# dies}}.",
|
"user_delete_delay": "El compte i els recursos de <b>{user}</b> es programaran per a la supressió permanent en {delay, plural, one {# dia} other {# dies}}.",
|
||||||
"user_delete_delay_settings": "Retard de la supressió",
|
"user_delete_delay_settings": "Retard de la supressió",
|
||||||
@@ -363,6 +387,8 @@
|
|||||||
"admin_password": "Contrasenya de l'administrador",
|
"admin_password": "Contrasenya de l'administrador",
|
||||||
"administration": "Administració",
|
"administration": "Administració",
|
||||||
"advanced": "Avançat",
|
"advanced": "Avançat",
|
||||||
|
"advanced_settings_beta_timeline_subtitle": "Prova la nova experiència de l'aplicació",
|
||||||
|
"advanced_settings_beta_timeline_title": "Cronologia beta",
|
||||||
"advanced_settings_enable_alternate_media_filter_subtitle": "Feu servir aquesta opció per filtrar els continguts multimèdia durant la sincronització segons criteris alternatius. Només proveu-ho si teniu problemes amb l'aplicació per detectar tots els àlbums.",
|
"advanced_settings_enable_alternate_media_filter_subtitle": "Feu servir aquesta opció per filtrar els continguts multimèdia durant la sincronització segons criteris alternatius. Només proveu-ho si teniu problemes amb l'aplicació per detectar tots els àlbums.",
|
||||||
"advanced_settings_enable_alternate_media_filter_title": "Utilitza el filtre de sincronització d'àlbums de dispositius alternatius",
|
"advanced_settings_enable_alternate_media_filter_title": "Utilitza el filtre de sincronització d'àlbums de dispositius alternatius",
|
||||||
"advanced_settings_log_level_title": "Nivell de registre: {level}",
|
"advanced_settings_log_level_title": "Nivell de registre: {level}",
|
||||||
@@ -370,6 +396,8 @@
|
|||||||
"advanced_settings_prefer_remote_title": "Prefereix imatges remotes",
|
"advanced_settings_prefer_remote_title": "Prefereix imatges remotes",
|
||||||
"advanced_settings_proxy_headers_subtitle": "Definiu les capçaleres de proxy que Immich per enviar amb cada sol·licitud de xarxa",
|
"advanced_settings_proxy_headers_subtitle": "Definiu les capçaleres de proxy que Immich per enviar amb cada sol·licitud de xarxa",
|
||||||
"advanced_settings_proxy_headers_title": "Capçaleres de proxy",
|
"advanced_settings_proxy_headers_title": "Capçaleres de proxy",
|
||||||
|
"advanced_settings_readonly_mode_subtitle": "Habilita el només de lectura mode on les fotos poden ser només vist, a coses els agrada seleccionant imatges múltiples, compartint, càsting, elimina és tot discapacitat. Habilita/Desactiva només de lectura via avatar d'usuari des de la pantalla major",
|
||||||
|
"advanced_settings_readonly_mode_title": "Mode de només lectura",
|
||||||
"advanced_settings_self_signed_ssl_subtitle": "Omet la verificació del certificat SSL del servidor. Requerit per a certificats autosignats.",
|
"advanced_settings_self_signed_ssl_subtitle": "Omet la verificació del certificat SSL del servidor. Requerit per a certificats autosignats.",
|
||||||
"advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats",
|
"advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats",
|
||||||
"advanced_settings_sync_remote_deletions_subtitle": "Suprimeix o restaura automàticament un actiu en aquest dispositiu quan es realitzi aquesta acció al web",
|
"advanced_settings_sync_remote_deletions_subtitle": "Suprimeix o restaura automàticament un actiu en aquest dispositiu quan es realitzi aquesta acció al web",
|
||||||
@@ -385,6 +413,7 @@
|
|||||||
"album_cover_updated": "Portada de l'àlbum actualitzada",
|
"album_cover_updated": "Portada de l'àlbum actualitzada",
|
||||||
"album_delete_confirmation": "Esteu segur que voleu suprimir l'àlbum {album}?",
|
"album_delete_confirmation": "Esteu segur que voleu suprimir l'àlbum {album}?",
|
||||||
"album_delete_confirmation_description": "Si aquest àlbum es comparteix, els altres usuaris ja no podran accedir-hi.",
|
"album_delete_confirmation_description": "Si aquest àlbum es comparteix, els altres usuaris ja no podran accedir-hi.",
|
||||||
|
"album_deleted": "S'ha suprimit l'àlbum",
|
||||||
"album_info_card_backup_album_excluded": "Exclosos",
|
"album_info_card_backup_album_excluded": "Exclosos",
|
||||||
"album_info_card_backup_album_included": "Inclosos",
|
"album_info_card_backup_album_included": "Inclosos",
|
||||||
"album_info_updated": "Informació de l'àlbum actualitzada",
|
"album_info_updated": "Informació de l'àlbum actualitzada",
|
||||||
@@ -394,6 +423,7 @@
|
|||||||
"album_options": "Opcions de l'àlbum",
|
"album_options": "Opcions de l'àlbum",
|
||||||
"album_remove_user": "Eliminar l'usuari?",
|
"album_remove_user": "Eliminar l'usuari?",
|
||||||
"album_remove_user_confirmation": "Esteu segurs que voleu eliminar {user}?",
|
"album_remove_user_confirmation": "Esteu segurs que voleu eliminar {user}?",
|
||||||
|
"album_search_not_found": "No s'ha trobat cap àlbum que coincideixi amb la teva cerca",
|
||||||
"album_share_no_users": "Sembla que has compartit aquest àlbum amb tots els usuaris o no tens cap usuari amb qui compartir-ho.",
|
"album_share_no_users": "Sembla que has compartit aquest àlbum amb tots els usuaris o no tens cap usuari amb qui compartir-ho.",
|
||||||
"album_updated": "Àlbum actualitzat",
|
"album_updated": "Àlbum actualitzat",
|
||||||
"album_updated_setting_description": "Rep una notificació per correu electrònic quan un àlbum compartit tingui recursos nous",
|
"album_updated_setting_description": "Rep una notificació per correu electrònic quan un àlbum compartit tingui recursos nous",
|
||||||
@@ -413,6 +443,7 @@
|
|||||||
"albums_default_sort_order": "Ordre per defecte de l'àlbum",
|
"albums_default_sort_order": "Ordre per defecte de l'àlbum",
|
||||||
"albums_default_sort_order_description": "Ordre de classificació inicial dels recursos al crear àlbums nous.",
|
"albums_default_sort_order_description": "Ordre de classificació inicial dels recursos al crear àlbums nous.",
|
||||||
"albums_feature_description": "Col·leccions d'actius que es poden compartir amb altres usuaris.",
|
"albums_feature_description": "Col·leccions d'actius que es poden compartir amb altres usuaris.",
|
||||||
|
"albums_on_device_count": "Àlbums al dispositiu ({count})",
|
||||||
"all": "Tots",
|
"all": "Tots",
|
||||||
"all_albums": "Tots els àlbum",
|
"all_albums": "Tots els àlbum",
|
||||||
"all_people": "Tota la gent",
|
"all_people": "Tota la gent",
|
||||||
@@ -432,6 +463,7 @@
|
|||||||
"app_bar_signout_dialog_title": "Tanca la sessió",
|
"app_bar_signout_dialog_title": "Tanca la sessió",
|
||||||
"app_settings": "Configuració de l'app",
|
"app_settings": "Configuració de l'app",
|
||||||
"appears_in": "Apareix a",
|
"appears_in": "Apareix a",
|
||||||
|
"apply_count": "Aplicar ({count, number})",
|
||||||
"archive": "Arxiu",
|
"archive": "Arxiu",
|
||||||
"archive_action_prompt": "{count} afegit a Arxiu",
|
"archive_action_prompt": "{count} afegit a Arxiu",
|
||||||
"archive_or_unarchive_photo": "Arxivar o desarxivar fotografia",
|
"archive_or_unarchive_photo": "Arxivar o desarxivar fotografia",
|
||||||
@@ -471,7 +503,9 @@
|
|||||||
"assets": "Elements",
|
"assets": "Elements",
|
||||||
"assets_added_count": "{count, plural, one {Afegit un element} other {Afegits # elements}}",
|
"assets_added_count": "{count, plural, one {Afegit un element} other {Afegits # elements}}",
|
||||||
"assets_added_to_album_count": "{count, plural, one {Afegit un element} other {Afegits # elements}} a l'àlbum",
|
"assets_added_to_album_count": "{count, plural, one {Afegit un element} other {Afegits # elements}} a l'àlbum",
|
||||||
|
"assets_added_to_albums_count": "Afegits {assetTotal, plural, one {# recurs} other {# recursos}} a {albumTotal, plural, one {# album} other {# albums}}",
|
||||||
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} no es pot afegir a l'àlbum",
|
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} no es pot afegir a l'àlbum",
|
||||||
|
"assets_cannot_be_added_to_albums": "{count, plural, one {El recurs} other {Els recursos}} no poden ser afegits a cap dels àlbums",
|
||||||
"assets_count": "{count, plural, one {# recurs} other {# recursos}}",
|
"assets_count": "{count, plural, one {# recurs} other {# recursos}}",
|
||||||
"assets_deleted_permanently": "{count} element(s) esborrats permanentment",
|
"assets_deleted_permanently": "{count} element(s) esborrats permanentment",
|
||||||
"assets_deleted_permanently_from_server": "{count} element(s) esborrats permanentment del servidor d'Immich",
|
"assets_deleted_permanently_from_server": "{count} element(s) esborrats permanentment del servidor d'Immich",
|
||||||
@@ -488,6 +522,7 @@
|
|||||||
"assets_trashed_count": "{count, plural, one {# element enviat} other {# elements enviats}} a la paperera",
|
"assets_trashed_count": "{count, plural, one {# element enviat} other {# elements enviats}} a la paperera",
|
||||||
"assets_trashed_from_server": "{count} element(s) enviat a la paperera del servidor d'Immich",
|
"assets_trashed_from_server": "{count} element(s) enviat a la paperera del servidor d'Immich",
|
||||||
"assets_were_part_of_album_count": "{count, plural, one {L'element ja és} other {Els elements ja són}} part de l'àlbum",
|
"assets_were_part_of_album_count": "{count, plural, one {L'element ja és} other {Els elements ja són}} part de l'àlbum",
|
||||||
|
"assets_were_part_of_albums_count": "{count, plural, one {El recurs ja formava} other {Els recursos ja formaven}} part dels àlbums",
|
||||||
"authorized_devices": "Dispositius autoritzats",
|
"authorized_devices": "Dispositius autoritzats",
|
||||||
"automatic_endpoint_switching_subtitle": "Connecteu-vos localment a través de la Wi-Fi designada quan estigui disponible i utilitzeu connexions alternatives en altres llocs",
|
"automatic_endpoint_switching_subtitle": "Connecteu-vos localment a través de la Wi-Fi designada quan estigui disponible i utilitzeu connexions alternatives en altres llocs",
|
||||||
"automatic_endpoint_switching_title": "Canvi automàtic d'URL",
|
"automatic_endpoint_switching_title": "Canvi automàtic d'URL",
|
||||||
@@ -557,9 +592,13 @@
|
|||||||
"backup_manual_in_progress": "La pujada ja està en curs. Torneu-ho a provar més tard",
|
"backup_manual_in_progress": "La pujada ja està en curs. Torneu-ho a provar més tard",
|
||||||
"backup_manual_success": "Èxit",
|
"backup_manual_success": "Èxit",
|
||||||
"backup_manual_title": "Estat de pujada",
|
"backup_manual_title": "Estat de pujada",
|
||||||
|
"backup_options": "Opcions de Còpia de Seguretat",
|
||||||
"backup_options_page_title": "Opcions de còpia de seguretat",
|
"backup_options_page_title": "Opcions de còpia de seguretat",
|
||||||
"backup_setting_subtitle": "Gestiona la configuració de càrrega en segon pla i en primer pla",
|
"backup_setting_subtitle": "Gestiona la configuració de càrrega en segon pla i en primer pla",
|
||||||
|
"backup_settings_subtitle": "Administra la configuració de pujada",
|
||||||
"backward": "Enrere",
|
"backward": "Enrere",
|
||||||
|
"beta_sync": "Estat de la sincronització beta",
|
||||||
|
"beta_sync_subtitle": "Administra el nou sistema de sincronització",
|
||||||
"biometric_auth_enabled": "Autentificació biomètrica activada",
|
"biometric_auth_enabled": "Autentificació biomètrica activada",
|
||||||
"biometric_locked_out": "Esteu bloquejats fora de l'autenticació biomètrica",
|
"biometric_locked_out": "Esteu bloquejats fora de l'autenticació biomètrica",
|
||||||
"biometric_no_options": "No hi ha opcions biomètriques disponibles",
|
"biometric_no_options": "No hi ha opcions biomètriques disponibles",
|
||||||
@@ -577,7 +616,7 @@
|
|||||||
"cache_settings_clear_cache_button": "Neteja la memòria cau",
|
"cache_settings_clear_cache_button": "Neteja la memòria cau",
|
||||||
"cache_settings_clear_cache_button_title": "Neteja la memòria cau de l'aplicació. Això impactarà significativament el rendiment fins que la memòria cau es torni a reconstruir.",
|
"cache_settings_clear_cache_button_title": "Neteja la memòria cau de l'aplicació. Això impactarà significativament el rendiment fins que la memòria cau es torni a reconstruir.",
|
||||||
"cache_settings_duplicated_assets_clear_button": "NETEJA",
|
"cache_settings_duplicated_assets_clear_button": "NETEJA",
|
||||||
"cache_settings_duplicated_assets_subtitle": "Fotos i vídeos que estan a la llista negra de l'aplicació",
|
"cache_settings_duplicated_assets_subtitle": "Fotos i vídeos que estan a la llista ignorada de l'aplicació",
|
||||||
"cache_settings_duplicated_assets_title": "Elements duplicats ({count})",
|
"cache_settings_duplicated_assets_title": "Elements duplicats ({count})",
|
||||||
"cache_settings_statistics_album": "Miniatures de la biblioteca",
|
"cache_settings_statistics_album": "Miniatures de la biblioteca",
|
||||||
"cache_settings_statistics_full": "Imatges completes",
|
"cache_settings_statistics_full": "Imatges completes",
|
||||||
@@ -594,6 +633,7 @@
|
|||||||
"cancel": "Cancel·la",
|
"cancel": "Cancel·la",
|
||||||
"cancel_search": "Cancel·la la cerca",
|
"cancel_search": "Cancel·la la cerca",
|
||||||
"canceled": "Cancel·lat",
|
"canceled": "Cancel·lat",
|
||||||
|
"canceling": "Cancel·lant",
|
||||||
"cannot_merge_people": "No es pot fusionar gent",
|
"cannot_merge_people": "No es pot fusionar gent",
|
||||||
"cannot_undo_this_action": "Aquesta acció no es pot desfer!",
|
"cannot_undo_this_action": "Aquesta acció no es pot desfer!",
|
||||||
"cannot_update_the_description": "No es pot actualitzar la descripció",
|
"cannot_update_the_description": "No es pot actualitzar la descripció",
|
||||||
@@ -625,6 +665,7 @@
|
|||||||
"clear": "Buida",
|
"clear": "Buida",
|
||||||
"clear_all": "Neteja-ho tot",
|
"clear_all": "Neteja-ho tot",
|
||||||
"clear_all_recent_searches": "Esborra totes les cerques recents",
|
"clear_all_recent_searches": "Esborra totes les cerques recents",
|
||||||
|
"clear_file_cache": "Buida la memòria cau de fitxers",
|
||||||
"clear_message": "Neteja el missatge",
|
"clear_message": "Neteja el missatge",
|
||||||
"clear_value": "Neteja el valor",
|
"clear_value": "Neteja el valor",
|
||||||
"client_cert_dialog_msg_confirm": "OK",
|
"client_cert_dialog_msg_confirm": "OK",
|
||||||
@@ -695,6 +736,7 @@
|
|||||||
"create_new_user": "Crea un usuari nou",
|
"create_new_user": "Crea un usuari nou",
|
||||||
"create_shared_album_page_share_add_assets": "AFEGEIX ELEMENTS",
|
"create_shared_album_page_share_add_assets": "AFEGEIX ELEMENTS",
|
||||||
"create_shared_album_page_share_select_photos": "Escull fotografies",
|
"create_shared_album_page_share_select_photos": "Escull fotografies",
|
||||||
|
"create_shared_link": "Crea un enllaç compartit",
|
||||||
"create_tag": "Crear etiqueta",
|
"create_tag": "Crear etiqueta",
|
||||||
"create_tag_description": "Crear una nova etiqueta. Per les etiquetes aniuades, escriu la ruta comperta de l'etiqueta, incloses les barres diagonals.",
|
"create_tag_description": "Crear una nova etiqueta. Per les etiquetes aniuades, escriu la ruta comperta de l'etiqueta, incloses les barres diagonals.",
|
||||||
"create_user": "Crea un usuari",
|
"create_user": "Crea un usuari",
|
||||||
@@ -707,6 +749,7 @@
|
|||||||
"current_server_address": "Adreça actual del servidor",
|
"current_server_address": "Adreça actual del servidor",
|
||||||
"custom_locale": "Localització personalitzada",
|
"custom_locale": "Localització personalitzada",
|
||||||
"custom_locale_description": "Format de dates i números segons la llengua i regió",
|
"custom_locale_description": "Format de dates i números segons la llengua i regió",
|
||||||
|
"custom_url": "URL personalitzada",
|
||||||
"daily_title_text_date": "E, dd MMM",
|
"daily_title_text_date": "E, dd MMM",
|
||||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||||
"dark": "Fosc",
|
"dark": "Fosc",
|
||||||
@@ -718,6 +761,7 @@
|
|||||||
"date_of_birth_saved": "Data de naixement guardada amb èxit",
|
"date_of_birth_saved": "Data de naixement guardada amb èxit",
|
||||||
"date_range": "Interval de dates",
|
"date_range": "Interval de dates",
|
||||||
"day": "Dia",
|
"day": "Dia",
|
||||||
|
"days": "Dies",
|
||||||
"deduplicate_all": "Desduplica-ho tot",
|
"deduplicate_all": "Desduplica-ho tot",
|
||||||
"deduplication_criteria_1": "Mida d'imatge en bytes",
|
"deduplication_criteria_1": "Mida d'imatge en bytes",
|
||||||
"deduplication_criteria_2": "Quantitat de dades EXIF",
|
"deduplication_criteria_2": "Quantitat de dades EXIF",
|
||||||
@@ -726,7 +770,8 @@
|
|||||||
"default_locale": "Localització predeterminada",
|
"default_locale": "Localització predeterminada",
|
||||||
"default_locale_description": "Format de dates i números segons la configuració del navegador",
|
"default_locale_description": "Format de dates i números segons la configuració del navegador",
|
||||||
"delete": "Esborra",
|
"delete": "Esborra",
|
||||||
"delete_action_prompt": "{count} eliminats permanentment",
|
"delete_action_confirmation_message": "Segur que vols eliminar aquest recurs? Aquesta acció el mourà a la paperera del servidor, i et preguntarà si el vols eliminar localment",
|
||||||
|
"delete_action_prompt": "{count} eliminats",
|
||||||
"delete_album": "Esborra l'àlbum",
|
"delete_album": "Esborra l'àlbum",
|
||||||
"delete_api_key_prompt": "Esteu segurs que voleu eliminar aquesta clau API?",
|
"delete_api_key_prompt": "Esteu segurs que voleu eliminar aquesta clau API?",
|
||||||
"delete_dialog_alert": "Aquests elements seran eliminats de manera permanent d'Immich i del vostre dispositiu",
|
"delete_dialog_alert": "Aquests elements seran eliminats de manera permanent d'Immich i del vostre dispositiu",
|
||||||
@@ -740,9 +785,12 @@
|
|||||||
"delete_key": "Suprimeix la clau",
|
"delete_key": "Suprimeix la clau",
|
||||||
"delete_library": "Suprimeix la Llibreria",
|
"delete_library": "Suprimeix la Llibreria",
|
||||||
"delete_link": "Esborra l'enllaç",
|
"delete_link": "Esborra l'enllaç",
|
||||||
|
"delete_local_action_prompt": "{count} eliminats localment",
|
||||||
"delete_local_dialog_ok_backed_up_only": "Esborrar només les que tinguin còpia de seguretat",
|
"delete_local_dialog_ok_backed_up_only": "Esborrar només les que tinguin còpia de seguretat",
|
||||||
"delete_local_dialog_ok_force": "Suprimeix de totes maneres",
|
"delete_local_dialog_ok_force": "Suprimeix de totes maneres",
|
||||||
"delete_others": "Suprimeix altres",
|
"delete_others": "Suprimeix altres",
|
||||||
|
"delete_permanently": "Eliminar permanentment",
|
||||||
|
"delete_permanently_action_prompt": "{count} eliminats permanentment",
|
||||||
"delete_shared_link": "Odstranit sdílený odkaz",
|
"delete_shared_link": "Odstranit sdílený odkaz",
|
||||||
"delete_shared_link_dialog_title": "Suprimeix l'enllaç compartit",
|
"delete_shared_link_dialog_title": "Suprimeix l'enllaç compartit",
|
||||||
"delete_tag": "Eliminar etiqueta",
|
"delete_tag": "Eliminar etiqueta",
|
||||||
@@ -753,6 +801,7 @@
|
|||||||
"description": "Descripció",
|
"description": "Descripció",
|
||||||
"description_input_hint_text": "Afegeix descripció...",
|
"description_input_hint_text": "Afegeix descripció...",
|
||||||
"description_input_submit_error": "S'ha produït un error en actualitzar la descripció, comproveu el registre per a més detalls",
|
"description_input_submit_error": "S'ha produït un error en actualitzar la descripció, comproveu el registre per a més detalls",
|
||||||
|
"deselect_all": "Deseleccionar Tots",
|
||||||
"details": "Detalls",
|
"details": "Detalls",
|
||||||
"direction": "Direcció",
|
"direction": "Direcció",
|
||||||
"disabled": "Desactivat",
|
"disabled": "Desactivat",
|
||||||
@@ -770,6 +819,7 @@
|
|||||||
"documentation": "Documentació",
|
"documentation": "Documentació",
|
||||||
"done": "Fet",
|
"done": "Fet",
|
||||||
"download": "Descarregar",
|
"download": "Descarregar",
|
||||||
|
"download_action_prompt": "Baixant {count} recursos",
|
||||||
"download_canceled": "Descàrrega cancel·lada",
|
"download_canceled": "Descàrrega cancel·lada",
|
||||||
"download_complete": "Descàrrega completada",
|
"download_complete": "Descàrrega completada",
|
||||||
"download_enqueue": "Descàrrega en cua",
|
"download_enqueue": "Descàrrega en cua",
|
||||||
@@ -796,8 +846,12 @@
|
|||||||
"edit": "Editar",
|
"edit": "Editar",
|
||||||
"edit_album": "Edita l'àlbum",
|
"edit_album": "Edita l'àlbum",
|
||||||
"edit_avatar": "Edita l'avatar",
|
"edit_avatar": "Edita l'avatar",
|
||||||
|
"edit_birthday": "Editar aniversari",
|
||||||
"edit_date": "Edita la data",
|
"edit_date": "Edita la data",
|
||||||
"edit_date_and_time": "Edita data i hora",
|
"edit_date_and_time": "Edita data i hora",
|
||||||
|
"edit_date_and_time_action_prompt": "{count} dates i hores editades",
|
||||||
|
"edit_date_and_time_by_offset": "Canviar data mitjançant diferència",
|
||||||
|
"edit_date_and_time_by_offset_interval": "Nou rang de dates: {from}-{to}",
|
||||||
"edit_description": "Edita la descripció",
|
"edit_description": "Edita la descripció",
|
||||||
"edit_description_prompt": "Si us plau, selecciona una nova descripció:",
|
"edit_description_prompt": "Si us plau, selecciona una nova descripció:",
|
||||||
"edit_exclusion_pattern": "Edita patró d'exclusió",
|
"edit_exclusion_pattern": "Edita patró d'exclusió",
|
||||||
@@ -826,6 +880,7 @@
|
|||||||
"empty_trash": "Buidar la paperera",
|
"empty_trash": "Buidar la paperera",
|
||||||
"empty_trash_confirmation": "Esteu segur que voleu buidar la paperera? Això eliminarà tots els recursos a la paperera permanentment d'Immich.\nNo podeu desfer aquesta acció!",
|
"empty_trash_confirmation": "Esteu segur que voleu buidar la paperera? Això eliminarà tots els recursos a la paperera permanentment d'Immich.\nNo podeu desfer aquesta acció!",
|
||||||
"enable": "Activar",
|
"enable": "Activar",
|
||||||
|
"enable_backup": "Habilitar Còpia de Seguretat",
|
||||||
"enable_biometric_auth_description": "Introduïu el codi PIN per a habilitar l'autenticació biomètrica",
|
"enable_biometric_auth_description": "Introduïu el codi PIN per a habilitar l'autenticació biomètrica",
|
||||||
"enabled": "Activat",
|
"enabled": "Activat",
|
||||||
"end_date": "Data final",
|
"end_date": "Data final",
|
||||||
@@ -869,6 +924,7 @@
|
|||||||
"failed_to_load_notifications": "Error en carregar les notificacions",
|
"failed_to_load_notifications": "Error en carregar les notificacions",
|
||||||
"failed_to_load_people": "No s'han pogut carregar les persones",
|
"failed_to_load_people": "No s'han pogut carregar les persones",
|
||||||
"failed_to_remove_product_key": "No s'ha pogut eliminar la clau del producte",
|
"failed_to_remove_product_key": "No s'ha pogut eliminar la clau del producte",
|
||||||
|
"failed_to_reset_pin_code": "No s'ha pogut reiniciar el codi PIN",
|
||||||
"failed_to_stack_assets": "No s'han pogut apilar els elements",
|
"failed_to_stack_assets": "No s'han pogut apilar els elements",
|
||||||
"failed_to_unstack_assets": "No s'han pogut desapilar els elements",
|
"failed_to_unstack_assets": "No s'han pogut desapilar els elements",
|
||||||
"failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions",
|
"failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions",
|
||||||
@@ -877,6 +933,7 @@
|
|||||||
"paths_validation_failed": "{paths, plural, one {# ruta} other {# rutes}} no ha pogut validar",
|
"paths_validation_failed": "{paths, plural, one {# ruta} other {# rutes}} no ha pogut validar",
|
||||||
"profile_picture_transparent_pixels": "Les fotos de perfil no poden tenir píxels transparents. Per favor, feu zoom in, mogueu la imatge o ambdues.",
|
"profile_picture_transparent_pixels": "Les fotos de perfil no poden tenir píxels transparents. Per favor, feu zoom in, mogueu la imatge o ambdues.",
|
||||||
"quota_higher_than_disk_size": "Heu establert una quota més gran que la mida de disc",
|
"quota_higher_than_disk_size": "Heu establert una quota més gran que la mida de disc",
|
||||||
|
"something_went_wrong": "Alguna cosa ha anat malament",
|
||||||
"unable_to_add_album_users": "No es poden afegir usuaris a l'àlbum",
|
"unable_to_add_album_users": "No es poden afegir usuaris a l'àlbum",
|
||||||
"unable_to_add_assets_to_shared_link": "No s'han pogut afegir els elements a l'enllaç compartit",
|
"unable_to_add_assets_to_shared_link": "No s'han pogut afegir els elements a l'enllaç compartit",
|
||||||
"unable_to_add_comment": "No es pot afegir el comentari",
|
"unable_to_add_comment": "No es pot afegir el comentari",
|
||||||
@@ -962,13 +1019,11 @@
|
|||||||
},
|
},
|
||||||
"exif": "EXIF",
|
"exif": "EXIF",
|
||||||
"exif_bottom_sheet_description": "Afegeix descripció...",
|
"exif_bottom_sheet_description": "Afegeix descripció...",
|
||||||
|
"exif_bottom_sheet_description_error": "No s'ha pogut actualitzar la descripció",
|
||||||
"exif_bottom_sheet_details": "DETALLS",
|
"exif_bottom_sheet_details": "DETALLS",
|
||||||
"exif_bottom_sheet_location": "UBICACIÓ",
|
"exif_bottom_sheet_location": "UBICACIÓ",
|
||||||
"exif_bottom_sheet_people": "PERSONES",
|
"exif_bottom_sheet_people": "PERSONES",
|
||||||
"exif_bottom_sheet_person_add_person": "Afegir nom",
|
"exif_bottom_sheet_person_add_person": "Afegir nom",
|
||||||
"exif_bottom_sheet_person_age_months": "Edat {months} mesos",
|
|
||||||
"exif_bottom_sheet_person_age_year_months": "Edat 1 any, {months} mesos",
|
|
||||||
"exif_bottom_sheet_person_age_years": "Edat {years}",
|
|
||||||
"exit_slideshow": "Surt de la presentació de diapositives",
|
"exit_slideshow": "Surt de la presentació de diapositives",
|
||||||
"expand_all": "Ampliar-ho tot",
|
"expand_all": "Ampliar-ho tot",
|
||||||
"experimental_settings_new_asset_list_subtitle": "Treball en curs",
|
"experimental_settings_new_asset_list_subtitle": "Treball en curs",
|
||||||
@@ -982,6 +1037,8 @@
|
|||||||
"explorer": "Explorador",
|
"explorer": "Explorador",
|
||||||
"export": "Exporta",
|
"export": "Exporta",
|
||||||
"export_as_json": "Exportar com a JSON",
|
"export_as_json": "Exportar com a JSON",
|
||||||
|
"export_database": "Exportar base de dades",
|
||||||
|
"export_database_description": "Exportar la base de dades SQLite",
|
||||||
"extension": "Extensió",
|
"extension": "Extensió",
|
||||||
"external": "Extern",
|
"external": "Extern",
|
||||||
"external_libraries": "Llibreries externes",
|
"external_libraries": "Llibreries externes",
|
||||||
@@ -1008,21 +1065,29 @@
|
|||||||
"filter_people": "Filtra persones",
|
"filter_people": "Filtra persones",
|
||||||
"filter_places": "Filtrar per llocs",
|
"filter_places": "Filtrar per llocs",
|
||||||
"find_them_fast": "Trobeu-los ràpidament pel nom amb la cerca",
|
"find_them_fast": "Trobeu-los ràpidament pel nom amb la cerca",
|
||||||
|
"first": "Primer",
|
||||||
"fix_incorrect_match": "Corregiu la coincidència incorrecta",
|
"fix_incorrect_match": "Corregiu la coincidència incorrecta",
|
||||||
"folder": "Carpeta",
|
"folder": "Carpeta",
|
||||||
"folder_not_found": "Carpeta no trobada",
|
"folder_not_found": "Carpeta no trobada",
|
||||||
"folders": "Carpetes",
|
"folders": "Carpetes",
|
||||||
"folders_feature_description": "Explorar la vista de carpetes per les fotos i vídeos del sistema d'arxius",
|
"folders_feature_description": "Explorar la vista de carpetes per les fotos i vídeos del sistema d'arxius",
|
||||||
|
"forgot_pin_code_question": "Has oblidat el teu PIN?",
|
||||||
"forward": "Endavant",
|
"forward": "Endavant",
|
||||||
"gcast_enabled": "Google Cast",
|
"gcast_enabled": "Google Cast",
|
||||||
"gcast_enabled_description": "Aquesta funció carrega recursos externs de Google per funcionar.",
|
"gcast_enabled_description": "Aquesta funció carrega recursos externs de Google per funcionar.",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
|
"geolocation_instruction_all_have_location": "Tots els actius d'aquesta data ja tenen dades d'ubicació. Prova de mostrar tots els actius o selecciona una data diferent",
|
||||||
|
"geolocation_instruction_location": "Fes click en un element amb coordinades GPS per utilitzar la seva ubicació o selecciona una ubicació des del mapa",
|
||||||
|
"geolocation_instruction_no_date": "Seleccioneu una data per gestionar dades d'ubicació per a fotos i vídeos d'aquest dia",
|
||||||
|
"geolocation_instruction_no_photos": "Cap foto o vídeo trobats per a aquesta data. Selecciona una data diferent",
|
||||||
"get_help": "Aconseguir ajuda",
|
"get_help": "Aconseguir ajuda",
|
||||||
"get_wifiname_error": "No s'ha pogut obtenir el nom de la Wi-Fi. Assegureu-vos que heu concedit els permisos necessaris i que esteu connectat a una xarxa Wi-Fi",
|
"get_wifiname_error": "No s'ha pogut obtenir el nom de la Wi-Fi. Assegureu-vos que heu concedit els permisos necessaris i que esteu connectat a una xarxa Wi-Fi",
|
||||||
"getting_started": "Començant",
|
"getting_started": "Començant",
|
||||||
"go_back": "Torna",
|
"go_back": "Torna",
|
||||||
"go_to_folder": "Anar al directori",
|
"go_to_folder": "Anar al directori",
|
||||||
"go_to_search": "Vés a cercar",
|
"go_to_search": "Vés a cercar",
|
||||||
|
"gps": "GPS",
|
||||||
|
"gps_missing": "Sense GPS",
|
||||||
"grant_permission": "Concedir permís",
|
"grant_permission": "Concedir permís",
|
||||||
"group_albums_by": "Agrupa àlbums per...",
|
"group_albums_by": "Agrupa àlbums per...",
|
||||||
"group_country": "Agrupar per país",
|
"group_country": "Agrupar per país",
|
||||||
@@ -1033,6 +1098,9 @@
|
|||||||
"haptic_feedback_switch": "Activa la resposta hàptica",
|
"haptic_feedback_switch": "Activa la resposta hàptica",
|
||||||
"haptic_feedback_title": "Resposta Hàptica",
|
"haptic_feedback_title": "Resposta Hàptica",
|
||||||
"has_quota": "Quota",
|
"has_quota": "Quota",
|
||||||
|
"hash_asset": "Hash del recurs",
|
||||||
|
"hashed_assets": "Recursos amb hash",
|
||||||
|
"hashing": "Hashing",
|
||||||
"header_settings_add_header_tip": "Afegeix Capçalera",
|
"header_settings_add_header_tip": "Afegeix Capçalera",
|
||||||
"header_settings_field_validator_msg": "El valor no pot estar buit",
|
"header_settings_field_validator_msg": "El valor no pot estar buit",
|
||||||
"header_settings_header_name_input": "Nom de la capçalera",
|
"header_settings_header_name_input": "Nom de la capçalera",
|
||||||
@@ -1064,7 +1132,9 @@
|
|||||||
"home_page_upload_err_limit": "Només es poden pujar un màxim de 30 elements alhora, ometent",
|
"home_page_upload_err_limit": "Només es poden pujar un màxim de 30 elements alhora, ometent",
|
||||||
"host": "Amfitrió",
|
"host": "Amfitrió",
|
||||||
"hour": "Hora",
|
"hour": "Hora",
|
||||||
|
"hours": "Hores",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
|
"idle": "En espera",
|
||||||
"ignore_icloud_photos": "Ignora fotos d'iCloud",
|
"ignore_icloud_photos": "Ignora fotos d'iCloud",
|
||||||
"ignore_icloud_photos_description": "Les fotos emmagatzemades a iCloud no es penjaran al servidor Immich",
|
"ignore_icloud_photos_description": "Les fotos emmagatzemades a iCloud no es penjaran al servidor Immich",
|
||||||
"image": "Imatge",
|
"image": "Imatge",
|
||||||
@@ -1122,10 +1192,13 @@
|
|||||||
"language_no_results_title": "No s'han trobat idiomes",
|
"language_no_results_title": "No s'han trobat idiomes",
|
||||||
"language_search_hint": "Cerca idiomes...",
|
"language_search_hint": "Cerca idiomes...",
|
||||||
"language_setting_description": "Seleccioneu el vostre idioma",
|
"language_setting_description": "Seleccioneu el vostre idioma",
|
||||||
|
"large_files": "Fitxers Grans",
|
||||||
|
"last": "Últim",
|
||||||
"last_seen": "Vist per últim cop",
|
"last_seen": "Vist per últim cop",
|
||||||
"latest_version": "Última versió",
|
"latest_version": "Última versió",
|
||||||
"latitude": "Latitud",
|
"latitude": "Latitud",
|
||||||
"leave": "Marxar",
|
"leave": "Marxar",
|
||||||
|
"leave_album": "Abandonar àlbum",
|
||||||
"lens_model": "Model de lents",
|
"lens_model": "Model de lents",
|
||||||
"let_others_respond": "Deixa que els altres responguin",
|
"let_others_respond": "Deixa que els altres responguin",
|
||||||
"level": "Nivell",
|
"level": "Nivell",
|
||||||
@@ -1137,7 +1210,9 @@
|
|||||||
"library_page_sort_created": "Creat més recentment",
|
"library_page_sort_created": "Creat més recentment",
|
||||||
"library_page_sort_last_modified": "Darrera modificació",
|
"library_page_sort_last_modified": "Darrera modificació",
|
||||||
"library_page_sort_title": "Títol de l'àlbum",
|
"library_page_sort_title": "Títol de l'àlbum",
|
||||||
|
"licenses": "Llicències",
|
||||||
"light": "Llum",
|
"light": "Llum",
|
||||||
|
"like": "M'agrada",
|
||||||
"like_deleted": "M'agrada suprimit",
|
"like_deleted": "M'agrada suprimit",
|
||||||
"link_motion_video": "Enllaçar vídeo en moviment",
|
"link_motion_video": "Enllaçar vídeo en moviment",
|
||||||
"link_to_oauth": "Enllaç a OAuth",
|
"link_to_oauth": "Enllaç a OAuth",
|
||||||
@@ -1145,7 +1220,9 @@
|
|||||||
"list": "Llista",
|
"list": "Llista",
|
||||||
"loading": "Carregant",
|
"loading": "Carregant",
|
||||||
"loading_search_results_failed": "No s'han pogut carregar els resultats de la cerca",
|
"loading_search_results_failed": "No s'han pogut carregar els resultats de la cerca",
|
||||||
|
"local": "Local",
|
||||||
"local_asset_cast_failed": "No es pot convertir un actiu que no s'ha penjat al servidor",
|
"local_asset_cast_failed": "No es pot convertir un actiu que no s'ha penjat al servidor",
|
||||||
|
"local_assets": "Recursos Locals",
|
||||||
"local_network": "Xarxa local",
|
"local_network": "Xarxa local",
|
||||||
"local_network_sheet_info": "L'aplicació es connectarà al servidor mitjançant aquest URL quan utilitzeu la xarxa Wi-Fi especificada",
|
"local_network_sheet_info": "L'aplicació es connectarà al servidor mitjançant aquest URL quan utilitzeu la xarxa Wi-Fi especificada",
|
||||||
"location_permission": "Permís d'ubicació",
|
"location_permission": "Permís d'ubicació",
|
||||||
@@ -1168,7 +1245,7 @@
|
|||||||
"login_form_back_button_text": "Enrere",
|
"login_form_back_button_text": "Enrere",
|
||||||
"login_form_email_hint": "elteu@correu.cat",
|
"login_form_email_hint": "elteu@correu.cat",
|
||||||
"login_form_endpoint_hint": "http://ip-del-servidor:port",
|
"login_form_endpoint_hint": "http://ip-del-servidor:port",
|
||||||
"login_form_endpoint_url": "URL del servidor",
|
"login_form_endpoint_url": "URL del punt final del servidor",
|
||||||
"login_form_err_http": "Especifica http:// o https://",
|
"login_form_err_http": "Especifica http:// o https://",
|
||||||
"login_form_err_invalid_email": "Adreça de correu electrònic no vàlida",
|
"login_form_err_invalid_email": "Adreça de correu electrònic no vàlida",
|
||||||
"login_form_err_invalid_url": "URL no vàlid",
|
"login_form_err_invalid_url": "URL no vàlid",
|
||||||
@@ -1194,6 +1271,7 @@
|
|||||||
"main_branch_warning": "Esteu utilitzant una versió en desenvolupament; Recomanem fer servir una versió publicada!",
|
"main_branch_warning": "Esteu utilitzant una versió en desenvolupament; Recomanem fer servir una versió publicada!",
|
||||||
"main_menu": "Menú principal",
|
"main_menu": "Menú principal",
|
||||||
"make": "Fabricant",
|
"make": "Fabricant",
|
||||||
|
"manage_geolocation": "Gestioneu la vostra ubicació",
|
||||||
"manage_shared_links": "Administrar enllaços compartits",
|
"manage_shared_links": "Administrar enllaços compartits",
|
||||||
"manage_sharing_with_partners": "Gestiona la compartició amb els companys",
|
"manage_sharing_with_partners": "Gestiona la compartició amb els companys",
|
||||||
"manage_the_app_settings": "Gestioneu la configuració de l'aplicació",
|
"manage_the_app_settings": "Gestioneu la configuració de l'aplicació",
|
||||||
@@ -1202,7 +1280,7 @@
|
|||||||
"manage_your_devices": "Gestioneu els vostres dispositius connectats",
|
"manage_your_devices": "Gestioneu els vostres dispositius connectats",
|
||||||
"manage_your_oauth_connection": "Gestioneu la vostra connexió OAuth",
|
"manage_your_oauth_connection": "Gestioneu la vostra connexió OAuth",
|
||||||
"map": "Mapa",
|
"map": "Mapa",
|
||||||
"map_assets_in_bounds": "{count} fotos",
|
"map_assets_in_bounds": "{count, plural, =0 {No hi ha fotos en aquesta àrea} one {# foto} other {# fotos}}",
|
||||||
"map_cannot_get_user_location": "No es pot obtenir la ubicació de l'usuari",
|
"map_cannot_get_user_location": "No es pot obtenir la ubicació de l'usuari",
|
||||||
"map_location_dialog_yes": "Sí",
|
"map_location_dialog_yes": "Sí",
|
||||||
"map_location_picker_page_use_location": "Utilitzar aquesta ubicació",
|
"map_location_picker_page_use_location": "Utilitzar aquesta ubicació",
|
||||||
@@ -1210,7 +1288,6 @@
|
|||||||
"map_location_service_disabled_title": "Servei de localització desactivat",
|
"map_location_service_disabled_title": "Servei de localització desactivat",
|
||||||
"map_marker_for_images": "Marcador de mapa per a imatges fetes a {city}, {country}",
|
"map_marker_for_images": "Marcador de mapa per a imatges fetes a {city}, {country}",
|
||||||
"map_marker_with_image": "Marcador de mapa amb imatge",
|
"map_marker_with_image": "Marcador de mapa amb imatge",
|
||||||
"map_no_assets_in_bounds": "No hi ha fotos en aquesta zona",
|
|
||||||
"map_no_location_permission_content": "Es necessita el permís de localització per mostrar els elements de la teva ubicació actual. Vols permetre-ho ara?",
|
"map_no_location_permission_content": "Es necessita el permís de localització per mostrar els elements de la teva ubicació actual. Vols permetre-ho ara?",
|
||||||
"map_no_location_permission_title": "Permís de localització denegat",
|
"map_no_location_permission_title": "Permís de localització denegat",
|
||||||
"map_settings": "Paràmetres de mapa",
|
"map_settings": "Paràmetres de mapa",
|
||||||
@@ -1247,6 +1324,7 @@
|
|||||||
"merged_people_count": "Combinades {count, plural, one {# persona} other {# persones}}",
|
"merged_people_count": "Combinades {count, plural, one {# persona} other {# persones}}",
|
||||||
"minimize": "Minimitza",
|
"minimize": "Minimitza",
|
||||||
"minute": "Minut",
|
"minute": "Minut",
|
||||||
|
"minutes": "Minuts",
|
||||||
"missing": "Restants",
|
"missing": "Restants",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"month": "Mes",
|
"month": "Mes",
|
||||||
@@ -1266,6 +1344,9 @@
|
|||||||
"my_albums": "Els meus àlbums",
|
"my_albums": "Els meus àlbums",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"name_or_nickname": "Nom o sobrenom",
|
"name_or_nickname": "Nom o sobrenom",
|
||||||
|
"network_requirement_photos_upload": "Fes servir dades mòbils per a còpies de seguretat de fotos",
|
||||||
|
"network_requirement_videos_upload": "Fes servir dades mòbils per a còpies de seguretat de videos",
|
||||||
|
"network_requirements_updated": "Han canviat els requeriments de xarxa, reiniciant la cua",
|
||||||
"networking_settings": "Xarxes",
|
"networking_settings": "Xarxes",
|
||||||
"networking_subtitle": "Gestiona la configuració del endpoint del servidor",
|
"networking_subtitle": "Gestiona la configuració del endpoint del servidor",
|
||||||
"never": "Mai",
|
"never": "Mai",
|
||||||
@@ -1301,6 +1382,7 @@
|
|||||||
"no_results": "Sense resultats",
|
"no_results": "Sense resultats",
|
||||||
"no_results_description": "Proveu un sinònim o una paraula clau més general",
|
"no_results_description": "Proveu un sinònim o una paraula clau més general",
|
||||||
"no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa",
|
"no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa",
|
||||||
|
"no_uploads_in_progress": "Cap pujada en progrés",
|
||||||
"not_in_any_album": "En cap àlbum",
|
"not_in_any_album": "En cap àlbum",
|
||||||
"not_selected": "No seleccionat",
|
"not_selected": "No seleccionat",
|
||||||
"note_apply_storage_label_to_previously_uploaded assets": "Nota: per aplicar l'etiqueta d'emmagatzematge als actius penjats anteriorment, executeu el",
|
"note_apply_storage_label_to_previously_uploaded assets": "Nota: per aplicar l'etiqueta d'emmagatzematge als actius penjats anteriorment, executeu el",
|
||||||
@@ -1316,6 +1398,7 @@
|
|||||||
"oauth": "OAuth",
|
"oauth": "OAuth",
|
||||||
"official_immich_resources": "Recursos oficials d'Immich",
|
"official_immich_resources": "Recursos oficials d'Immich",
|
||||||
"offline": "Fora de línia",
|
"offline": "Fora de línia",
|
||||||
|
"offset": "Diferència",
|
||||||
"ok": "D'acord",
|
"ok": "D'acord",
|
||||||
"oldest_first": "El més vell primer",
|
"oldest_first": "El més vell primer",
|
||||||
"on_this_device": "En aquest dispositiu",
|
"on_this_device": "En aquest dispositiu",
|
||||||
@@ -1338,6 +1421,7 @@
|
|||||||
"original": "original",
|
"original": "original",
|
||||||
"other": "Altres",
|
"other": "Altres",
|
||||||
"other_devices": "Altres dispositius",
|
"other_devices": "Altres dispositius",
|
||||||
|
"other_entities": "Altres entitats",
|
||||||
"other_variables": "Altres variables",
|
"other_variables": "Altres variables",
|
||||||
"owned": "Propi",
|
"owned": "Propi",
|
||||||
"owner": "Propietari",
|
"owner": "Propietari",
|
||||||
@@ -1392,6 +1476,9 @@
|
|||||||
"permission_onboarding_permission_limited": "Permís limitat. Per a permetre que Immich faci còpies de seguretat i gestioni tota la col·lecció de la galeria, concediu permisos de fotos i vídeos a Configuració.",
|
"permission_onboarding_permission_limited": "Permís limitat. Per a permetre que Immich faci còpies de seguretat i gestioni tota la col·lecció de la galeria, concediu permisos de fotos i vídeos a Configuració.",
|
||||||
"permission_onboarding_request": "Immich requereix permís per veure les vostres fotos i vídeos.",
|
"permission_onboarding_request": "Immich requereix permís per veure les vostres fotos i vídeos.",
|
||||||
"person": "Persona",
|
"person": "Persona",
|
||||||
|
"person_age_months": "{months, plural, one {# mes} other {# mesos}} d'antiguitat",
|
||||||
|
"person_age_year_months": "1 any, {months, plural, one {# mes} other {# mesos}} d'antiguitat",
|
||||||
|
"person_age_years": "{years, plural, other {# anys}} d'antiguitat",
|
||||||
"person_birthdate": "Nascut a {date}",
|
"person_birthdate": "Nascut a {date}",
|
||||||
"person_hidden": "{name}{hidden, select, true { (ocultat)} other {}}",
|
"person_hidden": "{name}{hidden, select, true { (ocultat)} other {}}",
|
||||||
"photo_shared_all_users": "Sembla que has compartit les teves fotos amb tots els usuaris o no tens cap usuari amb qui compartir-les.",
|
"photo_shared_all_users": "Sembla que has compartit les teves fotos amb tots els usuaris o no tens cap usuari amb qui compartir-les.",
|
||||||
@@ -1431,6 +1518,7 @@
|
|||||||
"profile_drawer_client_out_of_date_minor": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió menor.",
|
"profile_drawer_client_out_of_date_minor": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió menor.",
|
||||||
"profile_drawer_client_server_up_to_date": "El Client i el Servidor estan actualitzats",
|
"profile_drawer_client_server_up_to_date": "El Client i el Servidor estan actualitzats",
|
||||||
"profile_drawer_github": "GitHub",
|
"profile_drawer_github": "GitHub",
|
||||||
|
"profile_drawer_readonly_mode": "Manera de només lectura activada. Feu doble click a la icona de l'avatar de l'usuari per sortir.",
|
||||||
"profile_drawer_server_out_of_date_major": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió major.",
|
"profile_drawer_server_out_of_date_major": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió major.",
|
||||||
"profile_drawer_server_out_of_date_minor": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió menor.",
|
"profile_drawer_server_out_of_date_minor": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió menor.",
|
||||||
"profile_image_of_user": "Imatge de perfil de {user}",
|
"profile_image_of_user": "Imatge de perfil de {user}",
|
||||||
@@ -1469,12 +1557,15 @@
|
|||||||
"purchase_server_description_2": "Estat del contribuent",
|
"purchase_server_description_2": "Estat del contribuent",
|
||||||
"purchase_server_title": "Servidor",
|
"purchase_server_title": "Servidor",
|
||||||
"purchase_settings_server_activated": "La clau de producte del servidor la gestiona l'administrador",
|
"purchase_settings_server_activated": "La clau de producte del servidor la gestiona l'administrador",
|
||||||
|
"queue_status": "En cua {count}/{total}",
|
||||||
"rating": "Valoració",
|
"rating": "Valoració",
|
||||||
"rating_clear": "Esborrar valoració",
|
"rating_clear": "Esborrar valoració",
|
||||||
"rating_count": "{count, plural, one {# estrella} other {# estrelles}}",
|
"rating_count": "{count, plural, one {# estrella} other {# estrelles}}",
|
||||||
"rating_description": "Mostrar la valoració EXIF al panell d'informació",
|
"rating_description": "Mostrar la valoració EXIF al panell d'informació",
|
||||||
"reaction_options": "Opcions de reacció",
|
"reaction_options": "Opcions de reacció",
|
||||||
"read_changelog": "Llegeix el registre de canvis",
|
"read_changelog": "Llegeix el registre de canvis",
|
||||||
|
"readonly_mode_disabled": "Mode de només lectura desactivat",
|
||||||
|
"readonly_mode_enabled": "Mode de només lectura activat",
|
||||||
"reassign": "Reassignar",
|
"reassign": "Reassignar",
|
||||||
"reassigned_assets_to_existing_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a {name, select, null {una persona existent} other {{name}}}",
|
"reassigned_assets_to_existing_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a {name, select, null {una persona existent} other {{name}}}",
|
||||||
"reassigned_assets_to_new_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a una persona nova",
|
"reassigned_assets_to_new_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a una persona nova",
|
||||||
@@ -1497,6 +1588,8 @@
|
|||||||
"refreshing_faces": "Refrescant cares",
|
"refreshing_faces": "Refrescant cares",
|
||||||
"refreshing_metadata": "Actualitzant les metadades",
|
"refreshing_metadata": "Actualitzant les metadades",
|
||||||
"regenerating_thumbnails": "Regenerant les miniatures",
|
"regenerating_thumbnails": "Regenerant les miniatures",
|
||||||
|
"remote": "Remot",
|
||||||
|
"remote_assets": "Recursos Remots",
|
||||||
"remove": "Eliminar",
|
"remove": "Eliminar",
|
||||||
"remove_assets_album_confirmation": "Confirmes que vols eliminar {count, plural, one {# recurs} other {# recursos}} de l'àlbum?",
|
"remove_assets_album_confirmation": "Confirmes que vols eliminar {count, plural, one {# recurs} other {# recursos}} de l'àlbum?",
|
||||||
"remove_assets_shared_link_confirmation": "Esteu segur que voleu eliminar {count, plural, one {# recurs} other {# recursos}} d'aquest enllaç compartit?",
|
"remove_assets_shared_link_confirmation": "Esteu segur que voleu eliminar {count, plural, one {# recurs} other {# recursos}} d'aquest enllaç compartit?",
|
||||||
@@ -1504,6 +1597,7 @@
|
|||||||
"remove_custom_date_range": "Elimina l'interval de dates personalitzat",
|
"remove_custom_date_range": "Elimina l'interval de dates personalitzat",
|
||||||
"remove_deleted_assets": "Suprimeix fitxers fora de línia",
|
"remove_deleted_assets": "Suprimeix fitxers fora de línia",
|
||||||
"remove_from_album": "Treu de l'àlbum",
|
"remove_from_album": "Treu de l'àlbum",
|
||||||
|
"remove_from_album_action_prompt": "{count} eliminats de l'àlbum",
|
||||||
"remove_from_favorites": "Eliminar dels preferits",
|
"remove_from_favorites": "Eliminar dels preferits",
|
||||||
"remove_from_lock_folder_action_prompt": "{count} eliminades de la carpeta protegida",
|
"remove_from_lock_folder_action_prompt": "{count} eliminades de la carpeta protegida",
|
||||||
"remove_from_locked_folder": "Elimina de la carpeta bloquejada",
|
"remove_from_locked_folder": "Elimina de la carpeta bloquejada",
|
||||||
@@ -1533,19 +1627,28 @@
|
|||||||
"reset_password": "Restablir contrasenya",
|
"reset_password": "Restablir contrasenya",
|
||||||
"reset_people_visibility": "Restablir la visibilitat de les persones",
|
"reset_people_visibility": "Restablir la visibilitat de les persones",
|
||||||
"reset_pin_code": "Restablir el codi PIN",
|
"reset_pin_code": "Restablir el codi PIN",
|
||||||
|
"reset_pin_code_description": "Si has oblidat el teu codi PIN, pots contactar amb l'administrador del servidor per a reiniciar-lo",
|
||||||
|
"reset_pin_code_success": "Codi PIN reiniciat correctament",
|
||||||
|
"reset_pin_code_with_password": "Sempre pots reiniciar el codi PIN amb la teva contrasenya",
|
||||||
|
"reset_sqlite": "Reiniciar base de dades SQLite",
|
||||||
|
"reset_sqlite_confirmation": "Segur que vols reiniciar la base de dades SQLite? Hauràs de tancar la sessió i tornar a accedir per a resincronitzar les dades",
|
||||||
|
"reset_sqlite_success": "S'ha reiniciat la base de dades correctament",
|
||||||
"reset_to_default": "Restableix els valors predeterminats",
|
"reset_to_default": "Restableix els valors predeterminats",
|
||||||
"resolve_duplicates": "Resoldre duplicats",
|
"resolve_duplicates": "Resoldre duplicats",
|
||||||
"resolved_all_duplicates": "Tots els duplicats resolts",
|
"resolved_all_duplicates": "Tots els duplicats resolts",
|
||||||
"restore": "Recupera",
|
"restore": "Recupera",
|
||||||
"restore_all": "Restaurar-ho tot",
|
"restore_all": "Restaurar-ho tot",
|
||||||
|
"restore_trash_action_prompt": "{count} recuperats de la paperera",
|
||||||
"restore_user": "Restaurar l'usuari",
|
"restore_user": "Restaurar l'usuari",
|
||||||
"restored_asset": "Element restaurat",
|
"restored_asset": "Element restaurat",
|
||||||
"resume": "Reprendre",
|
"resume": "Reprendre",
|
||||||
"retry_upload": "Torna a provar de pujar",
|
"retry_upload": "Torna a provar de pujar",
|
||||||
"review_duplicates": "Revisar duplicats",
|
"review_duplicates": "Revisar duplicats",
|
||||||
|
"review_large_files": "Revisar fitxers grans",
|
||||||
"role": "Rol",
|
"role": "Rol",
|
||||||
"role_editor": "Editor",
|
"role_editor": "Editor",
|
||||||
"role_viewer": "Visor",
|
"role_viewer": "Visor",
|
||||||
|
"running": "En execució",
|
||||||
"save": "Desa",
|
"save": "Desa",
|
||||||
"save_to_gallery": "Desa a galeria",
|
"save_to_gallery": "Desa a galeria",
|
||||||
"saved_api_key": "Clau d'API guardada",
|
"saved_api_key": "Clau d'API guardada",
|
||||||
@@ -1632,6 +1735,7 @@
|
|||||||
"select_user_for_sharing_page_err_album": "Error al crear l'àlbum",
|
"select_user_for_sharing_page_err_album": "Error al crear l'àlbum",
|
||||||
"selected": "Seleccionat",
|
"selected": "Seleccionat",
|
||||||
"selected_count": "{count, plural, one {# seleccionat} other {# seleccionats}}",
|
"selected_count": "{count, plural, one {# seleccionat} other {# seleccionats}}",
|
||||||
|
"selected_gps_coordinates": "seleccio de coordinades GPS",
|
||||||
"send_message": "Envia missatge",
|
"send_message": "Envia missatge",
|
||||||
"send_welcome_email": "Envia correu de benvinguda",
|
"send_welcome_email": "Envia correu de benvinguda",
|
||||||
"server_endpoint": "Endpoint de Servidor",
|
"server_endpoint": "Endpoint de Servidor",
|
||||||
@@ -1677,6 +1781,7 @@
|
|||||||
"settings_saved": "Configuració desada",
|
"settings_saved": "Configuració desada",
|
||||||
"setup_pin_code": "Configurar un codi PIN",
|
"setup_pin_code": "Configurar un codi PIN",
|
||||||
"share": "Comparteix",
|
"share": "Comparteix",
|
||||||
|
"share_action_prompt": "Compartits {count} recursos",
|
||||||
"share_add_photos": "Afegeix fotografies",
|
"share_add_photos": "Afegeix fotografies",
|
||||||
"share_assets_selected": "{count} seleccionats",
|
"share_assets_selected": "{count} seleccionats",
|
||||||
"share_dialog_preparing": "S'està preparant...",
|
"share_dialog_preparing": "S'està preparant...",
|
||||||
@@ -1698,6 +1803,7 @@
|
|||||||
"shared_link_clipboard_copied_massage": "S'ha copiat al porta-retalls",
|
"shared_link_clipboard_copied_massage": "S'ha copiat al porta-retalls",
|
||||||
"shared_link_clipboard_text": "Enllaç: {link}\nContrasenya: {password}",
|
"shared_link_clipboard_text": "Enllaç: {link}\nContrasenya: {password}",
|
||||||
"shared_link_create_error": "S'ha produït un error en crear l'enllaç compartit",
|
"shared_link_create_error": "S'ha produït un error en crear l'enllaç compartit",
|
||||||
|
"shared_link_custom_url_description": "Accedeix a aquest enllaç compartit amb una URL personalitzada",
|
||||||
"shared_link_edit_description_hint": "Introduïu la descripció de compartició",
|
"shared_link_edit_description_hint": "Introduïu la descripció de compartició",
|
||||||
"shared_link_edit_expire_after_option_day": "1 dia",
|
"shared_link_edit_expire_after_option_day": "1 dia",
|
||||||
"shared_link_edit_expire_after_option_days": "{count} dies",
|
"shared_link_edit_expire_after_option_days": "{count} dies",
|
||||||
@@ -1723,6 +1829,7 @@
|
|||||||
"shared_link_info_chip_metadata": "EXIF",
|
"shared_link_info_chip_metadata": "EXIF",
|
||||||
"shared_link_manage_links": "Gestiona els enllaços compartits",
|
"shared_link_manage_links": "Gestiona els enllaços compartits",
|
||||||
"shared_link_options": "Opcions d'enllaços compartits",
|
"shared_link_options": "Opcions d'enllaços compartits",
|
||||||
|
"shared_link_password_description": "Requereix una contrasenya per accedir a aquest enllaç compartit",
|
||||||
"shared_links": "Enllaços compartits",
|
"shared_links": "Enllaços compartits",
|
||||||
"shared_links_description": "Comparteix fotos i vídeos amb un enllaç",
|
"shared_links_description": "Comparteix fotos i vídeos amb un enllaç",
|
||||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# fotos i vídeos compartits.}}",
|
"shared_photos_and_videos_count": "{assetCount, plural, other {# fotos i vídeos compartits.}}",
|
||||||
@@ -1739,8 +1846,10 @@
|
|||||||
"shift_to_permanent_delete": "premeu ⇧ per suprimir el recurs permanentment",
|
"shift_to_permanent_delete": "premeu ⇧ per suprimir el recurs permanentment",
|
||||||
"show_album_options": "Mostra les opcions d'àlbum",
|
"show_album_options": "Mostra les opcions d'àlbum",
|
||||||
"show_albums": "Mostrar àlbums",
|
"show_albums": "Mostrar àlbums",
|
||||||
|
"show_all_assets": "Mostrar tots els elements",
|
||||||
"show_all_people": "Veure totes les persones",
|
"show_all_people": "Veure totes les persones",
|
||||||
"show_and_hide_people": "Mostra i amaga persones",
|
"show_and_hide_people": "Mostra i amaga persones",
|
||||||
|
"show_assets_without_location": "Mostra els elements sense ubicació",
|
||||||
"show_file_location": "Mostra l'ubicació del fitxer",
|
"show_file_location": "Mostra l'ubicació del fitxer",
|
||||||
"show_gallery": "Mostra la galeria",
|
"show_gallery": "Mostra la galeria",
|
||||||
"show_hidden_people": "Mostra persones ocultes",
|
"show_hidden_people": "Mostra persones ocultes",
|
||||||
@@ -1772,12 +1881,14 @@
|
|||||||
"sort_created": "Data de creació",
|
"sort_created": "Data de creació",
|
||||||
"sort_items": "Nombre d'elements",
|
"sort_items": "Nombre d'elements",
|
||||||
"sort_modified": "Data de modificació",
|
"sort_modified": "Data de modificació",
|
||||||
|
"sort_newest": "Foto més nova",
|
||||||
"sort_oldest": "Foto més antiga",
|
"sort_oldest": "Foto més antiga",
|
||||||
"sort_people_by_similarity": "Ordenar personar per semblança",
|
"sort_people_by_similarity": "Ordenar personar per semblança",
|
||||||
"sort_recent": "Foto més recent",
|
"sort_recent": "Foto més recent",
|
||||||
"sort_title": "Títol",
|
"sort_title": "Títol",
|
||||||
"source": "Font",
|
"source": "Font",
|
||||||
"stack": "Apila",
|
"stack": "Apila",
|
||||||
|
"stack_action_prompt": "{count} apilats",
|
||||||
"stack_duplicates": "Aplica duplicats",
|
"stack_duplicates": "Aplica duplicats",
|
||||||
"stack_select_one_photo": "Selecciona una imatge principal per la pila",
|
"stack_select_one_photo": "Selecciona una imatge principal per la pila",
|
||||||
"stack_selected_photos": "Apila les fotos seleccionades",
|
"stack_selected_photos": "Apila les fotos seleccionades",
|
||||||
@@ -1797,6 +1908,7 @@
|
|||||||
"storage_quota": "Quota d'emmagatzematge",
|
"storage_quota": "Quota d'emmagatzematge",
|
||||||
"storage_usage": "{used} de {available} en ús",
|
"storage_usage": "{used} de {available} en ús",
|
||||||
"submit": "Envia",
|
"submit": "Envia",
|
||||||
|
"success": "Amb èxit",
|
||||||
"suggestions": "Suggeriments",
|
"suggestions": "Suggeriments",
|
||||||
"sunrise_on_the_beach": "Albada a la platja",
|
"sunrise_on_the_beach": "Albada a la platja",
|
||||||
"support": "Suport",
|
"support": "Suport",
|
||||||
@@ -1806,6 +1918,8 @@
|
|||||||
"sync": "Sincronitza",
|
"sync": "Sincronitza",
|
||||||
"sync_albums": "Sincronitzar àlbums",
|
"sync_albums": "Sincronitzar àlbums",
|
||||||
"sync_albums_manual_subtitle": "Sincronitza tots els vídeos i fotos penjats amb els àlbums de còpia de seguretat seleccionats",
|
"sync_albums_manual_subtitle": "Sincronitza tots els vídeos i fotos penjats amb els àlbums de còpia de seguretat seleccionats",
|
||||||
|
"sync_local": "Sincronitza Local",
|
||||||
|
"sync_remote": "Sincronitza Remot",
|
||||||
"sync_upload_album_setting_subtitle": "Creeu i pugeu les seves fotos i vídeos als àlbums seleccionats a Immich",
|
"sync_upload_album_setting_subtitle": "Creeu i pugeu les seves fotos i vídeos als àlbums seleccionats a Immich",
|
||||||
"tag": "Etiqueta",
|
"tag": "Etiqueta",
|
||||||
"tag_assets": "Etiquetar actius",
|
"tag_assets": "Etiquetar actius",
|
||||||
@@ -1816,6 +1930,7 @@
|
|||||||
"tag_updated": "Etiqueta actualizada: {tag}",
|
"tag_updated": "Etiqueta actualizada: {tag}",
|
||||||
"tagged_assets": "{count, plural, one {#Etiquetat} other {#Etiquetats}} {count, plural, one {# actiu} other {# actius}}",
|
"tagged_assets": "{count, plural, one {#Etiquetat} other {#Etiquetats}} {count, plural, one {# actiu} other {# actius}}",
|
||||||
"tags": "Etiquetes",
|
"tags": "Etiquetes",
|
||||||
|
"tap_to_run_job": "Toca per executar el treball",
|
||||||
"template": "Plantilla",
|
"template": "Plantilla",
|
||||||
"theme": "Tema",
|
"theme": "Tema",
|
||||||
"theme_selection": "Selecció de tema",
|
"theme_selection": "Selecció de tema",
|
||||||
@@ -1842,7 +1957,9 @@
|
|||||||
"to_change_password": "Canviar la contrasenya",
|
"to_change_password": "Canviar la contrasenya",
|
||||||
"to_favorite": "Prefereix",
|
"to_favorite": "Prefereix",
|
||||||
"to_login": "Iniciar sessió",
|
"to_login": "Iniciar sessió",
|
||||||
|
"to_multi_select": "per multi-seleccionar",
|
||||||
"to_parent": "Anar als pares",
|
"to_parent": "Anar als pares",
|
||||||
|
"to_select": "per seleccionar",
|
||||||
"to_trash": "Paperera",
|
"to_trash": "Paperera",
|
||||||
"toggle_settings": "Canvia configuració",
|
"toggle_settings": "Canvia configuració",
|
||||||
"total": "Total",
|
"total": "Total",
|
||||||
@@ -1888,15 +2005,21 @@
|
|||||||
"unselect_all_duplicates": "Desmarqueu tots els duplicats",
|
"unselect_all_duplicates": "Desmarqueu tots els duplicats",
|
||||||
"unselect_all_in": "Desseleccionar tots els elements de {group}",
|
"unselect_all_in": "Desseleccionar tots els elements de {group}",
|
||||||
"unstack": "Desapila",
|
"unstack": "Desapila",
|
||||||
|
"unstack_action_prompt": "{count} sense apilar",
|
||||||
"unstacked_assets_count": "No apilat {count, plural, one {# recurs} other {# recursos}}",
|
"unstacked_assets_count": "No apilat {count, plural, one {# recurs} other {# recursos}}",
|
||||||
|
"untagged": "Sense etiqueta",
|
||||||
"up_next": "Pròxim",
|
"up_next": "Pròxim",
|
||||||
|
"update_location_action_prompt": "Actualitza la ubicació de {count} elements seleccionats amb:",
|
||||||
"updated_at": "Actualitzat",
|
"updated_at": "Actualitzat",
|
||||||
"updated_password": "Contrasenya actualitzada",
|
"updated_password": "Contrasenya actualitzada",
|
||||||
"upload": "Pujar",
|
"upload": "Pujar",
|
||||||
|
"upload_action_prompt": "{count} a la cua per a pujar",
|
||||||
"upload_concurrency": "Concurrència de pujades",
|
"upload_concurrency": "Concurrència de pujades",
|
||||||
|
"upload_details": "Detalls de la Pujada",
|
||||||
"upload_dialog_info": "Vols fer còpia de seguretat dels elements seleccionats al servidor?",
|
"upload_dialog_info": "Vols fer còpia de seguretat dels elements seleccionats al servidor?",
|
||||||
"upload_dialog_title": "Puja elements",
|
"upload_dialog_title": "Puja elements",
|
||||||
"upload_errors": "Càrrega completada amb {count, plural, one {# error} other {# errors}}, actualitzeu la pàgina per veure els nous elements carregats.",
|
"upload_errors": "Càrrega completada amb {count, plural, one {# error} other {# errors}}, actualitzeu la pàgina per veure els nous elements carregats.",
|
||||||
|
"upload_finished": "Pujada finalitzada",
|
||||||
"upload_progress": "Restant {remaining, number} - Processat {processed, number}/{total, number}",
|
"upload_progress": "Restant {remaining, number} - Processat {processed, number}/{total, number}",
|
||||||
"upload_skipped_duplicates": "{count, plural, one {S'ha omès # recurs duplicat} other {S'han omès # recursos duplicats}}",
|
"upload_skipped_duplicates": "{count, plural, one {S'ha omès # recurs duplicat} other {S'han omès # recursos duplicats}}",
|
||||||
"upload_status_duplicates": "Duplicats",
|
"upload_status_duplicates": "Duplicats",
|
||||||
@@ -1905,11 +2028,13 @@
|
|||||||
"upload_success": "Pujada correcta, actualitza la pàgina per veure nous recursos de pujada.",
|
"upload_success": "Pujada correcta, actualitza la pàgina per veure nous recursos de pujada.",
|
||||||
"upload_to_immich": "Puja a Immich ({count})",
|
"upload_to_immich": "Puja a Immich ({count})",
|
||||||
"uploading": "Pujant",
|
"uploading": "Pujant",
|
||||||
|
"uploading_media": "Pujant mitjans",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"usage": "Ús",
|
"usage": "Ús",
|
||||||
"use_biometric": "Empra biometria",
|
"use_biometric": "Empra biometria",
|
||||||
"use_current_connection": "utilitzar la connexió actual",
|
"use_current_connection": "utilitzar la connexió actual",
|
||||||
"use_custom_date_range": "Fes servir un rang de dates personalitzat",
|
"use_custom_date_range": "Fes servir un rang de dates personalitzat",
|
||||||
|
"use_this_location": "Fes clic per utilitzar la ubicació",
|
||||||
"user": "Usuari",
|
"user": "Usuari",
|
||||||
"user_has_been_deleted": "Aquest usuari ha sigut eliminat.",
|
"user_has_been_deleted": "Aquest usuari ha sigut eliminat.",
|
||||||
"user_id": "ID d'usuari",
|
"user_id": "ID d'usuari",
|
||||||
@@ -1925,6 +2050,7 @@
|
|||||||
"user_usage_stats_description": "Veure les estadístiques d'ús del compte",
|
"user_usage_stats_description": "Veure les estadístiques d'ús del compte",
|
||||||
"username": "Nom d'usuari",
|
"username": "Nom d'usuari",
|
||||||
"users": "Usuaris",
|
"users": "Usuaris",
|
||||||
|
"users_added_to_album_count": "{count, plural, one {S'ha afegit # usuari} other {S'han afegit # usuaris}} a l'àlbum",
|
||||||
"utilities": "Utilitats",
|
"utilities": "Utilitats",
|
||||||
"validate": "Valida",
|
"validate": "Valida",
|
||||||
"validate_endpoint_error": "Per favor introdueix un URL vàlid",
|
"validate_endpoint_error": "Per favor introdueix un URL vàlid",
|
||||||
@@ -1943,6 +2069,7 @@
|
|||||||
"view_album": "Veure l'àlbum",
|
"view_album": "Veure l'àlbum",
|
||||||
"view_all": "Veure tot",
|
"view_all": "Veure tot",
|
||||||
"view_all_users": "Mostra tot els usuaris",
|
"view_all_users": "Mostra tot els usuaris",
|
||||||
|
"view_details": "Veure Detalls",
|
||||||
"view_in_timeline": "Mostrar a la línia de temps",
|
"view_in_timeline": "Mostrar a la línia de temps",
|
||||||
"view_link": "Veure enllaç",
|
"view_link": "Veure enllaç",
|
||||||
"view_links": "Mostra enllaços",
|
"view_links": "Mostra enllaços",
|
||||||
|
|||||||