Compare commits

..

1 Commits

Author SHA1 Message Date
Yaros
2db907239f fix: update ocr & faces after asset edit 2026-06-24 13:18:42 +02:00
787 changed files with 25054 additions and 33039 deletions

View File

@@ -83,7 +83,7 @@
}
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:4": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
// https://github.com/devcontainers/features/issues/1466
"moby": false
}

View File

@@ -15,7 +15,7 @@ jobs:
outputs:
uses_template: ${{ steps.check.outputs.uses_template }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
sparse-checkout: .github/pull_request_template.md
sparse-checkout-cone-mode: false

View File

@@ -51,11 +51,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -80,14 +79,12 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
permission-pull-requests: write
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ inputs.ref }}
persist-credentials: false
@@ -106,14 +103,14 @@ jobs:
working-directory: ./mobile
run: printf "%s" $KEY_JKS | base64 -d > android/key.jks
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
- uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0
with:
distribution: 'zulu'
java-version: '17'
- name: Restore Gradle Cache
id: cache-gradle-restore
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.gradle/caches
@@ -184,7 +181,7 @@ jobs:
- name: Save Gradle Cache
id: cache-gradle-save
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
if: github.ref == 'refs/heads/main'
with:
path: |
@@ -201,21 +198,20 @@ jobs:
contents: read
# Run on main branch or workflow_dispatch, or on PRs/other branches (build only, no upload)
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
runs-on: macos-26
runs-on: macos-15
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Select Xcode 26
run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
@@ -241,7 +237,7 @@ jobs:
run: flutter build ios --config-only --no-codesign
- name: Setup Ruby
uses: ruby/setup-ruby@d45b1a4e94b71acab930e56e79c6aa188764e7f9 # v1.316.0
uses: ruby/setup-ruby@89f90524b88a01fe6e0b732220432cc6142926af # v1.313.0
with:
ruby-version: '3.3'
bundler-cache: true

View File

@@ -19,15 +19,13 @@ jobs:
actions: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
permission-actions: write
- name: Check out code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -20,12 +20,12 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Check for breaking API changes
uses: oasdiff/oasdiff-action/breaking@291b6594ce617f22f49af5898ee038ed0b46e8fe # v0.1.5
uses: oasdiff/oasdiff-action/breaking@e24529087d93f837b28b50bb66ba9016380a7fcc # v0.1.2
with:
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
revision: open-api/immich-openapi-specs.json
@@ -38,7 +38,7 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

View File

@@ -31,14 +31,13 @@ jobs:
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -64,26 +63,25 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
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@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Login to GitHub Container Registry
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
registry: ghcr.io
@@ -98,7 +96,7 @@ jobs:
- name: Generate docker image tags
id: metadata
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
flavor: |
latest=false
@@ -109,7 +107,7 @@ jobs:
type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
- name: Build and push image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
file: packages/cli/Dockerfile
platforms: linux/amd64,linux/arm64

View File

@@ -39,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:e3fe456f346b02c2f479462100763aee3ba8245768dfeac3c4262acb068e5c62
image: ghcr.io/immich-app/mdq:main@sha256:2a64c7f045cb7b580fbdf3614d7d1805f5775fec453e3d1023764180efa8c70b
outputs:
checked: ${{ steps.get_checkbox.outputs.checked }}
steps:

View File

@@ -44,21 +44,20 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
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@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
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.
@@ -71,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@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
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
@@ -84,6 +83,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
category: '/language:${{matrix.language}}'

View File

@@ -23,11 +23,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -61,7 +60,7 @@ jobs:
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -91,7 +90,7 @@ jobs:
suffix: ['']
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}

View File

@@ -21,11 +21,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -55,14 +54,13 @@ jobs:
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -20,12 +20,10 @@ jobs:
artifact: ${{ steps.get-artifact.outputs.result }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-actions: read
permission-pull-requests: read
- if: ${{ github.event.workflow_run.conclusion != 'success' }}
run: echo 'The triggering workflow did not succeed' && exit 1
@@ -128,16 +126,13 @@ 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@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
permission-actions: read
permission-pull-requests: write
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -17,15 +17,13 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
permission-pull-requests: write
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -1,56 +0,0 @@
name: Update F-Droid Repo
on:
release:
types: [published]
permissions: {}
jobs:
update-index:
runs-on: ubuntu-latest
if: ${{ !github.event.release.prerelease }}
permissions:
contents: read
steps:
- name: Checkout pubspec for versionCode
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.release.tag_name }}
persist-credentials: false
sparse-checkout: mobile/pubspec.yaml
sparse-checkout-cone-mode: false
- name: Update F-Droid repo
env:
GITLAB_TOKEN: ${{ secrets.FDROID_REPO_TOKEN }}
RELEASE: ${{ toJSON(github.event.release) }}
TAG: ${{ github.event.release.tag_name }}
run: |
VERSION_CODE=$(yq '.version' mobile/pubspec.yaml | cut -d+ -f2)
export VERSION_CODE
NEW_ENTRY=$(yq -P '
[.assets[] | select(.name == "app-release.apk")] as $matches |
with(select($matches | length == 0); error("app-release.apk not found in release assets")) |
{
"url": $matches[0].browser_download_url,
"sha256sum": ($matches[0].digest | sub("^sha256:", "")),
"date": (.published_at | split("T") | .[0]),
"version-code": env(VERSION_CODE)
} | .date tag= "!!timestamp"
' <<< "$RELEASE")
export NEW_ENTRY
git clone --depth 1 "https://oauth2:${GITLAB_TOKEN}@gitlab.futo.org/fdroid/repo-v2.git" fdroid-repo
cd fdroid-repo
yq -i '
with(select([.apks[] | select(."version-code" == env(VERSION_CODE))] | length > 0); error("version-code already in index")) |
.apks = [env(NEW_ENTRY)] + .apks
' apps/Immich/index.yml
git config user.name "Immich Release Bot"
git config user.email "bot@immich.app"
git commit -am "Immich: add version-code ${VERSION_CODE} (${TAG})"
git push

View File

@@ -15,15 +15,13 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: write
permission-pull-requests: write
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ github.event.pull_request.head.ref }}
persist-credentials: true

View File

@@ -35,8 +35,6 @@ jobs:
with:
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
permission-contents: write
permission-pull-requests: write
- name: Find translation PR
id: find_pr

View File

@@ -14,14 +14,13 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-pull-requests: write
- name: Require PR to have a changelog label
uses: mheap/github-action-required-labels@23e10fde7e062233401931a0eece796cd9bf3177 # v5.6.0
uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5.2
with:
token: ${{ steps.token.outputs.token }}
mode: exactly

View File

@@ -12,13 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
permission-pull-requests: write
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
with:
repo-token: ${{ steps.token.outputs.token }}

View File

@@ -3,8 +3,8 @@ name: Prepare new release
on:
workflow_dispatch:
inputs:
releaseType:
description: 'Release type'
serverBump:
description: 'Bump server version'
required: true
default: 'false'
type: choice
@@ -54,14 +54,13 @@ jobs:
permissions: {} # No job-level permissions are needed because it uses the app-token
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: write
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
token: ${{ steps.token.outputs.token }}
persist-credentials: true
@@ -74,13 +73,13 @@ jobs:
# TODO move to mise
- name: Install uv
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
- name: Bump version
env:
RELEASE_TYPE: ${{ inputs.releaseType }}
SERVER_BUMP: ${{ inputs.serverBump }}
MOBILE_BUMP: ${{ inputs.mobileBump }}
run: mise //:release --type "${RELEASE_TYPE}" --mobile "${MOBILE_BUMP}"
run: pnpm --silent release -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
- id: output
run: |
@@ -136,11 +135,9 @@ jobs:
with:
client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
permission-contents: write
permission-actions: read
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: false
@@ -152,7 +149,7 @@ jobs:
github-token: ${{ steps.generate-token.outputs.token }}
- name: Create draft release
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
draft: true
prerelease: ${{ needs.bump_version.outputs.rc }}

View File

@@ -14,11 +14,10 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-pull-requests: write
- uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
with:
@@ -33,11 +32,10 @@ jobs:
pull-requests: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-pull-requests: write
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:

View File

@@ -16,14 +16,13 @@ jobs:
packages: write
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -20,11 +20,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -34,7 +33,6 @@ jobs:
filters: |
mobile:
- 'mobile/**'
- 'i18n/en.json'
force-filters: |
- '.github/workflows/static_analysis.yml'
force-events: 'workflow_dispatch,release'
@@ -51,14 +49,13 @@ jobs:
working-directory: ./mobile
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -17,11 +17,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -29,8 +28,8 @@ jobs:
with:
github-token: ${{ steps.token.outputs.token }}
filters: |
scripts:
- 'packages/scripts/**'
root:
- 'misc/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
i18n:
@@ -46,8 +45,6 @@ jobs:
- 'server/**'
- 'pnpm-lock.yaml'
- 'mise.toml'
- 'packages/plugin-core/**'
- 'packages/plugin-sdk/**'
cli:
- 'packages/cli/**'
- 'packages/sdk/**'
@@ -69,23 +66,22 @@ jobs:
- '.github/workflows/test.yml'
force-events: 'workflow_dispatch'
script-unit-tests:
name: Scripts unit tests
root-unit-tests:
name: Test the root workspace
needs: pre-job
if: ${{ fromJSON(needs.pre-job.outputs.should_run).scripts == true }}
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@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -96,7 +92,7 @@ jobs:
github_token: ${{ steps.token.outputs.token }}
- name: Run unit tests
run: pnpm --filter @immich/scripts test
run: pnpm test
server-unit-tests:
name: Test & Lint Server
@@ -107,14 +103,13 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -139,14 +134,13 @@ jobs:
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -171,14 +165,13 @@ jobs:
working-directory: ./packages/cli
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -216,14 +209,13 @@ jobs:
working-directory: ./web
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -255,14 +247,13 @@ jobs:
working-directory: ./web
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -284,14 +275,13 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -335,14 +325,13 @@ jobs:
working-directory: ./e2e
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -368,14 +357,13 @@ jobs:
working-directory: ./server
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
submodules: 'recursive'
@@ -405,14 +393,13 @@ jobs:
runner: [ubuntu-latest, ubuntu-24.04-arm]
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
submodules: 'recursive'
@@ -422,7 +409,7 @@ jobs:
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
@@ -483,14 +470,13 @@ jobs:
runner: [ubuntu-latest, ubuntu-24.04-arm]
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
submodules: 'recursive'
@@ -500,7 +486,7 @@ jobs:
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
@@ -592,13 +578,12 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -631,13 +616,12 @@ jobs:
working-directory: ./machine-learning
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -662,14 +646,13 @@ jobs:
working-directory: ./.github
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -693,13 +676,12 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -715,14 +697,13 @@ jobs:
contents: read
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -774,14 +755,13 @@ jobs:
- 5432:5432
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -24,11 +24,10 @@ jobs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-contents: read
- name: Check what should run
id: check
@@ -48,11 +47,10 @@ jobs:
if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }}
steps:
- id: token
uses: immich-app/devtools/actions/create-workflow-token@1af396ae134e4bc3b63d947e672bc68bf4ff9dc5 # create-workflow-token-action-v3.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 }}
permission-pull-requests: read
- name: Bot review status
env:

38
.vscode/settings.json vendored
View File

