mirror of
https://github.com/immich-app/immich.git
synced 2026-06-12 19:11:52 -07:00
Compare commits
290 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| def9efba72 | |||
| b21af78454 | |||
| abd62d9295 | |||
| e31d4aa909 | |||
| 43b2d04e2c | |||
| 4e0f651b80 | |||
| e4dbe777a0 | |||
| d36aed4c5b | |||
| f1da9d2429 | |||
| 232ca3cf3f | |||
| bed0dfe4ef | |||
| 50f1121459 | |||
| 892397807c | |||
| 714c647937 | |||
| c56f477a0f | |||
| 296cd40da9 | |||
| a17276fd1e | |||
| c3e23a6b3a | |||
| 13a7b4a276 | |||
| 563cff26bf | |||
| e81b6778ca | |||
| aa6af7ce36 | |||
| 59d036a2ed | |||
| 7a5c014558 | |||
| e2954b6411 | |||
| 0fb18ed241 | |||
| c0b3b08ce6 | |||
| e8a1084e5b | |||
| d227ba2d51 | |||
| 9cb94343d1 | |||
| aa126e377c | |||
| 74878628c8 | |||
| 4ead3e697d | |||
| fb798a8f29 | |||
| 07813135b5 | |||
| 92a75b0cd3 | |||
| 8132e8a38c | |||
| 43f2f56530 | |||
| e580bb5d0a | |||
| d3680871ef | |||
| b9b1cc2f65 | |||
| 7d198956a6 | |||
| a7b5f81701 | |||
| 5c38373808 | |||
| 1ce961fbb3 | |||
| 4bc411b7c7 | |||
| 11c1025271 | |||
| 8b5385f94b | |||
| d3438cf4a7 | |||
| 6c5c6a1035 | |||
| c928787b3e | |||
| fe9ca4f40a | |||
| a665cec920 | |||
| 568283a8eb | |||
| f382624e68 | |||
| 24dad15636 | |||
| 7ab533b57b | |||
| d10153bbc7 | |||
| b846afeb08 | |||
| e222b19576 | |||
| 1fee99cd2a | |||
| 70bb7e4b7e | |||
| f973927c68 | |||
| e29267359e | |||
| 164cda87a3 | |||
| 12d344efe0 | |||
| 474efd39f8 | |||
| 9e453440e6 | |||
| 8860817c76 | |||
| 3c108a8d22 | |||
| 8d553d6e9c | |||
| 346b98ed4f | |||
| 60683bd91e | |||
| b6938614b2 | |||
| 98961a1d36 | |||
| 5ae95102b4 | |||
| 216d0ba365 | |||
| 28e42f7e29 | |||
| 733373c0ca | |||
| 5617d6ca7c | |||
| 875dd2dead | |||
| 9043bc8435 | |||
| b3d49045de | |||
| 58528cad08 | |||
| 99281de6ab | |||
| 6268d23d12 | |||
| d7999ce1d1 | |||
| 6b0fd89cd2 | |||
| 4b0adb7a1e | |||
| de70d19d20 | |||
| 7155bb1e80 | |||
| fa08e72d30 | |||
| e2de8c7c53 | |||
| 429e181c8f | |||
| 7f611d9031 | |||
| e94e22f3f8 | |||
| 4a8c3b60be | |||
| 2190aa72a8 | |||
| d21cb28526 | |||
| 5c33eb3204 | |||
| 137687bc0f | |||
| 9d4a6614b1 | |||
| e4352a7817 | |||
| 911dde39c9 | |||
| afa836181c | |||
| 963862b1b9 | |||
| 96d521e149 | |||
| 1bb7517da0 | |||
| 814c2e32e4 | |||
| 92841f311f | |||
| 9d2e576630 | |||
| 936418a464 | |||
| 84c75d95c7 | |||
| 9287fa08c6 | |||
| 408e1180ca | |||
| 07f19d2caa | |||
| 368cb7a4ad | |||
| 109e0a7ad0 | |||
| 59750dad7d | |||
| 13ecfc8876 | |||
| 65d8b35f8b | |||
| 942d3c648c | |||
| 82db8be5ff | |||
| 03554b24ad | |||
| c5fb67c004 | |||
| 40983b46c8 | |||
| 5dcdbf04ea | |||
| da8ed3eceb | |||
| 2afde23a5d | |||
| d57a152040 | |||
| 728e92ea33 | |||
| 138e2d9158 | |||
| 7eabac6702 | |||
| cf4789e008 | |||
| 412884fce3 | |||
| 16aee2b869 | |||
| 3f7af51531 | |||
| 4eb100327e | |||
| 69b1946484 | |||
| 61cd69a286 | |||
| c8a1d0e400 | |||
| d120444a87 | |||
| 2382894fa2 | |||
| a52e7dc11a | |||
| 206992605e | |||
| 65611bb860 | |||
| 14aff51da9 | |||
| c42cea5ca9 | |||
| da8505f61d | |||
| 58586483dc | |||
| a838167f11 | |||
| b189fc571c | |||
| 96923f6115 | |||
| 0d6cce4a5b | |||
| 55947cb227 | |||
| 8783180cf3 | |||
| 134c0d4dfb | |||
| aecf8ec88b | |||
| bcff1d42b0 | |||
| 1bd367bd51 | |||
| 725f266b81 | |||
| d08e3de207 | |||
| 26714f6bfe | |||
| a5ce3fc927 | |||
| 3b23f71a3f | |||
| dec33cadd9 | |||
| 80c15a5e27 | |||
| 936c28a40b | |||
| 1a837a28ac | |||
| 8d5d12b108 | |||
| dd7a94135f | |||
| 1acc511b5c | |||
| 452e88267a | |||
| b941108cbd | |||
| e46f2843f7 | |||
| cf991e7b1b | |||
| 748a13104a | |||
| 2dd6b47714 | |||
| 8682be4774 | |||
| dc66892ca1 | |||
| 53a24783f5 | |||
| 0546bc900c | |||
| 7c25bcc0a7 | |||
| 7905853639 | |||
| 073dcc1fbe | |||
| ccdaa4223c | |||
| 5386b62dc4 | |||
| 9733fa4872 | |||
| 3b34c53092 | |||
| fd7ddfef54 | |||
| 0975b1599c | |||
| 78ac0ade01 | |||
| 7b9dab872b | |||
| 6413495fb8 | |||
| b414b3d32b | |||
| 20da7c4267 | |||
| 92b6778d2d | |||
| 5a61e589e8 | |||
| 85192bb110 | |||
| c7ae97fa2b | |||
| 8d02f3625d | |||
| a5a7380a26 | |||
| d9ce3d2046 | |||
| 815ff677fc | |||
| 915d865ce2 | |||
| c28e5f90b6 | |||
| 4383473ed6 | |||
| 77701dd5a3 | |||
| d4808fdc4d | |||
| 7fa967a98e | |||
| 9cffcc9f4e | |||
| 40925f0a06 | |||
| 0544d22902 | |||
| 3d075f2bf8 | |||
| 7384799f19 | |||
| 4a7f06e8fd | |||
| 8f662fc459 | |||
| 24b1dae9f2 | |||
| 3a3469a5f9 | |||
| 7993619ed2 | |||
| 4d1f6f869b | |||
| 3eb03f7934 | |||
| 03ed3daa31 | |||
| 02581e81a7 | |||
| 3ab3d5cf43 | |||
| 0ef04d9baa | |||
| df016f9228 | |||
| 17779c1e74 | |||
| 01d6a244d8 | |||
| 21d6755f39 | |||
| e91c017dd0 | |||
| 43687cd8b4 | |||
| 06729ee5a5 | |||
| b0c9743d9a | |||
| 37cc028868 | |||
| 84a2b7a3c8 | |||
| 89b3433346 | |||
| 3ff0d47ee3 | |||
| aeaf846482 | |||
| b031548791 | |||
| fcea617313 | |||
| 024f20ea26 | |||
| 0a4ed6fd71 | |||
| b6e2ce1f35 | |||
| e323e778cd | |||
| 6a87797649 | |||
| f4a4649bbc | |||
| 6ca54ee722 | |||
| 8e3035f783 | |||
| 79801595db | |||
| 3e1c8aacb1 | |||
| 91ac56cef2 | |||
| 58beac8fe0 | |||
| f632d320f5 | |||
| 2ddaf6a611 | |||
| 1932c60e1c | |||
| dc6f8e746e | |||
| ad7aedb843 | |||
| 571e6a8560 | |||
| 4791313def | |||
| f88fdae048 | |||
| bcef7aa6b6 | |||
| ce292bdce9 | |||
| 4eee023648 | |||
| 8f4b0fce49 | |||
| c6b3127b35 | |||
| 4d6a50c2cb | |||
| 15f3947ae6 | |||
| e142e3aca7 | |||
| 38438c8d9a | |||
| a278c10c75 | |||
| 2276443c56 | |||
| bb44773e57 | |||
| 14d9e90a03 | |||
| 03e042213c | |||
| db589455f4 | |||
| fb0a54d548 | |||
| 7013cc0904 | |||
| dcaf7b4a65 | |||
| 12f7b2a005 | |||
| 7837d40f57 | |||
| b4f719653f | |||
| f370b4bac6 | |||
| d788169bf3 | |||
| eea820fa2f | |||
| 271f1cb868 | |||
| 8c8dc9d32f | |||
| fd18e55f7c | |||
| faab9e620d | |||
| 5ba3efafd8 |
@@ -75,7 +75,7 @@
|
||||
{
|
||||
"label": "Build Immich CLI",
|
||||
"type": "shell",
|
||||
"command": "pnpm --filter cli build:dev"
|
||||
"command": "pnpm --filter @immich/cli build:dev"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ services:
|
||||
volumes:
|
||||
- ${UPLOAD_LOCATION:-upload-devcontainer-volume}${UPLOAD_LOCATION:+/photos}:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- pnpm_store_server:/buildcache/pnpm-store
|
||||
- ../plugins:/build/corePlugin
|
||||
- build_cache:/buildcache
|
||||
- ../packages/plugin-core:/build/plugins/immich-plugin-core
|
||||
immich-web:
|
||||
env_file: !reset []
|
||||
immich-machine-learning:
|
||||
|
||||
@@ -8,6 +8,8 @@ log "Preparing Immich Web Frontend"
|
||||
log ""
|
||||
run_cmd pnpm --filter @immich/sdk install
|
||||
run_cmd pnpm --filter @immich/sdk build
|
||||
run_cmd pnpm --filter @immich/plugin-sdk install
|
||||
run_cmd pnpm --filter @immich/plugin-sdk build
|
||||
run_cmd pnpm --filter immich-web install
|
||||
|
||||
log "Starting Immich Web Frontend"
|
||||
|
||||
+1
-3
@@ -30,9 +30,7 @@ machine-learning/
|
||||
misc/
|
||||
mobile/
|
||||
|
||||
open-api/typescript-sdk/build/
|
||||
!open-api/typescript-sdk/package.json
|
||||
!open-api/typescript-sdk/package-lock.json
|
||||
packages/sdk/build/
|
||||
|
||||
server/upload/
|
||||
server/src/queries
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ mobile/lib/infrastructure/repositories/db.repository.steps.dart linguist-generat
|
||||
mobile/test/drift/main/generated/** -diff -merge
|
||||
mobile/test/drift/main/generated/** linguist-generated=true
|
||||
|
||||
open-api/typescript-sdk/fetch-client.ts -diff -merge
|
||||
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
|
||||
packages/sdk/fetch-client.ts -diff -merge
|
||||
packages/sdk/fetch-client.ts linguist-generated=true
|
||||
|
||||
*.sh text eol=lf
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
custom: ['https://buy.immich.app', 'https://immich.store']
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
cli:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- cli/src/**
|
||||
- packages/cli/src/**
|
||||
|
||||
documentation:
|
||||
- changed-files:
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
outputs:
|
||||
uses_template: ${{ steps.check.outputs.uses_template }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
sparse-checkout: .github/pull_request_template.md
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
@@ -51,8 +51,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -61,7 +60,7 @@ jobs:
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token || github.token }}
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
mobile:
|
||||
- 'mobile/**'
|
||||
@@ -80,17 +79,22 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token || github.token }}
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
working_directory: ./mobile
|
||||
|
||||
- name: Create the Keystore
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
@@ -113,16 +117,8 @@ jobs:
|
||||
~/.gradle/wrapper
|
||||
~/.android/sdk
|
||||
mobile/android/.gradle
|
||||
mobile/.dart_tool
|
||||
key: build-mobile-gradle-${{ runner.os }}-main
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
cache: true
|
||||
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
|
||||
with:
|
||||
@@ -133,11 +129,10 @@ jobs:
|
||||
run: flutter pub get
|
||||
|
||||
- name: Generate translation file
|
||||
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||
working-directory: ./mobile
|
||||
run: mise //mobile:codegen:translation
|
||||
|
||||
- name: Generate platform APIs
|
||||
run: make pigeon
|
||||
run: mise //mobile:codegen:pigeon
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Build Android App Bundle
|
||||
@@ -165,21 +160,24 @@ jobs:
|
||||
|
||||
- name: Comment APK download link on PR
|
||||
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork }}
|
||||
uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3.11.0
|
||||
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
env:
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
APK_URL: ${{ steps.upload-apk.outputs.artifact-url }}
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'mobile-android-apk'
|
||||
message: |
|
||||
id: mobile-android-apk
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
body: |
|
||||
📱 **Android release APK (universal)** — `${{ env.HEAD_SHA }}`
|
||||
|
||||
Download: ${{ env.APK_URL }}
|
||||
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=${{ env.APK_URL }}" alt="QR code" />
|
||||
<details>
|
||||
<summary>QR code</summary>
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=${{ env.APK_URL }}" alt="QR code" />
|
||||
</details>
|
||||
|
||||
GitHub login required. Downloads as a zip containing a single `app-release.apk` — extract and install. Installs as a separate app (applicationId `app.alextran.immich.pr${{ github.event.pull_request.number }}`), so it coexists with the Play Store version and any other PR builds.
|
||||
Installs as a separate app (applicationId `app.alextran.immich.pr${{ github.event.pull_request.number }}`), so it coexists with the Play Store version and any other PR builds.
|
||||
|
||||
- name: Save Gradle Cache
|
||||
id: cache-gradle-save
|
||||
@@ -191,7 +189,6 @@ jobs:
|
||||
~/.gradle/wrapper
|
||||
~/.android/sdk
|
||||
mobile/android/.gradle
|
||||
mobile/.dart_tool
|
||||
key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }}
|
||||
|
||||
build-sign-ios:
|
||||
@@ -204,36 +201,43 @@ jobs:
|
||||
runs-on: macos-15
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Select Xcode 26
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
cache: true
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
working_directory: ./mobile
|
||||
|
||||
- name: Install Flutter dependencies
|
||||
working-directory: ./mobile
|
||||
run: flutter pub get
|
||||
|
||||
- name: Generate translation files
|
||||
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||
working-directory: ./mobile
|
||||
run: mise //mobile:codegen:translation
|
||||
|
||||
- name: Generate platform APIs
|
||||
run: make pigeon
|
||||
run: mise //mobile:codegen:pigeon
|
||||
|
||||
- name: Resolve iOS Swift Packages
|
||||
working-directory: ./mobile
|
||||
run: flutter build ios --config-only --no-codesign
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
|
||||
uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
|
||||
with:
|
||||
ruby-version: '3.3'
|
||||
bundler-cache: true
|
||||
@@ -290,7 +294,6 @@ jobs:
|
||||
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
||||
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
||||
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
||||
BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }}
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 120
|
||||
FASTLANE_XCODEBUILD_SETTINGS_RETRIES: 6
|
||||
|
||||
@@ -19,13 +19,13 @@ jobs:
|
||||
actions: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -4,6 +4,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'open-api/**'
|
||||
- 'mobile/lib/utils/openapi_patching.dart'
|
||||
- '.github/workflows/check-openapi.yml'
|
||||
|
||||
concurrency:
|
||||
@@ -19,13 +20,46 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check for breaking API changes
|
||||
uses: oasdiff/oasdiff-action/breaking@37bf9ff785c7315df88216660826e71be4cc03da # v0.0.44
|
||||
uses: oasdiff/oasdiff-action/breaking@a8c7f0e5649d20d623edb5b38446d3ab3d82d43c # v0.0.53
|
||||
with:
|
||||
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
|
||||
revision: open-api/immich-openapi-specs.json
|
||||
fail-on: ERR
|
||||
|
||||
check-mobile-patches:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ github.token }}
|
||||
working_directory: ./mobile
|
||||
|
||||
- name: Get packages
|
||||
working-directory: ./mobile
|
||||
run: flutter pub get
|
||||
|
||||
- name: Fetch base spec from main
|
||||
run: |
|
||||
curl -fsSL \
|
||||
"https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json" \
|
||||
-o /tmp/base-spec.json
|
||||
|
||||
- name: Check newly-required fields have a backward-compat patch
|
||||
working-directory: ./mobile
|
||||
env:
|
||||
OPENAPI_BASE_SPEC: /tmp/base-spec.json
|
||||
OPENAPI_REVISION_SPEC: ../open-api/immich-openapi-specs.json
|
||||
run: flutter test test/openapi_patches_coverage.dart
|
||||
|
||||
+19
-17
@@ -3,11 +3,11 @@ on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'cli/**'
|
||||
- 'packages/cli/**'
|
||||
- '.github/workflows/cli.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'cli/**'
|
||||
- 'packages/cli/**'
|
||||
- '.github/workflows/cli.yml'
|
||||
release:
|
||||
types: [published]
|
||||
@@ -28,28 +28,30 @@ jobs:
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
working-directory: ./packages/cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Publish
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
run: mise run ci-publish
|
||||
env:
|
||||
NPM_TAG: ${{ github.event.release.prerelease && 'rc' || 'latest' }}
|
||||
run: mise run ci-publish -- --tag "$NPM_TAG"
|
||||
|
||||
docker:
|
||||
name: Docker
|
||||
@@ -61,25 +63,25 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
registry: ghcr.io
|
||||
@@ -89,12 +91,12 @@ jobs:
|
||||
- name: Get package version
|
||||
id: package-version
|
||||
run: |
|
||||
version=$(jq -r '.version' cli/package.json)
|
||||
version=$(jq -r '.version' packages/cli/package.json)
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate docker image tags
|
||||
id: metadata
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
|
||||
with:
|
||||
flavor: |
|
||||
latest=false
|
||||
@@ -102,12 +104,12 @@ jobs:
|
||||
name=ghcr.io/${{ github.repository_owner }}/immich-cli
|
||||
tags: |
|
||||
type=raw,value=${{ steps.package-version.outputs.version }},enable=${{ github.event_name == 'release' }}
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||
with:
|
||||
file: cli/Dockerfile
|
||||
file: packages/cli/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name == 'release' }}
|
||||
cache-from: type=gha
|
||||
|
||||
@@ -14,7 +14,11 @@ jobs:
|
||||
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
|
||||
run: |
|
||||
echo "run=${{
|
||||
(github.event_name == 'issues' || github.event.discussion.category.name == 'Feature Request')
|
||||
&& !contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association || github.event.discussion.author_association)
|
||||
}}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
get_body:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -35,7 +39,7 @@ jobs:
|
||||
needs: [get_body, should_run]
|
||||
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
||||
container:
|
||||
image: ghcr.io/immich-app/mdq:main@sha256:32abe582452b12dff55055e1d6bc24508a8f17164f9d1831db7bb70953c014c6
|
||||
image: ghcr.io/immich-app/mdq:main@sha256:e73f60195b39748c4876f23e3e6cd22a68a9754acec8aef1fd6979fd52cd2c9f
|
||||
outputs:
|
||||
checked: ${{ steps.get_checkbox.outputs.checked }}
|
||||
steps:
|
||||
|
||||
@@ -44,20 +44,20 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -83,6 +83,6 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
||||
with:
|
||||
category: '/language:${{matrix.language}}'
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
|
||||
steps:
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
suffix: ['']
|
||||
steps:
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -132,7 +132,7 @@ jobs:
|
||||
suffixes: '-rocm'
|
||||
platforms: linux/amd64
|
||||
runner-mapping: '{"linux/amd64": "pokedex-large"}'
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@5813c7c4f7016c748ae7ac5d5f684846649d4d20 # multi-runner-build-workflow-v2.4.0
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@db54dcf16fbb12c43479a23749ceea0ad1b4a704 # multi-runner-build-workflow-v3.0.0
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
platforms: ${{ matrix.platforms }}
|
||||
runner-mapping: ${{ matrix.runner-mapping }}
|
||||
suffixes: ${{ matrix.suffixes }}
|
||||
dockerhub-push: ${{ github.event_name == 'release' }}
|
||||
dockerhub-push: ${{ github.event_name == 'release' && !github.event.release.prerelease }}
|
||||
build-args: |
|
||||
DEVICE=${{ matrix.device }}
|
||||
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
name: Build and Push Server
|
||||
needs: pre-job
|
||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@5813c7c4f7016c748ae7ac5d5f684846649d4d20 # multi-runner-build-workflow-v2.4.0
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@db54dcf16fbb12c43479a23749ceea0ad1b4a704 # multi-runner-build-workflow-v3.0.0
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
@@ -167,7 +167,7 @@ jobs:
|
||||
image: immich-server
|
||||
context: .
|
||||
dockerfile: server/Dockerfile
|
||||
dockerhub-push: ${{ github.event_name == 'release' }}
|
||||
dockerhub-push: ${{ github.event_name == 'release' && !github.event.release.prerelease }}
|
||||
build-args: |
|
||||
DEVICE=cpu
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -54,19 +54,19 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
artifact: ${{ steps.get-artifact.outputs.result }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -98,9 +98,16 @@ jobs:
|
||||
shouldDeploy: true
|
||||
};
|
||||
} else if (eventType == "release") {
|
||||
const tag = context.payload.workflow_run.head_branch;
|
||||
const { data: release } = await github.rest.repos.getReleaseByTag({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
tag,
|
||||
});
|
||||
parameters = {
|
||||
event: "release",
|
||||
name: context.payload.workflow_run.head_branch,
|
||||
name: tag,
|
||||
prerelease: release.prerelease,
|
||||
shouldDeploy: !isFork
|
||||
};
|
||||
}
|
||||
@@ -119,19 +126,19 @@ jobs:
|
||||
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -146,6 +153,7 @@ jobs:
|
||||
const parameters = JSON.parse(process.env.PARAM_JSON);
|
||||
core.setOutput("event", parameters.event);
|
||||
core.setOutput("name", parameters.name);
|
||||
core.setOutput("prerelease", parameters.prerelease);
|
||||
core.setOutput("shouldDeploy", parameters.shouldDeploy);
|
||||
|
||||
- name: Download artifact
|
||||
@@ -203,7 +211,7 @@ jobs:
|
||||
run: mise run //docs:deploy
|
||||
|
||||
- name: Deploy Docs Release Domain
|
||||
if: ${{ steps.parameters.outputs.event == 'release' }}
|
||||
if: ${{ steps.parameters.outputs.event == 'release' && steps.parameters.outputs.prerelease != 'true' }}
|
||||
env:
|
||||
TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
@@ -213,12 +221,11 @@ jobs:
|
||||
run: 'mise run //deployment:tf apply'
|
||||
|
||||
- name: Comment
|
||||
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
|
||||
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
||||
with:
|
||||
id: docs-pr-url
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
|
||||
body: |
|
||||
📖 Documentation deployed to [${{ steps.docs-output.outputs.subdomain }}](https://${{ steps.docs-output.outputs.subdomain }})
|
||||
emojis: 'rocket'
|
||||
body-include: '<!-- Docs PR URL -->'
|
||||
|
||||
@@ -17,19 +17,19 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -44,9 +44,8 @@ jobs:
|
||||
run: 'mise run //deployment:tf destroy -- -refresh=false'
|
||||
|
||||
- name: Comment
|
||||
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
|
||||
uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
with:
|
||||
id: docs-pr-url
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
number: ${{ github.event.number }}
|
||||
delete: true
|
||||
body-include: '<!-- Docs PR URL -->'
|
||||
|
||||
@@ -15,20 +15,20 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
persist-credentials: true
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ steps.generate-token.outputs.token }}
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.payload.pull_request.number,
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Generate a token
|
||||
id: generate_token
|
||||
if: ${{ inputs.skip != true }}
|
||||
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
@@ -13,3 +13,4 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
secrets: inherit
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
@@ -12,11 +12,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1
|
||||
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
|
||||
with:
|
||||
repo-token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -10,9 +10,13 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- 'false'
|
||||
- major
|
||||
- minor
|
||||
- patch
|
||||
- premajor
|
||||
- preminor
|
||||
- prepatch
|
||||
- prerelease
|
||||
- release
|
||||
mobileBump:
|
||||
description: 'Bump mobile build number'
|
||||
required: false
|
||||
@@ -46,38 +50,45 @@ jobs:
|
||||
outputs:
|
||||
ref: ${{ steps.push-tag.outputs.commit_long_sha }}
|
||||
version: ${{ steps.output.outputs.version }}
|
||||
rc: ${{ steps.output.outputs.rc }}
|
||||
permissions: {} # No job-level permissions are needed because it uses the app-token
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
persist-credentials: true
|
||||
ref: main
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
# TODO move to mise
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
||||
|
||||
- name: Bump version
|
||||
env:
|
||||
SERVER_BUMP: ${{ inputs.serverBump }}
|
||||
MOBILE_BUMP: ${{ inputs.mobileBump }}
|
||||
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
||||
run: pnpm --silent release -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
||||
|
||||
- id: output
|
||||
run: echo "version=$IMMICH_VERSION" >> $GITHUB_OUTPUT
|
||||
run: |
|
||||
echo "version=$IMMICH_VERSION" >> $GITHUB_OUTPUT
|
||||
if [[ "$IMMICH_VERSION" =~ -rc\.[0-9]+$ ]]; then
|
||||
echo "rc=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "rc=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Commit and tag
|
||||
id: push-tag
|
||||
@@ -93,6 +104,7 @@ jobs:
|
||||
needs: bump_version
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
secrets:
|
||||
KEY_JKS: ${{ secrets.KEY_JKS }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
@@ -119,13 +131,13 @@ jobs:
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
persist-credentials: false
|
||||
@@ -137,9 +149,10 @@ jobs:
|
||||
github-token: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
with:
|
||||
draft: true
|
||||
prerelease: ${{ needs.bump_version.outputs.rc }}
|
||||
tag_name: ${{ needs.bump_version.outputs.version }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
generate_release_notes: true
|
||||
|
||||
@@ -14,16 +14,16 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3.11.0
|
||||
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'preview-status'
|
||||
message: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.build/'
|
||||
id: preview-status
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
body: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.build/'
|
||||
|
||||
remove-label:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -48,16 +48,16 @@ jobs:
|
||||
name: 'preview'
|
||||
})
|
||||
|
||||
- uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3.11.0
|
||||
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
if: ${{ github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'preview-status'
|
||||
message: 'PRs from forks cannot have preview environments.'
|
||||
id: preview-status
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
body: 'PRs from forks cannot have preview environments.'
|
||||
|
||||
- uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3.11.0
|
||||
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'preview-status'
|
||||
message: 'Preview environment has been removed.'
|
||||
id: preview-status
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
body: 'Preview environment has been removed.'
|
||||
|
||||
@@ -14,32 +14,31 @@ jobs:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Install deps
|
||||
run: pnpm install --frozen-lockfile
|
||||
run: pnpm --filter @immich/sdk install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
run: pnpm --filter @immich/sdk build
|
||||
|
||||
- name: Publish
|
||||
run: pnpm publish --provenance --no-git-checks
|
||||
env:
|
||||
NPM_TAG: ${{ github.event.release.prerelease && 'rc' || 'latest' }}
|
||||
run: pnpm --filter @immich/sdk publish --provenance --no-git-checks --tag "$NPM_TAG"
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -49,49 +49,38 @@ jobs:
|
||||
working-directory: ./mobile
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
working_directory: ./mobile
|
||||
|
||||
- name: Install dependencies
|
||||
run: dart pub get
|
||||
run: flutter pub get
|
||||
|
||||
- name: Install dependencies for UI package
|
||||
run: dart pub get
|
||||
run: flutter pub get
|
||||
working-directory: ./mobile/packages/ui
|
||||
|
||||
- name: Install dependencies for UI Showcase
|
||||
run: dart pub get
|
||||
working-directory: ./mobile/packages/ui/showcase
|
||||
|
||||
- name: Install DCM
|
||||
uses: CQLabs/setup-dcm@8697ae0790c0852e964a6ef1d768d62a6675481a # v2.0.1
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
version: auto
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Generate translation file
|
||||
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||
- name: Generate translation files
|
||||
run: mise //mobile:codegen:translation
|
||||
|
||||
- name: Run Build Runner
|
||||
run: make build
|
||||
run: mise //mobile:codegen:dart
|
||||
|
||||
- name: Generate platform API
|
||||
run: make pigeon
|
||||
run: mise //mobile:codegen:pigeon
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||
@@ -101,26 +90,24 @@ jobs:
|
||||
mobile/**/*.g.dart
|
||||
mobile/**/*.gr.dart
|
||||
mobile/**/*.drift.dart
|
||||
mobile/**/*.g.swift
|
||||
mobile/**/*.g.kt
|
||||
|
||||
- name: Verify files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
|
||||
run: |
|
||||
echo "ERROR: Generated files not up to date! Run 'make build' and 'make pigeon' inside the mobile directory"
|
||||
echo "ERROR: Generated files not up to date! Run 'mise //mobile:codegen:dart' and 'mise //mobile:codegen:pigeon'"
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
exit 1
|
||||
|
||||
- name: Run dart analyze
|
||||
run: dart analyze --fatal-infos
|
||||
- name: Run analyze
|
||||
run: mise //mobile:analyze
|
||||
|
||||
- name: Run dart format
|
||||
run: make format
|
||||
- name: Run format
|
||||
run: mise //mobile:format
|
||||
|
||||
# TODO: Re-enable after upgrading custom_lint
|
||||
# - name: Run dart custom_lint
|
||||
# run: dart run custom_lint
|
||||
|
||||
# TODO: Use https://github.com/CQLabs/dcm-action
|
||||
- name: Run DCM
|
||||
run: dcm analyze lib --fatal-style --fatal-warnings
|
||||
|
||||
+130
-104
@@ -17,7 +17,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -28,33 +28,72 @@ jobs:
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
root:
|
||||
- 'misc/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'mise.toml'
|
||||
i18n:
|
||||
- 'i18n/**'
|
||||
- 'mise.toml'
|
||||
web:
|
||||
- 'web/**'
|
||||
- 'i18n/**'
|
||||
- 'open-api/typescript-sdk/**'
|
||||
- 'packages/sdk/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'mise.toml'
|
||||
server:
|
||||
- 'server/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'mise.toml'
|
||||
cli:
|
||||
- 'cli/**'
|
||||
- 'open-api/typescript-sdk/**'
|
||||
- 'packages/cli/**'
|
||||
- 'packages/sdk/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'mise.toml'
|
||||
e2e:
|
||||
- 'e2e/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'mise.toml'
|
||||
mobile:
|
||||
- 'mobile/**'
|
||||
- 'mise.toml'
|
||||
machine-learning:
|
||||
- 'machine-learning/**'
|
||||
- 'mise.toml'
|
||||
.github:
|
||||
- '.github/**'
|
||||
force-filters: |
|
||||
- '.github/workflows/test.yml'
|
||||
force-events: 'workflow_dispatch'
|
||||
|
||||
root-unit-tests:
|
||||
name: Test the root workspace
|
||||
needs: pre-job
|
||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).root == true }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Run unit tests
|
||||
run: pnpm test
|
||||
|
||||
server-unit-tests:
|
||||
name: Test & Lint Server
|
||||
needs: pre-job
|
||||
@@ -62,29 +101,26 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Run ci-unit
|
||||
run: mise run ci-unit
|
||||
run: mise run //server:ci-unit
|
||||
|
||||
cli-unit-tests:
|
||||
name: Unit Test CLI
|
||||
@@ -95,22 +131,22 @@ jobs:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
working-directory: ./packages/cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -126,34 +162,29 @@ jobs:
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./cli
|
||||
working-directory: ./packages/cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
- name: Setup typescript-sdk
|
||||
run: pnpm install --frozen-lockfile && pnpm build
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Install deps
|
||||
- name: Run setup @immich/sdk
|
||||
run: mise run //:sdk:install && mise run //:sdk:build
|
||||
|
||||
- name: Run pnpm install
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
# Skip linter & formatter in Windows test.
|
||||
@@ -178,23 +209,23 @@ jobs:
|
||||
working-directory: ./web
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Run setup typescript-sdk
|
||||
- name: Run setup @immich/sdk
|
||||
run: mise run //:sdk:install && mise run //:sdk:build
|
||||
|
||||
- name: Run pnpm install
|
||||
@@ -216,19 +247,19 @@ jobs:
|
||||
working-directory: ./web
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -244,27 +275,27 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm --filter=immich-i18n install --frozen-lockfile
|
||||
run: pnpm -w install --frozen-lockfile
|
||||
|
||||
- name: Format
|
||||
run: pnpm --filter=immich-i18n format:fix
|
||||
run: pnpm format:fix
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||
@@ -294,19 +325,19 @@ jobs:
|
||||
working-directory: ./e2e
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -326,20 +357,20 @@ jobs:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -362,20 +393,20 @@ jobs:
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
@@ -384,20 +415,14 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
|
||||
- name: Setup typescript-sdk
|
||||
run: pnpm install --frozen-lockfile && pnpm build
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
- name: Setup packages
|
||||
run: pnpm --filter @immich/sdk --filter @immich/cli install --frozen-lockfile && pnpm --filter @immich/sdk --filter @immich/cli build
|
||||
|
||||
- name: Run setup web
|
||||
run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync
|
||||
working-directory: ./web
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
- name: Run setup cli
|
||||
run: pnpm install --frozen-lockfile && pnpm build
|
||||
working-directory: ./cli
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
if: ${{ !cancelled() }}
|
||||
@@ -445,20 +470,20 @@ jobs:
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
@@ -467,9 +492,8 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
|
||||
- name: Run setup typescript-sdk
|
||||
run: pnpm install --frozen-lockfile && pnpm build
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
- name: Run setup @immich/sdk
|
||||
run: pnpm --filter @immich/sdk install --frozen-lockfile && pnpm --filter @immich/sdk build
|
||||
|
||||
if: ${{ !cancelled() }}
|
||||
- name: Install dependencies
|
||||
@@ -554,26 +578,32 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
- name: Generate translation file
|
||||
run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
working_directory: ./mobile
|
||||
|
||||
- name: Install dependencies
|
||||
run: flutter pub get
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Generate translation files
|
||||
run: mise //mobile:codegen:translation
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ./mobile
|
||||
run: flutter test -j 1
|
||||
run: mise //mobile:test
|
||||
|
||||
ml-unit-tests:
|
||||
name: Unit Test ML
|
||||
needs: pre-job
|
||||
@@ -586,18 +616,18 @@ jobs:
|
||||
working-directory: ./machine-learning
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -616,19 +646,19 @@ jobs:
|
||||
working-directory: ./.github
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
@@ -646,12 +676,12 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
@@ -667,30 +697,26 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Install server dependencies
|
||||
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich install --frozen-lockfile
|
||||
|
||||
- name: Build the app
|
||||
run: pnpm --filter immich build
|
||||
|
||||
- name: Run API generation
|
||||
run: ./bin/generate-open-api.sh
|
||||
run: mise //:open-api
|
||||
working-directory: open-api
|
||||
|
||||
- name: Find file changes
|
||||
@@ -699,7 +725,7 @@ jobs:
|
||||
with:
|
||||
files: |
|
||||
mobile/openapi
|
||||
open-api/typescript-sdk
|
||||
packages/sdk
|
||||
open-api/immich-openapi-specs.json
|
||||
|
||||
- name: Verify files have not changed
|
||||
@@ -727,42 +753,42 @@ jobs:
|
||||
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@01a4d354b70f99a6baf4a1b72827f6d4922e4978 # use-mise-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2
|
||||
with:
|
||||
github_token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Install server dependencies
|
||||
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build plugins
|
||||
run: mise //:plugins
|
||||
|
||||
- name: Build the app
|
||||
run: pnpm build
|
||||
run: mise //server:build
|
||||
|
||||
- name: Run existing migrations
|
||||
run: pnpm migrations:run
|
||||
run: pnpm --filter immich migrations:run
|
||||
|
||||
- name: Test npm run schema:reset command works
|
||||
run: pnpm schema:reset
|
||||
run: pnpm --filter immich schema:reset
|
||||
|
||||
- name: Generate new migrations
|
||||
continue-on-error: true
|
||||
run: pnpm migrations:generate src/TestMigration
|
||||
run: pnpm --filter migrations:generate src/TestMigration
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||
@@ -778,11 +804,11 @@ jobs:
|
||||
run: |
|
||||
echo "ERROR: Generated migration files not up to date!"
|
||||
echo "Changed files: ${CHANGED_FILES}"
|
||||
cat ./src/*-TestMigration.ts
|
||||
cat ./server/src/*-TestMigration.ts
|
||||
exit 1
|
||||
|
||||
- name: Run SQL generation
|
||||
run: pnpm sync:sql
|
||||
run: mise //:sql
|
||||
env:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
i18n:
|
||||
- modified: 'i18n/!(en|package)**\.json'
|
||||
- modified: 'i18n/!(en)**\.json'
|
||||
skip-force-logic: 'true'
|
||||
|
||||
enforce-lock:
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
|
||||
uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
|
||||
with:
|
||||
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ mobile/openapi/doc
|
||||
mobile/openapi/.openapi-generator/FILES
|
||||
mobile/ios/build
|
||||
|
||||
open-api/typescript-sdk/build
|
||||
packages/**/build
|
||||
mobile/android/fastlane/report.xml
|
||||
mobile/ios/fastlane/report.xml
|
||||
|
||||
|
||||
Vendored
+6
-4
@@ -23,15 +23,17 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Immich CLI",
|
||||
"program": "${workspaceFolder}/cli/dist/index.js",
|
||||
"program": "${workspaceFolder}/packages/cli/dist/index.js",
|
||||
"args": ["upload", "--help"],
|
||||
"runtimeArgs": ["--enable-source-maps"],
|
||||
"console": "integratedTerminal",
|
||||
"resolveSourceMapLocations": ["${workspaceFolder}/cli/dist/**/*.js.map"],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/packages/cli/dist/**/*.js.map"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceFolder}/cli/dist/**/*.js"],
|
||||
"outFiles": ["${workspaceFolder}/packages/cli/dist/**/*.js"],
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"preLaunchTask": "Build Immich CLI"
|
||||
"preLaunchTask": "Build @immich/cli"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -60,6 +60,7 @@
|
||||
"explorer.fileNesting.patterns": {
|
||||
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
||||
"*.ts": "${capture}.spec.ts,${capture}.mock.ts",
|
||||
"*.js": "${capture}.spec.js,${capture}.mock.js",
|
||||
"package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, bun.lock, pnpm-workspace.yaml, .pnpmfile.cjs"
|
||||
},
|
||||
"search.exclude": {
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
/web/ @danieldietzler
|
||||
/machine-learning/ @mertalev
|
||||
/e2e/ @danieldietzler
|
||||
/mobile/ @shenlong-tanwen
|
||||
/mobile/ @shenlong-tanwen @santoshakil
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation
|
||||
in our community a harassment-free experience for everyone, regardless
|
||||
of age, body size, visible or invisible disability, ethnicity, sex
|
||||
characteristics, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance,
|
||||
race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open,
|
||||
welcoming, diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for
|
||||
our community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our
|
||||
mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or
|
||||
political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in
|
||||
a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our
|
||||
standards of acceptable behavior and will take appropriate and fair
|
||||
corrective action in response to any behavior that they deem
|
||||
inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit,
|
||||
or reject comments, commits, code, wiki edits, issues, and other
|
||||
contributions that are not aligned to this Code of Conduct, and will
|
||||
communicate reasons for moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also
|
||||
applies when an individual is officially representing the community in
|
||||
public spaces. Examples of representing our community include using an
|
||||
official e-mail address, posting via an official social media account,
|
||||
or acting as an appointed representative at an online or offline
|
||||
event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior
|
||||
may be reported to the community leaders responsible for enforcement
|
||||
at our Discord channel. All complaints
|
||||
will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and
|
||||
security of the reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in
|
||||
determining the consequences for any action they deem in violation of
|
||||
this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior
|
||||
deemed unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders,
|
||||
providing clarity around the nature of the violation and an
|
||||
explanation of why the behavior was inappropriate. A public apology
|
||||
may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued
|
||||
behavior. No interaction with the people involved, including
|
||||
unsolicited interaction with those enforcing the Code of Conduct, for
|
||||
a specified period of time. This includes avoiding interactions in
|
||||
community spaces as well as external channels like social
|
||||
media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards,
|
||||
including sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or
|
||||
public communication with the community for a specified period of
|
||||
time. No public or private interaction with the people involved,
|
||||
including unsolicited interaction with those enforcing the Code of
|
||||
Conduct, is allowed during this period. Violating these terms may lead
|
||||
to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of
|
||||
community standards, including sustained inappropriate behavior,
|
||||
harassment of an individual, or aggression toward or disparagement of
|
||||
classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction
|
||||
within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor
|
||||
Covenant][homepage], version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of
|
||||
conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the
|
||||
FAQ at https://www.contributor-covenant.org/faq. Translations are
|
||||
available at https://www.contributor-covenant.org/translations.
|
||||
@@ -1,152 +1,58 @@
|
||||
dev:
|
||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise dev # or mise //:dev from another directory\n\n" >&2 && exit 1
|
||||
|
||||
dev-down:
|
||||
docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise dev-down # or mise //:dev-down from another directory\n\n" >&2 && exit 1
|
||||
|
||||
dev-update:
|
||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise dev-update # or mise //:dev-update from another directory\n\n" >&2 && exit 1
|
||||
|
||||
dev-scale:
|
||||
@trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise dev-scale # or mise //:dev-scale from another directory\n\n" >&2 && exit 1
|
||||
|
||||
dev-docs:
|
||||
npm --prefix docs run start
|
||||
|
||||
.PHONY: e2e
|
||||
e2e:
|
||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise e2e # or mise //:e2e from another directory\n\n" >&2 && exit 1
|
||||
|
||||
e2e-dev:
|
||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise e2e-dev # or mise //:e2e-dev from another directory\n\n" >&2 && exit 1
|
||||
|
||||
e2e-update:
|
||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise e2e-update # or mise //:e2e-update from another directory\n\n" >&2 && exit 1
|
||||
|
||||
e2e-down:
|
||||
docker compose -f ./e2e/docker-compose.yml down --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise e2e-down # or mise //:e2e-down from another directory\n\n" >&2 && exit 1
|
||||
|
||||
prod:
|
||||
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise prod # or mise //:prod from another directory\n\n" >&2 && exit 1
|
||||
|
||||
prod-down:
|
||||
docker compose -f ./docker/docker-compose.prod.yml down --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise prod-down # or mise //:prod-down from another directory\n\n" >&2 && exit 1
|
||||
|
||||
prod-scale:
|
||||
@trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans
|
||||
@printf "This command has been removed. Please use:\n\n mise prod-scale # or mise //:prod-scale from another directory\n\n" >&2 && exit 1
|
||||
|
||||
.PHONY: open-api
|
||||
open-api:
|
||||
cd ./open-api && bash ./bin/generate-open-api.sh
|
||||
|
||||
open-api-dart:
|
||||
cd ./open-api && bash ./bin/generate-open-api.sh dart
|
||||
|
||||
open-api-typescript:
|
||||
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
||||
@printf "This command has been removed. Please use:\n\n mise open-api # or mise //:open-api from another directory\n\n" >&2 && exit 1
|
||||
|
||||
sql:
|
||||
pnpm --filter immich run sync:sql
|
||||
@printf "This command has been removed. Please use:\n\n mise sql # or mise //:sql from another directory\n\n" >&2 && exit 1
|
||||
|
||||
attach-server:
|
||||
docker exec -it docker_immich-server_1 sh
|
||||
|
||||
renovate:
|
||||
LOG_LEVEL=debug pnpm exec renovate --platform=local --repository-cache=reset
|
||||
|
||||
# Directories that need to be created for volumes or build output
|
||||
VOLUME_DIRS = \
|
||||
./.pnpm-store \
|
||||
./web/.svelte-kit \
|
||||
./web/node_modules \
|
||||
./web/coverage \
|
||||
./e2e/node_modules \
|
||||
./docs/node_modules \
|
||||
./server/node_modules \
|
||||
./open-api/typescript-sdk/node_modules \
|
||||
./.github/node_modules \
|
||||
./node_modules \
|
||||
./cli/node_modules
|
||||
|
||||
# Include .env file if it exists
|
||||
-include docker/.env
|
||||
|
||||
MODULES = e2e server web cli sdk docs .github
|
||||
|
||||
# directory to package name mapping function
|
||||
# cli = @immich/cli
|
||||
# docs = documentation
|
||||
# e2e = immich-e2e
|
||||
# open-api/typescript-sdk = @immich/sdk
|
||||
# server = immich
|
||||
# web = immich-web
|
||||
map-package = $(subst sdk,@immich/sdk,$(subst cli,@immich/cli,$(subst docs,documentation,$(subst e2e,immich-e2e,$(subst server,immich,$(subst web,immich-web,$1))))))
|
||||
|
||||
audit-%:
|
||||
pnpm --filter $(call map-package,$*) audit fix
|
||||
install-%:
|
||||
pnpm --filter $(call map-package,$*) install $(if $(FROZEN),--frozen-lockfile) $(if $(OFFLINE),--offline)
|
||||
build-cli: build-sdk
|
||||
build-web: build-sdk
|
||||
build-%: install-%
|
||||
pnpm --filter $(call map-package,$*) run build
|
||||
format-%:
|
||||
pnpm --filter $(call map-package,$*) run format:fix
|
||||
lint-%:
|
||||
pnpm --filter $(call map-package,$*) run lint:fix
|
||||
check-%:
|
||||
pnpm --filter $(call map-package,$*) run check
|
||||
check-web:
|
||||
pnpm --filter immich-web run check:typescript
|
||||
pnpm --filter immich-web run check:svelte
|
||||
test-%:
|
||||
pnpm --filter $(call map-package,$*) run test
|
||||
test-e2e:
|
||||
docker compose -f ./e2e/docker-compose.yml build
|
||||
pnpm --filter immich-e2e run test
|
||||
pnpm --filter immich-e2e run test:web
|
||||
test-medium:
|
||||
docker run \
|
||||
--rm \
|
||||
-v ./server/src:/usr/src/app/src \
|
||||
-v ./server/test:/usr/src/app/test \
|
||||
-v ./server/vitest.config.medium.mjs:/usr/src/app/vitest.config.medium.mjs \
|
||||
-v ./server/tsconfig.json:/usr/src/app/tsconfig.json \
|
||||
-e NODE_ENV=development \
|
||||
immich-server:latest \
|
||||
-c "pnpm test:medium -- --run"
|
||||
test-medium-dev:
|
||||
docker exec -it immich_server /bin/sh -c "pnpm run test:medium"
|
||||
|
||||
install-all:
|
||||
pnpm -r --filter '!documentation' install
|
||||
|
||||
build-all: $(foreach M,$(filter-out e2e docs .github,$(MODULES)),build-$M) ;
|
||||
|
||||
check-all:
|
||||
pnpm -r --filter '!documentation' run "/^(check|check\:svelte|check\:typescript)$/"
|
||||
lint-all:
|
||||
pnpm -r --filter '!documentation' run lint:fix
|
||||
format-all:
|
||||
pnpm -r --filter '!documentation' run format:fix
|
||||
audit-all:
|
||||
pnpm -r --filter '!documentation' audit fix
|
||||
hygiene-all: audit-all
|
||||
pnpm -r --filter '!documentation' run "/(format:fix|check|check:svelte|check:typescript|sql)/"
|
||||
|
||||
test-all:
|
||||
pnpm -r --filter '!documentation' run "/^test/"
|
||||
@printf "This command has been removed. Please use:\n\n mise //e2e:test # or mise //e2e:test-web for web tests, respectively\n\n" >&2 && exit 1
|
||||
|
||||
clean:
|
||||
find . -name "node_modules" -type d -prune -exec rm -rf {} +
|
||||
find . -name "dist" -type d -prune -exec rm -rf '{}' +
|
||||
find . -name "build" -type d -prune -exec rm -rf '{}' +
|
||||
find . -name ".svelte-kit" -type d -prune -exec rm -rf '{}' +
|
||||
find . -name "coverage" -type d -prune -exec rm -rf '{}' +
|
||||
find . -name ".pnpm-store" -type d -prune -exec rm -rf '{}' +
|
||||
command -v docker >/dev/null 2>&1 && docker compose -f ./docker/docker-compose.dev.yml down -v --remove-orphans || true
|
||||
command -v docker >/dev/null 2>&1 && docker compose -f ./e2e/docker-compose.yml down -v --remove-orphans || true
|
||||
|
||||
|
||||
setup-server-dev: install-server
|
||||
setup-web-dev: install-sdk build-sdk install-web
|
||||
@printf "This command has been removed. Please use:\n\n mise clean # or mise //:clean from another directory\n\n" >&2 && exit 1
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report security issues to `security@immich.app`
|
||||
@@ -1,14 +0,0 @@
|
||||
FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a7dea969802d7e0c2b25 AS core
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
COPY package* pnpm* .pnpmfile.cjs ./
|
||||
COPY ./cli ./cli/
|
||||
COPY ./open-api/typescript-sdk ./open-api/typescript-sdk/
|
||||
RUN corepack enable pnpm && \
|
||||
pnpm install --filter @immich/sdk --filter @immich/cli --frozen-lockfile && \
|
||||
pnpm --filter @immich/sdk build && \
|
||||
pnpm --filter @immich/cli build
|
||||
|
||||
WORKDIR /import
|
||||
|
||||
ENTRYPOINT ["node", "/usr/src/app/cli/dist"]
|
||||
@@ -0,0 +1,65 @@
|
||||
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
|
||||
|
||||
[[tools.opentofu]]
|
||||
version = "1.11.6"
|
||||
backend = "aqua:opentofu/opentofu"
|
||||
|
||||
[tools.opentofu."platforms.linux-arm64"]
|
||||
checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.linux-arm64-musl"]
|
||||
checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.linux-x64"]
|
||||
checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.linux-x64-musl"]
|
||||
checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.macos-arm64"]
|
||||
checksum = "sha256:62d7fa8539e13b444827aa0a3b90c5972da5c47e8f8882d9dcf2e430e78840c1"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_arm64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.macos-x64"]
|
||||
checksum = "sha256:1408cdef1c380f914565e6b4bb70794c6b163f195fcb233357f3d6c5745906b6"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_amd64.tar.gz"
|
||||
|
||||
[tools.opentofu."platforms.windows-x64"]
|
||||
checksum = "sha256:27323f70c875b8251bfd7e61a4cffc3ebff4e56ed1e611b955016f0c7077367e"
|
||||
url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_windows_amd64.tar.gz"
|
||||
|
||||
[[tools.terragrunt]]
|
||||
version = "1.0.3"
|
||||
backend = "aqua:gruntwork-io/terragrunt"
|
||||
|
||||
[tools.terragrunt."platforms.linux-arm64"]
|
||||
checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.linux-arm64-musl"]
|
||||
checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.linux-x64"]
|
||||
checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.linux-x64-musl"]
|
||||
checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.macos-arm64"]
|
||||
checksum = "sha256:aacb5be2ca5475300cbce246dfbd8a45eb47510fbaa70fab8561c49ef5db03aa"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_arm64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.macos-x64"]
|
||||
checksum = "sha256:3133c2251e191aede8e3dd2a5b3aee2e91c5f08f88f117aee40eed9a24c8ef6b"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_amd64.tar.gz"
|
||||
|
||||
[tools.terragrunt."platforms.windows-x64"]
|
||||
checksum = "sha256:183b2745b4e04980a6bfa4450ff81956a12596ca22d70f7aaa793980f5b036db"
|
||||
url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_windows_amd64.exe.tar.gz"
|
||||
+30
-30
@@ -2,37 +2,37 @@
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "4.52.5"
|
||||
constraints = "4.52.5"
|
||||
version = "4.52.7"
|
||||
constraints = "4.52.7"
|
||||
hashes = [
|
||||
"h1:+rfzF+16ZcWZWnTyW/p1HHTzYbPKX8Zt2nIFtR/+f+E=",
|
||||
"h1:18bXaaOSq8MWKuMxo/4y7EB7/i7G90y5QsKHZRmkoDo=",
|
||||
"h1:4vZVOpKeEQZsF2VrARRZFeL37Ed/gD4rRMtfnvWQres=",
|
||||
"h1:BZOsTF83QPKXTAaYqxPKzdl1KRjk/L2qbPpFjM0w28A=",
|
||||
"h1:CDuC+HXLvc1z6wkCRsSDcc/+QENIHEtssYshiWg3opA=",
|
||||
"h1:DE+YFzLnqSe79pI2R4idRGx5QzLdrA7RXvngTkGfZ30=",
|
||||
"h1:DfaJwH3Ml4yrRbdAY4AcDVy0QTQk5T3A622TXzS/u2E=",
|
||||
"h1:EIDXP0W3kgIv2pecrFmqtK/DnlqkyckzBzhxKaXU+4A=",
|
||||
"h1:EV4kYyaOnwGA0bh/3hU6Ezqnt1PFDxopH7i85e48IzY=",
|
||||
"h1:M0iXabfzamU+MPDi0G9XACpbacFKMakmM+Z9HZ8HrsM=",
|
||||
"h1:YWmCbGF/KbsrUzcYVBLscwLizidbp95TDQa0N2qpmVo=",
|
||||
"h1:cxPcCB5gbrpUO1+IXkQYs1YTY50/0IlApCzGea0cwuQ=",
|
||||
"h1:g6DldikTV2HXUu9uoeNY5FuLufgaYWF4ufgZg7wq62s=",
|
||||
"h1:oi/Hrx9pwoQ+Z52CBC+rrowVH387EIj0qvnxQgDeI+0=",
|
||||
"zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b",
|
||||
"zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a",
|
||||
"zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7",
|
||||
"zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238",
|
||||
"zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b",
|
||||
"zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072",
|
||||
"zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661",
|
||||
"zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c",
|
||||
"h1:+O72J3QYiZtYmYYZM/Eh0f4NNfl1BvjX1eju43qTQsQ=",
|
||||
"h1:0oqjYIPXcXh7XiDiKI085cHDYQQ5mh8kDl9dmBtvtog=",
|
||||
"h1:4b4ESb87MGv5bnadgYe7sK5rEkKMZhbkQcwPubQTsR4=",
|
||||
"h1:6mTr3eA1Ddb348lLmJuyvn98z4KF+ejqaUEJ76D1rzQ=",
|
||||
"h1:9/3YH+9k9HqsvFtbmBf7SO2+xqZeZrXNKzLkjNuhUEA=",
|
||||
"h1:Jcq4tBWgyH4/2JsojNBSRaN0mcItVMchO+lynonrlqc=",
|
||||
"h1:Y4Vv/2RdP0Q+uxqhOxzOdKxuuEMjXPDcU0vPc5bCQzI=",
|
||||
"h1:a0gW8FBKsbP9Fi0HEDoy49WIbEWVHk9+BR4/iwuBdDQ=",
|
||||
"h1:gElv6iqJtg8OKN77gbw+MjrkrQmJHPkkMEi1J+0xkpU=",
|
||||
"h1:oslXUugD/NQ+duJgT4BhKQyfGbuFOANknMvR73fiOeM=",
|
||||
"h1:pPItIWii5oymR+geZB219ROSPuSODPLTlM4S/u8xLvM=",
|
||||
"h1:u67GWw8GwD9NDlDzp9Y5VRnSQGcCrE8rSpkGPaBpDl0=",
|
||||
"h1:uUUa9dY0XQOycI8pxg16PFFtL0WCTi9uEJz8trTQ7pU=",
|
||||
"h1:y3rV8KF2q6GEMANNlf5EkKJurlfbKlIKpjGcdxoy7pQ=",
|
||||
"zh:0c904ce31a4c6c4a5b3bf7ff1560e77c0cc7e2450c8553ded8e8c90398e1418b",
|
||||
"zh:36183d310c36373fe4cb936b83c595c6fd3b0a94bc7827f28e5789ccbf59752e",
|
||||
"zh:556a568a6f0235e8f41647de9e4d3a1e7b1d6502df8b19b54ec441f1c653ea10",
|
||||
"zh:633ebbd5b0245e75e500ef9be4d9e62288f97e8da3baaa51323892a786d90285",
|
||||
"zh:6acfe60cf52a65ba8f044f748548d2119e7f4fd7f8ebcb14698960d87c68f529",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54",
|
||||
"zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852",
|
||||
"zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0",
|
||||
"zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5",
|
||||
"zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036",
|
||||
"zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803",
|
||||
"zh:904acc31ebb9d6ef68c792074b30532ee61bf515f19e0a3c75b46f126cca1f13",
|
||||
"zh:a1d0a81246afc8750286d3f6fe7a8fbe6460dd2662407b28dbfbabb612e5fa9d",
|
||||
"zh:a41a36fe253fc365fe2b7ffc749624688b2693b4634862fda161179ab100029f",
|
||||
"zh:a7ef269e77ffa8715c8945a2c14322c7ff159ea44c15f62505f3cbb2cae3b32d",
|
||||
"zh:b01aa3bed30610633b762df64332b26f8844a68c3960cebcb30f04918efc67fe",
|
||||
"zh:b069cc2cd18cae10757df3ae030508eac8d55de7e49eda7a5e3e11f2f7fe6455",
|
||||
"zh:b2d2c6313729ebb7465dceece374049e2d08bda34473901be9ff46a8836d42b2",
|
||||
"zh:db0e114edaf4bc2f3d4769958807c83022bfbc619a00bdf4c4bd17faa4ab2d8b",
|
||||
"zh:ecc0aa8b9044f664fd2aaf8fa992d976578f78478980555b4b8f6148e8d1a5fe",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "4.52.5"
|
||||
version = "4.52.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-30
@@ -2,37 +2,37 @@
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "4.52.5"
|
||||
constraints = "4.52.5"
|
||||
version = "4.52.7"
|
||||
constraints = "4.52.7"
|
||||
hashes = [
|
||||
"h1:+rfzF+16ZcWZWnTyW/p1HHTzYbPKX8Zt2nIFtR/+f+E=",
|
||||
"h1:18bXaaOSq8MWKuMxo/4y7EB7/i7G90y5QsKHZRmkoDo=",
|
||||
"h1:4vZVOpKeEQZsF2VrARRZFeL37Ed/gD4rRMtfnvWQres=",
|
||||
"h1:BZOsTF83QPKXTAaYqxPKzdl1KRjk/L2qbPpFjM0w28A=",
|
||||
"h1:CDuC+HXLvc1z6wkCRsSDcc/+QENIHEtssYshiWg3opA=",
|
||||
"h1:DE+YFzLnqSe79pI2R4idRGx5QzLdrA7RXvngTkGfZ30=",
|
||||
"h1:DfaJwH3Ml4yrRbdAY4AcDVy0QTQk5T3A622TXzS/u2E=",
|
||||
"h1:EIDXP0W3kgIv2pecrFmqtK/DnlqkyckzBzhxKaXU+4A=",
|
||||
"h1:EV4kYyaOnwGA0bh/3hU6Ezqnt1PFDxopH7i85e48IzY=",
|
||||
"h1:M0iXabfzamU+MPDi0G9XACpbacFKMakmM+Z9HZ8HrsM=",
|
||||
"h1:YWmCbGF/KbsrUzcYVBLscwLizidbp95TDQa0N2qpmVo=",
|
||||
"h1:cxPcCB5gbrpUO1+IXkQYs1YTY50/0IlApCzGea0cwuQ=",
|
||||
"h1:g6DldikTV2HXUu9uoeNY5FuLufgaYWF4ufgZg7wq62s=",
|
||||
"h1:oi/Hrx9pwoQ+Z52CBC+rrowVH387EIj0qvnxQgDeI+0=",
|
||||
"zh:1a3400cb38863b2585968d1876706bcfc67a148e1318a1d325c6c7704adc999b",
|
||||
"zh:4c5062cb9e9da1676f06ae92b8370186d98976cc4c7030d3cd76df12af54282a",
|
||||
"zh:52110f493b5f0587ef77a1cfd1a67001fd4c617b14c6502d732ab47352bdc2f7",
|
||||
"zh:5aa536f9eaeb43823aaf2aa80e7d39b25ef2b383405ed034aa16a28b446a9238",
|
||||
"zh:5cc39459a1c6be8a918f17054e4fbba573825ed5597dcada588fe99614d98a5b",
|
||||
"zh:629ae6a7ba298815131da826474d199312d21cec53a4d5ded4fa56a692e6f072",
|
||||
"zh:719cc7c75dc1d3eb30c22ff5102a017996d9788b948078c7e1c5b3446aeca661",
|
||||
"zh:8698635a3ca04383c1e93b21d6963346bdae54d27177a48e4b1435b7f731731c",
|
||||
"h1:+O72J3QYiZtYmYYZM/Eh0f4NNfl1BvjX1eju43qTQsQ=",
|
||||
"h1:0oqjYIPXcXh7XiDiKI085cHDYQQ5mh8kDl9dmBtvtog=",
|
||||
"h1:4b4ESb87MGv5bnadgYe7sK5rEkKMZhbkQcwPubQTsR4=",
|
||||
"h1:6mTr3eA1Ddb348lLmJuyvn98z4KF+ejqaUEJ76D1rzQ=",
|
||||
"h1:9/3YH+9k9HqsvFtbmBf7SO2+xqZeZrXNKzLkjNuhUEA=",
|
||||
"h1:Jcq4tBWgyH4/2JsojNBSRaN0mcItVMchO+lynonrlqc=",
|
||||
"h1:Y4Vv/2RdP0Q+uxqhOxzOdKxuuEMjXPDcU0vPc5bCQzI=",
|
||||
"h1:a0gW8FBKsbP9Fi0HEDoy49WIbEWVHk9+BR4/iwuBdDQ=",
|
||||
"h1:gElv6iqJtg8OKN77gbw+MjrkrQmJHPkkMEi1J+0xkpU=",
|
||||
"h1:oslXUugD/NQ+duJgT4BhKQyfGbuFOANknMvR73fiOeM=",
|
||||
"h1:pPItIWii5oymR+geZB219ROSPuSODPLTlM4S/u8xLvM=",
|
||||
"h1:u67GWw8GwD9NDlDzp9Y5VRnSQGcCrE8rSpkGPaBpDl0=",
|
||||
"h1:uUUa9dY0XQOycI8pxg16PFFtL0WCTi9uEJz8trTQ7pU=",
|
||||
"h1:y3rV8KF2q6GEMANNlf5EkKJurlfbKlIKpjGcdxoy7pQ=",
|
||||
"zh:0c904ce31a4c6c4a5b3bf7ff1560e77c0cc7e2450c8553ded8e8c90398e1418b",
|
||||
"zh:36183d310c36373fe4cb936b83c595c6fd3b0a94bc7827f28e5789ccbf59752e",
|
||||
"zh:556a568a6f0235e8f41647de9e4d3a1e7b1d6502df8b19b54ec441f1c653ea10",
|
||||
"zh:633ebbd5b0245e75e500ef9be4d9e62288f97e8da3baaa51323892a786d90285",
|
||||
"zh:6acfe60cf52a65ba8f044f748548d2119e7f4fd7f8ebcb14698960d87c68f529",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:8a9993f1dcadf1dd6ca43b23348abe374605d29945a2fafc07fb3457644e6a54",
|
||||
"zh:b1b9a1e6bcc24d5863a664a411d2dc906373ae7a2399d2d65548ce7377057852",
|
||||
"zh:b270184cdeec277218e84b94cb136fead753da717f9b9dc378e51907f3f00bb0",
|
||||
"zh:dff2bc10071210181726ce270f954995fe42c696e61e2e8f874021fed02521e5",
|
||||
"zh:e8e87b40b6a87dc097b0fdc20d3f725cec0d82abc9cc3755c1f89f8f6e8b0036",
|
||||
"zh:ee964a6573d399a5dd22ce328fb38ca1207797a02248f14b2e4913ee390e7803",
|
||||
"zh:904acc31ebb9d6ef68c792074b30532ee61bf515f19e0a3c75b46f126cca1f13",
|
||||
"zh:a1d0a81246afc8750286d3f6fe7a8fbe6460dd2662407b28dbfbabb612e5fa9d",
|
||||
"zh:a41a36fe253fc365fe2b7ffc749624688b2693b4634862fda161179ab100029f",
|
||||
"zh:a7ef269e77ffa8715c8945a2c14322c7ff159ea44c15f62505f3cbb2cae3b32d",
|
||||
"zh:b01aa3bed30610633b762df64332b26f8844a68c3960cebcb30f04918efc67fe",
|
||||
"zh:b069cc2cd18cae10757df3ae030508eac8d55de7e49eda7a5e3e11f2f7fe6455",
|
||||
"zh:b2d2c6313729ebb7465dceece374049e2d08bda34473901be9ff46a8836d42b2",
|
||||
"zh:db0e114edaf4bc2f3d4769958807c83022bfbc619a00bdf4c4bd17faa4ab2d8b",
|
||||
"zh:ecc0aa8b9044f664fd2aaf8fa992d976578f78478980555b4b8f6148e8d1a5fe",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "4.52.5"
|
||||
version = "4.52.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ services:
|
||||
volumes:
|
||||
- ..:/usr/src/app
|
||||
# - ../../ui:/usr/src/ui
|
||||
- pnpm_cache:/buildcache/pnpm_cache
|
||||
- build_cache:/buildcache
|
||||
- server_node_modules:/usr/src/app/server/node_modules
|
||||
- web_node_modules:/usr/src/app/web/node_modules
|
||||
- github_node_modules:/usr/src/app/.github/node_modules
|
||||
- cli_node_modules:/usr/src/app/cli/node_modules
|
||||
- cli_node_modules:/usr/src/app/packages/cli/node_modules
|
||||
- docs_node_modules:/usr/src/app/docs/node_modules
|
||||
- e2e_node_modules:/usr/src/app/e2e/node_modules
|
||||
- sdk_node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
|
||||
- sdk_node_modules:/usr/src/app/packages/sdk/node_modules
|
||||
- app_node_modules:/usr/src/app/node_modules
|
||||
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||
- coverage:/usr/src/app/web/coverage
|
||||
@@ -45,11 +45,11 @@ services:
|
||||
target: dev
|
||||
command:
|
||||
- |
|
||||
pnpm install
|
||||
mise install
|
||||
touch /tmp/init-complete
|
||||
exec tail -f /dev/null
|
||||
volumes:
|
||||
- pnpm_store_server:/buildcache/pnpm-store
|
||||
- build_cache:/buildcache
|
||||
restart: 'no'
|
||||
healthcheck:
|
||||
test: ['CMD', 'test', '-f', '/tmp/init-complete']
|
||||
@@ -73,8 +73,7 @@ services:
|
||||
volumes:
|
||||
- ${UPLOAD_LOCATION}/photos:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- pnpm_store_server:/buildcache/pnpm-store
|
||||
- ../plugins:/build/corePlugin
|
||||
- ../packages/plugin-core:/build/plugins/immich-plugin-core
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
@@ -122,8 +121,6 @@ services:
|
||||
ports:
|
||||
- 3000:3000
|
||||
- 24678:24678
|
||||
volumes:
|
||||
- pnpm_store_web:/buildcache/pnpm-store
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
immich-init:
|
||||
@@ -157,7 +154,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
|
||||
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
|
||||
@@ -203,9 +200,7 @@ volumes:
|
||||
model_cache:
|
||||
prometheus_data:
|
||||
grafana_data:
|
||||
pnpm_cache:
|
||||
pnpm_store_server:
|
||||
pnpm_store_web:
|
||||
build_cache:
|
||||
server_node_modules:
|
||||
web_node_modules:
|
||||
github_node_modules:
|
||||
|
||||
@@ -56,7 +56,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
|
||||
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
container_name: immich_prometheus
|
||||
ports:
|
||||
- 9090:9090
|
||||
image: prom/prometheus@sha256:e4254400b85610324913f0dc4acf92603d9984e7519414c5a12811aa6146acc3
|
||||
image: prom/prometheus@sha256:69f5241418838263316593f7274a304b095c40bcf22e57272865da91bd60a8ac
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- prometheus-data:/prometheus
|
||||
@@ -97,7 +97,7 @@ services:
|
||||
command: ['./run.sh', '-disable-reporting']
|
||||
ports:
|
||||
- 3000:3000
|
||||
image: grafana/grafana:12.4.3-ubuntu@sha256:ca3f764fdc48cebdf22dd206f33ecb0795a9a7210eacd1b5c02204aebd78b223
|
||||
image: grafana/grafana:12.4.4-ubuntu@sha256:df2e7ef5f32f771794cf76bad5f2bceac227036460a2cc269a9045e5662abc58
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
|
||||
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
|
||||
user: '1000:1000'
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
@@ -95,6 +95,3 @@ services:
|
||||
restart: always
|
||||
healthcheck:
|
||||
disable: false
|
||||
|
||||
volumes:
|
||||
model-cache:
|
||||
|
||||
@@ -49,7 +49,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
|
||||
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
|
||||
@@ -26,6 +26,8 @@ For organizations seeking to resell Immich, we have established the following gu
|
||||
|
||||
When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app
|
||||
|
||||
---
|
||||
|
||||
## User
|
||||
|
||||
### How can I reset the admin password?
|
||||
@@ -36,6 +38,10 @@ The admin password can be reset by running the [reset-admin-password](/administr
|
||||
|
||||
You can see the list of all users by running [list-users](/administration/server-commands.md) Command on the Immich-server.
|
||||
|
||||
### How can I change my profile picture?
|
||||
|
||||
View a single photo, press the three dots in the top-right to show context menu, and select "Set as profile picture". In the pop-up, use your mouse scroll wheel to zoom in the picture until it completely fills the circle. Click and drag the picture to align it to your liking. Press "Save" to save your changes.
|
||||
|
||||
---
|
||||
|
||||
## Mobile App
|
||||
|
||||
@@ -17,7 +17,7 @@ running `apt install postgresql-NN-pgvector`, where `NN` is your Postgres versio
|
||||
You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
|
||||
|
||||
:::note Supported versions
|
||||
Immich is known to work with Postgres versions `>= 14, < 19`.
|
||||
Immich is known to work with Postgres versions `>= 14, < 20`.
|
||||
|
||||
VectorChord is known to work with pgvector versions `>= 0.7, < 0.9`.
|
||||
|
||||
@@ -144,7 +144,7 @@ ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE vector(512);
|
||||
|
||||
<details>
|
||||
<summary>Migration steps</summary>
|
||||
1. Ensure you have at least 0.7.0 of pgvector installed. If it is below that, please upgrade it and run the SQL command `ALTER EXTENSION vector UPDATE;` using psql or your choice of database client
|
||||
1. Ensure you have at least `0.7.0` of pgvector installed. If it is below that, please upgrade it and run the SQL command `ALTER EXTENSION vector UPDATE;` using psql or your choice of database client
|
||||
2. Follow the Prerequisites to install VectorChord
|
||||
3. If Immich does not have superuser permissions, run the SQL command `CREATE EXTENSION vchord CASCADE;`
|
||||
4. Remove the `DB_VECTOR_EXTENSION=pgvector` environmental variable as it will make Immich still use pgvector if set
|
||||
|
||||
@@ -112,7 +112,7 @@ services:
|
||||
traefik.enable: true
|
||||
# increase readingTimeouts for the entrypoint used here
|
||||
traefik.http.routers.immich.entrypoints: websecure
|
||||
traefik.http.routers.immich.rule: Host(`immich.your-domain.com`)
|
||||
traefik.http.routers.immich.rule: Host(`immich.example.com`)
|
||||
traefik.http.services.immich.loadbalancer.server.port: 2283
|
||||
```
|
||||
|
||||
|
||||
@@ -13,8 +13,11 @@ The `immich-server` docker image comes preinstalled with an administrative CLI (
|
||||
| `enable-oauth-login` | Enable OAuth login |
|
||||
| `disable-oauth-login` | Disable OAuth login |
|
||||
| `list-users` | List Immich users |
|
||||
| `grant-admin` | Grant admin privileges to a user (by email) |
|
||||
| `revoke-admin` | Revoke admin privileges from a user (by email) |
|
||||
| `version` | Print Immich version |
|
||||
| `change-media-location` | Change database file paths to align with a new media location |
|
||||
| `schema-check` | Verify database migrations and check for schema drift |
|
||||
|
||||
## How to run a command
|
||||
|
||||
@@ -87,7 +90,7 @@ immich-admin list-users
|
||||
[
|
||||
{
|
||||
id: 'e65e6f88-2a30-4dbe-8dd9-1885f4889b53',
|
||||
email: 'immich@example.com.com',
|
||||
email: 'immich@example.com',
|
||||
name: 'Immich Admin',
|
||||
storageLabel: 'admin',
|
||||
externalPath: null,
|
||||
@@ -102,6 +105,22 @@ immich-admin list-users
|
||||
]
|
||||
```
|
||||
|
||||
Grant Admin
|
||||
|
||||
```
|
||||
immich-admin grant-admin
|
||||
? Please enter the user email: user@example.com
|
||||
Admin access has been granted to user@example.com
|
||||
```
|
||||
|
||||
Revoke Admin
|
||||
|
||||
```
|
||||
immich-admin revoke-admin
|
||||
? Please enter the user email: user@example.com
|
||||
Admin access has been revoked from user@example.com
|
||||
```
|
||||
|
||||
Print Immich Version
|
||||
|
||||
```
|
||||
@@ -126,3 +145,12 @@ immich-admin change-media-location
|
||||
Database file paths updated successfully! 🎉
|
||||
...
|
||||
```
|
||||
|
||||
Schema Check
|
||||
|
||||
```
|
||||
immich-admin schema-check
|
||||
Migrations are up to date
|
||||
|
||||
No schema drift detected
|
||||
```
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ Immich uses the [OpenAPI](https://swagger.io/specification/) standard to generat
|
||||
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). The generated SDK is based on the `immich-openapi-specs.json` file, which is autogenerated by the server **when running in development mode**. The `immich-openapi-specs.json` file can be modified with `@nestjs/swagger` decorators used or referenced by controller endpoints. See the [NestJS OpenAPI docs](https://docs.nestjs.com/openapi/types-and-parameters) for more info. When you add a new endpoint or modify an existing one, you must run the server in development mode and run the command below to update the client SDK.
|
||||
|
||||
```bash
|
||||
make open-api
|
||||
mise open-api
|
||||
```
|
||||
|
||||
You can find the generated client SDK in the `open-api/typescript-sdk/client` for Typescript SDK and `mobile/openapi` for Dart SDK.
|
||||
You can find the generated client SDK in the `packages/sdk/client` for Typescript SDK and `mobile/openapi` for Dart SDK.
|
||||
|
||||
@@ -5,7 +5,7 @@ After making any changes in the `server/src/schema`, a database migration need t
|
||||
1. Run the command
|
||||
|
||||
```bash
|
||||
pnpm run migrations:generate <migration-name>
|
||||
mise //server:migrations generate <migration-name>
|
||||
```
|
||||
|
||||
2. Check if the migration file makes sense.
|
||||
@@ -18,7 +18,7 @@ The server will automatically detect `*.ts` file changes and restart. Part of th
|
||||
If you need to undo the most recently applied migration—for example, when developing or testing on schema changes—run:
|
||||
|
||||
```bash
|
||||
pnpm run migrations:revert
|
||||
mise //server:migrations revert
|
||||
```
|
||||
|
||||
This command rolls back the latest migration and brings the database schema back to its previous state.
|
||||
|
||||
@@ -205,7 +205,7 @@ When the Dev Container starts, it automatically:
|
||||
1. **Runs post-create script** (`container-server-post-create.sh`):
|
||||
- Adjusts file permissions for the `node` user
|
||||
- Installs dependencies: `pnpm install` in all packages
|
||||
- Builds TypeScript SDK: `pnpm run build` in `open-api/typescript-sdk`
|
||||
- Builds TypeScript SDK: `pnpm --filter @immich/sdk build`
|
||||
|
||||
2. **Starts development servers** via VS Code tasks:
|
||||
- `Immich API Server (Nest)` - API server with hot-reloading on port 2283
|
||||
@@ -218,7 +218,7 @@ When the Dev Container starts, it automatically:
|
||||
- Debug ports: 9230 (workers), 9231 (API)
|
||||
|
||||
:::info
|
||||
The Dev Container setup replaces the `make dev` command from the traditional setup. All services start automatically when you open the container.
|
||||
The Dev Container setup replaces the `mise dev` command from the traditional setup. All services start automatically when you open the container.
|
||||
:::
|
||||
|
||||
### Accessing Services
|
||||
@@ -243,8 +243,8 @@ To connect the mobile app to your Dev Container:
|
||||
|
||||
- **Server code** (`/server`): Changes trigger automatic restart
|
||||
- **Web code** (`/web`): Changes trigger hot module replacement
|
||||
- **Database migrations**: Run `pnpm run sync:sql` in the server directory
|
||||
- **API changes**: Regenerate TypeScript SDK with `make open-api`
|
||||
- **Database migrations**: Run `mise //:sql`
|
||||
- **API changes**: Regenerate TypeScript SDK with `mise //:open-api`
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -252,85 +252,33 @@ To connect the mobile app to your Dev Container:
|
||||
|
||||
The Dev Container supports multiple ways to run tests:
|
||||
|
||||
#### Using Make Commands (Recommended)
|
||||
|
||||
```bash
|
||||
# Run tests for specific components
|
||||
make test-server # Server unit tests
|
||||
make test-web # Web unit tests
|
||||
make test-e2e # End-to-end tests
|
||||
make test-cli # CLI tests
|
||||
# Server
|
||||
mise //server:test # unit tests
|
||||
mise //server:test-medium # medium / integration tests
|
||||
|
||||
# Run all tests
|
||||
make test-all # Runs tests for all components
|
||||
# Web
|
||||
mise //web:test # unit tests
|
||||
|
||||
# Medium tests (integration tests)
|
||||
make test-medium-dev # End-to-end tests
|
||||
# E2E
|
||||
mise //e2e:test # API tests
|
||||
mise //e2e:test-web # web UI tests (Playwright)
|
||||
|
||||
# Run all checks for a component
|
||||
mise //server:checklist
|
||||
mise //web:checklist
|
||||
```
|
||||
|
||||
#### Using PNPM Directly
|
||||
### Additional Commands
|
||||
|
||||
```bash
|
||||
# Server tests
|
||||
cd /workspaces/immich/server
|
||||
pnpm test # Run all tests
|
||||
pnpm run test:medium # Medium tests (integration tests)
|
||||
pnpm run test:watch # Watch mode
|
||||
pnpm run test:cov # Coverage report
|
||||
|
||||
# Web tests
|
||||
cd /workspaces/immich/web
|
||||
pnpm test # Run all tests
|
||||
pnpm run test:watch # Watch mode
|
||||
|
||||
# E2E tests
|
||||
cd /workspaces/immich/e2e
|
||||
pnpm run test # Run API tests
|
||||
pnpm run test:web # Run web UI tests
|
||||
```
|
||||
|
||||
### Code Quality Commands
|
||||
|
||||
```bash
|
||||
# Linting
|
||||
make lint-server # Lint server code
|
||||
make lint-web # Lint web code
|
||||
make lint-all # Lint all components
|
||||
|
||||
# Formatting
|
||||
make format-server # Format server code
|
||||
make format-web # Format web code
|
||||
make format-all # Format all code
|
||||
|
||||
# Type checking
|
||||
make check-server # Type check server
|
||||
make check-web # Type check web
|
||||
make check-all # Check all components
|
||||
|
||||
# Complete hygiene check
|
||||
make hygiene-all # Run lint, format, check, SQL sync, and audit
|
||||
```
|
||||
|
||||
### Additional Make Commands
|
||||
|
||||
```bash
|
||||
# Build commands
|
||||
make build-server # Build server
|
||||
make build-web # Build web app
|
||||
make build-all # Build everything
|
||||
|
||||
# API generation
|
||||
make open-api # Generate OpenAPI specs
|
||||
make open-api-typescript # Generate TypeScript SDK
|
||||
make open-api-dart # Generate Dart SDK
|
||||
mise //:open-api # Generate OpenAPI specs
|
||||
mise //:open-api-typescript # Generate TypeScript SDK
|
||||
mise //:open-api-dart # Generate Dart SDK
|
||||
|
||||
# Database
|
||||
make sql # Sync database schema
|
||||
|
||||
# Dependencies
|
||||
make install-server # Install server dependencies
|
||||
make install-web # Install web dependencies
|
||||
make install-all # Install all dependencies
|
||||
mise //server:sql # Sync database schema
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
@@ -10,7 +10,8 @@ Our [GitHub Repository](https://github.com/immich-app/immich) is a [monorepo](ht
|
||||
| :------------------ | :------------------------------------------------------------------- |
|
||||
| `.github/` | Github templates and action workflows |
|
||||
| `.vscode/` | VSCode debug launch profiles |
|
||||
| `cli/` | Source code for the work-in-progress CLI rewrite |
|
||||
| `packages/cli` | Source code for the CLI |
|
||||
| `packages/sdk` | Source code for the generated OpenAPI SDK |
|
||||
| `docker/` | Docker compose resources for dev, test, production |
|
||||
| `design/` | Screenshots and logos for the README |
|
||||
| `docs/` | Source code for the [https://immich.app](https://immich.app) website |
|
||||
|
||||
@@ -2,53 +2,74 @@
|
||||
|
||||
A minimal devcontainer is supplied with this repository. All commands can be executed directly inside this container to avoid tedious installation of the environment.
|
||||
:::warning
|
||||
The provided devcontainer isn't complete at the moment. At least all dockerized steps in the Makefile won't work (`make dev`, ....). Feel free to contribute!
|
||||
The provided devcontainer isn't complete at the moment. At least all dockerized steps in the Makefile won't work (`mise dev`, ....). Feel free to contribute!
|
||||
:::
|
||||
When contributing code through a pull request, please check the following:
|
||||
|
||||
## Web Checks
|
||||
|
||||
- [ ] `pnpm run lint` (linting via ESLint)
|
||||
- [ ] `pnpm run format` (formatting via Prettier)
|
||||
- [ ] `pnpm run check:svelte` (Type checking via SvelteKit)
|
||||
- [ ] `pnpm run check:typescript` (check typescript)
|
||||
- [ ] `pnpm test` (unit tests)
|
||||
- [ ] `mise //web:lint` (linting via ESLint)
|
||||
- [ ] `mise //web:format` (formatting via Prettier)
|
||||
- [ ] `mise //web:check-svelte` (type checking via SvelteKit)
|
||||
- [ ] `mise //web:check-typescript` (type checking via `tsc`)
|
||||
- [ ] `mise //web:test` (unit tests)
|
||||
|
||||
:::tip AIO
|
||||
Run all web checks with `pnpm run check:all`
|
||||
Run all web checks with `mise //web:checklist`
|
||||
:::
|
||||
|
||||
:::tip Auto Fix
|
||||
Use `mise //web:lint-fix` and `mise //web:format-fix` to automatically correct some issues.
|
||||
:::
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ ] `pnpm run format` (formatting via Prettier)
|
||||
- [ ] `mise //docs:format` (formatting via Prettier)
|
||||
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
|
||||
|
||||
:::tip Auto Fix
|
||||
Use `mise //docs:format-fix` to automatically fix formatting.
|
||||
:::
|
||||
|
||||
## Server Checks
|
||||
|
||||
- [ ] `pnpm run lint` (linting via ESLint)
|
||||
- [ ] `pnpm run format` (formatting via Prettier)
|
||||
- [ ] `pnpm run check` (Type checking via `tsc`)
|
||||
- [ ] `pnpm test` (unit tests)
|
||||
- [ ] `mise //server:lint` (linting via ESLint)
|
||||
- [ ] `mise //server:format` (formatting via Prettier)
|
||||
- [ ] `mise //server:check` (type checking via `tsc`)
|
||||
- [ ] `mise //server:test` (unit tests)
|
||||
|
||||
:::tip AIO
|
||||
Run all server checks with `pnpm run check:all`
|
||||
Run all server checks with `mise //server:checklist`
|
||||
:::
|
||||
|
||||
:::info Auto Fix
|
||||
You can use `pnpm run __:fix` to potentially correct some issues automatically for `pnpm run format` and `lint`.
|
||||
:::tip Auto Fix
|
||||
Use `mise //server:lint-fix` and `mise //server:format-fix` to automatically correct some issues.
|
||||
:::
|
||||
|
||||
## Mobile Checks
|
||||
## Mobile Checklist
|
||||
|
||||
The following commands must be executed from within the mobile app directory of the codebase.
|
||||
- [ ] `mise //mobile:codegen` (auto-generate files using build_runner)
|
||||
- [ ] `mise //mobile:lint` (static analysis via Dart Analyzer and DCM)
|
||||
- [ ] `mise //mobile:format` (formatting via Dart Formatter)
|
||||
- [ ] `mise //mobile:test` (unit tests)
|
||||
|
||||
- [ ] `make build` (auto-generate files using build_runner)
|
||||
- [ ] `make analyze` (static analysis via Dart Analyzer and DCM)
|
||||
- [ ] `make format` (formatting via Dart Formatter)
|
||||
- [ ] `make test` (unit tests)
|
||||
:::tip
|
||||
Run all these commands at once with `mise //mobile:checklist`
|
||||
:::
|
||||
|
||||
:::info Auto Fix
|
||||
You can use `dart fix --apply` and `dcm fix lib` to potentially correct some issues automatically for `make analyze`.
|
||||
:::tip Auto Fix
|
||||
You can use `mise //mobile:lint-fix` to potentially correct some issues automatically for `mise //mobile:lint`.
|
||||
:::
|
||||
|
||||
## Machine Learning Checklist
|
||||
|
||||
- [ ] `mise //machine-learning:lint` (linting via ruff)
|
||||
- [ ] `mise //machine-learning:format` (formatting via ruff)
|
||||
- [ ] `mise //machine-learning:check` (type checking via mypy)
|
||||
- [ ] `mise //machine-learning:test` (unit tests via pytest)
|
||||
|
||||
:::tip AIO
|
||||
Run all machine learning checks with `mise //machine-learning:checklist`
|
||||
:::
|
||||
|
||||
## OpenAPI
|
||||
|
||||
@@ -32,6 +32,10 @@ This environment includes the services below. Additional details are available i
|
||||
|
||||
All the services are packaged to run as with single Docker Compose command.
|
||||
|
||||
:::tip mise
|
||||
[mise](https://mise.jdx.dev) is used throughout the project to manage tool versions and run tasks. [Install mise](https://mise.jdx.dev/installing-mise.html), then from the repo root run `mise trust` and `mise install` to get all required tools. Tasks for each service can be run from the repo root using `mise //namespace:task` (e.g. `mise //server:lint`). To list all available tasks, run `mise tasks ls --all`.
|
||||
:::
|
||||
|
||||
### Server and web apps
|
||||
|
||||
1. Clone the project repo.
|
||||
@@ -41,7 +45,7 @@ All the services are packaged to run as with single Docker Compose command.
|
||||
5. From the root directory, run:
|
||||
|
||||
```bash title="Start development server"
|
||||
make dev # required Makefile installed on the system.
|
||||
mise dev
|
||||
```
|
||||
|
||||
5. Access the dev instance in your browser at http://localhost:3000, or connect via the mobile app.
|
||||
@@ -56,22 +60,23 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3
|
||||
|
||||
#### Connect web to a remote backend
|
||||
|
||||
If you only want to do web development connected to an existing, remote backend, follow these steps:
|
||||
|
||||
1. Build the Immich SDK - `cd open-api/typescript-sdk && pnpm i && pnpm run build && cd -`
|
||||
2. Enter the web directory - `cd web/`
|
||||
3. Install web dependencies - `pnpm i`
|
||||
4. Start the web development server
|
||||
If you only want to do web development connected to an existing, remote backend, run from the repo root:
|
||||
|
||||
```bash
|
||||
IMMICH_SERVER_URL=https://demo.immich.app/ pnpm run dev
|
||||
IMMICH_SERVER_URL=https://demo.immich.app/ mise //web:start
|
||||
```
|
||||
|
||||
This will install all dependencies (including the SDK) and start the dev server in one step. To connect to the hosted demo server specifically, use the shorthand:
|
||||
|
||||
```bash
|
||||
mise //web:start-demo
|
||||
```
|
||||
|
||||
If you're using PowerShell on Windows you may need to set the env var separately like so:
|
||||
|
||||
```powershell
|
||||
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
|
||||
pnpm run dev
|
||||
mise //web:start
|
||||
```
|
||||
|
||||
#### `@immich/ui`
|
||||
@@ -83,31 +88,45 @@ To see local changes to `@immich/ui` in Immich, do the following:
|
||||
3. Uncomment the corresponding volume in web service of the `docker/docker-compose.dev.yml` file (`../../ui:/usr/src/ui`)
|
||||
4. Uncomment the corresponding alias in the `web/vite.config.ts` file (`'@immich/ui': path.resolve(\_\_dirname, '../../ui/packages/ui')`)
|
||||
5. Uncomment the import statement in `web/src/app.css` file `@import '../../../ui/packages/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 `mise dev`
|
||||
7. After making changes in `@immich/ui`, rebuild it (`pnpm run build`)
|
||||
|
||||
### Mobile app
|
||||
|
||||
#### Setup
|
||||
|
||||
1. [Install mise](https://mise.jdx.dev/installing-mise.html).
|
||||
2. Change to the immich (root) directory and trust the mise config with `mise trust`.
|
||||
3. Install tools with mise: `mise install`.
|
||||
4. Change to the `mobile/` directory.
|
||||
5. Run `flutter pub get` to install the dependencies.
|
||||
6. Run `make translation` to generate the translation file.
|
||||
7. Run `flutter run` to start the app.
|
||||
1. Run `mise //mobile:install` to install Flutter dependencies.
|
||||
2. Run `mise //mobile:translation` to generate the translation file.
|
||||
3. Change to the `mobile/` directory and run `flutter run` to start the app.
|
||||
|
||||
#### Translation
|
||||
|
||||
To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then, from the `mobile/` directory, run
|
||||
To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then run:
|
||||
|
||||
```bash
|
||||
make translation
|
||||
mise //mobile:translation
|
||||
```
|
||||
|
||||
The mobile app asks you what backend to connect to. You can utilize the demo backend (https://demo.immich.app/) if you don't need to change server code or upload photos. Alternatively, you can run the server yourself per the instructions above.
|
||||
|
||||
#### UI components and widget previews
|
||||
|
||||
Shared design-system widgets (buttons, inputs, forms) live in the
|
||||
[`immich_ui` package](https://github.com/immich-app/immich/tree/main/mobile/packages/ui/)
|
||||
under `mobile/packages/ui/`. Components are defined in `lib/src/components/`
|
||||
and have matching previews in `lib/src/previews/`.
|
||||
|
||||
To inspect a component in isolation with a light/dark toggle and hot reload,
|
||||
launch [Flutter's Widget Previewer](https://docs.flutter.dev/tools/widget-previewer):
|
||||
|
||||
```bash
|
||||
cd mobile/packages/ui
|
||||
flutter widget-preview start
|
||||
```
|
||||
|
||||
In VS Code or Android Studio with the Flutter plugin, the previewer
|
||||
auto-starts when you open the **Flutter Widget Preview** tab in the sidebar.
|
||||
|
||||
## IDE setup
|
||||
|
||||
### Lint / format extensions
|
||||
|
||||
@@ -4,28 +4,26 @@
|
||||
|
||||
### Unit tests
|
||||
|
||||
Unit are run by calling `pnpm run test` from the `server/` directory.
|
||||
You need to run `pnpm install` (in `server/`) before _once_.
|
||||
Unit tests are run with `mise //server:test`.
|
||||
You need to run `mise //server:install` before _once_.
|
||||
|
||||
### End to end tests
|
||||
|
||||
The e2e tests can be run by first starting up a test production environment via:
|
||||
|
||||
```bash
|
||||
make e2e
|
||||
mise e2e
|
||||
```
|
||||
|
||||
Before you can run the tests, you need to run the following commands _once_:
|
||||
|
||||
- `pnpm install` (in `e2e/`)
|
||||
- `pnpm run build` (in `cli/`)
|
||||
- `make open-api` (in the project root `/`)
|
||||
- `mise //e2e:ci-setup` (installs e2e, SDK, and CLI dependencies)
|
||||
- `mise //:open-api`
|
||||
|
||||
Once the test environment is running, the e2e tests can be run via:
|
||||
|
||||
```bash
|
||||
cd e2e/
|
||||
pnpm test
|
||||
mise //e2e:test
|
||||
```
|
||||
|
||||
The tests check various things including:
|
||||
|
||||
@@ -17,7 +17,7 @@ services:
|
||||
ports:
|
||||
- "8888:80"
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: user-name@domain-name.com
|
||||
PGADMIN_DEFAULT_EMAIL: admin@example.com
|
||||
PGADMIN_DEFAULT_PASSWORD: strong-password
|
||||
volumes:
|
||||
- pgadmin-data:/var/lib/pgadmin
|
||||
|
||||
@@ -26,7 +26,7 @@ The default configuration looks like this:
|
||||
},
|
||||
"ffmpeg": {
|
||||
"accel": "disabled",
|
||||
"accelDecode": false,
|
||||
"accelDecode": true,
|
||||
"acceptedAudioCodecs": ["aac", "mp3", "opus"],
|
||||
"acceptedContainers": ["mov", "ogg", "webm"],
|
||||
"acceptedVideoCodecs": ["h264"],
|
||||
|
||||
@@ -154,33 +154,33 @@ Redis (Sentinel) URL example JSON before encoding:
|
||||
|
||||
## Machine Learning
|
||||
|
||||
| Variable | Description | Default | Containers |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------: | :--------------- |
|
||||
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
|
||||
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
|
||||
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `120` (`300` if using OpenVINO) | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
|
||||
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
|
||||
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
|
||||
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
|
||||
| `MACHINE_LEARNING_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning |
|
||||
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
|
||||
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
|
||||
| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning |
|
||||
| Variable | Description | Default | Containers |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :--------------- |
|
||||
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
|
||||
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
|
||||
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `300` (`900` if using ROCm) | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning |
|
||||
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
|
||||
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
|
||||
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
|
||||
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
|
||||
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
|
||||
| `MACHINE_LEARNING_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning |
|
||||
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
|
||||
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning |
|
||||
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
|
||||
| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning |
|
||||
|
||||
\*1: It is recommended to begin with this parameter when changing the concurrency levels of the machine learning service and then tune the other ones.
|
||||
|
||||
|
||||
@@ -20,9 +20,11 @@ Hardware and software requirements for Immich:
|
||||
- **RAM**: Minimum 6GB, recommended 8GB.
|
||||
- **CPU**: Minimum 2 cores, recommended 4 cores.
|
||||
- Immich runs on the `amd64` and `arm64` platforms.
|
||||
Since `v2.6`, the machine learning container on `amd64` requires the `>= x86-64-v2` [microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels).
|
||||
Since `v3`, the machine learning container on `amd64` requires the `>= x86-64-v2` [microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels).
|
||||
Most CPUs released since ~2012 support this microarchitecture.
|
||||
If you are using a virtual machine, ensure you have selected a [supported microarchitecture](https://pve.proxmox.com/pve-docs/chapter-qm.html#_qemu_cpu_types).
|
||||
If you are unable to support this instruction set, the last version to support `x86-64-v1` is `v2.7.5`.
|
||||
Note that this release is no longer supported, and you must run a matching `immich-server` version.
|
||||
- **Storage**: Recommended Unix-compatible filesystem (EXT4, ZFS, APFS, etc.) with support for user/group ownership and permissions.
|
||||
- The generation of thumbnails and transcoded video can increase the size of the photo library by 10-20% on average.
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ Scroll to the bottom of the "**Details**" section and find the `IP Address` list
|
||||
|
||||
## Step 4 - Configure Firewall Settings
|
||||
|
||||
Once your project completes the build process, your containers will start. In order to be able to access Immich from your browser, you need to configure the firewall settings for your Synology NAS.
|
||||
Once your project completes the build process, your containers will start. In order to be able to access Immich from your browser, you need to configure the firewall settings for your Synology NAS to allow communication between the Immich containers.
|
||||
|
||||
Open "**Control Panel**" on your Synology NAS, and select "**Security**". Navigate to "**Firewall**"
|
||||
|
||||
@@ -74,6 +74,7 @@ Read the [Post Installation](/install/post-install.mdx) steps and [upgrade instr
|
||||
|
||||
<details>
|
||||
<summary>Updating Immich using Container Manager</summary>
|
||||
|
||||
Check the post installation and upgrade instructions at the links above before proceeding with this section.
|
||||
|
||||
## Step 1. Backup
|
||||
@@ -110,7 +111,7 @@ Go to **Project**, select **Action** then **Build**. This will download, unpack,
|
||||
|
||||
## Step 5. Update firewall rule
|
||||
|
||||
The default behavior is to automatically start the containers once installed. If `immich_server` runs for a few seconds and then stops, it may be because the firewall rule no longer matches the server IP address.
|
||||
Without a fixed subnet, the default behavior is to automatically start the containers once installed. If `immich_server` runs for a few seconds and then stops, it may be because the firewall rule no longer matches the server IP address.
|
||||
|
||||
Go to the **Container** section. Click on `immich_server` and scroll down on **General** to find the IP address.
|
||||

|
||||
@@ -123,4 +124,67 @@ In this example, the IP addresses mismatch and the firewall rule needs to be edi
|
||||
|
||||

|
||||
|
||||
To prevent future firewall issues, you may set a fixed subnet. [See Set Fixed Subnet](#set-fixed-subnet) for instructions.
|
||||
|
||||
</details>
|
||||
|
||||
<details id="set-fixed-subnet">
|
||||
<summary>Set Fixed Subnet</summary>
|
||||
|
||||
Docker by default assigns dynamic subnets to bridge networks which can change when rebuilding containers and can cause firewall rules to break. To avoid this, define a fixed subnet in your `docker-compose.yml`:
|
||||
|
||||
## Step 1. Determine current subnet
|
||||
|
||||
Go to the **Container** section. Click on `immich_server` and scroll down on **General** to find the IP address.
|
||||

|
||||
|
||||
## Step 2. Add network configuration
|
||||
|
||||
Add the following network configuration at the end of your `docker-compose.yml` file:
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
immich-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
gateway: 172.20.0.1
|
||||
```
|
||||
|
||||
If your docker container is running on a different subnet then update accordingly.
|
||||
|
||||
## Step 3. Add network to each service
|
||||
|
||||
Add the network to each service (immich-server, immich-machine-learning, redis, database):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
immich-server:
|
||||
# other config options
|
||||
networks:
|
||||
- immich-network
|
||||
|
||||
immich-machine-learning:
|
||||
# other config options
|
||||
networks:
|
||||
- immich-network
|
||||
|
||||
redis:
|
||||
# other config options
|
||||
networks:
|
||||
- immich-network
|
||||
|
||||
database:
|
||||
# other config options
|
||||
networks:
|
||||
- immich-network
|
||||
```
|
||||
|
||||
Save your changes. Synology will ask if you want to save changes only or rebuild containers. Select rebuild containers.
|
||||
|
||||
## Step 4. Update Firewall Rules, if necessary
|
||||
|
||||
If your firewall rules were not already set for this subnet, the firewall rules will need to be updated. See [Step 4 - Configure Firewall Settings](#step-4---configure-firewall-settings).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -10,7 +10,6 @@ const config = {
|
||||
url: 'https://docs.immich.app',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.png',
|
||||
|
||||
// GitHub pages deployment config.
|
||||
@@ -29,6 +28,9 @@ const config = {
|
||||
// Mermaid diagrams
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
hooks: {
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
},
|
||||
},
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
|
||||
|
||||
[[tools.wrangler]]
|
||||
version = "4.66.0"
|
||||
backend = "npm:wrangler"
|
||||
+2
-2
@@ -3,7 +3,7 @@ run = "pnpm install --filter documentation --frozen-lockfile"
|
||||
|
||||
[tasks.start]
|
||||
env._.path = "./node_modules/.bin"
|
||||
run = "docusaurus --port 3005"
|
||||
run = "docusaurus start --port 3005"
|
||||
|
||||
[tasks.build]
|
||||
env._.path = "./node_modules/.bin"
|
||||
@@ -28,4 +28,4 @@ run = "prettier --write ."
|
||||
run = "wrangler pages deploy build --project-name=${PROJECT_NAME} --branch=${BRANCH_NAME}"
|
||||
|
||||
[tools]
|
||||
wrangler = "4.66.0"
|
||||
wrangler = "4.98.0"
|
||||
|
||||
Vendored
+4
@@ -1,4 +1,8 @@
|
||||
[
|
||||
{
|
||||
"label": "v3.0.0-rc.0",
|
||||
"url": "https://docs.v3.0.0-rc.0.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v2.7.5",
|
||||
"url": "https://docs.v2.7.5.archive.immich.app"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a7dea969802d7e0c2b25
|
||||
RUN corepack enable
|
||||
ADD package.json *.ts ./
|
||||
RUN pnpm install
|
||||
EXPOSE 2286
|
||||
CMD ["pnpm", "run", "start"]
|
||||
@@ -83,9 +83,7 @@ volumes:
|
||||
model_cache:
|
||||
prometheus_data:
|
||||
grafana_data:
|
||||
pnpm_cache:
|
||||
pnpm_store_server:
|
||||
pnpm_store_web:
|
||||
build_cache:
|
||||
server_node_modules:
|
||||
web_node_modules:
|
||||
github_node_modules:
|
||||
|
||||
@@ -4,7 +4,8 @@ services:
|
||||
e2e-auth-server:
|
||||
container_name: immich-e2e-auth-server
|
||||
build:
|
||||
context: ../e2e-auth-server
|
||||
context: ../
|
||||
dockerfile: packages/e2e-auth-server/Dockerfile
|
||||
ports:
|
||||
- 2286:2286
|
||||
|
||||
@@ -44,7 +45,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich-e2e-redis
|
||||
image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
|
||||
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
|
||||
|
||||
+16
-1
@@ -1,11 +1,21 @@
|
||||
[tasks.install]
|
||||
run = "pnpm install --filter immich-e2e --frozen-lockfile"
|
||||
|
||||
[tasks.build]
|
||||
dir = "{{ config_root }}"
|
||||
run = "docker compose build"
|
||||
|
||||
[tasks.test]
|
||||
depends = ["//e2e:build", "//e2e:ci-setup"]
|
||||
env._.path = "./node_modules/.bin"
|
||||
run = "vitest --run"
|
||||
|
||||
[tasks.playwright-install]
|
||||
env._.path = "./node_modules/.bin"
|
||||
run = "playwright install"
|
||||
|
||||
[tasks."test-web"]
|
||||
depends = ["//e2e:build", "//e2e:ci-setup", "//e2e:playwright-install"]
|
||||
env._.path = "./node_modules/.bin"
|
||||
run = "playwright test"
|
||||
|
||||
@@ -30,7 +40,12 @@ run = "tsc --noEmit"
|
||||
|
||||
|
||||
[tasks.ci-setup]
|
||||
depends = ["//:sdk:install", "//:sdk:build", "//cli:install", "//cli:build"]
|
||||
depends = [
|
||||
"//:sdk:install",
|
||||
"//:sdk:build",
|
||||
"//packages/cli:install",
|
||||
"//packages/cli:build",
|
||||
]
|
||||
run = { task = ":install" }
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "2.7.5",
|
||||
"version": "3.0.0-rc.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
@@ -32,7 +32,7 @@
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@socket.io/component-emitter": "^3.1.2",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^24.12.2",
|
||||
"@types/node": "^24.12.4",
|
||||
"@types/pg": "^8.15.1",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
"@types/supertest": "^7.0.0",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { LoginResponseDto, ManualJobName } from '@immich/sdk';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/admin/database-backups', () => {
|
||||
let cookie: string | undefined;
|
||||
@@ -13,6 +13,9 @@ describe('/admin/database-backups', () => {
|
||||
admin = await utils.adminSetup({
|
||||
onboarding: false,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await utils.resetBackups(admin.accessToken);
|
||||
});
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ describe('/admin/maintenance', () => {
|
||||
},
|
||||
{
|
||||
interval: 500,
|
||||
timeout: 10_000,
|
||||
timeout: 60_000,
|
||||
},
|
||||
)
|
||||
.toBeTruthy();
|
||||
@@ -190,7 +190,7 @@ describe('/admin/maintenance', () => {
|
||||
},
|
||||
{
|
||||
interval: 500,
|
||||
timeout: 10_000,
|
||||
timeout: 60_000,
|
||||
},
|
||||
)
|
||||
.toBeFalsy();
|
||||
|
||||
@@ -504,13 +504,14 @@ describe('/albums', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not be able to share album with owner', async () => {
|
||||
it('should deduplicate owner from albumUsers on create', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/albums')
|
||||
.send({ albumName: 'New album', albumUsers: [{ role: AlbumUserRole.Editor, userId: user1.userId }] })
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('Cannot share album with owner'));
|
||||
expect(status).toBe(201);
|
||||
expect(body.albumUsers).toHaveLength(1);
|
||||
expect(body.albumUsers[0]).toMatchObject({ role: AlbumUserRole.Owner, user: { id: user1.userId } });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
getMyUser,
|
||||
LoginResponseDto,
|
||||
SharedLinkType,
|
||||
updateConfig,
|
||||
} from '@immich/sdk';
|
||||
import { exiftool } from 'exiftool-vendored';
|
||||
import { DateTime } from 'luxon';
|
||||
@@ -24,7 +23,6 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
const locationAssetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
|
||||
const ratingAssetFilepath = `${testAssetDir}/metadata/rating/mongolels.jpg`;
|
||||
const facesAssetDir = `${testAssetDir}/metadata/faces`;
|
||||
|
||||
const readTags = async (bytes: Buffer, filename: string) => {
|
||||
const filepath = join(tempDir, filename);
|
||||
@@ -185,78 +183,6 @@ describe('/asset', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('faces', () => {
|
||||
const metadataFaceTests = [
|
||||
{
|
||||
description: 'without orientation',
|
||||
filename: 'portrait.jpg',
|
||||
},
|
||||
{
|
||||
description: 'adjusting face regions to orientation',
|
||||
filename: 'portrait-orientation-6.jpg',
|
||||
},
|
||||
];
|
||||
// should produce same resulting face region coordinates for any orientation
|
||||
const expectedFaces = [
|
||||
{
|
||||
name: 'Marie Curie',
|
||||
birthDate: null,
|
||||
isHidden: false,
|
||||
faces: [
|
||||
{
|
||||
imageHeight: 700,
|
||||
imageWidth: 840,
|
||||
boundingBoxX1: 261,
|
||||
boundingBoxX2: 356,
|
||||
boundingBoxY1: 146,
|
||||
boundingBoxY2: 284,
|
||||
sourceType: 'exif',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Pierre Curie',
|
||||
birthDate: null,
|
||||
isHidden: false,
|
||||
faces: [
|
||||
{
|
||||
imageHeight: 700,
|
||||
imageWidth: 840,
|
||||
boundingBoxX1: 536,
|
||||
boundingBoxX2: 618,
|
||||
boundingBoxY1: 83,
|
||||
boundingBoxY2: 252,
|
||||
sourceType: 'exif',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
it.each(metadataFaceTests)('should get the asset faces from $filename $description', async ({ filename }) => {
|
||||
const config = await utils.getSystemConfig(admin.accessToken);
|
||||
config.metadata.faces.import = true;
|
||||
await updateConfig({ systemConfigDto: config }, { headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const facesAsset = await utils.createAsset(admin.accessToken, {
|
||||
assetData: {
|
||||
filename,
|
||||
bytes: await readFile(`${facesAssetDir}/${filename}`),
|
||||
},
|
||||
});
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: facesAsset.id });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get(`/assets/${facesAsset.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body.id).toEqual(facesAsset.id);
|
||||
const sortedPeople = body.people.toSorted((a: any, b: any) => a.name.localeCompare(b.name));
|
||||
expect(sortedPeople).toMatchObject(expectedFaces);
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with a shared link', async () => {
|
||||
const sharedLink = await utils.createSharedLink(user1.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
|
||||
@@ -0,0 +1,669 @@
|
||||
import {
|
||||
AssetMediaResponseDto,
|
||||
IntegrityReportResponseDto,
|
||||
LoginResponseDto,
|
||||
ManualJobName,
|
||||
QueueCommand,
|
||||
QueueName,
|
||||
} from '@immich/sdk';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { app, testAssetDir, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterEach, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
const assetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
|
||||
const asset1Filepath = `${testAssetDir}/albums/nature/el_torcal_rocks.jpg`;
|
||||
const asset2Filepath = `${testAssetDir}/albums/nature/wood_anemones.jpg`;
|
||||
|
||||
describe('/admin/integrity', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let asset: AssetMediaResponseDto;
|
||||
|
||||
let user1: LoginResponseDto;
|
||||
let asset1: AssetMediaResponseDto;
|
||||
|
||||
let user2: LoginResponseDto;
|
||||
let asset2: AssetMediaResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup();
|
||||
|
||||
user1 = await utils.userSetup(admin.accessToken, {
|
||||
email: '1@example.com',
|
||||
name: '1',
|
||||
password: '1',
|
||||
});
|
||||
|
||||
user2 = await utils.userSetup(admin.accessToken, {
|
||||
email: '2@example.com',
|
||||
name: '2',
|
||||
password: '2',
|
||||
});
|
||||
|
||||
for (const queue of Object.values(QueueName)) {
|
||||
if (queue === QueueName.IntegrityCheck) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await utils.queueCommand(admin.accessToken, queue, {
|
||||
command: QueueCommand.Pause,
|
||||
});
|
||||
}
|
||||
|
||||
asset = await utils.createAsset(admin.accessToken, {
|
||||
assetData: {
|
||||
filename: 'asset.jpg',
|
||||
bytes: await readFile(assetFilepath),
|
||||
},
|
||||
});
|
||||
|
||||
asset1 = await utils.createAsset(user1.accessToken, {
|
||||
assetData: {
|
||||
filename: 'asset.jpg',
|
||||
bytes: await readFile(asset1Filepath),
|
||||
},
|
||||
});
|
||||
|
||||
asset2 = await utils.createAsset(user2.accessToken, {
|
||||
assetData: {
|
||||
filename: 'asset.jpg',
|
||||
bytes: await readFile(asset2Filepath),
|
||||
},
|
||||
});
|
||||
|
||||
await utils.mkFolder('/data/bak');
|
||||
await utils.copyFolder(`/data/upload/${admin.userId}`, `/data/bak/${admin.userId}`);
|
||||
|
||||
for (const queue of Object.values(QueueName)) {
|
||||
if (queue === QueueName.IntegrityCheck) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await utils.queueCommand(admin.accessToken, queue, {
|
||||
command: QueueCommand.Empty,
|
||||
});
|
||||
|
||||
await utils.queueCommand(admin.accessToken, queue, {
|
||||
command: QueueCommand.Resume,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await utils.deleteFolder(`/data/upload/${admin.userId}`);
|
||||
await utils.copyFolder(`/data/bak/${admin.userId}`, `/data/upload/${admin.userId}`);
|
||||
});
|
||||
|
||||
describe('POST /summary (& jobs)', async () => {
|
||||
it.sequential('reports no issues', async () => {
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFilesDeleteAll,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
missing_file: 0,
|
||||
untracked_file: 0,
|
||||
checksum_mismatch: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it.sequential('should detect an untracked file (job: check untracked files)', async () => {
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
untracked_file: 1,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should detect outdated untracked file reports (job: refresh untracked files)', async () => {
|
||||
// these should not be detected:
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked2.png`);
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked3.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFilesRefresh,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
untracked_file: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should delete untracked files (job: delete all untracked file reports)', async () => {
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFilesDeleteAll,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
untracked_file: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should detect a missing file and not a checksum mismatch (job: check missing files)', async () => {
|
||||
await utils.deleteFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
missing_file: 1,
|
||||
checksum_mismatch: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should detect outdated missing file reports (job: refresh missing files)', async () => {
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFilesRefresh,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
missing_file: 0,
|
||||
checksum_mismatch: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should delete assets with missing files (job: delete all missing file reports)', async () => {
|
||||
await utils.deleteFolder(`/data/upload/${user1.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus, body: listBody } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus).toBe(200);
|
||||
expect(listBody).toEqual(
|
||||
expect.objectContaining({
|
||||
missing_file: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFilesDeleteAll,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
missing_file: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(utils.getAssetInfo(user1.accessToken, asset1.id)).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
isTrashed: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should detect a checksum mismatch (job: check file checksums)', async () => {
|
||||
await utils.truncateFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
checksum_mismatch: 1,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('should detect outdated checksum mismatch reports (job: refresh file checksums)', async () => {
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatchRefresh,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
checksum_mismatch: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential(
|
||||
'should delete assets with mismatched checksum (job: delete all checksum mismatch reports)',
|
||||
async () => {
|
||||
await utils.truncateFolder(`/data/upload/${user2.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus, body: listBody } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus).toBe(200);
|
||||
expect(listBody).toEqual(
|
||||
expect.objectContaining({
|
||||
checksum_mismatch: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatchDeleteAll,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/summary')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
checksum_mismatch: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(utils.getAssetInfo(user2.accessToken, asset2.id)).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
isTrashed: true,
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('POST /report', async () => {
|
||||
it.sequential('reports untracked files', async () => {
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/report?type=untracked_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
nextCursor: undefined,
|
||||
items: expect.arrayContaining([
|
||||
{
|
||||
id: expect.any(String),
|
||||
type: 'untracked_file',
|
||||
path: `/data/upload/${admin.userId}/untracked1.png`,
|
||||
assetId: null,
|
||||
fileAssetId: null,
|
||||
createdAt: expect.any(String),
|
||||
},
|
||||
]),
|
||||
});
|
||||
});
|
||||
|
||||
it.sequential('reports missing files', async () => {
|
||||
await utils.deleteFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/report?type=missing_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
nextCursor: undefined,
|
||||
items: expect.arrayContaining([
|
||||
{
|
||||
id: expect.any(String),
|
||||
type: 'missing_file',
|
||||
path: expect.any(String),
|
||||
assetId: asset.id,
|
||||
fileAssetId: null,
|
||||
createdAt: expect.any(String),
|
||||
},
|
||||
]),
|
||||
});
|
||||
});
|
||||
|
||||
it.sequential('reports checksum mismatched files', async () => {
|
||||
await utils.truncateFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/admin/integrity/report?type=checksum_mismatch')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
nextCursor: undefined,
|
||||
items: expect.arrayContaining([
|
||||
{
|
||||
id: expect.any(String),
|
||||
type: 'checksum_mismatch',
|
||||
path: expect.any(String),
|
||||
assetId: asset.id,
|
||||
fileAssetId: null,
|
||||
createdAt: expect.any(String),
|
||||
},
|
||||
]),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /report/:id', async () => {
|
||||
it.sequential('delete untracked files', async () => {
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus, body: listBody } = await request(app)
|
||||
.get('/admin/integrity/report?type=untracked_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus).toBe(200);
|
||||
|
||||
const report = (listBody as IntegrityReportResponseDto).items.find(
|
||||
(item) => item.path === `/data/upload/${admin.userId}/untracked1.png`,
|
||||
)!;
|
||||
|
||||
const { status } = await request(app)
|
||||
.delete(`/admin/integrity/report/${report.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus2, body: listBody2 } = await request(app)
|
||||
.get('/admin/integrity/report?type=untracked_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus2).toBe(200);
|
||||
expect(listBody2).not.toBe(
|
||||
expect.objectContaining({
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: report.id,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.sequential('delete assets missing files', async () => {
|
||||
await utils.deleteFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus, body: listBody } = await request(app)
|
||||
.get('/admin/integrity/report?type=missing_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus).toBe(200);
|
||||
expect(listBody.items.length).toBe(1);
|
||||
|
||||
const report = (listBody as IntegrityReportResponseDto).items[0];
|
||||
|
||||
const { status } = await request(app)
|
||||
.delete(`/admin/integrity/report/${report.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityMissingFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus2, body: listBody2 } = await request(app)
|
||||
.get('/admin/integrity/report?type=missing_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus2).toBe(200);
|
||||
expect(listBody2.items.length).toBe(0);
|
||||
});
|
||||
|
||||
it.sequential('delete assets with failing checksum', async () => {
|
||||
await utils.truncateFolder(`/data/upload/${admin.userId}`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus, body: listBody } = await request(app)
|
||||
.get('/admin/integrity/report?type=checksum_mismatch')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus).toBe(200);
|
||||
expect(listBody.items.length).toBe(1);
|
||||
|
||||
const report = (listBody as IntegrityReportResponseDto).items[0];
|
||||
|
||||
const { status } = await request(app)
|
||||
.delete(`/admin/integrity/report/${report.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityChecksumMismatch,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status: listStatus2, body: listBody2 } = await request(app)
|
||||
.get('/admin/integrity/report?type=checksum_mismatch')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(listStatus2).toBe(200);
|
||||
expect(listBody2.items.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /report/:type/csv', () => {
|
||||
it.sequential('exports untracked files as csv', async () => {
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { status, headers, text } = await request(app)
|
||||
.get('/admin/integrity/report/untracked_file/csv')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(headers['content-type']).toContain('text/csv');
|
||||
expect(headers['content-disposition']).toContain('.csv');
|
||||
expect(text).toContain('id,type,assetId,fileAssetId,path');
|
||||
expect(text).toContain(`untracked_file`);
|
||||
expect(text).toContain(`/data/upload/${admin.userId}/untracked1.png`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /report/:id/file', () => {
|
||||
it.sequential('downloads untracked file', async () => {
|
||||
await utils.putTextFile('untracked-content', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
const { body: listBody } = await request(app)
|
||||
.get('/admin/integrity/report?type=untracked_file')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
|
||||
const report = (listBody as IntegrityReportResponseDto).items.find(
|
||||
(item) => item.path === `/data/upload/${admin.userId}/untracked1.png`,
|
||||
)!;
|
||||
|
||||
const { status, headers, body } = await request(app)
|
||||
.get(`/admin/integrity/report/${report.id}/file`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.buffer(true)
|
||||
.send();
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(headers['content-type']).toContain('application/octet-stream');
|
||||
expect(body.toString()).toBe('untracked-content');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -259,17 +259,6 @@ describe('/search', () => {
|
||||
assets: [assetHeic],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: "should search city ('')",
|
||||
deferred: () => ({
|
||||
dto: {
|
||||
city: '',
|
||||
visibility: AssetVisibility.Timeline,
|
||||
includeNull: true,
|
||||
},
|
||||
assets: [assetLast],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: 'should search city (null)',
|
||||
deferred: () => ({
|
||||
@@ -291,18 +280,6 @@ describe('/search', () => {
|
||||
assets: [assetDensity],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: "should search state ('')",
|
||||
deferred: () => ({
|
||||
dto: {
|
||||
state: '',
|
||||
visibility: AssetVisibility.Timeline,
|
||||
withExif: true,
|
||||
includeNull: true,
|
||||
},
|
||||
assets: [assetLast, assetNotocactus],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: 'should search state (null)',
|
||||
deferred: () => ({
|
||||
@@ -324,17 +301,6 @@ describe('/search', () => {
|
||||
assets: [assetFalcon],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: "should search country ('')",
|
||||
deferred: () => ({
|
||||
dto: {
|
||||
country: '',
|
||||
visibility: AssetVisibility.Timeline,
|
||||
includeNull: true,
|
||||
},
|
||||
assets: [assetLast],
|
||||
}),
|
||||
},
|
||||
{
|
||||
should: 'should search country (null)',
|
||||
deferred: () => ({
|
||||
@@ -441,7 +407,18 @@ describe('/search', () => {
|
||||
.get('/search/explore')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual([{ fieldName: 'exifInfo.city', items: [] }]);
|
||||
expect(Array.isArray(body)).toBe(true);
|
||||
expect(body).toEqual(expect.arrayContaining([{ fieldName: 'exifInfo.city', items: [] }]));
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
fieldName: 'createdAt',
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({ data: expect.objectContaining({ id: assetLast.id }) }),
|
||||
]),
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ describe('/server', () => {
|
||||
major: expect.any(Number),
|
||||
minor: expect.any(Number),
|
||||
patch: expect.any(Number),
|
||||
prerelease: expect.anything(),
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -115,6 +116,7 @@ describe('/server', () => {
|
||||
oauthAutoLaunch: false,
|
||||
ocr: false,
|
||||
passwordLogin: true,
|
||||
realtimeTranscoding: false,
|
||||
search: true,
|
||||
sidecar: true,
|
||||
trash: true,
|
||||
@@ -139,6 +141,7 @@ describe('/server', () => {
|
||||
maintenanceMode: false,
|
||||
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
|
||||
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
|
||||
minFaces: 3,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,18 +21,18 @@ describe('/system-config', () => {
|
||||
const response1 = await request(app)
|
||||
.put('/system-config')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ...config, newVersionCheck: { enabled: false } });
|
||||
.send({ ...config, newVersionCheck: { enabled: false, channel: 'stable' } });
|
||||
|
||||
expect(response1.status).toBe(200);
|
||||
expect(response1.body).toEqual({ ...config, newVersionCheck: { enabled: false } });
|
||||
expect(response1.body).toEqual({ ...config, newVersionCheck: { enabled: false, channel: 'stable' } });
|
||||
|
||||
const response2 = await request(app)
|
||||
.put('/system-config')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ...config, newVersionCheck: { enabled: true } });
|
||||
.send({ ...config, newVersionCheck: { enabled: true, channel: 'stable' } });
|
||||
|
||||
expect(response2.status).toBe(200);
|
||||
expect(response2.body).toEqual({ ...config, newVersionCheck: { enabled: true } });
|
||||
expect(response2.body).toEqual({ ...config, newVersionCheck: { enabled: true, channel: 'stable' } });
|
||||
});
|
||||
|
||||
it('should reject an invalid config entry', async () => {
|
||||
|
||||
@@ -230,6 +230,21 @@ describe('/users', () => {
|
||||
const after = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ download: { includeEmbeddedVideos: true } });
|
||||
});
|
||||
|
||||
it('should update minimum face count to display people', async () => {
|
||||
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(before).toMatchObject({ people: { minimumFaces: 3 } });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put('/users/me/preferences')
|
||||
.send({ people: { minimumFaces: 2 } })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ people: { minimumFaces: 2 } });
|
||||
|
||||
const after = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toMatchObject({ people: { minimumFaces: 2 } });
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /users/:id', () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
|
||||
import { immichCli } from 'src/utils';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const pkg = JSON.parse(readFileSync('../cli/package.json', 'utf8'));
|
||||
const pkg = JSON.parse(readFileSync('../packages/cli/package.json', 'utf8'));
|
||||
|
||||
describe(`immich --version`, () => {
|
||||
describe('immich --version', () => {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { LoginResponseDto, ManualJobName, QueueName } from '@immich/sdk';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { utils } from 'src/utils';
|
||||
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.describe.skip('Integrity', () => {
|
||||
let admin: LoginResponseDto;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
utils.initSdk();
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup();
|
||||
});
|
||||
|
||||
test('run integrity jobs to update stats', async ({ context, page }) => {
|
||||
await utils.setAuthCookies(context, admin.accessToken);
|
||||
|
||||
await utils.createJob(admin.accessToken, {
|
||||
name: ManualJobName.IntegrityUntrackedFiles,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, QueueName.IntegrityCheck);
|
||||
|
||||
await page.goto('/admin/maintenance');
|
||||
|
||||
const count = page.getByText('Untracked Files').locator('..').locator('..').locator('div').nth(1);
|
||||
|
||||
const previousCount = Number.parseInt((await count.textContent()) ?? '');
|
||||
|
||||
await utils.mkFolder(`/data/upload/${admin.userId}`);
|
||||
await utils.putTextFile('untracked', `/data/upload/${admin.userId}/untracked1.png`);
|
||||
|
||||
const checkButton = page.getByText('Integrity Report').locator('..').getByRole('button', { name: 'Check All' });
|
||||
|
||||
await checkButton.click();
|
||||
await expect(checkButton).toBeEnabled();
|
||||
|
||||
await expect(count).toContainText((previousCount + 1).toString());
|
||||
});
|
||||
});
|
||||
@@ -28,6 +28,7 @@ export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetRe
|
||||
ownerId: [],
|
||||
ratio: [],
|
||||
thumbhash: [],
|
||||
createdAt: [],
|
||||
fileCreatedAt: [],
|
||||
localOffsetHours: [],
|
||||
isFavorite: [],
|
||||
@@ -54,8 +55,8 @@ export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetRe
|
||||
result.duration.push(asset.duration);
|
||||
result.projectionType.push(asset.projectionType);
|
||||
result.livePhotoVideoId.push(asset.livePhotoVideoId);
|
||||
result.city.push(asset.city);
|
||||
result.country.push(asset.country);
|
||||
result.city?.push(asset.city);
|
||||
result.country?.push(asset.country);
|
||||
result.visibility.push(asset.visibility);
|
||||
}
|
||||
|
||||
@@ -338,7 +339,6 @@ export function toAssetResponseDto(asset: MockTimelineAsset, owner?: UserRespons
|
||||
livePhotoVideoId: asset.livePhotoVideoId,
|
||||
tags: [],
|
||||
people: [],
|
||||
unassignedFaces: [],
|
||||
stack: asset.stack,
|
||||
isOffline: false,
|
||||
hasMetadata: true,
|
||||
|
||||
@@ -66,7 +66,6 @@ export const createMockStackAsset = (ownerId: string): AssetResponseDto => {
|
||||
livePhotoVideoId: null,
|
||||
tags: [],
|
||||
people: [],
|
||||
unassignedFaces: [],
|
||||
stack: undefined,
|
||||
isOffline: false,
|
||||
hasMetadata: true,
|
||||
|
||||
@@ -536,7 +536,7 @@ test.describe('Timeline', () => {
|
||||
force: false,
|
||||
ids: [assetToTrash.id],
|
||||
});
|
||||
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
|
||||
await page.locator('#control-bar').getByLabel('Close').click();
|
||||
await page.getByText('Trash', { exact: true }).click();
|
||||
await timelineUtils.waitForTimelineLoad(page);
|
||||
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
|
||||
@@ -676,7 +676,7 @@ test.describe('Timeline', () => {
|
||||
ids: [assetToArchive.id],
|
||||
});
|
||||
await thumbnailUtils.expectThumbnailIsArchive(page, assetToArchive.id);
|
||||
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
|
||||
await page.locator('#control-bar').getByLabel('Close').click();
|
||||
await page.getByRole('link').getByText('Archive').click();
|
||||
await timelineUtils.waitForTimelineLoad(page);
|
||||
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
|
||||
@@ -823,7 +823,7 @@ test.describe('Timeline', () => {
|
||||
});
|
||||
// ensure thumbnail still exists and has favorite icon
|
||||
await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id);
|
||||
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
|
||||
await page.locator('#control-bar').getByLabel('Close').click();
|
||||
await page.getByRole('link').getByText('Favorites').click();
|
||||
await timelineUtils.waitForTimelineLoad(page);
|
||||
await pageUtils.goToAsset(page, assetToFavorite.fileCreatedAt);
|
||||
|
||||
+49
-4
@@ -90,7 +90,7 @@ export const tempDir = tmpdir();
|
||||
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
|
||||
export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
|
||||
export const immichCli = (args: string[]) =>
|
||||
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../cli' }).promise;
|
||||
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../packages/cli' }).promise;
|
||||
export const dockerExec = (args: string[]) =>
|
||||
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', args.join(' ')]);
|
||||
export const immichAdmin = (args: string[]) => dockerExec([`immich-admin ${args.join(' ')}`]);
|
||||
@@ -192,6 +192,7 @@ export const utils = {
|
||||
'user',
|
||||
'system_metadata',
|
||||
'tag',
|
||||
'integrity_report',
|
||||
];
|
||||
|
||||
const truncateTables = tables.filter((table) => table !== 'system_metadata');
|
||||
@@ -559,15 +560,61 @@ export const utils = {
|
||||
mkdirSync(`${testAssetDir}/temp`, { recursive: true });
|
||||
},
|
||||
|
||||
putFile(source: string, dest: string) {
|
||||
return executeCommand('docker', ['cp', source, `immich-e2e-server:${dest}`]).promise;
|
||||
},
|
||||
|
||||
async putTextFile(contents: string, dest: string) {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'test-'));
|
||||
const fn = join(dir, 'file');
|
||||
await pipeline(Readable.from(contents), createWriteStream(fn));
|
||||
return executeCommand('docker', ['cp', fn, `immich-e2e-server:${dest}`]).promise;
|
||||
},
|
||||
|
||||
async move(source: string, dest: string) {
|
||||
return executeCommand('docker', ['exec', 'immich-e2e-server', 'mv', source, dest]).promise;
|
||||
},
|
||||
|
||||
async copyFolder(source: string, dest: string) {
|
||||
return executeCommand('docker', ['exec', 'immich-e2e-server', 'cp', '-r', source, dest]).promise;
|
||||
},
|
||||
|
||||
async deleteFile(path: string) {
|
||||
return executeCommand('docker', ['exec', 'immich-e2e-server', 'rm', path]).promise;
|
||||
},
|
||||
|
||||
async deleteFolder(path: string) {
|
||||
return executeCommand('docker', ['exec', 'immich-e2e-server', 'rm', '-r', path]).promise;
|
||||
},
|
||||
|
||||
async truncateFolder(path: string) {
|
||||
return executeCommand('docker', [
|
||||
'exec',
|
||||
'immich-e2e-server',
|
||||
'find',
|
||||
path,
|
||||
'-type',
|
||||
'f',
|
||||
'-exec',
|
||||
'truncate',
|
||||
'-s',
|
||||
'1',
|
||||
'{}',
|
||||
';',
|
||||
]).promise;
|
||||
},
|
||||
|
||||
async mkFolder(path: string) {
|
||||
return executeCommand('docker', ['exec', 'immich-e2e-server', 'mkdir', '-p', path]).promise;
|
||||
},
|
||||
|
||||
createBackup: async (accessToken: string) => {
|
||||
await utils.createJob(accessToken, {
|
||||
name: ManualJobName.BackupDatabase,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(accessToken, 'backupDatabase');
|
||||
|
||||
return utils.poll(
|
||||
() => request(app).get('/admin/database-backups').set('Authorization', `Bearer ${accessToken}`),
|
||||
({ status, body }) => status === 200 && body.backups.length === 1,
|
||||
@@ -577,10 +624,8 @@ export const utils = {
|
||||
|
||||
resetBackups: async (accessToken: string) => {
|
||||
const { backups } = await listDatabaseBackups({ headers: asBearerAuth(accessToken) });
|
||||
|
||||
const backupFiles = backups.map((b) => b.filename);
|
||||
await deleteDatabaseBackup(
|
||||
{ databaseBackupDeleteDto: { backups: backupFiles } },
|
||||
{ databaseBackupDeleteDto: { backups: backups.map((dto) => dto.filename) } },
|
||||
{ headers: asBearerAuth(accessToken) },
|
||||
);
|
||||
},
|
||||
|
||||
+13
-1
@@ -5,8 +5,10 @@
|
||||
"acknowledge": "Neem kennis",
|
||||
"action": "Aksie",
|
||||
"action_common_update": "Werk by",
|
||||
"action_description": "’n Stel van aksies om op die gefiltreerde bates uit te voer",
|
||||
"actions": "Aksies",
|
||||
"active": "Aktief",
|
||||
"active_count": "Aktief: {count}",
|
||||
"activity": "Aktiwiteite",
|
||||
"activity_changed": "Aktiwiteit is {enabled, select, true {geaktiveer} other {gedeaktiveer}}",
|
||||
"add": "Voeg toe",
|
||||
@@ -14,6 +16,9 @@
|
||||
"add_a_location": "Voeg ’n ligging toe",
|
||||
"add_a_name": "Voeg ’n naam toe",
|
||||
"add_a_title": "Voeg ’n titel toe",
|
||||
"add_action": "Voeg aksie toe",
|
||||
"add_action_description": "Klik om ’n aksie toe te voeg om uit te voer",
|
||||
"add_assets": "Voeg bates by",
|
||||
"add_birthday": "Voeg ’n verjaarsdag toe",
|
||||
"add_endpoint": "Voeg eindpunt toe",
|
||||
"add_exclusion_pattern": "Voeg uitsluitingspatroon toe",
|
||||
@@ -27,9 +32,13 @@
|
||||
"add_to_album": "Voeg toe tot album",
|
||||
"add_to_album_bottom_sheet_added": "Tot {album} toegevoeg",
|
||||
"add_to_album_bottom_sheet_already_exists": "Reeds in {album}",
|
||||
"add_to_album_bottom_sheet_some_local_assets": "Sommige plaaslike bates kon nie toe gevoeg word tot die album nie",
|
||||
"add_to_album_toggle": "Wissel seleksie vir {album}",
|
||||
"add_to_albums": "Voeg toe tot albums",
|
||||
"add_to_albums_count": "Voeg toe tot albums ({count})",
|
||||
"add_to_bottom_bar": "Voeg toe",
|
||||
"add_to_shared_album": "Voeg toe tot gedeelde album",
|
||||
"add_upload_to_stack": "Voeg oplaai by stapel",
|
||||
"add_url": "Voeg bronadres toe",
|
||||
"added_to_archive": "Tot argief toegevoeg",
|
||||
"added_to_favorites": "Tot gunstelinge toegevoeg",
|
||||
@@ -46,6 +55,7 @@
|
||||
"backup_database": "Skep Databasisstortlêer",
|
||||
"backup_database_enable_description": "Aktiveer databasisstortlêers",
|
||||
"backup_keep_last_amount": "Aantal vorige stortlêers om te hou",
|
||||
"backup_onboarding_2_description": "plaaslike kopieë op verskillende toestelle. Dit sluit die hooflêers en ’n rugsteun van daardie lêers plaaslik in.",
|
||||
"backup_onboarding_3_description": "totale kopieë van u data, insluitend die oorspronklike lêers. Dit sluit 1 kopie op ’n ander perseel en 2 lokale kopieë in.",
|
||||
"backup_onboarding_description": "’n <backblaze-link>3-2-1-rugsteunstrategie</backblaze-link> word sterk aanbeveel om u data veilig te hou. Hou kopieë van u foto’s/video’s sowel as die Immich-databasis vir ’n volledige rugsteunoplossing.",
|
||||
"backup_onboarding_footer": "Lees hierdie <link>dokument</link> vir meer inligting oor hoe om ’n rugsteunkopie van Immich te maak.",
|
||||
@@ -61,6 +71,7 @@
|
||||
"confirm_reprocess_all_faces": "Is u seker u wil alle gesigte herverwerk? Dit sal ook genoemde mense skoonmaak.",
|
||||
"confirm_user_password_reset": "Is u seker u wil {user} se wagwoord terugstel?",
|
||||
"confirm_user_pin_code_reset": "Is u seker u wil {user} se PIN-kode herstel?",
|
||||
"copy_config_to_clipboard_description": "Kopieer die huidige stelselkonfigurasie as ’n JSON‑objek na die klipbord",
|
||||
"create_job": "Skep taak",
|
||||
"cron_expression": "Cron-uitdrukking",
|
||||
"cron_expression_description": "Stel die skanderingsinterval in met die cron-formaat. Kyk gerus na bv. <link>Crontab Guru</link> vir meer inligting",
|
||||
@@ -68,6 +79,8 @@
|
||||
"disable_login": "Deaktiveer aantekening",
|
||||
"duplicate_detection_job_description": "Begin masjienleer op items om soortgelyke beelde op te spoor. Maak staat op Slimsoek",
|
||||
"exclusion_pattern_description": "Met uitsluitingspatrone kan u lêers en vouers ignoreer wanneer u u biblioteek skandeer. Dit is nuttig as u vouers het wat lêers bevat wat u nie wil invoer nie, soos RAW-lêers.",
|
||||
"export_config_as_json_description": "Laai die huidige stelselkonfigurasie af as ’n JSON‑lêer",
|
||||
"external_libraries_page_description": "Admin eksterne biblioteekbladsy",
|
||||
"face_detection": "Gesigherkenning",
|
||||
"face_detection_description": "Identifiseer die gesigte in media d.m.v. masjienleer. Vir video’s word slegs die duimnael oorweeg. “Herlaai” (ver)werk al die media weer. “Stel terug” verwyder alle huidige gesigdata. “Onverwerk” plaas items in die ry wat nog nie verwerk is nie. Geïdentifiseerde gesigte sal ná voltooiing van Gesigidentifikasie vir Gesigherkenning in die ry geplaas word om hulle in bestaande of nuwe persone te groepeer.",
|
||||
"facial_recognition_job_description": "Groepeer gesigte in mense. Die stap is vinniger nadat Gesigherkenning klaar is. “Herstel” (her-)groepeer alle gesigte. “Vermiste” plaas gesigte in ry wat nie ’n persoon gekoppel het nie.",
|
||||
@@ -189,7 +202,6 @@
|
||||
"unsupported_field_type": "Onondersteunde veldtipe",
|
||||
"unsupported_file_type": "Lêer {file} kan nie opgelaai word nie omdat die lêertipe {type} nie ondersteun word nie.",
|
||||
"untagged": "Sonder etiket",
|
||||
"untitled_workflow": "Naamlose werkvloei",
|
||||
"up_next": "Volgende",
|
||||
"update_location_action_prompt": "Werk die ligging van {count} gekose items by met:",
|
||||
"updated_at": "Bygewerk",
|
||||
|
||||
+107
-19
@@ -5,10 +5,10 @@
|
||||
"acknowledge": "أُدرك ذلك",
|
||||
"action": "إجراء",
|
||||
"action_common_update": "تحديث",
|
||||
"action_description": "مجموعة من الفعاليات التي ستنفذ على الأصول التي تم تصفيتها",
|
||||
"action_description": "مجموعة إجراءات لتنفيذها على المحتويات المصفاة",
|
||||
"actions": "عمليات",
|
||||
"active": "نشط",
|
||||
"active_count": "فعال: {count}",
|
||||
"active_count": "نشط: {count}",
|
||||
"activity": "نشاط",
|
||||
"activity_changed": "النشاط {enabled, select, true {مُفْعل} other {معطّل}}",
|
||||
"add": "إضافة",
|
||||
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "أضف تاريخ الميلاد",
|
||||
"add_endpoint": "اضف نقطة نهاية",
|
||||
"add_exclusion_pattern": "إضافة نمط إستثناء",
|
||||
"add_filter": "اضف تصفية",
|
||||
"add_filter_description": "اضغط لاضافة شرط تصفية",
|
||||
"add_location": "إضافة موقع",
|
||||
"add_more_users": "إضافة مستخدمين آخرين",
|
||||
"add_partner": "أضف شريكًا",
|
||||
"add_path": "إضافة مسار",
|
||||
"add_photos": "إضافة صور",
|
||||
"add_step": "اضف خطوة",
|
||||
"add_tag": "اضف علامة",
|
||||
"add_to": "إضافة إلى…",
|
||||
"add_to_album": "إضافة إلى ألبوم",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "إضافة إلى ألبوم مشارك",
|
||||
"add_upload_to_stack": "اضف رفع الى حزمة",
|
||||
"add_url": "إضافة رابط",
|
||||
"add_workflow_step": "اضف خطوة سير عمل",
|
||||
"added_to_archive": "أُضيفت للأرشيف",
|
||||
"added_to_favorites": "أُضيفت للمفضلات",
|
||||
"added_to_favorites_count": "تم إضافة {count, number} إلى المفضلات",
|
||||
@@ -61,8 +59,8 @@
|
||||
"backup_onboarding_1_description": "نسخة خارج الموقع في موقع آخر.",
|
||||
"backup_onboarding_2_description": "نسخ محلية على أجهزة مختلفة. يشمل ذلك الملفات الرئيسية ونسخة احتياطية محلية منها.",
|
||||
"backup_onboarding_3_description": "إجمالي نُسخ بياناتك، بما في ذلك الملفات الأصلية. يشمل ذلك نسخةً واحدةً خارج الموقع ونسختين محليتين.",
|
||||
"backup_onboarding_description": "يُنصح باتباع <backblaze-link>استراتيجية النسخ الاحتياطي 3-2- 1</backblaze-link> لحماية بياناتك. احتفظ بنسخ احتياطية من صورك/فيديوهاتك المحمّلة، بالإضافة إلى قاعدة بيانات Immich، لضمان حل نسخ احتياطي شامل.",
|
||||
"backup_onboarding_footer": "لمزيد من المعلومات حول النسخ الاحتياطي لـ <link>Immich</link>، يرجى الرجوع إلى <link>الوثائق</link>.",
|
||||
"backup_onboarding_description": "يُنصح باتباع استراتيجية النسخ الاحتياطي <backblaze-link>3-2-1 backup strategy</backblaze-link> لحماية بياناتك. يجب عليك الاحتفاظ بنسخ من الصور/مقاطع الفيديو المرفوعة بالإضافة إلى قاعدة بيانات Immich للحصول على حل نسخ احتياطي شامل.",
|
||||
"backup_onboarding_footer": "لمزيد من المعلومات حول النسخ الاحتياطي لـ Immich، يرجى الرجوع إلى <link>الوثائق</link>.",
|
||||
"backup_onboarding_parts_title": "يتضمن النسخ الاحتياطي 3-2-1 ما يلي:",
|
||||
"backup_onboarding_title": "النسخ الاحتياطية",
|
||||
"backup_settings": "إعدادات تفريغ قاعدة البيانات",
|
||||
@@ -267,6 +265,8 @@
|
||||
"notification_enable_email_notifications": "تفعيل إشعارات البريد الإلكتروني",
|
||||
"notification_settings": "إعدادات الإشعارات",
|
||||
"notification_settings_description": "إدارة إعدادات الإشعارات، بما في ذلك البريد الإلكتروني",
|
||||
"oauth_allow_insecure_requests": "السماح بالطلبات الغير الآمنة",
|
||||
"oauth_allow_insecure_requests_description": "تحذير: هذا يعطل التحقق من صحة شهادة أمن طبقة النقل لطلبات الترخيص المفتوح وقد يعرضك الهجمات الوسطية.",
|
||||
"oauth_auto_launch": "التشغيل التلقائي",
|
||||
"oauth_auto_launch_description": "ابدأ تدفق تسجيل الدخول OAuth تلقائيًا عند الانتقال إلى صفحة تسجيل الدخول",
|
||||
"oauth_auto_register": "التسجيل التلقائي",
|
||||
@@ -274,9 +274,11 @@
|
||||
"oauth_button_text": "نص الزر",
|
||||
"oauth_client_secret_description": "مطلوب للعميل السري، او اذا PKCE(مفتاح الاثبات لتبادل الكود) ليس مدعوم من العميل العام.",
|
||||
"oauth_enable_description": "تسجيل الدخول باستخدام OAuth",
|
||||
"oauth_end_session_url_description": "إعادة توجيه المستخدم إلى معرف الموارد الموحد (URI) هذا عند تسجيل الخروج.",
|
||||
"oauth_mobile_redirect_uri": "عنوان URI لإعادة التوجيه على الهاتف",
|
||||
"oauth_mobile_redirect_uri_override": "تجاوز عنوان URI لإعادة التوجيه على الهاتف",
|
||||
"oauth_mobile_redirect_uri_override_description": "قم بتفعيله عندما لا يسمح موفر OAuth بمعرف URI للجوال، مثل ''{callback}''",
|
||||
"oauth_prompt_description": "مُعامل التوجيه (مثلselect_account, login, consent)",
|
||||
"oauth_role_claim": "المطالبة بالدور(صلاحيات)",
|
||||
"oauth_role_claim_description": "منح وصول المسؤول تلقائيًا بناءً على وجود هذا الطلب. قد يكون الطلب إما 'مستخدم' أو 'مسؤول'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +305,8 @@
|
||||
"refreshing_all_libraries": "تحديث كافة المكتبات",
|
||||
"registration": "تسجيل المدير",
|
||||
"registration_description": "بما أنك أول مستخدم في النظام، سيتم تعيينك كمسؤول وستكون مسؤولًا عن المهام الإدارية، وسيتم إنشاء مستخدمين إضافيين بواسطتك.",
|
||||
"release_channel_release_candidate": "إصدار مرشح",
|
||||
"release_channel_stable": "مستقر",
|
||||
"remove_failed_jobs": "ازالة العمليات التي فشلت",
|
||||
"require_password_change_on_login": "الطلب من المستخدم تغيير كلمة المرور عند تسجيل الدخول الأول",
|
||||
"reset_settings_to_default": "إعادة ضبط الإعدادات إلى الوضع الافتراضي",
|
||||
@@ -333,7 +337,7 @@
|
||||
"storage_template_migration_description": "قم بتطبيق القالب الحالي <link>{template}</link> على المحتويات التي تم رفعها سابقًا",
|
||||
"storage_template_migration_info": "تغييرات النموذج الخزني ستغير جميع الصيغ الى احرف صغيرة. تغييرات النموذج ستنطبق فقط على المحتويات الجديدة. لتطبيق النموذج على المحتويات التي تم رفعها سابقًا، قم بتشغيل <link>{job}</link>.",
|
||||
"storage_template_migration_job": "وظيفة تهجير قالب التخزين",
|
||||
"storage_template_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <template-link>Storage Template</template-link> و <implications-link>implications</implications-link>.",
|
||||
"storage_template_more_details": "لمزيد من التفاصيل حول هذه الميزة، يرجى الرجوع إلى <template-link>Storage Template</template-link> و <implications-link>implications</implications-link>",
|
||||
"storage_template_onboarding_description_v2": "عند التفعيل. هذه الخاصية ستقوم بالترتيب التلقائي للملفات بناء على نموذج معرف من قبل المستخدم. رجاء اطلع على <link>التوثيق</link>.",
|
||||
"storage_template_path_length": "الحد التقريبي لطول المسار: <b>{length, number}</b>/{limit, number}",
|
||||
"storage_template_settings": "قالب التخزين",
|
||||
@@ -397,6 +401,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "ينطبق فقط على VAAPI وQSV. يضبط عقدة dri المستخدمة لتحويل ترميز الأجهزة.",
|
||||
"transcoding_preset_preset": "الضبط المُسبق (-preset)",
|
||||
"transcoding_preset_preset_description": "سرعة الضغط. تؤدي الإعدادات المسبقة الأبطأ إلى إنتاج ملفات أصغر حجمًا، وزيادة الجودة عند استهداف معدل بت معين. يتجاهل VP9 السرعات الأعلى من 'الأسرع'.",
|
||||
"transcoding_realtime": "تحويل الترميز في الوقت الفعلي [تجريبي]",
|
||||
"transcoding_realtime_description": "يتيح إجراء تحويل الترميز في الوقت الفعلي أثناء بث الفيديو. كما يمكّن من تبديل الجودة، ولكنه قد يتسبب في زيادة زمن تأخير التشغيل وحدوث تقطيع، اعتماداً على قدرات الخادم.",
|
||||
"transcoding_realtime_enabled": "تفعيل تحويل الترميز في الوقت الفعلي",
|
||||
"transcoding_realtime_enabled_description": "في حال تعطيله، سيرفض الخادم بدء جلسات تحويل ترميز جديدة في الوقت الفعلي.",
|
||||
"transcoding_reference_frames": "الإطارات المرجعية",
|
||||
"transcoding_reference_frames_description": "عدد الإطارات التي يجب الرجوع إليها عند ضغط إطار معين. تعمل القيم الأعلى على تحسين كفاءة الضغط، ولكنها تبطئ عملية التشفير. 0 يضبط هذه القيمة تلقائيًا.",
|
||||
"transcoding_required_description": "فقط مقاطع الفيديو ذات التنسيق غير المقبول",
|
||||
@@ -440,6 +448,8 @@
|
||||
"user_settings_description": "إدارة إعدادات المستخدم",
|
||||
"user_successfully_removed": "المستخدم {email} تمت ازالته بنجاح.",
|
||||
"users_page_description": "صفحة ادارة المستخدمين",
|
||||
"version_check_channel": "قناة الإصدار",
|
||||
"version_check_channel_description": "اختر قناة الإصدار التي ترغب في تلقي إعلانات الإصدارات لها",
|
||||
"version_check_enabled_description": "تفعيل التحقق من الإصدارات الجديدة",
|
||||
"version_check_implications": "تعتمد ميزة التحقق من الإصدار على التواصل الدوري مع {server}",
|
||||
"version_check_settings": "التحقق من الإصدار",
|
||||
@@ -566,7 +576,7 @@
|
||||
"asset_hashing": "التجزئة…",
|
||||
"asset_list_group_by_sub_title": "تنظيم بواسطة",
|
||||
"asset_list_layout_settings_dynamic_layout_title": "تخطيط ديناميكي",
|
||||
"asset_list_layout_settings_group_automatically": "تلقائي",
|
||||
"asset_list_layout_settings_group_automatically": "تلقائيا",
|
||||
"asset_list_layout_settings_group_by": "مجموعة الأصول حسب",
|
||||
"asset_list_layout_settings_group_by_month_day": "شهر + يوم",
|
||||
"asset_list_layout_sub_title": "تصميم",
|
||||
@@ -696,6 +706,7 @@
|
||||
"birthdate_saved": "تم حفظ تاريخ الميلاد بنجاح",
|
||||
"birthdate_set_description": "يتم استخدام تاريخ الميلاد لحساب عمر هذا الشخص وقت التقاط الصورة.",
|
||||
"blurred_background": "خلفية مشوشة",
|
||||
"browse_templates": "تصفح القوالب",
|
||||
"bugs_and_feature_requests": "الأخطاء وطلبات الميزات",
|
||||
"build": "يبني",
|
||||
"build_image": "بناء الصورة",
|
||||
@@ -729,6 +740,7 @@
|
||||
"cannot_update_the_description": "لا يمكن تحديث الوصف",
|
||||
"cast": "بث",
|
||||
"cast_description": "ضبط وجهات البث المتوفرة",
|
||||
"change": "تغيير",
|
||||
"change_date": "غيّر التاريخ",
|
||||
"change_description": "تغيير الوصف",
|
||||
"change_display_order": "تغيير ترتيب العرض",
|
||||
@@ -757,6 +769,7 @@
|
||||
"check_corrupt_asset_backup_description": "قم بإجراء هذا الفحص فقط عبر شبكة Wi-Fi وبعد نسخ جميع الأصول احتياطيًا. قد يستغرق الإجراء بضع دقائق.",
|
||||
"check_logs": "تحقق من السجلات",
|
||||
"checksum": "مجموع التحقق",
|
||||
"choose": "اختيار",
|
||||
"choose_matching_people_to_merge": "اختر الأشخاص المتطابقين لدمجهم",
|
||||
"city": "المدينة",
|
||||
"cleanup_confirm_description": "Immich وجد {count} اصول (انشئت قبل {date}) تم خزنها احتياطيا الى الخادم. ازالة النسخ المحلية من هذا الجهاز?",
|
||||
@@ -774,6 +787,7 @@
|
||||
"clear": "إخلاء",
|
||||
"clear_all": "إخلاء الكل",
|
||||
"clear_all_recent_searches": "مسح جميع عمليات البحث الأخيرة",
|
||||
"clear_failed_count": "فشل المسح ({count})",
|
||||
"clear_file_cache": "مسح ذاكرة التخزين المؤقت للملفات",
|
||||
"clear_message": "إخلاء الرسالة",
|
||||
"clear_value": "إخلاء القيمة",
|
||||
@@ -805,6 +819,7 @@
|
||||
"comments_are_disabled": "التعليقات معطلة",
|
||||
"common_create_new_album": "إنشاء ألبوم جديد",
|
||||
"completed": "اكتمل",
|
||||
"configuration": "اعدادات",
|
||||
"confirm": "تأكيد",
|
||||
"confirm_admin_password": "تأكيد كلمة مرور المسؤول",
|
||||
"confirm_delete_face": "هل أنت متأكد من حذف وجه {name} من الأصول؟",
|
||||
@@ -819,6 +834,7 @@
|
||||
"contain": "محتواة",
|
||||
"context": "السياق",
|
||||
"continue": "متابعة",
|
||||
"control_bottom_app_bar_add_tags": "اضافة علامات",
|
||||
"control_bottom_app_bar_create_new_album": "إنشاء ألبوم جديد",
|
||||
"control_bottom_app_bar_delete_from_immich": "حذف من Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "حذف من الجهاز",
|
||||
@@ -832,6 +848,7 @@
|
||||
"copy_error": "نسخ الخطأ",
|
||||
"copy_file_path": "نسخ مسار الملف",
|
||||
"copy_image": "نسخ الصورة",
|
||||
"copy_json": "نسخ JSON",
|
||||
"copy_link": "نسخ الرابط",
|
||||
"copy_link_to_clipboard": "انسخ الرابط إلى الحافظة",
|
||||
"copy_password": "نسخ كلمة المرور",
|
||||
@@ -881,17 +898,16 @@
|
||||
"cutoff_date_description": "احتفظ بالصور من آخر…",
|
||||
"cutoff_day": "{count, plural, one {يوم} other {ايام}}",
|
||||
"cutoff_year": "{count, plural, one {سنة} other {سنوات}}",
|
||||
"daily_title_text_date": "E ، MMM DD",
|
||||
"daily_title_text_date_year": "E ، MMM DD ، yyyy",
|
||||
"dark": "معتم",
|
||||
"dark_theme": "تبديل المظهر إلى الداكن",
|
||||
"date": "تاريخ",
|
||||
"date_after": "التارخ بعد",
|
||||
"date_and_time": "التاريخ و الوقت",
|
||||
"date_before": "التاريخ قبل",
|
||||
"date_format": "E ، Lll D ، Y • H: MM A",
|
||||
"date_of_birth": "تاريخ الميلاد",
|
||||
"date_of_birth_saved": "تم حفظ تاريخ الميلاد بنجاح",
|
||||
"date_range": "نطاق الموعد",
|
||||
"date_time_original": "تاريخ/وقت الاصلي",
|
||||
"day": "يوم",
|
||||
"days": "ايام",
|
||||
"deduplicate_all": "إلغاء تكرار الكل",
|
||||
@@ -970,7 +986,10 @@
|
||||
"downloading_asset_filename": "جاري تنزيل الاصل {filename}",
|
||||
"downloading_from_icloud": "التنزيل من iCloud",
|
||||
"downloading_media": "تنزيل الوسائط",
|
||||
"drag_to_reorder": "اسحب لإعادة الترتيب",
|
||||
"drop_files_to_upload": "قم بإسقاط الملفات في أي مكان لرفعها",
|
||||
"duplicate": "تكرار",
|
||||
"duplicate_workflow": "تكرار سير العمل",
|
||||
"duplicates": "التكرارات",
|
||||
"duplicates_description": "قم بحل كل مجموعة من خلال الإشارة إلى التكرارات، إن وجدت.",
|
||||
"duration": "المدة",
|
||||
@@ -1072,6 +1091,7 @@
|
||||
"failed_to_remove_product_key": "تعذر إزالة مفتاح المنتج",
|
||||
"failed_to_reset_pin_code": "فشل اعادة تعيين رمز الPIN",
|
||||
"failed_to_stack_assets": "فشل في تكديس المحتويات",
|
||||
"failed_to_tag_assets": "فشل في وضع علامات على الأصول",
|
||||
"failed_to_unstack_assets": "فشل في فصل المحتويات",
|
||||
"failed_to_update_notification_status": "فشل في تحديث حالة الإشعار",
|
||||
"incorrect_email_or_password": "بريد أو كلمة مرور غير صحيحة",
|
||||
@@ -1191,11 +1211,13 @@
|
||||
"export_as_json": "تصدير كـ JSON",
|
||||
"export_database": "تصدير قاعدة البيانات",
|
||||
"export_database_description": "تصدير قاعدة البيانات من نوع SQLite",
|
||||
"exposure_time": "وقت التعرض",
|
||||
"extension": "الإمتداد",
|
||||
"external": "خارجي",
|
||||
"external_libraries": "المكتبات الخارجية",
|
||||
"external_network": "شبكة خارجية",
|
||||
"external_network_sheet_info": "عندما لا يتواجد على شبكة Wi-Fi المفضلة، فإنه سيتصل بالخادم من خلال أول عناوين URL أدناه التي يمكنه الوصول إليها، بدءًا من الأعلى إلى الأسفل",
|
||||
"f_number": "الفتحة البؤرية",
|
||||
"face_unassigned": "غير معين",
|
||||
"failed": "فشل",
|
||||
"failed_count": "فشل: {count}",
|
||||
@@ -1213,7 +1235,6 @@
|
||||
"features_setting_description": "إدارة ميزات التطبيق",
|
||||
"file_name_or_extension": "اسم الملف أو امتداده",
|
||||
"file_name_text": "أسم الملف",
|
||||
"file_name_with_value": "اسم الملف: {file_name}",
|
||||
"file_size": "حجم الملف",
|
||||
"filename": "اسم الملف",
|
||||
"filetype": "نوع الملف",
|
||||
@@ -1226,6 +1247,7 @@
|
||||
"find_them_fast": "يمكنك العثور عليها بسرعة بالاسم من خلال البحث",
|
||||
"first": "الاول",
|
||||
"fix_incorrect_match": "إصلاح المطابقة غير الصحيحة",
|
||||
"focal_length": "البعد البؤري",
|
||||
"folder": "مجلد",
|
||||
"folder_not_found": "لم يتم العثور على المجلد",
|
||||
"folders": "المجلدات",
|
||||
@@ -1236,6 +1258,7 @@
|
||||
"free_up_space_description": "نقل الصور والفديوات التي تم خزنها احتياطياالى سلة المهملات الخاصه بجهازك لتحرير المساحة. نسخك على اىخادم ستبقى بأمان.",
|
||||
"free_up_space_settings_subtitle": "تحرير خزن الجهاز",
|
||||
"full_path": "مسار كامل:{path}",
|
||||
"full_path_or_folder": "المسار الكامل او المجلد",
|
||||
"gcast_enabled": "كوكل كاست",
|
||||
"gcast_enabled_description": "تقوم هذه الميزة بتحميل الموارد الخارجية من Google حتى تعمل.",
|
||||
"general": "عام",
|
||||
@@ -1345,6 +1368,7 @@
|
||||
"ios_debug_info_no_sync_yet": "لم يتم تشغيل أي مهمة مزامنة في الخلفية حتى الآن",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {{count} عملية خلفية ادخلتةفي طابور} other {{count} عمليات خلفية ادخلت في طابور}}",
|
||||
"ios_debug_info_processing_ran_at": "المعالجة جرت في {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# عنصر} other {# عناصر}}",
|
||||
"jobs": "الوظائف",
|
||||
"json_editor": "محرر JSON",
|
||||
@@ -1392,11 +1416,13 @@
|
||||
"light_theme": "التبديل إلى المظهر الفاتح",
|
||||
"like": "اعجاب",
|
||||
"like_deleted": "تم حذف الإعجاب",
|
||||
"link": "رابط",
|
||||
"link_motion_video": "رابط فيديو الحركة",
|
||||
"link_to_docs": "لمزيد من المعلومات، يُرجى الرجوع إلى <link>الوثائق</link>.",
|
||||
"link_to_oauth": "الربط مع OAuth",
|
||||
"linked_oauth_account": "حساب مرتبط بـ OAuth",
|
||||
"list": "قائمة",
|
||||
"live": "حي",
|
||||
"loading": "تحميل",
|
||||
"loading_search_results_failed": "فشل تحميل نتائج البحث",
|
||||
"local": "محلّي",
|
||||
@@ -1518,6 +1544,38 @@
|
||||
"marked_all_as_read": "تم تحديد الكل كمقروء",
|
||||
"matches": "تطابقات",
|
||||
"matching_assets": "الاصول المطابقة",
|
||||
"media_chrome": {
|
||||
"auto": "تلقائي",
|
||||
"captions": "التعليقات التوضيحية",
|
||||
"captions_off": "اطفاء",
|
||||
"closed_captions": "الترجمة المرئية المغلقة",
|
||||
"decode_error": "فشل فك التشفير",
|
||||
"disable_captions": "تعطيل الترجمة",
|
||||
"enable_captions": "تفعيل الترجمة",
|
||||
"enter_fullscreen_mode": "ادخل إلى وضع ملء الشاشة",
|
||||
"exit_fullscreen_mode": "اخرج من وضع ملء الشاشة",
|
||||
"loop": "حلقة",
|
||||
"media_error_description": "خطأ في الوسائط تسبب في ايقاف التشغيل. قد تكون الوسائط تالفة او ان متصفحك لا يدعم الصيغة.",
|
||||
"media_loading": "تحميل الوسائط",
|
||||
"mute": "كتم",
|
||||
"network_error": "خطأ في الشبكة",
|
||||
"network_error_description": "خطأ في الشبكة تسبب في فشل تنزيل الوسائط.",
|
||||
"not_supported_error": "المصدر غير مدعوم",
|
||||
"playback_rate": "معدل التشغيل",
|
||||
"playback_rate_current": "معدل التشغيل الحالي",
|
||||
"playback_rate_value": "معدل التشغيل {playbackRate}",
|
||||
"playback_time": "وقت التشغيل",
|
||||
"quality": "جودة",
|
||||
"second": "ثانية",
|
||||
"seconds": "ثواني",
|
||||
"time_value_of_total_time": "{currentTime} من {totalTime}",
|
||||
"time_value_remaining": "{time} متبقي",
|
||||
"unmute": "الغاء الكتم",
|
||||
"unsupported_error_description": "حدث خطأ غير مدعوم. حدث فشل في الخادم او الشبكة, او المتصفح الخاص بك لا يدعم هذه الصيغة.",
|
||||
"video_not_loaded_unknown_time": "الفيديو غير محمل, الوقت غير معلوم.",
|
||||
"video_player": "مشغل الفيديو",
|
||||
"volume": "حجم"
|
||||
},
|
||||
"media_type": "نوع الوسائط",
|
||||
"memories": "الذكريات",
|
||||
"memories_all_caught_up": "كل شيء محدث",
|
||||
@@ -1543,9 +1601,10 @@
|
||||
"mobile_app": "تطبيق الجوال",
|
||||
"mobile_app_download_onboarding_note": "قم بتنزيل التطبيق المصاحب للهاتف المحمول باستخدام الخيارات التالية",
|
||||
"model": "نموذج",
|
||||
"modify_date": "تغيير التاريخ",
|
||||
"month": "شهر",
|
||||
"monthly_title_text_date_format": "ط ط ط",
|
||||
"more": "المزيد",
|
||||
"motion": "حركة",
|
||||
"move": "تحريك",
|
||||
"move_down": "انزل الى الاسفل",
|
||||
"move_off_locked_folder": "تحريك خارج المجلد المقفل",
|
||||
@@ -1562,6 +1621,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "لا يمكن تعديل موقع الأصول (المواد) للقراءة فقط، سوف يتخطى",
|
||||
"mute_memories": "كتم الذكريات",
|
||||
"my_albums": "ألبوماتي",
|
||||
"my_immich_description": "نسخ الصفحة الحالية كرابط Immich الخاص بي",
|
||||
"my_immich_title": "رابط Immich الخاص بي",
|
||||
"name": "الاسم",
|
||||
"name_or_nickname": "الاسم أو اللقب",
|
||||
"name_required": "الاسم مطلوب",
|
||||
@@ -1589,7 +1650,6 @@
|
||||
"next": "التالي",
|
||||
"next_memory": "الذكرى التالية",
|
||||
"no": "لا",
|
||||
"no_actions_added": "لم تتم إضافة إجراءات حتى الان",
|
||||
"no_albums_found": "لم يتم ايجاد البومات",
|
||||
"no_albums_message": "قم بإنشاء ألبوم لتنظيم الصور ومقاطع الفيديو الخاصة بك",
|
||||
"no_albums_with_name_yet": "يبدو أنه ليس لديك أي ألبومات بهذا الاسم حتى الآن.",
|
||||
@@ -1606,7 +1666,6 @@
|
||||
"no_exif_info_available": "لا تتوفر معلومات exif",
|
||||
"no_explore_results_message": "قم برفع المزيد من الصور لاستكشاف مجموعتك.",
|
||||
"no_favorites_message": "أضف المفضلة للعثور بسرعة على أفضل الصور ومقاطع الفيديو",
|
||||
"no_filters_added": "لم تتم إضافة أي فلتر بعد",
|
||||
"no_libraries_message": "إنشاء مكتبة خارجية لعرض الصور ومقاطع الفيديو الخاصة بك",
|
||||
"no_local_assets_found": "لم يتم العثور على أي اصول محلية تتطابق مع قيمة التحقق هذه",
|
||||
"no_location_set": "لم يتم تحديد موقع",
|
||||
@@ -1619,6 +1678,7 @@
|
||||
"no_results": "لا يوجد نتائج",
|
||||
"no_results_description": "جرب كلمة رئيسية مرادفة أو أكثر عمومية",
|
||||
"no_shared_albums_message": "قم بإنشاء ألبوم لمشاركة الصور ومقاطع الفيديو مع الأشخاص في شبكتك",
|
||||
"no_steps": "لم يتم اضافة خطوات بعد",
|
||||
"no_uploads_in_progress": "لا يوجد اي ملفات قيد الرفع",
|
||||
"none": "لا يوجد",
|
||||
"not_allowed": "غير مسموح",
|
||||
@@ -1664,6 +1724,7 @@
|
||||
"organize_into_albums": "ترتيب في ألبومات",
|
||||
"organize_into_albums_description": "أضف الصور الموجودة إلى الألبومات باستخدام إعدادات النسخ المتزامن الحالية",
|
||||
"organize_your_library": "تنظيم مكتبتك",
|
||||
"orientation": "اتجاه",
|
||||
"original": "أصلي",
|
||||
"other": "أخرى",
|
||||
"other_devices": "أجهزة أخرى",
|
||||
@@ -1755,6 +1816,8 @@
|
||||
"play_original_video_setting_description": "تفضيل تشغيل مقاطع الفيديو الأصلية بدلاً من مقاطع الفيديو المحولة. إذا لم يكن الملف الأصلي متوافقًا، فقد لا يتم تشغيله بشكل صحيح.",
|
||||
"play_transcoded_video": "تشغيل الفيديو المُعاد ترميزه",
|
||||
"please_auth_to_access": "الرجاء القيام بالمصادقة للوصول",
|
||||
"plugin_method_filter_type": "تصفية",
|
||||
"plugin_method_filter_type_description": "هذه الوسيلة تستطيع تصفية الاحداث و تمنع تشغيل الخطوات التالية شرطيا",
|
||||
"port": "المنفذ",
|
||||
"preferences_settings_subtitle": "ادارة تفضيلات التطبيق",
|
||||
"preferences_settings_title": "التفضيلات",
|
||||
@@ -1776,6 +1839,7 @@
|
||||
"profile_drawer_readonly_mode": "تم تفعيل وضع القراءة فقط. اضغط مطولا على رمز صورة المستخدم للخروج.",
|
||||
"profile_image_of_user": "صورة الملف الشخصي لـ {user}",
|
||||
"profile_picture_set": "مجموعة الصور الشخصية.",
|
||||
"projection_type": "نوع العرض",
|
||||
"public_album": "الألبوم العام",
|
||||
"public_share": "مشاركة عامة",
|
||||
"purchase_account_info": "داعم",
|
||||
@@ -1853,6 +1917,7 @@
|
||||
"remove_assets_title": "هل تريد إزالة المحتويات؟",
|
||||
"remove_custom_date_range": "إزالة النطاق الزمني المخصص",
|
||||
"remove_deleted_assets": "إزالة الملفات الغير متصلة",
|
||||
"remove_filter": "ازالة التصفية",
|
||||
"remove_from_album": "إزالة من الألبوم",
|
||||
"remove_from_album_action_prompt": "تم ازالة {count} من الالبوم",
|
||||
"remove_from_favorites": "إزالة من المفضلة",
|
||||
@@ -1926,6 +1991,8 @@
|
||||
"scan_settings": "إعدادات الفحص",
|
||||
"scanning": "جاري البحث",
|
||||
"scanning_for_album": "جارٍ الفحص عن ألبوم...",
|
||||
"screencast_mode_description": "إظهار مؤشرات أحداث لوحة المفاتيح والماوس على الشاشة",
|
||||
"screencast_mode_title": "تبديل وضع تسجيل الشاشة",
|
||||
"search": "البحث",
|
||||
"search_albums": "البحث في الألبومات",
|
||||
"search_by_context": "البحث حسب السياق",
|
||||
@@ -1933,6 +2000,8 @@
|
||||
"search_by_description_example": "يوم المشي لمسافات طويلة في سابا",
|
||||
"search_by_filename": "البحث بإسم الملف أو نوعه",
|
||||
"search_by_filename_example": "كـ IMG_1234.JPG أو PNG",
|
||||
"search_by_full_path": "بحث بالمسار الكامل او المجلد",
|
||||
"search_by_full_path_example": "/احمد/مشاريع/طباعة_ثلاثية_الابعاد/2026-07-01 - يمكنك البحث عن مشاريع, طباعة_ثلاثية_الابعاد, 2026 الخ.",
|
||||
"search_by_ocr": "البحث عن طريق التعرف البصري على الحروف",
|
||||
"search_by_ocr_example": "لاتيه",
|
||||
"search_camera_lens_model": "بحث نموذج العدسة...",
|
||||
@@ -2140,7 +2209,9 @@
|
||||
"show_in_timeline": "إظهار في المخطط الزمني",
|
||||
"show_in_timeline_setting_description": "إظهار الصور ومقاطع الفيديو من هذا المستخدم في المخطط الزمني الخاص بك",
|
||||
"show_keyboard_shortcuts": "إظهار اختصارات لوحة المفاتيح",
|
||||
"show_less": "اضهر اقل",
|
||||
"show_metadata": "إظهار البيانات الوصفية",
|
||||
"show_more_fields": "{count, plural, one {اضهر #حقل اكثر} other {اضهر # حقول اكثر}}",
|
||||
"show_or_hide_info": "إظهار أو إخفاء المعلومات",
|
||||
"show_password": "إظهار كلمة المرور",
|
||||
"show_person_options": "إظهار خيارات الشخص",
|
||||
@@ -2148,6 +2219,7 @@
|
||||
"show_schema": "أظهر المخطط",
|
||||
"show_search_options": "إظهار خيارات البحث",
|
||||
"show_shared_links": "عرض الروابط المشتركة",
|
||||
"show_slideshow_metadata_overlay": "عرض معلومات الصورة",
|
||||
"show_slideshow_transition": "إظهار انتقال عرض الشرائح",
|
||||
"show_supporter_badge": "شارة المؤيد",
|
||||
"show_supporter_badge_description": "إظهار شارة المؤيد",
|
||||
@@ -2163,9 +2235,13 @@
|
||||
"skip_to_folders": "تخطي إلى المجلدات",
|
||||
"skip_to_tags": "تخطي إلى العلامات",
|
||||
"slideshow": "عرض الشرائح",
|
||||
"slideshow_metadata_overlay_mode": "محتوى التراكب",
|
||||
"slideshow_metadata_overlay_mode_description_only": "وصف فقط",
|
||||
"slideshow_metadata_overlay_mode_full": "كامل",
|
||||
"slideshow_repeat": "اعادة عرض الشرائح",
|
||||
"slideshow_repeat_description": "العودة إلى البداية عند انتهاء عرض الشرائح",
|
||||
"slideshow_settings": "إعدادات عرض الشرائح",
|
||||
"smart_album": "ألبوم ذكي",
|
||||
"sort_albums_by": "رتب الألبومات حسب...",
|
||||
"sort_created": "تاريخ الإنشاء",
|
||||
"sort_items": "عدد العناصر",
|
||||
@@ -2188,6 +2264,11 @@
|
||||
"start_date_before_end_date": "يجب أن يكون تاريخ بدء الفترة قبل تاريخ نهايتها",
|
||||
"state": "الولاية",
|
||||
"status": "الحالة",
|
||||
"step_delete": "حذف خطوة",
|
||||
"step_delete_confirm": "هل انت متاكد من انك تريد حذف هذه الخطوة؟",
|
||||
"step_details": "تفاصيل الخطوة",
|
||||
"steps": "خطوات",
|
||||
"steps_count": "{count, plural, one {# خطوة} other {# خطوات}}",
|
||||
"stop_casting": "ايقاف البث",
|
||||
"stop_motion_photo": "إيقاف حركة الصورة",
|
||||
"stop_photo_sharing": "توقف عن مشاركة صورك؟",
|
||||
@@ -2214,6 +2295,8 @@
|
||||
"sync_status": "حالة النسخ المتزامن",
|
||||
"sync_status_subtitle": "عرض وإدارة نظام النسخ المتزامن",
|
||||
"sync_upload_album_setting_subtitle": "انشئ و ارفع صورك و فديوهاتك الالبومات المختارة في Immich",
|
||||
"system_theme": "سمة النظام",
|
||||
"system_theme_command_description": "استعمل سمة النظام ({value})",
|
||||
"tag": "العلامة",
|
||||
"tag_assets": "أصول العلامة",
|
||||
"tag_created": "تم إنشاء العلامة: {tag}",
|
||||
@@ -2279,7 +2362,7 @@
|
||||
"trash_page_title": "سلة المهملات ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "سيتم حذفُ العناصر المحذوفة نِهائيًا بعد {days, plural, one {# يوم} other {# أيام }}.",
|
||||
"trigger": "مفعِل",
|
||||
"trigger_asset_uploaded": "تم رفع الاصل",
|
||||
"trigger_asset_uploaded": "رفع الاصل",
|
||||
"trigger_asset_uploaded_description": "يتم تفعيله عند تحميل أصل جديد",
|
||||
"trigger_description": "حدث يبدأ سير العمل",
|
||||
"trigger_person_recognized": "تم التعرف على شخص",
|
||||
@@ -2319,7 +2402,6 @@
|
||||
"unsupported_field_type": "نوع حقل غير مدعوم",
|
||||
"unsupported_file_type": "لا يمكن رفع الملف {file} لأن نوع الملف {type} غير مدعوم.",
|
||||
"untagged": "غير مُعَلَّم",
|
||||
"untitled_workflow": "خطة سير عمل بدون عنوان",
|
||||
"up_next": "التالي",
|
||||
"update_location_action_prompt": "تحديث موقع {count} عناصر محددة على النحو التالي:",
|
||||
"updated_at": "تم التحديث",
|
||||
@@ -2348,6 +2430,7 @@
|
||||
"use_browser_locale_description": "تنسيق التواريخ والأوقات والأرقام وفقًا لإعدادات اللغة في متصفحك",
|
||||
"use_current_connection": "استخدم الاتصال الحالي",
|
||||
"use_custom_date_range": "استخدم النطاق الزمني المخصص بدلاً من ذلك",
|
||||
"use_template": "استخدام القالب",
|
||||
"user": "مستخدم",
|
||||
"user_has_been_deleted": "هذا المستخدم تم حذفه.",
|
||||
"user_id": "معرف المستخدم",
|
||||
@@ -2377,6 +2460,7 @@
|
||||
"video": "فيديو",
|
||||
"video_hover_setting": "تشغيل الصورة المصغرة للفيديو عند التمرير",
|
||||
"video_hover_setting_description": "تشغيل الصورة المصغرة للفيديو عند تحريك الماوس فوق العنصر. حتى عند التعطيل، يمكن بدء التشغيل عن طريق التمرير فوق رمز التشغيل.",
|
||||
"video_quality": "جودة الفيديو",
|
||||
"videos": "فيديوهات",
|
||||
"videos_count": "{count, plural, one {# مقطع فيديو } other {# مقاطع الفيديو }}",
|
||||
"videos_only": "الفديوات فقط",
|
||||
@@ -2409,8 +2493,10 @@
|
||||
"week": "أسبوع",
|
||||
"welcome": "مرحباً",
|
||||
"welcome_to_immich": "مرحباً بك في Immich",
|
||||
"when": "عندما",
|
||||
"width": "عُرض",
|
||||
"wifi_name": "اسم شبكة Wi-Fi",
|
||||
"workflow": "سير العمل",
|
||||
"workflow_delete_prompt": "متأكد من حذف سير العمل هذا؟",
|
||||
"workflow_deleted": "تم حذف سير العمل",
|
||||
"workflow_description": "وصف سير العمل",
|
||||
@@ -2420,11 +2506,13 @@
|
||||
"workflow_name": "اسم سير العمل",
|
||||
"workflow_navigation_prompt": "متاكد من المغادرة بدون حفظ التغييرات؟",
|
||||
"workflow_summary": "ملخص سير العمل",
|
||||
"workflow_templates": "قوالب سير العمل",
|
||||
"workflow_update_success": "تم تحديث سير العمل بنجاح",
|
||||
"workflow_updated": "تم تحديث سير العمل",
|
||||
"workflows": "سير العمل",
|
||||
"workflows": "سير العمليات",
|
||||
"workflows_help_text": "تعمل سير العمل على أتمتة الإجراءات على أصولك بناءً على المفعلات والفلاتر",
|
||||
"wrong_pin_code": "رمز التعريف الشخصي خاطئ",
|
||||
"x_of_total": "{x}\\{total}",
|
||||
"year": "سنة",
|
||||
"years_ago": "{years, plural, one {# سنة} other {# سنوات}} مضت",
|
||||
"yes": "نعم",
|
||||
|
||||
+24
-2
@@ -5,6 +5,7 @@
|
||||
"acknowledge": "Təsdiq et",
|
||||
"action": "Əməliyyat",
|
||||
"action_common_update": "Yenilə",
|
||||
"action_description": "Filtrlənmiş aktivliklər üzərində yerinə yetiriləcək əməliyyatlar toplusu",
|
||||
"actions": "Əməliyyatlar",
|
||||
"active": "Aktiv",
|
||||
"active_count": "Aktiv: {count}",
|
||||
@@ -15,6 +16,9 @@
|
||||
"add_a_location": "Məkan əlavə et",
|
||||
"add_a_name": "Ad əlavə et",
|
||||
"add_a_title": "Başlıq əlavə et",
|
||||
"add_action": "Yeni əməliyyat əlavə et",
|
||||
"add_action_description": "Əməliyyat əlavə etmək üçün klikləyin",
|
||||
"add_assets": "Aktivlik əlavə et",
|
||||
"add_birthday": "Doğum günü əlavə et",
|
||||
"add_endpoint": "Son nöqtə əlavə et",
|
||||
"add_exclusion_pattern": "Çıxarma nümunəsi əlavə et",
|
||||
@@ -46,7 +50,7 @@
|
||||
"authentication_settings": "Səlahiyyətləndirmə parametrləri",
|
||||
"authentication_settings_description": "Şifrə, OAuth və digər səlahiyyətləndirmə parametrləri",
|
||||
"authentication_settings_disable_all": "Bütün giriş etmə metodlarını söndürmək istədiyinizdən əminsinizmi? Giriş etmə funksiyası tamamilə söndürüləcəkdir.",
|
||||
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link> -ni istifadə edin.",
|
||||
"authentication_settings_reenable": "Yenidən aktiv etmək üçün <link> Server Əmri</link>-ni istifadə edin.",
|
||||
"background_task_job": "Arxa plan tapşırıqları",
|
||||
"backup_database": "Verilənlər bazasının dump-ını yaradın",
|
||||
"backup_database_enable_description": "Verilənlər bazasının artıq nüsxələrini aktiv et",
|
||||
@@ -54,6 +58,7 @@
|
||||
"backup_onboarding_1_description": "buludda və ya başqa fiziki yerdə saytdan kənar surət.",
|
||||
"backup_onboarding_2_description": "müxtəlif cihazlarda yerli nüsxələr. Bura əsas fayllar və həmin faylların ehtiyat lokal nüsxəsi daxildir.",
|
||||
"backup_onboarding_3_description": "orijinal fayllar da daxil olmaqla məlumatlarınızın ümumi surətləri. Buraya 1 kənar nüsxə və 2 lokal nüsxə daxildir.",
|
||||
"backup_onboarding_description": "<backblaze-link>3-2-1 yedəkləmə strategiyası</backblaze-link> məlumatlarınızı qorumaq üçün tövsiyə olunur. Yüklədiyiniz şəkil və videoların, həmçinin Immich verilənlər bazasının surətlərini saxlamalısınız ki, hərtərəfli yedəkləmə həlli əldə edəsiniz.",
|
||||
"backup_onboarding_footer": "Immich-in ehtiyat nüsxəsini çıxarmaq haqqında ətraflı məlumat üçün <link>sənədlərə</link> müraciət edin.",
|
||||
"backup_onboarding_parts_title": "3-2-1 ehtiyat nüsxəsinə aşağıdakılar daxildir:",
|
||||
"backup_onboarding_title": "Ehtiyat surətlər",
|
||||
@@ -61,14 +66,31 @@
|
||||
"backup_settings_description": "Verilənlər bazasının ehtiyat nüsxə parametrlərini idarə et",
|
||||
"cleared_jobs": "{job} üçün tapşırıqlar silindi",
|
||||
"config_set_by_file": "Konfiqurasiya hal-hazırda konfiqurasiya faylı ilə təyin olunub",
|
||||
"confirm_delete_library": "{library} kitabxanasını silmək istədiyinizdən əminmisiniz?",
|
||||
"confirm_delete_library": "{library} kitabxanasını silmək istədiyinizə əminmisiniz?",
|
||||
"confirm_email_below": "Təsdiqləmək üçün aşağıya {email} yazın",
|
||||
"confirm_reprocess_all_faces": "Bütün üzləri yenidən emal etmək istədiyinizə əminsiniz? Bu, həmçinin adlandırılmış şəxsləri siləcək.",
|
||||
"confirm_user_password_reset": "{user} adlı istifadəçinin şifrəsini sıfırlamaq istədiyinizdən əminmisiniz?",
|
||||
"confirm_user_pin_code_reset": "{user} istifadəçisinin PIN kodunu sıfırlamaq istədiyinizə əminsiniz?",
|
||||
"copy_config_to_clipboard_description": "Cari sistem konfiqurasiyasını JSON obyekt kimi mübadilə buferinə kopyalayın",
|
||||
"create_job": "İş yarat",
|
||||
"cron_expression": "Cron ifadəsi",
|
||||
"cron_expression_description": "Cron formatından istifadə edərək skan intervalını təyin edin. Ətraflı məlumat üçün nümunələrə baxa bilərsiniz. <link>Crontab Guru</link>",
|
||||
"cron_expression_presets": "Cron ifadəsi ön ayarları",
|
||||
"disable_login": "Giriş etməni söndür",
|
||||
"duplicate_detection_job_description": "Bənzər şəkilləri tapmaq üçün maşın öyrənməsini işə salın. Bu prosses Smart Search funksiyasına əsaslanır",
|
||||
"exclusion_pattern_description": "İstisna nümunələri kitabxananızı skan edərkən faylları və qovluqları nəzərə almamağa imkan verir. Bu, RAW faylları kimi idxal etmək istəmədiyiniz faylları olan qovluqlarınız olduqda faydalıdır.",
|
||||
"export_config_as_json_description": "Cari sistem konfiqurasiyasını JSON faylı kimi endirin",
|
||||
"external_libraries_page_description": "Admin xarici kitabxana səhifəsi",
|
||||
"face_detection": "Üz tanıma",
|
||||
"failed_job_command": "{command} əmri {job} işi üçün uğursuz oldu",
|
||||
"force_delete_user_warning": "XƏBƏRDARLIQ: Bu əməliyyat istifadəçi və bütün məlumatları siləcəkdir. Bu prossesi və silinən faylları geri qaytarmaq olmaz.",
|
||||
"image_format": "Format",
|
||||
"image_format_description": "WebP, JPEG faylına görə daha kiçik həcmə sahibdir, lakin onu kodlaşdırmaq daha çox vaxt alır.",
|
||||
"image_fullsize_description": "Böyüdülmüş halda istifadə edilən, metadata-sı silinmiş tam ölçülü şəkil",
|
||||
"image_fullsize_enabled": "Tam ölçülü şəkil generasiyasını aktiv et",
|
||||
"image_fullsize_enabled_description": "Veb üçün uyğun olmayan formatlar üçün tam ölçülü şəkil yaradın. “Daxili önizləməyə üstünlük ver” aktiv olduqda, daxili önizləmələr çevrilmədən birbaşa istifadə olunur. JPEG kimi veb üçün uyğun formatlara təsir etmir.",
|
||||
"image_fullsize_quality_description": "Tam ölçülü şəkil keyfiyyəti (1-100). Daha yüksək dəyər daha yaxşı keyfiyyət verir, lakin daha böyük ölçülü fayl yaradır.",
|
||||
"image_fullsize_title": "Tam ölçülü şəkil tənzimləmələri",
|
||||
"image_preview_title": "Önizləmə parametrləri",
|
||||
"image_quality": "Keyfiyyət",
|
||||
"image_resolution": "Çözümlülük",
|
||||
|
||||
+1954
-39
File diff suppressed because it is too large
Load Diff
+130
-12
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "Добави дата на раждане",
|
||||
"add_endpoint": "Добави крайна точка",
|
||||
"add_exclusion_pattern": "Добави модел за изключване",
|
||||
"add_filter": "Добави филтър",
|
||||
"add_filter_description": "Натиснете за да добавите условие за филтър",
|
||||
"add_location": "Дoбави местоположение",
|
||||
"add_more_users": "Добави още потребители",
|
||||
"add_partner": "Добави партньор",
|
||||
"add_path": "Добави път",
|
||||
"add_photos": "Добави снимки",
|
||||
"add_step": "Добави стъпка",
|
||||
"add_tag": "Добави маркер",
|
||||
"add_to": "Добави към…",
|
||||
"add_to_album": "Добави към албум",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "Добави към споделен албум",
|
||||
"add_upload_to_stack": "Добави качените в група",
|
||||
"add_url": "Добави URL",
|
||||
"add_workflow_step": "Добави стъпка от работния процес",
|
||||
"added_to_archive": "Добавено към архива",
|
||||
"added_to_favorites": "Добавени към любимите ви",
|
||||
"added_to_favorites_count": "Добавени {count, number} към любими",
|
||||
@@ -81,6 +79,7 @@
|
||||
"cron_expression_description": "Настрой интервала на сканиране използвайки cron формата. За повече информация <link>Crontab Guru</link>",
|
||||
"cron_expression_presets": "Примерни Cron изрази",
|
||||
"disable_login": "Изключете вписването",
|
||||
"download_csv": "Изтегли CSV",
|
||||
"duplicate_detection_job_description": "Стартиране машинно обучение върху елементи, за откриване на подобни изображения. Разчита на Интелигентно Търсене",
|
||||
"exclusion_pattern_description": "Модели за изключване позволяват да игнорирате файлове и папки, когато сканирате вашата библиотека. Това е потребно, ако имате папки, които съдържат файлове, които не искате да импортирате. Примерно - RAW файлове.",
|
||||
"export_config_as_json_description": "Запази текущата системна конфигурация като JSON файл",
|
||||
@@ -193,6 +192,17 @@
|
||||
"maintenance_delete_backup": "Изтриване на архив",
|
||||
"maintenance_delete_backup_description": "Този файл ще бъде безвъзвратно изтрит.",
|
||||
"maintenance_delete_error": "Неуспешно изтриване на архив.",
|
||||
"maintenance_integrity_check_all": "Провери всички",
|
||||
"maintenance_integrity_checksum_mismatch": "Несъответствие на контролната сума",
|
||||
"maintenance_integrity_checksum_mismatch_job": "Проверка на контролните суми",
|
||||
"maintenance_integrity_checksum_mismatch_refresh_job": "Обнови докладите за проверка на конторлните суми",
|
||||
"maintenance_integrity_missing_file": "Липсващи файлове",
|
||||
"maintenance_integrity_missing_file_job": "Проверка за липсващи файлове",
|
||||
"maintenance_integrity_missing_file_refresh_job": "Обнови докладите за липсващи файлове",
|
||||
"maintenance_integrity_report": "Отчет за непокътнатост",
|
||||
"maintenance_integrity_untracked_file": "Непроследени файлове",
|
||||
"maintenance_integrity_untracked_file_job": "Проверка за непроследени файлове",
|
||||
"maintenance_integrity_untracked_file_refresh_job": "Обнови докладите за непроследени файлове",
|
||||
"maintenance_restore_backup": "Възстановяване на архив",
|
||||
"maintenance_restore_backup_description": "Immich ще изтрие всички текущи данни и после ще възстанови данните от избрания архив. Първо ще направи нов архив.",
|
||||
"maintenance_restore_backup_different_version": "Този архив е създаден с различна версия на Immich!",
|
||||
@@ -267,6 +277,8 @@
|
||||
"notification_enable_email_notifications": "Включване на имейл известията",
|
||||
"notification_settings": "Настройки на известията",
|
||||
"notification_settings_description": "Управление на настройките за известия, вкл. имейл",
|
||||
"oauth_allow_insecure_requests": "Разрешаване на несигурни заявки",
|
||||
"oauth_allow_insecure_requests_description": "ПРЕДУПРЕЖДЕНИЕ: Това изключва проверката за валидност на TLS сертификата при OAuth заявки и отваря възможност за атака от типа \"човек по средата\".",
|
||||
"oauth_auto_launch": "Автоматично стартиране",
|
||||
"oauth_auto_launch_description": "Автоматично стартиране на вход чрез OAuth, когато се отвори страницата за вход",
|
||||
"oauth_auto_register": "Автоматична регистрация",
|
||||
@@ -274,9 +286,11 @@
|
||||
"oauth_button_text": "Текст на бутона",
|
||||
"oauth_client_secret_description": "Задължително за поверителен клиент или когато не се поддържа PKCE (Proof Key for Code Exchange) за публичен клиент.",
|
||||
"oauth_enable_description": "Влизане с OAuth",
|
||||
"oauth_end_session_url_description": "Пренасочване на потребителя към този URI адрес, когато излезе от системата.",
|
||||
"oauth_mobile_redirect_uri": "URI за мобилно пренасочване",
|
||||
"oauth_mobile_redirect_uri_override": "URI пренасочване за мобилни устройства",
|
||||
"oauth_mobile_redirect_uri_override_description": "Разреши когато доставчика за OAuth удостоверяване не позволява за мобилни URI идентификатори, като ''{callback}''",
|
||||
"oauth_prompt_description": "Параметър за подкана (напр. select_account, login, consent)",
|
||||
"oauth_role_claim": "Потвърждение на роля",
|
||||
"oauth_role_claim_description": "Автоматично предоставяне на административни права при наличие на това потвържение. Потвърждението може да има стойност 'user' или 'admin'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +317,8 @@
|
||||
"refreshing_all_libraries": "Опресняване на всички библиотеки",
|
||||
"registration": "Администраторска регистрация",
|
||||
"registration_description": "Тъй като сте първият потребител в системата, ще бъдете назначен като администратор и ще отговаряте за административните задачи, а допълнителните потребители ще бъдат създадени от вас.",
|
||||
"release_channel_release_candidate": "Предварителна версия",
|
||||
"release_channel_stable": "Стабилна версия",
|
||||
"remove_failed_jobs": "Премахване на неуспешни задачи",
|
||||
"require_password_change_on_login": "Изискване за промяна паролата при първо влизане",
|
||||
"reset_settings_to_default": "Възстановяване на настройките по подразбиране",
|
||||
@@ -397,6 +413,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "Прилага се само за VAAPI и QSV. Задава dri възела, използван за хардуерно транскодиране.",
|
||||
"transcoding_preset_preset": "Предварително зададени(-preset)",
|
||||
"transcoding_preset_preset_description": "Скорост на компресия. По-бавните предварително зададени настройки създават по-малки файлове и повишават качеството при насочване към определен битрейт. VP9 игнорира скорости над „по-бързо“.",
|
||||
"transcoding_realtime": "Транскодиране в реално време [ЕКСПЕРИМЕНТАЛНО]",
|
||||
"transcoding_realtime_description": "Позволява транскодиране на видео по време на възпроизвеждане. Разрешава превключване на качеството, но може да предизвика по-голямо забавяне или накъсване на възпроизвеждането според възможностите на сървъра.",
|
||||
"transcoding_realtime_enabled": "Включи транскодиране в реално време",
|
||||
"transcoding_realtime_enabled_description": "Ако е изключено, сървъра ще отказва нова сесия за транскодиране в реално време.",
|
||||
"transcoding_reference_frames": "Референтни кадри",
|
||||
"transcoding_reference_frames_description": "Броят кадри за препратка при компресиране на даден кадър. По-високите стойности подобряват ефективността на компресията, но забавят кодирането. 0 задава тази стойност автоматично.",
|
||||
"transcoding_required_description": "Само видеа, които не са в приет формат",
|
||||
@@ -440,6 +460,8 @@
|
||||
"user_settings_description": "Управление на потребителските настройки",
|
||||
"user_successfully_removed": "Потребител {email} е успешно премахнат.",
|
||||
"users_page_description": "Страница за администриране на потребители",
|
||||
"version_check_channel": "Канал за обновявания",
|
||||
"version_check_channel_description": "Посочете канал, по който да получавате известия за нова версия",
|
||||
"version_check_enabled_description": "Активирай проверка на версията",
|
||||
"version_check_implications": "Функцията за проверка на версията разчита на периодична комуникация с {server}",
|
||||
"version_check_settings": "Проверка на версията",
|
||||
@@ -560,6 +582,7 @@
|
||||
"asset_added_to_album": "Добавено в албум",
|
||||
"asset_adding_to_album": "Добавяне в албум…",
|
||||
"asset_created": "Обектът е създаден",
|
||||
"asset_day_count": "{date}: {count, plural, one {# обект} other {# обекта}}",
|
||||
"asset_description_updated": "Описанието на елемента е обновено",
|
||||
"asset_filename_is_offline": "Активът {filename} е офлайн",
|
||||
"asset_has_unassigned_faces": "Елементът има незададени лица",
|
||||
@@ -689,6 +712,7 @@
|
||||
"backup_settings_subtitle": "Управление на настройките за качване",
|
||||
"backup_upload_details_page_more_details": "Повече подробности",
|
||||
"backward": "Назад",
|
||||
"battery_optimization_backup_reliability": "Изключване на оптимизацията на използване на батерията може да подобри надеждността на архивиране във фонов режим",
|
||||
"biometric_auth_enabled": "Включена биометрично удостоверяване",
|
||||
"biometric_locked_out": "Няма достъп до биометрично удостоверяване",
|
||||
"biometric_no_options": "Няма биометрична автентикация",
|
||||
@@ -696,6 +720,7 @@
|
||||
"birthdate_saved": "Датата на раждане е запазена успешно",
|
||||
"birthdate_set_description": "Датата на раждане се използва за изчисляване на възрастта на този човек към момента на снимката.",
|
||||
"blurred_background": "Замъглен заден фон",
|
||||
"browse_templates": "Разглеждане на шаблони",
|
||||
"bugs_and_feature_requests": "Бъгове и заявки за функции",
|
||||
"build": "Версия",
|
||||
"build_image": "Docker версия",
|
||||
@@ -729,6 +754,7 @@
|
||||
"cannot_update_the_description": "Описанието не може да бъде обновено",
|
||||
"cast": "Поточно предаване",
|
||||
"cast_description": "Настройка на наличните цели за предаване",
|
||||
"change": "Промени",
|
||||
"change_date": "Промени датата",
|
||||
"change_description": "Промени описанието",
|
||||
"change_display_order": "Промени реда на показване",
|
||||
@@ -757,6 +783,7 @@
|
||||
"check_corrupt_asset_backup_description": "Изпълни тази проверка само при Wi-Fi и след архивиране на всички обекти. Процедурата може да продължи няколко минути.",
|
||||
"check_logs": "Провери логовете",
|
||||
"checksum": "Контролна сума",
|
||||
"choose": "Избeри",
|
||||
"choose_matching_people_to_merge": "Изберете подходящи хора за сливане",
|
||||
"city": "Град",
|
||||
"cleanup_confirm_description": "Immich намери {count} обекта (създадени преди {date}), които са архивирани на сървъра. Да се премахнат ли локалните копия от това устройство?",
|
||||
@@ -774,6 +801,7 @@
|
||||
"clear": "Изчисти",
|
||||
"clear_all": "Изчисти всичко",
|
||||
"clear_all_recent_searches": "Изчистете всички скорошни търсения",
|
||||
"clear_failed_count": "Неуспешно изчистване на ({count})",
|
||||
"clear_file_cache": "Изчистване на кеша на файловете",
|
||||
"clear_message": "Изчисти съобщението",
|
||||
"clear_value": "Изчисти стойността",
|
||||
@@ -805,6 +833,7 @@
|
||||
"comments_are_disabled": "Коментарите са деактивирани",
|
||||
"common_create_new_album": "Създай нов албум",
|
||||
"completed": "Завършено",
|
||||
"configuration": "Конфигурация",
|
||||
"confirm": "Потвърди",
|
||||
"confirm_admin_password": "Потвърждаване на паролата на администратора",
|
||||
"confirm_delete_face": "Сигурни ли сте, че искате да изтриете лицето на {name} от актива?",
|
||||
@@ -819,6 +848,7 @@
|
||||
"contain": "В рамките на",
|
||||
"context": "Контекст",
|
||||
"continue": "Продължи",
|
||||
"control_bottom_app_bar_add_tags": "Добавяне на етикети",
|
||||
"control_bottom_app_bar_create_new_album": "Създай нов албум",
|
||||
"control_bottom_app_bar_delete_from_immich": "Премахни от Immich съръра",
|
||||
"control_bottom_app_bar_delete_from_local": "Премахни от устройството",
|
||||
@@ -832,6 +862,7 @@
|
||||
"copy_error": "Грешка при копирането",
|
||||
"copy_file_path": "Копирай пътя на файла",
|
||||
"copy_image": "Копиране на изображението",
|
||||
"copy_json": "Копирай JSON",
|
||||
"copy_link": "Копиране на линк",
|
||||
"copy_link_to_clipboard": "Копиране на връзката в клипборда",
|
||||
"copy_password": "Копиране на парола",
|
||||
@@ -881,22 +912,23 @@
|
||||
"cutoff_date_description": "Запазване на снимки от последните…",
|
||||
"cutoff_day": "{count, plural, one {ден} other {дни}}",
|
||||
"cutoff_year": "{count, plural, one {година} other {години}}",
|
||||
"daily_title_text_date": "E, dd MMM",
|
||||
"daily_title_text_date_year": "E, dd MMM yyyy",
|
||||
"dark": "Тъмен",
|
||||
"dark_theme": "Премини към тъмна тема",
|
||||
"date": "Дата",
|
||||
"date_after": "Дата след",
|
||||
"date_and_time": "Дата и час",
|
||||
"date_before": "Дата преди",
|
||||
"date_format": "E, d LLL y • h:mm a",
|
||||
"date_of_birth": "Дата на раждане",
|
||||
"date_of_birth_saved": "Дата на раждане е записана успешно",
|
||||
"date_range": "Период от време",
|
||||
"date_time_original": "Дата/Час на оригинала",
|
||||
"day": "Ден",
|
||||
"days": "Дни",
|
||||
"deduplicate_all": "Дедупликиране на всички",
|
||||
"default_locale": "Език по подразбиране",
|
||||
"default_locale_description": "Формат на дата и числа според езиковата настройка на браузъра",
|
||||
"default_quality_subtitle": "Качество при споделяне на файлове. Задръжте бутона за споделяне, за да изберете качеството.",
|
||||
"default_share_quality": "Качество по подразбиране при споделяне на файлове",
|
||||
"delete": "Изтрий",
|
||||
"delete_action_confirmation_message": "Сигурни ли сте, че искате да изтриете този обект? Следва преместване на обекта в коша за отпадъци на сървъра и ще получите предложение обекта да бъде изтрит локално",
|
||||
"delete_action_prompt": "{count} са изтрити",
|
||||
@@ -970,7 +1002,10 @@
|
||||
"downloading_asset_filename": "Изтегляне на файл {filename}",
|
||||
"downloading_from_icloud": "Сваляне от iCloud",
|
||||
"downloading_media": "Изтегляне на медия",
|
||||
"drag_to_reorder": "Плъзнете, за да пренаредите",
|
||||
"drop_files_to_upload": "Пуснете файловете, за да ги качите",
|
||||
"duplicate": "Направи копие",
|
||||
"duplicate_workflow": "Дублиране на работен процес",
|
||||
"duplicates": "Дубликати",
|
||||
"duplicates_description": "Изберете всяка група, като посочите кои, ако има такива, са дубликати.",
|
||||
"duration": "Продължителност",
|
||||
@@ -1072,6 +1107,7 @@
|
||||
"failed_to_remove_product_key": "Неуспешно премахване на продуктовия ключ",
|
||||
"failed_to_reset_pin_code": "Неуспешно нулиране на ПИН кода",
|
||||
"failed_to_stack_assets": "Неуспешно подреждане на обекти",
|
||||
"failed_to_tag_assets": "Неуспешно добавяне на етикет",
|
||||
"failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти",
|
||||
"failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията",
|
||||
"incorrect_email_or_password": "Неправилен имейл или парола",
|
||||
@@ -1191,15 +1227,18 @@
|
||||
"export_as_json": "Експортиране като JSON",
|
||||
"export_database": "Експорт на базата данни",
|
||||
"export_database_description": "Експорт на базата данни SQLite",
|
||||
"exposure_time": "Време на експозиция",
|
||||
"extension": "Разширение",
|
||||
"external": "Външно",
|
||||
"external_libraries": "Външни библиотеки",
|
||||
"external_network": "Външна мрежа",
|
||||
"external_network_sheet_info": "Когато няма връзка с предпочитаната Wi-Fi мрежа, приложението ще опитва да се свърже със сървъра чрез първия достъпен URL адрес, започвайки отгоре надолу",
|
||||
"f_number": "F-число",
|
||||
"face_unassigned": "Незададено",
|
||||
"failed": "Неуспешно",
|
||||
"failed_count": "Неуспешни: {count}",
|
||||
"failed_to_authenticate": "Неуспешна автентикация",
|
||||
"failed_to_delete_file": "Неуспешно изтриване на файл",
|
||||
"failed_to_load_assets": "Неуспешно зареждане на елементи",
|
||||
"failed_to_load_folder": "Неуспешно зареждане на папка",
|
||||
"favorite": "Любим",
|
||||
@@ -1213,7 +1252,6 @@
|
||||
"features_setting_description": "Управление на функциите на приложението",
|
||||
"file_name_or_extension": "Име на файл или разширение",
|
||||
"file_name_text": "Имe на файл",
|
||||
"file_name_with_value": "Име на файл: {file_name}",
|
||||
"file_size": "Размер на файла",
|
||||
"filename": "Име на файл",
|
||||
"filetype": "Тип на файл",
|
||||
@@ -1226,6 +1264,7 @@
|
||||
"find_them_fast": "Намерете ги бързо по име с търсене",
|
||||
"first": "Първи",
|
||||
"fix_incorrect_match": "Поправяне на неправилно съвпадение",
|
||||
"focal_length": "Фокусно разстояние",
|
||||
"folder": "Папка",
|
||||
"folder_not_found": "Папката не е намерена",
|
||||
"folders": "Папки",
|
||||
@@ -1236,6 +1275,7 @@
|
||||
"free_up_space_description": "Преместете архивираните снимки и видеа в кошчето на устройството, за да освободите място. Копията на сървъра ще бъдат запазени.",
|
||||
"free_up_space_settings_subtitle": "Освобождаване на място за съхранение на устройството",
|
||||
"full_path": "Пълен път: {path}",
|
||||
"full_path_or_folder": "Пълен път или папка",
|
||||
"gcast_enabled": "Gооgle Cast",
|
||||
"gcast_enabled_description": "За да работи тази функция зарежда външни ресурси от Google.",
|
||||
"general": "Общи",
|
||||
@@ -1329,6 +1369,7 @@
|
||||
"individual_share": "Индивидуално споделяне",
|
||||
"individual_shares": "Индивидуални споделяния",
|
||||
"info": "Информация",
|
||||
"integrity_checks": "Проверка за непокътнатост",
|
||||
"interval": {
|
||||
"day_at_onepm": "Всеки ден в 13:00",
|
||||
"hours": "Всеки {hours, plural, one {час} other {{hours, number} часа}}",
|
||||
@@ -1345,6 +1386,7 @@
|
||||
"ios_debug_info_no_sync_yet": "Все още не е изпълнявана задача за фонова синхронизация",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {{count} фонов процес} many {{count} фонови процеса} other {{count} фонови процеса}} в опашката",
|
||||
"ios_debug_info_processing_ran_at": "Започната обработка на {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# елемент} other {# елементи}}",
|
||||
"jobs": "Задачи",
|
||||
"json_editor": "JSON редактор",
|
||||
@@ -1375,6 +1417,7 @@
|
||||
"leave": "Излез",
|
||||
"leave_album": "Напускане на албума",
|
||||
"lens_model": "Модел леща",
|
||||
"less": "По-малко",
|
||||
"let_others_respond": "Позволете на другите да отговорят",
|
||||
"level": "Ниво",
|
||||
"library": "Библиотека",
|
||||
@@ -1392,11 +1435,14 @@
|
||||
"light_theme": "Премини към светла тема",
|
||||
"like": "Харесайте",
|
||||
"like_deleted": "Като изтрит",
|
||||
"link": "Връзка",
|
||||
"link_motion_video": "Линк към видео",
|
||||
"link_to_docs": "За повече информация вижте <link>документацията</link>.",
|
||||
"link_to_oauth": "Линк към OAuth",
|
||||
"linked_oauth_account": "Свързан OAuth акаунт",
|
||||
"list": "Лист",
|
||||
"live": "Живот",
|
||||
"load_more": "Зареди още",
|
||||
"loading": "Зареждане",
|
||||
"loading_search_results_failed": "Зареждането на резултатите от търсенето е неуспешно",
|
||||
"local": "Локално",
|
||||
@@ -1518,6 +1564,38 @@
|
||||
"marked_all_as_read": "Всички маркирани като прочетени",
|
||||
"matches": "Съвпадения",
|
||||
"matching_assets": "Съвпадащи обекти",
|
||||
"media_chrome": {
|
||||
"auto": "Авто",
|
||||
"captions": "Субтитри",
|
||||
"captions_off": "Изключенo",
|
||||
"closed_captions": "субтитри",
|
||||
"decode_error": "Грешка при декодиране",
|
||||
"disable_captions": "Изключи субтитри",
|
||||
"enable_captions": "Включи субтитри",
|
||||
"enter_fullscreen_mode": "На цял екран",
|
||||
"exit_fullscreen_mode": "Изход от цял екран",
|
||||
"loop": "Повтаряй",
|
||||
"media_error_description": "Възпроизвеждането е спряно поради грешка във файла. Може би файлът е повреден или браузъра не поддържа този формат.",
|
||||
"media_loading": "зареждане на медия",
|
||||
"mute": "Без звук",
|
||||
"network_error": "Грешка в мрежата",
|
||||
"network_error_description": "Прекъсване на зареждането поради грешка в мрежата.",
|
||||
"not_supported_error": "Този източник не се поддържа",
|
||||
"playback_rate": "Скорост на възпроизвеждане",
|
||||
"playback_rate_current": "текуща скорост на възпроизвеждане",
|
||||
"playback_rate_value": "Скорост на възпроизвеждане {playbackRate}",
|
||||
"playback_time": "продължителност",
|
||||
"quality": "Качество",
|
||||
"second": "секунда",
|
||||
"seconds": "секунди",
|
||||
"time_value_of_total_time": "{currentTime} от {totalTime}",
|
||||
"time_value_remaining": "{time} остават",
|
||||
"unmute": "Включи звук",
|
||||
"unsupported_error_description": "Възникна непоправима грешка. Проблем в сървъра или мрежата, възможно е браузъра да не поддържа този формат.",
|
||||
"video_not_loaded_unknown_time": "не е заредено видео, неизвестно време.",
|
||||
"video_player": "видеоплеер",
|
||||
"volume": "сила на звука"
|
||||
},
|
||||
"media_type": "Вид медия",
|
||||
"memories": "Спомени",
|
||||
"memories_all_caught_up": "Това е всичко за днес",
|
||||
@@ -1534,6 +1612,8 @@
|
||||
"merge_people_prompt": "Искате ли да слеете тези хора? Това действие е необратимо.",
|
||||
"merge_people_successfully": "Успешно сливане на хора",
|
||||
"merged_people_count": "Слят {count, plural, one {# човек} other {# човека}}",
|
||||
"minFaces": "Минимум лица",
|
||||
"minFaces_description": "Минималният брой разпознати лица, за да бъде показан човек като разпознат",
|
||||
"minimize": "Минимизиране",
|
||||
"minute": "Минута",
|
||||
"minutes": "Минути",
|
||||
@@ -1543,9 +1623,10 @@
|
||||
"mobile_app": "Мобилно приложение",
|
||||
"mobile_app_download_onboarding_note": "Свалете мобилното приложение Immich с някоя от следните опции",
|
||||
"model": "Модел",
|
||||
"modify_date": "Дата на промянa",
|
||||
"month": "Месец",
|
||||
"monthly_title_text_date_format": "MMMM г",
|
||||
"more": "Още",
|
||||
"motion": "Движение",
|
||||
"move": "Премести",
|
||||
"move_down": "Премести надолу",
|
||||
"move_off_locked_folder": "Извади от заключената папка",
|
||||
@@ -1562,6 +1643,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "Не може да се редактира местоположението на обект само за четене, пропускане",
|
||||
"mute_memories": "Изключване на звука на спомените",
|
||||
"my_albums": "Мои албуми",
|
||||
"my_immich_description": "Копирай адреса на текущата страница като връзка към моя Immich",
|
||||
"my_immich_title": "Връзка към моя Immich",
|
||||
"name": "Име",
|
||||
"name_or_nickname": "Име или прякор",
|
||||
"name_required": "Задължително е Име",
|
||||
@@ -1589,7 +1672,6 @@
|
||||
"next": "Следващо",
|
||||
"next_memory": "Следващ спомен",
|
||||
"no": "Не",
|
||||
"no_actions_added": "Все още не са добавени действия",
|
||||
"no_albums_found": "Не са намерени албуми",
|
||||
"no_albums_message": "Създайте албум за организиране на снимки и видеоклипове",
|
||||
"no_albums_with_name_yet": "Изглежда, че все още нямате албуми с това име.",
|
||||
@@ -1606,7 +1688,6 @@
|
||||
"no_exif_info_available": "Няма exif информация",
|
||||
"no_explore_results_message": "Качете още снимки, за да разгледате колекцията си.",
|
||||
"no_favorites_message": "Добавете в любими, за да намирате бързо най-добрите си снимки и видеоклипове",
|
||||
"no_filters_added": "Все още не са добавени филтри",
|
||||
"no_libraries_message": "Създайте външна библиотека за да разглеждате снимки и видеоклипове",
|
||||
"no_local_assets_found": "Не е намерен локален обект с такава контролна сума",
|
||||
"no_location_set": "Не е зададено местоположение",
|
||||
@@ -1619,6 +1700,7 @@
|
||||
"no_results": "Няма резултати",
|
||||
"no_results_description": "Опитайте със синоним или по-обща ключова дума",
|
||||
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
|
||||
"no_steps": "Все още няма добавени стъпки",
|
||||
"no_uploads_in_progress": "Няма качване в момента",
|
||||
"none": "Нищо",
|
||||
"not_allowed": "Не е разрешено",
|
||||
@@ -1627,6 +1709,7 @@
|
||||
"not_selected": "Не е избрано",
|
||||
"notes": "Бележки",
|
||||
"nothing_here_yet": "Засега тук няма нищо",
|
||||
"notification_backup_reliability": "Позволете известията, за да подобрите надеждността на архивиране във фонов режим",
|
||||
"notification_permission_dialog_content": "За да включиш известията, отиди в Настройки и избери Разреши.",
|
||||
"notification_permission_list_tile_content": "Дай разрешение за активиране на известията.",
|
||||
"notification_permission_list_tile_enable_button": "Разреши известията",
|
||||
@@ -1664,6 +1747,7 @@
|
||||
"organize_into_albums": "Подредете в албуми",
|
||||
"organize_into_albums_description": "Добавете наличните снимки в албуми, като използвате текущите настройки за синхронизиране",
|
||||
"organize_your_library": "Организиране на вашата библиотека",
|
||||
"orientation": "Ориентация",
|
||||
"original": "оригинал",
|
||||
"other": "Други",
|
||||
"other_devices": "Други устройства",
|
||||
@@ -1755,6 +1839,8 @@
|
||||
"play_original_video_setting_description": "Предпочитане на показване на оригиналното видео, вместо транскодирани. Ако формата на оригиналния файл не се поддържа, възпроизвеждането може да бъде неправилно.",
|
||||
"play_transcoded_video": "Покажи транскодирано видео",
|
||||
"please_auth_to_access": "Моля, удостовери за достъп",
|
||||
"plugin_method_filter_type": "Филтър",
|
||||
"plugin_method_filter_type_description": "Този метод може да филтрира събития и по условие да спира изпълнението на следващи стъпки",
|
||||
"port": "Порт",
|
||||
"preferences_settings_subtitle": "Управление на предпочитанията на приложението",
|
||||
"preferences_settings_title": "Предпочитания",
|
||||
@@ -1776,6 +1862,7 @@
|
||||
"profile_drawer_readonly_mode": "Режима само за четене е активиран. С дълго натискане върху картиката-аватар на потребителя ще деактивирате само за четене.",
|
||||
"profile_image_of_user": "Профилна снимка на {user}",
|
||||
"profile_picture_set": "Профилната снимка е сложена.",
|
||||
"projection_type": "Тип проекция",
|
||||
"public_album": "Публичен албум",
|
||||
"public_share": "Публично споделяне",
|
||||
"purchase_account_info": "Поддръжник",
|
||||
@@ -1853,6 +1940,7 @@
|
||||
"remove_assets_title": "Премахване на елементите?",
|
||||
"remove_custom_date_range": "Премахни зададения диапазон от дати",
|
||||
"remove_deleted_assets": "Премахни Изтритите Елементи",
|
||||
"remove_filter": "Премахни филтър",
|
||||
"remove_from_album": "Премахни от албума",
|
||||
"remove_from_album_action_prompt": "{count} са премахнати от албума",
|
||||
"remove_from_favorites": "Премахни от Любими",
|
||||
@@ -1926,6 +2014,8 @@
|
||||
"scan_settings": "Сканирай настройките",
|
||||
"scanning": "Сканиране",
|
||||
"scanning_for_album": "Сканирай за албум...",
|
||||
"screencast_mode_description": "Показване на екрана на индикатори за събития от клавиатурата и мишката",
|
||||
"screencast_mode_title": "Превключване на режима на скрийнкаст",
|
||||
"search": "Търсене",
|
||||
"search_albums": "Търси албуми",
|
||||
"search_by_context": "Търси по контекст",
|
||||
@@ -1933,6 +2023,8 @@
|
||||
"search_by_description_example": "Разходка в Сапа",
|
||||
"search_by_filename": "Търси по име на файла или разширение",
|
||||
"search_by_filename_example": "например IMG_1234.JPG или PNG",
|
||||
"search_by_full_path": "Търсене по пълен път или папка",
|
||||
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - търсена за Projects, 3D, Printing, 2026 и т.н.",
|
||||
"search_by_ocr": "Търсене на текст",
|
||||
"search_by_ocr_example": "Lattе",
|
||||
"search_camera_lens_model": "Търсене на модел на обектива...",
|
||||
@@ -2009,6 +2101,7 @@
|
||||
"select_person": "Изберете човек",
|
||||
"select_person_to_tag": "Избери лице, което да маркираш",
|
||||
"select_photos": "Изберете снимки",
|
||||
"select_quality": "Изберете качество",
|
||||
"select_trash_all": "Изберете всичко за кошчето",
|
||||
"select_user_for_sharing_page_err_album": "Създаването на албум не бе успешно",
|
||||
"selected": "Избрано",
|
||||
@@ -2072,6 +2165,8 @@
|
||||
"share_assets_selected": "{count} избрани",
|
||||
"share_dialog_preparing": "Подготовка...",
|
||||
"share_link": "Връзка за споделяне",
|
||||
"share_original": "Използвай оригинала (голям размер)",
|
||||
"share_preview": "Използвай миниатюра (намален размер)",
|
||||
"shared": "Споделено",
|
||||
"shared_album_activities_input_disable": "Коментарите са изключени",
|
||||
"shared_album_activity_remove_content": "Искате ли да изтриете тази активност?",
|
||||
@@ -2140,7 +2235,9 @@
|
||||
"show_in_timeline": "Показване във времевата линия",
|
||||
"show_in_timeline_setting_description": "Показване на снимки и видеа от този потребител във времевата линия",
|
||||
"show_keyboard_shortcuts": "Покажи клавишни комбинации",
|
||||
"show_less": "Покажи по-малко",
|
||||
"show_metadata": "Покажи метаданни",
|
||||
"show_more_fields": "{count, plural, one {Покажи още # поле} other {Покажи още # полета}}",
|
||||
"show_or_hide_info": "Покажи или скрий информацията",
|
||||
"show_password": "Покажи паролата",
|
||||
"show_person_options": "Показване на опции за лица",
|
||||
@@ -2148,6 +2245,7 @@
|
||||
"show_schema": "Покажи схема",
|
||||
"show_search_options": "Показване на опциите за търсене",
|
||||
"show_shared_links": "Покажи споделени линкове",
|
||||
"show_slideshow_metadata_overlay": "Покажи информационния слой",
|
||||
"show_slideshow_transition": "Покажи прехода на слайдшоуто",
|
||||
"show_supporter_badge": "Значка поддръжник",
|
||||
"show_supporter_badge_description": "Покажи значка поддръжник",
|
||||
@@ -2163,9 +2261,14 @@
|
||||
"skip_to_folders": "Премини към папките",
|
||||
"skip_to_tags": "Премини към етикетите",
|
||||
"slideshow": "Слайдшоу",
|
||||
"slideshow_metadata_overlay_mode": "Съдържание на слоя с информация",
|
||||
"slideshow_metadata_overlay_mode_description_only": "Само описание",
|
||||
"slideshow_metadata_overlay_mode_full": "Пълна",
|
||||
"slideshow_repeat": "Повтаряй слайдшоуто",
|
||||
"slideshow_repeat_description": "Започвай отново, когато слайдшоуто приключи",
|
||||
"slideshow_settings": "Настройки за слайдшоу",
|
||||
"smart_album": "Умен албум",
|
||||
"some_assets_already_have_a_location_warning": "Някои от избраните файлове вече имат местоположение",
|
||||
"sort_albums_by": "Сортиране на албуми по...",
|
||||
"sort_created": "Дата на създаване",
|
||||
"sort_items": "Брой елементи",
|
||||
@@ -2188,6 +2291,11 @@
|
||||
"start_date_before_end_date": "Началната дата трябва да бъде преди крайната дата",
|
||||
"state": "Щат",
|
||||
"status": "Статус",
|
||||
"step_delete": "Премахни стъпката",
|
||||
"step_delete_confirm": "Сигурни ли сте, че искате да премахнете тази стъпка?",
|
||||
"step_details": "Подробности за стъпката",
|
||||
"steps": "Стъпки",
|
||||
"steps_count": "{count, plural, one {# стъпка} other {# стъпки}}",
|
||||
"stop_casting": "Спри предаването",
|
||||
"stop_motion_photo": "Снимка със стоп кадър",
|
||||
"stop_photo_sharing": "Да спра ли споделянето на вашите снимки?",
|
||||
@@ -2214,6 +2322,8 @@
|
||||
"sync_status": "Състояние на синхронизацията",
|
||||
"sync_status_subtitle": "Преглед и управление на системата за синхронизация",
|
||||
"sync_upload_album_setting_subtitle": "Създавайте и зареждайте снимки и видеа в избрани албуми в Immich",
|
||||
"system_theme": "Тема от системата",
|
||||
"system_theme_command_description": "Използвай системната тема ({value})",
|
||||
"tag": "Таг",
|
||||
"tag_assets": "Тагни елементи",
|
||||
"tag_created": "Създаден етикет: {tag}",
|
||||
@@ -2279,7 +2389,7 @@
|
||||
"trash_page_title": "В коша ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Изхвърлените в кошчето елементи ще бъдат изтрити за постоянно след {days, plural, one {# ден} other {# дни}}.",
|
||||
"trigger": "Тригер",
|
||||
"trigger_asset_uploaded": "Обектът е зареден",
|
||||
"trigger_asset_uploaded": "Качване на файлове",
|
||||
"trigger_asset_uploaded_description": "Сработва при зареждане на нов обект",
|
||||
"trigger_description": "Събитие, което стартира работния процес",
|
||||
"trigger_person_recognized": "Разпознато е лице",
|
||||
@@ -2319,13 +2429,13 @@
|
||||
"unsupported_field_type": "Типа на полето не се поддържа",
|
||||
"unsupported_file_type": "Файлът {file} не може да бъде зареден, защото неговият тип {type} не се поддържа.",
|
||||
"untagged": "Немаркирани",
|
||||
"untitled_workflow": "Работен процес без име",
|
||||
"up_next": "Следващ",
|
||||
"update_location_action_prompt": "Обнови координатите на {count} избрани обекта с:",
|
||||
"updated_at": "Обновено",
|
||||
"updated_password": "Паролата е променена",
|
||||
"upload": "Качване",
|
||||
"upload_concurrency": "Успоредни качвания",
|
||||
"upload_day_count": "{date}: {count, plural, one {# качване} other {# качвания}}",
|
||||
"upload_details": "Детайли за качването",
|
||||
"upload_dialog_info": "Искате ли да архивирате на сървъра избраните обекти?",
|
||||
"upload_dialog_title": "Качи обект",
|
||||
@@ -2341,6 +2451,8 @@
|
||||
"upload_to_immich": "Казване в Immich ({count})",
|
||||
"uploading": "Качваме",
|
||||
"uploading_media": "Качване на медийни файлове",
|
||||
"uploads": "Качвания",
|
||||
"uploads_count": "{count, plural, one {# качване} other {# качвания}}",
|
||||
"url": "URL",
|
||||
"usage": "Потребление",
|
||||
"use_biometric": "Използвай биометрия",
|
||||
@@ -2348,6 +2460,7 @@
|
||||
"use_browser_locale_description": "Формат на дата, време и числа според езиковата настройка на браузъра",
|
||||
"use_current_connection": "Използвай текущата връзка",
|
||||
"use_custom_date_range": "Използвайте собствен диапазон от дати вместо това",
|
||||
"use_template": "Използвайте шаблон",
|
||||
"user": "Потребител",
|
||||
"user_has_been_deleted": "Този потребител е премахнат.",
|
||||
"user_id": "Потребител ИД",
|
||||
@@ -2377,6 +2490,7 @@
|
||||
"video": "Видеоклип",
|
||||
"video_hover_setting": "Възпроизвеждане на видеоклип при посочване с мишката",
|
||||
"video_hover_setting_description": "Възпроизвеждане на видеоклипа, когато мишката се движи над елемента. Дори когато е деактивирано, възпроизвеждането може да бъде стартирано чрез задържане на курсора на мишката върху иконата за възпроизвеждане.",
|
||||
"video_quality": "Качество на видеото",
|
||||
"videos": "Видеоклипове",
|
||||
"videos_count": "{count, plural, one {# Видео} other {# Видеа}}",
|
||||
"videos_only": "Само видеа",
|
||||
@@ -2409,8 +2523,10 @@
|
||||
"week": "Седмица",
|
||||
"welcome": "Добре дошли",
|
||||
"welcome_to_immich": "Добре дошли в Immich",
|
||||
"when": "Когато",
|
||||
"width": "Ширинa",
|
||||
"wifi_name": "Wi-Fi мрежа",
|
||||
"workflow": "Работен процес",
|
||||
"workflow_delete_prompt": "Наистина ли искате да изтриете този работен процес?",
|
||||
"workflow_deleted": "Работния процес е изтрит",
|
||||
"workflow_description": "Описание на работния процес",
|
||||
@@ -2420,11 +2536,13 @@
|
||||
"workflow_name": "Име на работния процес",
|
||||
"workflow_navigation_prompt": "Наистина ли искате да излезете без да съхраните промените?",
|
||||
"workflow_summary": "Обобщение за работния процес",
|
||||
"workflow_templates": "Шаблони на работния процес",
|
||||
"workflow_update_success": "Работният процес е успешно обновен",
|
||||
"workflow_updated": "Работният процес е обновен",
|
||||
"workflows": "Работни процеси",
|
||||
"workflows_help_text": "Работните процеси автоматизират действията с вашите обекти чрез тригери и филтри",
|
||||
"wrong_pin_code": "Грешен PIN код",
|
||||
"x_of_total": "{x}/{total}",
|
||||
"year": "Година",
|
||||
"years_ago": "преди {years, plural, one {# година} other {# години}}",
|
||||
"yes": "Да",
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
"add_birthday": "জন্মদিন যোগ করুন",
|
||||
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
|
||||
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
|
||||
"add_filter": "ফিল্টার যোগ করুন",
|
||||
"add_filter_description": "একটি ফিল্টার শর্ত যোগ করতে ক্লিক করুন",
|
||||
"add_location": "অবস্থান যুক্ত করুন",
|
||||
"add_more_users": "আরো ব্যবহারকারী যুক্ত করুন",
|
||||
"add_partner": "অংশীদার যোগ করুন",
|
||||
@@ -42,7 +40,6 @@
|
||||
"add_to_shared_album": "শেয়ার করা অ্যালবামে যোগ করুন",
|
||||
"add_upload_to_stack": "আপলোড স্ট্যাকে যোগ করুন",
|
||||
"add_url": "লিঙ্ক যোগ করুন",
|
||||
"add_workflow_step": "কাজের ধাপ যোগ করুন",
|
||||
"added_to_archive": "আর্কাইভ এ যোগ করা হয়েছে",
|
||||
"added_to_favorites": "ফেভারিটে যোগ করা হয়েছে",
|
||||
"added_to_favorites_count": "পছন্দের তালিকায় {count, number} যোগ করা হয়েছে",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
+111
-14
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "Afegeix la data de naixement",
|
||||
"add_endpoint": "afegir endpoint",
|
||||
"add_exclusion_pattern": "Afegir un patró d'exclusió",
|
||||
"add_filter": "Afegir filtre",
|
||||
"add_filter_description": "Feu clic per afegir una condició de filtre",
|
||||
"add_location": "Afegir la ubicació",
|
||||
"add_more_users": "Afegir més usuaris",
|
||||
"add_partner": "Afegir company/a",
|
||||
"add_path": "Afegir una ruta",
|
||||
"add_photos": "Afegir fotografies",
|
||||
"add_step": "Afegeix pas",
|
||||
"add_tag": "Afegir una etiqueta",
|
||||
"add_to": "Afegir a…",
|
||||
"add_to_album": "Afegir a un l'àlbum",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "Afegir a un àlbum compartit",
|
||||
"add_upload_to_stack": "Afegeix la càrrega a la pila",
|
||||
"add_url": "Afegir URL",
|
||||
"add_workflow_step": "Afegeix un pas del flux de treball",
|
||||
"added_to_archive": "Afegir a l'arxiu",
|
||||
"added_to_favorites": "Afegit als preferits",
|
||||
"added_to_favorites_count": "{count, number} afegits als preferits",
|
||||
@@ -267,6 +265,8 @@
|
||||
"notification_enable_email_notifications": "Habilita les notificacions de correu electrònic",
|
||||
"notification_settings": "Configuració de notificacions",
|
||||
"notification_settings_description": "Gestiona la configuració de notificacions, incloent-hi el correu electrònic",
|
||||
"oauth_allow_insecure_requests": "Permet sol·licituds no segures",
|
||||
"oauth_allow_insecure_requests_description": "AVÍS: Això inhabilita la validació de certificats TLS per a les sol·licituds OAuth i us pot exposar a atacs MITM.",
|
||||
"oauth_auto_launch": "Execució automàtica",
|
||||
"oauth_auto_launch_description": "Inicia el flux d'inici de sessió OAuth automàticament en accedir a la pàgina d'inici de sessió",
|
||||
"oauth_auto_register": "Registre automàtic",
|
||||
@@ -274,9 +274,11 @@
|
||||
"oauth_button_text": "Text del botó",
|
||||
"oauth_client_secret_description": "Requerit per clients confidencials, o si PKCE (Proof Key for Code Exchange) no està suportat pel client públic.",
|
||||
"oauth_enable_description": "Iniciar sessió amb OAuth",
|
||||
"oauth_end_session_url_description": "Redirigeix l'usuari a aquest URI quan tanqui la sessió.",
|
||||
"oauth_mobile_redirect_uri": "URI de redirecció mòbil",
|
||||
"oauth_mobile_redirect_uri_override": "Sobreescriu l'URI de redirecció mòbil",
|
||||
"oauth_mobile_redirect_uri_override_description": "Habilita quan el proveïdor d'OAuth no permet una URI mòbil, com ara ''{callback}''",
|
||||
"oauth_prompt_description": "Paràmetre de sol·licitud (per exemple, select_account, login, consent)",
|
||||
"oauth_role_claim": "Concessió de rol",
|
||||
"oauth_role_claim_description": "Atorgar accés d'administrador automàticament segons la presència d'aquesta concessió. La concessió pot ser 'usuari' o 'admin'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +305,8 @@
|
||||
"refreshing_all_libraries": "Actualitzant totes les biblioteques",
|
||||
"registration": "Registre d'administrador",
|
||||
"registration_description": "Com que ets el primer usuari del sistema, seràs designat com a administrador i seràs responsable de les tasques administratives. També seràs l'encarregat de crear usuaris addicionals.",
|
||||
"release_channel_release_candidate": "Candidat a versió",
|
||||
"release_channel_stable": "Estable",
|
||||
"remove_failed_jobs": "Eliminar treballs fallits",
|
||||
"require_password_change_on_login": "Requerir que l'usuari canviï la contrasenya en el primer inici de sessió",
|
||||
"reset_settings_to_default": "Restablir configuracions per defecte",
|
||||
@@ -397,6 +401,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "S'aplica només a VAAPI i QSV. Estableix el node dri utilitzat per a la transcodificació de maquinari.",
|
||||
"transcoding_preset_preset": "Preestablert (-preset)",
|
||||
"transcoding_preset_preset_description": "Velocitat de compressió. Els valors predefinits més lents produeixen fitxers més petits i augmenten la qualitat quan s'orienta a una taxa de bits determinada. VP9 ignora les velocitats superiors a 'més ràpides'.",
|
||||
"transcoding_realtime": "Transcodificació en temps real [EXPERIMENTAL]",
|
||||
"transcoding_realtime_description": "Permet que la transcodificació es realitzi en temps real mentre es retransmet el vídeo. Habilita el canvi de qualitat, però pot causar una latència de reproducció més alta i entretallats segons les capacitats del servidor.",
|
||||
"transcoding_realtime_enabled": "Activa transcodificació en temps real",
|
||||
"transcoding_realtime_enabled_description": "Si està desactivat, el servidor rebutjarà iniciar noves sessions de transcodificació en temps real.",
|
||||
"transcoding_reference_frames": "Fotogrames de referència",
|
||||
"transcoding_reference_frames_description": "El nombre de fotogrames a fer referència en comprimir un fotograma determinat. Els valors més alts milloren l'eficiència de la compressió, però alenteixen la codificació. 0 estableix aquest valor automàticament.",
|
||||
"transcoding_required_description": "Només vídeos que no tenen un format acceptat",
|
||||
@@ -440,6 +448,8 @@
|
||||
"user_settings_description": "Gestiona la configuració dels usuaris",
|
||||
"user_successfully_removed": "L'usuari {email} s'ha eliminat correctament.",
|
||||
"users_page_description": "Pàgina d'usuaris de l'administrador",
|
||||
"version_check_channel": "Canal de publicació",
|
||||
"version_check_channel_description": "Tria el canal de publicació del qual vols rebre avisos de noves versions",
|
||||
"version_check_enabled_description": "Activa la comprovació de la versió",
|
||||
"version_check_implications": "La funció de comprovació de versions depèn de comunicacions periòdiques amb {server}",
|
||||
"version_check_settings": "Comprovació de versió",
|
||||
@@ -560,6 +570,7 @@
|
||||
"asset_added_to_album": "Afegit a l'àlbum",
|
||||
"asset_adding_to_album": "Afegint a l'àlbum…",
|
||||
"asset_created": "Recurs creat",
|
||||
"asset_day_count": "{date}: {count, plural, one {# element} other {# elements}}",
|
||||
"asset_description_updated": "La descripció del recurs s'ha actualitzat",
|
||||
"asset_filename_is_offline": "L'element {filename} està fora de línia",
|
||||
"asset_has_unassigned_faces": "L'element té cares no assignades",
|
||||
@@ -689,6 +700,7 @@
|
||||
"backup_settings_subtitle": "Administra la configuració de pujada",
|
||||
"backup_upload_details_page_more_details": "Toqueu per obtenir més detalls",
|
||||
"backward": "Enrere",
|
||||
"battery_optimization_backup_reliability": "Desactivar les optimitzacions de la bateria pot millorar la fiabilitat de la còpia de seguretat en segon pla",
|
||||
"biometric_auth_enabled": "Autentificació biomètrica activada",
|
||||
"biometric_locked_out": "Esteu bloquejats fora de l'autenticació biomètrica",
|
||||
"biometric_no_options": "No hi ha opcions biomètriques disponibles",
|
||||
@@ -696,9 +708,10 @@
|
||||
"birthdate_saved": "Data de naixement guardada amb èxit",
|
||||
"birthdate_set_description": "La data de naixement s'utilitza per calcular l'edat d'aquesta persona en el moment d'una foto.",
|
||||
"blurred_background": "Fons difuminat",
|
||||
"browse_templates": "Explorar plantilles",
|
||||
"bugs_and_feature_requests": "Errors i sol·licituds de funcions",
|
||||
"build": "Construeix",
|
||||
"build_image": "Construeix la imatge",
|
||||
"build": "Número de compilació",
|
||||
"build_image": "Versió de la imatge compilada",
|
||||
"bulk_delete_duplicates_confirmation": "Esteu segurs que voleu suprimir de manera massiva {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i esborrarà permanentment tots els altres duplicats. No podeu desfer aquesta acció!",
|
||||
"bulk_keep_duplicates_confirmation": "Esteu segur que voleu mantenir {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això resoldrà tots els grups duplicats sense eliminar res.",
|
||||
"bulk_trash_duplicates_confirmation": "Esteu segur que voleu enviar a les escombraries {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i eliminarà la resta de duplicats.",
|
||||
@@ -729,6 +742,7 @@
|
||||
"cannot_update_the_description": "No es pot actualitzar la descripció",
|
||||
"cast": "Emet",
|
||||
"cast_description": "Configurar les destinacions de transmissió disponibles",
|
||||
"change": "Canvia",
|
||||
"change_date": "Canvia la data",
|
||||
"change_description": "Canvia la descripció",
|
||||
"change_display_order": "Canvia l'ordre de visualització",
|
||||
@@ -757,6 +771,7 @@
|
||||
"check_corrupt_asset_backup_description": "Executeu aquesta comprovació només mitjançant Wi-Fi i un cop s'hagi fet una còpia de seguretat de tots els actius. El procediment pot trigar uns minuts.",
|
||||
"check_logs": "Comprovar els registres",
|
||||
"checksum": "Suma de control",
|
||||
"choose": "Tria",
|
||||
"choose_matching_people_to_merge": "Trieu les persones que coincideixin per combinar-les",
|
||||
"city": "Ciutat",
|
||||
"cleanup_confirm_description": "Immich ha trobat {count} recursos (creats abans del {date}) carregats adequadament al servidor. Eliminar les còpies locals d'aquest dispositiu?",
|
||||
@@ -774,6 +789,7 @@
|
||||
"clear": "Buida",
|
||||
"clear_all": "Neteja-ho tot",
|
||||
"clear_all_recent_searches": "Esborra totes les cerques recents",
|
||||
"clear_failed_count": "Buida fallades ({count})",
|
||||
"clear_file_cache": "Buida la memòria cau de fitxers",
|
||||
"clear_message": "Neteja el missatge",
|
||||
"clear_value": "Neteja el valor",
|
||||
@@ -805,6 +821,7 @@
|
||||
"comments_are_disabled": "Els comentaris estan desactivats",
|
||||
"common_create_new_album": "Crea un àlbum nou",
|
||||
"completed": "Completat",
|
||||
"configuration": "Configuració",
|
||||
"confirm": "Confirmar",
|
||||
"confirm_admin_password": "Confirmeu la contrasenya d'administrador",
|
||||
"confirm_delete_face": "Estàs segur que vols eliminar la cara de {name} de les cares reconegudes?",
|
||||
@@ -819,6 +836,7 @@
|
||||
"contain": "Contingut",
|
||||
"context": "Context",
|
||||
"continue": "Continuar",
|
||||
"control_bottom_app_bar_add_tags": "Afegeix etiquetes",
|
||||
"control_bottom_app_bar_create_new_album": "Crea un àlbum nou",
|
||||
"control_bottom_app_bar_delete_from_immich": "Suprimeix del Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Suprimeix del dispositiu",
|
||||
@@ -832,6 +850,7 @@
|
||||
"copy_error": "Error de còpia",
|
||||
"copy_file_path": "Copia la ruta del fitxer",
|
||||
"copy_image": "Còpia imatge",
|
||||
"copy_json": "Copia el JSON",
|
||||
"copy_link": "Còpia l'enllaç",
|
||||
"copy_link_to_clipboard": "Còpia l'enllaç al porta-retalls",
|
||||
"copy_password": "Còpia la contrasenya",
|
||||
@@ -881,17 +900,16 @@
|
||||
"cutoff_date_description": "Manté fotos des de l'últim…",
|
||||
"cutoff_day": "{count, plural, one {dia} other {dies}}",
|
||||
"cutoff_year": "{count, plural, one {any} other {anys}}",
|
||||
"daily_title_text_date": "E, dd MMM",
|
||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||
"dark": "Fosc",
|
||||
"dark_theme": "Canvia a tema fosc",
|
||||
"date": "Data",
|
||||
"date_after": "Data posterior a",
|
||||
"date_and_time": "Data i hora",
|
||||
"date_before": "Data anterior a",
|
||||
"date_format": "E, d LLL, y • hh:mm",
|
||||
"date_of_birth": "Data de naixement",
|
||||
"date_of_birth_saved": "Data de naixement guardada amb èxit",
|
||||
"date_range": "Interval de dates",
|
||||
"date_time_original": "Data/Hora original",
|
||||
"day": "Dia",
|
||||
"days": "Dies",
|
||||
"deduplicate_all": "Desduplica-ho tot",
|
||||
@@ -970,7 +988,10 @@
|
||||
"downloading_asset_filename": "Descarregant l'element {filename}",
|
||||
"downloading_from_icloud": "Descarregant des d'iCloud",
|
||||
"downloading_media": "Descàrrega multimèdia",
|
||||
"drag_to_reorder": "Arrossegueu per reordenar",
|
||||
"drop_files_to_upload": "Deixeu els fitxers a qualsevol lloc per pujar-los",
|
||||
"duplicate": "Duplica",
|
||||
"duplicate_workflow": "Duplica el flux de treball",
|
||||
"duplicates": "Duplicats",
|
||||
"duplicates_description": "Resol cada grup indicant, si n'hi ha, quins són duplicats.",
|
||||
"duration": "Durada",
|
||||
@@ -1072,6 +1093,7 @@
|
||||
"failed_to_remove_product_key": "No s'ha pogut eliminar la clau del producte",
|
||||
"failed_to_reset_pin_code": "No s'ha pogut reiniciar el codi PIN",
|
||||
"failed_to_stack_assets": "No s'han pogut apilar els elements",
|
||||
"failed_to_tag_assets": "Ha fallat l'assignació d'etiquetes",
|
||||
"failed_to_unstack_assets": "No s'han pogut desapilar els elements",
|
||||
"failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions",
|
||||
"incorrect_email_or_password": "Correu electrònic o contrasenya incorrectes",
|
||||
@@ -1191,11 +1213,13 @@
|
||||
"export_as_json": "Exportar com a JSON",
|
||||
"export_database": "Exportar base de dades",
|
||||
"export_database_description": "Exportar la base de dades SQLite",
|
||||
"exposure_time": "Temps d'exposició",
|
||||
"extension": "Extensió",
|
||||
"external": "Extern",
|
||||
"external_libraries": "Llibreries externes",
|
||||
"external_network": "Xarxa externa",
|
||||
"external_network_sheet_info": "Quan no estigui a la xarxa Wi-Fi preferida, l'aplicació es connectarà al servidor mitjançant el primer dels URL següents a què pot arribar, començant de dalt a baix",
|
||||
"f_number": "Obertura",
|
||||
"face_unassigned": "Sense assignar",
|
||||
"failed": "Fallat",
|
||||
"failed_count": "Fallits: {count}",
|
||||
@@ -1213,7 +1237,6 @@
|
||||
"features_setting_description": "Administrar les funcions de l'aplicació",
|
||||
"file_name_or_extension": "Nom de l'arxiu o extensió",
|
||||
"file_name_text": "Nom del fitxer",
|
||||
"file_name_with_value": "Nom del fitxer: {file_name}",
|
||||
"file_size": "Mida del fitxer",
|
||||
"filename": "Nom del fitxer",
|
||||
"filetype": "Tipus d'arxiu",
|
||||
@@ -1226,6 +1249,7 @@
|
||||
"find_them_fast": "Trobeu-los ràpidament pel nom amb la cerca",
|
||||
"first": "Primer",
|
||||
"fix_incorrect_match": "Corregiu la coincidència incorrecta",
|
||||
"focal_length": "Longitud focal",
|
||||
"folder": "Carpeta",
|
||||
"folder_not_found": "Carpeta no trobada",
|
||||
"folders": "Carpetes",
|
||||
@@ -1236,6 +1260,7 @@
|
||||
"free_up_space_description": "Mou fotos i videos que ja tinguen còpia al servidor a la paperera del teu dispositiu per alliberar espai. Les còpies del servidor no es modificaran.",
|
||||
"free_up_space_settings_subtitle": "Alliberar espai del dispositiu",
|
||||
"full_path": "Ruta completa: {path}",
|
||||
"full_path_or_folder": "Camí sencer o carpeta",
|
||||
"gcast_enabled": "Google Cast",
|
||||
"gcast_enabled_description": "Aquesta funció carrega recursos externs de Google per funcionar.",
|
||||
"general": "General",
|
||||
@@ -1345,6 +1370,7 @@
|
||||
"ios_debug_info_no_sync_yet": "Encara no s'ha executat cap tasca de sincronització en segon pla",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {Un procés en segon pla a la cua} other {{count} processos en segon pla a la cua}}",
|
||||
"ios_debug_info_processing_ran_at": "El processament s'ha executat {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# element} other {# elements}}",
|
||||
"jobs": "Tasques",
|
||||
"json_editor": "Editor JSON",
|
||||
@@ -1375,6 +1401,7 @@
|
||||
"leave": "Marxar",
|
||||
"leave_album": "Abandonar àlbum",
|
||||
"lens_model": "Model de lents",
|
||||
"less": "Menys",
|
||||
"let_others_respond": "Deixa que els altres responguin",
|
||||
"level": "Nivell",
|
||||
"library": "Bibilioteca",
|
||||
@@ -1392,11 +1419,13 @@
|
||||
"light_theme": "Canviar a tema clar",
|
||||
"like": "M'agrada",
|
||||
"like_deleted": "M'agrada suprimit",
|
||||
"link": "Enllaç",
|
||||
"link_motion_video": "Enllaçar vídeo en moviment",
|
||||
"link_to_docs": "Per més informació, mirar la <link>documentation</link>.",
|
||||
"link_to_oauth": "Enllaç a OAuth",
|
||||
"linked_oauth_account": "Compte OAuth enllaçat",
|
||||
"list": "Llista",
|
||||
"live": "En viu",
|
||||
"loading": "Carregant",
|
||||
"loading_search_results_failed": "No s'han pogut carregar els resultats de la cerca",
|
||||
"local": "Local",
|
||||
@@ -1518,6 +1547,38 @@
|
||||
"marked_all_as_read": "Marcat tot com a llegit",
|
||||
"matches": "Coincidències",
|
||||
"matching_assets": "Recursos Coincidents",
|
||||
"media_chrome": {
|
||||
"auto": "Auto",
|
||||
"captions": "Llegendes",
|
||||
"captions_off": "Desactivat",
|
||||
"closed_captions": "Llegendes tancades",
|
||||
"decode_error": "Error de decodificació",
|
||||
"disable_captions": "Desactivar llegendes",
|
||||
"enable_captions": "Activar llegendes",
|
||||
"enter_fullscreen_mode": "Activar mode pantalla sencera",
|
||||
"exit_fullscreen_mode": "Desactivar mode pantalla sencera",
|
||||
"loop": "Bucle",
|
||||
"media_error_description": "Un error dels mitjans ha provocat l'aturada de la reproducció. El mitjà pot estar corromput o el navegador no suporta el format.",
|
||||
"media_loading": "carregant el mitjà",
|
||||
"mute": "Silencia",
|
||||
"network_error": "Error de xarxa",
|
||||
"network_error_description": "Un error de xarxa ha provocat la fallada de la descarrega.",
|
||||
"not_supported_error": "Font origen no suportada",
|
||||
"playback_rate": "Velocitat de reproducció",
|
||||
"playback_rate_current": "velocitat actual de reproducció",
|
||||
"playback_rate_value": "Velocitat de reproducció {playbackRate}",
|
||||
"playback_time": "temps de reproducció",
|
||||
"quality": "Quallitat",
|
||||
"second": "segon",
|
||||
"seconds": "segons",
|
||||
"time_value_of_total_time": "{currentTime} de {totalTime}",
|
||||
"time_value_remaining": "{time} restant",
|
||||
"unmute": "Activa so",
|
||||
"unsupported_error_description": "Un error no suportat ha passat. El servidor o la xarxa han fallat, o el vostre navegador no accepta aquest format.",
|
||||
"video_not_loaded_unknown_time": "vídeo no carregat, temps desconegut.",
|
||||
"video_player": "reproductor de vídeo",
|
||||
"volume": "volum"
|
||||
},
|
||||
"media_type": "Tipus de mitjà",
|
||||
"memories": "Records",
|
||||
"memories_all_caught_up": "Posat al dia",
|
||||
@@ -1534,6 +1595,8 @@
|
||||
"merge_people_prompt": "Vols combinar aquestes persones? Aquesta acció és irreversible.",
|
||||
"merge_people_successfully": "Persones combinades amb èxit",
|
||||
"merged_people_count": "Combinades {count, plural, one {# persona} other {# persones}}",
|
||||
"minFaces": "Nombre mínim de cares",
|
||||
"minFaces_description": "El nombre mínim de cares reconegudes perquè es mostri una persona",
|
||||
"minimize": "Minimitza",
|
||||
"minute": "Minut",
|
||||
"minutes": "Minuts",
|
||||
@@ -1543,9 +1606,10 @@
|
||||
"mobile_app": "Aplicació mòbil",
|
||||
"mobile_app_download_onboarding_note": "Descarregar la App de mòbil fent servir les seguents opcions",
|
||||
"model": "Model",
|
||||
"modify_date": "Canvia la data",
|
||||
"month": "Mes",
|
||||
"monthly_title_text_date_format": "MMMM a",
|
||||
"more": "Més",
|
||||
"motion": "Moviment",
|
||||
"move": "Moure",
|
||||
"move_down": "Moure cap avall",
|
||||
"move_off_locked_folder": "Moure fora de la carpeta bloquejada",
|
||||
@@ -1562,6 +1626,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "No es pot canviar la localització de fitxers de només lectura, saltant",
|
||||
"mute_memories": "Silenciar records",
|
||||
"my_albums": "Els meus àlbums",
|
||||
"my_immich_description": "Copia la pàgina actual com a enllaç de My Immich",
|
||||
"my_immich_title": "Enllaç My Immich",
|
||||
"name": "Nom",
|
||||
"name_or_nickname": "Nom o sobrenom",
|
||||
"name_required": "El nom és obligatori",
|
||||
@@ -1589,7 +1655,6 @@
|
||||
"next": "Següent",
|
||||
"next_memory": "Següent record",
|
||||
"no": "No",
|
||||
"no_actions_added": "Encara no s'han afegit accions",
|
||||
"no_albums_found": "No s'han trobat àlbums",
|
||||
"no_albums_message": "Creeu un àlbum per organitzar les vostres fotos i vídeos",
|
||||
"no_albums_with_name_yet": "Sembla que encara no tens cap àlbum amb aquest nom.",
|
||||
@@ -1606,7 +1671,6 @@
|
||||
"no_exif_info_available": "No hi ha informació d'exif disponible",
|
||||
"no_explore_results_message": "Penja més fotos per explorar la teva col·lecció.",
|
||||
"no_favorites_message": "Afegiu preferits per trobar les millors fotos i vídeos a l'instant",
|
||||
"no_filters_added": "Encara no s'han afegit filtres",
|
||||
"no_libraries_message": "Creeu una llibreria externa per veure les vostres fotos i vídeos",
|
||||
"no_local_assets_found": "No s'ha trobat cap recurs local amb aquest checksum",
|
||||
"no_location_set": "No s'ha definit cap ubicació",
|
||||
@@ -1619,6 +1683,7 @@
|
||||
"no_results": "Sense resultats",
|
||||
"no_results_description": "Proveu un sinònim o una paraula clau més general",
|
||||
"no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa",
|
||||
"no_steps": "Encara no s'ha afegit cap pas",
|
||||
"no_uploads_in_progress": "Cap pujada en progrés",
|
||||
"none": "Cap",
|
||||
"not_allowed": "No permès",
|
||||
@@ -1627,6 +1692,7 @@
|
||||
"not_selected": "No seleccionat",
|
||||
"notes": "Notes",
|
||||
"nothing_here_yet": "No hi ha res encara",
|
||||
"notification_backup_reliability": "Activa les notificacions per millorar la fiabilitat de les còpies de seguretat en segon pla",
|
||||
"notification_permission_dialog_content": "Per activar les notificacions, aneu a Configuració i seleccioneu permet.",
|
||||
"notification_permission_list_tile_content": "Atorga permís per a activar les notificacions.",
|
||||
"notification_permission_list_tile_enable_button": "Activa les notificacions",
|
||||
@@ -1664,6 +1730,7 @@
|
||||
"organize_into_albums": "Organitzar en àlbums",
|
||||
"organize_into_albums_description": "Posar fotos existents en àlbums utilitzant la configuració de sincronització actual",
|
||||
"organize_your_library": "Organitzeu la llibreria",
|
||||
"orientation": "Orientació",
|
||||
"original": "original",
|
||||
"other": "Altres",
|
||||
"other_devices": "Altres dispositius",
|
||||
@@ -1755,6 +1822,8 @@
|
||||
"play_original_video_setting_description": "Preferir la reproducció del video original sobre el video recodificat. Si el video original no es compatible potser no es reprodueixi correctament.",
|
||||
"play_transcoded_video": "Veure el video recodificat",
|
||||
"please_auth_to_access": "Per favor, autentica't per accedir",
|
||||
"plugin_method_filter_type": "Filtre",
|
||||
"plugin_method_filter_type_description": "Aquest mètode pot filtrar esdeveniments i, condicionat, evitar que s'executin els passos següents",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Gestiona les preferències de l'aplicació",
|
||||
"preferences_settings_title": "Preferències",
|
||||
@@ -1776,6 +1845,7 @@
|
||||
"profile_drawer_readonly_mode": "Mode només lectura. Feu pulsació llarga a la icona de l'avatar d'usuari per sortir.",
|
||||
"profile_image_of_user": "Imatge de perfil de {user}",
|
||||
"profile_picture_set": "Imatge de perfil configurada.",
|
||||
"projection_type": "Tipus de Projecció",
|
||||
"public_album": "Àlbum públic",
|
||||
"public_share": "Compartit públicament",
|
||||
"purchase_account_info": "Contribuent",
|
||||
@@ -1853,6 +1923,7 @@
|
||||
"remove_assets_title": "Eliminar els elements?",
|
||||
"remove_custom_date_range": "Elimina l'interval de dates personalitzat",
|
||||
"remove_deleted_assets": "Suprimeix fitxers fora de línia",
|
||||
"remove_filter": "Elimina el filtre",
|
||||
"remove_from_album": "Treu de l'àlbum",
|
||||
"remove_from_album_action_prompt": "{count} eliminats de l'àlbum",
|
||||
"remove_from_favorites": "Eliminar dels preferits",
|
||||
@@ -1926,6 +1997,8 @@
|
||||
"scan_settings": "Configuració d'escaneig",
|
||||
"scanning": "Escanejant",
|
||||
"scanning_for_album": "S'està buscant l'àlbum...",
|
||||
"screencast_mode_description": "Mostra els indicadors d'esdeveniments del teclat i del ratolí a la pantalla",
|
||||
"screencast_mode_title": "Activa/desactiva el mode de captura de pantalla",
|
||||
"search": "Cerca",
|
||||
"search_albums": "Buscar àlbums",
|
||||
"search_by_context": "Buscar per context",
|
||||
@@ -1933,6 +2006,8 @@
|
||||
"search_by_description_example": "Jornada de senderisme a Sapa",
|
||||
"search_by_filename": "Cerca per nom de fitxer o extensió",
|
||||
"search_by_filename_example": "per exemple IMG_1234.JPG o PNG",
|
||||
"search_by_full_path": "Cerca per camí complert o carpeta",
|
||||
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - pots buscar Projectes, 3D, Impressió, 2026 etc.",
|
||||
"search_by_ocr": "Buscar per OCR",
|
||||
"search_by_ocr_example": "Després",
|
||||
"search_camera_lens_model": "Buscar model de lents....",
|
||||
@@ -2140,7 +2215,9 @@
|
||||
"show_in_timeline": "Mostra a la cronologia",
|
||||
"show_in_timeline_setting_description": "Mostra fotos i vídeos d'aquest usuari a la cronologia",
|
||||
"show_keyboard_shortcuts": "Mostra dreceres de teclat",
|
||||
"show_less": "Mostra'n menys",
|
||||
"show_metadata": "Mostra metadades",
|
||||
"show_more_fields": "{count, plural, one {Veure # camp més} other {Veure # camps més}}",
|
||||
"show_or_hide_info": "Mostra o amaga informació",
|
||||
"show_password": "Mostra contrasenya",
|
||||
"show_person_options": "Mostra opcions de la persona",
|
||||
@@ -2148,6 +2225,7 @@
|
||||
"show_schema": "Mostrar esquema",
|
||||
"show_search_options": "Mostra opcions de cerca",
|
||||
"show_shared_links": "Mostra els enllaços compartits",
|
||||
"show_slideshow_metadata_overlay": "Mostra informació sobre la imatge",
|
||||
"show_slideshow_transition": "Mostra la transició de la presentació de diapositives",
|
||||
"show_supporter_badge": "Insígnia de contribuent",
|
||||
"show_supporter_badge_description": "Mostra una insígnia de contributor",
|
||||
@@ -2163,9 +2241,13 @@
|
||||
"skip_to_folders": "Anar a carpetes",
|
||||
"skip_to_tags": "Anar a etiquetes",
|
||||
"slideshow": "Diapositives",
|
||||
"slideshow_metadata_overlay_mode": "Contingut de superposició",
|
||||
"slideshow_metadata_overlay_mode_description_only": "Descripció només",
|
||||
"slideshow_metadata_overlay_mode_full": "Tot",
|
||||
"slideshow_repeat": "Repeteix la presentació de diapositives",
|
||||
"slideshow_repeat_description": "Torna al principi quan acaba la presentació de diapositives",
|
||||
"slideshow_settings": "Configuració de diapositives",
|
||||
"smart_album": "Àlbum inteŀligent",
|
||||
"sort_albums_by": "Ordena àlbums per...",
|
||||
"sort_created": "Data de creació",
|
||||
"sort_items": "Quantitat d'elements",
|
||||
@@ -2188,6 +2270,11 @@
|
||||
"start_date_before_end_date": "La data d'inici ha de ser abans de la data de fi",
|
||||
"state": "Regió",
|
||||
"status": "Estat",
|
||||
"step_delete": "Elimina el pas",
|
||||
"step_delete_confirm": "Esteu segur que voleu eliminar el pas?",
|
||||
"step_details": "Detalls del pas",
|
||||
"steps": "Passos",
|
||||
"steps_count": "{count, plural, one {# pas} other {# passos}}",
|
||||
"stop_casting": "Atura la transmisió",
|
||||
"stop_motion_photo": "Atura foto en moviment",
|
||||
"stop_photo_sharing": "Deixar de compartir les teves fotos?",
|
||||
@@ -2214,6 +2301,8 @@
|
||||
"sync_status": "Estat de la incronització",
|
||||
"sync_status_subtitle": "Observa i administra el sistema de sincronització",
|
||||
"sync_upload_album_setting_subtitle": "Creeu i pugeu les seves fotos i vídeos als àlbums seleccionats a Immich",
|
||||
"system_theme": "Tema del sistema",
|
||||
"system_theme_command_description": "Utilitza el tema del sistema ({value})",
|
||||
"tag": "Etiqueta",
|
||||
"tag_assets": "Etiquetar actius",
|
||||
"tag_created": "Etiqueta creada: {tag}",
|
||||
@@ -2279,7 +2368,7 @@
|
||||
"trash_page_title": "Paperera ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Els elements que s'enviïn a la paperera s'eliminaran permanentment després de {days, plural, one {# dia} other {# dies}}.",
|
||||
"trigger": "Disparador",
|
||||
"trigger_asset_uploaded": "Mitjà Carregat",
|
||||
"trigger_asset_uploaded": "Càrrega de Mitjans",
|
||||
"trigger_asset_uploaded_description": "Es dispara quan un nou mitjà es puge al servidor",
|
||||
"trigger_description": "L'esdeveniment que inicia l'automatització",
|
||||
"trigger_person_recognized": "Persona identificada",
|
||||
@@ -2319,13 +2408,13 @@
|
||||
"unsupported_field_type": "Tipus de camp no suportat",
|
||||
"unsupported_file_type": "No es pot carregar el fitxer {file} perquè el seu tipus de fitxer {type} no és compatible.",
|
||||
"untagged": "Sense etiqueta",
|
||||
"untitled_workflow": "Automatització sense títol",
|
||||
"up_next": "Pròxim",
|
||||
"update_location_action_prompt": "Actualitza la ubicació de {count} elements seleccionats amb:",
|
||||
"updated_at": "Actualitzat",
|
||||
"updated_password": "Contrasenya actualitzada",
|
||||
"upload": "Pujar",
|
||||
"upload_concurrency": "Concurrència de pujades",
|
||||
"upload_day_count": "{date}: {count, plural, one {# pujada} other {# pujades}}",
|
||||
"upload_details": "Detalls de la Pujada",
|
||||
"upload_dialog_info": "Vols fer còpia de seguretat dels elements seleccionats al servidor?",
|
||||
"upload_dialog_title": "Puja elements",
|
||||
@@ -2341,6 +2430,8 @@
|
||||
"upload_to_immich": "Puja a Immich ({count})",
|
||||
"uploading": "Pujant",
|
||||
"uploading_media": "Pujant mitjans",
|
||||
"uploads": "Pujades",
|
||||
"uploads_count": "{count, plural, one {# pujada} other {# pujades}}",
|
||||
"url": "URL",
|
||||
"usage": "Ús",
|
||||
"use_biometric": "Empra biometria",
|
||||
@@ -2348,6 +2439,7 @@
|
||||
"use_browser_locale_description": "Formatejar dates, hores i números segons la llengua i regió del navegador",
|
||||
"use_current_connection": "Utilitza la connexió actual",
|
||||
"use_custom_date_range": "Fes servir un rang de dates personalitzat",
|
||||
"use_template": "Utilitza la plantilla",
|
||||
"user": "Usuari",
|
||||
"user_has_been_deleted": "Aquest usuari ha sigut eliminat.",
|
||||
"user_id": "ID d'usuari",
|
||||
@@ -2377,6 +2469,7 @@
|
||||
"video": "Vídeo",
|
||||
"video_hover_setting": "Reprodueix la miniatura en passar el ratolí",
|
||||
"video_hover_setting_description": "Reprodueix la miniatura quan el ratolí plana sobre l'element. Fins i tot quan estigui deshabilitat, la reproducció s'iniciarà planant sobre el botó de reproducció.",
|
||||
"video_quality": "Qualitat del vídeo",
|
||||
"videos": "Vídeos",
|
||||
"videos_count": "{count, plural, one {# vídeo} other {# vídeos}}",
|
||||
"videos_only": "Només videos",
|
||||
@@ -2409,8 +2502,10 @@
|
||||
"week": "Setmana",
|
||||
"welcome": "Benvingut",
|
||||
"welcome_to_immich": "Benvingut a immich",
|
||||
"when": "Quan",
|
||||
"width": "Amplada",
|
||||
"wifi_name": "Nom Wi-Fi",
|
||||
"workflow": "Flux de treball",
|
||||
"workflow_delete_prompt": "Segur que vols eliminar aquesta automatització?",
|
||||
"workflow_deleted": "Automatització eliminada",
|
||||
"workflow_description": "Descripció de l'automatització",
|
||||
@@ -2420,11 +2515,13 @@
|
||||
"workflow_name": "Nom de l'automatització",
|
||||
"workflow_navigation_prompt": "Segur que vols sortir sense desar els canvis?",
|
||||
"workflow_summary": "Resum de l'automatització",
|
||||
"workflow_templates": "Plantilles de fluxos de treball",
|
||||
"workflow_update_success": "Automatització actualitzada amb èxit",
|
||||
"workflow_updated": "Automatització actualitzada",
|
||||
"workflows": "Automatitzacions",
|
||||
"workflows_help_text": "Les automatitzacions realitzen accions automàticament sobre els teus mitjans basant-se en disparadors i filtres",
|
||||
"wrong_pin_code": "Codi PIN incorrecte",
|
||||
"x_of_total": "{x}/{total}",
|
||||
"year": "Any",
|
||||
"years_ago": "Fa {years, plural, one {# any} other {# anys}}",
|
||||
"yes": "Sí",
|
||||
|
||||
+133
-13
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "Přidat datum narození",
|
||||
"add_endpoint": "Přidat koncový bod",
|
||||
"add_exclusion_pattern": "Přidat vzor vyloučení",
|
||||
"add_filter": "Přidat filtr",
|
||||
"add_filter_description": "Kliknutím přidejte podmínku filtru",
|
||||
"add_location": "Přidat polohu",
|
||||
"add_more_users": "Přidat další uživatele",
|
||||
"add_partner": "Přidat partnera",
|
||||
"add_path": "Přidat cestu",
|
||||
"add_photos": "Přidat fotky",
|
||||
"add_step": "Přidat krok",
|
||||
"add_tag": "Přidat značku",
|
||||
"add_to": "Přidat do…",
|
||||
"add_to_album": "Přidat do alba",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "Přidat do sdíleného alba",
|
||||
"add_upload_to_stack": "Přidat nahrané do seskupení",
|
||||
"add_url": "Přidat URL",
|
||||
"add_workflow_step": "Přidat krok pracovního postupu",
|
||||
"added_to_archive": "Přidáno do archivu",
|
||||
"added_to_favorites": "Přidáno do oblíbených",
|
||||
"added_to_favorites_count": "Přidáno {count, number} do oblíbených",
|
||||
@@ -81,6 +79,7 @@
|
||||
"cron_expression_description": "Nastavte interval prohledávání pomocí cron formátu. Další informace naleznete např. v <link>Crontab Guru</link>",
|
||||
"cron_expression_presets": "Předvolby výrazů cron",
|
||||
"disable_login": "Zakázat přihlášení",
|
||||
"download_csv": "Stáhnout CSV",
|
||||
"duplicate_detection_job_description": "Spuštění strojového učení na položkách za účelem detekce podobných obrázků. Spoléhá na Chytré vyhledávání",
|
||||
"exclusion_pattern_description": "Vzory vyloučení umožňují při prohledávání knihovny ignorovat soubory a složky. To je užitečné, pokud máte složky obsahující soubory, které nechcete importovat, například RAW soubory.",
|
||||
"export_config_as_json_description": "Stáhněte si aktuální konfiguraci systému jako JSON soubor",
|
||||
@@ -193,6 +192,17 @@
|
||||
"maintenance_delete_backup": "Smazat zálohu",
|
||||
"maintenance_delete_backup_description": "Tento soubor bude trvale smazán.",
|
||||
"maintenance_delete_error": "Nepodařilo se smazat zálohu.",
|
||||
"maintenance_integrity_check_all": "Zkontrolovat vše",
|
||||
"maintenance_integrity_checksum_mismatch": "Neshoda kontrolního součtu",
|
||||
"maintenance_integrity_checksum_mismatch_job": "Kontrola shod kontrolních součtů",
|
||||
"maintenance_integrity_checksum_mismatch_refresh_job": "Obnovit hlášení o neshodách kontrolních součtů",
|
||||
"maintenance_integrity_missing_file": "Chybějící soubory",
|
||||
"maintenance_integrity_missing_file_job": "Kontrola chybějících souborů",
|
||||
"maintenance_integrity_missing_file_refresh_job": "Obnovit hlášení o chybějících souborech",
|
||||
"maintenance_integrity_report": "Hlášení o integritě",
|
||||
"maintenance_integrity_untracked_file": "Nesledované soubory",
|
||||
"maintenance_integrity_untracked_file_job": "Kontrola nesledovaných souborů",
|
||||
"maintenance_integrity_untracked_file_refresh_job": "Obnovit hlášení o nesledovaných souborech",
|
||||
"maintenance_restore_backup": "Obnovit zálohu",
|
||||
"maintenance_restore_backup_description": "Immich bude vymazán a obnoven z vybrané zálohy. Před pokračováním bude vytvořena záloha.",
|
||||
"maintenance_restore_backup_different_version": "Tato záloha byla vytvořena pomocí jiné verze aplikace Immich!",
|
||||
@@ -232,7 +242,7 @@
|
||||
"migration_job": "Migrace",
|
||||
"migration_job_description": "Migrace miniatur snímků a obličejů do nejnovější struktury složek",
|
||||
"nightly_tasks_cluster_faces_setting_description": "Spustit rozpoznávání obličeje na nově nalezených obličejích",
|
||||
"nightly_tasks_cluster_new_faces_setting": "Seskupit nové tváře",
|
||||
"nightly_tasks_cluster_new_faces_setting": "Seskupit nové obličeje",
|
||||
"nightly_tasks_database_cleanup_setting": "Úlohy čištění databáze",
|
||||
"nightly_tasks_database_cleanup_setting_description": "Vyčistit databázi od starých dat, jejichž platnost vypršela",
|
||||
"nightly_tasks_generate_memories_setting": "Vytváření vzpomínek",
|
||||
@@ -267,6 +277,8 @@
|
||||
"notification_enable_email_notifications": "Povolení e-mailových oznámení",
|
||||
"notification_settings": "Oznámení",
|
||||
"notification_settings_description": "Správa nastavení oznámení včetně e-mailu",
|
||||
"oauth_allow_insecure_requests": "Povolit nezabezpečené požadavky",
|
||||
"oauth_allow_insecure_requests_description": "VAROVÁNÍ: Toto zakáže ověřování TLS certifikátů u požadavků OAuth, což vás může vystavit riziku útoků typu MITM.",
|
||||
"oauth_auto_launch": "Automatické zahájení",
|
||||
"oauth_auto_launch_description": "Automatické zahájení přihlašovacího toku OAuth po přechodu na přihlašovací stránku",
|
||||
"oauth_auto_register": "Automatická registrace",
|
||||
@@ -274,9 +286,11 @@
|
||||
"oauth_button_text": "Text tlačítka",
|
||||
"oauth_client_secret_description": "Vyžadováno pro důvěrné klienty nebo pokud PKCE (Proof Key for Code Exchange) není podporováno pro veřejné klienty.",
|
||||
"oauth_enable_description": "Přihlásit pomocí OAuth",
|
||||
"oauth_end_session_url_description": "Přesměrovat uživatele po odhlášení na tuto adresu.",
|
||||
"oauth_mobile_redirect_uri": "Mobilní přesměrování URI",
|
||||
"oauth_mobile_redirect_uri_override": "Přepsat mobilní přesměrování URI",
|
||||
"oauth_mobile_redirect_uri_override_description": "Povolit, pokud poskytovatel OAuth nepovoluje mobilní URI, například ''{callback}''",
|
||||
"oauth_prompt_description": "Parametr dotazu (např. select_account, login, consent)",
|
||||
"oauth_role_claim": "Deklarace Role",
|
||||
"oauth_role_claim_description": "Automaticky udělit přístup správce na základě přítomnosti této deklarace. Deklarace může mít hodnotu 'user' nebo 'admin'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +317,8 @@
|
||||
"refreshing_all_libraries": "Obnovení všech knihoven",
|
||||
"registration": "Registrace správce",
|
||||
"registration_description": "Vzhledem k tomu, že jste prvním uživatelem v systému, budete přiřazen jako správce a budete zodpovědný za úkoly správy a další uživatelé budou vytvořeni vámi.",
|
||||
"release_channel_release_candidate": "Kandidát na vydání",
|
||||
"release_channel_stable": "Stabilní",
|
||||
"remove_failed_jobs": "Odebrat neúspěšné úlohy",
|
||||
"require_password_change_on_login": "Požadovat, aby si uživatel při prvním přihlášení změnil heslo",
|
||||
"reset_settings_to_default": "Obnovení výchozího nastavení",
|
||||
@@ -397,6 +413,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "Platí pouze pro VAAPI a QSV. Nastaví dri uzel použitý pro hardwarové překódování.",
|
||||
"transcoding_preset_preset": "Předvolba (-preset)",
|
||||
"transcoding_preset_preset_description": "Rychlost komprese. Pomalejší předvolby vytvářejí menší soubory a zvyšují kvalitu při dosažení určitého datového toku. VP9 ignoruje rychlosti vyšší než 'faster'.",
|
||||
"transcoding_realtime": "Překódování v reálném čase [EXPERIMENTÁLNÍ]",
|
||||
"transcoding_realtime_description": "Umožňuje provádět překódování v reálném čase během přenosu videa. Zpřístupní přepínání kvality, ale v závislosti na výkonu serveru může docházet k delším zpožděním při přehrávání a k trhanému přehrávání.",
|
||||
"transcoding_realtime_enabled": "Povolit překódování v reálném čase",
|
||||
"transcoding_realtime_enabled_description": "Pokud je zakázáno, server odmítne spustit nové relace překódování v reálném čase.",
|
||||
"transcoding_reference_frames": "Referenční snímky",
|
||||
"transcoding_reference_frames_description": "Počet referenčních snímků při kompresi daného snímku. Vyšší hodnoty zvyšují účinnost komprese, ale zpomalují kódování. Hodnota 0 toto nastavuje automaticky.",
|
||||
"transcoding_required_description": "Pouze videa, která nejsou v akceptovaném formátu",
|
||||
@@ -440,6 +460,8 @@
|
||||
"user_settings_description": "Správa nastavení uživatelů",
|
||||
"user_successfully_removed": "Uživatel {email} byl úspěšně odstraněn.",
|
||||
"users_page_description": "Stránka správců",
|
||||
"version_check_channel": "Kanál vydání",
|
||||
"version_check_channel_description": "Vyberte si kanál vydání, pro který chcete dostávat oznámení o nových verzích",
|
||||
"version_check_enabled_description": "Povolit kontrolu verzí",
|
||||
"version_check_implications": "Kontrola verze je založena na pravidelné komunikaci s {server}",
|
||||
"version_check_settings": "Kontrola verze",
|
||||
@@ -560,6 +582,7 @@
|
||||
"asset_added_to_album": "Přidáno do alba",
|
||||
"asset_adding_to_album": "Přidávání do alba…",
|
||||
"asset_created": "Položka vytvořena",
|
||||
"asset_day_count": "{date}: {count, plural, one {# položka} few {# položky} other {# položek}}",
|
||||
"asset_description_updated": "Popis položky byl aktualizován",
|
||||
"asset_filename_is_offline": "Položka {filename} je offline",
|
||||
"asset_has_unassigned_faces": "Položka má nepřiřazené obličeje",
|
||||
@@ -689,6 +712,7 @@
|
||||
"backup_settings_subtitle": "Správa nastavení nahrávání",
|
||||
"backup_upload_details_page_more_details": "Klepněte pro více informací",
|
||||
"backward": "Pozpátku",
|
||||
"battery_optimization_backup_reliability": "Zakázání optimalizací baterie může zlepšit spolehlivost zálohování na pozadí",
|
||||
"biometric_auth_enabled": "Biometrické ověřování je povoleno",
|
||||
"biometric_locked_out": "Jste vyloučeni z biometrického ověřování",
|
||||
"biometric_no_options": "Biometrické možnosti nejsou k dispozici",
|
||||
@@ -696,6 +720,7 @@
|
||||
"birthdate_saved": "Datum narození úspěšně uloženo",
|
||||
"birthdate_set_description": "Datum narození se používá k výpočtu věku osoby v době pořízení fotografie.",
|
||||
"blurred_background": "Rozmazané pozadí",
|
||||
"browse_templates": "Procházet šablony",
|
||||
"bugs_and_feature_requests": "Chyby a návrhy na funkce",
|
||||
"build": "Sestavení",
|
||||
"build_image": "Sestavení obrazu",
|
||||
@@ -729,6 +754,7 @@
|
||||
"cannot_update_the_description": "Nelze aktualizovat popis",
|
||||
"cast": "Odeslat do zařízení",
|
||||
"cast_description": "Nastavení dostupných cílů přenosu",
|
||||
"change": "Změnit",
|
||||
"change_date": "Změnit datum",
|
||||
"change_description": "Změnit popis",
|
||||
"change_display_order": "Změnit pořadí zobrazení",
|
||||
@@ -757,6 +783,7 @@
|
||||
"check_corrupt_asset_backup_description": "Tuto kontrolu provádějte pouze přes Wi-Fi a po zálohování všech prostředků. Takto operace může trvat několik minut.",
|
||||
"check_logs": "Zkontrolujte protokoly",
|
||||
"checksum": "Kontrolní součet",
|
||||
"choose": "Vybrat",
|
||||
"choose_matching_people_to_merge": "Zvolte odpovídající osoby ke sloučení",
|
||||
"city": "Město",
|
||||
"cleanup_confirm_description": "Immich našel {count} položek (vytvořených před {date}), které jsou bezpečně zálohovány na serveru. Chcete odstranit místní kopie z tohoto zařízení?",
|
||||
@@ -774,6 +801,7 @@
|
||||
"clear": "Vymazat",
|
||||
"clear_all": "Vymazat vše",
|
||||
"clear_all_recent_searches": "Vymazat všechna nedávná vyhledávání",
|
||||
"clear_failed_count": "Vymazání selhalo ({count})",
|
||||
"clear_file_cache": "Vymazat mezipaměť souborů",
|
||||
"clear_message": "Vymazat zprávu",
|
||||
"clear_value": "Vymazat hodnotu",
|
||||
@@ -805,6 +833,7 @@
|
||||
"comments_are_disabled": "Komentáře jsou vypnuty",
|
||||
"common_create_new_album": "Vytvořit nové album",
|
||||
"completed": "Dokončeno",
|
||||
"configuration": "Nastavení",
|
||||
"confirm": "Potvrdit",
|
||||
"confirm_admin_password": "Potvrzení hesla správce",
|
||||
"confirm_delete_face": "Opravdu chcete z položky odstranit obličej osoby {name}?",
|
||||
@@ -819,6 +848,7 @@
|
||||
"contain": "Obsah",
|
||||
"context": "Kontext",
|
||||
"continue": "Pokračovat",
|
||||
"control_bottom_app_bar_add_tags": "Přidat značky",
|
||||
"control_bottom_app_bar_create_new_album": "Vytvořit nové album",
|
||||
"control_bottom_app_bar_delete_from_immich": "Smazat ze serveru Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Smazat ze zařízení",
|
||||
@@ -832,6 +862,7 @@
|
||||
"copy_error": "Chyba kopírování",
|
||||
"copy_file_path": "Kopírovat cestu k souboru",
|
||||
"copy_image": "Kopírovat obrázek",
|
||||
"copy_json": "Kopírovat JSON",
|
||||
"copy_link": "Kopírovat odkaz",
|
||||
"copy_link_to_clipboard": "Kopírovat odkaz do schránky",
|
||||
"copy_password": "Kopírovat heslo",
|
||||
@@ -881,22 +912,23 @@
|
||||
"cutoff_date_description": "Zanechat fotografie a videa z posledních…",
|
||||
"cutoff_day": "{count, plural, one {den} few {dny} other {dnů}}",
|
||||
"cutoff_year": "{count, plural, one {rok} few {roky} other {let}}",
|
||||
"daily_title_text_date": "EEEE, d. MMMM",
|
||||
"daily_title_text_date_year": "EEEE, d. MMMM y",
|
||||
"dark": "Tmavý",
|
||||
"dark_theme": "Přepnout na tmavý motiv",
|
||||
"date": "Datum",
|
||||
"date_after": "Datum po",
|
||||
"date_and_time": "Datum a čas",
|
||||
"date_before": "Datum před",
|
||||
"date_format": "EEEE, d. MMMM y • H:mm",
|
||||
"date_of_birth": "Datum narození",
|
||||
"date_of_birth_saved": "Datum narození úspěšně uloženo",
|
||||
"date_range": "Rozsah dat",
|
||||
"date_time_original": "Původní datum/čas",
|
||||
"day": "Den",
|
||||
"days": "Dnů",
|
||||
"deduplicate_all": "Odstranit všechny duplicity",
|
||||
"default_locale": "Výchozí národní prostředí",
|
||||
"default_locale_description": "Formátování datumu a čísel podle místního nastavení prohlížeče",
|
||||
"default_quality_subtitle": "Kvalita použitá při sdílení. Pro výběr pokaždé dlouze stiskněte tlačítko sdílení.",
|
||||
"default_share_quality": "Výchozí kvalita sdílení",
|
||||
"delete": "Smazat",
|
||||
"delete_action_confirmation_message": "Opravdu chcete odstranit tuto položku? Tato akce přesune položku do serverového koše a zeptá se vás, zda ji chcete odstranit lokálně",
|
||||
"delete_action_prompt": "{count} smazáno",
|
||||
@@ -970,7 +1002,10 @@
|
||||
"downloading_asset_filename": "Stahování položky {filename}",
|
||||
"downloading_from_icloud": "Stahování z iCloudu",
|
||||
"downloading_media": "Stahování média",
|
||||
"drag_to_reorder": "Posuňte pro změnu pořadí",
|
||||
"drop_files_to_upload": "Pro nahrání sem přetáhněte soubory",
|
||||
"duplicate": "Duplikovat",
|
||||
"duplicate_workflow": "Duplikovat pracovní postup",
|
||||
"duplicates": "Duplicity",
|
||||
"duplicates_description": "Vyřešte každou skupinu tak, že uvedete, které skupiny jsou duplicitní.",
|
||||
"duration": "Doba trvání",
|
||||
@@ -1072,6 +1107,7 @@
|
||||
"failed_to_remove_product_key": "Nepodařilo se odebrat klíč produktu",
|
||||
"failed_to_reset_pin_code": "Nepodařilo se resetovat PIN kód",
|
||||
"failed_to_stack_assets": "Nepodařilo se seskupit položky",
|
||||
"failed_to_tag_assets": "Nepodařilo se přidat značky k položkám",
|
||||
"failed_to_unstack_assets": "Nepodařilo se zrušit seskupení položek",
|
||||
"failed_to_update_notification_status": "Nepodařilo se aktualizovat stav oznámení",
|
||||
"incorrect_email_or_password": "Nesprávný e-mail nebo heslo",
|
||||
@@ -1191,15 +1227,18 @@
|
||||
"export_as_json": "Exportovat jako JSON",
|
||||
"export_database": "Exportovat databázi",
|
||||
"export_database_description": "Exportovat databázi SQLite",
|
||||
"exposure_time": "Expoziční čas",
|
||||
"extension": "Přípona",
|
||||
"external": "Externí",
|
||||
"external_libraries": "Externí knihovny",
|
||||
"external_network": "Externí síť",
|
||||
"external_network_sheet_info": "Pokud nejste v preferované síti Wi-Fi, aplikace se připojí k serveru prostřednictvím první z níže uvedených adres URL, které může dosáhnout, počínaje shora dolů",
|
||||
"f_number": "Clonové číslo",
|
||||
"face_unassigned": "Nepřiřazena",
|
||||
"failed": "Selhalo",
|
||||
"failed_count": "Selhalo: {count}",
|
||||
"failed_to_authenticate": "Ověření se nezdařilo",
|
||||
"failed_to_delete_file": "Odstranění souboru se nezdařilo",
|
||||
"failed_to_load_assets": "Nepodařilo se načíst položky",
|
||||
"failed_to_load_folder": "Nepodařilo se načíst složku",
|
||||
"favorite": "Oblíbit",
|
||||
@@ -1213,7 +1252,6 @@
|
||||
"features_setting_description": "Správa funkcí aplikace",
|
||||
"file_name_or_extension": "Název nebo přípona souboru",
|
||||
"file_name_text": "Název souboru",
|
||||
"file_name_with_value": "Název souboru: {file_name}",
|
||||
"file_size": "Velikost souboru",
|
||||
"filename": "Název souboru",
|
||||
"filetype": "Typ souboru",
|
||||
@@ -1226,6 +1264,7 @@
|
||||
"find_them_fast": "Najděte je rychle vyhledáním jejich jména",
|
||||
"first": "První",
|
||||
"fix_incorrect_match": "Opravit nesprávnou shodu",
|
||||
"focal_length": "Ohnisková vzdálenost",
|
||||
"folder": "Složka",
|
||||
"folder_not_found": "Složka nebyla nalezena",
|
||||
"folders": "Složky",
|
||||
@@ -1236,6 +1275,7 @@
|
||||
"free_up_space_description": "Přesunout zálohované fotografie a videa do koše zařízení, abyste uvolnili místo. Vaše kopie na serveru zůstanou v bezpečí.",
|
||||
"free_up_space_settings_subtitle": "Uvolnit úložiště zařízení",
|
||||
"full_path": "Úplná cesta: {path}",
|
||||
"full_path_or_folder": "Celá cesta nebo složka",
|
||||
"gcast_enabled": "Google Cast",
|
||||
"gcast_enabled_description": "Tato funkce načítá externí zdroje z Googlu, aby mohla fungovat.",
|
||||
"general": "Obecné",
|
||||
@@ -1329,6 +1369,7 @@
|
||||
"individual_share": "Sdílení jednotlivých položek",
|
||||
"individual_shares": "Sdílení jednotlivých položek",
|
||||
"info": "Informace",
|
||||
"integrity_checks": "Kontroly integrity",
|
||||
"interval": {
|
||||
"day_at_onepm": "Každý den ve 13:00",
|
||||
"hours": "{hours, plural, one {Každou hodinu} few {Každé {hours, number} hodiny} other {Každých {hours, number} hodin}}",
|
||||
@@ -1345,6 +1386,7 @@
|
||||
"ios_debug_info_no_sync_yet": "Dosud nebyla spuštěna žádná úloha synchronizace na pozadí",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {{count} proces na pozadí ve frontě} few {{count} procesy na pozadí ve frontě} other {{count} procesů na pozadí ve frontě}}",
|
||||
"ios_debug_info_processing_ran_at": "Zpracování spuštěno {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# položka} few {# položky} other {# položek}}",
|
||||
"jobs": "Úlohy",
|
||||
"json_editor": "JSON editor",
|
||||
@@ -1375,6 +1417,7 @@
|
||||
"leave": "Opustit",
|
||||
"leave_album": "Opustit album",
|
||||
"lens_model": "Model objektivu",
|
||||
"less": "Méně",
|
||||
"let_others_respond": "Nechte ostatní reagovat",
|
||||
"level": "Úroveň",
|
||||
"library": "Knihovna",
|
||||
@@ -1392,11 +1435,14 @@
|
||||
"light_theme": "Přepnout na světlý motiv",
|
||||
"like": "Líbí se mi",
|
||||
"like_deleted": "Oblíbení smazáno",
|
||||
"link": "Odkaz",
|
||||
"link_motion_video": "Připojit pohyblivé video",
|
||||
"link_to_docs": "Další informace najdete v <link>dokumentaci</link>.",
|
||||
"link_to_oauth": "Propojit s OAuth",
|
||||
"linked_oauth_account": "Propojený OAuth účet",
|
||||
"list": "Seznam",
|
||||
"live": "Živý",
|
||||
"load_more": "Načíst další",
|
||||
"loading": "Načítání",
|
||||
"loading_search_results_failed": "Načítání výsledků vyhledávání se nezdařilo",
|
||||
"local": "Místní",
|
||||
@@ -1518,6 +1564,38 @@
|
||||
"marked_all_as_read": "Vše označeno jako přečtené",
|
||||
"matches": "Shody",
|
||||
"matching_assets": "Odpovídající položky",
|
||||
"media_chrome": {
|
||||
"auto": "Automaticky",
|
||||
"captions": "Titulky",
|
||||
"captions_off": "Vypnuto",
|
||||
"closed_captions": "skryté titulky",
|
||||
"decode_error": "Chyba dekódování",
|
||||
"disable_captions": "Vypnout titulky",
|
||||
"enable_captions": "Zapnout titulky",
|
||||
"enter_fullscreen_mode": "Přepnout do režimu celé obrazovky",
|
||||
"exit_fullscreen_mode": "Ukončit režim celé obrazovky",
|
||||
"loop": "Smyčka",
|
||||
"media_error_description": "K přerušení přehrávání došlo kvůli chybě souboru. Soubor může být poškozený, případně váš prohlížeč tento formát nepodporuje.",
|
||||
"media_loading": "načítání médií",
|
||||
"mute": "Ztlumit",
|
||||
"network_error": "Chyba sítě",
|
||||
"network_error_description": "K selhání stahování médií došlo kvůli síťové chybě.",
|
||||
"not_supported_error": "Zdroj není podporován",
|
||||
"playback_rate": "Rychlost přehrávání",
|
||||
"playback_rate_current": "aktuální rychlost přehrávání",
|
||||
"playback_rate_value": "Rychlost přehrávání {playbackRate}",
|
||||
"playback_time": "doba přehrávání",
|
||||
"quality": "Kvalita",
|
||||
"second": "sekunda",
|
||||
"seconds": "sekund",
|
||||
"time_value_of_total_time": "{currentTime} z {totalTime}",
|
||||
"time_value_remaining": "zbývá {time}",
|
||||
"unmute": "Zrušit ztlumení",
|
||||
"unsupported_error_description": "Došlo k chybě způsobené nepodporovaným formátem. Došlo k selhání serveru nebo sítě, případně váš prohlížeč tento formát nepodporuje.",
|
||||
"video_not_loaded_unknown_time": "video se nenačetlo, známý čas.",
|
||||
"video_player": "videopřehrávač",
|
||||
"volume": "hlasitost"
|
||||
},
|
||||
"media_type": "Typ média",
|
||||
"memories": "Vzpomínky",
|
||||
"memories_all_caught_up": "To je všechno",
|
||||
@@ -1534,6 +1612,8 @@
|
||||
"merge_people_prompt": "Chcete tyto lidi sloučit? Tato akce je nevratná.",
|
||||
"merge_people_successfully": "Sloučení osob proběhlo úspěšně",
|
||||
"merged_people_count": "{count, plural, one {Sloučena # osoba} few {Sloučeny # osoby} other {Sloučeno # lidí}}",
|
||||
"minFaces": "Minimální počet obličejů",
|
||||
"minFaces_description": "Minimální počet rozpoznaných obličejů, aby byla daná osoba zobrazena",
|
||||
"minimize": "Minimalizovat",
|
||||
"minute": "Minuta",
|
||||
"minutes": "Minut",
|
||||
@@ -1543,9 +1623,10 @@
|
||||
"mobile_app": "Mobilní aplikace",
|
||||
"mobile_app_download_onboarding_note": "Stáhněte si doprovodnou mobilní aplikaci pomocí následujících možností",
|
||||
"model": "Model",
|
||||
"modify_date": "Datum úpravy",
|
||||
"month": "Měsíc",
|
||||
"monthly_title_text_date_format": "LLLL y",
|
||||
"more": "Více",
|
||||
"motion": "Pohyb",
|
||||
"move": "Přesunout",
|
||||
"move_down": "Přesunout dolů",
|
||||
"move_off_locked_folder": "Přesunout z uzamčené složky",
|
||||
@@ -1562,6 +1643,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "Nelze upravit polohu položek pouze pro čtení, přeskakuji",
|
||||
"mute_memories": "Ztlumit vzpomínky",
|
||||
"my_albums": "Moje alba",
|
||||
"my_immich_description": "Zkopírovat aktuální stránku jako odkaz na Můj Immich",
|
||||
"my_immich_title": "Odkaz na Můj Immich",
|
||||
"name": "Jméno",
|
||||
"name_or_nickname": "Jméno nebo přezdívka",
|
||||
"name_required": "Jméno je povinné",
|
||||
@@ -1589,7 +1672,6 @@
|
||||
"next": "Další",
|
||||
"next_memory": "Další vzpomínka",
|
||||
"no": "Ne",
|
||||
"no_actions_added": "Zatím nebyly přidány žádné akce",
|
||||
"no_albums_found": "Žádná alba nenalezena",
|
||||
"no_albums_message": "Vytvořte si album pro uspořádání fotografií a videí",
|
||||
"no_albums_with_name_yet": "Vypadá to, že zatím nemáte žádná alba s tímto názvem.",
|
||||
@@ -1606,7 +1688,6 @@
|
||||
"no_exif_info_available": "Exif není k dispozici",
|
||||
"no_explore_results_message": "Nahrajte další fotografie a prozkoumejte svou sbírku.",
|
||||
"no_favorites_message": "Přidejte si oblíbené položky a rychle najděte své nejlepší obrázky a videa",
|
||||
"no_filters_added": "Zatím nebyly přidány žádné filtry",
|
||||
"no_libraries_message": "Vytvořte si externí knihovnu pro zobrazení fotografií a videí",
|
||||
"no_local_assets_found": "Nebyly nalezeny žádné místní položky s tímto kontrolním součtem",
|
||||
"no_location_set": "Není nastavena poloha",
|
||||
@@ -1619,6 +1700,7 @@
|
||||
"no_results": "Žádné výsledky",
|
||||
"no_results_description": "Zkuste použít synonymum nebo obecnější klíčové slovo",
|
||||
"no_shared_albums_message": "Vytvořte si album a sdílejte fotografie a videa s lidmi ve své síti",
|
||||
"no_steps": "Zatím nebyly přidány žádné kroky",
|
||||
"no_uploads_in_progress": "Neprobíhá žádné nahrávání",
|
||||
"none": "Žádné",
|
||||
"not_allowed": "Nepovoleno",
|
||||
@@ -1627,6 +1709,7 @@
|
||||
"not_selected": "Není vybráno",
|
||||
"notes": "Poznámky",
|
||||
"nothing_here_yet": "Zatím zde nic není",
|
||||
"notification_backup_reliability": "Povolte oznámení pro zlepšení spolehlivosti zálohování na pozadí",
|
||||
"notification_permission_dialog_content": "Chcete-li povolit oznámení, přejděte do nastavení a vyberte možnost povolit.",
|
||||
"notification_permission_list_tile_content": "Udělte oprávnění k aktivaci oznámení.",
|
||||
"notification_permission_list_tile_enable_button": "Povolit oznámení",
|
||||
@@ -1664,6 +1747,7 @@
|
||||
"organize_into_albums": "Organizovat do alb",
|
||||
"organize_into_albums_description": "Umístit existující fotky do alb s použitím aktuálního nastavení synchronizace",
|
||||
"organize_your_library": "Uspořádejte si knihovnu",
|
||||
"orientation": "Orientace",
|
||||
"original": "originál",
|
||||
"other": "Ostatní",
|
||||
"other_devices": "Ostatní zařízení",
|
||||
@@ -1755,6 +1839,8 @@
|
||||
"play_original_video_setting_description": "Upřednostňujte přehrávání originálních videí před překódovanými videi. Pokud originální soubor není kompatibilní, nemusí se přehrávat správně.",
|
||||
"play_transcoded_video": "Přehrát překódované video",
|
||||
"please_auth_to_access": "Pro přístup se prosím ověřte",
|
||||
"plugin_method_filter_type": "Filtr",
|
||||
"plugin_method_filter_type_description": "Tato metoda umožňuje filtrovat události a podmíněně zabránit spuštění dalších kroků",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Správa předvoleb aplikace",
|
||||
"preferences_settings_title": "Předvolby",
|
||||
@@ -1776,6 +1862,7 @@
|
||||
"profile_drawer_readonly_mode": "Režim jen pro čtení. Ukončíte ho dlouhým podržením ikony avataru.",
|
||||
"profile_image_of_user": "Profilový obrázek uživatele {user}",
|
||||
"profile_picture_set": "Profilový obrázek nastaven.",
|
||||
"projection_type": "Typ projekce",
|
||||
"public_album": "Veřejné album",
|
||||
"public_share": "Veřejné sdílení",
|
||||
"purchase_account_info": "Podporovatel",
|
||||
@@ -1853,6 +1940,7 @@
|
||||
"remove_assets_title": "Odstranit položky?",
|
||||
"remove_custom_date_range": "Odstranit vlastní rozsah dat",
|
||||
"remove_deleted_assets": "Odstranit offline soubory",
|
||||
"remove_filter": "Odstranit filtr",
|
||||
"remove_from_album": "Odstranit z alba",
|
||||
"remove_from_album_action_prompt": "{count} odstraněných z alba",
|
||||
"remove_from_favorites": "Odstranit z oblíbených",
|
||||
@@ -1926,6 +2014,8 @@
|
||||
"scan_settings": "Nastavení prohledávání",
|
||||
"scanning": "Prohládává se",
|
||||
"scanning_for_album": "Prohledávání alba...",
|
||||
"screencast_mode_description": "Zobrazit na obrazovce indikátory událostí klávesnice a myši",
|
||||
"screencast_mode_title": "Přepnout režim screencastu",
|
||||
"search": "Hledat",
|
||||
"search_albums": "Vyhledávejte alba",
|
||||
"search_by_context": "Vyhledávání podle obsahu",
|
||||
@@ -1933,6 +2023,8 @@
|
||||
"search_by_description_example": "Pěší turistika v Sapě",
|
||||
"search_by_filename": "Vyhledávání podle názvu nebo přípony souboru",
|
||||
"search_by_filename_example": "např. IMG_1234.JPG nebo PNG",
|
||||
"search_by_full_path": "Hledat podle celé cesty nebo složky",
|
||||
"search_by_full_path_example": "/Jan/Projekty/3D_tisk/2026-07-01 – můžete hledat Projekty, 3D, tisk, 2026 apod.",
|
||||
"search_by_ocr": "Hledat pomocí OCR",
|
||||
"search_by_ocr_example": "Latte",
|
||||
"search_camera_lens_model": "Vyhledat model objektivu...",
|
||||
@@ -2009,6 +2101,7 @@
|
||||
"select_person": "Vybrat osobu",
|
||||
"select_person_to_tag": "Vyberte osobu, kterou chcete označit",
|
||||
"select_photos": "Vybrat fotky",
|
||||
"select_quality": "Vybrat kvalitu",
|
||||
"select_trash_all": "Vybrat vyhodit vše",
|
||||
"select_user_for_sharing_page_err_album": "Nepodařilo se vytvořit album",
|
||||
"selected": "Vybráno",
|
||||
@@ -2072,6 +2165,8 @@
|
||||
"share_assets_selected": "{count} vybráno",
|
||||
"share_dialog_preparing": "Připravuji...",
|
||||
"share_link": "Sdílet odkaz",
|
||||
"share_original": "Použít originál (velký)",
|
||||
"share_preview": "Použít miniaturu (malý)",
|
||||
"shared": "Sdílené",
|
||||
"shared_album_activities_input_disable": "Komentář je vypnutý",
|
||||
"shared_album_activity_remove_content": "Chcete odstranit tuto aktivitu?",
|
||||
@@ -2140,7 +2235,9 @@
|
||||
"show_in_timeline": "Zobrazit na časové ose",
|
||||
"show_in_timeline_setting_description": "Zobrazit fotky a videa tohoto uživatele na časové ose",
|
||||
"show_keyboard_shortcuts": "Zobrazit klávesové zkratky",
|
||||
"show_less": "Zobrazit méně",
|
||||
"show_metadata": "Zobrazit metadata",
|
||||
"show_more_fields": "{count, plural, one {Zobrazit # další pole} few {Zobrazit # další pole} other {Zobrazit # dalších polí}}",
|
||||
"show_or_hide_info": "Zobrazit nebo skrýt informace",
|
||||
"show_password": "Zobrazit heslo",
|
||||
"show_person_options": "Zobrazit možnosti osoby",
|
||||
@@ -2148,6 +2245,7 @@
|
||||
"show_schema": "Zobrazit schéma",
|
||||
"show_search_options": "Zobrazit možnosti vyhledávání",
|
||||
"show_shared_links": "Zobrazit sdílené odkazy",
|
||||
"show_slideshow_metadata_overlay": "Zobrazit překryvné informace k obrázku",
|
||||
"show_slideshow_transition": "Zobrazit přechod prezentace",
|
||||
"show_supporter_badge": "Odznak podporovatele",
|
||||
"show_supporter_badge_description": "Zobrazit odznak podporovatele",
|
||||
@@ -2163,9 +2261,14 @@
|
||||
"skip_to_folders": "Přeskočit na složky",
|
||||
"skip_to_tags": "Přeskočit na značky",
|
||||
"slideshow": "Prezentace",
|
||||
"slideshow_metadata_overlay_mode": "Obsah překryvného panelu",
|
||||
"slideshow_metadata_overlay_mode_description_only": "Pouze popis",
|
||||
"slideshow_metadata_overlay_mode_full": "Úplný",
|
||||
"slideshow_repeat": "Opakovat prezentaci",
|
||||
"slideshow_repeat_description": "Po skončení prezentace se vrátit na začátek",
|
||||
"slideshow_settings": "Nastavení prezentace",
|
||||
"smart_album": "Chytré album",
|
||||
"some_assets_already_have_a_location_warning": "Některé z vybraných položek již mají polohu",
|
||||
"sort_albums_by": "Seřadit alba podle...",
|
||||
"sort_created": "Datum vytvoření",
|
||||
"sort_items": "Počet položek",
|
||||
@@ -2188,6 +2291,11 @@
|
||||
"start_date_before_end_date": "Počáteční datum se musí nacházet před konečným datem",
|
||||
"state": "Stát",
|
||||
"status": "Stav",
|
||||
"step_delete": "Odstranit krok",
|
||||
"step_delete_confirm": "Opravdu chcete odstranit tento krok?",
|
||||
"step_details": "Podrobnosti o kroku",
|
||||
"steps": "Kroky",
|
||||
"steps_count": "{count, plural, one {# krok} few {# kroky} other {# kroků}}",
|
||||
"stop_casting": "Zastavit odesílání",
|
||||
"stop_motion_photo": "Zastavit pohyblivou fotografii",
|
||||
"stop_photo_sharing": "Přestat sdílet své fotografie?",
|
||||
@@ -2214,6 +2322,8 @@
|
||||
"sync_status": "Stav synchronizace",
|
||||
"sync_status_subtitle": "Zobrazit a spravovat synchronizační systém",
|
||||
"sync_upload_album_setting_subtitle": "Vytvořit a nahrát fotografie a videa do vybraných alb na Immich",
|
||||
"system_theme": "Vzhled systému",
|
||||
"system_theme_command_description": "Použít systémové téma ({value})",
|
||||
"tag": "Značka",
|
||||
"tag_assets": "Přiřadit značku",
|
||||
"tag_created": "Vytvořena značka: {tag}",
|
||||
@@ -2279,7 +2389,9 @@
|
||||
"trash_page_title": "Koš ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Smazané položky budou trvale odstraněny po {days, plural, one {# dni} other {# dnech}}.",
|
||||
"trigger": "Spouštěč",
|
||||
"trigger_asset_uploaded": "Položka nahrána",
|
||||
"trigger_asset_metadata_extraction": "Extrakce metadat položek",
|
||||
"trigger_asset_metadata_extraction_description": "Spustí se při extrakci EXIF údajů z mediálního souboru",
|
||||
"trigger_asset_uploaded": "Nahrání položky",
|
||||
"trigger_asset_uploaded_description": "Spustí se při nahrání nového souboru",
|
||||
"trigger_description": "Událost, která spustí pracovní postup",
|
||||
"trigger_person_recognized": "Osoba rozpoznána",
|
||||
@@ -2319,13 +2431,13 @@
|
||||
"unsupported_field_type": "Nepodporovaný typ pole",
|
||||
"unsupported_file_type": "Soubor {file} nelze nahrát, protože jeho typ {type} není podporován.",
|
||||
"untagged": "Neoznačeno",
|
||||
"untitled_workflow": "Pracovní postup bez názvu",
|
||||
"up_next": "To je prozatím vše",
|
||||
"update_location_action_prompt": "Aktualizovat polohu {count} vybraných položek pomocí:",
|
||||
"updated_at": "Aktualizováno",
|
||||
"updated_password": "Heslo aktualizováno",
|
||||
"upload": "Nahrát",
|
||||
"upload_concurrency": "Souběžnost nahrávání",
|
||||
"upload_day_count": "{date}: {count, plural, one {# nahraná} few {# nahrané} other {# nahraných}}",
|
||||
"upload_details": "Detaily nahrávání",
|
||||
"upload_dialog_info": "Chcete zálohovat vybrané položky na server?",
|
||||
"upload_dialog_title": "Nahrát položku",
|
||||
@@ -2341,6 +2453,8 @@
|
||||
"upload_to_immich": "Nahrát do Immich ({count})",
|
||||
"uploading": "Nahrávání",
|
||||
"uploading_media": "Nahrávání médií",
|
||||
"uploads": "Nahrané",
|
||||
"uploads_count": "{count, plural, one {# nahraná} few {# nahrané} other {# nahraných}}",
|
||||
"url": "URL",
|
||||
"usage": "Využití",
|
||||
"use_biometric": "Použít biometrické údaje",
|
||||
@@ -2348,6 +2462,7 @@
|
||||
"use_browser_locale_description": "Formátujte data, časy a čísla podle nastavení místního formátu vašeho prohlížeče",
|
||||
"use_current_connection": "Použít aktuální připojení",
|
||||
"use_custom_date_range": "Použít vlastní rozsah dat",
|
||||
"use_template": "Použít šablonu",
|
||||
"user": "Uživatel",
|
||||
"user_has_been_deleted": "Tento uživatel byl smazán.",
|
||||
"user_id": "ID uživatele",
|
||||
@@ -2377,6 +2492,7 @@
|
||||
"video": "Video",
|
||||
"video_hover_setting": "Přehrávat miniaturu videa po najetí myší",
|
||||
"video_hover_setting_description": "Přehrát miniaturu videa při najetí myší na položku. I když je přehrávání vypnuto, lze jej spustit najetím na ikonu přehrávání.",
|
||||
"video_quality": "Kvalita videa",
|
||||
"videos": "Videa",
|
||||
"videos_count": "{count, plural, one {# video} few {# videa} other {# videí}}",
|
||||
"videos_only": "Pouze videa",
|
||||
@@ -2409,8 +2525,10 @@
|
||||
"week": "Týden",
|
||||
"welcome": "Vítejte",
|
||||
"welcome_to_immich": "Vítejte v Immichi",
|
||||
"when": "Kdy",
|
||||
"width": "Šířka",
|
||||
"wifi_name": "Název Wi-Fi",
|
||||
"workflow": "Workflow",
|
||||
"workflow_delete_prompt": "Opravdu chcete tento pracovní postup smazat?",
|
||||
"workflow_deleted": "Pracovní postup smazán",
|
||||
"workflow_description": "Popis pracovního postupu",
|
||||
@@ -2420,11 +2538,13 @@
|
||||
"workflow_name": "Název pracovního postupu",
|
||||
"workflow_navigation_prompt": "Opravdu chcete odejít bez uložení změn?",
|
||||
"workflow_summary": "Shrnutí pracovního postupu",
|
||||
"workflow_templates": "Šablony pracovních postupů",
|
||||
"workflow_update_success": "Pracovní postup byl úspěšně aktualizován",
|
||||
"workflow_updated": "Pracovní postup aktualizován",
|
||||
"workflows": "Pracovní postupy",
|
||||
"workflows_help_text": "Pracovní postupy automatizují akce týkající se vašich položek na základě spouštěčů a filtrů",
|
||||
"wrong_pin_code": "Chybný PIN kód",
|
||||
"x_of_total": "{x}/{total}",
|
||||
"year": "Rok",
|
||||
"years_ago": "Před {years, plural, one {rokem} other {# lety}}",
|
||||
"yes": "Ano",
|
||||
|
||||
+114
-17
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "Tilføj en fødselsdag",
|
||||
"add_endpoint": "Tilføj endepunkt",
|
||||
"add_exclusion_pattern": "Tilføj udelukkelsesmønster",
|
||||
"add_filter": "Tilføj filter",
|
||||
"add_filter_description": "Klik for at tilføje en filterbetingelse",
|
||||
"add_location": "Tilføj placering",
|
||||
"add_more_users": "Tilføj flere brugere",
|
||||
"add_partner": "Tilføj partner",
|
||||
"add_path": "Tilføj sti",
|
||||
"add_photos": "Tilføj billeder",
|
||||
"add_step": "Tilføj trin",
|
||||
"add_tag": "Tilføj tag",
|
||||
"add_to": "Tilføj til…",
|
||||
"add_to_album": "Tilføj til album",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "Tilføj til delt album",
|
||||
"add_upload_to_stack": "Tilføj upload til stack",
|
||||
"add_url": "Tilføj URL",
|
||||
"add_workflow_step": "Tilføj workflow-trin",
|
||||
"added_to_archive": "Tilføjet til arkiv",
|
||||
"added_to_favorites": "Tilføjet til favoritter",
|
||||
"added_to_favorites_count": "Tilføjede {count, number} til favoritter",
|
||||
@@ -267,6 +265,8 @@
|
||||
"notification_enable_email_notifications": "Slå emailnotifikationer til",
|
||||
"notification_settings": "Notifikationsindstillinger",
|
||||
"notification_settings_description": "Administrer notifikationsindstillinger, inklusiv email",
|
||||
"oauth_allow_insecure_requests": "Tillad usikre anmodninger",
|
||||
"oauth_allow_insecure_requests_description": "ADVARSEL: Dette deaktiverer TLS-certificering for OAuth anmodninger og kan udsætte dig for MITM angreb.",
|
||||
"oauth_auto_launch": "Auto-opstart",
|
||||
"oauth_auto_launch_description": "Påbegynd OAuth login-flow automatisk når loginsiden tilgås",
|
||||
"oauth_auto_register": "Autoregistrér",
|
||||
@@ -274,9 +274,11 @@
|
||||
"oauth_button_text": "Knaptekst",
|
||||
"oauth_client_secret_description": "Påkrævet for en fortrolig klient eller hvis PKCE (Proof Key for Code Exchange) ikke understøttes for en offentlig klient.",
|
||||
"oauth_enable_description": "Log ind med OAuth",
|
||||
"oauth_end_session_url_description": "Omdiriger brugeren til denne URI, når de logger ud.",
|
||||
"oauth_mobile_redirect_uri": "Mobilomdiregerings-URL",
|
||||
"oauth_mobile_redirect_uri_override": "Tilsidesættelse af mobil omdiregerings-URL",
|
||||
"oauth_mobile_redirect_uri_override_description": "Aktiver, når OAuth-udbyderen ikke tillader en mobil URI, som ''{callback}''",
|
||||
"oauth_prompt_description": "Prompt-parameter (f.eks. select_account, login, consent)",
|
||||
"oauth_role_claim": "Rolle attribut",
|
||||
"oauth_role_claim_description": "Tildel automatisk admin adgang på basis af forekomst af denne påstand. Dén kan være enten 'user' eller 'admin'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +305,8 @@
|
||||
"refreshing_all_libraries": "Opdaterer alle biblioteker",
|
||||
"registration": "Administratorregistrering",
|
||||
"registration_description": "Da du er den første bruger i systemet, får du tildelt rollen som administrator og ansvar for administration og oprettelsen af nye brugere.",
|
||||
"release_channel_release_candidate": "Udgivelseskandidat",
|
||||
"release_channel_stable": "Stabil",
|
||||
"remove_failed_jobs": "Fjern mislykkede opgaver",
|
||||
"require_password_change_on_login": "Kræv at brugeren skifter adgangskode ved første login",
|
||||
"reset_settings_to_default": "Nulstil indstillingerne til standard",
|
||||
@@ -397,6 +401,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "Gælder kun VAAPI og QSV. Sætter dri node'n som bruges til hardware-transkodning.",
|
||||
"transcoding_preset_preset": "Forudindstilling (-preset)",
|
||||
"transcoding_preset_preset_description": "Kompressionshastighed. Langsommere forudindstillinger producerer mindre filer, og øger kvalitet når der gås efter en specifik bitrate. VP9 ignorerer hastigheder hurtigere end \"hurtigere\".",
|
||||
"transcoding_realtime": "Realtids-transkodning [EKSPERIMENTEL]",
|
||||
"transcoding_realtime_description": "Tillader transkodning i realtid, mens videoen streames. Muliggør kvalitetsskifte, men kan forårsage højere afspilningsforsinkelse og hakken afhængigt af serverens kapacitet.",
|
||||
"transcoding_realtime_enabled": "Aktiver real-time transkodning",
|
||||
"transcoding_realtime_enabled_description": "Hvis deaktiveret, kan serveren ikke starte nye realtids transkodningssessioner.",
|
||||
"transcoding_reference_frames": "Referencerammer",
|
||||
"transcoding_reference_frames_description": "Antallet af frames, der skal refereres til, når en given frame komprimeres. Højere værdier forbedrer kompressionseffektiviteten, men gør indkodning langsommere. 0 sætter denne værdi automatisk.",
|
||||
"transcoding_required_description": "Kun videoer ikke i et godkendt format",
|
||||
@@ -440,6 +448,8 @@
|
||||
"user_settings_description": "Administrér brugerindstillinger",
|
||||
"user_successfully_removed": "Bruger {email} er blevet fjernet med succes.",
|
||||
"users_page_description": "Admin-brugere side",
|
||||
"version_check_channel": "Udgivelseskanal",
|
||||
"version_check_channel_description": "Vælg den udgivelseskanal, du vil modtage versionsmeddelelser for",
|
||||
"version_check_enabled_description": "Aktivér versionstjek",
|
||||
"version_check_implications": "Funktionen til versionstjek er afhængig af periodisk kommunikation med {server}",
|
||||
"version_check_settings": "Versionstjek",
|
||||
@@ -560,6 +570,7 @@
|
||||
"asset_added_to_album": "Tilføjet til album",
|
||||
"asset_adding_to_album": "Tilføjer til album…",
|
||||
"asset_created": "Mediefil oprettet",
|
||||
"asset_day_count": "{date}: {count, plural, one {# mediefil} other {# mediefiler}}",
|
||||
"asset_description_updated": "Mediefilsbeskrivelse er blevet opdateret",
|
||||
"asset_filename_is_offline": "Mediefil {filename} er offline",
|
||||
"asset_has_unassigned_faces": "Aktivet har ikke-tildelte ansigter",
|
||||
@@ -689,6 +700,7 @@
|
||||
"backup_settings_subtitle": "Håndtere upload indstillinger",
|
||||
"backup_upload_details_page_more_details": "Tryk for flere detaljer",
|
||||
"backward": "Baglæns",
|
||||
"battery_optimization_backup_reliability": "Deaktivering af batterioptimering kan forbedre pålideligheden af baggrundsbackup",
|
||||
"biometric_auth_enabled": "Biometrisk adgangskontrol slået til",
|
||||
"biometric_locked_out": "Du er låst ude af biometrisk adgangskontrol",
|
||||
"biometric_no_options": "Ingen biometrisk adgangskontrol tilgængelig",
|
||||
@@ -696,6 +708,7 @@
|
||||
"birthdate_saved": "Fødselsdatoen blev gemt",
|
||||
"birthdate_set_description": "Fødselsdato bruges til at beregne denne persons alder på det tidspunkt, et billede er taget.",
|
||||
"blurred_background": "Sløret baggrund",
|
||||
"browse_templates": "Gennemse skabeloner",
|
||||
"bugs_and_feature_requests": "Fejl & forbedringsønsker",
|
||||
"build": "Byg",
|
||||
"build_image": "Byggefil",
|
||||
@@ -729,6 +742,7 @@
|
||||
"cannot_update_the_description": "Kan ikke opdatere beskrivelsen",
|
||||
"cast": "Caste",
|
||||
"cast_description": "Konfigurer tilgængelige cast destinationer",
|
||||
"change": "Ændr",
|
||||
"change_date": "Ændr dato",
|
||||
"change_description": "Ændr beskrivelse",
|
||||
"change_display_order": "Ændrer visningsrækkefølge",
|
||||
@@ -757,6 +771,7 @@
|
||||
"check_corrupt_asset_backup_description": "Kør kun denne kontrol via Wi-Fi, og når alle elementer er blevet sikkerhedskopieret. Proceduren kan tage et par minutter.",
|
||||
"check_logs": "Tjek logfiler",
|
||||
"checksum": "Checksum",
|
||||
"choose": "Vælg",
|
||||
"choose_matching_people_to_merge": "Vælg matchende personer til sammenfletning",
|
||||
"city": "By",
|
||||
"cleanup_confirm_description": "Immich fandt {count} assets (oprettet før {date}) sikkert sikkerhedskopieret til serveren. Fjern de lokale kopier fra denne enhed?",
|
||||
@@ -774,6 +789,7 @@
|
||||
"clear": "Ryd",
|
||||
"clear_all": "Ryd alle",
|
||||
"clear_all_recent_searches": "Ryd alle seneste søgninger",
|
||||
"clear_failed_count": "Ryd mislykkede ({count})",
|
||||
"clear_file_cache": "Ryd filcache",
|
||||
"clear_message": "Ryd bedsked",
|
||||
"clear_value": "Ryd værdi",
|
||||
@@ -805,6 +821,7 @@
|
||||
"comments_are_disabled": "Kommentarer er slået fra",
|
||||
"common_create_new_album": "Opret et nyt album",
|
||||
"completed": "Fuldført",
|
||||
"configuration": "Konfiguration",
|
||||
"confirm": "Bekræft",
|
||||
"confirm_admin_password": "Bekræft administratoradgangskode",
|
||||
"confirm_delete_face": "Er du sikker på, du vil slette {name}s ansigt fra denne mediefil?",
|
||||
@@ -819,6 +836,7 @@
|
||||
"contain": "Inddæm",
|
||||
"context": "Kontekst",
|
||||
"continue": "Fortsæt",
|
||||
"control_bottom_app_bar_add_tags": "Tilføj Tags",
|
||||
"control_bottom_app_bar_create_new_album": "Opret nyt album",
|
||||
"control_bottom_app_bar_delete_from_immich": "Slet fra Immich",
|
||||
"control_bottom_app_bar_delete_from_local": "Slet fra enhed",
|
||||
@@ -832,6 +850,7 @@
|
||||
"copy_error": "Kopifejl",
|
||||
"copy_file_path": "Kopiér filsti",
|
||||
"copy_image": "Kopiér billede",
|
||||
"copy_json": "Kopier JSON",
|
||||
"copy_link": "Kopiér link",
|
||||
"copy_link_to_clipboard": "Kopiér link til udklipsholder",
|
||||
"copy_password": "Kopier adgangskode",
|
||||
@@ -881,17 +900,16 @@
|
||||
"cutoff_date_description": "Behold fotos fra den sidste…",
|
||||
"cutoff_day": "{count, plural, one {dag} other {dage}}",
|
||||
"cutoff_year": "{count, plural, one {år} other {år}}",
|
||||
"daily_title_text_date": "E, dd MMM",
|
||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||
"dark": "Mørk",
|
||||
"dark_theme": "Skift til mørkt tema",
|
||||
"date": "Dato",
|
||||
"date_after": "Dato efter",
|
||||
"date_and_time": "Dato og klokkeslæt",
|
||||
"date_before": "Dato før",
|
||||
"date_format": "E d. LLL y • hh:mm",
|
||||
"date_of_birth": "Fødselsdag",
|
||||
"date_of_birth_saved": "Fødselsdatoen blev gemt korrekt",
|
||||
"date_range": "Datointerval",
|
||||
"date_time_original": "Dato/Tid Original",
|
||||
"day": "Dag",
|
||||
"days": "Dage",
|
||||
"deduplicate_all": "Dedubliker alle",
|
||||
@@ -970,9 +988,12 @@
|
||||
"downloading_asset_filename": "Downloader mediefil {filename}",
|
||||
"downloading_from_icloud": "Downloading fra iCloud",
|
||||
"downloading_media": "Download medier",
|
||||
"drag_to_reorder": "Træk for at ændre rækkefølgen",
|
||||
"drop_files_to_upload": "Slip filer hvor som helst for at uploade dem",
|
||||
"duplicate": "Duplikere",
|
||||
"duplicate_workflow": "Duplikeret arbejdsgang",
|
||||
"duplicates": "Duplikater",
|
||||
"duplicates_description": "Løs hver gruppe ved at angive hvilke, hvis nogen, er dubletter",
|
||||
"duplicates_description": "Løs hver gruppe ved at angive hvilke, hvis nogen, er dubletter.",
|
||||
"duration": "Varighed",
|
||||
"edit": "Rediger",
|
||||
"edit_album": "Redigér album",
|
||||
@@ -998,7 +1019,7 @@
|
||||
"edit_title": "Redigér titel",
|
||||
"edit_user": "Redigér bruger",
|
||||
"edit_workflow": "Rediger workflow",
|
||||
"editor": "Redaktør",
|
||||
"editor": "Rediger",
|
||||
"editor_close_without_save_prompt": "Ændringerne vil ikke blive gemt",
|
||||
"editor_close_without_save_title": "Luk editor?",
|
||||
"editor_confirm_reset_all_changes": "Er du sikker på, at du vil nulstille alle ændringer?",
|
||||
@@ -1072,6 +1093,7 @@
|
||||
"failed_to_remove_product_key": "Fjernelse af produktnøgle mislykkedes",
|
||||
"failed_to_reset_pin_code": "Kunne ikke resette PIN-koden",
|
||||
"failed_to_stack_assets": "Det lykkedes ikke at stable mediefiler",
|
||||
"failed_to_tag_assets": "Kunne ikke tagge mediefiler",
|
||||
"failed_to_unstack_assets": "Det lykkedes ikke at fjerne gruperingen af mediefiler",
|
||||
"failed_to_update_notification_status": "Kunne ikke uploade notifikations status",
|
||||
"incorrect_email_or_password": "Forkert email eller kodeord",
|
||||
@@ -1191,11 +1213,13 @@
|
||||
"export_as_json": "Eksportér som JSON",
|
||||
"export_database": "Eksporter database",
|
||||
"export_database_description": "Eksporter SQLite databasen",
|
||||
"exposure_time": "Eksponeringstid",
|
||||
"extension": "Udvidelse",
|
||||
"external": "Ekstern",
|
||||
"external_libraries": "Eksterne biblioteker",
|
||||
"external_network": "Eksternt netværk",
|
||||
"external_network_sheet_info": "Nå der er ikke er forbundet til det foretrukne Wi-Fi netværk, vil appen forbinde til den første URL den kan forbinde til, på listen nedenfor. Startende fra toppen",
|
||||
"f_number": "F-Nummer",
|
||||
"face_unassigned": "Ikke tildelt",
|
||||
"failed": "Fejlet",
|
||||
"failed_count": "Fejlede: {count}",
|
||||
@@ -1213,7 +1237,6 @@
|
||||
"features_setting_description": "Administrer app-funktioner",
|
||||
"file_name_or_extension": "Filnavn eller filtype",
|
||||
"file_name_text": "Filnavn",
|
||||
"file_name_with_value": "Filnavn: {file_name}",
|
||||
"file_size": "Fil størrelse",
|
||||
"filename": "Filnavn",
|
||||
"filetype": "Filtype",
|
||||
@@ -1226,6 +1249,7 @@
|
||||
"find_them_fast": "Find dem hurtigt med søgning via navn",
|
||||
"first": "Første",
|
||||
"fix_incorrect_match": "Fix forkert match",
|
||||
"focal_length": "Brændvidde",
|
||||
"folder": "Mappe",
|
||||
"folder_not_found": "Mappe ikke fundet",
|
||||
"folders": "Mapper",
|
||||
@@ -1236,6 +1260,7 @@
|
||||
"free_up_space_description": "Flyt sikkerhedskopierede fotos og videoer til din enheds skraldespand for at frigøre plads. Dine kopier på serveren forbliver sikre.",
|
||||
"free_up_space_settings_subtitle": "Frigør enhedslagerplads",
|
||||
"full_path": "Fuld sti: {path}",
|
||||
"full_path_or_folder": "Fuld sti eller mappe",
|
||||
"gcast_enabled": "Google Cast",
|
||||
"gcast_enabled_description": "Denne funktion indlæser eksterne ressourcer fra Google for at virke.",
|
||||
"general": "Generel",
|
||||
@@ -1345,6 +1370,7 @@
|
||||
"ios_debug_info_no_sync_yet": "Der er endnu ikke kørt noget baggrundssynkroniseringsjob",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {{count} baggrundsproces i kø} other {{count} baggrundsprocesser i kø}}",
|
||||
"ios_debug_info_processing_ran_at": "Behandlingen kørte {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# element} other {# elementer}}",
|
||||
"jobs": "Opgaver",
|
||||
"json_editor": "JSON editor",
|
||||
@@ -1375,6 +1401,7 @@
|
||||
"leave": "Forlad",
|
||||
"leave_album": "Forlad album",
|
||||
"lens_model": "Objektivmodel",
|
||||
"less": "Mindre",
|
||||
"let_others_respond": "Lad andre svare",
|
||||
"level": "Niveau",
|
||||
"library": "Bibliotek",
|
||||
@@ -1392,11 +1419,13 @@
|
||||
"light_theme": "Skift til lyst tema",
|
||||
"like": "Synes om",
|
||||
"like_deleted": "Ligesom slettet",
|
||||
"link": "Link",
|
||||
"link_motion_video": "Link bevægelsesvideo",
|
||||
"link_to_docs": "For yderligere information, se <link>dokumentationen</link>.",
|
||||
"link_to_oauth": "Link til OAuth",
|
||||
"linked_oauth_account": "Tilsluttet OAuth-konto",
|
||||
"list": "Liste",
|
||||
"live": "Live",
|
||||
"loading": "Indlæser",
|
||||
"loading_search_results_failed": "Indlæsning af søgeresultater fejlede",
|
||||
"local": "Lokal",
|
||||
@@ -1518,7 +1547,39 @@
|
||||
"marked_all_as_read": "Markerede alle som læst",
|
||||
"matches": "Parringer",
|
||||
"matching_assets": "Matchende objekter",
|
||||
"media_type": "Medietype",
|
||||
"media_chrome": {
|
||||
"auto": "Auto",
|
||||
"captions": "Undertekster",
|
||||
"captions_off": "Fra",
|
||||
"closed_captions": "Undertekster for hørehæmmede",
|
||||
"decode_error": "Fejl ved dekodning",
|
||||
"disable_captions": "Slå undertekster fra",
|
||||
"enable_captions": "Slå undertekster til",
|
||||
"enter_fullscreen_mode": "Fuld skærm",
|
||||
"exit_fullscreen_mode": "Luk fuld skærm",
|
||||
"loop": "Gentag",
|
||||
"media_error_description": "En mediefejl stoppede afspilningen. Filen kan være korrupt eller browseren understøtter ikke filtypen.",
|
||||
"media_loading": "Loader medie",
|
||||
"mute": "Sluk lyd",
|
||||
"network_error": "Netværksfejl",
|
||||
"network_error_description": "En netværksfejl fik download til at fejle.",
|
||||
"not_supported_error": "Kilde er ikke understøttet",
|
||||
"playback_rate": "Afspilningshastighed",
|
||||
"playback_rate_current": "nuværende afspilningshastighed",
|
||||
"playback_rate_value": "Afspilningshastighed {playbackRate}",
|
||||
"playback_time": "afspilnings varighed",
|
||||
"quality": "Kvalitet",
|
||||
"second": "sekund",
|
||||
"seconds": "sekunder",
|
||||
"time_value_of_total_time": "{currentTime} af {totalTime}",
|
||||
"time_value_remaining": "{time} tilbage",
|
||||
"unmute": "Lyd til",
|
||||
"unsupported_error_description": "En ukendt fejl opstod. Fejl på server, netværk eller din browser understøtter ikke formatet.",
|
||||
"video_not_loaded_unknown_time": "video er ikke indlæst, ukendt tidspunkt.",
|
||||
"video_player": "videoafspiller",
|
||||
"volume": "lydstyrke"
|
||||
},
|
||||
"media_type": "Medieformat",
|
||||
"memories": "Minder",
|
||||
"memories_all_caught_up": "Ajour",
|
||||
"memories_check_back_tomorrow": "Kom tilbage i morgen for at se nye minder",
|
||||
@@ -1534,6 +1595,8 @@
|
||||
"merge_people_prompt": "Vil du flette disse mennesker sammen? Denne handling er uigenkaldelig.",
|
||||
"merge_people_successfully": "Personer sammenflettet med succes",
|
||||
"merged_people_count": "{count, plural, one {# person} other {# personer}} lagt sammen",
|
||||
"minFaces": "Minimum ansigter",
|
||||
"minFaces_description": "Det mindste antal ansigter der skal genkendes for at en person vises",
|
||||
"minimize": "Minimér",
|
||||
"minute": "Minut",
|
||||
"minutes": "Minutter",
|
||||
@@ -1543,9 +1606,10 @@
|
||||
"mobile_app": "Mobil App",
|
||||
"mobile_app_download_onboarding_note": "Hent den tilhørende mobilapp via en af følgende muligheder",
|
||||
"model": "Model",
|
||||
"modify_date": "Ændre dato",
|
||||
"month": "Måned",
|
||||
"monthly_title_text_date_format": "MMMM å",
|
||||
"more": "Mere",
|
||||
"motion": "Bevægelse",
|
||||
"move": "Flyt",
|
||||
"move_down": "Flyt ned",
|
||||
"move_off_locked_folder": "Flyt ud af låst mappe",
|
||||
@@ -1562,6 +1626,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af skrivebeskyttet elementer. Springer over",
|
||||
"mute_memories": "Dæmp minder",
|
||||
"my_albums": "Mine albummer",
|
||||
"my_immich_description": "Kopier aktuel side som et Mit Immich link",
|
||||
"my_immich_title": "Mit Immich link",
|
||||
"name": "Navn",
|
||||
"name_or_nickname": "Navn eller kaldenavn",
|
||||
"name_required": "Navn er påkrævet",
|
||||
@@ -1589,7 +1655,6 @@
|
||||
"next": "Næste",
|
||||
"next_memory": "Næste minde",
|
||||
"no": "Nej",
|
||||
"no_actions_added": "Ingen handlinger tilføjet endnu",
|
||||
"no_albums_found": "Ingen album fundet",
|
||||
"no_albums_message": "Opret et album for at organisere dine billeder og videoer",
|
||||
"no_albums_with_name_yet": "Det ser ud til, at du ikke har noget album med dette navn endnu.",
|
||||
@@ -1606,7 +1671,6 @@
|
||||
"no_exif_info_available": "Ingen tilgængelig exif information",
|
||||
"no_explore_results_message": "Upload flere billeder for at udforske din samling.",
|
||||
"no_favorites_message": "Tilføj favoritter for hurtigt at finde dine bedst billeder og videoer",
|
||||
"no_filters_added": "Ingen filtre tilføjet endnu",
|
||||
"no_libraries_message": "Opret et eksternt bibliotek for at se dine billeder og videoer",
|
||||
"no_local_assets_found": "Ingen lokale objekter fundet med denne checksum",
|
||||
"no_location_set": "Ingen placering sat",
|
||||
@@ -1619,6 +1683,7 @@
|
||||
"no_results": "Ingen resultater",
|
||||
"no_results_description": "Prøv et synonym eller et mere generelt søgeord",
|
||||
"no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk",
|
||||
"no_steps": "Ingen trin tilføjet endnu",
|
||||
"no_uploads_in_progress": "Ingen upload i gang",
|
||||
"none": "Ingen",
|
||||
"not_allowed": "Ikke tilladt",
|
||||
@@ -1627,6 +1692,7 @@
|
||||
"not_selected": "Ikke valgt",
|
||||
"notes": "Noter",
|
||||
"nothing_here_yet": "Intet her endnu",
|
||||
"notification_backup_reliability": "Aktivér notifikationer for at forbedre pålideligheden af backup i baggrunden",
|
||||
"notification_permission_dialog_content": "Gå til indstillinger for at slå notifikationer til.",
|
||||
"notification_permission_list_tile_content": "Tillad at bruge notifikationer.",
|
||||
"notification_permission_list_tile_enable_button": "Slå notifikationer til",
|
||||
@@ -1664,6 +1730,7 @@
|
||||
"organize_into_albums": "Organiser i album",
|
||||
"organize_into_albums_description": "Sæt eksisterende billeder i albummer ved hjælp af aktuelle synkroniseringsindstillinger",
|
||||
"organize_your_library": "Organisér dit bibliotek",
|
||||
"orientation": "Orientering",
|
||||
"original": "original",
|
||||
"other": "Andet",
|
||||
"other_devices": "Andre enheder",
|
||||
@@ -1755,6 +1822,8 @@
|
||||
"play_original_video_setting_description": "Foretrækker afspilning af originale videoer frem for transkodede videoer. Hvis det originale element ikke er kompatibelt, afspilles det muligvis ikke korrekt.",
|
||||
"play_transcoded_video": "Afspil transkodet video",
|
||||
"please_auth_to_access": "Log venligst ind for at tilgå",
|
||||
"plugin_method_filter_type": "Filter",
|
||||
"plugin_method_filter_type_description": "Denne metode kan filtrere hændelser og betinget forhindre efterfølgende trin i at køre",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Administrer appens indstillinger",
|
||||
"preferences_settings_title": "Præferencer",
|
||||
@@ -1776,6 +1845,7 @@
|
||||
"profile_drawer_readonly_mode": "Skrivebeskyttet tilstand aktiveret. Lang tryk på bruger avatar ikonet for at afslutte.",
|
||||
"profile_image_of_user": "Profilbillede af {user}",
|
||||
"profile_picture_set": "Profilbillede indstillet.",
|
||||
"projection_type": "Projektionstype",
|
||||
"public_album": "Offentligt album",
|
||||
"public_share": "Offentlig deling",
|
||||
"purchase_account_info": "Supporter",
|
||||
@@ -1853,6 +1923,7 @@
|
||||
"remove_assets_title": "Fjern mediefiler?",
|
||||
"remove_custom_date_range": "Fjern tilpasset datointerval",
|
||||
"remove_deleted_assets": "Fjern slettede mediefiler",
|
||||
"remove_filter": "Fjern filter",
|
||||
"remove_from_album": "Fjern fra album",
|
||||
"remove_from_album_action_prompt": "{count} fjernet fra albummet",
|
||||
"remove_from_favorites": "Fjern fra favoritter",
|
||||
@@ -1908,7 +1979,7 @@
|
||||
"review_duplicates": "Gennemgå dubletter",
|
||||
"review_large_files": "Gennemgå store filer",
|
||||
"role": "Rolle",
|
||||
"role_editor": "Redaktør",
|
||||
"role_editor": "Rediger",
|
||||
"role_viewer": "Seer",
|
||||
"running": "Kører",
|
||||
"save": "Gem",
|
||||
@@ -1926,6 +1997,8 @@
|
||||
"scan_settings": "Skanningsindstillinger",
|
||||
"scanning": "Skanner",
|
||||
"scanning_for_album": "Skanner efter albummer...",
|
||||
"screencast_mode_description": "Vis indikatorer for tastatur- og musehændelse på skærmen",
|
||||
"screencast_mode_title": "Skift skærmcast-tilstand",
|
||||
"search": "Søg",
|
||||
"search_albums": "Søg i albummer",
|
||||
"search_by_context": "Søg efter kontekst",
|
||||
@@ -1933,6 +2006,8 @@
|
||||
"search_by_description_example": "Vandredag i Paris",
|
||||
"search_by_filename": "Søg efter filnavn eller filtypenavn",
|
||||
"search_by_filename_example": "dvs. IMG_1234.JPG eller PNG",
|
||||
"search_by_full_path": "søg efter fuld sti eller mappe",
|
||||
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - du kan søge efter Projects, 3D, Printing, 2026 osv.",
|
||||
"search_by_ocr": "Søg via OCR",
|
||||
"search_by_ocr_example": "Søg efter tekst i dine billeder",
|
||||
"search_camera_lens_model": "Søg objektiv model...",
|
||||
@@ -2101,7 +2176,7 @@
|
||||
"shared_link_edit_expire_after_option_year": "{count} år",
|
||||
"shared_link_edit_password_hint": "Indtast kodeordet",
|
||||
"shared_link_edit_submit_button": "Opdater link",
|
||||
"shared_link_error_server_url_fetch": "Kan ikke hente server URL",
|
||||
"shared_link_error_server_url_fetch": "Kan ikke hente server url",
|
||||
"shared_link_expires_day": "Udløber om {count} dag",
|
||||
"shared_link_expires_days": "Udløber om {count} dage",
|
||||
"shared_link_expires_hour": "Udløber om {count} time",
|
||||
@@ -2140,7 +2215,9 @@
|
||||
"show_in_timeline": "Vis på tidslinje",
|
||||
"show_in_timeline_setting_description": "Vis billeder og videoer fra denne bruger på din tidslinje",
|
||||
"show_keyboard_shortcuts": "Vis tastaturgenveje",
|
||||
"show_less": "Vis mindre",
|
||||
"show_metadata": "Vis metadata",
|
||||
"show_more_fields": "{count, plural, one {Vis # mere felt} other {Vis # flere felter}}",
|
||||
"show_or_hide_info": "Vis eller skjul info",
|
||||
"show_password": "Vis adgangskode",
|
||||
"show_person_options": "Vis personindstillinger",
|
||||
@@ -2148,6 +2225,7 @@
|
||||
"show_schema": "Vis skema",
|
||||
"show_search_options": "Vis søgeindstillinger",
|
||||
"show_shared_links": "Vis delte links",
|
||||
"show_slideshow_metadata_overlay": "Vis billedinfo-overlay",
|
||||
"show_slideshow_transition": "Vis overgang til diasshow",
|
||||
"show_supporter_badge": "Supporter skilt",
|
||||
"show_supporter_badge_description": "Vis et supporter ikon",
|
||||
@@ -2163,9 +2241,13 @@
|
||||
"skip_to_folders": "Spring til mapper",
|
||||
"skip_to_tags": "Spring til tags",
|
||||
"slideshow": "Diasshow",
|
||||
"slideshow_metadata_overlay_mode": "Overlay indhold",
|
||||
"slideshow_metadata_overlay_mode_description_only": "Kun beskrivelse",
|
||||
"slideshow_metadata_overlay_mode_full": "Fuld",
|
||||
"slideshow_repeat": "Gentag diasshow",
|
||||
"slideshow_repeat_description": "Hop tilbage til begyndelsen når diasshow stopper",
|
||||
"slideshow_settings": "Diasshowindstillinger",
|
||||
"smart_album": "Smart album",
|
||||
"sort_albums_by": "Sortér albummer efter...",
|
||||
"sort_created": "Dato oprettet",
|
||||
"sort_items": "Antal genstande",
|
||||
@@ -2188,6 +2270,11 @@
|
||||
"start_date_before_end_date": "Startdato skal ligge før slutdato",
|
||||
"state": "Stat",
|
||||
"status": "Status",
|
||||
"step_delete": "Slet trin",
|
||||
"step_delete_confirm": "Er du sikker på, at du vil slette dette trin?",
|
||||
"step_details": "Trin detaljer",
|
||||
"steps": "Trin",
|
||||
"steps_count": "{count, plural, one {# trin} other {# trin}}",
|
||||
"stop_casting": "Stop med at caste",
|
||||
"stop_motion_photo": "Stopmotionbillede",
|
||||
"stop_photo_sharing": "Stop med at dele dine billeder?",
|
||||
@@ -2214,6 +2301,8 @@
|
||||
"sync_status": "Synkroniserings Status",
|
||||
"sync_status_subtitle": "Se og administrér synkroniseringssystemet",
|
||||
"sync_upload_album_setting_subtitle": "Opret og upload dine billeder og videoer til de valgte albummer i Immich",
|
||||
"system_theme": "Systemtema",
|
||||
"system_theme_command_description": "Brug systemtemaet ({value})",
|
||||
"tag": "Tag",
|
||||
"tag_assets": "Tag mediefiler",
|
||||
"tag_created": "Oprettet tag: {tag}",
|
||||
@@ -2279,7 +2368,7 @@
|
||||
"trash_page_title": "Papirkurv ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Mediefiler i papirkurven vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.",
|
||||
"trigger": "Udløser",
|
||||
"trigger_asset_uploaded": "Mediefil uploaded",
|
||||
"trigger_asset_uploaded": "Mediefil upload",
|
||||
"trigger_asset_uploaded_description": "Udløses, når et nyt asset bliver uploaded",
|
||||
"trigger_description": "En begivenhed, der starter en arbejdsgang",
|
||||
"trigger_person_recognized": "Peron genkendt",
|
||||
@@ -2319,13 +2408,13 @@
|
||||
"unsupported_field_type": "Ikke-understøttet felttype",
|
||||
"unsupported_file_type": "Filen {file} kan ikke uploades, fordi filtypen {type} ikke understøttes.",
|
||||
"untagged": "Umærket",
|
||||
"untitled_workflow": "Unavngivet arbejdsgang",
|
||||
"up_next": "Næste",
|
||||
"update_location_action_prompt": "Opdater lokationen for {count} valgte objekter med:",
|
||||
"updated_at": "Opdateret",
|
||||
"updated_password": "Opdaterede adgangskode",
|
||||
"upload": "Upload",
|
||||
"upload_concurrency": "Upload samtidighed",
|
||||
"upload_day_count": "{date}: {count, plural, one {# upload} other {# uploads}}",
|
||||
"upload_details": "Upload detaljer",
|
||||
"upload_dialog_info": "Vil du sikkerhedskopiere de(t) valgte element(er) til serveren?",
|
||||
"upload_dialog_title": "Upload element",
|
||||
@@ -2341,6 +2430,8 @@
|
||||
"upload_to_immich": "Upload til Immich ({count})",
|
||||
"uploading": "Uploader",
|
||||
"uploading_media": "Uploader media",
|
||||
"uploads": "Uploads",
|
||||
"uploads_count": "{count, plural, one {# upload} other {# uploads}}",
|
||||
"url": "URL",
|
||||
"usage": "Forbrug",
|
||||
"use_biometric": "Brug biometrisk",
|
||||
@@ -2348,6 +2439,7 @@
|
||||
"use_browser_locale_description": "Formatér datoer, klokkeslæt og tal baseret på din browsers lokalitet",
|
||||
"use_current_connection": "Brug nuværende forbindelse",
|
||||
"use_custom_date_range": "Brug tilpasset datointerval i stedet",
|
||||
"use_template": "Brug skabelon",
|
||||
"user": "Bruger",
|
||||
"user_has_been_deleted": "Denne bruger er slettet.",
|
||||
"user_id": "Bruger-ID",
|
||||
@@ -2377,6 +2469,7 @@
|
||||
"video": "Video",
|
||||
"video_hover_setting": "Afspil miniaturevisning af video når musemarkøren er over den",
|
||||
"video_hover_setting_description": "Afspil miniaturevisning for videoer når musemarkøren holdes over elementet. Selv når det er deaktiveret, kan afspilning startes ved at holde musen over afspilningsikonet.",
|
||||
"video_quality": "Videokvalitet",
|
||||
"videos": "Videoer",
|
||||
"videos_count": "{count, plural, one {# Video} other {# Videoer}}",
|
||||
"videos_only": "Kun videoer",
|
||||
@@ -2409,8 +2502,10 @@
|
||||
"week": "Uge",
|
||||
"welcome": "Velkommen",
|
||||
"welcome_to_immich": "Velkommen til Immich",
|
||||
"when": "Hvornår",
|
||||
"width": "Bredde",
|
||||
"wifi_name": "Wi-Fi navn",
|
||||
"workflow": "Arbejdsgang",
|
||||
"workflow_delete_prompt": "Er du sikker på, at du vil slette denne arbejdsgang?",
|
||||
"workflow_deleted": "Arbejdsgang slettet",
|
||||
"workflow_description": "Arbejdsgangsbeskrivelse",
|
||||
@@ -2420,11 +2515,13 @@
|
||||
"workflow_name": "Navn på arbejdsgang",
|
||||
"workflow_navigation_prompt": "Er du sikker på, at du vil forlade uden at gemme dine ændringer?",
|
||||
"workflow_summary": "Arbejdsgangsoversigt",
|
||||
"workflow_templates": "Arbejdsgangsskabeloner",
|
||||
"workflow_update_success": "Arbejdsgang opdateret korrekt",
|
||||
"workflow_updated": "Arbejdsgang opdateret",
|
||||
"workflows": "Arbejdsgange",
|
||||
"workflows_help_text": "Arbejdsgange automatiserer handlinger på dine filer baseret på udløsere og filtre",
|
||||
"wrong_pin_code": "Forkert PIN kode",
|
||||
"x_of_total": "{x}/{total}",
|
||||
"year": "År",
|
||||
"years_ago": "{years, plural, one {# år} other {# år}} siden",
|
||||
"yes": "Ja",
|
||||
|
||||
+146
-28
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"about": "Über",
|
||||
"account": "Konto",
|
||||
"about": "Über Immich",
|
||||
"account": "Mein Konto",
|
||||
"account_settings": "Kontoeinstellungen",
|
||||
"acknowledge": "Verstanden",
|
||||
"acknowledge": "Schließen",
|
||||
"action": "Aktion",
|
||||
"action_common_update": "Aktualisieren",
|
||||
"action_description": "Eine Reihe von Aktionen, die an den gefilterten Assets ausgeführt werden sollen",
|
||||
"actions": "Aktionen",
|
||||
"active": "Aktiv",
|
||||
"active_count": "Aktive: {count}",
|
||||
"activity": "Aktivität",
|
||||
"activity": "Ansicht",
|
||||
"activity_changed": "Aktivität ist {enabled, select, true {aktiviert} other {deaktiviert}}",
|
||||
"add": "Hinzufügen",
|
||||
"add_a_description": "Beschreibung hinzufügen",
|
||||
@@ -18,17 +18,16 @@
|
||||
"add_a_title": "Titel hinzufügen",
|
||||
"add_action": "Aktion hinzufügen",
|
||||
"add_action_description": "Klicken um eine Aktion hinzuzufügen",
|
||||
"add_assets": "Assets hinzufügen",
|
||||
"add_assets": "Elemente hinzufügen",
|
||||
"add_birthday": "Geburtsdatum hinzufügen",
|
||||
"add_endpoint": "Endpunkt hinzufügen",
|
||||
"add_endpoint": "Ziel hinzufügen",
|
||||
"add_exclusion_pattern": "Ausschlussmuster hinzufügen",
|
||||
"add_filter": "Filter hinzufügen",
|
||||
"add_filter_description": "Klicken um eine Filterbedingung hinzuzufügen",
|
||||
"add_location": "Standort hinzufügen",
|
||||
"add_more_users": "Weitere Nutzer hinzufügen",
|
||||
"add_partner": "Partner hinzufügen",
|
||||
"add_path": "Pfad hinzufügen",
|
||||
"add_photos": "Fotos hinzufügen",
|
||||
"add_step": "Schritt hinzufügen",
|
||||
"add_tag": "Tag hinzufügen",
|
||||
"add_to": "Hinzufügen zu …",
|
||||
"add_to_album": "Zu Album hinzufügen",
|
||||
@@ -42,7 +41,6 @@
|
||||
"add_to_shared_album": "Zu geteiltem Album hinzufügen",
|
||||
"add_upload_to_stack": "Upload zum Stapel hinzufügen",
|
||||
"add_url": "URL hinzufügen",
|
||||
"add_workflow_step": "Workflow-Schritt hinzufügen",
|
||||
"added_to_archive": "Zum Archiv hinzugefügt",
|
||||
"added_to_favorites": "Zu Favoriten hinzugefügt",
|
||||
"added_to_favorites_count": "{count, number} zu Favoriten hinzugefügt",
|
||||
@@ -78,9 +76,10 @@
|
||||
"copy_config_to_clipboard_description": "Kopieren Sie die aktuelle Systemkonfiguration als JSON-Objekt in die Zwischenablage",
|
||||
"create_job": "Aufgabe erstellen",
|
||||
"cron_expression": "Cron-Ausdruck",
|
||||
"cron_expression_description": "Setze das Scanintervall im Cron-Format. Hilfe mit dem Format bietet dir dabei z. B. der <link>Crontab Guru</link>",
|
||||
"cron_expression_description": "Legen Sie das Scanintervall im Cron-Format fest. Weitere Informationen finden Sie z. B. bei <link>Crontab Guru</link>",
|
||||
"cron_expression_presets": "Vorlagen für Cron-Zeitangabe",
|
||||
"disable_login": "Login deaktivieren",
|
||||
"download_csv": "CSV herunterladen",
|
||||
"duplicate_detection_job_description": "Diese Aufgabe führt das maschinelle Lernen für jede Datei aus, um Duplikate zu finden. Diese Aufgabe beruht auf der intelligenten Suche",
|
||||
"exclusion_pattern_description": "Mit Ausschlussmustern können Dateien und Ordner beim Scannen Ihrer Bibliothek ignoriert werden. Dies ist nützlich, wenn du Ordner hast, die Dateien enthalten, die du nicht importieren möchtest, wie z. B. RAW-Dateien.",
|
||||
"export_config_as_json_description": "Laden Sie die aktuelle Systemkonfiguration als JSON-Datei herunter",
|
||||
@@ -193,6 +192,17 @@
|
||||
"maintenance_delete_backup": "Backup löschen",
|
||||
"maintenance_delete_backup_description": "Diese Datei wird irreversibel gelöscht.",
|
||||
"maintenance_delete_error": "Die Löschung der Sicherungskopie ist fehlgeschlagen.",
|
||||
"maintenance_integrity_check_all": "Überprüfe alle",
|
||||
"maintenance_integrity_checksum_mismatch": "Prüfsummenfehler",
|
||||
"maintenance_integrity_checksum_mismatch_job": "Auf Prüfsummen-Nichtübereinstimmungen prüfen",
|
||||
"maintenance_integrity_checksum_mismatch_refresh_job": "Aktualisieren Sie Berichte über Prüfsummenkonflikte",
|
||||
"maintenance_integrity_missing_file": "Fehlende Dateien",
|
||||
"maintenance_integrity_missing_file_job": "Auf fehlende Dateien prüfen",
|
||||
"maintenance_integrity_missing_file_refresh_job": "Berichte über fehlende Dateien aktualisieren",
|
||||
"maintenance_integrity_report": "Integritätsbericht",
|
||||
"maintenance_integrity_untracked_file": "Nicht getrackte Dateien",
|
||||
"maintenance_integrity_untracked_file_job": "Überprüfen Sie ungetrackte Dateien",
|
||||
"maintenance_integrity_untracked_file_refresh_job": "Berichte über nicht getrackte Dateien aktualisieren",
|
||||
"maintenance_restore_backup": "Sicherungskopie wiederherstellen",
|
||||
"maintenance_restore_backup_description": "Immich wird zurückgesetzt und von der ausgewählten Sicherungskopie wiederhergestellt. Ein Backup wird erstellt, bevor es weitergeht.",
|
||||
"maintenance_restore_backup_different_version": "Diese Sicherungskopie wurde mit einer anderen Version von Immich erstellt!",
|
||||
@@ -267,6 +277,8 @@
|
||||
"notification_enable_email_notifications": "E-Mail-Benachrichtigungen aktivieren",
|
||||
"notification_settings": "Benachrichtigungseinstellungen",
|
||||
"notification_settings_description": "Benachrichtigungseinstellungen (inkl. E-Mail) verwalten",
|
||||
"oauth_allow_insecure_requests": "Unsichere Anfragen erlauben",
|
||||
"oauth_allow_insecure_requests_description": "WARNUNG: Dies deaktiviert die TLS-Zertifikatsvalidierung für OAuth-Anfragen und kann Sie MITM-Angriffen aussetzen.",
|
||||
"oauth_auto_launch": "Auto-Start",
|
||||
"oauth_auto_launch_description": "Automatischer Start des OAuth-Anmeldevorgangs beim Aufrufen der Anmeldeseite",
|
||||
"oauth_auto_register": "Automatische Registrierung",
|
||||
@@ -274,9 +286,11 @@
|
||||
"oauth_button_text": "Button-Text",
|
||||
"oauth_client_secret_description": "Erforderlich für Confidential Clients oder wenn PKCE (Proof Key for Code Exchange) nicht für Public Clients unterstützt wird.",
|
||||
"oauth_enable_description": "Anmeldung mit OAuth",
|
||||
"oauth_end_session_url_description": "Leite den Benutzer nach dem Abmelden zu dieser URI weiter.",
|
||||
"oauth_mobile_redirect_uri": "Mobile Umleitungs-URI",
|
||||
"oauth_mobile_redirect_uri_override": "Mobile Umleitungs-URI überschreiben",
|
||||
"oauth_mobile_redirect_uri_override_description": "Einschalten, wenn der OAuth-Anbieter keine mobile URI wie ''{callback}'' erlaubt",
|
||||
"oauth_prompt_description": "Eingabe Parameter (z. B. Konto auswählen, Login, Einwilligung)",
|
||||
"oauth_role_claim": "Rollen-Claim",
|
||||
"oauth_role_claim_description": "Gewähre automatisch Admin-Zugriff basierend auf dem Vorhandensein dieses Claims. Der Claim kann entweder 'user' oder 'admin' sein.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -303,6 +317,8 @@
|
||||
"refreshing_all_libraries": "Alle Bibliotheken aktualisieren",
|
||||
"registration": "Admin-Registrierung",
|
||||
"registration_description": "Da du der erste Benutzer im System bist, wird dir die Rolle des Administrators zugewiesen, womit du für die Verwaltungsaufgaben verantwortlich bist. Weitere Benutzer werden von dir erstellt.",
|
||||
"release_channel_release_candidate": "Release Candidate",
|
||||
"release_channel_stable": "Stabil",
|
||||
"remove_failed_jobs": "Entferne fehlgeschlagene Aufgaben",
|
||||
"require_password_change_on_login": "Benutzer muss das Passwort beim ersten Login ändern",
|
||||
"reset_settings_to_default": "Einstellungen auf Standard zurücksetzen",
|
||||
@@ -397,6 +413,10 @@
|
||||
"transcoding_preferred_hardware_device_description": "Gilt nur für VAAPI und QSV. Legt den für die Hardware-Transkodierung verwendeten dri-Node fest.",
|
||||
"transcoding_preset_preset": "Voreinstellung (-preset)",
|
||||
"transcoding_preset_preset_description": "Komprimierungsgeschwindigkeit. Eine langsamere Voreinstellungen erzeugt kleinere Dateien und erhöht die Qualität, wenn man eine gewisse Bitrate anstrebt. VP9 ignoriert Geschwindigkeiten über „Schneller“.",
|
||||
"transcoding_realtime": "Echtzeit-Transkodierung [EXPERIMENTELL]",
|
||||
"transcoding_realtime_description": "Ermöglicht die Transkodierung in Echtzeit während des Videostreams. Ermöglicht einen Qualitätswechsel, kann jedoch je nach Serverkapazität zu einer höheren Wiedergabelatenz und Rucklern führen.",
|
||||
"transcoding_realtime_enabled": "Echtzeit-Transkodierung aktivieren",
|
||||
"transcoding_realtime_enabled_description": "Wenn diese Option deaktiviert ist, lehnt der Server den Start neuer Echtzeit-Transkodierungssitzungen ab.",
|
||||
"transcoding_reference_frames": "Referenz-Frames",
|
||||
"transcoding_reference_frames_description": "Die Anzahl der Bilder, auf die bei der Komprimierung eines bestimmten Bildes Bezug genommen wird. Höhere Werte verbessern die Komprimierungseffizienz, verlangsamen aber die Kodierung. 0 setzt diesen Wert automatisch.",
|
||||
"transcoding_required_description": "Nur Videos in einem nicht akzeptierten Format",
|
||||
@@ -440,6 +460,8 @@
|
||||
"user_settings_description": "Benutzereinstellungen verwalten",
|
||||
"user_successfully_removed": "Der Benutzer {email} wurde erfolgreich entfernt.",
|
||||
"users_page_description": "Administrator-Benutzerseite",
|
||||
"version_check_channel": "Release Kanal",
|
||||
"version_check_channel_description": "Wählen Sie den Release-Kanal aus, für den Sie Versionsankündigungen erhalten möchten",
|
||||
"version_check_enabled_description": "Versionsprüfung aktivieren",
|
||||
"version_check_implications": "Die Funktion zur Versionsprüfung basiert auf regelmäßiger Kommunikation mit {server}",
|
||||
"version_check_settings": "Versionsprüfung",
|
||||
@@ -560,6 +582,7 @@
|
||||
"asset_added_to_album": "Zum Album hinzugefügt",
|
||||
"asset_adding_to_album": "Hinzufügen zum Album…",
|
||||
"asset_created": "Datei erstellt",
|
||||
"asset_day_count": "{date}: {count, plural, one {# Datei} other {# Dateien}}",
|
||||
"asset_description_updated": "Die Beschreibung der Datei wurde aktualisiert",
|
||||
"asset_filename_is_offline": "Datei {filename} ist offline",
|
||||
"asset_has_unassigned_faces": "Datei hat nicht zugewiesene Gesichter",
|
||||
@@ -689,6 +712,7 @@
|
||||
"backup_settings_subtitle": "Upload-Einstellungen verwalten",
|
||||
"backup_upload_details_page_more_details": "Tippe für weitere Details",
|
||||
"backward": "Rückwärts",
|
||||
"battery_optimization_backup_reliability": "Das Deaktivieren der Akkuoptimierung kann die Zuverlässigkeit der Sicherung im Hintergrund verbessern",
|
||||
"biometric_auth_enabled": "Biometrische Authentifizierung aktiviert",
|
||||
"biometric_locked_out": "Du bist von der biometrischen Authentifizierung ausgeschlossen",
|
||||
"biometric_no_options": "Keine biometrischen Optionen verfügbar",
|
||||
@@ -696,6 +720,7 @@
|
||||
"birthdate_saved": "Geburtsdatum erfolgreich gespeichert",
|
||||
"birthdate_set_description": "Das Geburtsdatum wird verwendet, um das Alter dieser Person zum Zeitpunkt eines Fotos zu berechnen.",
|
||||
"blurred_background": "Unscharfer Hintergrund",
|
||||
"browse_templates": "Vorlagen durchsuchen",
|
||||
"bugs_and_feature_requests": "Fehler & Verbesserungsvorschläge",
|
||||
"build": "Build",
|
||||
"build_image": "Abbildversion",
|
||||
@@ -729,6 +754,7 @@
|
||||
"cannot_update_the_description": "Beschreibung kann nicht aktualisiert werden",
|
||||
"cast": "Übertragen",
|
||||
"cast_description": "Verfügbare Cast-Ziele konfigurieren",
|
||||
"change": "Ändern",
|
||||
"change_date": "Datum ändern",
|
||||
"change_description": "Beschreibung anpassen",
|
||||
"change_display_order": "Anzeigereihenfolge ändern",
|
||||
@@ -757,6 +783,7 @@
|
||||
"check_corrupt_asset_backup_description": "Führe diese Prüfung nur mit aktivierten WLAN durch, nachdem alle Dateien gesichert worden sind. Dieser Vorgang kann ein paar Minuten dauern.",
|
||||
"check_logs": "Logs prüfen",
|
||||
"checksum": "Prüfsumme",
|
||||
"choose": "Wählen",
|
||||
"choose_matching_people_to_merge": "Wähle passende Personen zum Zusammenführen",
|
||||
"city": "Stadt",
|
||||
"cleanup_confirm_description": "Immich hat {count} Dateien (vor dem {date} erstellt) sicher auf dem Server gefunden. Sollen die lokalen Kopien von diesem Gerät gelöscht werden?",
|
||||
@@ -774,6 +801,7 @@
|
||||
"clear": "Leeren",
|
||||
"clear_all": "Alles leeren",
|
||||
"clear_all_recent_searches": "Alle letzten Suchvorgänge löschen",
|
||||
"clear_failed_count": "({count}) Löschungen fehlgeschlagen",
|
||||
"clear_file_cache": "Dateien-Cache leeren",
|
||||
"clear_message": "Nachrichten leeren",
|
||||
"clear_value": "Wert leeren",
|
||||
@@ -805,6 +833,7 @@
|
||||
"comments_are_disabled": "Kommentare sind deaktiviert",
|
||||
"common_create_new_album": "Neues Album erstellen",
|
||||
"completed": "Abgeschlossen",
|
||||
"configuration": "Konfiguration",
|
||||
"confirm": "Bestätigen",
|
||||
"confirm_admin_password": "Administrator Passwort bestätigen",
|
||||
"confirm_delete_face": "Bist du sicher, dass du das Gesicht von {name} aus der Datei entfernen willst?",
|
||||
@@ -819,6 +848,7 @@
|
||||
"contain": "Vollständig",
|
||||
"context": "Kontext",
|
||||
"continue": "Fortsetzen",
|
||||
"control_bottom_app_bar_add_tags": "Tags hinzufügen",
|
||||
"control_bottom_app_bar_create_new_album": "Neues Album erstellen",
|
||||
"control_bottom_app_bar_delete_from_immich": "Aus Immich löschen",
|
||||
"control_bottom_app_bar_delete_from_local": "Vom Gerät löschen",
|
||||
@@ -832,6 +862,7 @@
|
||||
"copy_error": "Kopier-Fehler",
|
||||
"copy_file_path": "Dateipfad kopieren",
|
||||
"copy_image": "Bild kopieren",
|
||||
"copy_json": "JSON kopieren",
|
||||
"copy_link": "Link kopieren",
|
||||
"copy_link_to_clipboard": "Link in die Zwischenablage kopieren",
|
||||
"copy_password": "Passwort kopieren",
|
||||
@@ -881,22 +912,23 @@
|
||||
"cutoff_date_description": "Behalte Fotos der letzten…",
|
||||
"cutoff_day": "{count, plural, one {Tag} other {Tage}}",
|
||||
"cutoff_year": "{count, plural, one {Jahr} other {Jahre}}",
|
||||
"daily_title_text_date": "E, dd MMM",
|
||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||
"dark": "Dunkel",
|
||||
"dark_theme": "Auf dunkle Ansicht umschalten",
|
||||
"date": "Datum",
|
||||
"date_after": "Datum nach",
|
||||
"date_and_time": "Datum und Zeit",
|
||||
"date_before": "Datum vor",
|
||||
"date_format": "E d. LLL y • hh:mm",
|
||||
"date_of_birth_saved": "Das Geburtsdatum wurde erfolgreich gespeichert",
|
||||
"date_of_birth": "Geburtstag",
|
||||
"date_of_birth_saved": "Der Geburtstag wurde erfolgreich gespeichert",
|
||||
"date_range": "Datumsbereich",
|
||||
"date_time_original": "Datum/Uhrzeit Original",
|
||||
"day": "Tag",
|
||||
"days": "Tage",
|
||||
"deduplicate_all": "Alle Duplikate entfernen",
|
||||
"default_locale": "Standardgebietsschema",
|
||||
"default_locale_description": "Datumsangaben und Zahlen werden entsprechend Ihrer Browsereinstellungen formatiert",
|
||||
"default_quality_subtitle": "Die beim Teilen verwendete Qualität. Halten Sie die Teilen-Taste gedrückt, um die Auswahl jedes Mal neu zu treffen.",
|
||||
"default_share_quality": "Standardqualität beim Teilen",
|
||||
"delete": "Löschen",
|
||||
"delete_action_confirmation_message": "Bist du sicher, dass du dieses Objekt löschen willst? Diese Aktion wird das Objekt in den Papierkorb des Servers verschieben und fragen, ob du es lokal löschen willst",
|
||||
"delete_action_prompt": "{count} gelöscht",
|
||||
@@ -970,7 +1002,10 @@
|
||||
"downloading_asset_filename": "Datei {filename} wird heruntergeladen",
|
||||
"downloading_from_icloud": "von iCloud herunterladen",
|
||||
"downloading_media": "Medien werden heruntergeladen",
|
||||
"drag_to_reorder": "Ziehen um Reihenfolge zu ändern",
|
||||
"drop_files_to_upload": "Lade Dateien hoch, indem du sie hierhin ziehst",
|
||||
"duplicate": "Duplikat",
|
||||
"duplicate_workflow": "Workflow duplizieren",
|
||||
"duplicates": "Duplikate",
|
||||
"duplicates_description": "Löse jede Gruppe auf, indem du angibst, welche, wenn überhaupt, Duplikate sind.",
|
||||
"duration": "Dauer",
|
||||
@@ -1072,6 +1107,7 @@
|
||||
"failed_to_remove_product_key": "Fehler beim Entfernen des Produktschlüssels",
|
||||
"failed_to_reset_pin_code": "Zurücksetzen des PIN-Codes fehlgeschlagen",
|
||||
"failed_to_stack_assets": "Dateien konnten nicht gestapelt werden",
|
||||
"failed_to_tag_assets": "Dateien konnten nicht getaggt werden",
|
||||
"failed_to_unstack_assets": "Dateien konnten nicht entstapelt werden",
|
||||
"failed_to_update_notification_status": "Benachrichtigungsstatus aktualisieren fehlgeschlagen",
|
||||
"incorrect_email_or_password": "Ungültige E-Mail oder Passwort",
|
||||
@@ -1167,7 +1203,7 @@
|
||||
},
|
||||
"errors_text": "Fehler",
|
||||
"exclusion_pattern": "Ausschlussmuster",
|
||||
"exif": "EXIF",
|
||||
"exif": "Exif",
|
||||
"exif_bottom_sheet_description": "Beschreibung hinzufügen...",
|
||||
"exif_bottom_sheet_description_error": "Fehler bei der Aktualisierung der Beschreibung",
|
||||
"exif_bottom_sheet_details": "DETAILS",
|
||||
@@ -1191,15 +1227,18 @@
|
||||
"export_as_json": "Als JSON exportieren",
|
||||
"export_database": "Datenbank exportieren",
|
||||
"export_database_description": "Exportiert die SQLite Datenbank",
|
||||
"exposure_time": "Belichtungszeit",
|
||||
"extension": "Erweiterung",
|
||||
"external": "Extern",
|
||||
"external_libraries": "Externe Bibliotheken",
|
||||
"external_network": "Externes Netzwerk",
|
||||
"external_network_sheet_info": "Wenn sich die App nicht im bevorzugten WLAN-Netzwerk befindet, verbindet sie sich mit dem Server über die erste der folgenden URLs, die sie erreichen kann (von oben nach unten)",
|
||||
"f_number": "F-Nummer",
|
||||
"face_unassigned": "Nicht zugewiesen",
|
||||
"failed": "Fehlgeschlagen",
|
||||
"failed_count": "Fehlgeschlagen: {count}",
|
||||
"failed_to_authenticate": "Authentifizierung fehlgeschlagen",
|
||||
"failed_to_delete_file": "Löschen der Datei fehlgeschlagen",
|
||||
"failed_to_load_assets": "Laden der Assets fehlgeschlagen",
|
||||
"failed_to_load_folder": "Fehler beim Laden des Ordners",
|
||||
"favorite": "Favorit",
|
||||
@@ -1213,7 +1252,6 @@
|
||||
"features_setting_description": "Funktionen der App verwalten",
|
||||
"file_name_or_extension": "Dateiname oder -erweiterung",
|
||||
"file_name_text": "Dateiname",
|
||||
"file_name_with_value": "Dateiname: {file_name}",
|
||||
"file_size": "Dateigröße",
|
||||
"filename": "Dateiname",
|
||||
"filetype": "Dateityp",
|
||||
@@ -1226,6 +1264,7 @@
|
||||
"find_them_fast": "Finde sie schneller mit der Suche nach Namen",
|
||||
"first": "Erste",
|
||||
"fix_incorrect_match": "Fehlerhafte Übereinstimmung beheben",
|
||||
"focal_length": "Brennweite",
|
||||
"folder": "Ordner",
|
||||
"folder_not_found": "Ordner nicht gefunden",
|
||||
"folders": "Ordner",
|
||||
@@ -1236,6 +1275,7 @@
|
||||
"free_up_space_description": "Bewege Fotos und Videos, die bereits gesichert wurden, in den Papierkorb auf deinem Gerät. Die Kopie auf dem Server bleibt unberührt.",
|
||||
"free_up_space_settings_subtitle": "Gerätespeicher freigeben",
|
||||
"full_path": "Vollständiger Pfad: {path}",
|
||||
"full_path_or_folder": "Voller Ordnerpfad oder Ordner",
|
||||
"gcast_enabled": "Google Cast",
|
||||
"gcast_enabled_description": "Diese Funktion lädt externe Quellen von Google, um zu funktionieren.",
|
||||
"general": "Allgemein",
|
||||
@@ -1329,6 +1369,7 @@
|
||||
"individual_share": "Individuelle Freigabe",
|
||||
"individual_shares": "Individuelles Teilen",
|
||||
"info": "Info",
|
||||
"integrity_checks": "Integritätsprüfungen",
|
||||
"interval": {
|
||||
"day_at_onepm": "Täglich um 13:00 Uhr",
|
||||
"hours": "{hours, plural, one {Jede Stunde} other {Alle {hours, number} Stunden}}",
|
||||
@@ -1345,6 +1386,7 @@
|
||||
"ios_debug_info_no_sync_yet": "Noch kein Hintergrundsynchronisierungsauftrag ausgeführt",
|
||||
"ios_debug_info_processes_queued": "{count, plural, one {{count} Hintergrundprozess in der Warteschlange} other {{count} Hintergrundprozesse in der Warteschlange}}",
|
||||
"ios_debug_info_processing_ran_at": "Prozess läuft {dateTime}",
|
||||
"iso": "ISO",
|
||||
"items_count": "{count, plural, one {# Eintrag} other {# Einträge}}",
|
||||
"jobs": "Aufgaben",
|
||||
"json_editor": "JSON-Editor",
|
||||
@@ -1370,11 +1412,12 @@
|
||||
"last": "Letzte",
|
||||
"last_months": "{count, plural, one {Letzter Monat} other {Letzte # Monate}}",
|
||||
"last_seen": "Zuletzt gesehen",
|
||||
"latest_version": "Aktuelle Version",
|
||||
"latest_version": "Neuste Version",
|
||||
"latitude": "Breitengrad",
|
||||
"leave": "Verlassen",
|
||||
"leave_album": "Album verlassen",
|
||||
"lens_model": "Objektivmodell",
|
||||
"less": "Weniger",
|
||||
"let_others_respond": "Antworten zulassen",
|
||||
"level": "Level",
|
||||
"library": "Bibliothek",
|
||||
@@ -1392,11 +1435,14 @@
|
||||
"light_theme": "Auf helle Ansicht umschalten",
|
||||
"like": "Gefällt mir",
|
||||
"like_deleted": "Like gelöscht",
|
||||
"link": "Link",
|
||||
"link_motion_video": "Bewegungsvideo verknüpfen",
|
||||
"link_to_docs": "Weitere Informationen finden Sie in der <link>Dokumentation</link>.",
|
||||
"link_to_oauth": "Mit OAuth verknüpfen",
|
||||
"linked_oauth_account": "Verknüpftes OAuth-Konto",
|
||||
"list": "Liste",
|
||||
"live": "Live",
|
||||
"load_more": "Weitere laden",
|
||||
"loading": "Laden",
|
||||
"loading_search_results_failed": "Laden von Suchergebnissen fehlgeschlagen",
|
||||
"local": "Lokal",
|
||||
@@ -1494,7 +1540,7 @@
|
||||
"map_assets_in_bounds": "{count, plural, =0 {Keine Fotos in diesem Gebiet} one {# Foto} other {# Fotos}}",
|
||||
"map_cannot_get_user_location": "Standort konnte nicht ermittelt werden",
|
||||
"map_location_dialog_yes": "Ja",
|
||||
"map_location_picker_page_use_location": "Aufnahmeort verwenden",
|
||||
"map_location_picker_page_use_location": "Diesen Standort verwenden",
|
||||
"map_location_service_disabled_content": "Ortungsdienste müssen aktiviert sein, um Inhalte am aktuellen Standort anzuzeigen. Willst du die Ortungsdienste jetzt aktivieren?",
|
||||
"map_location_service_disabled_title": "Ortungsdienste deaktiviert",
|
||||
"map_marker_for_images": "Kartenmarkierung für Bilder, die in {city}, {country} aufgenommen wurden",
|
||||
@@ -1518,6 +1564,38 @@
|
||||
"marked_all_as_read": "Alle als gelesen markiert",
|
||||
"matches": "Treffer",
|
||||
"matching_assets": "Passende Dateien",
|
||||
"media_chrome": {
|
||||
"auto": "Auto",
|
||||
"captions": "Untertitel",
|
||||
"captions_off": "Aus",
|
||||
"closed_captions": "Untertitel",
|
||||
"decode_error": "Dekodierungsfehler",
|
||||
"disable_captions": "Untertitel deaktivieren",
|
||||
"enable_captions": "Untertitel aktivieren",
|
||||
"enter_fullscreen_mode": "Vollbildmodus aktivieren",
|
||||
"exit_fullscreen_mode": "Vollbildmodus beenden",
|
||||
"loop": "Endlosschleife",
|
||||
"media_error_description": "Ein Medienfehler hat die Wiedergabe abgebrochen. Das Medium könnte beschädigt sein oder Ihr Browser unterstützt dieses Format nicht.",
|
||||
"media_loading": "Medien werden geladen",
|
||||
"mute": "Stumm schalten",
|
||||
"network_error": "Netzwerkfehler",
|
||||
"network_error_description": "Ein Netzwerkfehler hat dazu geführt, dass der Medien-Download fehlgeschlagen ist.",
|
||||
"not_supported_error": "Quelle nicht unterstützt",
|
||||
"playback_rate": "Wiedergabegeschwindigkeit",
|
||||
"playback_rate_current": "aktuelle Wiedergabegeschwindigkeit",
|
||||
"playback_rate_value": "Wiedergabegeschwindigkeit {playbackRate}",
|
||||
"playback_time": "Wiedergabezeit",
|
||||
"quality": "Qualität",
|
||||
"second": "Sekunde",
|
||||
"seconds": "Sekunden",
|
||||
"time_value_of_total_time": "{currentTime} von {totalTime}",
|
||||
"time_value_remaining": "{time} verbleibend",
|
||||
"unmute": "Stummschaltung aufheben",
|
||||
"unsupported_error_description": "Ein nicht unterstützter Fehler ist aufgetreten. Der Server oder das Netzwerk ist fehlgeschlagen, oder Ihr Browser unterstützt dieses Format nicht.",
|
||||
"video_not_loaded_unknown_time": "Video nicht geladen, unbekannte Zeit.",
|
||||
"video_player": "Videoplayer",
|
||||
"volume": "Lautstärke"
|
||||
},
|
||||
"media_type": "Medientyp",
|
||||
"memories": "Erinnerungen",
|
||||
"memories_all_caught_up": "Alles aufgeholt",
|
||||
@@ -1534,6 +1612,8 @@
|
||||
"merge_people_prompt": "Willst du diese Personen zusammenführen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"merge_people_successfully": "Personen erfolgreich zusammengeführt",
|
||||
"merged_people_count": "{count, plural, one {# Person} other {# Personen}} zusammengefügt",
|
||||
"minFaces": "Mindestanzahl Gesichter",
|
||||
"minFaces_description": "Die Mindestanzahl an erkannten Gesichtern, damit eine Person angezeigt wird",
|
||||
"minimize": "Minimieren",
|
||||
"minute": "Minute",
|
||||
"minutes": "Minuten",
|
||||
@@ -1541,11 +1621,12 @@
|
||||
"mirror_vertical": "Vertikal",
|
||||
"missing": "Fehlende",
|
||||
"mobile_app": "Mobile App",
|
||||
"mobile_app_download_onboarding_note": "Herunterladen der mobilen Begleiter-App über einen der folgenden Möglichkeiten",
|
||||
"mobile_app_download_onboarding_note": "Herunterladen der mobilen Begleiter-App über eine der folgenden Möglichkeiten",
|
||||
"model": "Modell",
|
||||
"modify_date": "Änderungsdatum",
|
||||
"month": "Monat",
|
||||
"monthly_title_text_date_format": "MMMM y",
|
||||
"more": "Mehr",
|
||||
"motion": "Bewegung",
|
||||
"move": "Verschieben",
|
||||
"move_down": "Nach unten",
|
||||
"move_off_locked_folder": "Aus dem gesperrten Ordner verschieben",
|
||||
@@ -1562,6 +1643,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "Der Aufnahmeort von schreibgeschützten Inhalten kann nicht verändert werden, überspringen",
|
||||
"mute_memories": "Erinnerungen stumm schalten",
|
||||
"my_albums": "Meine Alben",
|
||||
"my_immich_description": "Diese Seite als „Mein Immich“-Link kopieren",
|
||||
"my_immich_title": "Mein Immich-Link",
|
||||
"name": "Name",
|
||||
"name_or_nickname": "Name oder Nickname",
|
||||
"name_required": "Name ist erforderlich",
|
||||
@@ -1589,7 +1672,6 @@
|
||||
"next": "Weiter",
|
||||
"next_memory": "Nächste Erinnerung",
|
||||
"no": "Nein",
|
||||
"no_actions_added": "Noch keine Aktionen hinzugefügt",
|
||||
"no_albums_found": "Keine Alben gefunden",
|
||||
"no_albums_message": "Erstelle ein Album, um deine Fotos und Videos zu organisieren",
|
||||
"no_albums_with_name_yet": "Es sieht so aus, als hättest du noch keine Alben mit diesem Namen.",
|
||||
@@ -1603,10 +1685,9 @@
|
||||
"no_configuration_needed": "Keine Konfiguration benötigt",
|
||||
"no_devices": "Keine verwendeten Geräte",
|
||||
"no_duplicates_found": "Es wurden keine Duplikate gefunden.",
|
||||
"no_exif_info_available": "Keine EXIF-Informationen vorhanden",
|
||||
"no_exif_info_available": "Keine Exif-Informationen vorhanden",
|
||||
"no_explore_results_message": "Lade weitere Fotos hoch, um deine Sammlung zu erkunden.",
|
||||
"no_favorites_message": "Füge Favoriten hinzu, um deine besten Bilder und Videos schnell zu finden",
|
||||
"no_filters_added": "Noch keine Filter hinzugefügt",
|
||||
"no_libraries_message": "Eine externe Bibliothek erstellen, um deine Fotos und Videos anzusehen",
|
||||
"no_local_assets_found": "Keine lokale Datei mit dieser Prüfsumme gefunden",
|
||||
"no_location_set": "Kein Standort festgelegt",
|
||||
@@ -1619,6 +1700,7 @@
|
||||
"no_results": "Keine Ergebnisse",
|
||||
"no_results_description": "Versuche es mit einem Synonym oder einem allgemeineren Stichwort",
|
||||
"no_shared_albums_message": "Erstelle ein Album, um Fotos und Videos mit Personen in deinem Netzwerk zu teilen",
|
||||
"no_steps": "Noch keine Schritte hinzugefügt",
|
||||
"no_uploads_in_progress": "Kein Upload in Bearbeitung",
|
||||
"none": "Keine",
|
||||
"not_allowed": "Nicht erlaubt",
|
||||
@@ -1627,6 +1709,7 @@
|
||||
"not_selected": "Nicht ausgewählt",
|
||||
"notes": "Hinweise",
|
||||
"nothing_here_yet": "Noch nichts hier",
|
||||
"notification_backup_reliability": "Benachrichtigungen aktivieren, um die Zuverlässigkeit der Sicherung im Hintergrund zu verbessern",
|
||||
"notification_permission_dialog_content": "Um Benachrichtigungen zu aktivieren, navigiere zu Einstellungen und klicke \"Erlauben\".",
|
||||
"notification_permission_list_tile_content": "Erlaube Berechtigung für Benachrichtigungen.",
|
||||
"notification_permission_list_tile_enable_button": "Aktiviere Benachrichtigungen",
|
||||
@@ -1664,6 +1747,7 @@
|
||||
"organize_into_albums": "In Alben organisieren",
|
||||
"organize_into_albums_description": "Aktuelle Synchronisationseinstellungen verwenden, um existierende Fotos in Alben zu laden",
|
||||
"organize_your_library": "Organisiere deine Bibliothek",
|
||||
"orientation": "Orientierung",
|
||||
"original": "Original",
|
||||
"other": "Sonstiges",
|
||||
"other_devices": "Andere Geräte",
|
||||
@@ -1749,12 +1833,14 @@
|
||||
"places_count": "{count, plural, one {{count, number} Ort} other {{count, number} Orte}}",
|
||||
"play": "Abspielen",
|
||||
"play_memories": "Erinnerungen abspielen",
|
||||
"play_motion_photo": "Bewegte Bilder abspielen",
|
||||
"play_motion_photo": "Live-Foto abspielen",
|
||||
"play_or_pause_video": "Video abspielen oder pausieren",
|
||||
"play_original_video": "Originales Video abspielen",
|
||||
"play_original_video_setting_description": "Bevorzugen die Wiedergabe von Originalvideos gegenüber transkodierten Videos. Wenn das Original nicht kompatibel ist, wird es möglicherweise nicht korrekt wiedergegeben.",
|
||||
"play_transcoded_video": "Transkodiertes Video abspielen",
|
||||
"please_auth_to_access": "Für den Zugriff bitte Authentifizieren",
|
||||
"plugin_method_filter_type": "Filter",
|
||||
"plugin_method_filter_type_description": "Mit dieser Methode lassen sich Ereignisse filtern und die Ausführung nachfolgender Schritte bedingt verhindern",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "App-Einstellungen verwalten",
|
||||
"preferences_settings_title": "Voreinstellungen",
|
||||
@@ -1776,6 +1862,7 @@
|
||||
"profile_drawer_readonly_mode": "Schreibgeschützter Modus aktiviert. Halte das Benutzer-Avatar-Symbol gedrückt, um den Modus zu verlassen.",
|
||||
"profile_image_of_user": "Profilbild von {user}",
|
||||
"profile_picture_set": "Profilbild gesetzt.",
|
||||
"projection_type": "Projektionstyp",
|
||||
"public_album": "Öffentliches Album",
|
||||
"public_share": "Öffentliche Freigabe",
|
||||
"purchase_account_info": "Unterstützer",
|
||||
@@ -1853,6 +1940,7 @@
|
||||
"remove_assets_title": "Dateien entfernen?",
|
||||
"remove_custom_date_range": "Benutzerdefinierten Datumsbereich entfernen",
|
||||
"remove_deleted_assets": "Offline-Dateien entfernen",
|
||||
"remove_filter": "Filter entfernen",
|
||||
"remove_from_album": "Aus Album entfernen",
|
||||
"remove_from_album_action_prompt": "{count} vom Album entfernt",
|
||||
"remove_from_favorites": "Aus Favoriten entfernen",
|
||||
@@ -1926,6 +2014,8 @@
|
||||
"scan_settings": "Scan-Einstellungen",
|
||||
"scanning": "Scanne",
|
||||
"scanning_for_album": "Nach Alben scannen...",
|
||||
"screencast_mode_description": "Tastatur- und Mausereignisindikatoren auf dem Bildschirm anzeigen",
|
||||
"screencast_mode_title": "Bildschirmübertragungsmodus umschalten",
|
||||
"search": "Suche",
|
||||
"search_albums": "Album suchen",
|
||||
"search_by_context": "Suche nach Kontext",
|
||||
@@ -1933,6 +2023,8 @@
|
||||
"search_by_description_example": "Wandern in Sapa",
|
||||
"search_by_filename": "Suche nach Dateiname oder -erweiterung",
|
||||
"search_by_filename_example": "z.B. IMG_1234.JPG oder PNG",
|
||||
"search_by_full_path": "Suchen nach Ordnerpfad oder Ordner",
|
||||
"search_by_full_path_example": "/John/Projects/3D_Printing/2026-07-01 - Sie können nach Projekten, 3D, Drucken, 2026 usw. suchen.",
|
||||
"search_by_ocr": "Suche per OCR",
|
||||
"search_by_ocr_example": "Latte",
|
||||
"search_camera_lens_model": "Suche nach Kameralinse...",
|
||||
@@ -2009,6 +2101,7 @@
|
||||
"select_person": "Person auswählen",
|
||||
"select_person_to_tag": "Wählen Sie eine Person zum Markieren aus",
|
||||
"select_photos": "Fotos auswählen",
|
||||
"select_quality": "Qualität auswählen",
|
||||
"select_trash_all": "Alle löschen",
|
||||
"select_user_for_sharing_page_err_album": "Album konnte nicht erstellt werden",
|
||||
"selected": "Ausgewählt",
|
||||
@@ -2072,6 +2165,8 @@
|
||||
"share_assets_selected": "{count} ausgewählt",
|
||||
"share_dialog_preparing": "Vorbereiten...",
|
||||
"share_link": "Link teilen",
|
||||
"share_original": "Original verwenden (groß)",
|
||||
"share_preview": "Verwenden Sie Thumbnail (klein)",
|
||||
"shared": "Geteilt",
|
||||
"shared_album_activities_input_disable": "Kommentare sind deaktiviert",
|
||||
"shared_album_activity_remove_content": "Möchtest du diese Aktivität entfernen?",
|
||||
@@ -2140,7 +2235,9 @@
|
||||
"show_in_timeline": "In Zeitleiste anzeigen",
|
||||
"show_in_timeline_setting_description": "Fotos und Videos dieses Benutzers in deiner Zeitleiste anzeigen",
|
||||
"show_keyboard_shortcuts": "Tastaturkürzel anzeigen",
|
||||
"show_less": "Weniger zeigen",
|
||||
"show_metadata": "Metadaten anzeigen",
|
||||
"show_more_fields": "{count, plural, one {Zeige # weiteres Feld} other {Zeige # weitere Felder}}",
|
||||
"show_or_hide_info": "Informationen ein- oder ausblenden",
|
||||
"show_password": "Passwort anzeigen",
|
||||
"show_person_options": "Personen-Optionen anzeigen",
|
||||
@@ -2148,6 +2245,7 @@
|
||||
"show_schema": "Schema anzeigen",
|
||||
"show_search_options": "Suchoptionen anzeigen",
|
||||
"show_shared_links": "Zeige geteilte Links",
|
||||
"show_slideshow_metadata_overlay": "Bildinformationen anzeigen",
|
||||
"show_slideshow_transition": "Slideshow-Übergang anzeigen",
|
||||
"show_supporter_badge": "Unterstützerabzeichen",
|
||||
"show_supporter_badge_description": "Zeige Unterstützerabzeichen",
|
||||
@@ -2163,13 +2261,18 @@
|
||||
"skip_to_folders": "Springe zu Ordnern",
|
||||
"skip_to_tags": "Springe zu Tags",
|
||||
"slideshow": "Diashow",
|
||||
"slideshow_metadata_overlay_mode": "Overlay Inhalt",
|
||||
"slideshow_metadata_overlay_mode_description_only": "Nur Beschreibung",
|
||||
"slideshow_metadata_overlay_mode_full": "Alles",
|
||||
"slideshow_repeat": "Slideshow wiederholen",
|
||||
"slideshow_repeat_description": "Wenn Slideshow beendet, zum Anfang zurückkehren",
|
||||
"slideshow_settings": "Diashow-Einstellungen",
|
||||
"smart_album": "Smart Album",
|
||||
"some_assets_already_have_a_location_warning": "Einige der ausgewählten Dateien haben bereits einen Standort",
|
||||
"sort_albums_by": "Alben sortieren nach...",
|
||||
"sort_created": "Erstellungsdatum",
|
||||
"sort_items": "Anzahl der Einträge",
|
||||
"sort_modified": "Änderungsdatum",
|
||||
"sort_modified": "Datum geändert",
|
||||
"sort_newest": "Neuestes Foto",
|
||||
"sort_oldest": "Ältestes Foto",
|
||||
"sort_people_by_similarity": "Personen nach Ähnlichkeit sortieren",
|
||||
@@ -2188,8 +2291,13 @@
|
||||
"start_date_before_end_date": "Anfangsdatum muss vor dem Enddatum liegen",
|
||||
"state": "Bundesland / Provinz",
|
||||
"status": "Status",
|
||||
"step_delete": "Schritt löschen",
|
||||
"step_delete_confirm": "Möchten Sie diesen Schritt wirklich löschen?",
|
||||
"step_details": "Details zum Schritt",
|
||||
"steps": "Schritte",
|
||||
"steps_count": "{count, plural, one {# Schritt} other {# Schritte}}",
|
||||
"stop_casting": "Übertragung stoppen",
|
||||
"stop_motion_photo": "Stop-Motion-Foto",
|
||||
"stop_motion_photo": "Live-Foto stoppen",
|
||||
"stop_photo_sharing": "Deine Fotos nicht mehr teilen?",
|
||||
"stop_photo_sharing_description": "{partner} wird keinen Zugriff mehr auf deine Fotos haben.",
|
||||
"stop_sharing_photos_with_user": "Aufhören Fotos mit diesem Benutzer zu teilen",
|
||||
@@ -2214,6 +2322,8 @@
|
||||
"sync_status": "Synchronisierungstatus",
|
||||
"sync_status_subtitle": "Synchronisierungssystem anzeigen und bearbeiten",
|
||||
"sync_upload_album_setting_subtitle": "Erstelle und lade deine ausgewählten Fotos und Videos in die ausgewählten Alben auf Immich hoch",
|
||||
"system_theme": "Systemthema",
|
||||
"system_theme_command_description": "Systemdesign verwenden ({value})",
|
||||
"tag": "Tag",
|
||||
"tag_assets": "Dateien taggen",
|
||||
"tag_created": "Tag erstellt: {tag}",
|
||||
@@ -2279,7 +2389,9 @@
|
||||
"trash_page_title": "Papierkorb ({count})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "Objekte im Papierkorb werden nach {days, plural, one {# Tag} other {# Tagen}} endgültig gelöscht.",
|
||||
"trigger": "Auslöser",
|
||||
"trigger_asset_uploaded": "Datei hochgeladen",
|
||||
"trigger_asset_metadata_extraction": "Extraktion von Asset-Metadaten",
|
||||
"trigger_asset_metadata_extraction_description": "Wird ausgelöst, wenn die EXIF-Daten eines Assets extrahiert werden",
|
||||
"trigger_asset_uploaded": "Datei hochladen",
|
||||
"trigger_asset_uploaded_description": "Löst aus, wenn eine neue Datei hochgeladen wurde",
|
||||
"trigger_description": "Ein Ereignis, das den Workflow startet",
|
||||
"trigger_person_recognized": "Person erkannt",
|
||||
@@ -2319,7 +2431,6 @@
|
||||
"unsupported_field_type": "Nicht unterstützter Feldtyp",
|
||||
"unsupported_file_type": "Die Datei {file} kann nicht hochgeladen werden, da der Dateityp {type} nicht unterstützt wird.",
|
||||
"untagged": "Ohne Tag",
|
||||
"untitled_workflow": "Unbenannter Workflow",
|
||||
"up_next": "Weiter",
|
||||
"update_location_action_prompt": "Aktualisiere den Ort von {count} ausgewählten Dateien mit:",
|
||||
"updated_at": "Aktualisiert",
|
||||
@@ -2341,6 +2452,7 @@
|
||||
"upload_to_immich": "Auf Immich hochladen ({count})",
|
||||
"uploading": "Wird hochgeladen",
|
||||
"uploading_media": "Medien werden hochgeladen",
|
||||
"uploads": "Uploads",
|
||||
"url": "URL",
|
||||
"usage": "Verwendung",
|
||||
"use_biometric": "Biometrie verwenden",
|
||||
@@ -2348,6 +2460,7 @@
|
||||
"use_browser_locale_description": "Datum, Uhrzeit und Zahlen werden entsprechend den Einstellungen Ihres Browsers formatiert",
|
||||
"use_current_connection": "Aktuelle Verbindung verwenden",
|
||||
"use_custom_date_range": "Stattdessen einen benutzerdefinierten Datumsbereich verwenden",
|
||||
"use_template": "Vorlage verwenden",
|
||||
"user": "Nutzer",
|
||||
"user_has_been_deleted": "Dieser Benutzer wurde gelöscht.",
|
||||
"user_id": "Nutzer-ID",
|
||||
@@ -2377,6 +2490,7 @@
|
||||
"video": "Video",
|
||||
"video_hover_setting": "Videovorschau beim Hovern abspielen",
|
||||
"video_hover_setting_description": "Spiele die Miniaturansicht des Videos ab, wenn sich die Maus über dem Element befindet. Auch wenn die Funktion deaktiviert ist, kann die Wiedergabe gestartet werden, indem du mit der Maus über das Wiedergabesymbol fährst.",
|
||||
"video_quality": "Videoqualität",
|
||||
"videos": "Videos",
|
||||
"videos_count": "{count, plural, one {# Video} other {# Videos}}",
|
||||
"videos_only": "Nur Videos",
|
||||
@@ -2409,8 +2523,10 @@
|
||||
"week": "Woche",
|
||||
"welcome": "Willkommen",
|
||||
"welcome_to_immich": "Willkommen bei Immich",
|
||||
"when": "Wann",
|
||||
"width": "Breite",
|
||||
"wifi_name": "WLAN-Netzwerk",
|
||||
"workflow": "Workflow",
|
||||
"workflow_delete_prompt": "Bist du sicher, dass du diesen Workflow löschen willst?",
|
||||
"workflow_deleted": "Workflow gelöscht",
|
||||
"workflow_description": "Workflow-Beschreibung",
|
||||
@@ -2420,11 +2536,13 @@
|
||||
"workflow_name": "Workflow-Name",
|
||||
"workflow_navigation_prompt": "Bist du sicher, dass du den Editor ohne zu speichern verlassen willst?",
|
||||
"workflow_summary": "Workflow-Zusammenfassung",
|
||||
"workflow_templates": "Vorlagen für Workflows",
|
||||
"workflow_update_success": "Workflow erfolgreich aktualisiert",
|
||||
"workflow_updated": "Workflow aktualisiert",
|
||||
"workflows": "Workflows",
|
||||
"workflows_help_text": "Workflows automatisieren Aktionen auf deinen Dateien, basierend auf Auslösern und Filtern",
|
||||
"wrong_pin_code": "PIN-Code falsch",
|
||||
"x_of_total": "{x}/{total}",
|
||||
"year": "Jahr",
|
||||
"years_ago": "Vor {years, plural, one {einem Jahr} other {# Jahren}}",
|
||||
"yes": "Ja",
|
||||
|
||||
+64
-19
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"about": "Über",
|
||||
"account": "Konto",
|
||||
"account_settings": "Konto Einstellungen",
|
||||
"account_settings": "Kontoistellige",
|
||||
"acknowledge": "Bestätigä",
|
||||
"action": "Aktion",
|
||||
"action_common_update": "Update",
|
||||
"action_description": "Aktionä, wo uf de gefilterti Mediä ausgführt werdä solled",
|
||||
"actions": "Aktionen",
|
||||
"action_description": "Aktionä, wo uf de gfilterte Medie usgführt wärde sölled",
|
||||
"actions": "Aktionä",
|
||||
"active": "Aktiv",
|
||||
"active_count": "Aktiv: {count}",
|
||||
"activity": "Aktivität",
|
||||
"activity_changed": "Aktivität ist {enabled, select, true {aktiviert} other {deaktiviert}}",
|
||||
"add": "Hinzuefüge",
|
||||
"add_a_description": "Beschreibung hinzufügen",
|
||||
"add_a_location": "Standort hinzuefügä",
|
||||
"add_a_description": "Beschribig afüege",
|
||||
"add_a_location": "Standort afüege",
|
||||
"add_a_name": "Namä hinzefügä",
|
||||
"add_a_title": "Titel hinzufeügä",
|
||||
"add_action": "Aktion hinzuefügä",
|
||||
@@ -22,13 +22,12 @@
|
||||
"add_birthday": "Geburtstag hinzuefüge",
|
||||
"add_endpoint": "Endpunkt hinzuefüge",
|
||||
"add_exclusion_pattern": "Ausschlussmuster hinzufügen",
|
||||
"add_filter": "Filter hinzufügen",
|
||||
"add_filter_description": "Klicke hier um eine Filterbedingung hinzuzufügen",
|
||||
"add_location": "Standort hinzufügen",
|
||||
"add_more_users": "Mehr Benutzer hinzufügen",
|
||||
"add_partner": "Partner hinzufügen",
|
||||
"add_path": "Pfad hinzufügen",
|
||||
"add_photos": "Fotos hinzufügen",
|
||||
"add_step": "Schritt hinzuefüege",
|
||||
"add_tag": "Tag hinzufügen",
|
||||
"add_to": "Hinzufügen zu…",
|
||||
"add_to_album": "Zu Album hinzufügen",
|
||||
@@ -38,11 +37,10 @@
|
||||
"add_to_album_toggle": "Auswahl umschalten für {album}",
|
||||
"add_to_albums": "Zu Alben hinzufügen",
|
||||
"add_to_albums_count": "Zu Alben hinzufügen ({count})",
|
||||
"add_to_bottom_bar": "Hinzufügen zu",
|
||||
"add_to_bottom_bar": "Däzuefüege zu",
|
||||
"add_to_shared_album": "Zu geteiltem Album hinzufügen",
|
||||
"add_upload_to_stack": "Upload zum Stapel hinzufügen",
|
||||
"add_url": "URL hinzufügen",
|
||||
"add_workflow_step": "Workflow-Schritt hinzufügen",
|
||||
"add_url": "URL däzuefüege",
|
||||
"added_to_archive": "Zum Archiv hinzugefügt",
|
||||
"added_to_favorites": "Zu Favoriten hinzugefügt",
|
||||
"added_to_favorites_count": "{count, number} zu Favoriten hinzugefügt",
|
||||
@@ -54,7 +52,7 @@
|
||||
"authentication_settings_description": "Passwort-, OAuth- und andere Authentifizierungseinstellungen verwalten",
|
||||
"authentication_settings_disable_all": "Bist du sicher, dass du alle Loginmethoden deaktivieren willst? Die Anmeldung wird vollständig deaktiviert.",
|
||||
"authentication_settings_reenable": "Nutze einen <link>Server-Befehl</link> zur Reaktivierung.",
|
||||
"background_task_job": "Hintergrundaufgaben",
|
||||
"background_task_job": "Hintergrundfarbä",
|
||||
"backup_database": "Datenbanksicherung erstellen",
|
||||
"backup_database_enable_description": "Datenbank regelmässig sichern",
|
||||
"backup_keep_last_amount": "Anzahl der aufzubewahrenden früheren Sicherungen",
|
||||
@@ -64,7 +62,7 @@
|
||||
"backup_onboarding_description": "Eine <backblaze-link>3-2-1 Sicherungsstrategie</backblaze-link> wird empfohlen, um deine Daten zu schützen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende Sicherungslösung zu haben.",
|
||||
"backup_onboarding_footer": "Weitere Informationen zum Sichern von Immich findest du in der <link>Dokumentation</link>.",
|
||||
"backup_onboarding_parts_title": "Eine 3-2-1-Sicherung umfasst:",
|
||||
"backup_onboarding_title": "Backups",
|
||||
"backup_onboarding_title": "Sicherige",
|
||||
"backup_settings": "Einstellungen für Datenbanksicherung",
|
||||
"backup_settings_description": "Einstellungen zur regelmässigen Sicherung der Datenbank.",
|
||||
"cleared_jobs": "Folgende Aufgaben zurückgesetzt: {job}",
|
||||
@@ -76,16 +74,16 @@
|
||||
"confirm_user_password_reset": "Bist du sicher, dass du das Passwort für {user} zurücksetzen möchtest?",
|
||||
"confirm_user_pin_code_reset": "Bist du sicher, dass du den PIN-Code von {user} zurücksetzen möchtest?",
|
||||
"copy_config_to_clipboard_description": "Aktuelle Systemkonfiguration als JSON-Objekt in die Zwischenablage kopieren",
|
||||
"create_job": "Aufgabe erstellen",
|
||||
"create_job": "Ufgab erstelle",
|
||||
"cron_expression": "Cron-Ausdruck",
|
||||
"cron_expression_description": "Setze das Scanintervall im Cron-Format. Für mehr Informationen, siehe z. B. <link>Crontab Guru</link>",
|
||||
"cron_expression_presets": "Vorlagen für Cron-Ausdrücke",
|
||||
"disable_login": "Login deaktivieren",
|
||||
"disable_login": "Login deaktivierä",
|
||||
"duplicate_detection_job_description": "Verwendet maschinelles Lernen auf den Dateien, um Duplikate zu finden. Baut auf der intelligenten Suche auf",
|
||||
"exclusion_pattern_description": "Mit Ausschlussmustern können Dateien und Ordner beim Scannen deiner Bibliothek ignoriert werden. Dies ist nützlich, wenn du Ordner hast, die Dateien enthalten, die du nicht importieren möchtest, wie z. B. RAW-Dateien.",
|
||||
"export_config_as_json_description": "Aktuelle Systemkonfiguration als JSON-Datei herunterladen",
|
||||
"external_libraries_page_description": "Externe Bibliotheksseite für Administratoren",
|
||||
"face_detection": "Gesichtserkennung",
|
||||
"face_detection": "Gsichtserkennig",
|
||||
"face_detection_description": "Diese Aufgabe erkennt mit maschinellem Lernen Gesichter in Dateien. Bei Videos wird nur das Vorschaubild verwendet. „Aktualisieren“ verarbeitet alle Dateien neu. „Zurücksetzen“ setzt zusätzlich alle Gesichter zurück. „Fehlende“ fügt nur nicht verarbeitete Dateien in die Warteschlange ein. Erfasste Gesichter werden zur Gesichtsidentifizierung in die Warteschlange eingefügt, um sie in bestehende oder neue Personen zu gruppieren.",
|
||||
"facial_recognition_job_description": "Diese Aufgabe gruppiert im Anschluss an die Gesichtserkennung die erkannten Gesichter zu Personen. „Zurücksetzen“ gruppiert alle Gesichter neu, während „Fehlende“ Gesichter ohne Zuordnung in die Warteschlange stellt.",
|
||||
"failed_job_command": "Befehl {command} ist für Aufgabe {job} fehlgeschlagen",
|
||||
@@ -99,7 +97,7 @@
|
||||
"image_fullsize_title": "Hochauflösende Vorschaueinstellungen",
|
||||
"image_prefer_embedded_preview": "Eingebettete Vorschau bevorzugen",
|
||||
"image_prefer_embedded_preview_setting_description": "Verwende eingebettete Vorschaubilder in RAW-Fotos als Grundlage für die Bildverarbeitung, sofern diese zur Verfügung stehen. Dies kann bei einigen Bildern genauere Farben erzeugen, allerdings ist die Qualität der Vorschau kameraabhängig und das Bild kann mehr Kompressionsartefakte aufweisen.",
|
||||
"image_prefer_wide_gamut": "Breites Spektrum bevorzugen",
|
||||
"image_prefer_wide_gamut": "weiterer Farbraum bevorzugen",
|
||||
"image_prefer_wide_gamut_setting_description": "Display P3 (DCI-P3) für Vorschaubilder verwenden. Dadurch bleibt die Lebendigkeit von Bildern mit breiten Farbräumen besser erhalten, aber die Bilder können auf älteren Geräten mit einer älteren Browserversion etwas anders aussehen. sRGB-Bilder werden im sRGB-Format belassen, um Farbverschiebungen zu vermeiden.",
|
||||
"image_preview_description": "Mittelgrosses Bild mit entfernten Metadaten, das bei der Betrachtung einer einzelnen Datei und für maschinelles Lernen verwendet wird",
|
||||
"image_preview_quality_description": "Vorschauqualität von 1-100. Ein höherer Wert ist besser, erzeugt dadurch aber grössere Dateien und kann die Reaktionsfähigkeit der App beeinträchtigen. Ein niedriger Wert kann dafür aber die Qualität des maschinellen Lernens beeinträchtigen.",
|
||||
@@ -107,7 +105,7 @@
|
||||
"image_progressive": "Fortlaufend",
|
||||
"image_progressive_description": "JPEG-Bilder schrittweise kodieren, um ein stufenweises Laden zu ermöglichen. Dies hat keine Auswirkungen auf WebP-Bilder.",
|
||||
"image_quality": "Qualität",
|
||||
"image_resolution": "Auflösung",
|
||||
"image_resolution": "Uflösig",
|
||||
"image_resolution_description": "Höhere Auflösungen können mehr Details erhalten, benötigen aber mehr Zeit für die Kodierung, haben grössere Dateigrössen und können die Reaktionsfähigkeit der App beeinträchtigen.",
|
||||
"image_settings": "Bildeinstellungen",
|
||||
"image_settings_description": "Qualität und Auflösung der generierten Bilder verwalten",
|
||||
@@ -120,6 +118,8 @@
|
||||
"job_not_concurrency_safe": "Diese Aufgabe kann nicht mehrmals parallel laufen gelassen werden.",
|
||||
"job_settings": "Aufgabeneinstellungen",
|
||||
"job_settings_description": "Gleichzeitige Ausführung von Aufgaben verwalten",
|
||||
"jobs_delayed": "Qualität",
|
||||
"jobs_failed": "{jobCount, plural, other {# failed}}",
|
||||
"jobs_over_time": "Jobs im Laufe der Zeit",
|
||||
"library_created": "Bibliothek erstellt: {library}",
|
||||
"library_deleted": "Bibliothek gelöscht",
|
||||
@@ -127,6 +127,51 @@
|
||||
"library_folder_description": "Wähle einen Ordner zum Importieren. Dieser Ordner wird inklusive Unterordnern nach Bildern und Videos durchsucht.",
|
||||
"library_remove_exclusion_pattern_prompt": "Bilst du sicher, dass du dieses Ausschlussmuster entfernen möchtest?",
|
||||
"library_remove_folder_prompt": "Bist du sicher, dass du diesen Import-Ordner entfernen möchtest?",
|
||||
"library_scanning": "Regelmässiges Scannen"
|
||||
}
|
||||
"library_scanning": "Regelmässiges Scannen",
|
||||
"library_scanning_description": "Regelmässiges Scannen der Bibliothek konfigurieren",
|
||||
"library_scanning_enable_description": "Regelmässiges Scannen der Bibliothek aktivieren",
|
||||
"library_settings": "Externe Bibliothek",
|
||||
"library_settings_description": "Einstellungen für externe Bibliotheken verwalten",
|
||||
"library_tasks_description": "Externe Bibliotheken nach neuen und/oder geänderten Assets durchsuchen",
|
||||
"library_updated": "Aktualisierte Bibliothek",
|
||||
"library_watching_enable_description": "Änderungen an Dateien in externen Bibliotheken überwachen",
|
||||
"library_watching_settings": "Bibliothek beobachten [EXPERIMENTELL]",
|
||||
"library_watching_settings_description": "Automatisch nach geänderten Dateien suchen",
|
||||
"logging_enable_description": "Logging aktivieren",
|
||||
"logging_level_description": "Wenn aktiviert, welches Logging-Level soll verwendet werden.",
|
||||
"logging_settings": "Logging",
|
||||
"machine_learning_availability_checks": "Verfügbarkeitsüberprüfungen",
|
||||
"machine_learning_availability_checks_description": "Verfügbare Machine-Learning-Server automatisch erkennen und bevorzugen",
|
||||
"machine_learning_availability_checks_enabled": "Verfügbarkeitsüberprüfungen aktivieren",
|
||||
"machine_learning_availability_checks_interval": "Überprüfungsintervall",
|
||||
"machine_learning_availability_checks_interval_description": "Intervall in Millisekunden zwischen Verfügbarkeitsüberprüfungen",
|
||||
"machine_learning_availability_checks_timeout": "Zeitüberschreitung der Anfrage",
|
||||
"machine_learning_availability_checks_timeout_description": "Timeout in Millisekunden für Verfügbarkeitsüberprüfungen",
|
||||
"machine_learning_clip_model": "CLIP Model",
|
||||
"machine_learning_clip_model_description": "Der Name eines der <link>hier</link> gelisteten CLIP-Modelle. Hinweis: Nach dem Ändern eines Modells muss der ‚Smart Search‘-Vorgang für alle Bilder erneut gestartet werden.",
|
||||
"machine_learning_duplicate_detection": "Duplikatserkennung",
|
||||
"machine_learning_duplicate_detection_enabled": "Duplikatserkennung aktivieren",
|
||||
"machine_learning_duplicate_detection_enabled_description": "Falls deaktiviert, werden exakt identische Assets weiterhin dedupliziert.",
|
||||
"machine_learning_duplicate_detection_setting_description": "Verwende CLIP embeddings um wahrscheinliche Dublikate zu finden",
|
||||
"machine_learning_enabled": "Maschinelles Lernen aktivieren",
|
||||
"machine_learning_enabled_description": "Falls deaktiviert, werden alle ML-Funktionen deaktiviert, unabhängig von den untenstehenden Einstellungen.",
|
||||
"machine_learning_facial_recognition": "Gesichtserkennung",
|
||||
"machine_learning_facial_recognition_description": "Gesichter in Bildern erkennen, identifizieren und gruppieren",
|
||||
"machine_learning_facial_recognition_model": "Model für die Gesichtserkennung",
|
||||
"machine_learning_facial_recognition_model_description": "Modell sind noch abstigender Grössi ufglitet. Grösseri Modell sind langsamer und bruched meh Arbeitsspeicher, aber produziered besseri Resultat. Gsichterkennig muss für alli Fotis neu usgfüehrt wärde, nochdem s Modell gwächslet worde esch.",
|
||||
"machine_learning_facial_recognition_setting": "Gsichtserkennig ischalte",
|
||||
"machine_learning_facial_recognition_setting_description": "Wenn usgschalte wärded Fotis ned für Gsichtserkennig enkodiert und wärded ned ide Personesektion uf de",
|
||||
"machine_learning_max_detection_distance": "Maximali Erkennigsdistanz",
|
||||
"machine_learning_max_detection_distance_description": "Maximali Distanz zwüsche zwei Bilder, um si als Duplikat z erkenne, zwische 0.001 - 0.1. Höcheri Wärt erkenned meh Duplikat, aber chönd Falschpositivi erzüge."
|
||||
},
|
||||
"video_quality": "Videoqualität",
|
||||
"videos": "Videos",
|
||||
"videos_only": "Nume Videos",
|
||||
"view": "Aasicht",
|
||||
"view_album": "Album aazeige",
|
||||
"view_all": "Alles aazeige",
|
||||
"view_all_users": "Alli Nutzer aazeige",
|
||||
"view_details": "Details aaluege",
|
||||
"view_link": "Link aazeige",
|
||||
"view_links": "Links aazeige"
|
||||
}
|
||||
|
||||
+11
-11
@@ -22,8 +22,6 @@
|
||||
"add_birthday": "Προσθήκη γενεθλίων",
|
||||
"add_endpoint": "Προσθήκη τελικού σημείου",
|
||||
"add_exclusion_pattern": "Προσθήκη μοτίβου αποκλεισμού",
|
||||
"add_filter": "Προσθήκη φίλτρου",
|
||||
"add_filter_description": "Κάντε κλικ για να προσθέσετε συνθήκη φίλτρου",
|
||||
"add_location": "Προσθήκη τοποθεσίας",
|
||||
"add_more_users": "Προσθήκη επιπλέον χρηστών",
|
||||
"add_partner": "Προσθήκη συνεργάτη",
|
||||
@@ -42,7 +40,6 @@
|
||||
"add_to_shared_album": "Προσθήκη σε κοινόχρηστο άλμπουμ",
|
||||
"add_upload_to_stack": "Προσθήκη αρχείου στην ουρά",
|
||||
"add_url": "Προσθήκη Συνδέσμου",
|
||||
"add_workflow_step": "Προσθήκη βήματος ροής εργασίας",
|
||||
"added_to_archive": "Προστέθηκε στο αρχείο",
|
||||
"added_to_favorites": "Προστέθηκε στα αγαπημένα",
|
||||
"added_to_favorites_count": "Προστέθηκαν {count, number} στα αγαπημένα",
|
||||
@@ -267,6 +264,8 @@
|
||||
"notification_enable_email_notifications": "Ενεργοποίηση ειδοποιήσεων μέσω email",
|
||||
"notification_settings": "Ρυθμίσεις ειδοποιήσεων",
|
||||
"notification_settings_description": "Διαχείρηση ρυθμίσεων ειδοποιήσεων, συμπεριλαμβανομένου του email",
|
||||
"oauth_allow_insecure_requests": "Να επιτρέπονται μη ασφαλή αιτήματα",
|
||||
"oauth_allow_insecure_requests_description": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Αυτό απενεργοποιεί την επαλήθευση πιστοποιητικών TLS για αιτήματα OAuth και μπορεί να σας εκθέσει σε επιθέσεις MITM.",
|
||||
"oauth_auto_launch": "Αυτόματη εκκίνηση",
|
||||
"oauth_auto_launch_description": "Αυτόματη εκκίνιση της υπηρεσίας OAuth με την πλοήγηση στην σελίδα σύνδεσης",
|
||||
"oauth_auto_register": "Αυτόματη καταχώρηση",
|
||||
@@ -274,9 +273,11 @@
|
||||
"oauth_button_text": "Κείμενο κουμπιού",
|
||||
"oauth_client_secret_description": "Απαιτείται για έμπιστο πρόγραμμα πελάτη ή αν δεν υποστηρίζεται PKCE (Proof Key for Code Exchange) σε δημόσιο πρόγραμμα πελάτη.",
|
||||
"oauth_enable_description": "Σύνδεση με OAuth",
|
||||
"oauth_end_session_url_description": "Ανακατεύθυνση του χρήστη σε αυτό το URI όταν αποσυνδέεται.",
|
||||
"oauth_mobile_redirect_uri": "URI Ανακατεύθυνσης για κινητά τηλέφωνα",
|
||||
"oauth_mobile_redirect_uri_override": "Προσπέλαση URI ανακατεύθυνσης για κινητά τηλέφωνα",
|
||||
"oauth_mobile_redirect_uri_override_description": "Ενεργοποιήστε το όταν ο πάροχος OAuth δεν επιτρέπει μια URI για κινητά, όπως το ''{callback}''",
|
||||
"oauth_prompt_description": "Παράμετρος προτροπής (π.χ. επιλογή_λογαριασμού, σύνδεση, συναίνεση)",
|
||||
"oauth_role_claim": "Ανάθεση ρόλου",
|
||||
"oauth_role_claim_description": "Αυτόματη παραχώρηση πρόσβασης διαχειριστή με βάση την ύπαρξη αυτής της ανάθεσης. Η ανάθεση μπορεί να είναι είτε 'χρήστης' είτε 'διαχειριστής'.",
|
||||
"oauth_settings": "OAuth",
|
||||
@@ -881,15 +882,12 @@
|
||||
"cutoff_date_description": "Διατήρηση φωτογραφιών από τις τελευταίες…",
|
||||
"cutoff_day": "{count, plural, one {ημέρα} other {ημέρες}}",
|
||||
"cutoff_year": "{count, plural, one {έτος} other {έτη}}",
|
||||
"daily_title_text_date": "Ε, MMM dd",
|
||||
"daily_title_text_date_year": "Ε, MMM dd, yyyy",
|
||||
"dark": "Σκούρο",
|
||||
"dark_theme": "Μετάβαση σε σκοτεινό θέμα",
|
||||
"date": "Ημερομηνία",
|
||||
"date_after": "Ημερομηνία μετά",
|
||||
"date_and_time": "Ημερομηνία και ώρα",
|
||||
"date_before": "Ημερομηνία πριν",
|
||||
"date_format": "Ε, LLL d, y • h:mm a",
|
||||
"date_of_birth_saved": "Η ημερομηνία γέννησης αποθηκεύτηκε επιτυχώς",
|
||||
"date_range": "Εύρος ημερομηνιών",
|
||||
"day": "Ημέρα",
|
||||
@@ -1213,7 +1211,6 @@
|
||||
"features_setting_description": "Διαχειριστείτε τα χαρακτηριστικά της εφαρμογής",
|
||||
"file_name_or_extension": "Όνομα αρχείου ή επέκταση",
|
||||
"file_name_text": "Όνομα αρχείου",
|
||||
"file_name_with_value": "Όνομα αρχείου: {file_name}",
|
||||
"file_size": "Μέγεθος αρχείου",
|
||||
"filename": "Ονομασία αρχείου",
|
||||
"filetype": "Τύπος αρχείου",
|
||||
@@ -1392,6 +1389,7 @@
|
||||
"light_theme": "Μετάβαση σε φωτεινό θέμα",
|
||||
"like": "Μου αρέσει",
|
||||
"like_deleted": "Το \"μου αρέσει\" διαγράφηκε",
|
||||
"link": "Σύνδεσμος",
|
||||
"link_motion_video": "Σύνδεσε βίντεο κίνησης",
|
||||
"link_to_docs": "Για περισσότερες πληροφορίες, ανατρέξτε στην <link>τεκμηρίωση</link>.",
|
||||
"link_to_oauth": "Σύνδεση στον OAuth",
|
||||
@@ -1544,7 +1542,6 @@
|
||||
"mobile_app_download_onboarding_note": "Κατέβασε την συνοδευτική εφαρμογή για κινητά χρησιμοποιώντας τις παρακάτω επιλογές",
|
||||
"model": "Μοντέλο",
|
||||
"month": "Μήνας",
|
||||
"monthly_title_text_date_format": "ΜΜΜΜ y",
|
||||
"more": "Περισσότερα",
|
||||
"move": "Μετακίνηση",
|
||||
"move_down": "Μετακίνηση προς τα κάτω",
|
||||
@@ -1562,6 +1559,8 @@
|
||||
"multiselect_grid_edit_gps_err_read_only": "Δεν είναι δυνατή η επεξεργασία της τοποθεσίας των στοιχείων μόνο για ανάγνωση, παραλείπεται",
|
||||
"mute_memories": "Σίγαση Αναμνήσεων",
|
||||
"my_albums": "Τα άλμπουμ μου",
|
||||
"my_immich_description": "Αντιγραφή της τρέχουσας σελίδας ως σύνδεσμος Το Immich μου",
|
||||
"my_immich_title": "Σύνδεσμος Το Immich μου",
|
||||
"name": "Όνομα",
|
||||
"name_or_nickname": "Όνομα ή ψευδώνυμο",
|
||||
"name_required": "Απαιτείται όνομα",
|
||||
@@ -1589,7 +1588,6 @@
|
||||
"next": "Επόμενο",
|
||||
"next_memory": "Επόμενη ανάμνηση",
|
||||
"no": "Όχι",
|
||||
"no_actions_added": "Δεν έχουν προστεθεί ακόμα ενέργειες",
|
||||
"no_albums_found": "Δεν βρέθηκαν άλμπουμ",
|
||||
"no_albums_message": "Δημιουργήστε ένα άλμπουμ για να οργανώσετε τις φωτογραφίες και τα βίντεό σας",
|
||||
"no_albums_with_name_yet": "Φαίνεται ότι δεν έχετε κανένα άλμπουμ με αυτό το όνομα ακόμα.",
|
||||
@@ -1606,7 +1604,6 @@
|
||||
"no_exif_info_available": "Καμία πληροφορία exif διαθέσιμη",
|
||||
"no_explore_results_message": "Ανεβάστε περισσότερες φωτογραφίες για να περιηγηθείτε στη συλλογή σας.",
|
||||
"no_favorites_message": "Προσθέστε αγαπημένα για να βρείτε γρήγορα τις καλύτερες φωτογραφίες και τα βίντεό σας",
|
||||
"no_filters_added": "Δεν έχουν προστεθεί ακόμα φίλτρα",
|
||||
"no_libraries_message": "Δημιουργήστε μια εξωτερική βιβλιοθήκη για να προβάλετε τις φωτογραφίες και τα βίντεό σας",
|
||||
"no_local_assets_found": "Δεν βρέθηκαν τοπικά στοιχεία με αυτό το checksum",
|
||||
"no_location_set": "Η τοποθεσία δεν έχει οριστεί",
|
||||
@@ -1926,6 +1923,8 @@
|
||||
"scan_settings": "Ρυθμίσεις Σάρωσης",
|
||||
"scanning": "Σαρώνεται",
|
||||
"scanning_for_album": "Σάρωση για άλμπουμ...",
|
||||
"screencast_mode_description": "Εμφάνιση ενδείξεων συμβάντων πληκτρολογίου και ποντικιού στην οθόνη",
|
||||
"screencast_mode_title": "Εναλλαγή λειτουργίας καταγραφής οθόνης",
|
||||
"search": "Αναζήτηση",
|
||||
"search_albums": "Αναζήτηση άλμπουμ",
|
||||
"search_by_context": "Αναζήτηση με βάση το πλαίσιο",
|
||||
@@ -2214,6 +2213,8 @@
|
||||
"sync_status": "Κατάσταση συγχρονισμού",
|
||||
"sync_status_subtitle": "Προβολή και διαχείριση του συστήματος συγχρονισμού",
|
||||
"sync_upload_album_setting_subtitle": "Δημιουργήστε και ανεβάστε τις φωτογραφίες και τα βίντεό σας στα επιλεγμένα άλμπουμ στο Immich",
|
||||
"system_theme": "Θέμα συστήματος",
|
||||
"system_theme_command_description": "Χρήση θέματος από το σύστημα ({value})",
|
||||
"tag": "Ετικέτα",
|
||||
"tag_assets": "Ετικετοποίηση στοιχείων",
|
||||
"tag_created": "Δημιουργήθηκε ετικέτα: {tag}",
|
||||
@@ -2319,7 +2320,6 @@
|
||||
"unsupported_field_type": "Μη υποστηριζόμενος τύπος πεδίου",
|
||||
"unsupported_file_type": "Το αρχείο {file} δεν μπορεί να μεταφορτωθεί επειδή ο τύπος αρχείου {type} δεν υποστηρίζεται.",
|
||||
"untagged": "Χωρίς ετικέτα",
|
||||
"untitled_workflow": "Νέα ροή εργασίας",
|
||||
"up_next": "Ακολουθεί",
|
||||
"update_location_action_prompt": "Ενημέρωση τοποθεσίας για {count} επιλεγμένα στοιχεία με:",
|
||||
"updated_at": "Ενημερωμένο",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user