@@ -29,6 +29,9 @@
"editor.formatOnSave": true,
"tailwindCSS.lint.suggestCanonicalClasses": "ignore"
},
"svelte.plugin.svelte.compilerWarnings": {
"state_referenced_locally": "ignore"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
@@ -40,40 +43,37 @@
"eslint.useFlatConfig": true,
"eslint.validate": ["javascript", "typescript", "svelte"],
"eslint.workingDirectories": [
{ "changeProcessCWD": true, "directory": "cli" },
{ "changeProcessCWD": true, "directory": "e2e" },
{ "changeProcessCWD": true, "directory": "server" },
{ "changeProcessCWD": true, "directory": "web" }
{ "directory": "cli", "changeProcessCWD": true },
{ "directory": "e2e", "changeProcessCWD": true },
{ "directory": "server", "changeProcessCWD": true },
{ "directory": "web", "changeProcessCWD": true }
],
"files.watcherExclude": {
"**/.jj/**": true,
"**/.git/**": true,
"**/node_modules/**": true,
"**/build/**": true,
"**/dist/**": true,
"**/.svelte-kit/**": true
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
"*.js": "${capture}.spec.js,${capture}.mock.js",
"*.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"
},
"files.watcherExclude": {
"**/.git/**": true,
"**/.jj/**": true,
"**/.svelte-kit/**": true,
"**/build/**": true,
"**/dist/**": true,
"**/node_modules/**": true
},
"js/ts.preferences.importModuleSpecifier": "non-relative",
"search.exclude": {
"**/.svelte-kit": true,
"**/node_modules": true,
"**/build": true,
"**/dist": true,
"**/node_modules": true,
"**/.svelte-kit": true,
"**/open-api/typescript-sdk/src": true
},
"svelte.enable-ts-plugin": true,
"svelte.plugin.svelte.compilerWarnings": {
"state_referenced_locally": "ignore"
},
"tailwindCSS.experimental.configFile": {
"web/src/app.css": "web/src/**"
},
"js/ts.preferences.importModuleSpecifier": "non-relative",
"vitest.maximumConfigs": 10
}

View File

@@ -4,4 +4,4 @@
/web/ @danieldietzler
/machine-learning/ @mertalev
/e2e/ @danieldietzler
/mobile/ @shenlong-tanwen @santoshakil @agg23
/mobile/ @shenlong-tanwen @santoshakil

View File

@@ -32,13 +32,11 @@
<a href="readme_i18n/README_zh_TW.md">正體中文</a>
<a href="readme_i18n/README_uk_UA.md">Українська</a>
<a href="readme_i18n/README_ru_RU.md">Русский</a>
<a href="readme_i18n/README_bg_BG.md">Български</a>
<a href="readme_i18n/README_pt_BR.md">Português Brasileiro</a>
<a href="readme_i18n/README_sv_SE.md">Svenska</a>
<a href="readme_i18n/README_ar_JO.md">العربية</a>
<a href="readme_i18n/README_vi_VN.md">Tiếng Việt</a>
<a href="readme_i18n/README_th_TH.md">ภาษาไทย</a>
<a href="readme_i18n/README_ml_IN.md">മലയാളം</a>
</p>

View File

@@ -7,37 +7,30 @@ 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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536382"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536382"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536401"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536401"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536399"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536384"
[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"
url_api = "https://api.github.com/repos/opentofu/opentofu/releases/assets/391536406"
[[tools.terragrunt]]
version = "1.0.3"
@@ -46,34 +39,27 @@ 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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654253"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654253"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654196"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654196"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654084"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406653970"
[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"
url_api = "https://api.github.com/repos/gruntwork-io/terragrunt/releases/assets/406654412"

View File

@@ -154,7 +154,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:8e8d64b405ce18f41b8e5ee20aa4687a8ed0022d1298f2ce31cdcf3a76e09411
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1

View File

@@ -56,7 +56,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:8e8d64b405ce18f41b8e5ee20aa4687a8ed0022d1298f2ce31cdcf3a76e09411
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:3c42b892cf723fa54d2f262c37a0e1f80aa8c8ddb1da7b9b0df9455a35a7f893
image: prom/prometheus@sha256:a75c5a35bc21d7afe69551eefa3cb1e1fb1775fe759408007a66b54ec3de1f29
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus

View File

@@ -61,7 +61,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:8e8d64b405ce18f41b8e5ee20aa4687a8ed0022d1298f2ce31cdcf3a76e09411
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
user: '1000:1000'
security_opt:
- no-new-privileges:true

View File

@@ -49,7 +49,7 @@ services:
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:9@sha256:8e8d64b405ce18f41b8e5ee20aa4687a8ed0022d1298f2ce31cdcf3a76e09411
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1
restart: always

View File

@@ -31,7 +31,7 @@ You can trigger a database backup manually:
1. Go to **Administration > Job Queues**
2. Click **Create job** in the top right
3. Select **Create Database Dump** and click **Confirm**
3. Select **Create Database Backup** and click **Confirm**
The backup will appear in `UPLOAD_LOCATION/backups` and counts toward your retention limit.

View File

@@ -14,8 +14,6 @@ Under Email, enter the required details to connect with an SMTP server.
You can use [this guide](/guides/smtp-gmail) to use Gmail's SMTP server.
You can use [this guide](/guides/smtp-microsoft365) to use Microsoft's SMTP server.
## User's notifications settings
Users can manage their email notification settings from their account settings page on the web. They can choose to turn email notifications on or off for the following events:

View File

@@ -1,30 +1,5 @@
# System Integrity
## Integrity report
At a [customizable interval](https://my.immich.app/admin/system-settings?isOpen=integrity-checks), Immich runs integrity checks to ensure that your library is still intact and there are no corrupt files.
There are three kind of issues Immich checks for:
- Untracked files: the path was found in Immich's directories but it is not referenced in Immich's database
- Missing files: the path is found in the Immich internal database, but does not actually exist on disk
- Checksum mismatches: the checksum of the file stored in Immich's database does not match the actual file's checksum anymore
All three run nightly at 3am by default. For the "Checksum files" check, there are additional time and progress limits, as those are the most taxing checks. With these additional limits, Immich can slowly check checksums of your files over the course of a couple of days.
You can see the results of these checks on the [maintenance](https://my.immich.app/admin/maintenance) page. Here, you can also trigger a full scan (a _check_) for specific jobs, or all of them. In addition, you can also _refresh_ checks. This will only look at items that have currently been reported on, and check if those have been fixed.
### Common causes
Most common are untracked files. In many cases those are corrupted thumbnails or encoded videos that have been partially generated at some point and never got cleaned up properly. These are usually fine to delete, as both can always be regenerated at a later point. Other files will need to be investigated on a case-by-case basis by checking they already exist in Immich and thinking about how they might have gotten untracked.
:::info
You might want to run the _missing_ jobs for thumbnails and encoded videos (https://my.immich.app/admin/queues) to make sure all your assets have proper thumbnails and encoded videos. Watch the server logs while running the jobs, in case there are any issues with some assets.
:::
Missing files are files where Immich references them internally, but they don't actually exist on disk in that location. It could be that you deleted a file on disk from the internal library (don't do that, Immich doesn't support it). It could also be that there are issues with your file storage. Please carefully investigate missing files, and never hesitate to reach out on [our Discord](https://discord.immich.app) if you have any questions!
Checksum mismatches are often indicative of file system corruption. It could also be that you previously edited a file from the internal library on the disk, which is also not supported and will cause a checksum mismatch. Again, the recommended action is to look at any reported item individually, check it out, try to remember if you changed it or some metadata on it at some point. If you edited the file, the supported resolution is to delete the mismatched asset from Immich and reupload it as a new asset.
## Folder checks
:::info
@@ -65,7 +40,7 @@ The above error messages show that the server has previously (successfully) writ
### Ignoring the checks
:::danger
:::warning
The checks are designed to catch common problems that we have seen users have in the past, and often indicate there's something wrong that you should solve. If you know what you're doing and you want to disable them you can set the following environment variable:
:::

View File

@@ -12,11 +12,11 @@ Our [GitHub Repository](https://github.com/immich-app/immich) is a [monorepo](ht
| `.vscode/` | VSCode debug launch profiles |
| `packages/cli` | Source code for the CLI |
| `packages/sdk` | Source code for the generated OpenAPI SDK |
| `packages/scripts` | Scripts for version bumps and draft releases |
| `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 |
| `machine-learning/` | Source code for the `immich-machine-learning` docker image |
| `misc/release/` | Scripts for version bumps and draft releases |
| `mobile/` | Source code for the mobile app, both Android and iOS |
| `server/` | Source code for the `immich-server` docker image |
| `web/` | Source code for the `web` |

View File

@@ -30,7 +30,7 @@ This environment includes the services below. Additional details are available i
- Redis
- PostgreSQL development database with exposed port `5432` so you can use any database client to access it
All the services are packaged to run with a single Docker Compose command.
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`.
@@ -41,7 +41,7 @@ All the services are packaged to run with a single Docker Compose command.
1. Clone the project repo.
2. Run `cp docker/example.env docker/.env`.
3. Edit `docker/.env` to provide values for the required variable `UPLOAD_LOCATION`.
4. Install dependencies - `mise x -- pnpm i`
4. Install dependencies - `pnpm i`
5. From the root directory, run:
```bash title="Start development server"
@@ -52,7 +52,7 @@ mise dev
All the services will be started with hot-reloading enabled for a quick feedback loop.
You can access the web from `http://your-machine-ip:3000` or `http://localhost:3000` and access the server from the mobile app at `http://your-machine-ip:3000`
You can access the web from `http://your-machine-ip:3000` or `http://localhost:3000` and access the server from the mobile app at `http://your-machine-ip:3000/api`
**Notes:**
@@ -99,21 +99,6 @@ To see local changes to `@immich/ui` in Immich, do the following:
2. Run `mise //mobile:translation` to generate the translation file.
3. Change to the `mobile/` directory and run `flutter run` to start the app.
##### iOS Code Signing
The Immich Apple Team ID and bundle IDs are specified in `mobile/ios/Signing.xcconfig`. For local development, we provide an override mechanism.
Create `mobile/ios/Signing.local.xcconfig` and populate it with the necessary values needed to build and sign Immich yourself. This local override file is gitignored.
```
IMMICH_TEAM_ID = ABCDE12345
IMMICH_BUNDLE_ID_PROD = com.customuniqueid.immich
IMMICH_BUNDLE_ID_DEV = com.customuniqueid.immichdev
IMMICH_GROUP_ID = group.com.customuniqueid.immich
```
The environment values are used across Immich's targets and schemes to prevent redundant edits by contributors.
#### 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 run:

View File

@@ -99,7 +99,6 @@ Options:
-H, --include-hidden Include hidden folders (default: false, env: IMMICH_INCLUDE_HIDDEN)
-a, --album Automatically create albums based on folder name (default: false, env: IMMICH_AUTO_CREATE_ALBUM)
-A, --album-name <name> Add all assets to specified album (env: IMMICH_ALBUM_NAME)
--visibility <visibility> Set the visibility of uploaded assets (choices: "archive", "timeline", "hidden", "locked", env: IMMICH_VISIBILITY)
-n, --dry-run Don't perform any actions, just show what will be done (default: false, env: IMMICH_DRY_RUN)
-c, --concurrency <number> Number of assets to upload at the same time (default: 4, env: IMMICH_UPLOAD_CONCURRENCY)
-j, --json-output Output detailed information in json format (default: false, env: IMMICH_JSON_OUTPUT)
@@ -177,12 +176,6 @@ By default, hidden files are skipped. If you want to include hidden files, use t
immich upload --include-hidden --recursive directory/
```
You can set the visibility of uploaded assets to `archive`, `timeline`, `hidden`, or `locked` with the `--visibility` option:
```bash
immich upload --visibility archive --recursive directory/
```
You can use the `--json-output` option to get a json printed which includes
three keys: `newFiles`, `duplicates` and `newAssets`. Due to some logging
output you will need to strip the first three lines of output to get the json.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -1,19 +0,0 @@
# SMTP settings using Microsoft 365
This guide walks you through how to get the information you need to set up your Immich instance to send emails using Microsoft's SMTP server.
## Create an app password
You will need to generate an app password to use your Microsoft email in Immich. Depending on if you have a personal or business account, you can use https://go.microsoft.com/fwlink/?linkid=2274139 or https://myaccount.microsoft.com/securtiy-info respectively.
## Entering the SMTP credential in Immich
Entering your credential in Immich's email notification settings at `Administration -> Settings -> Notification Settings`
Host: smtp-mail.outlook.com
Port: 587
username: your mail address
Password: app password you created earlier
SMTPS: set it to disabled
<img src={require('./img/email-ms-settings.webp').default} width="80%" title="SMTP settings" />

View File

@@ -89,7 +89,7 @@ Information on the current workers can be found [here](/administration/jobs-work
\*1: The values of `DB_USERNAME`, `DB_PASSWORD`, and `DB_DATABASE_NAME` are passed to the Postgres container as the variables `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` in `docker-compose.yml`.
\*2: If not provided, the appropriate extension to use is auto-detected at startup by inspecting the database. When multiple extensions are installed, the order of preference is VectorChord, pgvector.
\*2: If not provided, the appropriate extension to use is auto-detected at startup by introspecting the database. When multiple extensions are installed, the order of preference is VectorChord, pgvecto.rs, pgvector.
\*3: Uses either [`postgresql.ssd.conf`](https://github.com/immich-app/base-images/blob/main/postgres/postgresql.ssd.conf) or [`postgresql.hdd.conf`](https://github.com/immich-app/base-images/blob/main/postgres/postgresql.hdd.conf) which mainly controls the Postgres `effective_io_concurrency` setting to allow for concurrenct IO on SSDs and sequential IO on HDDs.

View File

@@ -7,7 +7,7 @@ sidebar_position: 85
:::note
This is a community contribution and not officially supported by the Immich team, but included here for convenience.
Community support should be directed to Synology-specific support platforms.
Community support can be found in the dedicated channel on the [Discord Server](https://discord.immich.app/).
:::
Immich can easily be installed on a Synology NAS using Container Manager within DSM. If you have not installed Container Manager already, you can install it in the Packages Center. Refer to the [Container Manager docs](https://kb.synology.com/en-us/DSM/help/ContainerManager/docker_desc?version=7) for more information on using Container Manager.

View File

@@ -121,7 +121,7 @@ alt="Go to Docker Tab and visit the address listed next to immich-web"
width="90%"
alt="Go to Docker Tab and visit the address listed next to immich-web"
/>
</details>
:::tip

View File

@@ -28,15 +28,11 @@ docker image prune
## Versioning Policy
Immich follows [semantic versioning][semver], which tags releases in the format `<major>.<minor>.<patch>`.
We intend for breaking changes, including those to the API or deployment, to be limited to major version releases.
You can configure your Docker image to point to the current major version by using a metatag, such as `:v3`. These metatags do not follow release candidates.
Immich follows [semantic versioning][semver], which tags releases in the format `<major>.<minor>.<patch>`. We intend for breaking changes to be limited to major version releases.
You can configure your Docker image to point to the current major version by using a metatag, such as `:v3`.
The mobile app is typically compatible with the current and prior major version. However, the server is only compatible with the matching major version.
Thus, we recommend upgrading all mobile clients before upgrading the server to ensure compatibility.
We do not backport patches to earlier versions. We encourage all users to run the most recent stable release of Immich.
Downgrading to an earlier version, even within the same minor version, is not supported.
Currently, we have no plans to backport patches to earlier versions. We encourage all users to run the most recent release of Immich.
Switching back to an earlier version, even within the same minor release tag, is not supported.
[semver]: https://semver.org/

View File

@@ -1,7 +1,7 @@
The mobile app can be downloaded from the following places:
- [Apple App Store](https://apps.apple.com/us/app/immich/id1613945652)
- [Google Play Store](https://play.google.com/store/apps/details?id=app.alextran.immich)
- [GitHub Releases (APK)](https://github.com/immich-app/immich/releases)
- Obtainium: You can get your Obtainium config link from the [Utilities page of your Immich server](https://my.immich.app/utilities).
- [F-Droid](https://app.futo.org/fdroid/repo/)
- [Google Play Store](https://play.google.com/store/apps/details?id=app.alextran.immich)
- [Apple App Store](https://apps.apple.com/us/app/immich/id1613945652)
- [F-Droid](https://f-droid.org/packages/app.alextran.immich)
- [GitHub Releases (apk)](https://github.com/immich-app/immich/releases)

View File

@@ -1,7 +1,7 @@
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
[[tools.wrangler]]
version = "4.110.0"
version = "4.100.0"
backend = "npm:wrangler"
[tools.wrangler.options]

View File

@@ -28,4 +28,4 @@ run = "prettier --write ."
run = "wrangler pages deploy build --project-name=${PROJECT_NAME} --branch=${BRANCH_NAME}"
[tools]
wrangler = "4.111.0"
wrangler = "4.100.0"

View File

@@ -40,8 +40,7 @@
"@docusaurus/tsconfig": "^3.10.0",
"@docusaurus/types": "^3.10.0",
"prettier": "^3.7.4",
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
"typescript": "^6.0.0"
},
"browserslist": {
"production": [

View File

@@ -1,7 +1,7 @@
[
{
"label": "v3.0.3",
"url": "https://docs.v3.0.3.archive.immich.app"
"label": "v3.0.0-rc.2",
"url": "https://docs.v3.0.0-rc.2.archive.immich.app"
},
{
"label": "v2.7.5",

View File

@@ -45,7 +45,7 @@ services:
redis:
container_name: immich-e2e-redis
image: docker.io/valkey/valkey:9@sha256:8e8d64b405ce18f41b8e5ee20aa4687a8ed0022d1298f2ce31cdcf3a76e09411
image: docker.io/valkey/valkey:9@sha256:4963247afc4cd33c7d3b2d2816b9f7f8eeebab148d29056c2ca4d7cbc966f2d9
healthcheck:
test: redis-cli ping || exit 1

View File

@@ -41,18 +41,9 @@ export default typescriptEslint.config([
'@typescript-eslint/no-floating-promises': 'error',
'unicorn/prefer-module': 'off',
'unicorn/import-style': 'off',
'unicorn/consistent-boolean-name': 'off',
'unicorn/no-non-function-verb-prefix': 'off',
'unicorn/no-unreadable-for-of-expression': 'off',
'unicorn/max-nested-calls': 'off',
'unicorn/prefer-uint8array-base64': 'off',
'unicorn/isolated-functions': 'off',
'unicorn/prefer-promise-with-resolvers': 'off',
'unicorn/no-declarations-before-early-exit': 'off',
'unicorn/prefer-simple-condition-first': 'off',
curly: 2,
'prettier/prettier': 0,
'unicorn/name-replacements': 'off',
'unicorn/prevent-abbreviations': 'off',
'unicorn/filename-case': 'off',
'unicorn/no-null': 'off',
'unicorn/prefer-top-level-await': 'off',

View File

@@ -1,6 +1,6 @@
{
"name": "immich-e2e",
"version": "3.0.3",
"version": "3.0.0-rc.2",
"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.13.3",
"@types/node": "^24.13.2",
"@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4",
"@types/supertest": "^7.0.0",
@@ -40,7 +40,7 @@
"eslint": "^10.0.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^72.0.0",
"eslint-plugin-unicorn": "^64.0.0",
"exiftool-vendored": "^35.0.0",
"globals": "^17.0.0",
"luxon": "^3.4.4",
@@ -51,8 +51,7 @@
"sharp": "^0.34.5",
"socket.io-client": "^4.7.4",
"supertest": "^7.0.0",
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2",
"typescript": "^6.0.0",
"typescript-eslint": "^8.28.0",
"utimes": "^5.2.1",
"vitest": "^4.0.0"

View File

@@ -118,7 +118,7 @@ describe('/admin/database-backups', () => {
expect(status).toBe(201);
cookie = headers['set-cookie'][0].split(';', 1)[0];
cookie = headers['set-cookie'][0].split(';')[0];
await expect
.poll(
@@ -224,7 +224,7 @@ describe('/admin/database-backups', () => {
});
expect(status).toBe(201);
cookie = headers['set-cookie'][0].split(';', 1)[0];
cookie = headers['set-cookie'][0].split(';')[0];
await expect
.poll(
@@ -295,7 +295,7 @@ describe('/admin/database-backups', () => {
});
expect(status).toBe(201);
cookie = headers['set-cookie'][0].split(';', 1)[0];
cookie = headers['set-cookie'][0].split(';')[0];
await expect
.poll(

View File

@@ -85,7 +85,7 @@ describe('/admin/maintenance', () => {
expect(status).toBe(201);
cookie = headers['set-cookie'][0].split(';', 1)[0];
cookie = headers['set-cookie'][0].split(';')[0];
expect(cookie).toEqual(
expect.stringMatching(/^immich_maintenance_token=[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$/),
);
@@ -149,7 +149,7 @@ describe('/admin/maintenance', () => {
const { status, body } = await request(app)
.post('/admin/maintenance/login')
.send({
token: cookie!.split('=', 2)[1].trim(),
token: cookie!.split('=')[1].trim(),
});
expect(status).toBe(201);
expect(body).toEqual(

View File

@@ -27,7 +27,7 @@ test.describe('Maintenance', () => {
test('maintenance shows no options to users until they authenticate', async ({ page }) => {
const setCookie = await utils.enterMaintenance(admin.accessToken);
const cookie = setCookie
?.map((cookie) => cookie.split(';', 1)[0].split('='))
?.map((cookie) => cookie.split(';')[0].split('='))
?.find(([name]) => name === 'immich_maintenance_token');
expect(cookie).toBeTruthy();

View File

@@ -120,7 +120,6 @@ describe('/albums', () => {
}),
]);
// eslint-disable-next-line unicorn/no-unreadable-array-destructuring
[user2Albums[0]] = await Promise.all([
getAlbumInfo({ id: user2Albums[0].id }, { headers: asBearerAuth(user2.accessToken) }),
deleteUserAdmin({ id: user3.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) }),
@@ -797,22 +796,5 @@ describe('/albums', () => {
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest('Not found or no album.share access'));
});
it('should not allow an editor to change the role of an owner', async () => {
const album = await utils.createAlbum(user1.accessToken, {
albumName: 'testAlbum',
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }],
});
expect(album.albumUsers[1].role).toEqual(AlbumUserRole.Editor);
const { status, body } = await request(app)
.put(`/albums/${album.id}/user/${user1.userId}`)
.set('Authorization', `Bearer ${user2.accessToken}`)
.send({ role: AlbumUserRole.Editor });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest('User is owner'));
});
});
});

View File

@@ -781,7 +781,7 @@ describe('/asset', () => {
exifImageWidth: 4032,
exifImageHeight: 3024,
latitude: 41.2203,
longitude: -96.071625,
longitude: -96.071_625,
make: 'Apple',
model: 'iPhone 7',
lensModel: 'iPhone 7 back camera 3.99mm f/1.8',
@@ -973,9 +973,9 @@ describe('/asset', () => {
fileSizeInByte: 31_175_472,
focalLength: 18.3,
iso: 100,
latitude: 36.61324,
latitude: 36.613_24,
lensModel: '18.3mm F2.8',
longitude: -121.89785,
longitude: -121.897_85,
make: 'RICOH IMAGING COMPANY, LTD.',
model: 'RICOH GR III',
orientation: '1',

View File

@@ -75,7 +75,7 @@ describe('/map', () => {
country: 'United States of America',
id: expect.any(String),
lat: expect.closeTo(39.115),
lon: expect.closeTo(-108.400968),
lon: expect.closeTo(-108.400_968),
state: 'Colorado',
},
{
@@ -83,7 +83,7 @@ describe('/map', () => {
country: 'United States of America',
id: expect.any(String),
lat: expect.closeTo(41.2203),
lon: expect.closeTo(-96.071625),
lon: expect.closeTo(-96.071_625),
state: 'Nebraska',
},
]);
@@ -123,7 +123,7 @@ describe('/map', () => {
country: 'United States of America',
id: expect.any(String),
lat: expect.closeTo(39.115),
lon: expect.closeTo(-108.400968),
lon: expect.closeTo(-108.400_968),
state: 'Colorado',
},
{
@@ -131,7 +131,7 @@ describe('/map', () => {
country: 'United States of America',
id: expect.any(String),
lat: expect.closeTo(41.2203),
lon: expect.closeTo(-96.071625),
lon: expect.closeTo(-96.071_625),
state: 'Nebraska',
},
]);
@@ -188,20 +188,20 @@ describe('/map', () => {
const reverseGeocodeTestCases = [
{
name: 'Vaucluse',
lat: -33.85897705866313,
lon: 151.27849073027048,
lat: -33.858_977_058_663_13,
lon: 151.278_490_730_270_48,
results: [{ city: 'Vaucluse', state: 'New South Wales', country: 'Australia' }],
},
{
name: 'Ravenhall',
lat: -37.76573239917475,
lon: 144.7524531648833,
lat: -37.765_732_399_174_75,
lon: 144.752_453_164_883_3,
results: [{ city: 'Ravenhall', state: 'Victoria', country: 'Australia' }],
},
{
name: 'Scarborough',
lat: -31.894346156789997,
lon: 115.75761710390464,
lat: -31.894_346_156_789_997,
lon: 115.757_617_103_904_64,
results: [{ city: 'Scarborough', state: 'Western Australia', country: 'Australia' }],
},
];

View File

@@ -44,7 +44,7 @@ const loginWithOAuth = async (sub: OAuthUser | string, redirectUri?: string) =>
});
// login
const response1 = await redirect(url.replace(authServer.internal, () => authServer.external));
const response1 = await redirect(url.replace(authServer.internal, authServer.external));
const response2 = await request(authServer.external + response1.location)
.post('')
.set('Cookie', response1.cookies)

View File

@@ -4,7 +4,6 @@ import {
AssetVisibility,
deleteAssets,
LoginResponseDto,
SharedLinkType,
updateAsset,
} from '@immich/sdk';
import { DateTime } from 'luxon';
@@ -87,23 +86,23 @@ describe('/search', () => {
// note: the coordinates here are not the actual coordinates of the images and are random for most of them
const coordinates = [
{ latitude: 48.85341, longitude: 2.3488 }, // paris
{ latitude: 35.6895, longitude: 139.69171 }, // tokyo
{ latitude: 52.52437, longitude: 13.41053 }, // berlin
{ latitude: 1.3146631, longitude: 103.8454093 }, // singapore
{ latitude: 41.01384, longitude: 28.94966 }, // istanbul
{ latitude: 5.55602, longitude: -0.1969 }, // accra
{ latitude: 37.5442706, longitude: -4.7277528 }, // andalusia
{ latitude: 23.13302, longitude: -82.38304 }, // havana
{ latitude: 41.69411, longitude: 44.83368 }, // tbilisi
{ latitude: 31.22222, longitude: 121.45806 }, // shanghai
{ latitude: 48.853_41, longitude: 2.3488 }, // paris
{ latitude: 35.6895, longitude: 139.691_71 }, // tokyo
{ latitude: 52.524_37, longitude: 13.410_53 }, // berlin
{ latitude: 1.314_663_1, longitude: 103.845_409_3 }, // singapore
{ latitude: 41.013_84, longitude: 28.949_66 }, // istanbul
{ latitude: 5.556_02, longitude: -0.1969 }, // accra
{ latitude: 37.544_270_6, longitude: -4.727_752_8 }, // andalusia
{ latitude: 23.133_02, longitude: -82.383_04 }, // havana
{ latitude: 41.694_11, longitude: 44.833_68 }, // tbilisi
{ latitude: 31.222_22, longitude: 121.458_06 }, // shanghai
{ latitude: 38.9711, longitude: -109.7137 }, // thompson springs
{ latitude: 40.71427, longitude: -74.00597 }, // new york
{ latitude: 47.04057, longitude: 9.06804 }, // glarus
{ latitude: 32.77152, longitude: -89.11673 }, // philadelphia
{ latitude: 31.63416, longitude: -7.99994 }, // marrakesh
{ latitude: 38.5237354, longitude: -78.4886194 }, // tanners ridge
{ latitude: 59.93863, longitude: 30.31413 }, // st. petersburg
{ latitude: 40.714_27, longitude: -74.005_97 }, // new york
{ latitude: 47.040_57, longitude: 9.068_04 }, // glarus
{ latitude: 32.771_52, longitude: -89.116_73 }, // philadelphia
{ latitude: 31.634_16, longitude: -7.999_94 }, // marrakesh
{ latitude: 38.523_735_4, longitude: -78.488_619_4 }, // tanners ridge
{ latitude: 59.938_63, longitude: 30.314_13 }, // st. petersburg
{ latitude: 0, longitude: 0 }, // null island
];
@@ -112,7 +111,7 @@ describe('/search', () => {
);
await Promise.all(updates);
for (const i of coordinates.keys()) {
for (const [i] of coordinates.entries()) {
await utils.waitForWebsocketEvent({ event: 'assetUpdate', id: assets[i].id });
}
@@ -358,32 +357,6 @@ describe('/search', () => {
expect(body.assets.items).toHaveLength(assets.length);
});
}
it('should reject shared link access without an album filter', async () => {
const album = await utils.createAlbum(admin.accessToken, { albumName: 'foo' });
const sharedLink = await utils.createSharedLink(admin.accessToken, {
type: SharedLinkType.Album,
albumId: album.id,
});
const { status, body } = await request(app).post(`/search/metadata?key=${sharedLink.key}`).send({});
expect(status).toBe(400);
expect(body).toEqual({ message: 'Shared link access is only allowed in combination with an albumIds filter' });
});
it('should allow shared link access for albums', async () => {
const asset = await utils.createAsset(admin.accessToken);
const album = await utils.createAlbum(admin.accessToken, { albumName: 'foo', assetIds: [asset.id] });
const sharedLink = await utils.createSharedLink(admin.accessToken, {
type: SharedLinkType.Album,
albumId: album.id,
});
const { status, body } = await request(app)
.post(`/search/metadata?key=${sharedLink.key}`)
.send({ albumIds: [album.id] });
expect(status).toBe(200);
expect(body.assets.items).toEqual([expect.objectContaining({ id: asset.id })]);
});
});
describe('POST /search/random', () => {

View File

@@ -91,14 +91,12 @@ describe('/server', () => {
it('should respond with the server version', async () => {
const { status, body } = await request(app).get('/server/version');
expect(status).toBe(200);
expect(body).toEqual(
expect.objectContaining({
major: expect.any(Number),
minor: expect.any(Number),
patch: expect.any(Number),
}),
);
expect(Object.keys(body)).toEqual(expect.arrayContaining(['major', 'minor', 'patch', 'prerelease']));
expect(body).toEqual({
major: expect.any(Number),
minor: expect.any(Number),
patch: expect.any(Number),
prerelease: expect.anything(),
});
});
});

View File

@@ -31,7 +31,7 @@ describe(`immich login`, () => {
it('should login and save auth.yml with 600', async () => {
const admin = await utils.adminSetup();
const key = await utils.createApiKey(admin.accessToken, [Permission.All]);
const { stdout, stderr, exitCode } = await immichCli(['login', app, key.secret]);
const { stdout, stderr, exitCode } = await immichCli(['login', app, `${key.secret}`]);
expect(stdout.split('\n')).toEqual([
'Logging in to http://127.0.0.1:2285/api',
'Logged in as admin@immich.cloud',
@@ -48,7 +48,7 @@ describe(`immich login`, () => {
it('should login without /api in the url', async () => {
const admin = await utils.adminSetup();
const key = await utils.createApiKey(admin.accessToken, [Permission.All]);
const { stdout, stderr, exitCode } = await immichCli(['login', app.replaceAll('/api', ''), key.secret]);
const { stdout, stderr, exitCode } = await immichCli(['login', app.replaceAll('/api', ''), `${key.secret}`]);
expect(stdout.split('\n')).toEqual([
'Logging in to http://127.0.0.1:2285',
'Discovered API at http://127.0.0.1:2285/api',

View File

@@ -119,9 +119,7 @@ describe(`immich upload`, () => {
const baseDir = `/tmp/upload/`;
const testPaths = Object.keys(files).map((filePath) => `${baseDir}/${filePath}`);
for (const filePath of testPaths) {
utils.createImageFile(filePath);
}
testPaths.map((filePath) => utils.createImageFile(filePath));
const commandLine = paths.map((argument) => `${baseDir}/${argument}`);
@@ -137,9 +135,7 @@ describe(`immich upload`, () => {
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
expect(assets.total).toBe(expectedCount);
for (const filePath of testPaths) {
utils.removeImageFile(filePath);
}
testPaths.map((filePath) => utils.removeImageFile(filePath));
});
}
});

View File

@@ -21,7 +21,7 @@ export const randomImageFromString = async (
let seedNumber = 0;
for (let i = 0; i < seed.length; i++) {
seedNumber = (seedNumber << 5) - seedNumber + (seed.codePointAt(i) ?? 0);
seedNumber &= seedNumber; // Convert to 32bit integer
seedNumber = seedNumber & seedNumber; // Convert to 32bit integer
}
return randomImage(new SeededRandom(Math.abs(seedNumber)), { width, height });
};

View File

@@ -64,7 +64,7 @@ export function generateAsset(
const asset: MockTimelineAsset = {
id: assetId,
ownerId,
ratio: Number(ratio.split(':', 1)[0]) / Number(ratio.split(':', 2)[1]),
ratio: Number.parseFloat(ratio.split(':')[0]) / Number.parseFloat(ratio.split(':')[1]),
thumbhash: generateThumbhash(rng),
localDateTime: date.toISOString(),
fileCreatedAt: date.toISOString(),
@@ -214,7 +214,7 @@ export function generateTimelineData(config: TimelineConfig): MockTimelineData {
}
// Create a mock album from random assets
const allAssets = buckets.values().toArray().flat();
const allAssets = [...buckets.values()].flat();
// Select 10-30 random assets for the album (or all assets if less than 10)
const albumSize = Math.min(allAssets.length, globalRng.nextInt(10, 31));

View File

@@ -172,7 +172,11 @@ function shouldIncludeAsset(
if (isArchived !== undefined && actuallyArchived !== isArchived) {
return false;
}
return isFavorite === undefined || actuallyFavorited === isFavorite;
if (isFavorite !== undefined && actuallyFavorited !== isFavorite) {
return false;
}
return true;
}
/**
* Get summary for all buckets (mimics getTimeBuckets API)
@@ -357,7 +361,7 @@ export function getAsset(
owner?: UserResponseDto,
): AssetResponseDto | undefined {
// Search through all buckets for the asset
const buckets = timelineData.buckets.values().toArray();
const buckets = [...timelineData.buckets.values()];
for (const assets of buckets) {
const asset = assets.find((a) => a.id === assetId);
if (asset) {
@@ -391,7 +395,7 @@ export function getAlbum(
// Get the actual asset objects from the timeline data
const albumAssets: AssetResponseDto[] = [];
const allAssets = timelineData.buckets.values().toArray().flat();
const allAssets = [...timelineData.buckets.values()].flat();
for (const assetId of album.assetIds) {
const assetConfig = allAssets.find((a) => a.id === assetId);

View File

@@ -143,7 +143,7 @@ export function validateTimelineConfig(config: TimelineConfig): void {
}
// Validate seed if provided
if (config.seed !== undefined && (config.seed < 0 || !Number.isSafeInteger(config.seed))) {
if (config.seed !== undefined && (config.seed < 0 || !Number.isInteger(config.seed))) {
throw new Error('Seed must be a non-negative integer');
}

View File

@@ -153,8 +153,11 @@ export function getMockAsset(
const isInDifferentPeriod = (date1: DateTime, date2: DateTime): boolean => {
if (unit === 'day') {
return !date1.startOf('day').equals(date2.startOf('day'));
} else if (unit === 'month') {
return date1.year !== date2.year || date1.month !== date2.month;
} else {
return date1.year !== date2.year;
}
return unit === 'month' ? date1.year !== date2.year || date1.month !== date2.month : date1.year !== date2.year;
};
if (direction === 'next') {

View File

@@ -82,9 +82,6 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI
cast: {
gCastEnabled: false,
},
recentlyAdded: {
sidebarWeb: false,
},
},
});
});

View File

@@ -40,8 +40,7 @@ export const setupTimelineMockApiRoutes = async (
contentType: 'application/json',
json: getTimeBuckets(timelineRestData, isTrashed, isArchived, isFavorite, albumId, changes),
});
}
if (pathname === '/api/timeline/bucket') {
} else if (pathname === '/api/timeline/bucket') {
const timeBucket = url.searchParams.get('timeBucket');
if (!timeBucket) {
return route.continue();

View File

@@ -38,7 +38,7 @@ test.describe('asset-viewer', () => {
assets.push(...timeBucket);
}
for (const yearMonth of timelineRestData.buckets.keys()) {
const [year, month] = yearMonth.split('-', 2);
const [year, month] = yearMonth.split('-');
yearMonths.push(`${year}-${Number(month)}`);
}
});

View File

@@ -110,7 +110,6 @@ export async function enableTagsPreference(context: BrowserContext) {
download: { archiveSize: 4_294_967_296, includeEmbeddedVideos: false },
purchase: { showSupportBadge: true, hideBuyButtonUntil: '2100-02-12T00:00:00.000Z' },
cast: { gCastEnabled: false },
recentlyAdded: { sidebarWeb: false },
},
});
});

View File

@@ -1,4 +1,3 @@
/* eslint-disable unicorn/no-this-outside-of-class */
import type { AssetResponseDto } from '@immich/sdk';
import { expect, Page } from '@playwright/test';

View File

@@ -49,7 +49,7 @@ test.describe('Timeline', () => {
assets.push(...timeBucket);
}
for (const yearMonth of timelineRestData.buckets.keys()) {
const [year, month] = yearMonth.split('-', 2);
const [year, month] = yearMonth.split('-');
yearMonths.push(`${year}-${Number(month)}`);
}
});

View File

@@ -7,7 +7,7 @@ export const sleep = (ms: number) => {
};
export const padYearMonth = (yearMonth: string) => {
const [year, month] = yearMonth.split('-', 2);
const [year, month] = yearMonth.split('-');
return `${year}-${month.padStart(2, '0')}`;
};
@@ -72,7 +72,6 @@ export const thumbnailUtils = {
},
async queryThumbnailInViewport(page: Page, collector: (assetId: string) => boolean) {
const assetIds: string[] = [];
// eslint-disable-next-line unicorn/no-this-outside-of-class
for (const thumb of await this.locator(page).all()) {
const box = await thumb.boundingBox();
if (box) {
@@ -152,7 +151,6 @@ export const timelineUtils = {
page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return document.querySelector('#asset-grid').scrollTop;
});
await expect.poll(queryTop).toBeGreaterThan(0);
@@ -179,7 +177,6 @@ export const assetViewerUtils = {
page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line unicorn/no-optional-chaining-on-undeclared-variable
return document.activeElement?.dataset?.asset;
});
await expect(poll(page, activeElement, (result) => result === assetId)).resolves.toBe(assetId);

View File

@@ -1,4 +1,3 @@
/* eslint-disable unicorn/no-top-level-assignment-in-function */
import {
AssetMediaCreateDto,
AssetMediaResponseDto,
@@ -178,7 +177,7 @@ export const utils = {
resetDatabase: async (tables?: string[]) => {
client = await utils.connectDatabase();
tables ||= [
tables = tables || [
// TODO e2e test for deleting a stack, since it is quite complex
'stack',
'library',
@@ -305,7 +304,7 @@ export const utils = {
},
adminSetup: async (options?: AdminSetupOptions) => {
options ||= { onboarding: true };
options = options || { onboarding: true };
await signUpAdmin({ signUpDto: signupDto.admin });
const response = await login({ loginCredentialDto: loginDto.admin });
@@ -546,7 +545,6 @@ export const utils = {
{
headers: asBearerAuth(accessToken),
fetch: (...args: Parameters<typeof fetch>) =>
// eslint-disable-next-line unicorn/no-invalid-argument-count, unicorn/prefer-await
fetch(...args).then((response) => {
setCookie = response.headers.getSetCookie();
return response;
@@ -676,7 +674,7 @@ export const utils = {
cliLogin: async (accessToken: string) => {
const key = await utils.createApiKey(accessToken, [Permission.All]);
await immichCli(['login', app, key.secret]);
await immichCli(['login', app, `${key.secret}`]);
return key.secret;
},
@@ -708,7 +706,6 @@ export const utils = {
},
};
// eslint-disable-next-line unicorn/no-top-level-side-effects
utils.initSdk();
if (!existsSync(`${testAssetDir}/albums`)) {

View File

@@ -10,7 +10,6 @@
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"target": "es2023",
"lib": ["dom", "ESNext"],
"sourceMap": true,
"outDir": "./dist",
"incremental": true,

View File

@@ -10,18 +10,22 @@
"active": "Aktief",
"active_count": "Aktief: {count}",
"activity": "Aktiwiteite",
"activity_changed": "Aktiwiteit is {enabled, select, true {geaktiveer} other {gedeaktiveer}}",
"add": "Voeg toe",
"add_a_description": "Voeg n beskrywing toe",
"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",
"add_location": "Voeg ligging toe",
"add_more_users": "Voeg meer gebruikers toe",
"add_partner": "Voeg vennoot toe",
"add_path": "Voeg pad toe",
"add_photos": "Voeg fotos toe",
"add_tag": "Voeg etiket toe",
"add_to": "Voeg toe tot…",
@@ -29,9 +33,11 @@
"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",
@@ -136,6 +142,7 @@
"advanced": "Gevorderd",
"albums": "Albums",
"all": "Alle",
"anti_clockwise": "Linksom",
"archive": "Argief",
"asset_skipped": "Oorgeslaan",
"asset_uploaded": "Opgelaai",
@@ -147,6 +154,7 @@
"camera": "Kamera",
"cancel": "Kanselleer",
"city": "Stad",
"clockwise": "Regsom",
"close": "Sluit",
"color": "Kleur",
"confirm": "Bevestig",
@@ -187,6 +195,7 @@
"unsaved_change": "Onbewaarde verandering",
"unselect_all": "Ontkies alles",
"unselect_all_duplicates": "Ontkies alle duplikate",
"unselect_all_in": "Ontkies alles in {group}",
"unstack": "Ontstapel",
"unstack_action_prompt": "{count} ongestapel",
"unstacked_assets_count": "{count, plural, one {# item} other {# items}} ontstapel",
@@ -200,6 +209,8 @@
"upload": "Laai op",
"upload_concurrency": "Aantal gelyktydige oplaaie",
"upload_details": "Oplaaidetails",
"upload_dialog_info": "Wil u n rugsteun maak van die gekose item(s) op die bediener?",
"upload_dialog_title": "Laai item op",
"upload_error_with_count": "Oplaaifout vir {count, plural, one {# item} other {# items}}",
"upload_errors": "Oplaai voltooi met {count, plural, one {# fout} other {# foute}}, verfris die blad om die nuwe items te sien.",
"upload_finished": "Klaar opgelaai",
@@ -228,6 +239,7 @@
"user_privacy": "Gebruikersprivaatheid",
"user_purchase_settings": "Koop",
"user_purchase_settings_description": "Bestuur u aankoop",
"user_role_set": "Stel {user} in as {role}",
"user_usage_detail": "Gedetailleerde gebruik van gebruikers",
"user_usage_stats": "Statistieke vir rekeninggebruik",
"user_usage_stats_description": "Bekyk statistieke van rekeninggebruik",
@@ -237,6 +249,7 @@
"utilities": "Gereedskap",
"validate": "Valideer",
"validate_endpoint_error": "Voer asb. n geldige bronadres in",
"validation_error": "Valideerfout",
"variables": "Veranderlikes",
"version": "Weergawe",
"version_announcement_closing": "Jou friend, Alex",
@@ -248,6 +261,7 @@
"video_hover_setting_description": "Speel videoduimnael wanneer muis oor item hang. Selfs indien gedeaktiveer kan afspeel begin deur oor die afspeelknop te hang.",
"videos": "Videos",
"videos_count": "{count, plural, one {# video} other {# videos}}",
"videos_only": "Slegs videos",
"view": "Bekyk",
"view_album": "Bekyk album",
"view_all": "Bekyk alle",
@@ -256,16 +270,21 @@
"view_details": "Bekyk detail",
"view_in_timeline": "Bekyk in tydlyn",
"view_link": "Bekyk skakel",
"view_links": "Bekyk skakels",
"view_name": "Bekyk",
"view_next_asset": "Bekyk volgende item",
"view_previous_asset": "Bekyk vorige item",
"view_qr_code": "Bekyk QR-kode",
"view_similar_photos": "Bekyk soortgelyke fotos",
"view_stack": "Bekyk stapel",
"view_user": "Bekyk gebruiker",
"viewer_remove_from_stack": "Verwyder van stapel",
"viewer_stack_use_as_main_asset": "Gebruik as hoofitem",
"viewer_unstack": "Ontstapel",
"visibility": "Sigbaarheid",
"visibility_changed": "Sigbaarheid verander vir {count, plural, one {# mens} other {# mense}}",
"visual": "Visueel",
"visual_builder": "Visuele bouer",
"waiting": "Wag",
"waiting_count": "Wagtend: {count}",
"warning": "Waarskuwing",
@@ -284,6 +303,7 @@
"workflow_navigation_prompt": "Is u seker u wil verlaat sonder om u veranderinge te bewaar?",
"workflow_summary": "Werkvloei-opsomming",
"workflow_update_success": "Werkvloei suksesvol bygewerk",
"workflow_updated": "Werkvloei bygewerk",
"workflows": "Werkvloeie",
"workflows_help_text": "Werkvloeie outomatiseer aksies op u items gebaseer op snellers en filters",
"wrong_pin_code": "Verkeerde PIN-kode",
@@ -293,5 +313,6 @@
"you_dont_have_any_shared_links": "U het geen gedeelde skakels nie",
"your_wifi_name": "U Wi-Fi-naam",
"zero_to_clear_rating": "druk 0 om itemgradering te wis",
"zoom_image": "Zoem in"
"zoom_image": "Zoem in",
"zoom_to_bounds": "Zoem na rande"
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,18 +10,22 @@
"active": "Aktiv",
"active_count": "Aktiv: {count}",
"activity": "Fəaliyyət",
"activity_changed": "Fəaliyyət {enabled, select, true {aktivdir} other {aktiv deyil}}",
"add": "Əlavə et",
"add_a_description": "Təsviri əlavə et",
"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",
"add_location": "Məkan əlavə et",
"add_more_users": "Daha çox istifadəçi əlavə et",
"add_partner": "Partnyor əlavə et",
"add_path": "Yol əlavə et",
"add_photos": "Şəkillər əlavə et",
"add_tag": "Etiket əlavə et",
"add_to": "Bura əlavə et…",
@@ -29,9 +33,11 @@
"add_to_album_bottom_sheet_added": "{album} albomuna əlavə edildi",
"add_to_album_bottom_sheet_already_exists": "Artıq {album} albomunda var",
"add_to_album_bottom_sheet_some_local_assets": "Bəzi lokal resurslar alboma əlavə edilə bilmədi",
"add_to_album_toggle": "{album} üçün seçimi dəyişin",
"add_to_albums": "Albomlara əlavə et",
"add_to_albums_count": "({count}) albomlarına əlavə et",
"add_to_bottom_bar": "Əlavə et",
"add_to_shared_album": "Paylaşılan alboma əlavə et",
"add_upload_to_stack": "Yeni yüklənmə əlavə et",
"add_url": "URL əlavə et",
"added_to_archive": "Arxivə əlavə edildi",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,7 @@
"acknowledge": "Akcept",
"active": "Stap Mekem",
"activity": "Wanem hemi Mekem",
"activity_changed": "WAnem hemi Mekem hemi",
"add": "Ad",
"add_a_description": "Putem Description blo hem",
"add_a_location": "Putem place blo hem",
@@ -12,9 +13,11 @@
"add_a_title": "Putem wan name blo hem",
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
"add_location": "Putem wan place blo hem",
"add_more_users": "Putem mor man",
"readonly_mode_enabled": "Mod blo yu no save janjem i on",
"reassigned_assets_to_new_person": "Janjem{count, plural, one {# asset} other {# assets}} blo nu man",
"reassing_hint": "janjem ol sumtin yu bin joos i go blo wan man",
"recent_albums": "album i no old tu mas",
"recent_searches": "lukabout wea i no old tu mas",
"time_based_memories_duration": "hao mus second blo wan wan imij i stap lo scrin.",
"timezone": "taemzon",
@@ -30,6 +33,7 @@
"trash_action_prompt": "{count} igo lo plaes lo toti",
"trash_all": "Putem ol i go lo toti",
"trash_count": "Toti {count, number}",
"trash_emptied": "basket blo toti i empti nomo",
"trash_no_results_message": "Foto mo video lo basket blo toti yu save lukem lo plaes ia.",
"trash_page_delete_all": "Delete oli ol"
}

View File

@@ -10,18 +10,22 @@
"active": "সচল",
"active_count": "Active: {count}",
"activity": "কার্যকলাপ",
"activity_changed": "একটিভিটি এখন {enabled, select, true {enabled} other {disabled}} আছে",
"add": "যোগ করুন",
"add_a_description": "একটি বিবরণ যোগ করুন",
"add_a_location": "একটি অবস্থান যোগ করুন",
"add_a_name": "একটি নাম যোগ করুন",
"add_a_title": "একটি শিরোনাম যোগ করুন",
"add_action": "কর্ম যোগ করুন",
"add_action_description": "সম্পাদন করার জন্য একটি কাজ যোগ করতে ক্লিক করুন",
"add_assets": "সম্পদ যোগ করুন",
"add_birthday": "জন্মদিন যোগ করুন",
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
"add_location": "অবস্থান যুক্ত করুন",
"add_more_users": "আরো ব্যবহারকারী যুক্ত করুন",
"add_partner": "অংশীদার যোগ করুন",
"add_path": "পাথ যুক্ত করুন",
"add_photos": "ছবি যুক্ত করুন",
"add_step": "ধাপ যোগ করুন",
"add_tag": "ট্যাগ যুক্ত করুন",
@@ -30,9 +34,11 @@
"add_to_album_bottom_sheet_added": "{album} এ যোগ করা হয়েছে",
"add_to_album_bottom_sheet_already_exists": "{album} এ আগে থেকেই আছে",
"add_to_album_bottom_sheet_some_local_assets": "কিছু স্থানীয় ছবি বা ভিডিও অ্যালবামে যোগ করা যায়নি",
"add_to_album_toggle": "{album} - এর নির্বাচন পরিবর্তন করুন",
"add_to_albums": "অ্যালবামে যোগ করুন",
"add_to_albums_count": "অ্যালবামে যোগ করুন ({count})",
"add_to_bottom_bar": "এ যোগ করুন",
"add_to_shared_album": "শেয়ার করা অ্যালবামে যোগ করুন",
"add_upload_to_stack": "আপলোড স্ট্যাকে যোগ করুন",
"add_url": "লিঙ্ক যোগ করুন",
"added_to_archive": "আর্কাইভ এ যোগ করা হয়েছে",
@@ -453,6 +459,8 @@
"album_delete_confirmation": "আপনি কি সত্যিই অ্যালবাম {album} মুছে ফেলতে চান?",
"album_delete_confirmation_description": "অ্যালবামটি শেয়ার করা থাকলেও অন্য ব্যবহারকারীরা আর এটি অ্যাক্সেস করতে পারবেন না।",
"album_info_updated": "অ্যালবামের তথ্য আপডেট করা হয়েছে",
"album_leave": "অ্যালবাম থেকে বেরিয়ে যেতে চান ?",
"album_leave_confirmation": "আপনি কি নিশ্চিত যে আপনি {album} ছেড়ে যেতে চান?",
"album_name": "অ্যালবামের নাম",
"album_options": "অ্যালবামের অপশনসমূহ",
"album_remove_user": "ব্যবহারকারী সরাতে চান?",
@@ -460,6 +468,8 @@
"album_share_no_users": "এই অ্যালবামটি সব ব্যবহারকারীর সঙ্গে শেয়ার করা হয়েছে, বা শেয়ার করার জন্য কোনো ব্যবহারকারী নেই।",
"album_updated": "অ্যালবাম আপডেট করা হয়েছে",
"album_updated_setting_description": "নতুন অ্যাসেট যুক্ত হলে শেয়ার করা অ্যালবামের জন্য ইমেইল নোটিফিকেশন পান",
"album_user_left": "বাম {album}",
"album_user_removed": "{user} কে সরানো হয়েছে",
"album_with_link_access": "লিঙ্ক থাকা যে কেউ এই অ্যালবামের ছবি ও মানুষজনকে দেখতে পারবে।",
"albums": "অ্যালবামসমূহ",
"all": "সব",
@@ -467,8 +477,10 @@
"all_people": "সব ব্যবহারকারী",
"all_videos": "সব ভিডিও",
"allow_dark_mode": "ডার্ক মোড চালু করুন",
"allow_edits": "এডিটের অনুমতি দিন",
"allow_public_user_to_download": "সাধারণ ব্যবহারকারী ডাউনলোড করতে পারবে",
"allow_public_user_to_upload": "সাধারণ ব্যবহারকারী আপলোড করতে পারবে",
"anti_clockwise": "বিপরীত দিক",
"api_key": "API কী",
"api_key_description": "এই মান একবারই দেখানো হবে। উইন্ডো বন্ধ করার আগে অবশ্যই এটি কপি করুন।",
"api_key_empty": "API কী-এর নাম খালি রাখা যাবে না",
@@ -484,6 +496,8 @@
"asset_added_to_album": "অ্যালবামে যুক্ত করা হয়েছে",
"asset_adding_to_album": "অ্যালবামে যুক্ত করা হচ্ছে…",
"asset_description_updated": "অ্যাসেটের বিবরণ আপডেট করা হয়েছে",
"asset_filename_is_offline": "{filename} অ্যাসেটটি বর্তমানে অফলাইন",
"asset_has_unassigned_faces": "অ্যাসেটটির কিছু মুখ অনির্ধারিত ফেস রয়েছে",
"asset_hashing": "হ্যাশিং চলছে…",
"asset_offline": "অ্যাসেট বর্তমানে অফলাইন",
"asset_offline_description": "এই এক্সটার্নাল অ্যাসেটটি এখন ডিস্কে নেই। সহায়তার জন্য Immich অ্যাডমিনিস্ট্রেটরের সাথে যোগাযোগ করুন।",
@@ -504,6 +518,7 @@
"back": "ফিরে যান",
"back_close_deselect": "ফিরে যান, বন্ধ করুন বা নির্বাচন বাতিল করুন",
"backward": "পিছনে",
"birthdate_saved": "জন্ম তারিখ সংরক্ষণ সম্পন্ন",
"birthdate_set_description": "একটি ছবির সময়ে ব্যক্তির বয়স গণনার জন্য জন্ম তারিখ ব্যবহার করা হয়।",
"blurred_background": "ব্লারড ব্যাকগ্রাউন্ড",
"bugs_and_feature_requests": "বাগ ও ফিচার রিকোয়েস্ট",
@@ -522,6 +537,7 @@
"cannot_undo_this_action": "এই কাজ পূর্বাবস্থায় ফেরানো যাবে না!",
"cannot_update_the_description": "বিবরণ পরিবর্তন সম্ভব নয়",
"change_date": "তারিখ পরিবর্তন",
"change_expiration_time": "মেয়াদ শেষের সময় পরিবর্তন",
"change_location": "লোকেশন পরিবর্তন",
"change_name": "নাম পরিবর্তন করুন",
"change_name_successfully": "নাম সফলভাবে পরিবর্তন হয়েছে",
@@ -537,10 +553,12 @@
"clear_all_recent_searches": "সাম্প্রতিক সব অনুসন্ধান পরিষ্কার করুন",
"clear_message": "মেসেজ পরিষ্কার করুন",
"clear_value": "ভ্যালু মুছুন",
"clockwise": "ঘড়ির কাঁটার দিকে",
"close": "বন্ধ",
"collapse": "সংকুচিত করুন",
"collapse_all": "সব সংকুচিত",
"color": "রং",
"color_theme": "কালার থিম",
"comment_deleted": "মন্তব্য মুছে ফেলা হয়েছে",
"comment_options": "মন্তব্য অপশন",
"comments_and_likes": "মন্তব্য ও লাইক",
@@ -556,6 +574,7 @@
"copied_image_to_clipboard": "ছবি ক্লিপবোর্ডে কপি হয়েছে।",
"copied_to_clipboard": "ক্লিপবোর্ডে কপি হয়েছে!",
"copy_error": "Error-টি কপি করুন",
"copy_file_path": "ফাইল পাথ কপি",
"copy_image": "ছবি কপি",
"copy_link": "লিঙ্ক কপি",
"copy_link_to_clipboard": "ক্লিপবোর্ডে লিঙ্ক কপি করুন",
@@ -598,13 +617,16 @@
"delete_tag_confirmation_prompt": "আপনি কি নিশ্চিতভাবে {tagName} ট্যাগটি মুছতে চান?",
"delete_user": "ইউজার মুছুন",
"deleted_shared_link": "শেয়ার করা লিঙ্কটি মুছুন",
"deletes_missing_assets": "ডিস্ক থেকে হারানো অ্যাসেটগুলো মুছে",
"description": "বিবরন",
"details": "বিস্তারিত",
"direction": "দিকনির্দেশনা",
"disabled": "নিষ্ক্রিয়",
"disallow_edits": "সম্পাদনা করার অনুমতি দেবেন না",
"discord": "ডিসকর্ড",
"discover": "ডিসকভার",
"dismiss_all_errors": "সব ত্রুটি বাতিল করুন",
"dismiss_error": "ত্রুটি বাতিল করুন",
"display_options": "ডিসপ্লে অপশন",
"display_order": "ডিসপ্লে অর্ডার",
"display_original_photos": "অরিজিনাল ছবি দেখান",
@@ -624,5 +646,6 @@
"you_dont_have_any_shared_links": "আপনার কোনো শেয়ার করা লিঙ্ক নেই (You don't have any shared links)",
"your_wifi_name": "আপনার ওয়াই-ফাই এর নাম (Your Wi-Fi name)",
"zero_to_clear_rating": "অ্যাসেট রেটিং মুছে ফেলতে চাপুন",
"zoom_image": "ছবি জুম করুন (Zoom Image)"
"zoom_image": "ছবি জুম করুন (Zoom Image)",
"zoom_to_bounds": "বাউন্ডস অনুযায়ী জুম করুন (Zoom to bounds)"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
"actions": "Ӗҫсем",
"active": "Хастар",
"activity": "Хастарлӑх",
"activity_changed": "Хастарлӑха {enabled, select, true {кӗртнӗ} other {сӳнтернӗ}}",
"add": "Хуш",
"add_a_description": "Ҫырса кӑтартни хуш",
"add_a_location": "Вырӑн хуш",
@@ -17,11 +18,14 @@
"add_endpoint": "Вӗҫӗмлӗ пӑнчӑ хушар",
"add_exclusion_pattern": "Кӑларса пӑрахмалли йӗрке хуш",
"add_location": "Вырӑн хуш",
"add_more_users": "Усӑҫсем ытларах хуш",
"add_partner": "Мӑшӑр хуш",
"add_path": "Ҫулне хуш",
"add_photos": "Сӑнӳкерчӗксем хуш",
"add_tag": "Тег хуш",
"add_to": "Мӗн те пулин хуш…",
"add_to_album": "Альбома хуш",
"add_to_shared_album": "Пӗрлехи альбома хуш",
"add_url": "URL хушӑр",
"added_to_archive": "Архива хушнӑ",
"added_to_favorites": "Суйласа илнине хушнӑ",
@@ -75,6 +79,7 @@
"people": "Ҫынсем",
"photos": "Сӑнӳкерчӗксем",
"photos_and_videos": "Сӑнӳкерчӗксем тете Видеосем",
"photos_count": "{count, plural, one {{count, number} Сӑнӳкерчӗк} other {{count, number} Сӑнӳкерчӗксем}}",
"photos_from_previous_years": "Иртнӗ ҫулсенчи сӑнӳкерчӗксем",
"place": "Тӗл",
"places": "Тӗлсем",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,18 +10,22 @@
"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": "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ä",
"add_action_description": "Klick do zum e Aktion hinzuefüge",
"add_assets": "Mediä hinzuefüge",
"add_birthday": "Geburtstag hinzuefüge",
"add_endpoint": "Endpunkt hinzuefüge",
"add_exclusion_pattern": "Ausschlussmuster hinzufü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",
@@ -30,9 +34,11 @@
"add_to_album_bottom_sheet_added": "Zu {album} hinzugefügt",
"add_to_album_bottom_sheet_already_exists": "Bereits in {album}",
"add_to_album_bottom_sheet_some_local_assets": "Einige lokale Dateien konnten nicht zum Album hinzugefügt werden",
"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": "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 däzuefüege",
"added_to_archive": "Zum Archiv hinzugefügt",
@@ -161,10 +167,12 @@
},
"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_link": "Link aazeige",
"view_links": "Links aazeige"
}

File diff suppressed because it is too large Load Diff

View File

@@ -108,21 +108,6 @@
"image_thumbnail_quality_description": "Thumbnail quality from 1-100. Higher is better, but produces larger files and can reduce app responsiveness.",
"image_thumbnail_title": "Thumbnail Settings",
"import_config_from_json_description": "Import system config by uploading a JSON config file",
"integrity_checks_checksum_files": "Checksum files",
"integrity_checks_checksum_files_description": "Configure the checksum check",
"integrity_checks_checksum_files_enable_description": "Enable the checksum check",
"integrity_checks_checksum_files_percentage_limit": "Percentage limit",
"integrity_checks_checksum_files_percentage_limit_description": "Configure the maximum percentage between 0.01 and 1 for how much the checksum check should run each interval.",
"integrity_checks_checksum_files_time_limit": "Time limit",
"integrity_checks_checksum_files_time_limit_description": "Configure the maximum duration for which the checksum check should run each interval. (ms)",
"integrity_checks_missing_files": "Missing files",
"integrity_checks_missing_files_description": "Configure the frequency and enable or disable the missing files check",
"integrity_checks_missing_files_enable_description": "Enable the missing files check",
"integrity_checks_settings": "Integrity checks",
"integrity_checks_settings_description": "Manage integrity checks intervals",
"integrity_checks_untracked_files": "Untracked files",
"integrity_checks_untracked_files_description": "Configure the frequency and enable or disable the untracked files check",
"integrity_checks_untracked_files_enable_description": "Enable the untracked files check",
"job_concurrency": "{job} concurrency",
"job_created": "Job created",
"job_not_concurrency_safe": "This job is not concurrency-safe.",
@@ -431,10 +416,6 @@
"transcoding_realtime_description": "Allows transcoding to be performed in real-time as the video is being streamed. Enables quality switching, but may cause higher playback latency and stuttering depending on server capabilities.",
"transcoding_realtime_enabled": "Enable real-time transcoding",
"transcoding_realtime_enabled_description": "If disabled, the server will refuse to start new real-time transcoding sessions.",
"transcoding_realtime_resolutions": "Resolutions",
"transcoding_realtime_resolutions_description": "The resolutions offered for real-time transcoding. Higher resolutions may cause playback issues if the server cannot transcode them quickly enough.",
"transcoding_realtime_video_codecs": "Video codecs",
"transcoding_realtime_video_codecs_description": "The video codecs offered for real-time transcoding. Clients will choose the best option they support during playback. AV1 is more efficient than HEVC, which is more efficient than H.264. When using hardware acceleration, only select the codecs the accelerator can encode. When using software transcoding, note that H.264 is faster than AV1, which is faster than HEVC.",
"transcoding_reference_frames": "Reference frames",
"transcoding_reference_frames_description": "The number of frames to reference when compressing a given frame. Higher values improve compression efficiency, but slow down encoding. 0 sets this value automatically.",
"transcoding_required_description": "Only videos not in an accepted format",
@@ -597,7 +578,6 @@
"asset_viewer_settings_title": "Asset Viewer",
"assets": "Assets",
"assets_added_to_album_count": "Added {count, plural, one {# asset} other {# assets}} to the album",
"assets_added_to_album_partial_count": "Added {successCount} out of {totalCount} {totalCount, plural, one {asset} other {assets}} to the album",
"assets_added_to_albums_count": "Added {assetTotal, plural, one {# asset} other {# assets}} to {albumTotal, plural, one {# album} other {# albums}}",
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} cannot be added to the album",
"assets_cannot_be_added_to_albums": "{count, plural, one {Asset} other {Assets}} cannot be added to any of the albums",
@@ -814,6 +794,7 @@
"custom_date": "Custom date",
"custom_locale": "Custom locale",
"custom_locale_description": "Format dates, times, and numbers based on the selected language and region",
"custom_url": "Custom URL",
"cutoff_date_description": "Keep photos from the last…",
"cutoff_day": "{count, plural, one {day} other {days}}",
"cutoff_year": "{count, plural, one {year} other {years}}",
@@ -1480,7 +1461,6 @@
"never": "Never",
"new_album": "New Album",
"new_api_key": "New API Key",
"new_feature": "New Feature",
"new_password": "New password",
"new_person": "New person",
"new_pin_code": "New PIN code",
@@ -1527,9 +1507,6 @@
"notes": "Notes",
"nothing_here_yet": "Nothing here yet",
"notification_backup_reliability": "Enable notifications to improve background backup reliability",
"notification_enabled_list_tile_content": "Immich uses notifications for background backup. Manage them in your device settings.",
"notification_enabled_list_tile_open_button": "Open settings",
"notification_enabled_list_tile_title": "Notifications enabled",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications",
@@ -1541,8 +1518,6 @@
"obtainium_configurator": "Obtainium Configurator",
"obtainium_configurator_instructions": "Use Obtainium to install and update the Android app directly from Immich GitHub's release. Create an API key and select a variant to create your Obtainium configuration link",
"ocr": "OCR",
"ocr_body": "Immich now reads the text inside your photos, so you can search for them by what they say.",
"ocr_title": "Search text in your photos",
"official_immich_resources": "Official Immich Resources",
"offline": "Offline",
"offset": "Offset",
@@ -1561,8 +1536,6 @@
"open": "Open",
"open_calendar": "Open calendar",
"open_in_browser": "Open in browser",
"open_in_immich_body": "Set Immich as your gallery on Android to open photos straight from other apps.",
"open_in_immich_title": "Open photos in Immich",
"open_in_map_view": "Open in map view",
"open_in_openstreetmap": "Open in OpenStreetMap",
"open_the_search_filters": "Open the search filters",
@@ -1620,7 +1593,7 @@
"person": "Person",
"person_age_months": "{months, plural, one {# month} other {# months}} old",
"person_age_year_months": "1 year, {months, plural, one {# month} other {# months}} old",
"person_age_years": "{years, plural, one {# year} other {# years}} old",
"person_age_years": "{years, plural, other {# years}} old",
"person_birthdate": "Born on {date}",
"person_hidden": "{name}{hidden, select, true { (hidden)} other {}}",
"person_recognized": "Person recognized",
@@ -1721,10 +1694,7 @@
"recent": "Recent",
"recent_searches": "Recent searches",
"recently_added": "Recently added",
"recently_added_body": "Jump straight to everything you've added lately on a dedicated page.",
"recently_added_description": "Browse your assets sorted by when they were uploaded to Immich",
"recently_added_page_title": "Recently Added",
"recently_added_title": "Recently added",
"recently_taken": "Recently taken",
"refresh": "Refresh",
"refresh_encoded_videos": "Refresh encoded videos",
@@ -1931,8 +1901,6 @@
"share_link": "Share Link",
"share_original": "Use original (large)",
"share_preview": "Use thumbnail (small)",
"share_quality_body": "Press and hold the share button to choose the image quality before you share.",
"share_quality_title": "Choose your share quality",
"shared": "Shared",
"shared_album_activities_input_disable": "Comment is disabled",
"shared_album_activity_remove_content": "Do you want to delete this activity?",
@@ -1947,9 +1915,7 @@
"shared_link_app_bar_title": "Shared Links",
"shared_link_clipboard_copied_massage": "Copied to clipboard",
"shared_link_create_error": "Error while creating shared link",
"shared_link_custom_url_description": "Access this shared link with a custom URL name",
"shared_link_custom_url_title": "Custom URL",
"shared_link_custom_url_warning": "Warning: a custom URL name with a forward slash may not behave as you expect.",
"shared_link_custom_url_description": "Access this shared link with a custom URL",
"shared_link_edit_description_hint": "Enter the share description",
"shared_link_edit_expire_after_option_day": "1 day",
"shared_link_edit_expire_after_option_days": "{count} days",
@@ -2016,19 +1982,16 @@
"sign_out": "Sign Out",
"sign_up": "Sign up",
"size": "Size",
"skip": "Skip",
"skip_to_content": "Skip to content",
"skip_to_folders": "Skip to folders",
"skip_to_tags": "Skip to tags",
"slideshow": "Slideshow",
"slideshow_body": "Sit back and watch your photos play in a full-screen slideshow.",
"slideshow_metadata_overlay_mode": "Overlay content",
"slideshow_metadata_overlay_mode_description_only": "Description only",
"slideshow_metadata_overlay_mode_full": "Full",
"slideshow_repeat": "Repeat slideshow",
"slideshow_repeat_description": "Loop back to beginning when slideshow ends",
"slideshow_settings": "Slideshow settings",
"slideshow_title": "Slideshow",
"smart_album": "Smart album",
"some_assets_already_have_a_location_warning": "Some of the selected assets already have a location",
"sort_albums_by": "Sort albums by...",
@@ -2156,7 +2119,6 @@
"unknown": "Unknown",
"unknown_country": "Unknown Country",
"unknown_date": "Unknown date",
"unknown_schema": "Unknown schema",
"unknown_year": "Unknown Year",
"unlimited": "Unlimited",
"unlink_motion_video": "Unlink motion video",
@@ -2192,8 +2154,6 @@
"upload_status_errors": "Errors",
"upload_status_uploaded": "Uploaded",
"upload_success": "Upload success, refresh the page to see new upload assets.",
"upload_to_album_body": "For users that don't utilize the manual upload feature, you can now choose to add local photos directly into an album as you upload them, no need to upload then add to an album later anymore.",
"upload_to_album_title": "Upload straight to an album",
"upload_to_immich": "Upload to Immich ({count})",
"uploading": "Uploading",
"uploading_media": "Uploading media",
@@ -2261,9 +2221,6 @@
"week": "Week",
"welcome": "Welcome",
"welcome_to_immich": "Welcome to Immich",
"whats_new": "What's new",
"whats_new_settings_subtitle": "See what's new in Immich",
"whats_new_version": "Version {version}",
"when": "When",
"width": "Width",
"wifi_name": "Wi-Fi Name",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -16,12 +16,15 @@
"add_a_name": "افزودن نام",
"add_a_title": "افزودن عنوان",
"add_action": "افزودن عملیات",
"add_action_description": "برای افزودن و اعمال یک عملیات کلیک کنید",
"add_assets": "افزودن عکس یا فیلم",
"add_birthday": "افزودن تاریخ تولد",
"add_endpoint": "افزودن پایانه",
"add_exclusion_pattern": "افزودن الگوی استثنا",
"add_location": "افزودن مکان",
"add_more_users": "افزودن کاربرهای بیشتر",
"add_partner": "افزودن شریک",
"add_path": "افزودن مسیر",
"add_photos": "افزودن عکس ها",
"add_tag": "افزودن تگ",
"add_to": "افزودن به …",
@@ -29,9 +32,11 @@
"add_to_album_bottom_sheet_added": "به آلبوم {album} اضافه شد",
"add_to_album_bottom_sheet_already_exists": "قبلا در آلبوم {album} موجود است",
"add_to_album_bottom_sheet_some_local_assets": "برخی از محتواهای محلی را نشد به آلبوم اضافه کرد",
"add_to_album_toggle": "تغییر وضعیت انتخاب برای {album}",
"add_to_albums": "افزودن به آلبوم",
"add_to_albums_count": "افزودن به آلبوم ها {count}",
"add_to_bottom_bar": "افزودن به",
"add_to_shared_album": "افزودن به آلبوم اشتراکی",
"add_upload_to_stack": "افزودن فایل ارسالی به مجموعه",
"add_url": "افزودن آدرس URL",
"added_to_archive": "به آرشیو اضافه شد",
@@ -398,6 +403,7 @@
"all": "همه",
"all_people": "همه افراد",
"allow_dark_mode": "اجازه دادن به حالت تاریک",
"allow_edits": "اجازه ویرایش",
"api_key": "کلید API",
"api_keys": "کلیدهای API",
"app_settings": "تنظیمات برنامه",
@@ -418,6 +424,7 @@
"cannot_merge_people": "نمی‌توان افراد را ادغام کرد",
"cannot_update_the_description": "نمی‌توان توضیحات را به‌روزرسانی کرد",
"change_date": "تغییر تاریخ",
"change_expiration_time": "تغییر زمان انقضا",
"change_location": "تغییر مکان",
"change_name": "تغییر نام",
"change_name_successfully": "نام با موفقیت تغییر یافت",
@@ -433,6 +440,7 @@
"clear_value": "پاک کردن مقدار",
"close": "بستن",
"collapse_all": "جمع کردن همه",
"color_theme": "تم رنگ",
"comment_options": "گزینه‌های نظر",
"comments_are_disabled": "نظرات غیرفعال هستند",
"confirm": "تأیید",
@@ -444,6 +452,7 @@
"copied_image_to_clipboard": "تصویر به کلیپ‌بورد کپی شد.",
"copied_to_clipboard": "به کلیپ‌بورد کپی شد!",
"copy_error": "خطا در کپی",
"copy_file_path": "کپی مسیر فایل",
"copy_image": "کپی تصویر",
"copy_link": "کپی لینک",
"copy_link_to_clipboard": "کپی لینک به کلیپ‌بورد",
@@ -481,8 +490,10 @@
"details": "جزئیات",
"direction": "جهت",
"disabled": "غیرفعال",
"disallow_edits": "عدم اجازه ویرایش",
"discover": "کشف کردن",
"dismiss_all_errors": "رد تمام خطاها",
"dismiss_error": "رد خطا",
"display_options": "گزینه‌های نمایش",
"display_order": "ترتیب نمایش",
"display_original_photos": "نمایش عکس‌های اصلی",
@@ -565,6 +576,7 @@
"let_others_respond": "اجازه به دیگران برای پاسخ‌گویی",
"level": "سطح",
"library": "کتابخانه",
"library_options": "گزینه‌های کتابخانه",
"light": "روشن",
"link_to_oauth": "اتصال به OAuth",
"linked_oauth_account": "حساب OAuth متصل شده",
@@ -579,6 +591,7 @@
"main_branch_warning": "شما در حال استفاده از نسخه توسعه‌دهندگان هستید که آزمایشی و ناپایدار است. اکیداً توصیه می‌کنیم از نسخه رسمی استفاده کنید!",
"main_menu": "منوی اصلی",
"make": "ساختن",
"manage_shared_links": "مدیریت لینک‌های اشتراکی",
"manage_sharing_with_partners": "مدیریت محتوای مشترک با همسر",
"manage_the_app_settings": "مدیریت تنظیمات برنامه",
"manage_your_account": "مدیریت حساب کاربری",
@@ -586,7 +599,9 @@
"manage_your_devices": "مدیریت دستگاه‌های متصل",
"manage_your_oauth_connection": "مدیریت اتصال OAuth",
"map": "نقشه",
"map_assets_in_bounds": "{count} عکس ها",
"map_cannot_get_user_location": "موقعیت مکانی در دسترس نیست",
"map_location_dialog_yes": "بله",
"map_location_picker_page_use_location": "استفاده از این موقعیت مکانی",
"map_location_service_disabled_content": "برای نمایش دارایی‌ها بر اساس موقعیت مکانی، نیاز به فعال‌سازی سرویس مکان‌یابی دارید. می‌خواهید همین حالا فعال شود؟",
"map_location_service_disabled_title": "سرویس مکان‌یابی غیرفعال است",
@@ -599,6 +614,7 @@
"map_settings_date_range_option_days": "{days} روز گذشته",
"map_settings_date_range_option_year": "پارسال",
"map_settings_date_range_option_years": "{years} سال گذشته",
"map_settings_dialog_title": "تنظیمات نقشه",
"map_settings_include_show_archived": "شامل موارد بایگانی شده",
"map_settings_include_show_partners": "شامل همسر",
"matches": "تطابق‌ها",
@@ -697,9 +713,12 @@
"refresh": "تازه سازی",
"refreshed": "تازه سازی شد",
"remove": "حذف",
"remove_deleted_assets": "حذف محتواهای حذف‌شده",
"remove_from_album": "حذف از آلبوم",
"remove_from_favorites": "حذف از علاقه‌مندی‌ها",
"rename": "تغییر نام",
"repair": "تعمیر",
"replace_with_upload": "جایگزینی با آپلود",
"reset": "بازنشانی",
"reset_password": "بازنشانی رمز عبور",
"restore": "بازیابی",
@@ -713,6 +732,7 @@
"saved_settings": "تنظیمات ذخیره شد",
"say_something": "چیزی بگویید",
"scan_all_libraries": "اسکن همه کتابخانه‌ها",
"scan_settings": "تنظیمات اسکن",
"search": "جستجو",
"search_albums": "جستجوی آلبوم‌ها",
"search_by_context": "جستجو براساس زمینه",
@@ -733,6 +753,7 @@
"select_face": "انتخاب چهره",
"select_featured_photo": "انتخاب عکس ویژه",
"select_keep_all": "انتخاب نگهداری همه",
"select_library_owner": "انتخاب مالک کتابخانه",
"select_new_face": "انتخاب چهره جدید",
"select_photos": "انتخاب عکس‌ها",
"selected": "انتخاب شده",
@@ -816,6 +837,7 @@
"view": "مشاهده",
"view_all": "مشاهده همه",
"view_all_users": "مشاهده همه کاربران",
"view_links": "مشاهده لینک‌ها",
"view_next_asset": "مشاهده محتوای بعدی",
"view_previous_asset": "مشاهده محتوای قبلی",
"waiting": "در انتظار",

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
"active": "Tumatakbo",
"active_count": "Aktibo: {count}",
"activity": "Mga Aktibidad",
"activity_changed": "Ang aktibidad ay {enabled, select, true {naka-enable} other {hindi naka-enable}}",
"add": "Mag dagdag",
"add_a_description": "Dagdagan ng deskripsyon",
"add_a_location": "Dagdagan ng lugar",
@@ -20,7 +21,9 @@
"add_endpoint": "Dagdagan ng dulo",
"add_exclusion_pattern": "Magdagdag ng exlusion pattern",
"add_location": "Magdagdag ng lugar",
"add_more_users": "Magdagdag ng mga user",
"add_partner": "Magdagdag ng kasangga",
"add_path": "Magdagdag ng path",
"add_photos": "Magdagdag ng litrato",
"add_step": "Magdagdag ng step",
"add_tag": "Magdagdag ng tag",
@@ -29,9 +32,11 @@
"add_to_album_bottom_sheet_added": "Naidagdag sa {album}",
"add_to_album_bottom_sheet_already_exists": "Nasa {album} na",
"add_to_album_bottom_sheet_some_local_assets": "May ilang mga local assets ang hindi maidagdag sa album",
"add_to_album_toggle": "Toggle selection para sa {album}",
"add_to_albums": "Idagdag sa mga album",
"add_to_albums_count": "Idagdag sa mga album ({count})",
"add_to_bottom_bar": "Idagdag sa",
"add_to_shared_album": "Idagdag sa shared album",
"add_upload_to_stack": "Magdagdag ng upload para ma-stack",
"add_url": "Magdagdag ng URL",
"added_to_archive": "Naidagdag sa archive",
@@ -77,13 +82,16 @@
"server_welcome_message_description": "Mensahe na ipapakita sa login page.",
"user_restore_description": "Ang account ni <b>{user}</b> ay maibabalik."
},
"album_user_left": "Umalis sa {album}",
"all_albums": "Lahat ng albums",
"all_people": "Lahat ng tao",
"all_videos": "Lahat ng video",
"api_key_description": "Isang beses lamang na ipapakita itong value. Siguraduhin na ikopya itong value bago iclose ang window na ito.",
"are_these_the_same_person": "Itong tao na ito ay parehas?",
"asset_adding_to_album": "Dinadagdag sa album...",
"asset_filename_is_offline": "Offline ang asset {filename}",
"asset_uploading": "Ina-upload...",
"backup_controller_page_background_app_refresh_enable_button_text": "Pumunta sa settings",
"change_your_password": "Palitan ang iyong password",
"country": "Bansa",
"create_album_page_untitled": "Walang pamagat",
@@ -96,6 +104,7 @@
"edit_birthday": "I-edit ang birthday",
"edit_date": "I-edit ang petsa",
"edit_date_and_time": "I-edit ang petsa at oras",
"editor_close_without_save_title": "Isara ang editor?",
"explore": "I-explore",
"export": "I-export",
"has_quota": "May quota",

File diff suppressed because it is too large Load Diff

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