Merge branch 'main' into feat/duplicates-grid-view

This commit is contained in:
Arno Wiest 2025-05-20 19:36:33 +02:00
commit 0496c69ccf
145 changed files with 2626 additions and 4919 deletions
.github
cli
docker
docs
e2e
i18n
mobile
open-api
server

2
.github/.nvmrc vendored
View file

@ -1 +1 @@
22.15.0 22.15.1

View file

@ -84,7 +84,7 @@ runs:
- name: Build and push image - name: Build and push image
id: build id: build
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with: with:
context: ${{ inputs.context }} context: ${{ inputs.context }}
file: ${{ inputs.dockerfile }} file: ${{ inputs.dockerfile }}

View file

@ -96,7 +96,7 @@ jobs:
type=raw,value=latest,enable=${{ github.event_name == 'release' }} type=raw,value=latest,enable=${{ github.event_name == 'release' }}
- name: Build and push image - name: Build and push image
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0 uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with: with:
file: cli/Dockerfile file: cli/Dockerfile
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64

View file

@ -150,7 +150,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5 uses: gruntwork-io/terragrunt-action@aee21a7df999be8b471c2a8564c6cd853cb674e1 # v2.1.8
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -165,7 +165,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5 uses: gruntwork-io/terragrunt-action@aee21a7df999be8b471c2a8564c6cd853cb674e1 # v2.1.8
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -199,7 +199,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5 uses: gruntwork-io/terragrunt-action@aee21a7df999be8b471c2a8564c6cd853cb674e1 # v2.1.8
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'

View file

@ -25,7 +25,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5 uses: gruntwork-io/terragrunt-action@aee21a7df999be8b471c2a8564c6cd853cb674e1 # v2.1.8
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'

View file

@ -115,7 +115,7 @@ jobs:
packages: write packages: write
steps: steps:
- name: Download digests - name: Download digests
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with: with:
path: ${{ runner.temp }}/digests path: ${{ runner.temp }}/digests
pattern: ${{ needs.matrix.outputs.key }}-* pattern: ${{ needs.matrix.outputs.key }}-*

View file

@ -643,7 +643,7 @@ jobs:
contents: read contents: read
services: services:
postgres: postgres:
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 image: ghcr.io/immich-app/postgres:14@sha256:14bec5d02e8704081eafd566029204a4eb6bb75f3056cfb34e81c5ab1657a490
env: env:
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres POSTGRES_USER: postgres

View file

@ -1 +1 @@
22.15.0 22.15.1

10
cli/package-lock.json generated
View file

@ -27,7 +27,7 @@
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9", "@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0", "byte-size": "^9.0.0",
"cli-progress": "^3.12.0", "cli-progress": "^3.12.0",
@ -61,7 +61,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@ -1372,9 +1372,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.15.17", "version": "22.15.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==", "integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View file

@ -21,7 +21,7 @@
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9", "@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0", "byte-size": "^9.0.0",
"cli-progress": "^3.12.0", "cli-progress": "^3.12.0",
@ -69,6 +69,6 @@
"micromatch": "^4.0.8" "micromatch": "^4.0.8"
}, },
"volta": { "volta": {
"node": "22.15.0" "node": "22.15.1"
} }
} }

View file

@ -122,7 +122,7 @@ services:
database: database:
container_name: immich_postgres container_name: immich_postgres
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
env_file: env_file:
- .env - .env
environment: environment:
@ -134,24 +134,6 @@ services:
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data - ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
ports: ports:
- 5432:5432 - 5432:5432
healthcheck:
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics # set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
# immich-prometheus: # immich-prometheus:

View file

@ -63,7 +63,7 @@ services:
database: database:
container_name: immich_postgres container_name: immich_postgres
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
env_file: env_file:
- .env - .env
environment: environment:
@ -75,24 +75,6 @@ services:
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data - ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
ports: ports:
- 5432:5432 - 5432:5432
healthcheck:
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
restart: always restart: always
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics # set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
@ -100,7 +82,7 @@ services:
container_name: immich_prometheus container_name: immich_prometheus
ports: ports:
- 9090:9090 - 9090:9090
image: prom/prometheus@sha256:e2b8aa62b64855956e3ec1e18b4f9387fb6203174a4471936f4662f437f04405 image: prom/prometheus@sha256:78ed1f9050eb9eaf766af6e580230b1c4965728650e332cd1ee918c0c4699775
volumes: volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml - ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus - prometheus-data:/prometheus

View file

@ -56,7 +56,7 @@ services:
database: database:
container_name: immich_postgres container_name: immich_postgres
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
environment: environment:
POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME} POSTGRES_USER: ${DB_USERNAME}
@ -65,24 +65,8 @@ services:
volumes: volumes:
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
healthcheck: # change ssd below to hdd if you are using a hard disk drive or other slow storage
test: >- command: postgres -c config_file=/etc/postgresql/postgresql.ssd.conf
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
echo "checksum failure count is $$Chksum";
[ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command: >-
postgres
-c shared_preload_libraries=vectors.so
-c 'search_path="$$user", public, vectors'
-c logging_collector=on
-c max_wal_size=2GB
-c shared_buffers=512MB
-c wal_compression=on
restart: always restart: always
volumes: volumes:

View file

@ -1 +1 @@
22.15.0 22.15.1

View file

@ -10,12 +10,12 @@ Running with a pre-existing Postgres server can unlock powerful administrative f
## Prerequisites ## Prerequisites
You must install pgvecto.rs into your instance of Postgres using their [instructions][vectors-install]. After installation, add `shared_preload_libraries = 'vectors.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vectors.so'`. You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
:::note :::note
Immich is known to work with Postgres versions 14, 15, and 16. Earlier versions are unsupported. Postgres 17 is nominally compatible, but pgvecto.rs does not have prebuilt images or packages for it as of writing. Immich is known to work with Postgres versions 14, 15, 16 and 17. Earlier versions are unsupported.
Make sure the installed version of pgvecto.rs is compatible with your version of Immich. The current accepted range for pgvecto.rs is `>= 0.2.0, < 0.4.0`. Make sure the installed version of VectorChord is compatible with your version of Immich. The current accepted range for VectorChord is `>= 0.3.0, < 1.0.0`.
::: :::
## Specifying the connection URL ## Specifying the connection URL
@ -53,16 +53,75 @@ CREATE DATABASE <immichdatabasename>;
\c <immichdatabasename> \c <immichdatabasename>
BEGIN; BEGIN;
ALTER DATABASE <immichdatabasename> OWNER TO <immichdbusername>; ALTER DATABASE <immichdatabasename> OWNER TO <immichdbusername>;
CREATE EXTENSION vectors; CREATE EXTENSION vchord CASCADE;
CREATE EXTENSION earthdistance CASCADE; CREATE EXTENSION earthdistance CASCADE;
ALTER DATABASE <immichdatabasename> SET search_path TO "$user", public, vectors;
ALTER SCHEMA vectors OWNER TO <immichdbusername>;
COMMIT; COMMIT;
``` ```
### Updating pgvecto.rs ### Updating VectorChord
When installing a new version of pgvecto.rs, you will need to manually update the extension by connecting to the Immich database and running `ALTER EXTENSION vectors UPDATE;`. When installing a new version of VectorChord, you will need to manually update the extension by connecting to the Immich database and running `ALTER EXTENSION vchord UPDATE;`.
## Migrating to VectorChord
VectorChord is the successor extension to pgvecto.rs, allowing for higher performance, lower memory usage and higher quality results for smart search and facial recognition.
### Migrating from pgvecto.rs
Support for pgvecto.rs will be dropped in a later release, hence we recommend all users currently using pgvecto.rs to migrate to VectorChord at their convenience. There are two primary approaches to do so.
The easiest option is to have both extensions installed during the migration:
1. Ensure you still have pgvecto.rs installed
2. [Install VectorChord][vchord-install]
3. Add `shared_preload_libraries= 'vchord.so, vectors.so'` to your `postgresql.conf`, making sure to include _both_ `vchord.so` and `vectors.so`. You may include other libraries here as well if needed
4. If Immich does not have superuser permissions, run the SQL command `CREATE EXTENSION vchord CASCADE;` using psql or your choice of database client
5. Start Immich and wait for the logs `Reindexed face_index` and `Reindexed clip_index` to be output
6. Remove the `vectors.so` entry from the `shared_preload_libraries` setting
7. Uninstall pgvecto.rs (e.g. `apt-get purge vectors-pg14` on Debian-based environments, replacing `pg14` as appropriate)
If it is not possible to have both VectorChord and pgvector.s installed at the same time, you can perform the migration with more manual steps:
1. While pgvecto.rs is still installed, run the following SQL command using psql or your choice of database client. Take note of the number outputted by this command as you will need it later
```sql
SELECT atttypmod as dimsize
FROM pg_attribute f
JOIN pg_class c ON c.oid = f.attrelid
WHERE c.relkind = 'r'::char
AND f.attnum > 0
AND c.relname = 'smart_search'::text
AND f.attname = 'embedding'::text;
```
2. Remove references to pgvecto.rs using the below SQL commands
```sql
DROP INDEX IF EXISTS clip_index;
DROP INDEX IF EXISTS face_index;
ALTER TABLE smart_search ALTER COLUMN embedding SET DATA TYPE real[];
ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE real[];
```
3. [Install VectorChord][vchord-install]
4. Change the columns back to the appropriate vector types, replacing `<number>` with the number from step 1
```sql
CREATE EXTENSION IF NOT EXISTS vchord CASCADE;
ALTER TABLE smart_search ALTER COLUMN embedding SET DATA TYPE vector(<number>);
ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE vector(512);
```
5. Start Immich and let it create new indices using VectorChord
### Migrating from pgvector
1. Ensure you have at least 0.7.0 of pgvector installed. If it is below that, please upgrade it and run the SQL command `ALTER EXTENSION vector UPDATE;` using psql or your choice of database client
2. Follow the Prerequisites to install VectorChord
3. If Immich does not have superuser permissions, run the SQL command `CREATE EXTENSION vchord CASCADE;`
4. Start Immich and let it create new indices using VectorChord
Note that VectorChord itself uses pgvector types, so you should not uninstall pgvector after following these steps.
### Common errors ### Common errors
@ -70,4 +129,4 @@ When installing a new version of pgvecto.rs, you will need to manually update th
If you get the error `driverError: error: permission denied for view pg_vector_index_stat`, you can fix this by connecting to the Immich database and running `GRANT SELECT ON TABLE pg_vector_index_stat TO <immichdbusername>;`. If you get the error `driverError: error: permission denied for view pg_vector_index_stat`, you can fix this by connecting to the Immich database and running `GRANT SELECT ON TABLE pg_vector_index_stat TO <immichdbusername>;`.
[vectors-install]: https://docs.vectorchord.ai/getting-started/installation.html [vchord-install]: https://docs.vectorchord.ai/vectorchord/getting-started/installation.html

View file

@ -5,7 +5,7 @@ import TabItem from '@theme/TabItem';
Immich uses Postgres as its search database for both metadata and contextual CLIP search. Immich uses Postgres as its search database for both metadata and contextual CLIP search.
Contextual CLIP search is powered by the [pgvecto.rs](https://github.com/tensorchord/pgvecto.rs) extension, utilizing machine learning models like [CLIP](https://openai.com/research/clip) to provide relevant search results. This allows for freeform searches without requiring specific keywords in the image or video metadata. Contextual CLIP search is powered by the [VectorChord](https://github.com/tensorchord/VectorChord) extension, utilizing machine learning models like [CLIP](https://openai.com/research/clip) to provide relevant search results. This allows for freeform searches without requiring specific keywords in the image or video metadata.
## Advanced Search Filters ## Advanced Search Filters

View file

@ -72,21 +72,21 @@ Information on the current workers can be found [here](/docs/administration/jobs
## Database ## Database
| Variable | Description | Default | Containers | | Variable | Description | Default | Containers |
| :---------------------------------- | :----------------------------------------------------------------------- | :----------: | :----------------------------- | | :---------------------------------- | :--------------------------------------------------------------------------- | :--------: | :----------------------------- |
| `DB_URL` | Database URL | | server | | `DB_URL` | Database URL | | server |
| `DB_HOSTNAME` | Database host | `database` | server | | `DB_HOSTNAME` | Database host | `database` | server |
| `DB_PORT` | Database port | `5432` | server | | `DB_PORT` | Database port | `5432` | server |
| `DB_USERNAME` | Database user | `postgres` | server, database<sup>\*1</sup> | | `DB_USERNAME` | Database user | `postgres` | server, database<sup>\*1</sup> |
| `DB_PASSWORD` | Database password | `postgres` | server, database<sup>\*1</sup> | | `DB_PASSWORD` | Database password | `postgres` | server, database<sup>\*1</sup> |
| `DB_DATABASE_NAME` | Database name | `immich` | server, database<sup>\*1</sup> | | `DB_DATABASE_NAME` | Database name | `immich` | server, database<sup>\*1</sup> |
| `DB_SSL_MODE` | Database SSL mode | | server | | `DB_SSL_MODE` | Database SSL mode | | server |
| `DB_VECTOR_EXTENSION`<sup>\*2</sup> | Database vector extension (one of [`pgvector`, `pgvecto.rs`]) | `pgvecto.rs` | server | | `DB_VECTOR_EXTENSION`<sup>\*2</sup> | Database vector extension (one of [`vectorchord`, `pgvector`, `pgvecto.rs`]) | | server |
| `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server | | `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server |
\*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`. \*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: This setting cannot be changed after the server has successfully started up. \*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.
:::info :::info

View file

@ -57,6 +57,6 @@
"node": ">=20" "node": ">=20"
}, },
"volta": { "volta": {
"node": "22.15.0" "node": "22.15.1"
} }
} }

View file

@ -1 +1 @@
22.15.0 22.15.1

View file

@ -37,8 +37,8 @@ services:
image: redis:6.2-alpine@sha256:3211c33a618c457e5d241922c975dbc4f446d0bdb2dc75694f5573ef8e2d01fa image: redis:6.2-alpine@sha256:3211c33a618c457e5d241922c975dbc4f446d0bdb2dc75694f5573ef8e2d01fa
database: database:
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 image: ghcr.io/immich-app/postgres:14
command: -c fsync=off -c shared_preload_libraries=vectors.so command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf
environment: environment:
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres POSTGRES_USER: postgres

12
e2e/package-lock.json generated
View file

@ -15,7 +15,7 @@
"@immich/sdk": "file:../open-api/typescript-sdk", "@immich/sdk": "file:../open-api/typescript-sdk",
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@types/oidc-provider": "^8.5.1", "@types/oidc-provider": "^8.5.1",
"@types/pg": "^8.15.1", "@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4", "@types/pngjs": "^6.0.4",
@ -66,7 +66,7 @@
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9", "@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0", "byte-size": "^9.0.0",
"cli-progress": "^3.12.0", "cli-progress": "^3.12.0",
@ -100,7 +100,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@ -1593,9 +1593,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.15.17", "version": "22.15.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==", "integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View file

@ -25,7 +25,7 @@
"@immich/sdk": "file:../open-api/typescript-sdk", "@immich/sdk": "file:../open-api/typescript-sdk",
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@types/oidc-provider": "^8.5.1", "@types/oidc-provider": "^8.5.1",
"@types/pg": "^8.15.1", "@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4", "@types/pngjs": "^6.0.4",
@ -52,6 +52,6 @@
"vitest": "^3.0.0" "vitest": "^3.0.0"
}, },
"volta": { "volta": {
"node": "22.15.0" "node": "22.15.1"
} }
} }

View file

@ -76,7 +76,6 @@
"library_watching_settings_description": "Dəyişdirilən faylları avtomatik olaraq yoxla", "library_watching_settings_description": "Dəyişdirilən faylları avtomatik olaraq yoxla",
"logging_enable_description": "Jurnalı aktivləşdir", "logging_enable_description": "Jurnalı aktivləşdir",
"logging_level_description": "Aktiv edildikdə hansı jurnal səviyyəsi istifadə olunur.", "logging_level_description": "Aktiv edildikdə hansı jurnal səviyyəsi istifadə olunur.",
"logging_settings": "",
"machine_learning_clip_model": "CLIP modeli", "machine_learning_clip_model": "CLIP modeli",
"machine_learning_clip_model_description": "<link>Burada</link>qeyd olunan CLIP modelinin adı. Modeli dəyişdirdikdən sonra bütün şəkillər üçün 'Ağıllı Axtarış' funksiyasını yenidən işə salmalısınız.", "machine_learning_clip_model_description": "<link>Burada</link>qeyd olunan CLIP modelinin adı. Modeli dəyişdirdikdən sonra bütün şəkillər üçün 'Ağıllı Axtarış' funksiyasını yenidən işə salmalısınız.",
"machine_learning_duplicate_detection": "Dublikat Aşkarlama", "machine_learning_duplicate_detection": "Dublikat Aşkarlama",

View file

@ -3,8 +3,6 @@
"account": "Akaont", "account": "Akaont",
"account_settings": "Seting blo Akaont", "account_settings": "Seting blo Akaont",
"acknowledge": "Akcept", "acknowledge": "Akcept",
"action": "",
"actions": "",
"active": "Stap Mekem", "active": "Stap Mekem",
"activity": "Wanem hemi Mekem", "activity": "Wanem hemi Mekem",
"activity_changed": "WAnem hemi Mekem hemi", "activity_changed": "WAnem hemi Mekem hemi",
@ -16,845 +14,5 @@
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot", "add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
"add_import_path": "Putem wan pat blo import", "add_import_path": "Putem wan pat blo import",
"add_location": "Putem wan place blo hem", "add_location": "Putem wan place blo hem",
"add_more_users": "Putem mor man", "add_more_users": "Putem mor man"
"add_partner": "",
"add_path": "",
"add_photos": "",
"add_to": "",
"add_to_album": "",
"add_to_shared_album": "",
"admin": {
"add_exclusion_pattern_description": "",
"authentication_settings": "",
"authentication_settings_description": "",
"background_task_job": "",
"check_all": "",
"config_set_by_file": "",
"confirm_delete_library": "",
"confirm_delete_library_assets": "",
"confirm_email_below": "",
"confirm_reprocess_all_faces": "",
"confirm_user_password_reset": "",
"disable_login": "",
"duplicate_detection_job_description": "",
"exclusion_pattern_description": "",
"external_library_created_at": "",
"external_library_management": "",
"face_detection": "",
"face_detection_description": "",
"facial_recognition_job_description": "",
"force_delete_user_warning": "",
"forcing_refresh_library_files": "",
"image_format_description": "",
"image_prefer_embedded_preview": "",
"image_prefer_embedded_preview_setting_description": "",
"image_prefer_wide_gamut": "",
"image_prefer_wide_gamut_setting_description": "",
"image_quality": "",
"image_settings": "",
"image_settings_description": "",
"job_concurrency": "",
"job_not_concurrency_safe": "",
"job_settings": "",
"job_settings_description": "",
"job_status": "",
"jobs_delayed": "",
"jobs_failed": "",
"library_created": "",
"library_deleted": "",
"library_import_path_description": "",
"library_scanning": "",
"library_scanning_description": "",
"library_scanning_enable_description": "",
"library_settings": "",
"library_settings_description": "",
"library_tasks_description": "",
"library_watching_enable_description": "",
"library_watching_settings": "",
"library_watching_settings_description": "",
"logging_enable_description": "",
"logging_level_description": "",
"logging_settings": "",
"machine_learning_clip_model": "",
"machine_learning_duplicate_detection": "",
"machine_learning_duplicate_detection_enabled_description": "",
"machine_learning_duplicate_detection_setting_description": "",
"machine_learning_enabled_description": "",
"machine_learning_facial_recognition": "",
"machine_learning_facial_recognition_description": "",
"machine_learning_facial_recognition_model": "",
"machine_learning_facial_recognition_model_description": "",
"machine_learning_facial_recognition_setting_description": "",
"machine_learning_max_detection_distance": "",
"machine_learning_max_detection_distance_description": "",
"machine_learning_max_recognition_distance": "",
"machine_learning_max_recognition_distance_description": "",
"machine_learning_min_detection_score": "",
"machine_learning_min_detection_score_description": "",
"machine_learning_min_recognized_faces": "",
"machine_learning_min_recognized_faces_description": "",
"machine_learning_settings": "",
"machine_learning_settings_description": "",
"machine_learning_smart_search": "",
"machine_learning_smart_search_description": "",
"machine_learning_smart_search_enabled_description": "",
"machine_learning_url_description": "",
"manage_concurrency": "",
"manage_log_settings": "",
"map_dark_style": "",
"map_enable_description": "",
"map_light_style": "",
"map_reverse_geocoding": "",
"map_reverse_geocoding_enable_description": "",
"map_reverse_geocoding_settings": "",
"map_settings": "",
"map_settings_description": "",
"map_style_description": "",
"metadata_extraction_job": "",
"metadata_extraction_job_description": "",
"migration_job": "",
"migration_job_description": "",
"no_paths_added": "",
"no_pattern_added": "",
"note_apply_storage_label_previous_assets": "",
"note_cannot_be_changed_later": "",
"notification_email_from_address": "",
"notification_email_from_address_description": "",
"notification_email_host_description": "",
"notification_email_ignore_certificate_errors": "",
"notification_email_ignore_certificate_errors_description": "",
"notification_email_password_description": "",
"notification_email_port_description": "",
"notification_email_sent_test_email_button": "",
"notification_email_setting_description": "",
"notification_email_test_email_failed": "",
"notification_email_test_email_sent": "",
"notification_email_username_description": "",
"notification_enable_email_notifications": "",
"notification_settings": "",
"notification_settings_description": "",
"oauth_auto_launch": "",
"oauth_auto_launch_description": "",
"oauth_auto_register": "",
"oauth_auto_register_description": "",
"oauth_button_text": "",
"oauth_enable_description": "",
"oauth_mobile_redirect_uri": "",
"oauth_mobile_redirect_uri_override": "",
"oauth_mobile_redirect_uri_override_description": "",
"oauth_settings": "",
"oauth_settings_description": "",
"oauth_storage_label_claim": "",
"oauth_storage_label_claim_description": "",
"oauth_storage_quota_claim": "",
"oauth_storage_quota_claim_description": "",
"oauth_storage_quota_default": "",
"oauth_storage_quota_default_description": "",
"offline_paths": "",
"offline_paths_description": "",
"password_enable_description": "",
"password_settings": "",
"password_settings_description": "",
"paths_validated_successfully": "",
"quota_size_gib": "",
"refreshing_all_libraries": "",
"repair_all": "",
"repair_matched_items": "",
"repaired_items": "",
"require_password_change_on_login": "",
"reset_settings_to_default": "",
"reset_settings_to_recent_saved": "",
"send_welcome_email": "",
"server_external_domain_settings": "",
"server_external_domain_settings_description": "",
"server_settings": "",
"server_settings_description": "",
"server_welcome_message": "",
"server_welcome_message_description": "",
"sidecar_job": "",
"sidecar_job_description": "",
"slideshow_duration_description": "",
"smart_search_job_description": "",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "",
"storage_template_hash_verification_enabled_description": "",
"storage_template_migration": "",
"storage_template_migration_job": "",
"storage_template_settings": "",
"storage_template_settings_description": "",
"system_settings": "",
"theme_custom_css_settings": "",
"theme_custom_css_settings_description": "",
"theme_settings": "",
"theme_settings_description": "",
"these_files_matched_by_checksum": "",
"thumbnail_generation_job": "",
"thumbnail_generation_job_description": "",
"transcoding_acceleration_api": "",
"transcoding_acceleration_api_description": "",
"transcoding_acceleration_nvenc": "",
"transcoding_acceleration_qsv": "",
"transcoding_acceleration_rkmpp": "",
"transcoding_acceleration_vaapi": "",
"transcoding_accepted_audio_codecs": "",
"transcoding_accepted_audio_codecs_description": "",
"transcoding_accepted_video_codecs": "",
"transcoding_accepted_video_codecs_description": "",
"transcoding_advanced_options_description": "",
"transcoding_audio_codec": "",
"transcoding_audio_codec_description": "",
"transcoding_bitrate_description": "",
"transcoding_constant_quality_mode": "",
"transcoding_constant_quality_mode_description": "",
"transcoding_constant_rate_factor": "",
"transcoding_constant_rate_factor_description": "",
"transcoding_disabled_description": "",
"transcoding_hardware_acceleration": "",
"transcoding_hardware_acceleration_description": "",
"transcoding_hardware_decoding": "",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "",
"transcoding_max_b_frames": "",
"transcoding_max_b_frames_description": "",
"transcoding_max_bitrate": "",
"transcoding_max_bitrate_description": "",
"transcoding_max_keyframe_interval": "",
"transcoding_max_keyframe_interval_description": "",
"transcoding_optimal_description": "",
"transcoding_preferred_hardware_device": "",
"transcoding_preferred_hardware_device_description": "",
"transcoding_preset_preset": "",
"transcoding_preset_preset_description": "",
"transcoding_reference_frames": "",
"transcoding_reference_frames_description": "",
"transcoding_required_description": "",
"transcoding_settings": "",
"transcoding_settings_description": "",
"transcoding_target_resolution": "",
"transcoding_target_resolution_description": "",
"transcoding_temporal_aq": "",
"transcoding_temporal_aq_description": "",
"transcoding_threads": "",
"transcoding_threads_description": "",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "",
"transcoding_transcode_policy": "",
"transcoding_transcode_policy_description": "",
"transcoding_two_pass_encoding": "",
"transcoding_two_pass_encoding_setting_description": "",
"transcoding_video_codec": "",
"transcoding_video_codec_description": "",
"trash_enabled_description": "",
"trash_number_of_days": "",
"trash_number_of_days_description": "",
"trash_settings": "",
"trash_settings_description": "",
"untracked_files": "",
"untracked_files_description": "",
"user_delete_delay_settings": "",
"user_delete_delay_settings_description": "",
"user_management": "",
"user_password_has_been_reset": "",
"user_password_reset_description": "",
"user_settings": "",
"user_settings_description": "",
"user_successfully_removed": "",
"version_check_enabled_description": "",
"version_check_settings": "",
"version_check_settings_description": "",
"video_conversion_job": "",
"video_conversion_job_description": ""
},
"admin_email": "",
"admin_password": "",
"administration": "",
"advanced": "",
"album_added": "",
"album_added_notification_setting_description": "",
"album_cover_updated": "",
"album_info_updated": "",
"album_name": "",
"album_options": "",
"album_updated": "",
"album_updated_setting_description": "",
"albums": "",
"albums_count": "",
"all": "",
"all_people": "",
"allow_dark_mode": "",
"allow_edits": "",
"api_key": "",
"api_keys": "",
"app_settings": "",
"appears_in": "",
"archive": "",
"archive_or_unarchive_photo": "",
"asset_offline": "",
"assets": "",
"authorized_devices": "",
"back": "",
"backward": "",
"blurred_background": "",
"camera": "",
"camera_brand": "",
"camera_model": "",
"cancel": "",
"cancel_search": "",
"cannot_merge_people": "",
"cannot_update_the_description": "",
"change_date": "",
"change_expiration_time": "",
"change_location": "",
"change_name": "",
"change_name_successfully": "",
"change_password": "",
"change_your_password": "",
"changed_visibility_successfully": "",
"check_all": "",
"check_logs": "",
"choose_matching_people_to_merge": "",
"city": "",
"clear": "",
"clear_all": "",
"clear_message": "",
"clear_value": "",
"close": "",
"collapse_all": "",
"color_theme": "",
"comment_options": "",
"comments_are_disabled": "",
"confirm": "",
"confirm_admin_password": "",
"confirm_delete_shared_link": "",
"confirm_password": "",
"contain": "",
"context": "",
"continue": "",
"copied_image_to_clipboard": "",
"copied_to_clipboard": "",
"copy_error": "",
"copy_file_path": "",
"copy_image": "",
"copy_link": "",
"copy_link_to_clipboard": "",
"copy_password": "",
"copy_to_clipboard": "",
"country": "",
"cover": "",
"covers": "",
"create": "",
"create_album": "",
"create_library": "",
"create_link": "",
"create_link_to_share": "",
"create_new_person": "",
"create_new_user": "",
"create_user": "",
"created": "",
"current_device": "",
"custom_locale": "",
"custom_locale_description": "",
"dark": "",
"date_after": "",
"date_and_time": "",
"date_before": "",
"date_range": "",
"day": "",
"default_locale": "",
"default_locale_description": "",
"delete": "",
"delete_album": "",
"delete_api_key_prompt": "",
"delete_key": "",
"delete_library": "",
"delete_link": "",
"delete_shared_link": "",
"delete_user": "",
"deleted_shared_link": "",
"description": "",
"details": "",
"direction": "",
"disabled": "",
"disallow_edits": "",
"discover": "",
"dismiss_all_errors": "",
"dismiss_error": "",
"display_options": "",
"display_order": "",
"display_original_photos": "",
"display_original_photos_setting_description": "",
"done": "",
"download": "",
"downloading": "",
"duration": "",
"edit_album": "",
"edit_avatar": "",
"edit_date": "",
"edit_date_and_time": "",
"edit_exclusion_pattern": "",
"edit_faces": "",
"edit_import_path": "",
"edit_import_paths": "",
"edit_key": "",
"edit_link": "",
"edit_location": "",
"edit_name": "",
"edit_people": "",
"edit_title": "",
"edit_user": "",
"edited": "",
"editor": "",
"email": "",
"empty_trash": "",
"enable": "",
"enabled": "",
"end_date": "",
"error": "",
"error_loading_image": "",
"errors": {
"cleared_jobs": "",
"exclusion_pattern_already_exists": "",
"failed_job_command": "",
"import_path_already_exists": "",
"paths_validation_failed": "",
"quota_higher_than_disk_size": "",
"repair_unable_to_check_items": "",
"unable_to_add_album_users": "",
"unable_to_add_comment": "",
"unable_to_add_exclusion_pattern": "",
"unable_to_add_import_path": "",
"unable_to_add_partners": "",
"unable_to_change_album_user_role": "",
"unable_to_change_date": "",
"unable_to_change_location": "",
"unable_to_change_password": "",
"unable_to_copy_to_clipboard": "",
"unable_to_create_api_key": "",
"unable_to_create_library": "",
"unable_to_create_user": "",
"unable_to_delete_album": "",
"unable_to_delete_asset": "",
"unable_to_delete_exclusion_pattern": "",
"unable_to_delete_import_path": "",
"unable_to_delete_shared_link": "",
"unable_to_delete_user": "",
"unable_to_edit_exclusion_pattern": "",
"unable_to_edit_import_path": "",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "",
"unable_to_exit_fullscreen": "",
"unable_to_hide_person": "",
"unable_to_link_oauth_account": "",
"unable_to_load_album": "",
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_play_video": "",
"unable_to_refresh_user": "",
"unable_to_remove_album_users": "",
"unable_to_remove_api_key": "",
"unable_to_remove_deleted_assets": "",
"unable_to_remove_library": "",
"unable_to_remove_partner": "",
"unable_to_remove_reaction": "",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_api_key": "",
"unable_to_save_name": "",
"unable_to_save_profile": "",
"unable_to_save_settings": "",
"unable_to_scan_libraries": "",
"unable_to_scan_library": "",
"unable_to_set_profile_picture": "",
"unable_to_submit_job": "",
"unable_to_trash_asset": "",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_timeline_display_status": "",
"unable_to_update_user": ""
},
"exit_slideshow": "",
"expand_all": "",
"expire_after": "",
"expired": "",
"explore": "",
"export": "",
"export_as_json": "",
"extension": "",
"external": "",
"external_libraries": "",
"favorite": "",
"favorite_or_unfavorite_photo": "",
"favorites": "",
"feature_photo_updated": "",
"file_name": "",
"file_name_or_extension": "",
"filename": "",
"filetype": "",
"filter_people": "",
"find_them_fast": "",
"fix_incorrect_match": "",
"forward": "",
"general": "",
"get_help": "",
"getting_started": "",
"go_back": "",
"go_to_search": "",
"group_albums_by": "",
"has_quota": "",
"hide_gallery": "",
"hide_password": "",
"hide_person": "",
"host": "",
"hour": "",
"image": "",
"immich_logo": "",
"import_from_json": "",
"import_path": "",
"in_archive": "",
"include_archived": "",
"include_shared_albums": "",
"include_shared_partner_assets": "",
"individual_share": "",
"info": "",
"interval": {
"day_at_onepm": "",
"hours": "",
"night_at_midnight": "",
"night_at_twoam": ""
},
"invite_people": "",
"invite_to_album": "",
"jobs": "",
"keep": "",
"keyboard_shortcuts": "",
"language": "",
"language_setting_description": "",
"last_seen": "",
"leave": "",
"let_others_respond": "",
"level": "",
"library": "",
"library_options": "",
"light": "",
"link_options": "",
"link_to_oauth": "",
"linked_oauth_account": "",
"list": "",
"loading": "",
"loading_search_results_failed": "",
"log_out": "",
"log_out_all_devices": "",
"login_has_been_disabled": "",
"look": "",
"loop_videos": "",
"loop_videos_description": "",
"make": "",
"manage_shared_links": "",
"manage_sharing_with_partners": "",
"manage_the_app_settings": "",
"manage_your_account": "",
"manage_your_api_keys": "",
"manage_your_devices": "",
"manage_your_oauth_connection": "",
"map": "",
"map_marker_with_image": "",
"map_settings": "",
"matches": "",
"media_type": "",
"memories": "",
"memories_setting_description": "",
"menu": "",
"merge": "",
"merge_people": "",
"merge_people_successfully": "",
"minimize": "",
"minute": "",
"missing": "",
"model": "",
"month": "",
"more": "",
"moved_to_trash": "",
"my_albums": "",
"name": "",
"name_or_nickname": "",
"never": "",
"new_api_key": "",
"new_password": "",
"new_person": "",
"new_user_created": "",
"newest_first": "",
"next": "",
"next_memory": "",
"no": "",
"no_albums_message": "",
"no_archived_assets_message": "",
"no_assets_message": "",
"no_duplicates_found": "",
"no_exif_info_available": "",
"no_explore_results_message": "",
"no_favorites_message": "",
"no_libraries_message": "",
"no_name": "",
"no_places": "",
"no_results": "",
"no_shared_albums_message": "",
"not_in_any_album": "",
"note_apply_storage_label_to_previously_uploaded assets": "",
"notes": "",
"notification_toggle_setting_description": "",
"notifications": "",
"notifications_setting_description": "",
"oauth": "",
"offline": "",
"offline_paths": "",
"offline_paths_description": "",
"ok": "",
"oldest_first": "",
"online": "",
"only_favorites": "",
"open_the_search_filters": "",
"options": "",
"organize_your_library": "",
"other": "",
"other_devices": "",
"other_variables": "",
"owned": "",
"owner": "",
"partner_can_access": "",
"partner_can_access_assets": "",
"partner_can_access_location": "",
"partner_sharing": "",
"partners": "",
"password": "",
"password_does_not_match": "",
"password_required": "",
"password_reset_success": "",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "",
"pattern": "",
"pause": "",
"pause_memories": "",
"paused": "",
"pending": "",
"people": "",
"people_sidebar_description": "",
"permanent_deletion_warning": "",
"permanent_deletion_warning_setting_description": "",
"permanently_delete": "",
"permanently_deleted_asset": "",
"photos": "",
"photos_count": "",
"photos_from_previous_years": "",
"pick_a_location": "",
"place": "",
"places": "",
"play": "",
"play_memories": "",
"play_motion_photo": "",
"play_or_pause_video": "",
"port": "",
"preset": "",
"preview": "",
"previous": "",
"previous_memory": "",
"previous_or_next_photo": "",
"primary": "",
"profile_picture_set": "",
"public_share": "",
"reaction_options": "",
"read_changelog": "",
"recent": "",
"recent_searches": "",
"refresh": "",
"refreshed": "",
"refreshes_every_file": "",
"remove": "",
"remove_deleted_assets": "",
"remove_from_album": "",
"remove_from_favorites": "",
"remove_from_shared_link": "",
"removed_api_key": "",
"rename": "",
"repair": "",
"repair_no_results_message": "",
"replace_with_upload": "",
"require_password": "",
"require_user_to_change_password_on_first_login": "",
"reset": "",
"reset_password": "",
"reset_people_visibility": "",
"restore": "",
"restore_all": "",
"restore_user": "",
"resume": "",
"retry_upload": "",
"review_duplicates": "",
"role": "",
"save": "",
"saved_api_key": "",
"saved_profile": "",
"saved_settings": "",
"say_something": "",
"scan_all_libraries": "",
"scan_settings": "",
"search": "",
"search_albums": "",
"search_by_context": "",
"search_camera_make": "",
"search_camera_model": "",
"search_city": "",
"search_country": "",
"search_for_existing_person": "",
"search_people": "",
"search_places": "",
"search_state": "",
"search_timezone": "",
"search_type": "",
"search_your_photos": "",
"searching_locales": "",
"second": "",
"select_album_cover": "",
"select_all": "",
"select_avatar_color": "",
"select_face": "",
"select_featured_photo": "",
"select_keep_all": "",
"select_library_owner": "",
"select_new_face": "",
"select_photos": "",
"select_trash_all": "",
"selected": "",
"send_message": "",
"send_welcome_email": "",
"server_stats": "",
"set": "",
"set_as_album_cover": "",
"set_as_profile_picture": "",
"set_date_of_birth": "",
"set_profile_picture": "",
"set_slideshow_to_fullscreen": "",
"settings": "",
"settings_saved": "",
"share": "",
"shared": "",
"shared_by": "",
"shared_by_you": "",
"shared_from_partner": "",
"shared_links": "",
"shared_with_partner": "",
"sharing": "",
"sharing_sidebar_description": "",
"show_album_options": "",
"show_and_hide_people": "",
"show_file_location": "",
"show_gallery": "",
"show_hidden_people": "",
"show_in_timeline": "",
"show_in_timeline_setting_description": "",
"show_keyboard_shortcuts": "",
"show_metadata": "",
"show_or_hide_info": "",
"show_password": "",
"show_person_options": "",
"show_progress_bar": "",
"show_search_options": "",
"shuffle": "",
"sign_out": "",
"sign_up": "",
"size": "",
"skip_to_content": "",
"slideshow": "",
"slideshow_settings": "",
"sort_albums_by": "",
"stack": "",
"stack_selected_photos": "",
"stacktrace": "",
"start": "",
"start_date": "",
"state": "",
"status": "",
"stop_motion_photo": "",
"stop_photo_sharing": "",
"stop_photo_sharing_description": "",
"stop_sharing_photos_with_user": "",
"storage": "",
"storage_label": "",
"storage_usage": "",
"submit": "",
"suggestions": "",
"sunrise_on_the_beach": "",
"swap_merge_direction": "",
"sync": "",
"template": "",
"theme": "",
"theme_selection": "",
"theme_selection_description": "",
"time_based_memories": "",
"timezone": "",
"to_archive": "",
"to_favorite": "",
"toggle_settings": "",
"toggle_theme": "",
"total_usage": "",
"trash": "",
"trash_all": "",
"trash_no_results_message": "",
"trashed_items_will_be_permanently_deleted_after": "",
"type": "",
"unarchive": "",
"unfavorite": "",
"unhide_person": "",
"unknown": "",
"unknown_year": "",
"unlimited": "",
"unlink_oauth": "",
"unlinked_oauth_account": "",
"unselect_all": "",
"unstack": "",
"untracked_files": "",
"untracked_files_decription": "",
"up_next": "",
"updated_password": "",
"upload": "",
"upload_concurrency": "",
"url": "",
"usage": "",
"user": "",
"user_id": "",
"user_usage_detail": "",
"username": "",
"users": "",
"utilities": "",
"validate": "",
"variables": "",
"version": "",
"video": "",
"video_hover_setting": "",
"video_hover_setting_description": "",
"videos": "",
"videos_count": "",
"view_all": "",
"view_all_users": "",
"view_links": "",
"view_next_asset": "",
"view_previous_asset": "",
"waiting": "",
"week": "",
"welcome_to_immich": "",
"year": "",
"yes": "",
"you_dont_have_any_shared_links": "",
"zoom_image": ""
} }

View file

@ -564,6 +564,10 @@
"backup_options_page_title": "Backup options", "backup_options_page_title": "Backup options",
"backup_setting_subtitle": "Manage background and foreground upload settings", "backup_setting_subtitle": "Manage background and foreground upload settings",
"backward": "Backward", "backward": "Backward",
"biometric_auth_enabled": "Biometric authentication enabled",
"biometric_locked_out": "You are locked out of biometric authentication",
"biometric_no_options": "No biometric options available",
"biometric_not_available": "Biometric authentication is not available on this device",
"birthdate_saved": "Date of birth saved successfully", "birthdate_saved": "Date of birth saved successfully",
"birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.", "birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.",
"blurred_background": "Blurred background", "blurred_background": "Blurred background",
@ -825,6 +829,7 @@
"empty_trash": "Empty trash", "empty_trash": "Empty trash",
"empty_trash_confirmation": "Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.\nYou cannot undo this action!", "empty_trash_confirmation": "Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.\nYou cannot undo this action!",
"enable": "Enable", "enable": "Enable",
"enable_biometric_auth_description": "Enter your PIN code to enable biometric authentication",
"enabled": "Enabled", "enabled": "Enabled",
"end_date": "End date", "end_date": "End date",
"enqueued": "Enqueued", "enqueued": "Enqueued",
@ -998,6 +1003,7 @@
"external_network_sheet_info": "When not on the preferred Wi-Fi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom", "external_network_sheet_info": "When not on the preferred Wi-Fi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
"face_unassigned": "Unassigned", "face_unassigned": "Unassigned",
"failed": "Failed", "failed": "Failed",
"failed_to_authenticate": "Failed to authenticate",
"failed_to_load_assets": "Failed to load assets", "failed_to_load_assets": "Failed to load assets",
"failed_to_load_folder": "Failed to load folder", "failed_to_load_folder": "Failed to load folder",
"favorite": "Favorite", "favorite": "Favorite",
@ -1064,6 +1070,8 @@
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping", "home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
"home_page_favorite_err_partner": "Can not favorite partner assets yet, skipping", "home_page_favorite_err_partner": "Can not favorite partner assets yet, skipping",
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album so that the timeline can populate photos and videos in it", "home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album so that the timeline can populate photos and videos in it",
"home_page_locked_error_local": "Can not move local assets to locked folder, skipping",
"home_page_locked_error_partner": "Can not move partner assets to locked folder, skipping",
"home_page_share_err_local": "Can not share local assets via link, skipping", "home_page_share_err_local": "Can not share local assets via link, skipping",
"home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping", "home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
"host": "Host", "host": "Host",
@ -1231,8 +1239,6 @@
"memories_setting_description": "Manage what you see in your memories", "memories_setting_description": "Manage what you see in your memories",
"memories_start_over": "Start Over", "memories_start_over": "Start Over",
"memories_swipe_to_close": "Swipe up to close", "memories_swipe_to_close": "Swipe up to close",
"memories_year_ago": "A year ago",
"memories_years_ago": "{years, plural, other {# years}} ago",
"memory": "Memory", "memory": "Memory",
"memory_lane_title": "Memory Lane {title}", "memory_lane_title": "Memory Lane {title}",
"menu": "Menu", "menu": "Menu",
@ -1404,6 +1410,7 @@
"play_memories": "Play memories", "play_memories": "Play memories",
"play_motion_photo": "Play Motion Photo", "play_motion_photo": "Play Motion Photo",
"play_or_pause_video": "Play or pause video", "play_or_pause_video": "Play or pause video",
"please_auth_to_access": "Please authenticate to access",
"port": "Port", "port": "Port",
"preferences_settings_subtitle": "Manage the app's preferences", "preferences_settings_subtitle": "Manage the app's preferences",
"preferences_settings_title": "Preferences", "preferences_settings_title": "Preferences",
@ -1665,6 +1672,7 @@
"share_add_photos": "Add photos", "share_add_photos": "Add photos",
"share_assets_selected": "{count} selected", "share_assets_selected": "{count} selected",
"share_dialog_preparing": "Preparing...", "share_dialog_preparing": "Preparing...",
"share_link": "Share Link",
"shared": "Shared", "shared": "Shared",
"shared_album_activities_input_disable": "Comment is disabled", "shared_album_activities_input_disable": "Comment is disabled",
"shared_album_activity_remove_content": "Do you want to delete this activity?", "shared_album_activity_remove_content": "Do you want to delete this activity?",
@ -1888,6 +1896,7 @@
"uploading": "Uploading", "uploading": "Uploading",
"url": "URL", "url": "URL",
"usage": "Usage", "usage": "Usage",
"use_biometric": "Use biometric",
"use_current_connection": "use current connection", "use_current_connection": "use current connection",
"use_custom_date_range": "Use custom date range instead", "use_custom_date_range": "Use custom date range instead",
"user": "User", "user": "User",

View file

@ -65,8 +65,6 @@
"job_settings": "تنظیمات کار", "job_settings": "تنظیمات کار",
"job_settings_description": "مدیریت همزمانی کار", "job_settings_description": "مدیریت همزمانی کار",
"job_status": "وضعیت کار", "job_status": "وضعیت کار",
"jobs_delayed": "",
"jobs_failed": "",
"library_created": "کتابخانه ایجاد شده: {library}", "library_created": "کتابخانه ایجاد شده: {library}",
"library_deleted": "کتابخانه حذف شد", "library_deleted": "کتابخانه حذف شد",
"library_import_path_description": "یک پوشه برای وارد کردن مشخص کنید. این پوشه، به همراه زیرپوشه‌ها، برای یافتن تصاویر و ویدیوها اسکن خواهد شد.", "library_import_path_description": "یک پوشه برای وارد کردن مشخص کنید. این پوشه، به همراه زیرپوشه‌ها، برای یافتن تصاویر و ویدیوها اسکن خواهد شد.",
@ -128,7 +126,6 @@
"metadata_extraction_job": "استخراج فرا داده", "metadata_extraction_job": "استخراج فرا داده",
"metadata_extraction_job_description": "استخراج اطلاعات ابرداده، مانند موقعیت جغرافیایی و کیفیت از هر فایل", "metadata_extraction_job_description": "استخراج اطلاعات ابرداده، مانند موقعیت جغرافیایی و کیفیت از هر فایل",
"migration_job": "مهاجرت", "migration_job": "مهاجرت",
"migration_job_description": "",
"no_paths_added": "هیچ مسیری اضافه نشده", "no_paths_added": "هیچ مسیری اضافه نشده",
"no_pattern_added": "هیچ الگوی اضافه نشده", "no_pattern_added": "هیچ الگوی اضافه نشده",
"note_apply_storage_label_previous_assets": "توجه: برای اعمال برچسب ذخیره سازی به دارایی هایی که قبلاً بارگذاری شده اند، دستور زیر را اجرا کنید", "note_apply_storage_label_previous_assets": "توجه: برای اعمال برچسب ذخیره سازی به دارایی هایی که قبلاً بارگذاری شده اند، دستور زیر را اجرا کنید",
@ -178,8 +175,6 @@
"registration": "ثبت نام مدیر", "registration": "ثبت نام مدیر",
"registration_description": "از آنجایی که شما اولین کاربر در سیستم هستید، به عنوان مدیر تعیین شده‌اید و مسئولیت انجام وظایف مدیریتی بر عهده شما خواهد بود و کاربران اضافی توسط شما ایجاد خواهند شد.", "registration_description": "از آنجایی که شما اولین کاربر در سیستم هستید، به عنوان مدیر تعیین شده‌اید و مسئولیت انجام وظایف مدیریتی بر عهده شما خواهد بود و کاربران اضافی توسط شما ایجاد خواهند شد.",
"repair_all": "بازسازی همه", "repair_all": "بازسازی همه",
"repair_matched_items": "",
"repaired_items": "",
"require_password_change_on_login": "الزام کاربر به تغییر گذرواژه در اولین ورود", "require_password_change_on_login": "الزام کاربر به تغییر گذرواژه در اولین ورود",
"reset_settings_to_default": "بازنشانی تنظیمات به حالت پیش‌فرض", "reset_settings_to_default": "بازنشانی تنظیمات به حالت پیش‌فرض",
"reset_settings_to_recent_saved": "بازنشانی تنظیمات به آخرین تنظیمات ذخیره شده", "reset_settings_to_recent_saved": "بازنشانی تنظیمات به آخرین تنظیمات ذخیره شده",
@ -196,7 +191,6 @@
"smart_search_job_description": "اجرای یادگیری ماشینی بر روی دارایی‌ها برای پشتیبانی از جستجوی هوشمند", "smart_search_job_description": "اجرای یادگیری ماشینی بر روی دارایی‌ها برای پشتیبانی از جستجوی هوشمند",
"storage_template_date_time_description": "زمان‌بندی ایجاد دارایی برای اطلاعات تاریخ و زمان استفاده می‌شود", "storage_template_date_time_description": "زمان‌بندی ایجاد دارایی برای اطلاعات تاریخ و زمان استفاده می‌شود",
"storage_template_date_time_sample": "نمونه زمان {date}", "storage_template_date_time_sample": "نمونه زمان {date}",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "تأیید هَش فعال شد", "storage_template_hash_verification_enabled": "تأیید هَش فعال شد",
"storage_template_hash_verification_enabled_description": "تأیید هَش را فعال می‌کند؛ این گزینه را غیرفعال نکنید مگر اینکه از عواقب آن مطمئن باشید", "storage_template_hash_verification_enabled_description": "تأیید هَش را فعال می‌کند؛ این گزینه را غیرفعال نکنید مگر اینکه از عواقب آن مطمئن باشید",
"storage_template_migration": "انتقال الگوی ذخیره سازی", "storage_template_migration": "انتقال الگوی ذخیره سازی",
@ -242,7 +236,6 @@
"transcoding_hardware_acceleration": "شتاب دهنده سخت افزاری", "transcoding_hardware_acceleration": "شتاب دهنده سخت افزاری",
"transcoding_hardware_acceleration_description": "آزمایشی؛ بسیار سریع‌تر است، اما در همان بیت‌ریت کیفیت کمتری خواهد داشت", "transcoding_hardware_acceleration_description": "آزمایشی؛ بسیار سریع‌تر است، اما در همان بیت‌ریت کیفیت کمتری خواهد داشت",
"transcoding_hardware_decoding": "رمزگشایی سخت افزاری", "transcoding_hardware_decoding": "رمزگشایی سخت افزاری",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "کدک HEVC", "transcoding_hevc_codec": "کدک HEVC",
"transcoding_max_b_frames": "بیشترین B-frames", "transcoding_max_b_frames": "بیشترین B-frames",
"transcoding_max_b_frames_description": "مقادیر بالاتر کارایی فشرده سازی را بهبود می‌بخشند، اما کدگذاری را کند می‌کنند. ممکن است با شتاب دهی سخت‌افزاری در دستگاه‌های قدیمی سازگار نباشد. مقدار( 0 ) B-frames را غیرفعال می‌کند، در حالی که مقدار ( 1 ) این مقدار را به صورت خودکار تنظیم می‌کند.", "transcoding_max_b_frames_description": "مقادیر بالاتر کارایی فشرده سازی را بهبود می‌بخشند، اما کدگذاری را کند می‌کنند. ممکن است با شتاب دهی سخت‌افزاری در دستگاه‌های قدیمی سازگار نباشد. مقدار( 0 ) B-frames را غیرفعال می‌کند، در حالی که مقدار ( 1 ) این مقدار را به صورت خودکار تنظیم می‌کند.",
@ -266,7 +259,6 @@
"transcoding_temporal_aq_description": "این مورد فقط برای NVENC اعمال می شود. افزایش کیفیت در صحنه های با جزئیات بالا و حرکت کم. ممکن است با دستگاه های قدیمی تر سازگار نباشد.", "transcoding_temporal_aq_description": "این مورد فقط برای NVENC اعمال می شود. افزایش کیفیت در صحنه های با جزئیات بالا و حرکت کم. ممکن است با دستگاه های قدیمی تر سازگار نباشد.",
"transcoding_threads": "رشته ها ( موضوعات )", "transcoding_threads": "رشته ها ( موضوعات )",
"transcoding_threads_description": "مقادیر بالاتر منجر به رمزگذاری سریع تر می شود، اما فضای کمتری برای پردازش سایر وظایف سرور در حین فعالیت باقی می گذارد. این مقدار نباید بیشتر از تعداد هسته های CPU باشد. اگر روی 0 تنظیم شود، بیشترین استفاده را خواهد داشت.", "transcoding_threads_description": "مقادیر بالاتر منجر به رمزگذاری سریع تر می شود، اما فضای کمتری برای پردازش سایر وظایف سرور در حین فعالیت باقی می گذارد. این مقدار نباید بیشتر از تعداد هسته های CPU باشد. اگر روی 0 تنظیم شود، بیشترین استفاده را خواهد داشت.",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "تلاش برای حفظ ظاهر ویدیوهای HDR هنگام تبدیل به SDR. هر الگوریتم تعادل های متفاوتی را برای رنگ، جزئیات و روشنایی ایجاد می کند. Hable جزئیات را حفظ می کند، Mobius رنگ را حفظ می کند و Reinhard روشنایی را حفظ می کند.", "transcoding_tone_mapping_description": "تلاش برای حفظ ظاهر ویدیوهای HDR هنگام تبدیل به SDR. هر الگوریتم تعادل های متفاوتی را برای رنگ، جزئیات و روشنایی ایجاد می کند. Hable جزئیات را حفظ می کند، Mobius رنگ را حفظ می کند و Reinhard روشنایی را حفظ می کند.",
"transcoding_transcode_policy": "سیاست رمزگذاری", "transcoding_transcode_policy": "سیاست رمزگذاری",
"transcoding_transcode_policy_description": "سیاست برای زمانی که ویدیویی باید مجددا تبدیل (رمزگذاری) شود. ویدیوهای HDR همیشه تبدیل (رمزگذاری) مجدد خواهند شد (مگر رمزگذاری مجدد غیرفعال باشد).", "transcoding_transcode_policy_description": "سیاست برای زمانی که ویدیویی باید مجددا تبدیل (رمزگذاری) شود. ویدیوهای HDR همیشه تبدیل (رمزگذاری) مجدد خواهند شد (مگر رمزگذاری مجدد غیرفعال باشد).",
@ -306,15 +298,12 @@
"administration": "مدیریت", "administration": "مدیریت",
"advanced": "پیشرفته", "advanced": "پیشرفته",
"album_added": "آلبوم اضافه شد", "album_added": "آلبوم اضافه شد",
"album_added_notification_setting_description": "",
"album_cover_updated": "جلد آلبوم به‌روزرسانی شد", "album_cover_updated": "جلد آلبوم به‌روزرسانی شد",
"album_info_updated": "اطلاعات آلبوم به‌روزرسانی شد", "album_info_updated": "اطلاعات آلبوم به‌روزرسانی شد",
"album_name": "نام آلبوم", "album_name": "نام آلبوم",
"album_options": "گزینه‌های آلبوم", "album_options": "گزینه‌های آلبوم",
"album_updated": "آلبوم به‌روزرسانی شد", "album_updated": "آلبوم به‌روزرسانی شد",
"album_updated_setting_description": "",
"albums": "آلبوم‌ها", "albums": "آلبوم‌ها",
"albums_count": "",
"all": "همه", "all": "همه",
"all_people": "همه افراد", "all_people": "همه افراد",
"allow_dark_mode": "اجازه دادن به حالت تاریک", "allow_dark_mode": "اجازه دادن به حالت تاریک",
@ -324,18 +313,13 @@
"app_settings": "تنظیمات برنامه", "app_settings": "تنظیمات برنامه",
"appears_in": "ظاهر می‌شود در", "appears_in": "ظاهر می‌شود در",
"archive": "بایگانی", "archive": "بایگانی",
"archive_or_unarchive_photo": "",
"archive_size": "اندازه بایگانی", "archive_size": "اندازه بایگانی",
"archive_size_description": "",
"asset_offline": "محتوا آفلاین", "asset_offline": "محتوا آفلاین",
"assets": "محتواها", "assets": "محتواها",
"authorized_devices": "دستگاه‌های مجاز", "authorized_devices": "دستگاه‌های مجاز",
"back": "بازگشت", "back": "بازگشت",
"backward": "عقب", "backward": "عقب",
"blurred_background": "پس‌زمینه محو", "blurred_background": "پس‌زمینه محو",
"bulk_delete_duplicates_confirmation": "",
"bulk_keep_duplicates_confirmation": "",
"bulk_trash_duplicates_confirmation": "",
"camera": "دوربین", "camera": "دوربین",
"camera_brand": "برند دوربین", "camera_brand": "برند دوربین",
"camera_model": "مدل دوربین", "camera_model": "مدل دوربین",
@ -350,10 +334,8 @@
"change_name_successfully": "نام با موفقیت تغییر یافت", "change_name_successfully": "نام با موفقیت تغییر یافت",
"change_password": "تغییر رمز عبور", "change_password": "تغییر رمز عبور",
"change_your_password": "رمز عبور خود را تغییر دهید", "change_your_password": "رمز عبور خود را تغییر دهید",
"changed_visibility_successfully": "",
"check_all": "انتخاب همه", "check_all": "انتخاب همه",
"check_logs": "بررسی لاگ‌ها", "check_logs": "بررسی لاگ‌ها",
"choose_matching_people_to_merge": "",
"city": "شهر", "city": "شهر",
"clear": "پاک کردن", "clear": "پاک کردن",
"clear_all": "پاک کردن همه", "clear_all": "پاک کردن همه",
@ -366,7 +348,6 @@
"comments_are_disabled": "نظرات غیرفعال هستند", "comments_are_disabled": "نظرات غیرفعال هستند",
"confirm": "تأیید", "confirm": "تأیید",
"confirm_admin_password": "تأیید رمز عبور مدیر", "confirm_admin_password": "تأیید رمز عبور مدیر",
"confirm_delete_shared_link": "",
"confirm_password": "تأیید رمز عبور", "confirm_password": "تأیید رمز عبور",
"contain": "شامل", "contain": "شامل",
"context": "زمینه", "context": "زمینه",
@ -393,8 +374,6 @@
"create_user": "ایجاد کاربر", "create_user": "ایجاد کاربر",
"created": "ایجاد شد", "created": "ایجاد شد",
"current_device": "دستگاه فعلی", "current_device": "دستگاه فعلی",
"custom_locale": "",
"custom_locale_description": "",
"dark": "تاریک", "dark": "تاریک",
"date_after": "تاریخ پس از", "date_after": "تاریخ پس از",
"date_and_time": "تاریخ و زمان", "date_and_time": "تاریخ و زمان",
@ -402,12 +381,8 @@
"date_range": "بازه زمانی", "date_range": "بازه زمانی",
"day": "روز", "day": "روز",
"deduplicate_all": "حذف تکراری‌ها به صورت کامل", "deduplicate_all": "حذف تکراری‌ها به صورت کامل",
"default_locale": "",
"default_locale_description": "",
"delete": "حذف", "delete": "حذف",
"delete_album": "حذف آلبوم", "delete_album": "حذف آلبوم",
"delete_api_key_prompt": "",
"delete_duplicates_confirmation": "",
"delete_key": "حذف کلید", "delete_key": "حذف کلید",
"delete_library": "حذف کتابخانه", "delete_library": "حذف کتابخانه",
"delete_link": "حذف لینک", "delete_link": "حذف لینک",
@ -425,14 +400,12 @@
"display_options": "گزینه‌های نمایش", "display_options": "گزینه‌های نمایش",
"display_order": "ترتیب نمایش", "display_order": "ترتیب نمایش",
"display_original_photos": "نمایش عکس‌های اصلی", "display_original_photos": "نمایش عکس‌های اصلی",
"display_original_photos_setting_description": "",
"done": "انجام شد", "done": "انجام شد",
"download": "دانلود", "download": "دانلود",
"download_settings": "تنظیمات دانلود", "download_settings": "تنظیمات دانلود",
"download_settings_description": "مدیریت تنظیمات مرتبط با دانلود محتوا", "download_settings_description": "مدیریت تنظیمات مرتبط با دانلود محتوا",
"downloading": "در حال دانلود", "downloading": "در حال دانلود",
"duplicates": "تکراری‌ها", "duplicates": "تکراری‌ها",
"duplicates_description": "",
"duration": "مدت زمان", "duration": "مدت زمان",
"edit_album": "ویرایش آلبوم", "edit_album": "ویرایش آلبوم",
"edit_avatar": "ویرایش آواتار", "edit_avatar": "ویرایش آواتار",
@ -440,8 +413,6 @@
"edit_date_and_time": "ویرایش تاریخ و زمان", "edit_date_and_time": "ویرایش تاریخ و زمان",
"edit_exclusion_pattern": "ویرایش الگوی استثناء", "edit_exclusion_pattern": "ویرایش الگوی استثناء",
"edit_faces": "ویرایش چهره‌ها", "edit_faces": "ویرایش چهره‌ها",
"edit_import_path": "",
"edit_import_paths": "",
"edit_key": "ویرایش کلید", "edit_key": "ویرایش کلید",
"edit_link": "ویرایش لینک", "edit_link": "ویرایش لینک",
"edit_location": "ویرایش مکان", "edit_location": "ویرایش مکان",
@ -456,73 +427,6 @@
"end_date": "تاریخ پایان", "end_date": "تاریخ پایان",
"error": "خطا", "error": "خطا",
"error_loading_image": "خطا در بارگذاری تصویر", "error_loading_image": "خطا در بارگذاری تصویر",
"errors": {
"exclusion_pattern_already_exists": "",
"import_path_already_exists": "",
"paths_validation_failed": "",
"quota_higher_than_disk_size": "",
"repair_unable_to_check_items": "",
"unable_to_add_album_users": "",
"unable_to_add_comment": "",
"unable_to_add_exclusion_pattern": "",
"unable_to_add_import_path": "",
"unable_to_add_partners": "",
"unable_to_change_album_user_role": "",
"unable_to_change_date": "",
"unable_to_change_location": "",
"unable_to_change_password": "",
"unable_to_copy_to_clipboard": "",
"unable_to_create_api_key": "",
"unable_to_create_library": "",
"unable_to_create_user": "",
"unable_to_delete_album": "",
"unable_to_delete_asset": "",
"unable_to_delete_exclusion_pattern": "",
"unable_to_delete_import_path": "",
"unable_to_delete_shared_link": "",
"unable_to_delete_user": "",
"unable_to_edit_exclusion_pattern": "",
"unable_to_edit_import_path": "",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "",
"unable_to_exit_fullscreen": "",
"unable_to_hide_person": "",
"unable_to_link_oauth_account": "",
"unable_to_load_album": "",
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_play_video": "",
"unable_to_refresh_user": "",
"unable_to_remove_album_users": "",
"unable_to_remove_api_key": "",
"unable_to_remove_deleted_assets": "",
"unable_to_remove_library": "",
"unable_to_remove_partner": "",
"unable_to_remove_reaction": "",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_api_key": "",
"unable_to_save_name": "",
"unable_to_save_profile": "",
"unable_to_save_settings": "",
"unable_to_scan_libraries": "",
"unable_to_scan_library": "",
"unable_to_set_profile_picture": "",
"unable_to_submit_job": "",
"unable_to_trash_asset": "",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_timeline_display_status": "",
"unable_to_update_user": ""
},
"exit_slideshow": "خروج از نمایش اسلاید", "exit_slideshow": "خروج از نمایش اسلاید",
"expand_all": "باز کردن همه", "expand_all": "باز کردن همه",
"expire_after": "منقضی شدن بعد از", "expire_after": "منقضی شدن بعد از",
@ -534,15 +438,12 @@
"external": "خارجی", "external": "خارجی",
"external_libraries": "کتابخانه‌های خارجی", "external_libraries": "کتابخانه‌های خارجی",
"favorite": "علاقه‌مندی", "favorite": "علاقه‌مندی",
"favorite_or_unfavorite_photo": "",
"favorites": "علاقه‌مندی‌ها", "favorites": "علاقه‌مندی‌ها",
"feature_photo_updated": "",
"file_name": "نام فایل", "file_name": "نام فایل",
"file_name_or_extension": "نام فایل یا پسوند", "file_name_or_extension": "نام فایل یا پسوند",
"filename": "نام فایل", "filename": "نام فایل",
"filetype": "نوع فایل", "filetype": "نوع فایل",
"filter_people": "فیلتر افراد", "filter_people": "فیلتر افراد",
"find_them_fast": "",
"fix_incorrect_match": "رفع تطابق نادرست", "fix_incorrect_match": "رفع تطابق نادرست",
"forward": "جلو", "forward": "جلو",
"general": "عمومی", "general": "عمومی",
@ -562,19 +463,11 @@
"immich_web_interface": "رابط وب Immich", "immich_web_interface": "رابط وب Immich",
"import_from_json": "وارد کردن از JSON", "import_from_json": "وارد کردن از JSON",
"import_path": "مسیر وارد کردن", "import_path": "مسیر وارد کردن",
"in_albums": "",
"in_archive": "در بایگانی", "in_archive": "در بایگانی",
"include_archived": "شامل بایگانی شده‌ها", "include_archived": "شامل بایگانی شده‌ها",
"include_shared_albums": "شامل آلبوم‌های اشتراکی", "include_shared_albums": "شامل آلبوم‌های اشتراکی",
"include_shared_partner_assets": "",
"individual_share": "اشتراک فردی", "individual_share": "اشتراک فردی",
"info": "اطلاعات", "info": "اطلاعات",
"interval": {
"day_at_onepm": "",
"hours": "",
"night_at_midnight": "",
"night_at_twoam": ""
},
"invite_people": "دعوت افراد", "invite_people": "دعوت افراد",
"invite_to_album": "دعوت به آلبوم", "invite_to_album": "دعوت به آلبوم",
"jobs": "وظایف", "jobs": "وظایف",
@ -601,28 +494,22 @@
"login_has_been_disabled": "ورود غیرفعال شده است.", "login_has_been_disabled": "ورود غیرفعال شده است.",
"look": "نگاه کردن", "look": "نگاه کردن",
"loop_videos": "پخش مداوم ویدئوها", "loop_videos": "پخش مداوم ویدئوها",
"loop_videos_description": "",
"make": "ساختن", "make": "ساختن",
"manage_shared_links": "مدیریت لینک‌های اشتراکی", "manage_shared_links": "مدیریت لینک‌های اشتراکی",
"manage_sharing_with_partners": "",
"manage_the_app_settings": "مدیریت تنظیمات برنامه", "manage_the_app_settings": "مدیریت تنظیمات برنامه",
"manage_your_account": "مدیریت حساب کاربری شما", "manage_your_account": "مدیریت حساب کاربری شما",
"manage_your_api_keys": "مدیریت کلیدهای API شما", "manage_your_api_keys": "مدیریت کلیدهای API شما",
"manage_your_devices": "مدیریت دستگاه‌های متصل", "manage_your_devices": "مدیریت دستگاه‌های متصل",
"manage_your_oauth_connection": "مدیریت اتصال OAuth شما", "manage_your_oauth_connection": "مدیریت اتصال OAuth شما",
"map": "نقشه", "map": "نقشه",
"map_marker_with_image": "",
"map_settings": "تنظیمات نقشه", "map_settings": "تنظیمات نقشه",
"matches": "تطابق‌ها", "matches": "تطابق‌ها",
"media_type": "نوع رسانه", "media_type": "نوع رسانه",
"memories": "خاطرات", "memories": "خاطرات",
"memories_setting_description": "",
"memory": "خاطره", "memory": "خاطره",
"menu": "منو", "menu": "منو",
"merge": "ادغام", "merge": "ادغام",
"merge_people": "ادغام افراد", "merge_people": "ادغام افراد",
"merge_people_limit": "",
"merge_people_prompt": "",
"merge_people_successfully": "ادغام افراد با موفقیت انجام شد", "merge_people_successfully": "ادغام افراد با موفقیت انجام شد",
"minimize": "کوچک کردن", "minimize": "کوچک کردن",
"minute": "دقیقه", "minute": "دقیقه",
@ -643,20 +530,12 @@
"next": "بعدی", "next": "بعدی",
"next_memory": "خاطره بعدی", "next_memory": "خاطره بعدی",
"no": "خیر", "no": "خیر",
"no_albums_message": "",
"no_archived_assets_message": "",
"no_assets_message": "",
"no_duplicates_found": "هیچ تکراری یافت نشد.", "no_duplicates_found": "هیچ تکراری یافت نشد.",
"no_exif_info_available": "اطلاعات EXIF موجود نیست", "no_exif_info_available": "اطلاعات EXIF موجود نیست",
"no_explore_results_message": "",
"no_favorites_message": "",
"no_libraries_message": "",
"no_name": "بدون نام", "no_name": "بدون نام",
"no_places": "مکانی یافت نشد", "no_places": "مکانی یافت نشد",
"no_results": "نتیجه‌ای یافت نشد", "no_results": "نتیجه‌ای یافت نشد",
"no_shared_albums_message": "",
"not_in_any_album": "در هیچ آلبومی نیست", "not_in_any_album": "در هیچ آلبومی نیست",
"note_apply_storage_label_to_previously_uploaded assets": "",
"notes": "یادداشت‌ها", "notes": "یادداشت‌ها",
"notification_toggle_setting_description": "اعلان‌های ایمیلی را فعال کنید", "notification_toggle_setting_description": "اعلان‌های ایمیلی را فعال کنید",
"notifications": "اعلان‌ها", "notifications": "اعلان‌ها",
@ -664,7 +543,6 @@
"oauth": "OAuth", "oauth": "OAuth",
"offline": "آفلاین", "offline": "آفلاین",
"offline_paths": "مسیرهای آفلاین", "offline_paths": "مسیرهای آفلاین",
"offline_paths_description": "",
"ok": "تأیید", "ok": "تأیید",
"oldest_first": "قدیمی‌ترین ابتدا", "oldest_first": "قدیمی‌ترین ابتدا",
"online": "آنلاین", "online": "آنلاین",
@ -679,7 +557,6 @@
"owner": "مالک", "owner": "مالک",
"partner": "شریک", "partner": "شریک",
"partner_can_access": "{partner} می‌تواند دسترسی داشته باشد", "partner_can_access": "{partner} می‌تواند دسترسی داشته باشد",
"partner_can_access_assets": "",
"partner_can_access_location": "مکان‌هایی که عکس‌های شما گرفته شده‌اند", "partner_can_access_location": "مکان‌هایی که عکس‌های شما گرفته شده‌اند",
"partner_sharing": "اشتراک‌گذاری با شریک", "partner_sharing": "اشتراک‌گذاری با شریک",
"partners": "شرکا", "partners": "شرکا",
@ -687,11 +564,6 @@
"password_does_not_match": "رمز عبور مطابقت ندارد", "password_does_not_match": "رمز عبور مطابقت ندارد",
"password_required": "رمز عبور مورد نیاز است", "password_required": "رمز عبور مورد نیاز است",
"password_reset_success": "بازنشانی رمز عبور موفقیت‌آمیز بود", "password_reset_success": "بازنشانی رمز عبور موفقیت‌آمیز بود",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "مسیر", "path": "مسیر",
"pattern": "الگو", "pattern": "الگو",
"pause": "توقف", "pause": "توقف",
@ -699,14 +571,12 @@
"paused": "متوقف شده", "paused": "متوقف شده",
"pending": "در انتظار", "pending": "در انتظار",
"people": "افراد", "people": "افراد",
"people_sidebar_description": "",
"permanent_deletion_warning": "هشدار حذف دائمی", "permanent_deletion_warning": "هشدار حذف دائمی",
"permanent_deletion_warning_setting_description": "نمایش هشدار هنگام حذف دائمی محتواها", "permanent_deletion_warning_setting_description": "نمایش هشدار هنگام حذف دائمی محتواها",
"permanently_delete": "حذف دائمی", "permanently_delete": "حذف دائمی",
"permanently_deleted_asset": "محتوای حذف شده دائمی", "permanently_deleted_asset": "محتوای حذف شده دائمی",
"person": "فرد", "person": "فرد",
"photos": "عکس‌ها", "photos": "عکس‌ها",
"photos_count": "",
"photos_from_previous_years": "عکس‌های سال‌های گذشته", "photos_from_previous_years": "عکس‌های سال‌های گذشته",
"pick_a_location": "یک مکان انتخاب کنید", "pick_a_location": "یک مکان انتخاب کنید",
"place": "مکان", "place": "مکان",
@ -730,38 +600,27 @@
"recent_searches": "جستجوهای اخیر", "recent_searches": "جستجوهای اخیر",
"refresh": "تازه سازی", "refresh": "تازه سازی",
"refreshed": "تازه سازی شد", "refreshed": "تازه سازی شد",
"refreshes_every_file": "",
"remove": "حذف", "remove": "حذف",
"remove_deleted_assets": "حذف محتواهای حذف‌شده", "remove_deleted_assets": "حذف محتواهای حذف‌شده",
"remove_from_album": "حذف از آلبوم", "remove_from_album": "حذف از آلبوم",
"remove_from_favorites": "حذف از علاقه‌مندی‌ها", "remove_from_favorites": "حذف از علاقه‌مندی‌ها",
"remove_from_shared_link": "",
"removed_api_key": "",
"rename": "تغییر نام", "rename": "تغییر نام",
"repair": "تعمیر", "repair": "تعمیر",
"repair_no_results_message": "",
"replace_with_upload": "جایگزینی با آپلود", "replace_with_upload": "جایگزینی با آپلود",
"require_password": "",
"require_user_to_change_password_on_first_login": "",
"reset": "بازنشانی", "reset": "بازنشانی",
"reset_password": "بازنشانی رمز عبور", "reset_password": "بازنشانی رمز عبور",
"reset_people_visibility": "",
"resolved_all_duplicates": "",
"restore": "بازیابی", "restore": "بازیابی",
"restore_all": "بازیابی همه", "restore_all": "بازیابی همه",
"restore_user": "بازیابی کاربر", "restore_user": "بازیابی کاربر",
"resume": "ادامه", "resume": "ادامه",
"retry_upload": "",
"review_duplicates": "بررسی تکراری‌ها", "review_duplicates": "بررسی تکراری‌ها",
"role": "نقش", "role": "نقش",
"save": "ذخیره", "save": "ذخیره",
"saved_api_key": "",
"saved_profile": "پروفایل ذخیره شد", "saved_profile": "پروفایل ذخیره شد",
"saved_settings": "تنظیمات ذخیره شد", "saved_settings": "تنظیمات ذخیره شد",
"say_something": "چیزی بگویید", "say_something": "چیزی بگویید",
"scan_all_libraries": "اسکن همه کتابخانه‌ها", "scan_all_libraries": "اسکن همه کتابخانه‌ها",
"scan_settings": "تنظیمات اسکن", "scan_settings": "تنظیمات اسکن",
"scanning_for_album": "",
"search": "جستجو", "search": "جستجو",
"search_albums": "جستجوی آلبوم‌ها", "search_albums": "جستجوی آلبوم‌ها",
"search_by_context": "جستجو براساس زمینه", "search_by_context": "جستجو براساس زمینه",
@ -775,8 +634,6 @@
"search_state": "جستجوی ایالت...", "search_state": "جستجوی ایالت...",
"search_timezone": "جستجوی منطقه زمانی...", "search_timezone": "جستجوی منطقه زمانی...",
"search_type": "نوع جستجو", "search_type": "نوع جستجو",
"search_your_photos": "",
"searching_locales": "",
"second": "ثانیه", "second": "ثانیه",
"select_album_cover": "انتخاب جلد آلبوم", "select_album_cover": "انتخاب جلد آلبوم",
"select_all": "انتخاب همه", "select_all": "انتخاب همه",
@ -787,41 +644,28 @@
"select_library_owner": "انتخاب مالک کتابخانه", "select_library_owner": "انتخاب مالک کتابخانه",
"select_new_face": "انتخاب چهره جدید", "select_new_face": "انتخاب چهره جدید",
"select_photos": "انتخاب عکس‌ها", "select_photos": "انتخاب عکس‌ها",
"select_trash_all": "",
"selected": "انتخاب شده", "selected": "انتخاب شده",
"send_message": "ارسال پیام", "send_message": "ارسال پیام",
"send_welcome_email": "ارسال ایمیل خوش‌آمدگویی", "send_welcome_email": "ارسال ایمیل خوش‌آمدگویی",
"server_stats": "آمار سرور", "server_stats": "آمار سرور",
"set": "تنظیم", "set": "تنظیم",
"set_as_album_cover": "",
"set_as_profile_picture": "",
"set_date_of_birth": "تنظیم تاریخ تولد", "set_date_of_birth": "تنظیم تاریخ تولد",
"set_profile_picture": "تنظیم تصویر پروفایل", "set_profile_picture": "تنظیم تصویر پروفایل",
"set_slideshow_to_fullscreen": "",
"settings": "تنظیمات", "settings": "تنظیمات",
"settings_saved": "تنظیمات ذخیره شد", "settings_saved": "تنظیمات ذخیره شد",
"share": "اشتراک‌گذاری", "share": "اشتراک‌گذاری",
"shared": "مشترک", "shared": "مشترک",
"shared_by": "مشترک توسط", "shared_by": "مشترک توسط",
"shared_by_you": "",
"shared_from_partner": "عکس‌ها از {partner}", "shared_from_partner": "عکس‌ها از {partner}",
"shared_links": "لینک‌های اشتراکی", "shared_links": "لینک‌های اشتراکی",
"shared_photos_and_videos_count": "",
"shared_with_partner": "مشترک با {partner}", "shared_with_partner": "مشترک با {partner}",
"sharing": "اشتراک‌گذاری", "sharing": "اشتراک‌گذاری",
"sharing_sidebar_description": "",
"show_album_options": "نمایش گزینه‌های آلبوم", "show_album_options": "نمایش گزینه‌های آلبوم",
"show_and_hide_people": "",
"show_file_location": "نمایش مسیر فایل", "show_file_location": "نمایش مسیر فایل",
"show_gallery": "نمایش گالری", "show_gallery": "نمایش گالری",
"show_hidden_people": "نمایش افراد پنهان", "show_hidden_people": "نمایش افراد پنهان",
"show_in_timeline": "",
"show_in_timeline_setting_description": "",
"show_keyboard_shortcuts": "",
"show_metadata": "نمایش اطلاعات متا", "show_metadata": "نمایش اطلاعات متا",
"show_or_hide_info": "",
"show_password": "نمایش رمز عبور", "show_password": "نمایش رمز عبور",
"show_person_options": "",
"show_progress_bar": "نمایش نوار پیشرفت", "show_progress_bar": "نمایش نوار پیشرفت",
"show_search_options": "نمایش گزینه‌های جستجو", "show_search_options": "نمایش گزینه‌های جستجو",
"shuffle": "تصادفی", "shuffle": "تصادفی",
@ -831,60 +675,39 @@
"skip_to_content": "رفتن به محتوا", "skip_to_content": "رفتن به محتوا",
"slideshow": "نمایش اسلاید", "slideshow": "نمایش اسلاید",
"slideshow_settings": "تنظیمات نمایش اسلاید", "slideshow_settings": "تنظیمات نمایش اسلاید",
"sort_albums_by": "",
"stack": "پشته", "stack": "پشته",
"stack_selected_photos": "",
"stacktrace": "",
"start": "شروع", "start": "شروع",
"start_date": "تاریخ شروع", "start_date": "تاریخ شروع",
"state": "ایالت", "state": "ایالت",
"status": "وضعیت", "status": "وضعیت",
"stop_motion_photo": "توقف عکس متحرک", "stop_motion_photo": "توقف عکس متحرک",
"stop_photo_sharing": "",
"stop_photo_sharing_description": "",
"stop_sharing_photos_with_user": "",
"storage": "فضای ذخیره‌سازی", "storage": "فضای ذخیره‌سازی",
"storage_label": "برچسب فضای ذخیره‌سازی", "storage_label": "برچسب فضای ذخیره‌سازی",
"storage_usage": "",
"submit": "ارسال", "submit": "ارسال",
"suggestions": "پیشنهادات", "suggestions": "پیشنهادات",
"sunrise_on_the_beach": "",
"swap_merge_direction": "تغییر جهت ادغام", "swap_merge_direction": "تغییر جهت ادغام",
"sync": "همگام‌سازی", "sync": "همگام‌سازی",
"template": "الگو", "template": "الگو",
"theme": "تم", "theme": "تم",
"theme_selection": "انتخاب تم", "theme_selection": "انتخاب تم",
"theme_selection_description": "",
"time_based_memories": "",
"timezone": "منطقه زمانی", "timezone": "منطقه زمانی",
"to_archive": "بایگانی", "to_archive": "بایگانی",
"to_favorite": "به علاقه‌مندی‌ها", "to_favorite": "به علاقه‌مندی‌ها",
"to_trash": "",
"toggle_settings": "تغییر تنظیمات", "toggle_settings": "تغییر تنظیمات",
"toggle_theme": "تغییر تم تاریک", "toggle_theme": "تغییر تم تاریک",
"total_usage": "استفاده کلی", "total_usage": "استفاده کلی",
"trash": "سطل زباله", "trash": "سطل زباله",
"trash_all": "",
"trash_count": "",
"trash_no_results_message": "",
"trashed_items_will_be_permanently_deleted_after": "",
"type": "نوع", "type": "نوع",
"unarchive": "",
"unfavorite": "حذف از علاقه‌مندی‌ها", "unfavorite": "حذف از علاقه‌مندی‌ها",
"unhide_person": "آشکار کردن فرد", "unhide_person": "آشکار کردن فرد",
"unknown": "ناشناخته", "unknown": "ناشناخته",
"unknown_year": "سال نامشخص", "unknown_year": "سال نامشخص",
"unlimited": "نامحدود", "unlimited": "نامحدود",
"unlink_oauth": "لغو اتصال OAuth", "unlink_oauth": "لغو اتصال OAuth",
"unlinked_oauth_account": "",
"unnamed_album": "آلبوم بدون نام", "unnamed_album": "آلبوم بدون نام",
"unnamed_share": "اشتراک بدون نام", "unnamed_share": "اشتراک بدون نام",
"unselect_all": "لغو انتخاب همه", "unselect_all": "لغو انتخاب همه",
"unstack": "",
"untracked_files": "",
"untracked_files_decription": "",
"up_next": "مورد بعدی", "up_next": "مورد بعدی",
"updated_password": "",
"upload": "آپلود", "upload": "آپلود",
"upload_concurrency": "تعداد آپلود همزمان", "upload_concurrency": "تعداد آپلود همزمان",
"url": "آدرس", "url": "آدرس",
@ -898,12 +721,8 @@
"validate": "اعتبارسنجی", "validate": "اعتبارسنجی",
"variables": "متغیرها", "variables": "متغیرها",
"version": "نسخه", "version": "نسخه",
"version_announcement_message": "",
"video": "ویدیو", "video": "ویدیو",
"video_hover_setting": "",
"video_hover_setting_description": "",
"videos": "ویدیوها", "videos": "ویدیوها",
"videos_count": "",
"view": "مشاهده", "view": "مشاهده",
"view_all": "مشاهده همه", "view_all": "مشاهده همه",
"view_all_users": "مشاهده همه کاربران", "view_all_users": "مشاهده همه کاربران",
@ -913,9 +732,7 @@
"waiting": "در انتظار", "waiting": "در انتظار",
"week": "هفته", "week": "هفته",
"welcome": "خوش آمدید", "welcome": "خوش آمدید",
"welcome_to_immich": "",
"year": "سال", "year": "سال",
"yes": "بله", "yes": "بله",
"you_dont_have_any_shared_links": "",
"zoom_image": "بزرگنمایی تصویر" "zoom_image": "بزرگنمایی تصویر"
} }

View file

@ -41,7 +41,6 @@
}, },
"album_user_left": "Umalis sa {album}", "album_user_left": "Umalis sa {album}",
"all_albums": "Lahat ng albums", "all_albums": "Lahat ng albums",
"anti_clockwise": "",
"api_key_description": "Isang beses lamang na ipapakita itong value. Siguraduhin na ikopya itong value bago iclose ang window na ito.", "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?", "are_these_the_same_person": "Itong tao na ito ay parehas?",
"asset_adding_to_album": "Dinadagdag sa album...", "asset_adding_to_album": "Dinadagdag sa album...",

View file

@ -689,7 +689,6 @@
"edit_title": "शीर्षक संपादित करें", "edit_title": "शीर्षक संपादित करें",
"edit_user": "यूजर को संपादित करो", "edit_user": "यूजर को संपादित करो",
"edited": "संपादित", "edited": "संपादित",
"editor": "",
"email": "ईमेल", "email": "ईमेल",
"empty_folder": "This folder is empty", "empty_folder": "This folder is empty",
"empty_trash": "कूड़ेदान खाली करें", "empty_trash": "कूड़ेदान खाली करें",
@ -922,7 +921,6 @@
"info": "जानकारी", "info": "जानकारी",
"interval": { "interval": {
"day_at_onepm": "हर दिन दोपहर 1 बजे", "day_at_onepm": "हर दिन दोपहर 1 बजे",
"hours": "",
"night_at_midnight": "हर रात आधी रात को", "night_at_midnight": "हर रात आधी रात को",
"night_at_twoam": "हर रात 2 बजे" "night_at_twoam": "हर रात 2 बजे"
}, },
@ -1142,11 +1140,6 @@
"password_does_not_match": "पासवर्ड मैच नहीं कर रहा है", "password_does_not_match": "पासवर्ड मैच नहीं कर रहा है",
"password_required": "पासवर्ड आवश्यक", "password_required": "पासवर्ड आवश्यक",
"password_reset_success": "पासवर्ड रीसेट सफल", "password_reset_success": "पासवर्ड रीसेट सफल",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "पथ", "path": "पथ",
"pattern": "नमूना", "pattern": "नमूना",
"pause": "विराम", "pause": "विराम",

View file

@ -1,784 +1,52 @@
{ {
"about": "Մասին", "about": "Մասին",
"account": "",
"account_settings": "",
"acknowledge": "",
"action": "Գործողություն", "action": "Գործողություն",
"actions": "",
"active": "",
"activity": "",
"add": "Ավելացնել", "add": "Ավելացնել",
"add_a_description": "",
"add_a_location": "Ավելացնել տեղ", "add_a_location": "Ավելացնել տեղ",
"add_a_name": "Ավելացնել անուն", "add_a_name": "Ավելացնել անուն",
"add_a_title": "",
"add_exclusion_pattern": "",
"add_import_path": "",
"add_location": "Ավելացնել տեղ", "add_location": "Ավելացնել տեղ",
"add_more_users": "",
"add_partner": "",
"add_path": "",
"add_photos": "Ավելացնել նկարներ", "add_photos": "Ավելացնել նկարներ",
"add_to": "",
"add_to_album": "",
"add_to_shared_album": "",
"admin": {
"add_exclusion_pattern_description": "",
"authentication_settings": "",
"authentication_settings_description": "",
"background_task_job": "",
"check_all": "",
"config_set_by_file": "",
"confirm_delete_library": "",
"confirm_delete_library_assets": "",
"confirm_email_below": "",
"confirm_reprocess_all_faces": "",
"confirm_user_password_reset": "",
"disable_login": "",
"duplicate_detection_job_description": "",
"exclusion_pattern_description": "",
"external_library_created_at": "",
"external_library_management": "",
"face_detection": "",
"face_detection_description": "",
"facial_recognition_job_description": "",
"force_delete_user_warning": "",
"forcing_refresh_library_files": "",
"image_format_description": "",
"image_prefer_embedded_preview": "",
"image_prefer_embedded_preview_setting_description": "",
"image_prefer_wide_gamut": "",
"image_prefer_wide_gamut_setting_description": "",
"image_quality": "",
"image_settings": "",
"image_settings_description": "",
"job_concurrency": "",
"job_not_concurrency_safe": "",
"job_settings": "",
"job_settings_description": "",
"job_status": "",
"jobs_delayed": "",
"jobs_failed": "",
"library_created": "",
"library_deleted": "",
"library_import_path_description": "",
"library_scanning": "",
"library_scanning_description": "",
"library_scanning_enable_description": "",
"library_settings": "",
"library_settings_description": "",
"library_tasks_description": "",
"library_watching_enable_description": "",
"library_watching_settings": "",
"library_watching_settings_description": "",
"logging_enable_description": "",
"logging_level_description": "",
"logging_settings": "",
"machine_learning_clip_model": "",
"machine_learning_duplicate_detection": "",
"machine_learning_duplicate_detection_enabled_description": "",
"machine_learning_duplicate_detection_setting_description": "",
"machine_learning_enabled_description": "",
"machine_learning_facial_recognition": "",
"machine_learning_facial_recognition_description": "",
"machine_learning_facial_recognition_model": "",
"machine_learning_facial_recognition_model_description": "",
"machine_learning_facial_recognition_setting_description": "",
"machine_learning_max_detection_distance": "",
"machine_learning_max_detection_distance_description": "",
"machine_learning_max_recognition_distance": "",
"machine_learning_max_recognition_distance_description": "",
"machine_learning_min_detection_score": "",
"machine_learning_min_detection_score_description": "",
"machine_learning_min_recognized_faces": "",
"machine_learning_min_recognized_faces_description": "",
"machine_learning_settings": "",
"machine_learning_settings_description": "",
"machine_learning_smart_search": "",
"machine_learning_smart_search_description": "",
"machine_learning_smart_search_enabled_description": "",
"machine_learning_url_description": "",
"manage_concurrency": "",
"manage_log_settings": "",
"map_dark_style": "",
"map_enable_description": "",
"map_light_style": "",
"map_reverse_geocoding": "",
"map_reverse_geocoding_enable_description": "",
"map_reverse_geocoding_settings": "",
"map_settings": "",
"map_settings_description": "",
"map_style_description": "",
"metadata_extraction_job": "",
"metadata_extraction_job_description": "",
"migration_job": "",
"migration_job_description": "",
"no_paths_added": "",
"no_pattern_added": "",
"note_apply_storage_label_previous_assets": "",
"note_cannot_be_changed_later": "",
"notification_email_from_address": "",
"notification_email_from_address_description": "",
"notification_email_host_description": "",
"notification_email_ignore_certificate_errors": "",
"notification_email_ignore_certificate_errors_description": "",
"notification_email_password_description": "",
"notification_email_port_description": "",
"notification_email_sent_test_email_button": "",
"notification_email_setting_description": "",
"notification_email_test_email_failed": "",
"notification_email_test_email_sent": "",
"notification_email_username_description": "",
"notification_enable_email_notifications": "",
"notification_settings": "",
"notification_settings_description": "",
"oauth_auto_launch": "",
"oauth_auto_launch_description": "",
"oauth_auto_register": "",
"oauth_auto_register_description": "",
"oauth_button_text": "",
"oauth_enable_description": "",
"oauth_mobile_redirect_uri": "",
"oauth_mobile_redirect_uri_override": "",
"oauth_mobile_redirect_uri_override_description": "",
"oauth_settings": "",
"oauth_settings_description": "",
"oauth_storage_label_claim": "",
"oauth_storage_label_claim_description": "",
"oauth_storage_quota_claim": "",
"oauth_storage_quota_claim_description": "",
"oauth_storage_quota_default": "",
"oauth_storage_quota_default_description": "",
"offline_paths": "",
"offline_paths_description": "",
"password_enable_description": "",
"password_settings": "",
"password_settings_description": "",
"paths_validated_successfully": "",
"quota_size_gib": "",
"refreshing_all_libraries": "",
"repair_all": "",
"repair_matched_items": "",
"repaired_items": "",
"require_password_change_on_login": "",
"reset_settings_to_default": "",
"reset_settings_to_recent_saved": "",
"send_welcome_email": "",
"server_external_domain_settings": "",
"server_external_domain_settings_description": "",
"server_settings": "",
"server_settings_description": "",
"server_welcome_message": "",
"server_welcome_message_description": "",
"sidecar_job": "",
"sidecar_job_description": "",
"slideshow_duration_description": "",
"smart_search_job_description": "",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "",
"storage_template_hash_verification_enabled_description": "",
"storage_template_migration": "",
"storage_template_migration_job": "",
"storage_template_settings": "",
"storage_template_settings_description": "",
"system_settings": "",
"theme_custom_css_settings": "",
"theme_custom_css_settings_description": "",
"theme_settings": "",
"theme_settings_description": "",
"these_files_matched_by_checksum": "",
"thumbnail_generation_job": "",
"thumbnail_generation_job_description": "",
"transcoding_acceleration_api": "",
"transcoding_acceleration_api_description": "",
"transcoding_acceleration_nvenc": "",
"transcoding_acceleration_qsv": "",
"transcoding_acceleration_rkmpp": "",
"transcoding_acceleration_vaapi": "",
"transcoding_accepted_audio_codecs": "",
"transcoding_accepted_audio_codecs_description": "",
"transcoding_accepted_video_codecs": "",
"transcoding_accepted_video_codecs_description": "",
"transcoding_advanced_options_description": "",
"transcoding_audio_codec": "",
"transcoding_audio_codec_description": "",
"transcoding_bitrate_description": "",
"transcoding_constant_quality_mode": "",
"transcoding_constant_quality_mode_description": "",
"transcoding_constant_rate_factor": "",
"transcoding_constant_rate_factor_description": "",
"transcoding_disabled_description": "",
"transcoding_hardware_acceleration": "",
"transcoding_hardware_acceleration_description": "",
"transcoding_hardware_decoding": "",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "",
"transcoding_max_b_frames": "",
"transcoding_max_b_frames_description": "",
"transcoding_max_bitrate": "",
"transcoding_max_bitrate_description": "",
"transcoding_max_keyframe_interval": "",
"transcoding_max_keyframe_interval_description": "",
"transcoding_optimal_description": "",
"transcoding_preferred_hardware_device": "",
"transcoding_preferred_hardware_device_description": "",
"transcoding_preset_preset": "",
"transcoding_preset_preset_description": "",
"transcoding_reference_frames": "",
"transcoding_reference_frames_description": "",
"transcoding_required_description": "",
"transcoding_settings": "",
"transcoding_settings_description": "",
"transcoding_target_resolution": "",
"transcoding_target_resolution_description": "",
"transcoding_temporal_aq": "",
"transcoding_temporal_aq_description": "",
"transcoding_threads": "",
"transcoding_threads_description": "",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "",
"transcoding_transcode_policy": "",
"transcoding_transcode_policy_description": "",
"transcoding_two_pass_encoding": "",
"transcoding_two_pass_encoding_setting_description": "",
"transcoding_video_codec": "",
"transcoding_video_codec_description": "",
"trash_enabled_description": "",
"trash_number_of_days": "",
"trash_number_of_days_description": "",
"trash_settings": "",
"trash_settings_description": "",
"untracked_files": "",
"untracked_files_description": "",
"user_delete_delay_settings": "",
"user_delete_delay_settings_description": "",
"user_management": "",
"user_password_has_been_reset": "",
"user_password_reset_description": "",
"user_settings": "",
"user_settings_description": "",
"user_successfully_removed": "",
"version_check_enabled_description": "",
"version_check_settings": "",
"version_check_settings_description": "",
"video_conversion_job": "",
"video_conversion_job_description": ""
},
"admin_email": "",
"admin_password": "",
"administration": "",
"advanced": "",
"album_added": "",
"album_added_notification_setting_description": "",
"album_cover_updated": "",
"album_info_updated": "",
"album_name": "",
"album_options": "",
"album_updated": "",
"album_updated_setting_description": "",
"albums": "",
"albums_count": "",
"all": "",
"all_people": "",
"allow_dark_mode": "",
"allow_edits": "",
"api_key": "",
"api_keys": "",
"app_settings": "",
"appears_in": "",
"archive": "",
"archive_or_unarchive_photo": "",
"asset_offline": "",
"assets": "",
"authorized_devices": "",
"back": "Հետ", "back": "Հետ",
"backup_all": "Բոլոր", "backup_all": "Բոլոր",
"backup_controller_page_background_battery_info_link": "Ցույց տուր ինչպես", "backup_controller_page_background_battery_info_link": "Ցույց տուր ինչպես",
"backup_controller_page_background_battery_info_ok": "Լավ", "backup_controller_page_background_battery_info_ok": "Լավ",
"backward": "",
"blurred_background": "",
"camera": "",
"camera_brand": "",
"camera_model": "",
"cancel": "",
"cancel_search": "",
"cannot_merge_people": "",
"cannot_update_the_description": "",
"change_date": "",
"change_expiration_time": "",
"change_location": "Փոխել տեղը", "change_location": "Փոխել տեղը",
"change_name": "Փոխել անուն", "change_name": "Փոխել անուն",
"change_name_successfully": "",
"change_password": "",
"change_your_password": "",
"changed_visibility_successfully": "",
"check_all": "",
"check_logs": "",
"choose_matching_people_to_merge": "",
"city": "Քաղաք", "city": "Քաղաք",
"clear": "",
"clear_all": "",
"clear_message": "",
"clear_value": "",
"client_cert_dialog_msg_confirm": "Լավ", "client_cert_dialog_msg_confirm": "Լավ",
"close": "",
"collapse_all": "",
"color": "Գույն", "color": "Գույն",
"color_theme": "",
"comment_options": "",
"comments_are_disabled": "",
"confirm": "",
"confirm_admin_password": "",
"confirm_delete_shared_link": "",
"confirm_password": "",
"contain": "",
"context": "",
"continue": "",
"control_bottom_app_bar_edit_location": "Փոխել Տեղը", "control_bottom_app_bar_edit_location": "Փոխել Տեղը",
"copied_image_to_clipboard": "",
"copied_to_clipboard": "",
"copy_error": "",
"copy_file_path": "",
"copy_image": "",
"copy_link": "",
"copy_link_to_clipboard": "",
"copy_password": "",
"copy_to_clipboard": "",
"country": "Երկիր", "country": "Երկիր",
"cover": "",
"covers": "",
"create": "",
"create_album": "",
"create_library": "",
"create_link": "",
"create_link_to_share": "",
"create_new": "ՍՏԵՂԾԵԼ ՆՈՐ", "create_new": "ՍՏԵՂԾԵԼ ՆՈՐ",
"create_new_person": "Ստեղծել նոր անձ", "create_new_person": "Ստեղծել նոր անձ",
"create_new_user": "",
"create_shared_album_page_share_select_photos": "Ընտրե Նկարներ", "create_shared_album_page_share_select_photos": "Ընտրե Նկարներ",
"create_user": "",
"created": "",
"curated_object_page_title": "Բաներ", "curated_object_page_title": "Բաներ",
"current_device": "",
"custom_locale": "",
"custom_locale_description": "",
"dark": "Մութ", "dark": "Մութ",
"date_after": "",
"date_and_time": "",
"date_before": "",
"date_range": "",
"day": "Օր", "day": "Օր",
"default_locale": "",
"default_locale_description": "",
"delete": "Ջնջել", "delete": "Ջնջել",
"delete_album": "",
"delete_api_key_prompt": "",
"delete_key": "",
"delete_library": "",
"delete_link": "",
"delete_shared_link": "",
"delete_user": "",
"deleted_shared_link": "",
"description": "",
"details": "",
"direction": "",
"disabled": "",
"disallow_edits": "",
"discover": "",
"dismiss_all_errors": "",
"dismiss_error": "",
"display_options": "",
"display_order": "",
"display_original_photos": "",
"display_original_photos_setting_description": "",
"done": "",
"download": "",
"downloading": "",
"duplicates": "",
"duration": "",
"edit_album": "",
"edit_avatar": "",
"edit_date": "",
"edit_date_and_time": "",
"edit_exclusion_pattern": "",
"edit_faces": "",
"edit_import_path": "",
"edit_import_paths": "",
"edit_key": "",
"edit_link": "",
"edit_location": "Փոխել տեղը", "edit_location": "Փոխել տեղը",
"edit_name": "",
"edit_people": "",
"edit_title": "",
"edit_user": "",
"edited": "",
"editor": "",
"email": "",
"empty_trash": "",
"enable": "",
"enabled": "",
"end_date": "",
"error": "",
"error_loading_image": "",
"errors": {
"cleared_jobs": "",
"exclusion_pattern_already_exists": "",
"failed_job_command": "",
"import_path_already_exists": "",
"paths_validation_failed": "",
"quota_higher_than_disk_size": "",
"repair_unable_to_check_items": "",
"unable_to_add_album_users": "",
"unable_to_add_comment": "",
"unable_to_add_exclusion_pattern": "",
"unable_to_add_import_path": "",
"unable_to_add_partners": "",
"unable_to_change_album_user_role": "",
"unable_to_change_date": "",
"unable_to_change_location": "",
"unable_to_change_password": "",
"unable_to_copy_to_clipboard": "",
"unable_to_create_api_key": "",
"unable_to_create_library": "",
"unable_to_create_user": "",
"unable_to_delete_album": "",
"unable_to_delete_asset": "",
"unable_to_delete_exclusion_pattern": "",
"unable_to_delete_import_path": "",
"unable_to_delete_shared_link": "",
"unable_to_delete_user": "",
"unable_to_edit_exclusion_pattern": "",
"unable_to_edit_import_path": "",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "",
"unable_to_exit_fullscreen": "",
"unable_to_hide_person": "",
"unable_to_link_oauth_account": "",
"unable_to_load_album": "",
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_play_video": "",
"unable_to_refresh_user": "",
"unable_to_remove_album_users": "",
"unable_to_remove_api_key": "",
"unable_to_remove_deleted_assets": "",
"unable_to_remove_library": "",
"unable_to_remove_partner": "",
"unable_to_remove_reaction": "",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_api_key": "",
"unable_to_save_name": "",
"unable_to_save_profile": "",
"unable_to_save_settings": "",
"unable_to_scan_libraries": "",
"unable_to_scan_library": "",
"unable_to_set_profile_picture": "",
"unable_to_submit_job": "",
"unable_to_trash_asset": "",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_timeline_display_status": "",
"unable_to_update_user": ""
},
"exif_bottom_sheet_person_add_person": "Ավելացնել անուն", "exif_bottom_sheet_person_add_person": "Ավելացնել անուն",
"exif_bottom_sheet_person_age": "Տարիք {}", "exif_bottom_sheet_person_age": "Տարիք {}",
"exif_bottom_sheet_person_age_years": "Տարիք {}", "exif_bottom_sheet_person_age_years": "Տարիք {}",
"exit_slideshow": "",
"expand_all": "",
"expire_after": "",
"expired": "",
"explore": "",
"export": "",
"export_as_json": "",
"extension": "",
"external": "",
"external_libraries": "",
"favorite": "",
"favorite_or_unfavorite_photo": "",
"favorites": "",
"feature_photo_updated": "",
"file_name": "",
"file_name_or_extension": "",
"filename": "",
"filetype": "",
"filter_people": "",
"find_them_fast": "",
"fix_incorrect_match": "",
"forward": "",
"general": "",
"get_help": "",
"getting_started": "",
"go_back": "",
"go_to_search": "",
"group_albums_by": "",
"has_quota": "",
"hi_user": "Բարեւ {name} ({email})", "hi_user": "Բարեւ {name} ({email})",
"hide_gallery": "",
"hide_password": "",
"hide_person": "",
"host": "",
"hour": "",
"image": "",
"immich_logo": "",
"immich_web_interface": "",
"import_from_json": "",
"import_path": "",
"in_archive": "",
"include_archived": "",
"include_shared_albums": "",
"include_shared_partner_assets": "",
"individual_share": "",
"info": "",
"interval": {
"day_at_onepm": "",
"hours": "",
"night_at_midnight": "",
"night_at_twoam": ""
},
"invite_people": "",
"invite_to_album": "",
"jobs": "",
"keep": "",
"keyboard_shortcuts": "",
"language": "",
"language_setting_description": "",
"last_seen": "",
"leave": "",
"let_others_respond": "",
"level": "",
"library": "",
"library_options": "",
"light": "",
"link_options": "",
"link_to_oauth": "",
"linked_oauth_account": "",
"list": "",
"loading": "",
"loading_search_results_failed": "",
"log_out": "",
"log_out_all_devices": "",
"login_has_been_disabled": "",
"look": "",
"loop_videos": "",
"loop_videos_description": "",
"make": "",
"manage_shared_links": "",
"manage_sharing_with_partners": "",
"manage_the_app_settings": "",
"manage_your_account": "",
"manage_your_api_keys": "",
"manage_your_devices": "",
"manage_your_oauth_connection": "",
"map": "",
"map_assets_in_bound": "{} նկար", "map_assets_in_bound": "{} նկար",
"map_assets_in_bounds": "{} նկարներ", "map_assets_in_bounds": "{} նկարներ",
"map_marker_with_image": "",
"map_settings": "",
"matches": "",
"media_type": "",
"memories": "",
"memories_setting_description": "",
"menu": "",
"merge": "",
"merge_people": "",
"merge_people_successfully": "",
"minimize": "",
"minute": "",
"missing": "",
"model": "",
"month": "",
"more": "",
"moved_to_trash": "",
"my_albums": "",
"name": "",
"name_or_nickname": "",
"never": "",
"new_api_key": "",
"new_password": "",
"new_person": "",
"new_user_created": "",
"newest_first": "",
"next": "",
"next_memory": "",
"no": "",
"no_albums_message": "",
"no_archived_assets_message": "",
"no_assets_message": "",
"no_duplicates_found": "",
"no_exif_info_available": "",
"no_explore_results_message": "",
"no_favorites_message": "",
"no_libraries_message": "",
"no_name": "",
"no_places": "",
"no_results": "",
"no_shared_albums_message": "",
"not_in_any_album": "",
"note_apply_storage_label_to_previously_uploaded assets": "",
"notes": "",
"notification_toggle_setting_description": "",
"notifications": "",
"notifications_setting_description": "",
"oauth": "",
"offline": "",
"offline_paths": "",
"offline_paths_description": "",
"ok": "",
"oldest_first": "",
"online": "",
"only_favorites": "",
"open_the_search_filters": "",
"options": "",
"organize_your_library": "",
"other": "",
"other_devices": "",
"other_variables": "",
"owned": "",
"owner": "",
"partner_can_access": "",
"partner_can_access_assets": "",
"partner_can_access_location": "",
"partner_list_user_photos": "{}-ին նկարները", "partner_list_user_photos": "{}-ին նկարները",
"partner_sharing": "",
"partners": "",
"password": "",
"password_does_not_match": "",
"password_required": "",
"password_reset_success": "",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "",
"pattern": "",
"pause": "",
"pause_memories": "",
"paused": "",
"pending": "",
"people": "",
"people_sidebar_description": "",
"permanent_deletion_warning": "",
"permanent_deletion_warning_setting_description": "",
"permanently_delete": "",
"permanently_deleted_asset": "",
"photos": "Նկարներ", "photos": "Նկարներ",
"photos_count": "",
"photos_from_previous_years": "",
"pick_a_location": "",
"place": "",
"places": "",
"play": "",
"play_memories": "",
"play_motion_photo": "",
"play_or_pause_video": "",
"port": "",
"preset": "",
"preview": "",
"previous": "",
"previous_memory": "",
"previous_or_next_photo": "",
"primary": "",
"profile_picture_set": "",
"public_share": "",
"reaction_options": "",
"read_changelog": "",
"recent": "",
"recent_searches": "",
"refresh": "",
"refreshed": "",
"refreshes_every_file": "",
"remove": "",
"remove_deleted_assets": "",
"remove_from_album": "",
"remove_from_favorites": "",
"remove_from_shared_link": "",
"removed_api_key": "",
"rename": "",
"repair": "",
"repair_no_results_message": "",
"replace_with_upload": "",
"require_password": "",
"require_user_to_change_password_on_first_login": "",
"reset": "",
"reset_password": "",
"reset_people_visibility": "",
"restore": "",
"restore_all": "",
"restore_user": "",
"resume": "",
"retry_upload": "",
"review_duplicates": "",
"role": "",
"save": "Պահե", "save": "Պահե",
"saved_api_key": "",
"saved_profile": "",
"saved_settings": "",
"say_something": "",
"scan_all_libraries": "",
"scan_library": "Նայե", "scan_library": "Նայե",
"scan_settings": "",
"search": "Փնտրե", "search": "Փնտրե",
"search_albums": "",
"search_by_context": "",
"search_camera_make": "",
"search_camera_model": "",
"search_city": "Որոնե քաղաք…", "search_city": "Որոնե քաղաք…",
"search_country": "",
"search_filter_date": "Ամսաթիվ", "search_filter_date": "Ամսաթիվ",
"search_filter_date_interval": "{start} մինչեւ {end}", "search_filter_date_interval": "{start} մինչեւ {end}",
"search_filter_location": "Տեղ", "search_filter_location": "Տեղ",
"search_filter_location_title": "Ընտրե տեղ", "search_filter_location_title": "Ընտրե տեղ",
"search_for_existing_person": "",
"search_no_people": "Ոչ մի անձ", "search_no_people": "Ոչ մի անձ",
"search_page_motion_photos": "Շարժվող Նկարներ", "search_page_motion_photos": "Շարժվող Նկարներ",
"search_people": "",
"search_places": "",
"search_state": "",
"search_timezone": "",
"search_type": "",
"search_your_photos": "",
"searching_locales": "",
"second": "",
"select_album_cover": "",
"select_all": "",
"select_avatar_color": "",
"select_face": "",
"select_featured_photo": "",
"select_keep_all": "",
"select_library_owner": "",
"select_new_face": "",
"select_photos": "Ընտրե նկարներ", "select_photos": "Ընտրե նկարներ",
"select_trash_all": "",
"selected": "",
"send_message": "",
"send_welcome_email": "",
"server_stats": "",
"set": "",
"set_as_album_cover": "",
"set_as_profile_picture": "",
"set_date_of_birth": "",
"set_profile_picture": "",
"set_slideshow_to_fullscreen": "",
"setting_notifications_notify_never": "երբեք", "setting_notifications_notify_never": "երբեք",
"setting_notifications_notify_seconds": "{} վայրկյան", "setting_notifications_notify_seconds": "{} վայրկյան",
"settings": "",
"settings_saved": "",
"share": "",
"share_add_photos": "Ավելացնել նկարներ", "share_add_photos": "Ավելացնել նկարներ",
"shared": "",
"shared_by": "",
"shared_by_you": "",
"shared_from_partner": "",
"shared_link_edit_expire_after_option_day": "1 օր", "shared_link_edit_expire_after_option_day": "1 օր",
"shared_link_edit_expire_after_option_days": "{} օր", "shared_link_edit_expire_after_option_days": "{} օր",
"shared_link_edit_expire_after_option_hour": "1 ժամ", "shared_link_edit_expire_after_option_hour": "1 ժամ",
@ -787,118 +55,20 @@
"shared_link_edit_expire_after_option_minutes": "{} րոպե", "shared_link_edit_expire_after_option_minutes": "{} րոպե",
"shared_link_edit_expire_after_option_months": "{} ամիս", "shared_link_edit_expire_after_option_months": "{} ամիս",
"shared_link_edit_expire_after_option_year": "{} տարի", "shared_link_edit_expire_after_option_year": "{} տարի",
"shared_links": "",
"shared_photos_and_videos_count": "",
"shared_with_partner": "",
"sharing": "",
"sharing_sidebar_description": "",
"show_album_options": "",
"show_and_hide_people": "",
"show_file_location": "",
"show_gallery": "",
"show_hidden_people": "",
"show_in_timeline": "",
"show_in_timeline_setting_description": "",
"show_keyboard_shortcuts": "",
"show_metadata": "",
"show_or_hide_info": "",
"show_password": "",
"show_person_options": "",
"show_progress_bar": "",
"show_search_options": "",
"shuffle": "",
"sign_out": "",
"sign_up": "",
"size": "",
"skip_to_content": "",
"slideshow": "",
"slideshow_settings": "",
"sort_albums_by": "",
"sort_oldest": "Ամենահին նկարը", "sort_oldest": "Ամենահին նկարը",
"sort_recent": "Ամենանոր նկարը", "sort_recent": "Ամենանոր նկարը",
"stack": "",
"stack_selected_photos": "",
"stacktrace": "",
"start": "",
"start_date": "",
"state": "",
"status": "",
"stop_motion_photo": "",
"stop_photo_sharing": "",
"stop_photo_sharing_description": "",
"stop_sharing_photos_with_user": "",
"storage": "",
"storage_label": "",
"storage_usage": "",
"submit": "",
"suggestions": "",
"sunrise_on_the_beach": "",
"swap_merge_direction": "",
"sync": "",
"template": "",
"theme": "",
"theme_selection": "",
"theme_selection_description": "",
"time_based_memories": "",
"timezone": "Ժամային գոտի", "timezone": "Ժամային գոտի",
"to_archive": "",
"to_favorite": "",
"to_trash": "Աղբ", "to_trash": "Աղբ",
"toggle_settings": "",
"toggle_theme": "",
"total_usage": "",
"trash": "Աղբ", "trash": "Աղբ",
"trash_all": "",
"trash_no_results_message": "",
"trash_page_title": "Աղբ ({})", "trash_page_title": "Աղբ ({})",
"trashed_items_will_be_permanently_deleted_after": "",
"type": "Տեսակ", "type": "Տեսակ",
"unarchive": "",
"unfavorite": "",
"unhide_person": "",
"unknown": "Անհայտ", "unknown": "Անհայտ",
"unknown_country": "Անհայտ Երկիր", "unknown_country": "Անհայտ Երկիր",
"unknown_year": "Անհայտ Տարի", "unknown_year": "Անհայտ Տարի",
"unlimited": "",
"unlink_oauth": "",
"unlinked_oauth_account": "",
"unselect_all": "",
"unstack": "",
"untracked_files": "",
"untracked_files_decription": "",
"up_next": "",
"updated_password": "",
"upload": "",
"upload_concurrency": "",
"upload_status_errors": "Սխալներ", "upload_status_errors": "Սխալներ",
"url": "",
"usage": "",
"user": "",
"user_id": "",
"user_usage_detail": "",
"username": "",
"users": "",
"utilities": "",
"validate": "",
"variables": "",
"version": "",
"version_announcement_closing": "Քո ընկերը՝ Ալեքսը", "version_announcement_closing": "Քո ընկերը՝ Ալեքսը",
"video": "",
"video_hover_setting": "",
"video_hover_setting_description": "",
"videos": "",
"videos_count": "",
"view_all": "",
"view_all_users": "",
"view_links": "",
"view_next_asset": "",
"view_previous_asset": "",
"waiting": "",
"week": "Շաբաթ", "week": "Շաբաթ",
"welcome": "Բարի գալուստ", "welcome": "Բարի գալուստ",
"welcome_to_immich": "",
"year": "Տարի", "year": "Տարի",
"yes": "Այո", "yes": "Այո"
"you_dont_have_any_shared_links": "",
"zoom_image": ""
} }

View file

@ -14,7 +14,6 @@
"add_a_location": "დაამატე ადგილი", "add_a_location": "დაამატე ადგილი",
"add_a_name": "დაამატე სახელი", "add_a_name": "დაამატე სახელი",
"add_a_title": "დაასათაურე", "add_a_title": "დაასათაურე",
"add_endpoint": "",
"add_exclusion_pattern": "დაამატე გამონაკლისი ნიმუში", "add_exclusion_pattern": "დაამატე გამონაკლისი ნიმუში",
"add_import_path": "დაამატე საიმპორტო მისამართი", "add_import_path": "დაამატე საიმპორტო მისამართი",
"add_location": "დაამატე ადგილი", "add_location": "დაამატე ადგილი",

View file

@ -2,868 +2,5 @@
"about": "دەربارە", "about": "دەربارە",
"account": "هەژمار", "account": "هەژمار",
"account_settings": "ڕێکخستنی هەژمار", "account_settings": "ڕێکخستنی هەژمار",
"acknowledge": "دانپێدانان", "acknowledge": "دانپێدانان"
"action": "",
"actions": "",
"active": "",
"activity": "",
"add": "",
"add_a_description": "",
"add_a_location": "",
"add_a_name": "",
"add_a_title": "",
"add_exclusion_pattern": "",
"add_import_path": "",
"add_location": "",
"add_more_users": "",
"add_partner": "",
"add_path": "",
"add_photos": "",
"add_to": "",
"add_to_album": "",
"add_to_shared_album": "",
"admin": {
"add_exclusion_pattern_description": "",
"authentication_settings": "",
"authentication_settings_description": "",
"background_task_job": "",
"check_all": "",
"config_set_by_file": "",
"confirm_delete_library": "",
"confirm_delete_library_assets": "",
"confirm_email_below": "",
"confirm_reprocess_all_faces": "",
"confirm_user_password_reset": "",
"disable_login": "",
"duplicate_detection_job_description": "",
"exclusion_pattern_description": "",
"external_library_created_at": "",
"external_library_management": "",
"face_detection": "",
"face_detection_description": "",
"facial_recognition_job_description": "",
"force_delete_user_warning": "",
"forcing_refresh_library_files": "",
"image_format_description": "",
"image_prefer_embedded_preview": "",
"image_prefer_embedded_preview_setting_description": "",
"image_prefer_wide_gamut": "",
"image_prefer_wide_gamut_setting_description": "",
"image_quality": "",
"image_settings": "",
"image_settings_description": "",
"job_concurrency": "",
"job_not_concurrency_safe": "",
"job_settings": "",
"job_settings_description": "",
"job_status": "",
"jobs_delayed": "",
"jobs_failed": "",
"library_created": "",
"library_deleted": "",
"library_import_path_description": "",
"library_scanning": "",
"library_scanning_description": "",
"library_scanning_enable_description": "",
"library_settings": "",
"library_settings_description": "",
"library_tasks_description": "",
"library_watching_enable_description": "",
"library_watching_settings": "",
"library_watching_settings_description": "",
"logging_enable_description": "",
"logging_level_description": "",
"logging_settings": "",
"machine_learning_clip_model": "",
"machine_learning_duplicate_detection": "",
"machine_learning_duplicate_detection_enabled": "",
"machine_learning_duplicate_detection_enabled_description": "",
"machine_learning_duplicate_detection_setting_description": "",
"machine_learning_enabled": "",
"machine_learning_enabled_description": "",
"machine_learning_facial_recognition": "",
"machine_learning_facial_recognition_description": "",
"machine_learning_facial_recognition_model": "",
"machine_learning_facial_recognition_model_description": "",
"machine_learning_facial_recognition_setting": "",
"machine_learning_facial_recognition_setting_description": "",
"machine_learning_max_detection_distance": "",
"machine_learning_max_detection_distance_description": "",
"machine_learning_max_recognition_distance": "",
"machine_learning_max_recognition_distance_description": "",
"machine_learning_min_detection_score": "",
"machine_learning_min_detection_score_description": "",
"machine_learning_min_recognized_faces": "",
"machine_learning_min_recognized_faces_description": "",
"machine_learning_settings": "",
"machine_learning_settings_description": "",
"machine_learning_smart_search": "",
"machine_learning_smart_search_description": "",
"machine_learning_smart_search_enabled": "",
"machine_learning_smart_search_enabled_description": "",
"machine_learning_url_description": "",
"manage_concurrency": "",
"manage_log_settings": "",
"map_dark_style": "",
"map_enable_description": "",
"map_light_style": "",
"map_reverse_geocoding": "",
"map_reverse_geocoding_enable_description": "",
"map_reverse_geocoding_settings": "",
"map_settings": "",
"map_settings_description": "",
"map_style_description": "",
"metadata_extraction_job": "",
"metadata_extraction_job_description": "",
"migration_job": "",
"migration_job_description": "",
"no_paths_added": "",
"no_pattern_added": "",
"note_apply_storage_label_previous_assets": "",
"note_cannot_be_changed_later": "",
"notification_email_from_address": "",
"notification_email_from_address_description": "",
"notification_email_host_description": "",
"notification_email_ignore_certificate_errors": "",
"notification_email_ignore_certificate_errors_description": "",
"notification_email_password_description": "",
"notification_email_port_description": "",
"notification_email_sent_test_email_button": "",
"notification_email_setting_description": "",
"notification_email_test_email_failed": "",
"notification_email_test_email_sent": "",
"notification_email_username_description": "",
"notification_enable_email_notifications": "",
"notification_settings": "",
"notification_settings_description": "",
"oauth_auto_launch": "",
"oauth_auto_launch_description": "",
"oauth_auto_register": "",
"oauth_auto_register_description": "",
"oauth_button_text": "",
"oauth_enable_description": "",
"oauth_mobile_redirect_uri": "",
"oauth_mobile_redirect_uri_override": "",
"oauth_mobile_redirect_uri_override_description": "",
"oauth_settings": "",
"oauth_settings_description": "",
"oauth_storage_label_claim": "",
"oauth_storage_label_claim_description": "",
"oauth_storage_quota_claim": "",
"oauth_storage_quota_claim_description": "",
"oauth_storage_quota_default": "",
"oauth_storage_quota_default_description": "",
"offline_paths": "",
"offline_paths_description": "",
"password_enable_description": "",
"password_settings": "",
"password_settings_description": "",
"paths_validated_successfully": "",
"quota_size_gib": "",
"refreshing_all_libraries": "",
"repair_all": "",
"repair_matched_items": "",
"repaired_items": "",
"require_password_change_on_login": "",
"reset_settings_to_default": "",
"reset_settings_to_recent_saved": "",
"send_welcome_email": "",
"server_external_domain_settings": "",
"server_external_domain_settings_description": "",
"server_settings": "",
"server_settings_description": "",
"server_welcome_message": "",
"server_welcome_message_description": "",
"sidecar_job": "",
"sidecar_job_description": "",
"slideshow_duration_description": "",
"smart_search_job_description": "",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "",
"storage_template_hash_verification_enabled_description": "",
"storage_template_migration": "",
"storage_template_migration_job": "",
"storage_template_settings": "",
"storage_template_settings_description": "",
"system_settings": "",
"theme_custom_css_settings": "",
"theme_custom_css_settings_description": "",
"theme_settings": "",
"theme_settings_description": "",
"these_files_matched_by_checksum": "",
"thumbnail_generation_job": "",
"thumbnail_generation_job_description": "",
"transcoding_acceleration_api": "",
"transcoding_acceleration_api_description": "",
"transcoding_acceleration_nvenc": "",
"transcoding_acceleration_qsv": "",
"transcoding_acceleration_rkmpp": "",
"transcoding_acceleration_vaapi": "",
"transcoding_accepted_audio_codecs": "",
"transcoding_accepted_audio_codecs_description": "",
"transcoding_accepted_video_codecs": "",
"transcoding_accepted_video_codecs_description": "",
"transcoding_advanced_options_description": "",
"transcoding_audio_codec": "",
"transcoding_audio_codec_description": "",
"transcoding_bitrate_description": "",
"transcoding_constant_quality_mode": "",
"transcoding_constant_quality_mode_description": "",
"transcoding_constant_rate_factor": "",
"transcoding_constant_rate_factor_description": "",
"transcoding_disabled_description": "",
"transcoding_hardware_acceleration": "",
"transcoding_hardware_acceleration_description": "",
"transcoding_hardware_decoding": "",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "",
"transcoding_max_b_frames": "",
"transcoding_max_b_frames_description": "",
"transcoding_max_bitrate": "",
"transcoding_max_bitrate_description": "",
"transcoding_max_keyframe_interval": "",
"transcoding_max_keyframe_interval_description": "",
"transcoding_optimal_description": "",
"transcoding_preferred_hardware_device": "",
"transcoding_preferred_hardware_device_description": "",
"transcoding_preset_preset": "",
"transcoding_preset_preset_description": "",
"transcoding_reference_frames": "",
"transcoding_reference_frames_description": "",
"transcoding_required_description": "",
"transcoding_settings": "",
"transcoding_settings_description": "",
"transcoding_target_resolution": "",
"transcoding_target_resolution_description": "",
"transcoding_temporal_aq": "",
"transcoding_temporal_aq_description": "",
"transcoding_threads": "",
"transcoding_threads_description": "",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "",
"transcoding_transcode_policy": "",
"transcoding_transcode_policy_description": "",
"transcoding_two_pass_encoding": "",
"transcoding_two_pass_encoding_setting_description": "",
"transcoding_video_codec": "",
"transcoding_video_codec_description": "",
"trash_enabled_description": "",
"trash_number_of_days": "",
"trash_number_of_days_description": "",
"trash_settings": "",
"trash_settings_description": "",
"untracked_files": "",
"untracked_files_description": "",
"user_delete_delay_settings": "",
"user_delete_delay_settings_description": "",
"user_management": "",
"user_password_has_been_reset": "",
"user_password_reset_description": "",
"user_settings": "",
"user_settings_description": "",
"user_successfully_removed": "",
"version_check_enabled_description": "",
"version_check_settings": "",
"version_check_settings_description": "",
"video_conversion_job": "",
"video_conversion_job_description": ""
},
"admin_email": "",
"admin_password": "",
"administration": "",
"advanced": "",
"album_added": "",
"album_added_notification_setting_description": "",
"album_cover_updated": "",
"album_info_updated": "",
"album_name": "",
"album_options": "",
"album_updated": "",
"album_updated_setting_description": "",
"albums": "",
"albums_count": "",
"all": "",
"all_people": "",
"allow_dark_mode": "",
"allow_edits": "",
"api_key": "",
"api_keys": "",
"app_settings": "",
"appears_in": "",
"archive": "",
"archive_or_unarchive_photo": "",
"archive_size": "",
"archive_size_description": "",
"asset_offline": "",
"assets": "",
"authorized_devices": "",
"back": "",
"backward": "",
"blurred_background": "",
"camera": "",
"camera_brand": "",
"camera_model": "",
"cancel": "",
"cancel_search": "",
"cannot_merge_people": "",
"cannot_update_the_description": "",
"change_date": "",
"change_expiration_time": "",
"change_location": "",
"change_name": "",
"change_name_successfully": "",
"change_password": "",
"change_your_password": "",
"changed_visibility_successfully": "",
"check_all": "",
"check_logs": "",
"choose_matching_people_to_merge": "",
"city": "",
"clear": "",
"clear_all": "",
"clear_message": "",
"clear_value": "",
"close": "",
"collapse_all": "",
"color_theme": "",
"comment_options": "",
"comments_are_disabled": "",
"confirm": "",
"confirm_admin_password": "",
"confirm_delete_shared_link": "",
"confirm_password": "",
"contain": "",
"context": "",
"continue": "",
"copied_image_to_clipboard": "",
"copied_to_clipboard": "",
"copy_error": "",
"copy_file_path": "",
"copy_image": "",
"copy_link": "",
"copy_link_to_clipboard": "",
"copy_password": "",
"copy_to_clipboard": "",
"country": "",
"cover": "",
"covers": "",
"create": "",
"create_album": "",
"create_library": "",
"create_link": "",
"create_link_to_share": "",
"create_new_person": "",
"create_new_user": "",
"create_user": "",
"created": "",
"current_device": "",
"custom_locale": "",
"custom_locale_description": "",
"dark": "",
"date_after": "",
"date_and_time": "",
"date_before": "",
"date_range": "",
"day": "",
"default_locale": "",
"default_locale_description": "",
"delete": "",
"delete_album": "",
"delete_api_key_prompt": "",
"delete_key": "",
"delete_library": "",
"delete_link": "",
"delete_shared_link": "",
"delete_user": "",
"deleted_shared_link": "",
"description": "",
"details": "",
"direction": "",
"disabled": "",
"disallow_edits": "",
"discover": "",
"dismiss_all_errors": "",
"dismiss_error": "",
"display_options": "",
"display_order": "",
"display_original_photos": "",
"display_original_photos_setting_description": "",
"done": "",
"download": "",
"download_settings": "",
"download_settings_description": "",
"downloading": "",
"duplicates": "",
"duration": "",
"edit_album": "",
"edit_avatar": "",
"edit_date": "",
"edit_date_and_time": "",
"edit_exclusion_pattern": "",
"edit_faces": "",
"edit_import_path": "",
"edit_import_paths": "",
"edit_key": "",
"edit_link": "",
"edit_location": "",
"edit_name": "",
"edit_people": "",
"edit_title": "",
"edit_user": "",
"edited": "",
"editor": "",
"email": "",
"empty_trash": "",
"end_date": "",
"error": "",
"error_loading_image": "",
"errors": {
"cleared_jobs": "",
"exclusion_pattern_already_exists": "",
"failed_job_command": "",
"import_path_already_exists": "",
"paths_validation_failed": "",
"quota_higher_than_disk_size": "",
"repair_unable_to_check_items": "",
"unable_to_add_album_users": "",
"unable_to_add_comment": "",
"unable_to_add_exclusion_pattern": "",
"unable_to_add_import_path": "",
"unable_to_add_partners": "",
"unable_to_change_album_user_role": "",
"unable_to_change_date": "",
"unable_to_change_location": "",
"unable_to_change_password": "",
"unable_to_copy_to_clipboard": "",
"unable_to_create_api_key": "",
"unable_to_create_library": "",
"unable_to_create_user": "",
"unable_to_delete_album": "",
"unable_to_delete_asset": "",
"unable_to_delete_exclusion_pattern": "",
"unable_to_delete_import_path": "",
"unable_to_delete_shared_link": "",
"unable_to_delete_user": "",
"unable_to_edit_exclusion_pattern": "",
"unable_to_edit_import_path": "",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "",
"unable_to_exit_fullscreen": "",
"unable_to_hide_person": "",
"unable_to_link_oauth_account": "",
"unable_to_load_album": "",
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_play_video": "",
"unable_to_refresh_user": "",
"unable_to_remove_album_users": "",
"unable_to_remove_api_key": "",
"unable_to_remove_deleted_assets": "",
"unable_to_remove_library": "",
"unable_to_remove_partner": "",
"unable_to_remove_reaction": "",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_api_key": "",
"unable_to_save_name": "",
"unable_to_save_profile": "",
"unable_to_save_settings": "",
"unable_to_scan_libraries": "",
"unable_to_scan_library": "",
"unable_to_set_profile_picture": "",
"unable_to_submit_job": "",
"unable_to_trash_asset": "",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_timeline_display_status": "",
"unable_to_update_user": ""
},
"exit_slideshow": "",
"expand_all": "",
"expire_after": "",
"expired": "",
"explore": "",
"export": "",
"export_as_json": "",
"extension": "",
"external": "",
"external_libraries": "",
"favorite": "",
"favorite_or_unfavorite_photo": "",
"favorites": "",
"feature_photo_updated": "",
"file_name": "",
"file_name_or_extension": "",
"filename": "",
"filetype": "",
"filter_people": "",
"find_them_fast": "",
"fix_incorrect_match": "",
"forward": "",
"general": "",
"get_help": "",
"getting_started": "",
"go_back": "",
"go_to_search": "",
"group_albums_by": "",
"has_quota": "",
"hide_gallery": "",
"hide_password": "",
"hide_person": "",
"host": "",
"hour": "",
"image": "",
"immich_logo": "",
"immich_web_interface": "",
"import_from_json": "",
"import_path": "",
"in_archive": "",
"include_archived": "",
"include_shared_albums": "",
"include_shared_partner_assets": "",
"individual_share": "",
"info": "",
"interval": {
"day_at_onepm": "",
"hours": "",
"night_at_midnight": "",
"night_at_twoam": ""
},
"invite_people": "",
"invite_to_album": "",
"jobs": "",
"keep": "",
"keyboard_shortcuts": "",
"language": "",
"language_setting_description": "",
"last_seen": "",
"leave": "",
"let_others_respond": "",
"level": "",
"library": "",
"library_options": "",
"light": "",
"link_options": "",
"link_to_oauth": "",
"linked_oauth_account": "",
"list": "",
"loading": "",
"loading_search_results_failed": "",
"log_out": "",
"log_out_all_devices": "",
"login_has_been_disabled": "",
"look": "",
"loop_videos": "",
"loop_videos_description": "",
"make": "",
"manage_shared_links": "",
"manage_sharing_with_partners": "",
"manage_the_app_settings": "",
"manage_your_account": "",
"manage_your_api_keys": "",
"manage_your_devices": "",
"manage_your_oauth_connection": "",
"map": "",
"map_marker_with_image": "",
"map_settings": "",
"matches": "",
"media_type": "",
"memories": "",
"memories_setting_description": "",
"menu": "",
"merge": "",
"merge_people": "",
"merge_people_successfully": "",
"minimize": "",
"minute": "",
"missing": "",
"model": "",
"month": "",
"more": "",
"moved_to_trash": "",
"my_albums": "",
"name": "",
"name_or_nickname": "",
"never": "",
"new_api_key": "",
"new_password": "",
"new_person": "",
"new_user_created": "",
"newest_first": "",
"next": "",
"next_memory": "",
"no": "",
"no_albums_message": "",
"no_archived_assets_message": "",
"no_assets_message": "",
"no_duplicates_found": "",
"no_exif_info_available": "",
"no_explore_results_message": "",
"no_favorites_message": "",
"no_libraries_message": "",
"no_name": "",
"no_places": "",
"no_results": "",
"no_shared_albums_message": "",
"not_in_any_album": "",
"note_apply_storage_label_to_previously_uploaded assets": "",
"notes": "",
"notification_toggle_setting_description": "",
"notifications": "",
"notifications_setting_description": "",
"oauth": "",
"offline": "",
"offline_paths": "",
"offline_paths_description": "",
"ok": "",
"oldest_first": "",
"online": "",
"only_favorites": "",
"open_the_search_filters": "",
"options": "",
"organize_your_library": "",
"other": "",
"other_devices": "",
"other_variables": "",
"owned": "",
"owner": "",
"partner_can_access": "",
"partner_can_access_assets": "",
"partner_can_access_location": "",
"partner_sharing": "",
"partners": "",
"password": "",
"password_does_not_match": "",
"password_required": "",
"password_reset_success": "",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "",
"pattern": "",
"pause": "",
"pause_memories": "",
"paused": "",
"pending": "",
"people": "",
"people_sidebar_description": "",
"permanent_deletion_warning": "",
"permanent_deletion_warning_setting_description": "",
"permanently_delete": "",
"permanently_deleted_asset": "",
"photos": "",
"photos_count": "",
"photos_from_previous_years": "",
"pick_a_location": "",
"place": "",
"places": "",
"play": "",
"play_memories": "",
"play_motion_photo": "",
"play_or_pause_video": "",
"port": "",
"preset": "",
"preview": "",
"previous": "",
"previous_memory": "",
"previous_or_next_photo": "",
"primary": "",
"profile_picture_set": "",
"public_share": "",
"reaction_options": "",
"read_changelog": "",
"recent": "",
"recent_searches": "",
"refresh": "",
"refreshed": "",
"refreshes_every_file": "",
"remove": "",
"remove_deleted_assets": "",
"remove_from_album": "",
"remove_from_favorites": "",
"remove_from_shared_link": "",
"removed_api_key": "",
"rename": "",
"repair": "",
"repair_no_results_message": "",
"replace_with_upload": "",
"require_password": "",
"require_user_to_change_password_on_first_login": "",
"reset": "",
"reset_password": "",
"reset_people_visibility": "",
"restore": "",
"restore_all": "",
"restore_user": "",
"resume": "",
"retry_upload": "",
"review_duplicates": "",
"role": "",
"save": "",
"saved_api_key": "",
"saved_profile": "",
"saved_settings": "",
"say_something": "",
"scan_all_libraries": "",
"scan_settings": "",
"search": "",
"search_albums": "",
"search_by_context": "",
"search_camera_make": "",
"search_camera_model": "",
"search_city": "",
"search_country": "",
"search_for_existing_person": "",
"search_people": "",
"search_places": "",
"search_state": "",
"search_timezone": "",
"search_type": "",
"search_your_photos": "",
"searching_locales": "",
"second": "",
"select_album_cover": "",
"select_all": "",
"select_avatar_color": "",
"select_face": "",
"select_featured_photo": "",
"select_keep_all": "",
"select_library_owner": "",
"select_new_face": "",
"select_photos": "",
"select_trash_all": "",
"selected": "",
"send_message": "",
"send_welcome_email": "",
"server_stats": "",
"set": "",
"set_as_album_cover": "",
"set_as_profile_picture": "",
"set_date_of_birth": "",
"set_profile_picture": "",
"set_slideshow_to_fullscreen": "",
"settings": "",
"settings_saved": "",
"share": "",
"shared": "",
"shared_by": "",
"shared_by_you": "",
"shared_from_partner": "",
"shared_links": "",
"shared_photos_and_videos_count": "",
"shared_with_partner": "",
"sharing": "",
"sharing_sidebar_description": "",
"show_album_options": "",
"show_and_hide_people": "",
"show_file_location": "",
"show_gallery": "",
"show_hidden_people": "",
"show_in_timeline": "",
"show_in_timeline_setting_description": "",
"show_keyboard_shortcuts": "",
"show_metadata": "",
"show_or_hide_info": "",
"show_password": "",
"show_person_options": "",
"show_progress_bar": "",
"show_search_options": "",
"shuffle": "",
"sign_out": "",
"sign_up": "",
"size": "",
"skip_to_content": "",
"slideshow": "",
"slideshow_settings": "",
"sort_albums_by": "",
"stack": "",
"stack_selected_photos": "",
"stacktrace": "",
"start": "",
"start_date": "",
"state": "",
"status": "",
"stop_motion_photo": "",
"stop_photo_sharing": "",
"stop_photo_sharing_description": "",
"stop_sharing_photos_with_user": "",
"storage": "",
"storage_label": "",
"storage_usage": "",
"submit": "",
"suggestions": "",
"sunrise_on_the_beach": "",
"swap_merge_direction": "",
"sync": "",
"template": "",
"theme": "",
"theme_selection": "",
"theme_selection_description": "",
"time_based_memories": "",
"timezone": "",
"to_archive": "",
"to_favorite": "",
"toggle_settings": "",
"toggle_theme": "",
"total_usage": "",
"trash": "",
"trash_all": "",
"trash_no_results_message": "",
"trashed_items_will_be_permanently_deleted_after": "",
"type": "",
"unarchive": "",
"unfavorite": "",
"unhide_person": "",
"unknown": "",
"unknown_year": "",
"unlimited": "",
"unlink_oauth": "",
"unlinked_oauth_account": "",
"unselect_all": "",
"unstack": "",
"untracked_files": "",
"untracked_files_decription": "",
"up_next": "",
"updated_password": "",
"upload": "",
"upload_concurrency": "",
"url": "",
"usage": "",
"user": "",
"user_id": "",
"user_usage_detail": "",
"username": "",
"users": "",
"utilities": "",
"validate": "",
"variables": "",
"version": "",
"video": "",
"video_hover_setting": "",
"video_hover_setting_description": "",
"videos": "",
"videos_count": "",
"view_all": "",
"view_all_users": "",
"view_links": "",
"view_next_asset": "",
"view_previous_asset": "",
"waiting": "",
"week": "",
"welcome": "",
"welcome_to_immich": "",
"year": "",
"yes": "",
"you_dont_have_any_shared_links": "",
"zoom_image": ""
} }

View file

@ -71,9 +71,7 @@
"image_format": "Formatas", "image_format": "Formatas",
"image_format_description": "WebP sukuria mažesnius failus nei JPEG, bet lėčiau juos apdoroja.", "image_format_description": "WebP sukuria mažesnius failus nei JPEG, bet lėčiau juos apdoroja.",
"image_prefer_embedded_preview": "Pageidautinai rodyti įterptą peržiūrą", "image_prefer_embedded_preview": "Pageidautinai rodyti įterptą peržiūrą",
"image_prefer_embedded_preview_setting_description": "",
"image_prefer_wide_gamut": "Teikti pirmenybę plačiai gamai", "image_prefer_wide_gamut": "Teikti pirmenybę plačiai gamai",
"image_prefer_wide_gamut_setting_description": "",
"image_preview_description": "Vidutinio dydžio vaizdas su išvalytais metaduomenimis, naudojamas kai žiūrimas vienas objektas arba mašininiam mokymuisi", "image_preview_description": "Vidutinio dydžio vaizdas su išvalytais metaduomenimis, naudojamas kai žiūrimas vienas objektas arba mašininiam mokymuisi",
"image_preview_quality_description": "Peržiūros kokybė nuo 1-100. Aukštesnės reikšmės yra geriau, bet sukuriami didesni failai gali sumažinti programos reagavimo laiką. Mažos vertės nustatymas gali paveikti mašininio mokymo kokybę.", "image_preview_quality_description": "Peržiūros kokybė nuo 1-100. Aukštesnės reikšmės yra geriau, bet sukuriami didesni failai gali sumažinti programos reagavimo laiką. Mažos vertės nustatymas gali paveikti mašininio mokymo kokybę.",
"image_preview_title": "Peržiūros nustatymai", "image_preview_title": "Peržiūros nustatymai",
@ -109,22 +107,18 @@
"machine_learning_clip_model": "CLIP modelis", "machine_learning_clip_model": "CLIP modelis",
"machine_learning_duplicate_detection": "Dublikatų aptikimas", "machine_learning_duplicate_detection": "Dublikatų aptikimas",
"machine_learning_duplicate_detection_enabled": "Įjungti dublikatų aptikimą", "machine_learning_duplicate_detection_enabled": "Įjungti dublikatų aptikimą",
"machine_learning_duplicate_detection_enabled_description": "",
"machine_learning_duplicate_detection_setting_description": "Naudoti CLIP įterpimus, norint rasti galimus duplikatus", "machine_learning_duplicate_detection_setting_description": "Naudoti CLIP įterpimus, norint rasti galimus duplikatus",
"machine_learning_enabled": "Įgalinti mašininį mokymąsi", "machine_learning_enabled": "Įgalinti mašininį mokymąsi",
"machine_learning_enabled_description": "Jei išjungta, visos „ML“ funkcijos bus išjungtos, nepaisant toliau pateiktų nustatymų.", "machine_learning_enabled_description": "Jei išjungta, visos „ML“ funkcijos bus išjungtos, nepaisant toliau pateiktų nustatymų.",
"machine_learning_facial_recognition": "Veidų atpažinimas", "machine_learning_facial_recognition": "Veidų atpažinimas",
"machine_learning_facial_recognition_description": "Aptikti, atpažinti ir sugrupuoti veidus nuotraukose", "machine_learning_facial_recognition_description": "Aptikti, atpažinti ir sugrupuoti veidus nuotraukose",
"machine_learning_facial_recognition_model": "Veidų atpažinimo modelis", "machine_learning_facial_recognition_model": "Veidų atpažinimo modelis",
"machine_learning_facial_recognition_model_description": "",
"machine_learning_facial_recognition_setting": "Įgalinti veidų atpažinimą", "machine_learning_facial_recognition_setting": "Įgalinti veidų atpažinimą",
"machine_learning_facial_recognition_setting_description": "Išjungus, vaizdai nebus užšifruoti veidų atpažinimui ir nebus naudojami Žmonių sekcijoje Naršymo puslapyje.", "machine_learning_facial_recognition_setting_description": "Išjungus, vaizdai nebus užšifruoti veidų atpažinimui ir nebus naudojami Žmonių sekcijoje Naršymo puslapyje.",
"machine_learning_max_detection_distance": "Maksimalus aptikimo atstumas", "machine_learning_max_detection_distance": "Maksimalus aptikimo atstumas",
"machine_learning_max_detection_distance_description": "Didžiausias atstumas tarp dviejų vaizdų, kad jie būtų laikomi dublikatais, svyruoja nuo 0,001 iki 0,1. Didesnės vertės aptiks daugiau dublikatų, tačiau gali būti klaidingai teigiami.", "machine_learning_max_detection_distance_description": "Didžiausias atstumas tarp dviejų vaizdų, kad jie būtų laikomi dublikatais, svyruoja nuo 0,001 iki 0,1. Didesnės vertės aptiks daugiau dublikatų, tačiau gali būti klaidingai teigiami.",
"machine_learning_max_recognition_distance": "Maksimalus atpažinimo atstumas", "machine_learning_max_recognition_distance": "Maksimalus atpažinimo atstumas",
"machine_learning_max_recognition_distance_description": "",
"machine_learning_min_detection_score": "Minimalus aptikimo balas", "machine_learning_min_detection_score": "Minimalus aptikimo balas",
"machine_learning_min_detection_score_description": "",
"machine_learning_min_recognized_faces": "Mažiausias atpažintų veidų skaičius", "machine_learning_min_recognized_faces": "Mažiausias atpažintų veidų skaičius",
"machine_learning_min_recognized_faces_description": "Mažiausias atpažintų veidų skaičius asmeniui, kurį reikia sukurti. Tai padidinus, veido atpažinimas tampa tikslesnis, bet padidėja tikimybė, kad veidas žmogui nepriskirtas.", "machine_learning_min_recognized_faces_description": "Mažiausias atpažintų veidų skaičius asmeniui, kurį reikia sukurti. Tai padidinus, veido atpažinimas tampa tikslesnis, bet padidėja tikimybė, kad veidas žmogui nepriskirtas.",
"machine_learning_settings": "Mašininio mokymosi nustatymai", "machine_learning_settings": "Mašininio mokymosi nustatymai",
@ -158,7 +152,6 @@
"metadata_settings": "Metaduomenų nustatymai", "metadata_settings": "Metaduomenų nustatymai",
"metadata_settings_description": "Tvarkyti metaduomenų nustatymus", "metadata_settings_description": "Tvarkyti metaduomenų nustatymus",
"migration_job": "Migracija", "migration_job": "Migracija",
"migration_job_description": "",
"no_paths_added": "Keliai nepridėti", "no_paths_added": "Keliai nepridėti",
"no_pattern_added": "Šablonas nepridėtas", "no_pattern_added": "Šablonas nepridėtas",
"note_apply_storage_label_previous_assets": "Pastaba: norėdami pritaikyti saugyklos etiketę seniau įkeltiems ištekliams, paleiskite", "note_apply_storage_label_previous_assets": "Pastaba: norėdami pritaikyti saugyklos etiketę seniau įkeltiems ištekliams, paleiskite",
@ -191,12 +184,6 @@
"oauth_settings": "OAuth", "oauth_settings": "OAuth",
"oauth_settings_description": "Tvarkyti OAuth prisijungimo nustatymus", "oauth_settings_description": "Tvarkyti OAuth prisijungimo nustatymus",
"oauth_settings_more_details": "Detaliau apie šią funkciją galite paskaityti <link>dokumentacijoje</link>.", "oauth_settings_more_details": "Detaliau apie šią funkciją galite paskaityti <link>dokumentacijoje</link>.",
"oauth_storage_label_claim": "",
"oauth_storage_label_claim_description": "",
"oauth_storage_quota_claim": "",
"oauth_storage_quota_claim_description": "",
"oauth_storage_quota_default": "",
"oauth_storage_quota_default_description": "",
"offline_paths": "Nepasiekiami adresai", "offline_paths": "Nepasiekiami adresai",
"offline_paths_description": "Šie rezultatai gali būti dėl rankinio failų ištrynimo, kurie nėra išorinės bibliotekos dalis.", "offline_paths_description": "Šie rezultatai gali būti dėl rankinio failų ištrynimo, kurie nėra išorinės bibliotekos dalis.",
"password_enable_description": "Prisijungti su el. paštu ir slaptažodžiu", "password_enable_description": "Prisijungti su el. paštu ir slaptažodžiu",
@ -217,93 +204,42 @@
"server_settings_description": "Tvarkyti serverio nustatymus", "server_settings_description": "Tvarkyti serverio nustatymus",
"server_welcome_message": "Sveikinimo pranešimas", "server_welcome_message": "Sveikinimo pranešimas",
"server_welcome_message_description": "Žinutė, rodoma prisijungimo puslapyje.", "server_welcome_message_description": "Žinutė, rodoma prisijungimo puslapyje.",
"sidecar_job_description": "",
"slideshow_duration_description": "Sekundžių skaičius, kiek viena nuotrauka rodoma", "slideshow_duration_description": "Sekundžių skaičius, kiek viena nuotrauka rodoma",
"smart_search_job_description": "Vykdykite mašininį mokymąsi bibliotekos elementų išmaniajai paieškai", "smart_search_job_description": "Vykdykite mašininį mokymąsi bibliotekos elementų išmaniajai paieškai",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "",
"storage_template_hash_verification_enabled_description": "",
"storage_template_migration_job": "",
"storage_template_settings": "",
"storage_template_settings_description": "",
"system_settings": "Sistemos nustatymai", "system_settings": "Sistemos nustatymai",
"tag_cleanup_job": "Žymų išvalymas", "tag_cleanup_job": "Žymų išvalymas",
"theme_custom_css_settings": "Individualizuotas CSS", "theme_custom_css_settings": "Individualizuotas CSS",
"theme_custom_css_settings_description": "",
"theme_settings": "Temos nustatymai", "theme_settings": "Temos nustatymai",
"theme_settings_description": "",
"thumbnail_generation_job": "Generuoti miniatiūras", "thumbnail_generation_job": "Generuoti miniatiūras",
"thumbnail_generation_job_description": "Didelių, mažų ir neryškių miniatiūrų generavimas kiekvienam bibliotekos elementui, taip pat miniatiūrų generavimas kiekvienam asmeniui", "thumbnail_generation_job_description": "Didelių, mažų ir neryškių miniatiūrų generavimas kiekvienam bibliotekos elementui, taip pat miniatiūrų generavimas kiekvienam asmeniui",
"transcoding_acceleration_api": "Spartinimo API", "transcoding_acceleration_api": "Spartinimo API",
"transcoding_acceleration_api_description": "",
"transcoding_acceleration_nvenc": "NVENC (reikalinga NVIDIA GPU)", "transcoding_acceleration_nvenc": "NVENC (reikalinga NVIDIA GPU)",
"transcoding_acceleration_qsv": "",
"transcoding_acceleration_rkmpp": "",
"transcoding_acceleration_vaapi": "VAAPI", "transcoding_acceleration_vaapi": "VAAPI",
"transcoding_accepted_audio_codecs": "",
"transcoding_accepted_audio_codecs_description": "",
"transcoding_accepted_containers": "Priimami konteineriai", "transcoding_accepted_containers": "Priimami konteineriai",
"transcoding_accepted_video_codecs": "",
"transcoding_accepted_video_codecs_description": "",
"transcoding_advanced_options_description": "Parinktys, kurių daugelis naudotojų keisti neturėtų", "transcoding_advanced_options_description": "Parinktys, kurių daugelis naudotojų keisti neturėtų",
"transcoding_audio_codec": "Garso kodekas", "transcoding_audio_codec": "Garso kodekas",
"transcoding_audio_codec_description": "Opus yra aukščiausios kokybės variantas, tačiau turi mažesnį suderinamumą su senesniais įrenginiais ar programine įranga.", "transcoding_audio_codec_description": "Opus yra aukščiausios kokybės variantas, tačiau turi mažesnį suderinamumą su senesniais įrenginiais ar programine įranga.",
"transcoding_bitrate_description": "Vaizdo įrašai viršija maksimalią leistiną bitų spartą arba nėra priimtino formato", "transcoding_bitrate_description": "Vaizdo įrašai viršija maksimalią leistiną bitų spartą arba nėra priimtino formato",
"transcoding_constant_quality_mode": "Pastovios kokybės režimas", "transcoding_constant_quality_mode": "Pastovios kokybės režimas",
"transcoding_constant_quality_mode_description": "",
"transcoding_constant_rate_factor": "",
"transcoding_constant_rate_factor_description": "",
"transcoding_disabled_description": "",
"transcoding_hardware_acceleration": "Techninės įrangos spartinimas", "transcoding_hardware_acceleration": "Techninės įrangos spartinimas",
"transcoding_hardware_acceleration_description": "",
"transcoding_hardware_decoding": "Aparatinis dekodavimas", "transcoding_hardware_decoding": "Aparatinis dekodavimas",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "HEVC kodekas", "transcoding_hevc_codec": "HEVC kodekas",
"transcoding_max_b_frames": "",
"transcoding_max_b_frames_description": "",
"transcoding_max_bitrate": "Maksimalus bitų srautas", "transcoding_max_bitrate": "Maksimalus bitų srautas",
"transcoding_max_bitrate_description": "",
"transcoding_max_keyframe_interval": "",
"transcoding_max_keyframe_interval_description": "",
"transcoding_optimal_description": "",
"transcoding_preferred_hardware_device": "",
"transcoding_preferred_hardware_device_description": "",
"transcoding_preset_preset": "",
"transcoding_preset_preset_description": "",
"transcoding_reference_frames": "",
"transcoding_reference_frames_description": "",
"transcoding_required_description": "",
"transcoding_settings": "",
"transcoding_settings_description": "",
"transcoding_target_resolution": "",
"transcoding_target_resolution_description": "Didesnės skiriamosios gebos gali išsaugoti daugiau detalių, tačiau jas koduoti užtrunka ilgiau, failų dydžiai yra didesni ir gali sumažėti programos jautrumas.", "transcoding_target_resolution_description": "Didesnės skiriamosios gebos gali išsaugoti daugiau detalių, tačiau jas koduoti užtrunka ilgiau, failų dydžiai yra didesni ir gali sumažėti programos jautrumas.",
"transcoding_temporal_aq": "",
"transcoding_temporal_aq_description": "",
"transcoding_threads": "",
"transcoding_threads_description": "",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "",
"transcoding_transcode_policy": "",
"transcoding_two_pass_encoding": "",
"transcoding_two_pass_encoding_setting_description": "",
"transcoding_video_codec": "Video kodekas", "transcoding_video_codec": "Video kodekas",
"transcoding_video_codec_description": "",
"trash_enabled_description": "Įgalinti šiukšliadėžės funkcijas", "trash_enabled_description": "Įgalinti šiukšliadėžės funkcijas",
"trash_number_of_days": "Dienų skaičius", "trash_number_of_days": "Dienų skaičius",
"trash_number_of_days_description": "",
"trash_settings": "Šiukšliadėžės nustatymai", "trash_settings": "Šiukšliadėžės nustatymai",
"trash_settings_description": "Tvarkyti šiukšliadėžės nustatymus", "trash_settings_description": "Tvarkyti šiukšliadėžės nustatymus",
"untracked_files": "Nesekami failai", "untracked_files": "Nesekami failai",
"untracked_files_description": "Šie failai aplikacijos nesekami. Jie galėjo atsirasti dėl nepavykusio perkėlimo, nutraukto įkėlimo ar palikti per klaidą", "untracked_files_description": "Šie failai aplikacijos nesekami. Jie galėjo atsirasti dėl nepavykusio perkėlimo, nutraukto įkėlimo ar palikti per klaidą",
"user_delete_delay_settings": "Ištrynimo delsa", "user_delete_delay_settings": "Ištrynimo delsa",
"user_delete_delay_settings_description": "",
"user_management": "Naudotojų valdymas", "user_management": "Naudotojų valdymas",
"user_password_has_been_reset": "Naudotojo slaptažodis buvo iš naujo nustatytas:", "user_password_has_been_reset": "Naudotojo slaptažodis buvo iš naujo nustatytas:",
"user_restore_description": "Naudotojo <b>{user}</b> paskyra bus atkurta.", "user_restore_description": "Naudotojo <b>{user}</b> paskyra bus atkurta.",
"user_settings": "Naudotojo nustatymai", "user_settings": "Naudotojo nustatymai",
"user_settings_description": "Valdyti naudotojo nustatymus", "user_settings_description": "Valdyti naudotojo nustatymus",
"user_successfully_removed": "Naudotojas {email} sėkmingai pašalintas.", "user_successfully_removed": "Naudotojas {email} sėkmingai pašalintas.",
"version_check_enabled_description": "",
"version_check_settings": "Versijos tikrinimas", "version_check_settings": "Versijos tikrinimas",
"version_check_settings_description": "Įjungti/išjungti naujos versijos pranešimus", "version_check_settings_description": "Įjungti/išjungti naujos versijos pranešimus",
"video_conversion_job": "Vaizdo įrašų konvertavimas", "video_conversion_job": "Vaizdo įrašų konvertavimas",
@ -312,7 +248,6 @@
"admin_email": "Administratoriaus el. paštas", "admin_email": "Administratoriaus el. paštas",
"admin_password": "Administratoriaus slaptažodis", "admin_password": "Administratoriaus slaptažodis",
"administration": "Administravimas", "administration": "Administravimas",
"advanced": "",
"advanced_settings_log_level_title": "Log level: {}", "advanced_settings_log_level_title": "Log level: {}",
"advanced_settings_prefer_remote_subtitle": "Some devices are painfully slow to load thumbnails from assets on the device. Activate this setting to load remote images instead.", "advanced_settings_prefer_remote_subtitle": "Some devices are painfully slow to load thumbnails from assets on the device. Activate this setting to load remote images instead.",
"advanced_settings_prefer_remote_title": "Prefer remote images", "advanced_settings_prefer_remote_title": "Prefer remote images",
@ -370,7 +305,6 @@
"app_bar_signout_dialog_ok": "Yes", "app_bar_signout_dialog_ok": "Yes",
"app_bar_signout_dialog_title": "Sign out", "app_bar_signout_dialog_title": "Sign out",
"app_settings": "Programos nustatymai", "app_settings": "Programos nustatymai",
"appears_in": "",
"archive": "Archyvas", "archive": "Archyvas",
"archive_or_unarchive_photo": "Archyvuoti arba išarchyvuoti nuotrauką", "archive_or_unarchive_photo": "Archyvuoti arba išarchyvuoti nuotrauką",
"archive_page_no_archived_assets": "No archived assets found", "archive_page_no_archived_assets": "No archived assets found",
@ -488,7 +422,6 @@
"backup_manual_title": "Upload status", "backup_manual_title": "Upload status",
"backup_options_page_title": "Backup options", "backup_options_page_title": "Backup options",
"backup_setting_subtitle": "Manage background and foreground upload settings", "backup_setting_subtitle": "Manage background and foreground upload settings",
"backward": "",
"birthdate_saved": "Sėkmingai išsaugota gimimo data", "birthdate_saved": "Sėkmingai išsaugota gimimo data",
"blurred_background": "Neryškus fonas", "blurred_background": "Neryškus fonas",
"bugs_and_feature_requests": "Klaidų ir funkcijų užklausos", "bugs_and_feature_requests": "Klaidų ir funkcijų užklausos",
@ -527,7 +460,6 @@
"change_expiration_time": "Pakeisti galiojimo trukmę", "change_expiration_time": "Pakeisti galiojimo trukmę",
"change_location": "Pakeisti vietovę", "change_location": "Pakeisti vietovę",
"change_name": "Pakeisti vardą", "change_name": "Pakeisti vardą",
"change_name_successfully": "",
"change_password": "Pakeisti slaptažodį", "change_password": "Pakeisti slaptažodį",
"change_password_description": "Tai arba pirmas kartas, kai jungiatės prie sistemos, arba buvo pateikta užklausa pakeisti jūsų slaptažodį. Prašome įvesti naują slaptažodį žemiau.", "change_password_description": "Tai arba pirmas kartas, kai jungiatės prie sistemos, arba buvo pateikta užklausa pakeisti jūsų slaptažodį. Prašome įvesti naują slaptažodį žemiau.",
"change_password_form_confirm_password": "Confirm Password", "change_password_form_confirm_password": "Confirm Password",
@ -570,7 +502,6 @@
"confirm_admin_password": "Patvirtinti administratoriaus slaptažodį", "confirm_admin_password": "Patvirtinti administratoriaus slaptažodį",
"confirm_delete_shared_link": "Ar tikrai norite ištrinti šią bendrinimo nuorodą?", "confirm_delete_shared_link": "Ar tikrai norite ištrinti šią bendrinimo nuorodą?",
"confirm_password": "Patvirtinti slaptažodį", "confirm_password": "Patvirtinti slaptažodį",
"contain": "",
"context": "Kontekstas", "context": "Kontekstas",
"continue": "Tęsti", "continue": "Tęsti",
"control_bottom_app_bar_album_info_shared": "{} items · Shared", "control_bottom_app_bar_album_info_shared": "{} items · Shared",
@ -592,8 +523,6 @@
"copy_password": "Kopijuoti slaptažodį", "copy_password": "Kopijuoti slaptažodį",
"copy_to_clipboard": "Kopijuoti į iškarpinę", "copy_to_clipboard": "Kopijuoti į iškarpinę",
"country": "Šalis", "country": "Šalis",
"cover": "",
"covers": "",
"create": "Sukurti", "create": "Sukurti",
"create_album": "Sukurti albumą", "create_album": "Sukurti albumą",
"create_album_page_untitled": "Untitled", "create_album_page_untitled": "Untitled",
@ -615,24 +544,20 @@
"curated_object_page_title": "Things", "curated_object_page_title": "Things",
"current_device": "Dabartinis įrenginys", "current_device": "Dabartinis įrenginys",
"current_server_address": "Current server address", "current_server_address": "Current server address",
"custom_locale": "",
"custom_locale_description": "Formatuoti datas ir skaičius pagal kalbą ir regioną", "custom_locale_description": "Formatuoti datas ir skaičius pagal kalbą ir regioną",
"daily_title_text_date": "E, MMM dd", "daily_title_text_date": "E, MMM dd",
"daily_title_text_date_year": "E, MMM dd, yyyy", "daily_title_text_date_year": "E, MMM dd, yyyy",
"dark": "",
"date_after": "Data po", "date_after": "Data po",
"date_and_time": "Data ir laikas", "date_and_time": "Data ir laikas",
"date_before": "Data prieš", "date_before": "Data prieš",
"date_format": "E, LLL d, y • h:mm a", "date_format": "E, LLL d, y • h:mm a",
"date_of_birth_saved": "Gimimo data sėkmingai išsaugota", "date_of_birth_saved": "Gimimo data sėkmingai išsaugota",
"date_range": "",
"day": "Diena", "day": "Diena",
"deduplicate_all": "Šalinti visus dublikatus", "deduplicate_all": "Šalinti visus dublikatus",
"deduplication_criteria_1": "Failo dydis baitais", "deduplication_criteria_1": "Failo dydis baitais",
"deduplication_criteria_2": "EXIF metaduomenų įrašų skaičius", "deduplication_criteria_2": "EXIF metaduomenų įrašų skaičius",
"deduplication_info": "Dublikatų šalinimo informacija", "deduplication_info": "Dublikatų šalinimo informacija",
"deduplication_info_description": "Automatinis elementų parinkimas ir masinis dublikatų šalinimas atliekamas atsižvelgiant į:", "deduplication_info_description": "Automatinis elementų parinkimas ir masinis dublikatų šalinimas atliekamas atsižvelgiant į:",
"default_locale": "",
"default_locale_description": "Formatuoti datas ir skaičius pagal jūsų naršyklės lokalę", "default_locale_description": "Formatuoti datas ir skaičius pagal jūsų naršyklės lokalę",
"delete": "Ištrinti", "delete": "Ištrinti",
"delete_album": "Ištrinti albumą", "delete_album": "Ištrinti albumą",
@ -665,13 +590,10 @@
"discover": "Atrasti", "discover": "Atrasti",
"dismiss_all_errors": "Nepaisyti visų klaidų", "dismiss_all_errors": "Nepaisyti visų klaidų",
"dismiss_error": "Nepaisyti klaidos", "dismiss_error": "Nepaisyti klaidos",
"display_options": "",
"display_order": "Atvaizdavimo tvarka", "display_order": "Atvaizdavimo tvarka",
"display_original_photos": "Rodyti originalias nuotraukas", "display_original_photos": "Rodyti originalias nuotraukas",
"display_original_photos_setting_description": "",
"do_not_show_again": "Daugiau nerodyti šio pranešimo", "do_not_show_again": "Daugiau nerodyti šio pranešimo",
"documentation": "Dokumentacija", "documentation": "Dokumentacija",
"done": "",
"download": "Atsisiųsti", "download": "Atsisiųsti",
"download_canceled": "Download canceled", "download_canceled": "Download canceled",
"download_complete": "Download complete", "download_complete": "Download complete",
@ -711,7 +633,6 @@
"edit_title": "Redaguoti antraštę", "edit_title": "Redaguoti antraštę",
"edit_user": "Redaguoti naudotoją", "edit_user": "Redaguoti naudotoją",
"edited": "Redaguota", "edited": "Redaguota",
"editor": "",
"email": "El. paštas", "email": "El. paštas",
"empty_folder": "This folder is empty", "empty_folder": "This folder is empty",
"empty_trash": "Ištuštinti šiukšliadėžę", "empty_trash": "Ištuštinti šiukšliadėžę",
@ -763,56 +684,37 @@
"unable_to_create_library": "Nepavyko sukurti bibliotekos", "unable_to_create_library": "Nepavyko sukurti bibliotekos",
"unable_to_create_user": "Nepavyko sukurti naudotojo", "unable_to_create_user": "Nepavyko sukurti naudotojo",
"unable_to_delete_album": "Nepavyksta ištrinti albumo", "unable_to_delete_album": "Nepavyksta ištrinti albumo",
"unable_to_delete_asset": "",
"unable_to_delete_exclusion_pattern": "Nepavyksta ištrinti išimčių šablono", "unable_to_delete_exclusion_pattern": "Nepavyksta ištrinti išimčių šablono",
"unable_to_delete_import_path": "Nepavyksta ištrinti importavimo kelio", "unable_to_delete_import_path": "Nepavyksta ištrinti importavimo kelio",
"unable_to_delete_shared_link": "Nepavyko ištrinti bendrinimo nuorodos", "unable_to_delete_shared_link": "Nepavyko ištrinti bendrinimo nuorodos",
"unable_to_delete_user": "Nepavyksta ištrinti naudotojo", "unable_to_delete_user": "Nepavyksta ištrinti naudotojo",
"unable_to_edit_exclusion_pattern": "Nepavyksta redaguoti išimčių šablono", "unable_to_edit_exclusion_pattern": "Nepavyksta redaguoti išimčių šablono",
"unable_to_edit_import_path": "Nepavyksta redaguoti išimčių kelio", "unable_to_edit_import_path": "Nepavyksta redaguoti išimčių kelio",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "Nepavyksta pereiti į viso ekrano režimą", "unable_to_enter_fullscreen": "Nepavyksta pereiti į viso ekrano režimą",
"unable_to_exit_fullscreen": "Nepavyksta išeiti iš viso ekrano režimo", "unable_to_exit_fullscreen": "Nepavyksta išeiti iš viso ekrano režimo",
"unable_to_get_shared_link": "Nepavyko gauti bendrinimo nuorodos", "unable_to_get_shared_link": "Nepavyko gauti bendrinimo nuorodos",
"unable_to_hide_person": "Nepavyksta paslėpti žmogaus", "unable_to_hide_person": "Nepavyksta paslėpti žmogaus",
"unable_to_link_oauth_account": "Nepavyko susieti su OAuth paskyra", "unable_to_link_oauth_account": "Nepavyko susieti su OAuth paskyra",
"unable_to_load_album": "Nepavyksta užkrauti albumo", "unable_to_load_album": "Nepavyksta užkrauti albumo",
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_log_out_all_devices": "Nepavyksta atjungti visų įrenginių", "unable_to_log_out_all_devices": "Nepavyksta atjungti visų įrenginių",
"unable_to_log_out_device": "Nepavyksta atjungti įrenginio", "unable_to_log_out_device": "Nepavyksta atjungti įrenginio",
"unable_to_login_with_oauth": "Nepavyko prisijungti su OAuth", "unable_to_login_with_oauth": "Nepavyko prisijungti su OAuth",
"unable_to_play_video": "Nepavyksta paleisti vaizdo įrašo", "unable_to_play_video": "Nepavyksta paleisti vaizdo įrašo",
"unable_to_refresh_user": "Nepavyksta atnaujinti naudotojo", "unable_to_refresh_user": "Nepavyksta atnaujinti naudotojo",
"unable_to_remove_album_users": "",
"unable_to_remove_api_key": "Nepavyko pašalinti API rakto", "unable_to_remove_api_key": "Nepavyko pašalinti API rakto",
"unable_to_remove_assets_from_shared_link": "Nepavyko iš bendrinimo nuorodos pašalinti elementų", "unable_to_remove_assets_from_shared_link": "Nepavyko iš bendrinimo nuorodos pašalinti elementų",
"unable_to_remove_deleted_assets": "Nepavyko pašalinti nepasiekiamų elementų", "unable_to_remove_deleted_assets": "Nepavyko pašalinti nepasiekiamų elementų",
"unable_to_remove_library": "Nepavyksta pašalinti bibliotekos", "unable_to_remove_library": "Nepavyksta pašalinti bibliotekos",
"unable_to_remove_partner": "Nepavyksta pašalinti partnerio", "unable_to_remove_partner": "Nepavyksta pašalinti partnerio",
"unable_to_remove_reaction": "Nepavyksta pašalinti reakcijos", "unable_to_remove_reaction": "Nepavyksta pašalinti reakcijos",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "Nepavyko sutvarkyti dublikatų", "unable_to_resolve_duplicate": "Nepavyko sutvarkyti dublikatų",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_name": "",
"unable_to_save_profile": "Nepavyko išsaugoti profilio", "unable_to_save_profile": "Nepavyko išsaugoti profilio",
"unable_to_save_settings": "Nepavyksta išsaugoti nustatymų", "unable_to_save_settings": "Nepavyksta išsaugoti nustatymų",
"unable_to_scan_libraries": "Nepavyksta nuskaityti bibliotekų", "unable_to_scan_libraries": "Nepavyksta nuskaityti bibliotekų",
"unable_to_scan_library": "Nepavyksta nuskaityti bibliotekos", "unable_to_scan_library": "Nepavyksta nuskaityti bibliotekos",
"unable_to_set_feature_photo": "Nepavyksta nustatyti mėgstamiausios nuotraukos", "unable_to_set_feature_photo": "Nepavyksta nustatyti mėgstamiausios nuotraukos",
"unable_to_set_profile_picture": "Nepavyksta nustatyti profilio nuotraukos", "unable_to_set_profile_picture": "Nepavyksta nustatyti profilio nuotraukos",
"unable_to_submit_job": "",
"unable_to_trash_asset": "Nepavyko perkelti į šiukšliadėžę", "unable_to_trash_asset": "Nepavyko perkelti į šiukšliadėžę",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_user": "",
"unable_to_upload_file": "Nepavyksta įkelti failo" "unable_to_upload_file": "Nepavyksta įkelti failo"
}, },
"exif": "Exif", "exif": "Exif",
@ -831,7 +733,6 @@
"experimental_settings_new_asset_list_title": "Enable experimental photo grid", "experimental_settings_new_asset_list_title": "Enable experimental photo grid",
"experimental_settings_subtitle": "Use at your own risk!", "experimental_settings_subtitle": "Use at your own risk!",
"experimental_settings_title": "Experimental", "experimental_settings_title": "Experimental",
"expire_after": "",
"expired": "Nebegalioja", "expired": "Nebegalioja",
"expires_date": "Nebegalios už {date}", "expires_date": "Nebegalios už {date}",
"explore": "Naršyti", "explore": "Naršyti",
@ -850,27 +751,19 @@
"favorite_or_unfavorite_photo": "Įtraukti prie arba pašalinti iš mėgstamiausių", "favorite_or_unfavorite_photo": "Įtraukti prie arba pašalinti iš mėgstamiausių",
"favorites": "Mėgstamiausi", "favorites": "Mėgstamiausi",
"favorites_page_no_favorites": "No favorite assets found", "favorites_page_no_favorites": "No favorite assets found",
"feature_photo_updated": "",
"features": "Funkcijos", "features": "Funkcijos",
"features_setting_description": "Valdyti aplikacijos funkcijas", "features_setting_description": "Valdyti aplikacijos funkcijas",
"file_name": "Failo pavadinimas", "file_name": "Failo pavadinimas",
"file_name_or_extension": "Failo pavadinimas arba plėtinys", "file_name_or_extension": "Failo pavadinimas arba plėtinys",
"filename": "",
"filetype": "Failo tipas", "filetype": "Failo tipas",
"filter": "Filter", "filter": "Filter",
"filter_people": "Filtruoti žmones", "filter_people": "Filtruoti žmones",
"fix_incorrect_match": "",
"folder": "Folder", "folder": "Folder",
"folder_not_found": "Folder not found", "folder_not_found": "Folder not found",
"folders": "Aplankai", "folders": "Aplankai",
"folders_feature_description": "Peržiūrėkite failų sistemoje esančias nuotraukas ir vaizdo įrašus aplankų rodinyje", "folders_feature_description": "Peržiūrėkite failų sistemoje esančias nuotraukas ir vaizdo įrašus aplankų rodinyje",
"forward": "",
"general": "",
"get_help": "Gauti pagalbos", "get_help": "Gauti pagalbos",
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network", "get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
"getting_started": "",
"go_back": "",
"go_to_search": "",
"grant_permission": "Grant permission", "grant_permission": "Grant permission",
"group_albums_by": "Grupuoti albumus pagal...", "group_albums_by": "Grupuoti albumus pagal...",
"group_no": "Negrupuoti", "group_no": "Negrupuoti",
@ -906,7 +799,6 @@
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).", "home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
"home_page_share_err_local": "Can not share local assets via link, skipping", "home_page_share_err_local": "Can not share local assets via link, skipping",
"home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping", "home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
"host": "",
"hour": "Valanda", "hour": "Valanda",
"ignore_icloud_photos": "Ignore iCloud photos", "ignore_icloud_photos": "Ignore iCloud photos",
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server", "ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
@ -922,11 +814,9 @@
"include_archived": "Įtraukti archyvuotus", "include_archived": "Įtraukti archyvuotus",
"include_shared_albums": "Įtraukti bendrinamus albumus", "include_shared_albums": "Įtraukti bendrinamus albumus",
"include_shared_partner_assets": "Įtraukti partnerio pasidalintus elementus", "include_shared_partner_assets": "Įtraukti partnerio pasidalintus elementus",
"individual_share": "",
"info": "Informacija", "info": "Informacija",
"interval": { "interval": {
"day_at_onepm": "Kiekvieną dieną 13:00", "day_at_onepm": "Kiekvieną dieną 13:00",
"hours": "",
"night_at_midnight": "Kiekvieną vidurnaktį", "night_at_midnight": "Kiekvieną vidurnaktį",
"night_at_twoam": "Kiekvieną naktį 02:00" "night_at_twoam": "Kiekvieną naktį 02:00"
}, },
@ -955,7 +845,6 @@
"library_page_sort_created": "Created date", "library_page_sort_created": "Created date",
"library_page_sort_last_modified": "Last modified", "library_page_sort_last_modified": "Last modified",
"library_page_sort_title": "Album title", "library_page_sort_title": "Album title",
"light": "",
"link_options": "Nuorodų parinktys", "link_options": "Nuorodų parinktys",
"link_to_oauth": "Susieti su OAuth", "link_to_oauth": "Susieti su OAuth",
"linked_oauth_account": "Susieta OAuth paskyra", "linked_oauth_account": "Susieta OAuth paskyra",
@ -1000,9 +889,7 @@
"logout_all_device_confirmation": "Ar tikrai norite atsijungti iš visų įrenginių?", "logout_all_device_confirmation": "Ar tikrai norite atsijungti iš visų įrenginių?",
"logout_this_device_confirmation": "Ar tikrai norite atsijungti iš šio prietaiso?", "logout_this_device_confirmation": "Ar tikrai norite atsijungti iš šio prietaiso?",
"longitude": "Ilguma", "longitude": "Ilguma",
"look": "",
"loop_videos": "Kartoti vaizdo įrašus", "loop_videos": "Kartoti vaizdo įrašus",
"loop_videos_description": "",
"make": "Gamintojas", "make": "Gamintojas",
"manage_shared_links": "Bendrinimo nuorodų tvarkymas", "manage_shared_links": "Bendrinimo nuorodų tvarkymas",
"manage_sharing_with_partners": "Valdyti dalijimąsi su partneriais", "manage_sharing_with_partners": "Valdyti dalijimąsi su partneriais",
@ -1019,7 +906,6 @@
"map_location_picker_page_use_location": "Use this location", "map_location_picker_page_use_location": "Use this location",
"map_location_service_disabled_content": "Location service needs to be enabled to display assets from your current location. Do you want to enable it now?", "map_location_service_disabled_content": "Location service needs to be enabled to display assets from your current location. Do you want to enable it now?",
"map_location_service_disabled_title": "Location Service disabled", "map_location_service_disabled_title": "Location Service disabled",
"map_marker_with_image": "",
"map_no_assets_in_bounds": "No photos in this area", "map_no_assets_in_bounds": "No photos in this area",
"map_no_location_permission_content": "Location permission is needed to display assets from your current location. Do you want to allow it now?", "map_no_location_permission_content": "Location permission is needed to display assets from your current location. Do you want to allow it now?",
"map_no_location_permission_title": "Location Permission denied", "map_no_location_permission_title": "Location Permission denied",
@ -1086,15 +972,11 @@
"no_assets_message": "SPUSTELĖKITE NORĖDAMI ĮKELTI PIRMĄJĄ NUOTRAUKĄ", "no_assets_message": "SPUSTELĖKITE NORĖDAMI ĮKELTI PIRMĄJĄ NUOTRAUKĄ",
"no_assets_to_show": "No assets to show", "no_assets_to_show": "No assets to show",
"no_duplicates_found": "Dublikatų nerasta.", "no_duplicates_found": "Dublikatų nerasta.",
"no_exif_info_available": "",
"no_explore_results_message": "Įkelkite daugiau nuotraukų ir tyrinėkite savo kolekciją.", "no_explore_results_message": "Įkelkite daugiau nuotraukų ir tyrinėkite savo kolekciją.",
"no_favorites_message": "",
"no_libraries_message": "Sukurkite išorinę biblioteką nuotraukoms ir vaizdo įrašams peržiūrėti", "no_libraries_message": "Sukurkite išorinę biblioteką nuotraukoms ir vaizdo įrašams peržiūrėti",
"no_name": "Be vardo", "no_name": "Be vardo",
"no_places": "",
"no_results": "Nerasta", "no_results": "Nerasta",
"no_results_description": "Pabandykite sinonimą arba bendresnį raktažodį", "no_results_description": "Pabandykite sinonimą arba bendresnį raktažodį",
"no_shared_albums_message": "",
"not_in_any_album": "Nė viename albume", "not_in_any_album": "Nė viename albume",
"not_selected": "Not selected", "not_selected": "Not selected",
"notes": "Pastabos", "notes": "Pastabos",
@ -1120,7 +1002,6 @@
"or": "arba", "or": "arba",
"organize_your_library": "Tvarkykite savo biblioteką", "organize_your_library": "Tvarkykite savo biblioteką",
"original": "Originalas", "original": "Originalas",
"other": "",
"other_devices": "Kiti įrenginiai", "other_devices": "Kiti įrenginiai",
"other_variables": "Kiti kintamieji", "other_variables": "Kiti kintamieji",
"owned": "Nuosavi", "owned": "Nuosavi",
@ -1137,19 +1018,12 @@
"partner_page_select_partner": "Select partner", "partner_page_select_partner": "Select partner",
"partner_page_shared_to_title": "Shared to", "partner_page_shared_to_title": "Shared to",
"partner_page_stop_sharing_content": "{} will no longer be able to access your photos.", "partner_page_stop_sharing_content": "{} will no longer be able to access your photos.",
"partner_sharing": "",
"partners": "Partneriai", "partners": "Partneriai",
"password": "Slaptažodis", "password": "Slaptažodis",
"password_does_not_match": "Slaptažodis nesutampa", "password_does_not_match": "Slaptažodis nesutampa",
"password_required": "Reikalingas slaptažodis", "password_required": "Reikalingas slaptažodis",
"password_reset_success": "Slaptažodis sėkmingai atkurtas", "password_reset_success": "Slaptažodis sėkmingai atkurtas",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "Kelias", "path": "Kelias",
"pattern": "",
"pause": "Sustabdyti", "pause": "Sustabdyti",
"pause_memories": "Pristabdyti atsiminimus", "pause_memories": "Pristabdyti atsiminimus",
"paused": "Sustabdyta", "paused": "Sustabdyta",
@ -1158,11 +1032,8 @@
"people_edits_count": "{count, plural, one {Redaguotas # asmuo} few {Redaguoti # asmenys} other {Redaguota # asmenų}}", "people_edits_count": "{count, plural, one {Redaguotas # asmuo} few {Redaguoti # asmenys} other {Redaguota # asmenų}}",
"people_feature_description": "Peržiūrėkite nuotraukas ir vaizdo įrašus sugrupuotus pagal asmenis", "people_feature_description": "Peržiūrėkite nuotraukas ir vaizdo įrašus sugrupuotus pagal asmenis",
"people_sidebar_description": "Rodyti asmenų rodinio nuorodą šoninėje juostoje", "people_sidebar_description": "Rodyti asmenų rodinio nuorodą šoninėje juostoje",
"permanent_deletion_warning": "",
"permanent_deletion_warning_setting_description": "",
"permanently_delete": "Ištrinti visam laikui", "permanently_delete": "Ištrinti visam laikui",
"permanently_delete_assets_count": "Visam laikui ištrinti {count, plural, one {# elementą} few {# elementus} other {# elementų}}", "permanently_delete_assets_count": "Visam laikui ištrinti {count, plural, one {# elementą} few {# elementus} other {# elementų}}",
"permanently_deleted_asset": "",
"permanently_deleted_assets_count": "Visam laikui {count, plural, one {ištrintas # elementas} few {ištrinti # elementai} other {ištrinta # elementų}}", "permanently_deleted_assets_count": "Visam laikui {count, plural, one {ištrintas # elementas} few {ištrinti # elementai} other {ištrinta # elementų}}",
"permission_onboarding_back": "Back", "permission_onboarding_back": "Back",
"permission_onboarding_continue_anyway": "Continue anyway", "permission_onboarding_continue_anyway": "Continue anyway",
@ -1176,22 +1047,11 @@
"photos_and_videos": "Nuotraukos ir vaizdo įrašai", "photos_and_videos": "Nuotraukos ir vaizdo įrašai",
"photos_count": "{count, plural, one {{count, number} nuotrauka} few {{count, number} nuotraukos} other {{count, number} nuotraukų}}", "photos_count": "{count, plural, one {{count, number} nuotrauka} few {{count, number} nuotraukos} other {{count, number} nuotraukų}}",
"photos_from_previous_years": "Ankstesnių metų nuotraukos", "photos_from_previous_years": "Ankstesnių metų nuotraukos",
"pick_a_location": "",
"place": "Vieta", "place": "Vieta",
"places": "Vietos", "places": "Vietos",
"play": "",
"play_memories": "Leisti atsiminimus", "play_memories": "Leisti atsiminimus",
"play_motion_photo": "",
"play_or_pause_video": "",
"port": "",
"preferences_settings_subtitle": "Manage the app's preferences", "preferences_settings_subtitle": "Manage the app's preferences",
"preferences_settings_title": "Preferences", "preferences_settings_title": "Preferences",
"preset": "",
"preview": "",
"previous": "",
"previous_memory": "",
"previous_or_next_photo": "",
"primary": "",
"profile_drawer_app_logs": "Logs", "profile_drawer_app_logs": "Logs",
"profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.", "profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.",
"profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.", "profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.",
@ -1202,7 +1062,6 @@
"profile_image_of_user": "{user} profilio nuotrauka", "profile_image_of_user": "{user} profilio nuotrauka",
"profile_picture_set": "Profilio nuotrauka nustatyta.", "profile_picture_set": "Profilio nuotrauka nustatyta.",
"public_album": "Viešas albumas", "public_album": "Viešas albumas",
"public_share": "",
"purchase_account_info": "Rėmėjas", "purchase_account_info": "Rėmėjas",
"purchase_activated_subtitle": "Dėkojame, kad remiate Immich ir atviro kodo programinę įrangą", "purchase_activated_subtitle": "Dėkojame, kad remiate Immich ir atviro kodo programinę įrangą",
"purchase_activated_time": "Suaktyvinta {date}", "purchase_activated_time": "Suaktyvinta {date}",
@ -1237,10 +1096,6 @@
"rating": "Įvertinimas žvaigždutėmis", "rating": "Įvertinimas žvaigždutėmis",
"rating_count": "{count, plural, one {# įvertinimas} few {# įvertinimai} other {# įvertinimų}}", "rating_count": "{count, plural, one {# įvertinimas} few {# įvertinimai} other {# įvertinimų}}",
"rating_description": "Rodyti EXIF įvertinimus informacijos skydelyje", "rating_description": "Rodyti EXIF įvertinimus informacijos skydelyje",
"reaction_options": "",
"read_changelog": "",
"recent": "",
"recent_searches": "",
"recently_added": "Recently added", "recently_added": "Recently added",
"recently_added_page_title": "Recently Added", "recently_added_page_title": "Recently Added",
"refresh": "Atnaujinti", "refresh": "Atnaujinti",
@ -1255,7 +1110,6 @@
"refreshing_metadata": "Perkraunami metaduomenys", "refreshing_metadata": "Perkraunami metaduomenys",
"remove": "Pašalinti", "remove": "Pašalinti",
"remove_assets_shared_link_confirmation": "Ar tikrai norite pašalinti {count, plural, one {# elementą} few {# elementus} other {# elementų}} iš šios bendrinimo nuorodos?", "remove_assets_shared_link_confirmation": "Ar tikrai norite pašalinti {count, plural, one {# elementą} few {# elementus} other {# elementų}} iš šios bendrinimo nuorodos?",
"remove_deleted_assets": "",
"remove_from_album": "Pašalinti iš albumo", "remove_from_album": "Pašalinti iš albumo",
"remove_from_favorites": "Pašalinti iš mėgstamiausių", "remove_from_favorites": "Pašalinti iš mėgstamiausių",
"remove_from_shared_link": "Pašalinti iš bendrinimo nuorodos", "remove_from_shared_link": "Pašalinti iš bendrinimo nuorodos",
@ -1273,16 +1127,12 @@
"replace_with_upload": "Pakeisti naujai įkeltu failu", "replace_with_upload": "Pakeisti naujai įkeltu failu",
"require_password": "Reikalauti slaptažodžio", "require_password": "Reikalauti slaptažodžio",
"reset": "Atstatyti", "reset": "Atstatyti",
"reset_password": "",
"reset_people_visibility": "",
"resolve_duplicates": "Sutvarkyti dublikatus", "resolve_duplicates": "Sutvarkyti dublikatus",
"resolved_all_duplicates": "Sutvarkyti visi dublikatai", "resolved_all_duplicates": "Sutvarkyti visi dublikatai",
"restore": "Atkurti", "restore": "Atkurti",
"restore_all": "Atkurti visus", "restore_all": "Atkurti visus",
"restore_user": "Atkurti naudotoją", "restore_user": "Atkurti naudotoją",
"retry_upload": "",
"review_duplicates": "Peržiūrėti dublikatus", "review_duplicates": "Peržiūrėti dublikatus",
"role": "",
"save": "Išsaugoti", "save": "Išsaugoti",
"save_to_gallery": "Save to gallery", "save_to_gallery": "Save to gallery",
"saved_api_key": "Išsaugotas API raktas", "saved_api_key": "Išsaugotas API raktas",
@ -1294,14 +1144,10 @@
"scan_library": "Skenuoti", "scan_library": "Skenuoti",
"scan_settings": "Skenavimo nustatymai", "scan_settings": "Skenavimo nustatymai",
"search": "Ieškoti", "search": "Ieškoti",
"search_albums": "",
"search_by_context": "Ieškoti pagal kontekstą", "search_by_context": "Ieškoti pagal kontekstą",
"search_by_description_example": "Žygio diena Sapoje", "search_by_description_example": "Žygio diena Sapoje",
"search_by_filename": "Ieškoti pagal failo pavadinimą arba plėtinį", "search_by_filename": "Ieškoti pagal failo pavadinimą arba plėtinį",
"search_by_filename_example": "pvz. IMG_1234.JPG arba PNG", "search_by_filename_example": "pvz. IMG_1234.JPG arba PNG",
"search_camera_make": "",
"search_camera_model": "",
"search_city": "",
"search_country": "Ieškoti šalies...", "search_country": "Ieškoti šalies...",
"search_filter_apply": "Apply filter", "search_filter_apply": "Apply filter",
"search_filter_camera_title": "Select camera type", "search_filter_camera_title": "Select camera type",
@ -1316,7 +1162,6 @@
"search_filter_media_type": "Media Type", "search_filter_media_type": "Media Type",
"search_filter_media_type_title": "Select media type", "search_filter_media_type_title": "Select media type",
"search_filter_people_title": "Select people", "search_filter_people_title": "Select people",
"search_for_existing_person": "",
"search_no_more_result": "No more results", "search_no_more_result": "No more results",
"search_no_people_named": "Nėra žmonių vardu „{name}“", "search_no_people_named": "Nėra žmonių vardu „{name}“",
"search_no_result": "No results found, try a different search term or combination", "search_no_result": "No results found, try a different search term or combination",
@ -1335,25 +1180,17 @@
"search_places": "Ieškoti vietų", "search_places": "Ieškoti vietų",
"search_result_page_new_search_hint": "New Search", "search_result_page_new_search_hint": "New Search",
"search_settings": "Ieškoti nustatymų", "search_settings": "Ieškoti nustatymų",
"search_state": "",
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ", "search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
"search_suggestion_list_smart_search_hint_2": "m:your-search-term", "search_suggestion_list_smart_search_hint_2": "m:your-search-term",
"search_tags": "Ieškoti žymų...", "search_tags": "Ieškoti žymų...",
"search_timezone": "",
"search_type": "Paieškos tipas", "search_type": "Paieškos tipas",
"search_your_photos": "Ieškoti nuotraukų", "search_your_photos": "Ieškoti nuotraukų",
"searching_locales": "",
"second": "",
"select_album_cover": "",
"select_all": "",
"select_all_duplicates": "Pasirinkti visus dublikatus", "select_all_duplicates": "Pasirinkti visus dublikatus",
"select_avatar_color": "Pasirinkti avataro spalvą", "select_avatar_color": "Pasirinkti avataro spalvą",
"select_face": "Pasirinkti veidą", "select_face": "Pasirinkti veidą",
"select_featured_photo": "Pasirinkti rodomą nuotrauką", "select_featured_photo": "Pasirinkti rodomą nuotrauką",
"select_keep_all": "Visus pažymėti \"Palikti\"", "select_keep_all": "Visus pažymėti \"Palikti\"",
"select_library_owner": "Pasirinkti bibliotekos savininką", "select_library_owner": "Pasirinkti bibliotekos savininką",
"select_new_face": "",
"select_photos": "",
"select_trash_all": "Visus pažymėti \"Išmesti\"", "select_trash_all": "Visus pažymėti \"Išmesti\"",
"select_user_for_sharing_page_err_album": "Failed to create album", "select_user_for_sharing_page_err_album": "Failed to create album",
"selected": "Pasirinkta", "selected": "Pasirinkta",
@ -1368,7 +1205,6 @@
"server_stats": "Serverio statistika", "server_stats": "Serverio statistika",
"server_version": "Serverio versija", "server_version": "Serverio versija",
"set": "Nustatyti", "set": "Nustatyti",
"set_as_album_cover": "",
"set_as_profile_picture": "Nustatyti kaip profilio nuotrauką", "set_as_profile_picture": "Nustatyti kaip profilio nuotrauką",
"set_date_of_birth": "Nustatyti gimimo datą", "set_date_of_birth": "Nustatyti gimimo datą",
"set_profile_picture": "Nustatyti profilio nuotrauką", "set_profile_picture": "Nustatyti profilio nuotrauką",
@ -1398,7 +1234,6 @@
"setting_video_viewer_original_video_title": "Force original video", "setting_video_viewer_original_video_title": "Force original video",
"settings": "Nustatymai", "settings": "Nustatymai",
"settings_require_restart": "Please restart Immich to apply this setting", "settings_require_restart": "Please restart Immich to apply this setting",
"settings_saved": "",
"share": "Dalintis", "share": "Dalintis",
"share_add_photos": "Add photos", "share_add_photos": "Add photos",
"share_assets_selected": "{} selected", "share_assets_selected": "{} selected",
@ -1411,8 +1246,6 @@
"shared_album_section_people_action_leave": "Remove user from album", "shared_album_section_people_action_leave": "Remove user from album",
"shared_album_section_people_action_remove_user": "Remove user from album", "shared_album_section_people_action_remove_user": "Remove user from album",
"shared_album_section_people_title": "PEOPLE", "shared_album_section_people_title": "PEOPLE",
"shared_by": "",
"shared_by_you": "",
"shared_intent_upload_button_progress_text": "{} / {} Uploaded", "shared_intent_upload_button_progress_text": "{} / {} Uploaded",
"shared_link_app_bar_title": "Shared Links", "shared_link_app_bar_title": "Shared Links",
"shared_link_clipboard_copied_massage": "Copied to clipboard", "shared_link_clipboard_copied_massage": "Copied to clipboard",
@ -1458,20 +1291,15 @@
"show_album_options": "Rodyti albumo parinktis", "show_album_options": "Rodyti albumo parinktis",
"show_file_location": "Rodyti rinkmenos vietą", "show_file_location": "Rodyti rinkmenos vietą",
"show_gallery": "Rodyti galeriją", "show_gallery": "Rodyti galeriją",
"show_hidden_people": "",
"show_in_timeline": "Rodyti laiko skalėje", "show_in_timeline": "Rodyti laiko skalėje",
"show_in_timeline_setting_description": "Rodyti šio naudotojo nuotraukas ir vaizdo įrašus mano laiko skalėje", "show_in_timeline_setting_description": "Rodyti šio naudotojo nuotraukas ir vaizdo įrašus mano laiko skalėje",
"show_keyboard_shortcuts": "",
"show_metadata": "Rodyti metaduomenis", "show_metadata": "Rodyti metaduomenis",
"show_or_hide_info": "Rodyti arba slėpti informaciją", "show_or_hide_info": "Rodyti arba slėpti informaciją",
"show_password": "Rodyti slaptažodį", "show_password": "Rodyti slaptažodį",
"show_person_options": "",
"show_progress_bar": "",
"show_search_options": "Rodyti paieškos parinktis", "show_search_options": "Rodyti paieškos parinktis",
"show_slideshow_transition": "Rodyti perėjimą tarp skaidrių", "show_slideshow_transition": "Rodyti perėjimą tarp skaidrių",
"show_supporter_badge": "Rėmėjo ženklelis", "show_supporter_badge": "Rėmėjo ženklelis",
"show_supporter_badge_description": "Rodyti rėmėjo ženklelį", "show_supporter_badge_description": "Rodyti rėmėjo ženklelį",
"shuffle": "",
"sidebar": "Šoninė juosta", "sidebar": "Šoninė juosta",
"sidebar_display_description": "Rodyti rodinio nuorodą šoninėje juostoje", "sidebar_display_description": "Rodyti rodinio nuorodą šoninėje juostoje",
"sign_out": "Atsijungti", "sign_out": "Atsijungti",
@ -1480,7 +1308,6 @@
"skip_to_content": "Pereiti prie turinio", "skip_to_content": "Pereiti prie turinio",
"slideshow": "Skaidrių peržiūra", "slideshow": "Skaidrių peržiūra",
"slideshow_settings": "Skaidrių peržiūros nustatymai", "slideshow_settings": "Skaidrių peržiūros nustatymai",
"sort_albums_by": "",
"sort_created": "Sukūrimo data", "sort_created": "Sukūrimo data",
"sort_modified": "Keitimo data", "sort_modified": "Keitimo data",
"sort_oldest": "Seniausia nuotrauka", "sort_oldest": "Seniausia nuotrauka",
@ -1492,20 +1319,14 @@
"stack_select_one_photo": "Pasirinkti pagrindinę grupės nuotrauką", "stack_select_one_photo": "Pasirinkti pagrindinę grupės nuotrauką",
"stack_selected_photos": "Grupuoti pasirinktas nuotraukas", "stack_selected_photos": "Grupuoti pasirinktas nuotraukas",
"stacked_assets_count": "{count, plural, one {Sugrupuotas # elementas} few {Sugrupuoti # elementai} other {Sugrupuota # elementų}}", "stacked_assets_count": "{count, plural, one {Sugrupuotas # elementas} few {Sugrupuoti # elementai} other {Sugrupuota # elementų}}",
"stacktrace": "",
"start": "Pradėti", "start": "Pradėti",
"start_date": "Pradžios data", "start_date": "Pradžios data",
"state": "",
"status": "Statusas", "status": "Statusas",
"stop_motion_photo": "",
"storage": "Saugykla", "storage": "Saugykla",
"storage_label": "",
"storage_usage": "Naudojama {used} iš {available}", "storage_usage": "Naudojama {used} iš {available}",
"submit": "Pateikti", "submit": "Pateikti",
"suggestions": "",
"sunrise_on_the_beach": "Saulėtekis paplūdimyje", "sunrise_on_the_beach": "Saulėtekis paplūdimyje",
"support_and_feedback": "Palaikymas ir atsiliepimai", "support_and_feedback": "Palaikymas ir atsiliepimai",
"swap_merge_direction": "",
"sync": "Sinchronizuoti", "sync": "Sinchronizuoti",
"sync_albums": "Sync albums", "sync_albums": "Sync albums",
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums", "sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
@ -1519,8 +1340,6 @@
"tags": "Žymos", "tags": "Žymos",
"template": "Šablonas", "template": "Šablonas",
"theme": "Tema", "theme": "Tema",
"theme_selection": "",
"theme_selection_description": "",
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles", "theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})", "theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})",
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.", "theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
@ -1541,9 +1360,6 @@
"to_change_password": "Pakeisti slaptažodį", "to_change_password": "Pakeisti slaptažodį",
"to_favorite": "Įtraukti prie mėgstamiausių", "to_favorite": "Įtraukti prie mėgstamiausių",
"to_trash": "Išmesti", "to_trash": "Išmesti",
"toggle_settings": "",
"toggle_theme": "",
"total_usage": "",
"trash": "Šiukšliadėžė", "trash": "Šiukšliadėžė",
"trash_all": "Perkelti visus į šiukšliadėžę", "trash_all": "Perkelti visus į šiukšliadėžę",
"trash_count": "Perkelti {count, number} į šiukšliadėžę", "trash_count": "Perkelti {count, number} į šiukšliadėžę",
@ -1561,8 +1377,6 @@
"unarchive": "Išarchyvuoti", "unarchive": "Išarchyvuoti",
"unarchived_count": "{count, plural, other {# išarchyvuota}}", "unarchived_count": "{count, plural, other {# išarchyvuota}}",
"unfavorite": "Pašalinti iš mėgstamiausių", "unfavorite": "Pašalinti iš mėgstamiausių",
"unhide_person": "",
"unknown": "",
"unknown_year": "Nežinomi metai", "unknown_year": "Nežinomi metai",
"unlink_oauth": "Atsieti OAuth", "unlink_oauth": "Atsieti OAuth",
"unlinked_oauth_account": "Atsieta OAuth paskyra", "unlinked_oauth_account": "Atsieta OAuth paskyra",
@ -1574,7 +1388,6 @@
"unstacked_assets_count": "{count, plural, one {Išgrupuotas # elementas} few {Išgrupuoti # elementai} other {Išgrupuota # elementų}}", "unstacked_assets_count": "{count, plural, one {Išgrupuotas # elementas} few {Išgrupuoti # elementai} other {Išgrupuota # elementų}}",
"untracked_files": "Nesekami failai", "untracked_files": "Nesekami failai",
"untracked_files_decription": "Šie failai aplikacijos nesekami. Jie galėjo atsirasti dėl nepavykusio perkėlimo, nutraukto įkėlimo ar palikti per klaidą", "untracked_files_decription": "Šie failai aplikacijos nesekami. Jie galėjo atsirasti dėl nepavykusio perkėlimo, nutraukto įkėlimo ar palikti per klaidą",
"up_next": "",
"updated_at": "Atnaujintas", "updated_at": "Atnaujintas",
"updated_password": "Slaptažodis atnaujintas", "updated_password": "Slaptažodis atnaujintas",
"upload": "Įkelti", "upload": "Įkelti",
@ -1597,7 +1410,6 @@
"user_id": "Naudotojo ID", "user_id": "Naudotojo ID",
"user_pin_code_settings": "PIN kodas", "user_pin_code_settings": "PIN kodas",
"user_pin_code_settings_description": "Tvarkykite savo PIN kodą", "user_pin_code_settings_description": "Tvarkykite savo PIN kodą",
"user_usage_detail": "",
"user_usage_stats": "Paskyros naudojimo statistika", "user_usage_stats": "Paskyros naudojimo statistika",
"user_usage_stats_description": "Žiūrėti paskyros naudojimo statistiką", "user_usage_stats_description": "Žiūrėti paskyros naudojimo statistiką",
"username": "Naudotojo vardas", "username": "Naudotojo vardas",
@ -1625,8 +1437,6 @@
"view_all_users": "Peržiūrėti visus naudotojus", "view_all_users": "Peržiūrėti visus naudotojus",
"view_in_timeline": "Žiūrėti laiko skalėje", "view_in_timeline": "Žiūrėti laiko skalėje",
"view_links": "Žiūrėti nuorodas", "view_links": "Žiūrėti nuorodas",
"view_next_asset": "",
"view_previous_asset": "",
"view_stack": "Peržiūrėti grupę", "view_stack": "Peržiūrėti grupę",
"viewer_remove_from_stack": "Remove from Stack", "viewer_remove_from_stack": "Remove from Stack",
"viewer_stack_use_as_main_asset": "Use as Main Asset", "viewer_stack_use_as_main_asset": "Use as Main Asset",

View file

@ -56,10 +56,6 @@
"face_detection": "Seju noteikšana", "face_detection": "Seju noteikšana",
"image_format": "Formāts", "image_format": "Formāts",
"image_format_description": "WebP veido mazākus failus nekā JPEG, taču to kodēšana ir lēnāka.", "image_format_description": "WebP veido mazākus failus nekā JPEG, taču to kodēšana ir lēnāka.",
"image_prefer_embedded_preview": "",
"image_prefer_embedded_preview_setting_description": "",
"image_prefer_wide_gamut": "",
"image_prefer_wide_gamut_setting_description": "",
"image_quality": "Kvalitāte", "image_quality": "Kvalitāte",
"image_resolution": "Izšķirtspēja", "image_resolution": "Izšķirtspēja",
"image_settings": "Attēla Iestatījumi", "image_settings": "Attēla Iestatījumi",
@ -70,98 +66,43 @@
"job_settings_description": "Uzdevumu izpildes vienlaicīguma pārvaldība", "job_settings_description": "Uzdevumu izpildes vienlaicīguma pārvaldība",
"job_status": "Uzdevumu statuss", "job_status": "Uzdevumu statuss",
"library_deleted": "Bibliotēka dzēsta", "library_deleted": "Bibliotēka dzēsta",
"library_scanning": "",
"library_scanning_description": "",
"library_scanning_enable_description": "",
"library_settings": "",
"library_settings_description": "Ārējo bibliotēku iestatījumu pārvaldība", "library_settings_description": "Ārējo bibliotēku iestatījumu pārvaldība",
"library_tasks_description": "",
"library_watching_enable_description": "",
"library_watching_settings": "",
"library_watching_settings_description": "",
"logging_enable_description": "",
"logging_level_description": "",
"logging_settings": "",
"machine_learning_clip_model": "CLIP modelis", "machine_learning_clip_model": "CLIP modelis",
"machine_learning_duplicate_detection": "Dublikātu noteikšana", "machine_learning_duplicate_detection": "Dublikātu noteikšana",
"machine_learning_duplicate_detection_enabled_description": "",
"machine_learning_duplicate_detection_setting_description": "",
"machine_learning_enabled_description": "",
"machine_learning_facial_recognition": "Seju atpazīšana", "machine_learning_facial_recognition": "Seju atpazīšana",
"machine_learning_facial_recognition_description": "",
"machine_learning_facial_recognition_model": "Seju atpazīšanas modelis", "machine_learning_facial_recognition_model": "Seju atpazīšanas modelis",
"machine_learning_facial_recognition_model_description": "",
"machine_learning_facial_recognition_setting_description": "",
"machine_learning_max_detection_distance": "",
"machine_learning_max_detection_distance_description": "",
"machine_learning_max_recognition_distance": "",
"machine_learning_max_recognition_distance_description": "",
"machine_learning_min_detection_score": "",
"machine_learning_min_detection_score_description": "",
"machine_learning_min_recognized_faces": "",
"machine_learning_min_recognized_faces_description": "",
"machine_learning_settings": "Mašīnmācīšanās iestatījumi", "machine_learning_settings": "Mašīnmācīšanās iestatījumi",
"machine_learning_settings_description": "Mašīnmācīšanās funkciju un iestatījumu pārvaldība", "machine_learning_settings_description": "Mašīnmācīšanās funkciju un iestatījumu pārvaldība",
"machine_learning_smart_search": "Viedā meklēšana", "machine_learning_smart_search": "Viedā meklēšana",
"machine_learning_smart_search_description": "",
"machine_learning_smart_search_enabled_description": "",
"machine_learning_url_description": "Mašīnmācīšanās servera URL", "machine_learning_url_description": "Mašīnmācīšanās servera URL",
"manage_concurrency": "Vienlaicīgas darbības pārvaldība", "manage_concurrency": "Vienlaicīgas darbības pārvaldība",
"manage_log_settings": "Žurnāla iestatījumu pārvaldība", "manage_log_settings": "Žurnāla iestatījumu pārvaldība",
"map_dark_style": "",
"map_enable_description": "",
"map_gps_settings": "Kartes un GPS iestatījumi", "map_gps_settings": "Kartes un GPS iestatījumi",
"map_gps_settings_description": "Karšu un GPS (apgrieztās ģeokodēšanas) iestatījumu pārvaldība", "map_gps_settings_description": "Karšu un GPS (apgrieztās ģeokodēšanas) iestatījumu pārvaldība",
"map_light_style": "",
"map_manage_reverse_geocoding_settings": "<link>Reversās ģeokodēšanas</link> iestatījumu pārvaldība", "map_manage_reverse_geocoding_settings": "<link>Reversās ģeokodēšanas</link> iestatījumu pārvaldība",
"map_reverse_geocoding": "",
"map_reverse_geocoding_enable_description": "",
"map_reverse_geocoding_settings": "",
"map_settings": "Karte", "map_settings": "Karte",
"map_settings_description": "Kartes iestatījumu pārvaldība", "map_settings_description": "Kartes iestatījumu pārvaldība",
"map_style_description": "",
"metadata_extraction_job": "Metadatu iegūšana", "metadata_extraction_job": "Metadatu iegūšana",
"metadata_extraction_job_description": "",
"metadata_settings": "Metadatu iestatījumi", "metadata_settings": "Metadatu iestatījumi",
"metadata_settings_description": "Metadatu iestatījumu pārvaldība", "metadata_settings_description": "Metadatu iestatījumu pārvaldība",
"migration_job": "Migrācija", "migration_job": "Migrācija",
"migration_job_description": "",
"no_paths_added": "Nav pievienots neviens ceļš", "no_paths_added": "Nav pievienots neviens ceļš",
"no_pattern_added": "Nav pievienots neviens izslēgšanas šablons", "no_pattern_added": "Nav pievienots neviens izslēgšanas šablons",
"note_cannot_be_changed_later": "PIEZĪME: Vēlāk to vairs nevar mainīt!", "note_cannot_be_changed_later": "PIEZĪME: Vēlāk to vairs nevar mainīt!",
"notification_email_from_address": "No adreses", "notification_email_from_address": "No adreses",
"notification_email_from_address_description": "Sūtītāja e-pasta adrese, piemēram: “Immich foto serveris <noreply@example.com>”", "notification_email_from_address_description": "Sūtītāja e-pasta adrese, piemēram: “Immich foto serveris <noreply@example.com>”",
"notification_email_host_description": "",
"notification_email_ignore_certificate_errors": "Ignorēt sertifikātu kļūdas", "notification_email_ignore_certificate_errors": "Ignorēt sertifikātu kļūdas",
"notification_email_ignore_certificate_errors_description": "Ignorēt TLS sertifikāta apstiprināšanas kļūdas (nav ieteicams)", "notification_email_ignore_certificate_errors_description": "Ignorēt TLS sertifikāta apstiprināšanas kļūdas (nav ieteicams)",
"notification_email_password_description": "",
"notification_email_port_description": "e-pasta servera ports (piemēram, 25, 465 vai 587)", "notification_email_port_description": "e-pasta servera ports (piemēram, 25, 465 vai 587)",
"notification_email_sent_test_email_button": "Nosūtīt testa e-pastu un saglabāt", "notification_email_sent_test_email_button": "Nosūtīt testa e-pastu un saglabāt",
"notification_email_setting_description": "",
"notification_email_test_email": "Nosūtīt testa e-pastu", "notification_email_test_email": "Nosūtīt testa e-pastu",
"notification_email_test_email_failed": "",
"notification_email_test_email_sent": "",
"notification_email_username_description": "",
"notification_enable_email_notifications": "",
"notification_settings": "Paziņojumu iestatījumi", "notification_settings": "Paziņojumu iestatījumi",
"notification_settings_description": "Paziņojumu iestatījumu, tostarp e-pasta, pārvaldība", "notification_settings_description": "Paziņojumu iestatījumu, tostarp e-pasta, pārvaldība",
"oauth_auto_launch": "",
"oauth_auto_launch_description": "",
"oauth_auto_register": "",
"oauth_auto_register_description": "",
"oauth_button_text": "Pogas teksts", "oauth_button_text": "Pogas teksts",
"oauth_enable_description": "Pieslēgties ar OAuth", "oauth_enable_description": "Pieslēgties ar OAuth",
"oauth_mobile_redirect_uri": "",
"oauth_mobile_redirect_uri_override": "",
"oauth_mobile_redirect_uri_override_description": "",
"oauth_settings": "OAuth", "oauth_settings": "OAuth",
"oauth_settings_description": "OAuth pieteikšanās iestatījumu pārvaldība", "oauth_settings_description": "OAuth pieteikšanās iestatījumu pārvaldība",
"oauth_storage_label_claim": "",
"oauth_storage_label_claim_description": "",
"oauth_storage_quota_claim": "",
"oauth_storage_quota_claim_description": "",
"oauth_storage_quota_default": "Noklusējuma krātuves kvota (GiB)", "oauth_storage_quota_default": "Noklusējuma krātuves kvota (GiB)",
"oauth_storage_quota_default_description": "",
"password_enable_description": "Pieteikšanās ar e-pasta adresi un paroli", "password_enable_description": "Pieteikšanās ar e-pasta adresi un paroli",
"password_settings": "Pieteikšanās ar paroli", "password_settings": "Pieteikšanās ar paroli",
"password_settings_description": "Pieteikšanās ar paroli iestatījumu pārvaldība", "password_settings_description": "Pieteikšanās ar paroli iestatījumu pārvaldība",
@ -172,105 +113,42 @@
"require_password_change_on_login": "Pieprasīt lietotājam mainīt paroli pēc pirmās pieteikšanās", "require_password_change_on_login": "Pieprasīt lietotājam mainīt paroli pēc pirmās pieteikšanās",
"scanning_library": "Skenē bibliotēku", "scanning_library": "Skenē bibliotēku",
"search_jobs": "Meklēt uzdevumus…", "search_jobs": "Meklēt uzdevumus…",
"server_external_domain_settings": "",
"server_external_domain_settings_description": "",
"server_settings": "Servera iestatījumi", "server_settings": "Servera iestatījumi",
"server_settings_description": "Servera iestatījumu pārvaldība", "server_settings_description": "Servera iestatījumu pārvaldība",
"server_welcome_message": "Sveiciena ziņa", "server_welcome_message": "Sveiciena ziņa",
"server_welcome_message_description": "Ziņojums, kas tiek parādīts pieslēgšanās lapā.", "server_welcome_message_description": "Ziņojums, kas tiek parādīts pieslēgšanās lapā.",
"sidecar_job_description": "",
"slideshow_duration_description": "",
"smart_search_job_description": "",
"storage_template_date_time_sample": "Laika paraugs {date}", "storage_template_date_time_sample": "Laika paraugs {date}",
"storage_template_enable_description": "",
"storage_template_hash_verification_enabled": "",
"storage_template_hash_verification_enabled_description": "",
"storage_template_migration": "Krātuves veidņu migrācija", "storage_template_migration": "Krātuves veidņu migrācija",
"storage_template_migration_job": "Krātuves veidņu migrācijas uzdevums", "storage_template_migration_job": "Krātuves veidņu migrācijas uzdevums",
"storage_template_path_length": "Aptuvenais ceļa garuma ierobežojums: <b>{length, number}</b>/{limit, number}", "storage_template_path_length": "Aptuvenais ceļa garuma ierobežojums: <b>{length, number}</b>/{limit, number}",
"storage_template_settings": "Krātuves veidne", "storage_template_settings": "Krātuves veidne",
"storage_template_settings_description": "",
"system_settings": "Sistēmas iestatījumi", "system_settings": "Sistēmas iestatījumi",
"template_email_preview": "Priekšskatījums", "template_email_preview": "Priekšskatījums",
"template_email_settings_description": "Pielāgotu e-pasta paziņojumu veidņu pārvaldība", "template_email_settings_description": "Pielāgotu e-pasta paziņojumu veidņu pārvaldība",
"template_settings_description": "Pielāgotu paziņojumu veidņu pārvaldība", "template_settings_description": "Pielāgotu paziņojumu veidņu pārvaldība",
"theme_custom_css_settings": "Pielāgots CSS", "theme_custom_css_settings": "Pielāgots CSS",
"theme_custom_css_settings_description": "Cascading Style Sheets ļauj pielāgot Immich izskatu.", "theme_custom_css_settings_description": "Cascading Style Sheets ļauj pielāgot Immich izskatu.",
"theme_settings": "",
"theme_settings_description": "Immich tīmekļa saskarnes pielāgojumu pārvaldība", "theme_settings_description": "Immich tīmekļa saskarnes pielāgojumu pārvaldība",
"thumbnail_generation_job": "Sīktēlu ģenerēšana", "thumbnail_generation_job": "Sīktēlu ģenerēšana",
"thumbnail_generation_job_description": "",
"transcoding_acceleration_api": "Paātrināšanas API", "transcoding_acceleration_api": "Paātrināšanas API",
"transcoding_acceleration_api_description": "",
"transcoding_acceleration_nvenc": "NVENC (nepieciešams NVIDIA GPU)", "transcoding_acceleration_nvenc": "NVENC (nepieciešams NVIDIA GPU)",
"transcoding_acceleration_qsv": "Quick Sync (nepieciešams 7. paaudzes vai jaunāks Intel procesors)", "transcoding_acceleration_qsv": "Quick Sync (nepieciešams 7. paaudzes vai jaunāks Intel procesors)",
"transcoding_acceleration_rkmpp": "RKMPP (tikai Rockchip SOC)", "transcoding_acceleration_rkmpp": "RKMPP (tikai Rockchip SOC)",
"transcoding_acceleration_vaapi": "VAAPI", "transcoding_acceleration_vaapi": "VAAPI",
"transcoding_accepted_audio_codecs": "",
"transcoding_accepted_audio_codecs_description": "",
"transcoding_accepted_video_codecs": "",
"transcoding_accepted_video_codecs_description": "",
"transcoding_advanced_options_description": "Lielākajai daļai lietotāju nevajadzētu mainīt šīs opcijas", "transcoding_advanced_options_description": "Lielākajai daļai lietotāju nevajadzētu mainīt šīs opcijas",
"transcoding_audio_codec": "Audio kodeks", "transcoding_audio_codec": "Audio kodeks",
"transcoding_audio_codec_description": "",
"transcoding_bitrate_description": "",
"transcoding_codecs_learn_more": "Lai uzzinātu vairāk par šeit lietoto terminoloģiju, skatiet FFmpeg dokumentāciju par <h264-link>H.264 kodeku</h264-link>, <hevc-link>HEVC kodeku</hevc-link> un <vp9-link>VP9 kodeku</vp9-link>.", "transcoding_codecs_learn_more": "Lai uzzinātu vairāk par šeit lietoto terminoloģiju, skatiet FFmpeg dokumentāciju par <h264-link>H.264 kodeku</h264-link>, <hevc-link>HEVC kodeku</hevc-link> un <vp9-link>VP9 kodeku</vp9-link>.",
"transcoding_constant_quality_mode": "",
"transcoding_constant_quality_mode_description": "",
"transcoding_constant_rate_factor": "",
"transcoding_constant_rate_factor_description": "",
"transcoding_disabled_description": "",
"transcoding_hardware_acceleration": "",
"transcoding_hardware_acceleration_description": "",
"transcoding_hardware_decoding": "",
"transcoding_hardware_decoding_setting_description": "",
"transcoding_hevc_codec": "",
"transcoding_max_b_frames": "",
"transcoding_max_b_frames_description": "",
"transcoding_max_bitrate": "",
"transcoding_max_bitrate_description": "",
"transcoding_max_keyframe_interval": "",
"transcoding_max_keyframe_interval_description": "",
"transcoding_optimal_description": "",
"transcoding_preferred_hardware_device": "",
"transcoding_preferred_hardware_device_description": "",
"transcoding_preset_preset": "",
"transcoding_preset_preset_description": "",
"transcoding_reference_frames": "",
"transcoding_reference_frames_description": "",
"transcoding_required_description": "",
"transcoding_settings": "",
"transcoding_settings_description": "",
"transcoding_target_resolution": "",
"transcoding_target_resolution_description": "",
"transcoding_temporal_aq": "",
"transcoding_temporal_aq_description": "",
"transcoding_threads": "Pavedieni", "transcoding_threads": "Pavedieni",
"transcoding_threads_description": "",
"transcoding_tone_mapping": "",
"transcoding_tone_mapping_description": "",
"transcoding_transcode_policy": "",
"transcoding_two_pass_encoding": "",
"transcoding_two_pass_encoding_setting_description": "",
"transcoding_video_codec": "Video kodeks", "transcoding_video_codec": "Video kodeks",
"transcoding_video_codec_description": "",
"trash_enabled_description": "",
"trash_number_of_days": "Dienu skaits", "trash_number_of_days": "Dienu skaits",
"trash_number_of_days_description": "",
"trash_settings": "",
"trash_settings_description": "Atkritnes iestatījumu pārvaldība", "trash_settings_description": "Atkritnes iestatījumu pārvaldība",
"user_delete_delay_settings": "",
"user_delete_delay_settings_description": "",
"user_management": "Lietotāju pārvaldība", "user_management": "Lietotāju pārvaldība",
"user_password_has_been_reset": "Lietotāja parole ir atiestatīta:", "user_password_has_been_reset": "Lietotāja parole ir atiestatīta:",
"user_restore_description": "<b>{user}</b> konts tiks atjaunots.", "user_restore_description": "<b>{user}</b> konts tiks atjaunots.",
"user_settings": "",
"user_settings_description": "Lietotāju iestatījumu pārvaldība", "user_settings_description": "Lietotāju iestatījumu pārvaldība",
"version_check_enabled_description": "Ieslēgt versijas pārbaudi", "version_check_enabled_description": "Ieslēgt versijas pārbaudi",
"version_check_implications": "Versiju pārbaudes funkcija ir atkarīga no periodiskas saziņas ar github.com", "version_check_implications": "Versiju pārbaudes funkcija ir atkarīga no periodiskas saziņas ar github.com",
"version_check_settings": "Versijas pārbaude", "version_check_settings": "Versijas pārbaude"
"version_check_settings_description": "",
"video_conversion_job_description": ""
}, },
"admin_email": "Administratora e-pasts", "admin_email": "Administratora e-pasts",
"admin_password": "Administratora parole", "admin_password": "Administratora parole",
@ -290,21 +168,18 @@
"age_year_months": "Vecums 1 gads, {months, plural, zero {# mēnešu} one {# mēnesis} other {# mēneši}}", "age_year_months": "Vecums 1 gads, {months, plural, zero {# mēnešu} one {# mēnesis} other {# mēneši}}",
"age_years": "{years, plural, zero {# gadu} one {# gads} other {# gadi}}", "age_years": "{years, plural, zero {# gadu} one {# gads} other {# gadi}}",
"album_added": "Albums pievienots", "album_added": "Albums pievienots",
"album_added_notification_setting_description": "",
"album_cover_updated": "Albuma attēls atjaunināts", "album_cover_updated": "Albuma attēls atjaunināts",
"album_info_card_backup_album_excluded": "NEIEKĻAUTS", "album_info_card_backup_album_excluded": "NEIEKĻAUTS",
"album_info_card_backup_album_included": "IEKĻAUTS", "album_info_card_backup_album_included": "IEKĻAUTS",
"album_info_updated": "Albuma informācija atjaunināta", "album_info_updated": "Albuma informācija atjaunināta",
"album_leave": "Pamest albumu?", "album_leave": "Pamest albumu?",
"album_name": "Albuma nosaukums", "album_name": "Albuma nosaukums",
"album_options": "",
"album_remove_user": "Noņemt lietotāju?", "album_remove_user": "Noņemt lietotāju?",
"album_thumbnail_card_item": "1 vienums", "album_thumbnail_card_item": "1 vienums",
"album_thumbnail_card_items": "{count} vienumi", "album_thumbnail_card_items": "{count} vienumi",
"album_thumbnail_card_shared": " · Kopīgots", "album_thumbnail_card_shared": " · Kopīgots",
"album_thumbnail_shared_by": "Kopīgoja {user}", "album_thumbnail_shared_by": "Kopīgoja {user}",
"album_updated": "Albums atjaunināts", "album_updated": "Albums atjaunināts",
"album_updated_setting_description": "",
"album_user_left": "Pameta {album}", "album_user_left": "Pameta {album}",
"album_user_removed": "Noņēma {user}", "album_user_removed": "Noņēma {user}",
"album_viewer_appbar_delete_confirm": "Vai tiešām vēlaties dzēst šo albumu no sava konta?", "album_viewer_appbar_delete_confirm": "Vai tiešām vēlaties dzēst šo albumu no sava konta?",
@ -331,10 +206,7 @@
"app_bar_signout_dialog_content": "Vai tiešām vēlaties izrakstīties?", "app_bar_signout_dialog_content": "Vai tiešām vēlaties izrakstīties?",
"app_bar_signout_dialog_ok": "Jā", "app_bar_signout_dialog_ok": "Jā",
"app_bar_signout_dialog_title": "Izrakstīties", "app_bar_signout_dialog_title": "Izrakstīties",
"app_settings": "",
"appears_in": "",
"archive": "Arhīvs", "archive": "Arhīvs",
"archive_or_unarchive_photo": "",
"archive_page_no_archived_assets": "Nav atrasts neviens arhivēts aktīvs", "archive_page_no_archived_assets": "Nav atrasts neviens arhivēts aktīvs",
"archive_page_title": "Arhīvs ({count})", "archive_page_title": "Arhīvs ({count})",
"archive_size": "Arhīva izmērs", "archive_size": "Arhīva izmērs",
@ -351,7 +223,6 @@
"asset_list_layout_sub_title": "Izvietojums", "asset_list_layout_sub_title": "Izvietojums",
"asset_list_settings_subtitle": "Fotorežģa izkārtojuma iestatījumi", "asset_list_settings_subtitle": "Fotorežģa izkārtojuma iestatījumi",
"asset_list_settings_title": "Fotorežģis", "asset_list_settings_title": "Fotorežģis",
"asset_offline": "",
"asset_restored_successfully": "Asset restored successfully", "asset_restored_successfully": "Asset restored successfully",
"asset_uploading": "Augšupielādē…", "asset_uploading": "Augšupielādē…",
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings", "asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
@ -431,10 +302,8 @@
"backup_manual_title": "Augšupielādes statuss", "backup_manual_title": "Augšupielādes statuss",
"backup_options_page_title": "Dublēšanas iestatījumi", "backup_options_page_title": "Dublēšanas iestatījumi",
"backup_setting_subtitle": "Manage background and foreground upload settings", "backup_setting_subtitle": "Manage background and foreground upload settings",
"backward": "",
"birthdate_saved": "Dzimšanas datums veiksmīgi saglabāts", "birthdate_saved": "Dzimšanas datums veiksmīgi saglabāts",
"birthdate_set_description": "Dzimšanas datums tiek izmantots, lai aprēķinātu šīs personas vecumu fotogrāfijas uzņemšanas brīdī.", "birthdate_set_description": "Dzimšanas datums tiek izmantots, lai aprēķinātu šīs personas vecumu fotogrāfijas uzņemšanas brīdī.",
"blurred_background": "",
"bugs_and_feature_requests": "Kļūdas un funkciju pieprasījumi", "bugs_and_feature_requests": "Kļūdas un funkciju pieprasījumi",
"build": "Būvējums", "build": "Būvējums",
"build_image": "Būvējuma attēls", "build_image": "Būvējuma attēls",
@ -456,14 +325,9 @@
"cache_settings_tile_subtitle": "Kontrolēt lokālās krātuves uzvedību", "cache_settings_tile_subtitle": "Kontrolēt lokālās krātuves uzvedību",
"cache_settings_tile_title": "Lokālā Krātuve", "cache_settings_tile_title": "Lokālā Krātuve",
"cache_settings_title": "Kešdarbes iestatījumi", "cache_settings_title": "Kešdarbes iestatījumi",
"camera": "",
"camera_brand": "",
"camera_model": "",
"cancel": "Atcelt", "cancel": "Atcelt",
"cancel_search": "",
"canceled": "Canceled", "canceled": "Canceled",
"cannot_merge_people": "Nevar apvienot cilvēkus", "cannot_merge_people": "Nevar apvienot cilvēkus",
"cannot_update_the_description": "",
"change_date": "Mainīt datumu", "change_date": "Mainīt datumu",
"change_display_order": "Change display order", "change_display_order": "Change display order",
"change_expiration_time": "Izmainīt derīguma termiņu", "change_expiration_time": "Izmainīt derīguma termiņu",
@ -477,17 +341,13 @@
"change_password_form_password_mismatch": "Paroles nesakrīt", "change_password_form_password_mismatch": "Paroles nesakrīt",
"change_password_form_reenter_new_password": "Atkārtoti ievadīt jaunu paroli", "change_password_form_reenter_new_password": "Atkārtoti ievadīt jaunu paroli",
"change_pin_code": "Nomainīt PIN kodu", "change_pin_code": "Nomainīt PIN kodu",
"change_your_password": "",
"changed_visibility_successfully": "",
"check_corrupt_asset_backup": "Check for corrupt asset backups", "check_corrupt_asset_backup": "Check for corrupt asset backups",
"check_corrupt_asset_backup_button": "Perform check", "check_corrupt_asset_backup_button": "Perform check",
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.", "check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
"check_logs": "",
"choose_matching_people_to_merge": "Izvēlies atbilstošus cilvēkus apvienošanai", "choose_matching_people_to_merge": "Izvēlies atbilstošus cilvēkus apvienošanai",
"city": "Pilsēta", "city": "Pilsēta",
"clear": "Notīrīt", "clear": "Notīrīt",
"clear_all": "Notīrīt visu", "clear_all": "Notīrīt visu",
"clear_message": "",
"clear_value": "Notīrīt vērtību", "clear_value": "Notīrīt vērtību",
"client_cert_dialog_msg_confirm": "OK", "client_cert_dialog_msg_confirm": "OK",
"client_cert_enter_password": "Enter Password", "client_cert_enter_password": "Enter Password",
@ -504,16 +364,12 @@
"color": "Krāsa", "color": "Krāsa",
"color_theme": "Krāsu tēma", "color_theme": "Krāsu tēma",
"comment_deleted": "Komentārs dzēsts", "comment_deleted": "Komentārs dzēsts",
"comment_options": "",
"comments_are_disabled": "",
"common_create_new_album": "Izveidot jaunu albumu", "common_create_new_album": "Izveidot jaunu albumu",
"common_server_error": "Lūdzu, pārbaudiet tīkla savienojumu, pārliecinieties, vai serveris ir sasniedzams un aplikācijas/servera versijas ir saderīgas.", "common_server_error": "Lūdzu, pārbaudiet tīkla savienojumu, pārliecinieties, vai serveris ir sasniedzams un aplikācijas/servera versijas ir saderīgas.",
"completed": "Completed", "completed": "Completed",
"confirm": "Apstiprināt", "confirm": "Apstiprināt",
"confirm_admin_password": "",
"confirm_new_pin_code": "Apstiprināt jauno PIN kodu", "confirm_new_pin_code": "Apstiprināt jauno PIN kodu",
"confirm_password": "Apstiprināt paroli", "confirm_password": "Apstiprināt paroli",
"contain": "",
"context": "Konteksts", "context": "Konteksts",
"continue": "Turpināt", "continue": "Turpināt",
"control_bottom_app_bar_album_info_shared": "{count} vienumi · Koplietoti", "control_bottom_app_bar_album_info_shared": "{count} vienumi · Koplietoti",
@ -525,17 +381,8 @@
"control_bottom_app_bar_share_link": "Share Link", "control_bottom_app_bar_share_link": "Share Link",
"control_bottom_app_bar_share_to": "Kopīgot Uz", "control_bottom_app_bar_share_to": "Kopīgot Uz",
"control_bottom_app_bar_trash_from_immich": "Pārvietot uz Atkritni", "control_bottom_app_bar_trash_from_immich": "Pārvietot uz Atkritni",
"copied_image_to_clipboard": "",
"copy_error": "Kopēšanas kļūda", "copy_error": "Kopēšanas kļūda",
"copy_file_path": "",
"copy_image": "",
"copy_link": "",
"copy_link_to_clipboard": "",
"copy_password": "",
"copy_to_clipboard": "",
"country": "Valsts", "country": "Valsts",
"cover": "",
"covers": "",
"create": "Izveidot", "create": "Izveidot",
"create_album": "Izveidot albumu", "create_album": "Izveidot albumu",
"create_album_page_untitled": "Bez nosaukuma", "create_album_page_untitled": "Bez nosaukuma",
@ -548,17 +395,12 @@
"create_shared_album_page_share_add_assets": "PIEVIENOT AKTĪVUS", "create_shared_album_page_share_add_assets": "PIEVIENOT AKTĪVUS",
"create_shared_album_page_share_select_photos": "Fotoattēlu Izvēle", "create_shared_album_page_share_select_photos": "Fotoattēlu Izvēle",
"create_user": "Izveidot lietotāju", "create_user": "Izveidot lietotāju",
"created": "",
"crop": "Crop", "crop": "Crop",
"curated_object_page_title": "Lietas", "curated_object_page_title": "Lietas",
"current_device": "",
"current_pin_code": "Esošais PIN kods", "current_pin_code": "Esošais PIN kods",
"current_server_address": "Current server address", "current_server_address": "Current server address",
"custom_locale": "",
"custom_locale_description": "",
"daily_title_text_date": "E, MMM dd", "daily_title_text_date": "E, MMM dd",
"daily_title_text_date_year": "E, MMM dd, gggg", "daily_title_text_date_year": "E, MMM dd, gggg",
"dark": "",
"date_after": "Datums pēc", "date_after": "Datums pēc",
"date_and_time": "Datums un Laiks", "date_and_time": "Datums un Laiks",
"date_before": "Datums pirms", "date_before": "Datums pirms",
@ -567,8 +409,6 @@
"date_range": "Datumu diapazons", "date_range": "Datumu diapazons",
"day": "Diena", "day": "Diena",
"deduplication_criteria_1": "Attēla izmērs baitos", "deduplication_criteria_1": "Attēla izmērs baitos",
"default_locale": "",
"default_locale_description": "",
"delete": "Dzēst", "delete": "Dzēst",
"delete_album": "Dzēst albumu", "delete_album": "Dzēst albumu",
"delete_dialog_alert": "Šie vienumi tiks neatgriezeniski dzēsti no Immich un jūsu ierīces", "delete_dialog_alert": "Šie vienumi tiks neatgriezeniski dzēsti no Immich un jūsu ierīces",
@ -593,15 +433,8 @@
"description_input_submit_error": "Atjauninot aprakstu, radās kļūda; papildinformāciju skatiet žurnālā", "description_input_submit_error": "Atjauninot aprakstu, radās kļūda; papildinformāciju skatiet žurnālā",
"details": "INFORMĀCIJA", "details": "INFORMĀCIJA",
"direction": "Virziens", "direction": "Virziens",
"disallow_edits": "",
"discord": "Discord", "discord": "Discord",
"discover": "",
"dismiss_all_errors": "",
"dismiss_error": "",
"display_options": "",
"display_order": "Attēlošanas secība", "display_order": "Attēlošanas secība",
"display_original_photos": "",
"display_original_photos_setting_description": "",
"documentation": "Dokumentācija", "documentation": "Dokumentācija",
"done": "Gatavs", "done": "Gatavs",
"download": "Lejupielādēt", "download": "Lejupielādēt",
@ -624,13 +457,10 @@
"downloading_asset_filename": "Lejupielādē failu {filename}", "downloading_asset_filename": "Lejupielādē failu {filename}",
"downloading_media": "Downloading media", "downloading_media": "Downloading media",
"duplicates": "Dublikāti", "duplicates": "Dublikāti",
"duration": "",
"edit": "Labot", "edit": "Labot",
"edit_album": "Labot albumu", "edit_album": "Labot albumu",
"edit_avatar": "",
"edit_date": "Labot datumu", "edit_date": "Labot datumu",
"edit_date_and_time": "Labot datumu un laiku", "edit_date_and_time": "Labot datumu un laiku",
"edit_exclusion_pattern": "",
"edit_faces": "Labot sejas", "edit_faces": "Labot sejas",
"edit_import_path": "Labot importa ceļu", "edit_import_path": "Labot importa ceļu",
"edit_import_paths": "Labot importa ceļus", "edit_import_paths": "Labot importa ceļus",
@ -650,66 +480,18 @@
"email_notifications": "E-pasta paziņojumi", "email_notifications": "E-pasta paziņojumi",
"empty_folder": "This folder is empty", "empty_folder": "This folder is empty",
"empty_trash": "Iztukšot atkritni", "empty_trash": "Iztukšot atkritni",
"enable": "",
"enabled": "",
"end_date": "",
"enqueued": "Enqueued", "enqueued": "Enqueued",
"enter_wifi_name": "Enter WiFi name", "enter_wifi_name": "Enter WiFi name",
"error": "",
"error_change_sort_album": "Failed to change album sort order", "error_change_sort_album": "Failed to change album sort order",
"error_loading_image": "",
"error_saving_image": "Kļūda: {error}", "error_saving_image": "Kļūda: {error}",
"errors": { "errors": {
"cant_get_faces": "Nevar iegūt sejas", "cant_get_faces": "Nevar iegūt sejas",
"cant_search_people": "Neizdevās veikt peronu meklēšanu", "cant_search_people": "Neizdevās veikt peronu meklēšanu",
"failed_to_create_album": "Neizdevās izveidot albumu", "failed_to_create_album": "Neizdevās izveidot albumu",
"unable_to_add_album_users": "",
"unable_to_add_comment": "",
"unable_to_add_partners": "",
"unable_to_change_album_user_role": "",
"unable_to_change_date": "",
"unable_to_change_location": "",
"unable_to_create_admin_account": "",
"unable_to_create_library": "",
"unable_to_create_user": "Neizdevās izveidot lietotāju", "unable_to_create_user": "Neizdevās izveidot lietotāju",
"unable_to_delete_album": "",
"unable_to_delete_asset": "",
"unable_to_delete_user": "Neizdevās dzēst lietotāju", "unable_to_delete_user": "Neizdevās dzēst lietotāju",
"unable_to_empty_trash": "",
"unable_to_enter_fullscreen": "",
"unable_to_exit_fullscreen": "",
"unable_to_hide_person": "Neizdevās paslēpt personu", "unable_to_hide_person": "Neizdevās paslēpt personu",
"unable_to_load_album": "", "unable_to_save_date_of_birth": "Neizdevās saglabāt dzimšanas datumu"
"unable_to_load_asset_activity": "",
"unable_to_load_items": "",
"unable_to_load_liked_status": "",
"unable_to_play_video": "",
"unable_to_refresh_user": "",
"unable_to_remove_album_users": "",
"unable_to_remove_library": "",
"unable_to_remove_partner": "",
"unable_to_remove_reaction": "",
"unable_to_repair_items": "",
"unable_to_reset_password": "",
"unable_to_resolve_duplicate": "",
"unable_to_restore_assets": "",
"unable_to_restore_trash": "",
"unable_to_restore_user": "",
"unable_to_save_album": "",
"unable_to_save_date_of_birth": "Neizdevās saglabāt dzimšanas datumu",
"unable_to_save_name": "",
"unable_to_save_profile": "",
"unable_to_save_settings": "",
"unable_to_scan_libraries": "",
"unable_to_scan_library": "",
"unable_to_set_profile_picture": "",
"unable_to_submit_job": "",
"unable_to_trash_asset": "",
"unable_to_unlink_account": "",
"unable_to_update_library": "",
"unable_to_update_location": "",
"unable_to_update_settings": "",
"unable_to_update_user": ""
}, },
"exif_bottom_sheet_description": "Pievienot Aprakstu...", "exif_bottom_sheet_description": "Pievienot Aprakstu...",
"exif_bottom_sheet_details": "INFORMĀCIJA", "exif_bottom_sheet_details": "INFORMĀCIJA",
@ -721,7 +503,6 @@
"exif_bottom_sheet_person_age_year_months": "Vecums 1 gads, {months} mēneši", "exif_bottom_sheet_person_age_year_months": "Vecums 1 gads, {months} mēneši",
"exif_bottom_sheet_person_age_years": "Vecums {years}", "exif_bottom_sheet_person_age_years": "Vecums {years}",
"exit_slideshow": "Iziet no slīdrādes", "exit_slideshow": "Iziet no slīdrādes",
"expand_all": "",
"experimental_settings_new_asset_list_subtitle": "Izstrādes posmā", "experimental_settings_new_asset_list_subtitle": "Izstrādes posmā",
"experimental_settings_new_asset_list_title": "Iespējot eksperimentālo fotorežģi", "experimental_settings_new_asset_list_title": "Iespējot eksperimentālo fotorežģi",
"experimental_settings_subtitle": "Izmanto uzņemoties risku!", "experimental_settings_subtitle": "Izmanto uzņemoties risku!",
@ -729,38 +510,21 @@
"expire_after": "Derīguma termiņš beidzas pēc", "expire_after": "Derīguma termiņš beidzas pēc",
"expired": "Derīguma termiņš beidzās", "expired": "Derīguma termiņš beidzās",
"explore": "Izpētīt", "explore": "Izpētīt",
"extension": "",
"external_libraries": "",
"external_network": "External network", "external_network": "External network",
"external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom", "external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
"failed": "Failed", "failed": "Failed",
"failed_to_load_assets": "Failed to load assets", "failed_to_load_assets": "Failed to load assets",
"failed_to_load_folder": "Failed to load folder", "failed_to_load_folder": "Failed to load folder",
"favorite": "Izlase", "favorite": "Izlase",
"favorite_or_unfavorite_photo": "",
"favorites": "Izlase", "favorites": "Izlase",
"favorites_page_no_favorites": "Nav atrasti iecienītākie aktīvi", "favorites_page_no_favorites": "Nav atrasti iecienītākie aktīvi",
"feature_photo_updated": "",
"features_setting_description": "Lietotnes funkciju pārvaldība", "features_setting_description": "Lietotnes funkciju pārvaldība",
"file_name": "",
"file_name_or_extension": "",
"filename": "",
"filetype": "",
"filter": "Filter", "filter": "Filter",
"filter_people": "",
"fix_incorrect_match": "",
"folder": "Folder", "folder": "Folder",
"folder_not_found": "Folder not found", "folder_not_found": "Folder not found",
"folders": "Mapes", "folders": "Mapes",
"forward": "",
"general": "",
"get_help": "",
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network", "get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
"getting_started": "",
"go_back": "",
"go_to_search": "",
"grant_permission": "Grant permission", "grant_permission": "Grant permission",
"group_albums_by": "",
"haptic_feedback_switch": "Iestatīt haptisku reakciju", "haptic_feedback_switch": "Iestatīt haptisku reakciju",
"haptic_feedback_title": "Haptiska Reakcija", "haptic_feedback_title": "Haptiska Reakcija",
"has_quota": "Ir kvota", "has_quota": "Ir kvota",
@ -770,9 +534,7 @@
"header_settings_header_value_input": "Header value", "header_settings_header_value_input": "Header value",
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request", "headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
"headers_settings_tile_title": "Custom proxy headers", "headers_settings_tile_title": "Custom proxy headers",
"hide_gallery": "",
"hide_named_person": "Paslēpt personu {name}", "hide_named_person": "Paslēpt personu {name}",
"hide_password": "",
"hide_person": "Paslēpt personu", "hide_person": "Paslēpt personu",
"home_page_add_to_album_conflicts": "Pievienoja {added} aktīvus albumam {album}. {failed} aktīvi jau ir albumā.", "home_page_add_to_album_conflicts": "Pievienoja {added} aktīvus albumam {album}. {failed} aktīvi jau ir albumā.",
"home_page_add_to_album_err_local": "Albumiem vēl nevar pievienot lokālos aktīvus, notiek izlaišana", "home_page_add_to_album_err_local": "Albumiem vēl nevar pievienot lokālos aktīvus, notiek izlaišana",
@ -788,8 +550,6 @@
"home_page_first_time_notice": "Ja šī ir pirmā reize, kad izmantojat aplikāciju, lūdzu, izvēlieties dublējuma albumu(s), lai laika skala varētu aizpildīt fotoattēlus un videoklipus albumā(os).", "home_page_first_time_notice": "Ja šī ir pirmā reize, kad izmantojat aplikāciju, lūdzu, izvēlieties dublējuma albumu(s), lai laika skala varētu aizpildīt fotoattēlus un videoklipus albumā(os).",
"home_page_share_err_local": "Caur saiti nevarēja kopīgot lokālos aktīvus, notiek izlaišana", "home_page_share_err_local": "Caur saiti nevarēja kopīgot lokālos aktīvus, notiek izlaišana",
"home_page_upload_err_limit": "Vienlaikus var augšupielādēt ne vairāk kā 30 aktīvus, notiek izlaišana", "home_page_upload_err_limit": "Vienlaikus var augšupielādēt ne vairāk kā 30 aktīvus, notiek izlaišana",
"host": "",
"hour": "",
"ignore_icloud_photos": "Ignore iCloud photos", "ignore_icloud_photos": "Ignore iCloud photos",
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server", "ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
"image": "Attēls", "image": "Attēls",
@ -804,12 +564,9 @@
"in_archive": "Arhīvā", "in_archive": "Arhīvā",
"include_archived": "Iekļaut arhivētos", "include_archived": "Iekļaut arhivētos",
"include_shared_albums": "Iekļaut koplietotos albumus", "include_shared_albums": "Iekļaut koplietotos albumus",
"include_shared_partner_assets": "",
"individual_share": "",
"info": "Informācija", "info": "Informācija",
"interval": { "interval": {
"day_at_onepm": "Katru dienu 13.00", "day_at_onepm": "Katru dienu 13.00",
"hours": "",
"night_at_midnight": "Katru dienu pusnaktī", "night_at_midnight": "Katru dienu pusnaktī",
"night_at_twoam": "Katru dienu 2.00 naktī" "night_at_twoam": "Katru dienu 2.00 naktī"
}, },
@ -830,20 +587,14 @@
"let_others_respond": "Ļaut citiem atbildēt", "let_others_respond": "Ļaut citiem atbildēt",
"level": "Līmenis", "level": "Līmenis",
"library": "Bibliotēka", "library": "Bibliotēka",
"library_options": "",
"library_page_device_albums": "Albumi ierīcē", "library_page_device_albums": "Albumi ierīcē",
"library_page_new_album": "Jauns albums", "library_page_new_album": "Jauns albums",
"library_page_sort_asset_count": "Daudzums ar aktīviem", "library_page_sort_asset_count": "Daudzums ar aktīviem",
"library_page_sort_created": "Jaunākais izveidotais", "library_page_sort_created": "Jaunākais izveidotais",
"library_page_sort_last_modified": "Pēdējo reizi modificēts", "library_page_sort_last_modified": "Pēdējo reizi modificēts",
"library_page_sort_title": "Albuma virsraksts", "library_page_sort_title": "Albuma virsraksts",
"light": "",
"link_options": "",
"link_to_oauth": "",
"linked_oauth_account": "",
"list": "Saraksts", "list": "Saraksts",
"loading": "Ielādē", "loading": "Ielādē",
"loading_search_results_failed": "",
"local_network": "Local network", "local_network": "Local network",
"local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network", "local_network_sheet_info": "The app will connect to the server through this URL when using the specified Wi-Fi network",
"location_permission": "Location permission", "location_permission": "Location permission",
@ -854,7 +605,6 @@
"location_picker_longitude_error": "Ievadiet korektu ģeogrāfisko garumu", "location_picker_longitude_error": "Ievadiet korektu ģeogrāfisko garumu",
"location_picker_longitude_hint": "Ievadiet savu ģeogrāfisko garumu šeit", "location_picker_longitude_hint": "Ievadiet savu ģeogrāfisko garumu šeit",
"log_out": "Izrakstīties", "log_out": "Izrakstīties",
"log_out_all_devices": "",
"login_disabled": "Pieslēgšanās ir atslēgta", "login_disabled": "Pieslēgšanās ir atslēgta",
"login_form_api_exception": "API izņēmums. Lūdzu, pārbaudiet servera URL un mēģiniet vēlreiz.", "login_form_api_exception": "API izņēmums. Lūdzu, pārbaudiet servera URL un mēģiniet vēlreiz.",
"login_form_back_button_text": "Atpakaļ", "login_form_back_button_text": "Atpakaļ",
@ -874,12 +624,10 @@
"login_form_save_login": "Palikt pieteiktam", "login_form_save_login": "Palikt pieteiktam",
"login_form_server_empty": "Ieraksties servera URL.", "login_form_server_empty": "Ieraksties servera URL.",
"login_form_server_error": "Nevarēja izveidot savienojumu ar serveri.", "login_form_server_error": "Nevarēja izveidot savienojumu ar serveri.",
"login_has_been_disabled": "",
"login_password_changed_error": "Atjaunojot paroli radās kļūda", "login_password_changed_error": "Atjaunojot paroli radās kļūda",
"login_password_changed_success": "Parole veiksmīgi atjaunota", "login_password_changed_success": "Parole veiksmīgi atjaunota",
"longitude": "Ģeogrāfiskais garums", "longitude": "Ģeogrāfiskais garums",
"look": "Izskats", "look": "Izskats",
"loop_videos": "",
"loop_videos_description": "Iespējot, lai automātiski videoklips tiktu cikliski palaists detaļu skatītājā.", "loop_videos_description": "Iespējot, lai automātiski videoklips tiktu cikliski palaists detaļu skatītājā.",
"make": "Firma", "make": "Firma",
"manage_shared_links": "Kopīgoto saišu pārvaldība", "manage_shared_links": "Kopīgoto saišu pārvaldība",
@ -919,7 +667,6 @@
"memories": "Atmiņas", "memories": "Atmiņas",
"memories_all_caught_up": "Šobrīd, tas arī viss", "memories_all_caught_up": "Šobrīd, tas arī viss",
"memories_check_back_tomorrow": "Priekš vairāk atmiņām atgriezieties rītdien.", "memories_check_back_tomorrow": "Priekš vairāk atmiņām atgriezieties rītdien.",
"memories_setting_description": "",
"memories_start_over": "Sākt no jauna", "memories_start_over": "Sākt no jauna",
"memories_swipe_to_close": "Pavelciet uz augšu, lai aizvērtu", "memories_swipe_to_close": "Pavelciet uz augšu, lai aizvērtu",
"memories_year_ago": "A year ago", "memories_year_ago": "A year ago",
@ -955,25 +702,19 @@
"new_pin_code": "Jaunais PIN kods", "new_pin_code": "Jaunais PIN kods",
"new_user_created": "Izveidots jauns lietotājs", "new_user_created": "Izveidots jauns lietotājs",
"new_version_available": "PIEEJAMA JAUNA VERSIJA", "new_version_available": "PIEEJAMA JAUNA VERSIJA",
"newest_first": "",
"next": "Nākošais", "next": "Nākošais",
"next_memory": "Nākamā atmiņa", "next_memory": "Nākamā atmiņa",
"no": "Nē", "no": "Nē",
"no_albums_message": "Izveido albumu, lai organizētu savas fotogrāfijas un video", "no_albums_message": "Izveido albumu, lai organizētu savas fotogrāfijas un video",
"no_archived_assets_message": "",
"no_assets_message": "NOKLIKŠĶINIET, LAI AUGŠUPIELĀDĒTU SAVU PIRMO FOTOATTĒLU", "no_assets_message": "NOKLIKŠĶINIET, LAI AUGŠUPIELĀDĒTU SAVU PIRMO FOTOATTĒLU",
"no_assets_to_show": "Nav uzrādāmo aktīvu", "no_assets_to_show": "Nav uzrādāmo aktīvu",
"no_duplicates_found": "Dublikāti netika atrasti.", "no_duplicates_found": "Dublikāti netika atrasti.",
"no_exif_info_available": "Nav pieejama exif informācija", "no_exif_info_available": "Nav pieejama exif informācija",
"no_explore_results_message": "",
"no_favorites_message": "",
"no_libraries_message": "",
"no_name": "Nav nosaukuma", "no_name": "Nav nosaukuma",
"no_notifications": "Nav paziņojumu", "no_notifications": "Nav paziņojumu",
"no_places": "Nav atrašanās vietu", "no_places": "Nav atrašanās vietu",
"no_results": "Nav rezultātu", "no_results": "Nav rezultātu",
"no_results_description": "Izmēģiniet sinonīmu vai vispārīgāku atslēgvārdu", "no_results_description": "Izmēģiniet sinonīmu vai vispārīgāku atslēgvārdu",
"no_shared_albums_message": "",
"not_in_any_album": "Nav nevienā albumā", "not_in_any_album": "Nav nevienā albumā",
"not_selected": "Not selected", "not_selected": "Not selected",
"notes": "Piezīmes", "notes": "Piezīmes",
@ -988,7 +729,6 @@
"official_immich_resources": "Oficiālie Immich resursi", "official_immich_resources": "Oficiālie Immich resursi",
"offline": "Bezsaistē", "offline": "Bezsaistē",
"ok": "Labi", "ok": "Labi",
"oldest_first": "",
"on_this_device": "On this device", "on_this_device": "On this device",
"online": "Tiešsaistē", "online": "Tiešsaistē",
"only_favorites": "Tikai izlase", "only_favorites": "Tikai izlase",
@ -997,7 +737,6 @@
"open_the_search_filters": "Atvērt meklēšanas filtrus", "open_the_search_filters": "Atvērt meklēšanas filtrus",
"options": "Iestatījumi", "options": "Iestatījumi",
"or": "vai", "or": "vai",
"organize_your_library": "",
"original": "oriģināls", "original": "oriģināls",
"other": "Citi", "other": "Citi",
"other_devices": "Citas ierīces", "other_devices": "Citas ierīces",
@ -1013,29 +752,11 @@
"partner_page_select_partner": "Izvēlēties partneri", "partner_page_select_partner": "Izvēlēties partneri",
"partner_page_shared_to_title": "Kopīgots uz", "partner_page_shared_to_title": "Kopīgots uz",
"partner_page_stop_sharing_content": "{partner} vairs nevarēs piekļūt jūsu fotoattēliem.", "partner_page_stop_sharing_content": "{partner} vairs nevarēs piekļūt jūsu fotoattēliem.",
"partner_sharing": "",
"partners": "Partneri", "partners": "Partneri",
"password": "Parole", "password": "Parole",
"password_does_not_match": "Parole nesakrīt", "password_does_not_match": "Parole nesakrīt",
"password_required": "",
"password_reset_success": "",
"past_durations": {
"days": "",
"hours": "",
"years": ""
},
"path": "Ceļš", "path": "Ceļš",
"pattern": "",
"pause": "",
"pause_memories": "",
"paused": "",
"pending": "",
"people": "Cilvēki", "people": "Cilvēki",
"people_sidebar_description": "",
"permanent_deletion_warning": "",
"permanent_deletion_warning_setting_description": "",
"permanently_delete": "",
"permanently_deleted_asset": "",
"permission_onboarding_back": "Atpakaļ", "permission_onboarding_back": "Atpakaļ",
"permission_onboarding_continue_anyway": "Tomēr turpināt", "permission_onboarding_continue_anyway": "Tomēr turpināt",
"permission_onboarding_get_started": "Darba sākšana", "permission_onboarding_get_started": "Darba sākšana",
@ -1047,22 +768,11 @@
"person": "Persona", "person": "Persona",
"photos": "Fotoattēli", "photos": "Fotoattēli",
"photos_from_previous_years": "Fotogrāfijas no iepriekšējiem gadiem", "photos_from_previous_years": "Fotogrāfijas no iepriekšējiem gadiem",
"pick_a_location": "",
"place": "",
"places": "Vietas", "places": "Vietas",
"play": "",
"play_memories": "",
"play_motion_photo": "",
"play_or_pause_video": "",
"port": "Ports", "port": "Ports",
"preferences_settings_subtitle": "Manage the app's preferences", "preferences_settings_subtitle": "Manage the app's preferences",
"preferences_settings_title": "Iestatījumi", "preferences_settings_title": "Iestatījumi",
"preset": "",
"preview": "Priekšskatījums", "preview": "Priekšskatījums",
"previous": "",
"previous_memory": "",
"previous_or_next_photo": "",
"primary": "",
"privacy": "Privātums", "privacy": "Privātums",
"profile": "Profils", "profile": "Profils",
"profile_drawer_app_logs": "Žurnāli", "profile_drawer_app_logs": "Žurnāli",
@ -1072,8 +782,6 @@
"profile_drawer_github": "GitHub", "profile_drawer_github": "GitHub",
"profile_drawer_server_out_of_date_major": "Serveris ir novecojis. Lūdzu atjaunojiet to uz jaunāko lielo versiju", "profile_drawer_server_out_of_date_major": "Serveris ir novecojis. Lūdzu atjaunojiet to uz jaunāko lielo versiju",
"profile_drawer_server_out_of_date_minor": "Serveris ir novecojis. Lūdzu atjaunojiet to uz jaunāko mazo versiju", "profile_drawer_server_out_of_date_minor": "Serveris ir novecojis. Lūdzu atjaunojiet to uz jaunāko mazo versiju",
"profile_picture_set": "",
"public_share": "",
"purchase_button_never_show_again": "Nekad vairs nerādīt", "purchase_button_never_show_again": "Nekad vairs nerādīt",
"purchase_button_reminder": "Atgādināt man pēc 30 dienām", "purchase_button_reminder": "Atgādināt man pēc 30 dienām",
"purchase_button_remove_key": "Noņemt atslēgu", "purchase_button_remove_key": "Noņemt atslēgu",
@ -1091,33 +799,20 @@
"purchase_server_title": "Serveris", "purchase_server_title": "Serveris",
"purchase_settings_server_activated": "Servera produkta atslēgu pārvalda administrators", "purchase_settings_server_activated": "Servera produkta atslēgu pārvalda administrators",
"rating_clear": "Noņemt vērtējumu", "rating_clear": "Noņemt vērtējumu",
"reaction_options": "",
"read_changelog": "Lasīt izmaiņu sarakstu", "read_changelog": "Lasīt izmaiņu sarakstu",
"recent": "",
"recent_searches": "",
"recently_added": "Recently added", "recently_added": "Recently added",
"recently_added_page_title": "Nesen Pievienotais", "recently_added_page_title": "Nesen Pievienotais",
"refresh": "",
"refreshed": "",
"refreshes_every_file": "",
"remove": "Noņemt", "remove": "Noņemt",
"remove_deleted_assets": "",
"remove_from_album": "Noņemt no albuma", "remove_from_album": "Noņemt no albuma",
"remove_from_favorites": "Noņemt no izlases", "remove_from_favorites": "Noņemt no izlases",
"remove_from_shared_link": "",
"remove_user": "Noņemt lietotāju", "remove_user": "Noņemt lietotāju",
"removed_api_key": "Noņēma API atslēgu: {name}", "removed_api_key": "Noņēma API atslēgu: {name}",
"removed_from_archive": "Noņēma no arhīva", "removed_from_archive": "Noņēma no arhīva",
"removed_from_favorites": "Noņēma no izlases", "removed_from_favorites": "Noņēma no izlases",
"rename": "Pārsaukt", "rename": "Pārsaukt",
"repair": "Remonts", "repair": "Remonts",
"repair_no_results_message": "",
"replace_with_upload": "Aizstāt ar augšupielādi", "replace_with_upload": "Aizstāt ar augšupielādi",
"require_password": "",
"require_user_to_change_password_on_first_login": "Pieprasīt lietotājam mainīt paroli pēc pirmās pieteikšanās", "require_user_to_change_password_on_first_login": "Pieprasīt lietotājam mainīt paroli pēc pirmās pieteikšanās",
"reset": "",
"reset_password": "",
"reset_people_visibility": "",
"resolve_duplicates": "Atrisināt dublēšanās gadījumus", "resolve_duplicates": "Atrisināt dublēšanās gadījumus",
"resolved_all_duplicates": "Visi dublikāti ir atrisināti", "resolved_all_duplicates": "Visi dublikāti ir atrisināti",
"restore": "Atjaunot", "restore": "Atjaunot",
@ -1136,16 +831,9 @@
"saved_settings": "Iestatījumi saglabāti", "saved_settings": "Iestatījumi saglabāti",
"say_something": "Teikt kaut ko", "say_something": "Teikt kaut ko",
"scaffold_body_error_occurred": "Radās kļūda", "scaffold_body_error_occurred": "Radās kļūda",
"scan_all_libraries": "",
"scan_settings": "",
"search": "Meklēt", "search": "Meklēt",
"search_albums": "Meklēt albumus", "search_albums": "Meklēt albumus",
"search_by_context": "",
"search_by_filename_example": "piemēram, IMG_1234.JPG vai PNG", "search_by_filename_example": "piemēram, IMG_1234.JPG vai PNG",
"search_camera_make": "",
"search_camera_model": "",
"search_city": "",
"search_country": "",
"search_filter_apply": "Lietot filtru", "search_filter_apply": "Lietot filtru",
"search_filter_camera_title": "Select camera type", "search_filter_camera_title": "Select camera type",
"search_filter_date": "Date", "search_filter_date": "Date",
@ -1159,7 +847,6 @@
"search_filter_media_type": "Media Type", "search_filter_media_type": "Media Type",
"search_filter_media_type_title": "Select media type", "search_filter_media_type_title": "Select media type",
"search_filter_people_title": "Select people", "search_filter_people_title": "Select people",
"search_for_existing_person": "",
"search_no_more_result": "No more results", "search_no_more_result": "No more results",
"search_no_people": "Nav cilvēku", "search_no_people": "Nav cilvēku",
"search_no_people_named": "Nav cilvēku ar vārdu \"{name}\"", "search_no_people_named": "Nav cilvēku ar vārdu \"{name}\"",
@ -1176,40 +863,22 @@
"search_page_your_activity": "Jūsu aktivitāte", "search_page_your_activity": "Jūsu aktivitāte",
"search_page_your_map": "Jūsu Karte", "search_page_your_map": "Jūsu Karte",
"search_people": "Meklēt cilvēkus", "search_people": "Meklēt cilvēkus",
"search_places": "",
"search_result_page_new_search_hint": "Jauns Meklējums", "search_result_page_new_search_hint": "Jauns Meklējums",
"search_state": "",
"search_suggestion_list_smart_search_hint_1": "Viedā meklēšana ir iespējota pēc noklusējuma, lai meklētu metadatus, izmantojiet sintaksi", "search_suggestion_list_smart_search_hint_1": "Viedā meklēšana ir iespējota pēc noklusējuma, lai meklētu metadatus, izmantojiet sintaksi",
"search_suggestion_list_smart_search_hint_2": "m:jūsu-meklēšanas-frāze", "search_suggestion_list_smart_search_hint_2": "m:jūsu-meklēšanas-frāze",
"search_timezone": "",
"search_type": "",
"search_your_photos": "Meklēt Jūsu fotoattēlus", "search_your_photos": "Meklēt Jūsu fotoattēlus",
"searching_locales": "",
"second": "Sekunde", "second": "Sekunde",
"select_album_cover": "Izvēlieties albuma vāciņu", "select_album_cover": "Izvēlieties albuma vāciņu",
"select_all": "",
"select_all_duplicates": "Atlasīt visus dublikātus", "select_all_duplicates": "Atlasīt visus dublikātus",
"select_avatar_color": "",
"select_face": "",
"select_featured_photo": "",
"select_library_owner": "",
"select_new_face": "",
"select_photos": "Fotoattēlu Izvēle", "select_photos": "Fotoattēlu Izvēle",
"select_user_for_sharing_page_err_album": "Neizdevās izveidot albumu", "select_user_for_sharing_page_err_album": "Neizdevās izveidot albumu",
"selected": "",
"send_message": "",
"server_endpoint": "Server Endpoint", "server_endpoint": "Server Endpoint",
"server_info_box_app_version": "Aplikācijas Versija", "server_info_box_app_version": "Aplikācijas Versija",
"server_info_box_server_url": "Servera URL", "server_info_box_server_url": "Servera URL",
"server_online": "Serveris tiešsaistē", "server_online": "Serveris tiešsaistē",
"server_stats": "Servera statistika", "server_stats": "Servera statistika",
"server_version": "Servera versija", "server_version": "Servera versija",
"set": "",
"set_as_album_cover": "",
"set_as_profile_picture": "",
"set_date_of_birth": "Iestatīt dzimšanas datumu", "set_date_of_birth": "Iestatīt dzimšanas datumu",
"set_profile_picture": "",
"set_slideshow_to_fullscreen": "",
"setting_image_viewer_help": "Detaļu skatītājs vispirms ielādē mazo sīktēlu, pēc tam ielādē vidēja lieluma priekšskatījumu (ja iespējots), visbeidzot ielādē oriģinālu (ja iespējots).", "setting_image_viewer_help": "Detaļu skatītājs vispirms ielādē mazo sīktēlu, pēc tam ielādē vidēja lieluma priekšskatījumu (ja iespējots), visbeidzot ielādē oriģinālu (ja iespējots).",
"setting_image_viewer_original_subtitle": "Iespējot sākotnējā pilnas izšķirtspējas attēla (liels!) ielādi. Atspējot, lai samazinātu datu lietojumu (gan tīklā, gan ierīces kešatmiņā).", "setting_image_viewer_original_subtitle": "Iespējot sākotnējā pilnas izšķirtspējas attēla (liels!) ielādi. Atspējot, lai samazinātu datu lietojumu (gan tīklā, gan ierīces kešatmiņā).",
"setting_image_viewer_original_title": "Ielādēt oriģinālo attēlu", "setting_image_viewer_original_title": "Ielādēt oriģinālo attēlu",
@ -1235,7 +904,6 @@
"setting_video_viewer_original_video_title": "Force original video", "setting_video_viewer_original_video_title": "Force original video",
"settings": "Iestatījumi", "settings": "Iestatījumi",
"settings_require_restart": "Lūdzu, restartējiet Immich, lai lietotu šo iestatījumu", "settings_require_restart": "Lūdzu, restartējiet Immich, lai lietotu šo iestatījumu",
"settings_saved": "",
"setup_pin_code": "Uzstādīt PIN kodu", "setup_pin_code": "Uzstādīt PIN kodu",
"share": "Kopīgot", "share": "Kopīgot",
"share_add_photos": "Pievienot fotoattēlus", "share_add_photos": "Pievienot fotoattēlus",
@ -1249,8 +917,6 @@
"shared_album_section_people_action_leave": "Noņemt lietotāju no albuma", "shared_album_section_people_action_leave": "Noņemt lietotāju no albuma",
"shared_album_section_people_action_remove_user": "Noņemt lietotāju no albuma", "shared_album_section_people_action_remove_user": "Noņemt lietotāju no albuma",
"shared_album_section_people_title": "CILVĒKI", "shared_album_section_people_title": "CILVĒKI",
"shared_by": "",
"shared_by_you": "",
"shared_intent_upload_button_progress_text": "Augšupielādēti {current} / {total}", "shared_intent_upload_button_progress_text": "Augšupielādēti {current} / {total}",
"shared_link_app_bar_title": "Kopīgotas Saites", "shared_link_app_bar_title": "Kopīgotas Saites",
"shared_link_clipboard_copied_massage": "Ievietots starpliktuvē", "shared_link_clipboard_copied_massage": "Ievietots starpliktuvē",
@ -1286,7 +952,6 @@
"sharing_page_album": "Kopīgotie albumi", "sharing_page_album": "Kopīgotie albumi",
"sharing_page_description": "Izveidojiet koplietojamus albumus, lai kopīgotu fotoattēlus un videoklipus ar Jūsu tīkla lietotājiem.", "sharing_page_description": "Izveidojiet koplietojamus albumus, lai kopīgotu fotoattēlus un videoklipus ar Jūsu tīkla lietotājiem.",
"sharing_page_empty_list": "TUKŠS SARAKSTS", "sharing_page_empty_list": "TUKŠS SARAKSTS",
"sharing_sidebar_description": "",
"sharing_silver_appbar_create_shared_album": "Izveidot kopīgotu albumu", "sharing_silver_appbar_create_shared_album": "Izveidot kopīgotu albumu",
"sharing_silver_appbar_share_partner": "Dalīties ar partneri", "sharing_silver_appbar_share_partner": "Dalīties ar partneri",
"show_album_options": "Rādīt albuma iespējas", "show_album_options": "Rādīt albuma iespējas",
@ -1296,21 +961,10 @@
"show_file_location": "Rādīt faila atrašanās vietu", "show_file_location": "Rādīt faila atrašanās vietu",
"show_gallery": "Rādīt galeriju", "show_gallery": "Rādīt galeriju",
"show_hidden_people": "Rādīt paslēptos cilvēkus", "show_hidden_people": "Rādīt paslēptos cilvēkus",
"show_in_timeline": "",
"show_in_timeline_setting_description": "",
"show_keyboard_shortcuts": "",
"show_metadata": "Rādīt metadatus", "show_metadata": "Rādīt metadatus",
"show_or_hide_info": "",
"show_password": "",
"show_person_options": "",
"show_progress_bar": "",
"show_search_options": "",
"show_supporter_badge": "Atbalstītāja nozīmīte", "show_supporter_badge": "Atbalstītāja nozīmīte",
"show_supporter_badge_description": "Rādīt atbalstītāja nozīmīti", "show_supporter_badge_description": "Rādīt atbalstītāja nozīmīti",
"shuffle": "",
"sign_up": "",
"size": "Izmērs", "size": "Izmērs",
"skip_to_content": "",
"slideshow": "Slīdrāde", "slideshow": "Slīdrāde",
"slideshow_settings": "Slīdrādes iestatījumi", "slideshow_settings": "Slīdrādes iestatījumi",
"sort_albums_by": "Kārtot albumus pēc...", "sort_albums_by": "Kārtot albumus pēc...",
@ -1322,30 +976,21 @@
"sort_title": "Nosaukums", "sort_title": "Nosaukums",
"source": "Pirmkods", "source": "Pirmkods",
"stack": "Apvienot kaudzē", "stack": "Apvienot kaudzē",
"stack_selected_photos": "",
"stacktrace": "",
"start_date": "",
"state": "Štats", "state": "Štats",
"status": "Statuss", "status": "Statuss",
"stop_motion_photo": "",
"stop_photo_sharing": "Beigt kopīgot jūsu fotogrāfijas?", "stop_photo_sharing": "Beigt kopīgot jūsu fotogrāfijas?",
"storage": "Vieta krātuvē", "storage": "Vieta krātuvē",
"storage_label": "",
"storage_usage": "{used} no {available} izmantoti", "storage_usage": "{used} no {available} izmantoti",
"submit": "Iesniegt", "submit": "Iesniegt",
"suggestions": "Ieteikumi", "suggestions": "Ieteikumi",
"sunrise_on_the_beach": "Saullēkts pludmalē", "sunrise_on_the_beach": "Saullēkts pludmalē",
"support": "Atbalsts", "support": "Atbalsts",
"support_and_feedback": "Atbalsts un atsauksmes", "support_and_feedback": "Atbalsts un atsauksmes",
"swap_merge_direction": "",
"sync": "Sinhronizēt", "sync": "Sinhronizēt",
"sync_albums": "Sync albums", "sync_albums": "Sync albums",
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums", "sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
"sync_upload_album_setting_subtitle": "Create and upload your photos and videos to the selected albums on Immich", "sync_upload_album_setting_subtitle": "Create and upload your photos and videos to the selected albums on Immich",
"template": "",
"theme": "Dizains", "theme": "Dizains",
"theme_selection": "",
"theme_selection_description": "",
"theme_setting_asset_list_storage_indicator_title": "Rādīt krātuves indikatoru uz aktīvu elementiem", "theme_setting_asset_list_storage_indicator_title": "Rādīt krātuves indikatoru uz aktīvu elementiem",
"theme_setting_asset_list_tiles_per_row_title": "Failu skaits rindā ({count})", "theme_setting_asset_list_tiles_per_row_title": "Failu skaits rindā ({count})",
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.", "theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
@ -1360,17 +1005,14 @@
"theme_setting_three_stage_loading_subtitle": "Trīspakāpju ielāde var palielināt ielādēšanas veiktspēju, bet izraisa ievērojami lielāku tīkla noslodzi", "theme_setting_three_stage_loading_subtitle": "Trīspakāpju ielāde var palielināt ielādēšanas veiktspēju, bet izraisa ievērojami lielāku tīkla noslodzi",
"theme_setting_three_stage_loading_title": "Iespējot trīspakāpju ielādi", "theme_setting_three_stage_loading_title": "Iespējot trīspakāpju ielādi",
"they_will_be_merged_together": "Tās tiks apvienotas", "they_will_be_merged_together": "Tās tiks apvienotas",
"time_based_memories": "",
"timezone": "Laika zona", "timezone": "Laika zona",
"to_archive": "Arhivēt", "to_archive": "Arhivēt",
"to_change_password": "Mainīt paroli", "to_change_password": "Mainīt paroli",
"toggle_settings": "Pārslēgt iestatījumus", "toggle_settings": "Pārslēgt iestatījumus",
"toggle_theme": "",
"total_usage": "Kopējais lietojums", "total_usage": "Kopējais lietojums",
"trash": "Atkritne", "trash": "Atkritne",
"trash_all": "Dzēst Visu", "trash_all": "Dzēst Visu",
"trash_emptied": "Emptied trash", "trash_emptied": "Emptied trash",
"trash_no_results_message": "",
"trash_page_delete_all": "Dzēst Visu", "trash_page_delete_all": "Dzēst Visu",
"trash_page_empty_trash_dialog_content": "Vai vēlaties iztukšot savus izmestos aktīvus? Tie tiks neatgriezeniski izņemti no Immich", "trash_page_empty_trash_dialog_content": "Vai vēlaties iztukšot savus izmestos aktīvus? Tie tiks neatgriezeniski izņemti no Immich",
"trash_page_info": "Atkritnes vienumi tiks neatgriezeniski dzēsti pēc {days} dienām", "trash_page_info": "Atkritnes vienumi tiks neatgriezeniski dzēsti pēc {days} dienām",
@ -1378,26 +1020,19 @@
"trash_page_restore_all": "Atjaunot Visu", "trash_page_restore_all": "Atjaunot Visu",
"trash_page_select_assets_btn": "Atlasīt aktīvus", "trash_page_select_assets_btn": "Atlasīt aktīvus",
"trash_page_title": "Atkritne ({count})", "trash_page_title": "Atkritne ({count})",
"type": "",
"unable_to_change_pin_code": "Neizdevās nomainīt PIN kodu", "unable_to_change_pin_code": "Neizdevās nomainīt PIN kodu",
"unable_to_setup_pin_code": "Neizdevās uzstādīt PIN kodu", "unable_to_setup_pin_code": "Neizdevās uzstādīt PIN kodu",
"unarchive": "Atarhivēt", "unarchive": "Atarhivēt",
"unfavorite": "Noņemt no izlases", "unfavorite": "Noņemt no izlases",
"unhide_person": "Atcelt personas slēpšanu", "unhide_person": "Atcelt personas slēpšanu",
"unknown": "",
"unknown_country": "Nezināma Valsts", "unknown_country": "Nezināma Valsts",
"unknown_year": "Nezināms gads", "unknown_year": "Nezināms gads",
"unlimited": "Neierobežots", "unlimited": "Neierobežots",
"unlink_oauth": "",
"unlinked_oauth_account": "",
"unnamed_album": "Albums bez nosaukuma", "unnamed_album": "Albums bez nosaukuma",
"unsaved_change": "Nesaglabāta izmaiņa", "unsaved_change": "Nesaglabāta izmaiņa",
"unselect_all": "",
"unstack": "At-Stekot", "unstack": "At-Stekot",
"up_next": "",
"updated_password": "Parole ir atjaunināta", "updated_password": "Parole ir atjaunināta",
"upload": "Augšupielādēt", "upload": "Augšupielādēt",
"upload_concurrency": "",
"upload_dialog_info": "Vai vēlaties veikt izvēlētā(-o) aktīva(-u) dublējumu uz servera?", "upload_dialog_info": "Vai vēlaties veikt izvēlētā(-o) aktīva(-u) dublējumu uz servera?",
"upload_dialog_title": "Augšupielādēt Aktīvu", "upload_dialog_title": "Augšupielādēt Aktīvu",
"upload_status_duplicates": "Dublikāti", "upload_status_duplicates": "Dublikāti",
@ -1405,7 +1040,6 @@
"upload_status_uploaded": "Augšupielādēts", "upload_status_uploaded": "Augšupielādēts",
"upload_to_immich": "Augšupielādēt Immich ({count})", "upload_to_immich": "Augšupielādēt Immich ({count})",
"uploading": "Uploading", "uploading": "Uploading",
"url": "",
"usage": "Lietojums", "usage": "Lietojums",
"use_current_connection": "use current connection", "use_current_connection": "use current connection",
"user": "Lietotājs", "user": "Lietotājs",
@ -1416,9 +1050,7 @@
"username": "Lietotājvārds", "username": "Lietotājvārds",
"users": "Lietotāji", "users": "Lietotāji",
"utilities": "Rīki", "utilities": "Rīki",
"validate": "",
"validate_endpoint_error": "Please enter a valid URL", "validate_endpoint_error": "Please enter a valid URL",
"variables": "",
"version": "Versija", "version": "Versija",
"version_announcement_message": "Sveiki! Ir pieejama jauna Immich versija. Lūdzu, veltiet laiku, lai izlasītu <link>laidiena piezīmes</link> un pārliecinātos, ka jūsu iestatījumi ir atjaunināti, lai novērstu jebkādu nepareizu konfigurāciju, jo īpaši, ja izmantojat WatchTower vai citu mehānismu, kas automātiski atjaunina jūsu Immich instanci.", "version_announcement_message": "Sveiki! Ir pieejama jauna Immich versija. Lūdzu, veltiet laiku, lai izlasītu <link>laidiena piezīmes</link> un pārliecinātos, ka jūsu iestatījumi ir atjaunināti, lai novērstu jebkādu nepareizu konfigurāciju, jo īpaši, ja izmantojat WatchTower vai citu mehānismu, kas automātiski atjaunina jūsu Immich instanci.",
"version_announcement_overlay_release_notes": "informācija par laidienu", "version_announcement_overlay_release_notes": "informācija par laidienu",
@ -1429,20 +1061,15 @@
"version_history": "Versiju vēsture", "version_history": "Versiju vēsture",
"version_history_item": "{version} uzstādīta {date}", "version_history_item": "{version} uzstādīta {date}",
"video": "Videoklips", "video": "Videoklips",
"video_hover_setting_description": "",
"videos": "Videoklipi", "videos": "Videoklipi",
"view_album": "Skatīt Albumu", "view_album": "Skatīt Albumu",
"view_all": "Apskatīt visu", "view_all": "Apskatīt visu",
"view_all_users": "Skatīt visus lietotājus", "view_all_users": "Skatīt visus lietotājus",
"view_links": "",
"view_next_asset": "",
"view_previous_asset": "",
"viewer_remove_from_stack": "Noņemt no Steka", "viewer_remove_from_stack": "Noņemt no Steka",
"viewer_stack_use_as_main_asset": "Izmantot kā Galveno Aktīvu", "viewer_stack_use_as_main_asset": "Izmantot kā Galveno Aktīvu",
"viewer_unstack": "At-Stekot", "viewer_unstack": "At-Stekot",
"waiting": "Gaida", "waiting": "Gaida",
"week": "Nedēļa", "week": "Nedēļa",
"welcome_to_immich": "",
"wifi_name": "WiFi Name", "wifi_name": "WiFi Name",
"year": "Gads", "year": "Gads",
"years_ago": "Pirms {years, plural, one {# gada} other {# gadiem}}", "years_ago": "Pirms {years, plural, one {# gada} other {# gadiem}}",

File diff suppressed because it is too large Load diff

View file

@ -301,7 +301,6 @@
"transcoding_reference_frames_description": "கொடுக்கப்பட்ட சட்டகத்தை சுருக்கும்போது குறிப்பிட வேண்டிய பிரேம்களின் எண்ணிக்கை. அதிக மதிப்புகள் சுருக்க செயல்திறனை மேம்படுத்துகின்றன, ஆனால் குறியாக்கத்தை மெதுவாக்குகின்றன. 0 இந்த மதிப்பை தானாக அமைக்கிறது.", "transcoding_reference_frames_description": "கொடுக்கப்பட்ட சட்டகத்தை சுருக்கும்போது குறிப்பிட வேண்டிய பிரேம்களின் எண்ணிக்கை. அதிக மதிப்புகள் சுருக்க செயல்திறனை மேம்படுத்துகின்றன, ஆனால் குறியாக்கத்தை மெதுவாக்குகின்றன. 0 இந்த மதிப்பை தானாக அமைக்கிறது.",
"transcoding_required_description": "ஏற்றுக்கொள்ளப்பட்ட வடிவத்தில் இல்லாத வீடியோக்கள் மட்டுமே", "transcoding_required_description": "ஏற்றுக்கொள்ளப்பட்ட வடிவத்தில் இல்லாத வீடியோக்கள் மட்டுமே",
"transcoding_settings": "வீடியோ டிரான்ச்கோடிங் அமைப்புகள்", "transcoding_settings": "வீடியோ டிரான்ச்கோடிங் அமைப்புகள்",
"transcoding_settings_description": "",
"transcoding_target_resolution": "இலக்கு தீர்மானம்", "transcoding_target_resolution": "இலக்கு தீர்மானம்",
"transcoding_target_resolution_description": "அதிக தீர்மானங்கள் அதிக விவரங்களை பாதுகாக்க முடியும், ஆனால் குறியாக்க அதிக நேரம் எடுக்கும், பெரிய கோப்பு அளவுகளைக் கொண்டிருக்கலாம், மேலும் பயன்பாட்டு மறுமொழியைக் குறைக்கலாம்.", "transcoding_target_resolution_description": "அதிக தீர்மானங்கள் அதிக விவரங்களை பாதுகாக்க முடியும், ஆனால் குறியாக்க அதிக நேரம் எடுக்கும், பெரிய கோப்பு அளவுகளைக் கொண்டிருக்கலாம், மேலும் பயன்பாட்டு மறுமொழியைக் குறைக்கலாம்.",
"transcoding_temporal_aq": "தம்போர்ல்", "transcoding_temporal_aq": "தம்போர்ல்",
@ -314,7 +313,6 @@
"transcoding_transcode_policy_description": "ஒரு வீடியோ எப்போது மாற்றப்பட வேண்டும் என்பதற்கான கொள்கை. எச்.டி.ஆர் வீடியோக்கள் எப்போதும் டிரான்ச்கோட் செய்யப்படும் (டிரான்ச்கோடிங் முடக்கப்பட்டிருந்தால் தவிர).", "transcoding_transcode_policy_description": "ஒரு வீடியோ எப்போது மாற்றப்பட வேண்டும் என்பதற்கான கொள்கை. எச்.டி.ஆர் வீடியோக்கள் எப்போதும் டிரான்ச்கோட் செய்யப்படும் (டிரான்ச்கோடிங் முடக்கப்பட்டிருந்தால் தவிர).",
"transcoding_two_pass_encoding": "இரண்டு-பாச் குறியாக்கம்", "transcoding_two_pass_encoding": "இரண்டு-பாச் குறியாக்கம்",
"transcoding_two_pass_encoding_setting_description": "சிறந்த குறியாக்கப்பட்ட வீடியோக்களை உருவாக்க இரண்டு பாச்களில் டிரான்ச்கோட். மேக்ச் பிட்ரேட் இயக்கப்பட்டிருக்கும்போது (H.264 மற்றும் HEVC உடன் வேலை செய்ய இது தேவைப்படுகிறது), இந்த பயன்முறை அதிகபட்ச பிட்ரேட்டை அடிப்படையாகக் கொண்ட பிட்ரேட் வரம்பைப் பயன்படுத்துகிறது மற்றும் CRF ஐ புறக்கணிக்கிறது. VP9 ஐப் பொறுத்தவரை, அதிகபட்ச பிட்ரேட் முடக்கப்பட்டிருந்தால் CRF ஐப் பயன்படுத்தலாம்.", "transcoding_two_pass_encoding_setting_description": "சிறந்த குறியாக்கப்பட்ட வீடியோக்களை உருவாக்க இரண்டு பாச்களில் டிரான்ச்கோட். மேக்ச் பிட்ரேட் இயக்கப்பட்டிருக்கும்போது (H.264 மற்றும் HEVC உடன் வேலை செய்ய இது தேவைப்படுகிறது), இந்த பயன்முறை அதிகபட்ச பிட்ரேட்டை அடிப்படையாகக் கொண்ட பிட்ரேட் வரம்பைப் பயன்படுத்துகிறது மற்றும் CRF ஐ புறக்கணிக்கிறது. VP9 ஐப் பொறுத்தவரை, அதிகபட்ச பிட்ரேட் முடக்கப்பட்டிருந்தால் CRF ஐப் பயன்படுத்தலாம்.",
"transcoding_video_codec": "",
"transcoding_video_codec_description": "VP9 அதிக செயல்திறன் மற்றும் வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது, ஆனால் டிரான்ச்கோடிற்கு அதிக நேரம் எடுக்கும். HEVC இதேபோல் செயல்படுகிறது, ஆனால் குறைந்த வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது. H.264 பரவலாக இணக்கமானது மற்றும் டிரான்ச்கோடு விரைவானது, ஆனால் மிகப் பெரிய கோப்புகளை உருவாக்குகிறது. ஏ.வி 1 மிகவும் திறமையான கோடெக் ஆனால் பழைய சாதனங்களில் உதவி இல்லை.", "transcoding_video_codec_description": "VP9 அதிக செயல்திறன் மற்றும் வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது, ஆனால் டிரான்ச்கோடிற்கு அதிக நேரம் எடுக்கும். HEVC இதேபோல் செயல்படுகிறது, ஆனால் குறைந்த வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது. H.264 பரவலாக இணக்கமானது மற்றும் டிரான்ச்கோடு விரைவானது, ஆனால் மிகப் பெரிய கோப்புகளை உருவாக்குகிறது. ஏ.வி 1 மிகவும் திறமையான கோடெக் ஆனால் பழைய சாதனங்களில் உதவி இல்லை.",
"trash_enabled_description": "குப்பை அம்சங்களை இயக்கவும்", "trash_enabled_description": "குப்பை அம்சங்களை இயக்கவும்",
"trash_number_of_days": "நாட்களின் எண்ணிக்கை", "trash_number_of_days": "நாட்களின் எண்ணிக்கை",

View file

@ -1700,7 +1700,6 @@
"stack_duplicates": "นำสิ่งที่ซ้ำมาซ้อนอยู่ด้วยกัน", "stack_duplicates": "นำสิ่งที่ซ้ำมาซ้อนอยู่ด้วยกัน",
"stack_select_one_photo": "เลือกรูปหลักหนึ่งรูปสำหรับรูปที่ซ้อนกันนี้", "stack_select_one_photo": "เลือกรูปหลักหนึ่งรูปสำหรับรูปที่ซ้อนกันนี้",
"stack_selected_photos": "ซ้อนรูปที่ถูกเลือก", "stack_selected_photos": "ซ้อนรูปที่ถูกเลือก",
"stacktrace": "",
"start": "เริ่มต้น", "start": "เริ่มต้น",
"start_date": "วันที่เริ่ม", "start_date": "วันที่เริ่ม",
"state": "รัฐ", "state": "รัฐ",

View file

@ -18,6 +18,7 @@
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" /> <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<!-- Foreground service permission --> <!-- Foreground service permission -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

View file

@ -1,14 +1,14 @@
package app.alextran.immich package app.alextran.immich
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import androidx.annotation.NonNull import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity : FlutterActivity() { class MainActivity : FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
flutterEngine.plugins.add(BackgroundServicePlugin()) flutterEngine.plugins.add(BackgroundServicePlugin())
flutterEngine.plugins.add(HttpSSLOptionsPlugin()) flutterEngine.plugins.add(HttpSSLOptionsPlugin())
// No need to set up method channel here as it's now handled in the plugin // No need to set up method channel here as it's now handled in the plugin
} }
} }

View file

@ -1,22 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> setting is off -->
<!-- Show a splash screen on the activity. Automatically removed when <style name="LaunchTheme" parent="Theme.AppCompat.DayNight">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame --> Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item> <item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item> <item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item> <item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style> </style>
<!-- Theme applied to the Android Window as soon as the process has started. <!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its Flutter UI initializes, as well as behind your Flutter UI while its
running. running.
This Theme is only used starting with V2 of Flutter's Android embedding. --> This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item> <item name="android:windowBackground">?android:colorBackground</item>
</style> </style>
</resources> </resources>

View file

@ -44,6 +44,8 @@ PODS:
- Flutter - Flutter
- flutter_native_splash (2.4.3): - flutter_native_splash (2.4.3):
- Flutter - Flutter
- flutter_secure_storage (6.0.0):
- Flutter
- flutter_udid (0.0.1): - flutter_udid (0.0.1):
- Flutter - Flutter
- SAMKeychain - SAMKeychain
@ -59,6 +61,9 @@ PODS:
- Flutter - Flutter
- isar_flutter_libs (1.0.0): - isar_flutter_libs (1.0.0):
- Flutter - Flutter
- local_auth_darwin (0.0.1):
- Flutter
- FlutterMacOS
- MapLibre (6.5.0) - MapLibre (6.5.0)
- maplibre_gl (0.0.1): - maplibre_gl (0.0.1):
- Flutter - Flutter
@ -130,6 +135,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`) - flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`) - flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
@ -137,6 +143,7 @@ DEPENDENCIES:
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`) - integration_test (from `.symlinks/plugins/integration_test/ios`)
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`) - isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
- maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`) - maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`)
- native_video_player (from `.symlinks/plugins/native_video_player/ios`) - native_video_player (from `.symlinks/plugins/native_video_player/ios`)
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`) - network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
@ -178,6 +185,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_local_notifications/ios" :path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_native_splash: flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios" :path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
flutter_udid: flutter_udid:
:path: ".symlinks/plugins/flutter_udid/ios" :path: ".symlinks/plugins/flutter_udid/ios"
flutter_web_auth_2: flutter_web_auth_2:
@ -192,6 +201,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios" :path: ".symlinks/plugins/integration_test/ios"
isar_flutter_libs: isar_flutter_libs:
:path: ".symlinks/plugins/isar_flutter_libs/ios" :path: ".symlinks/plugins/isar_flutter_libs/ios"
local_auth_darwin:
:path: ".symlinks/plugins/local_auth_darwin/darwin"
maplibre_gl: maplibre_gl:
:path: ".symlinks/plugins/maplibre_gl/ios" :path: ".symlinks/plugins/maplibre_gl/ios"
native_video_player: native_video_player:
@ -233,6 +244,7 @@ SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100 flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9 flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
flutter_web_auth_2: 5c8d9dcd7848b5a9efb086d24e7a9adcae979c80 flutter_web_auth_2: 5c8d9dcd7848b5a9efb086d24e7a9adcae979c80
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1 fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
@ -240,6 +252,7 @@ SPEC CHECKSUMS:
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
isar_flutter_libs: bc909e72c3d756c2759f14c8776c13b5b0556e26 isar_flutter_libs: bc909e72c3d756c2759f14c8776c13b5b0556e26
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
MapLibre: 0ebfa9329d313cec8bf0a5ba5a336a1dc903785e MapLibre: 0ebfa9329d313cec8bf0a5ba5a336a1dc903785e
maplibre_gl: eab61cca6e1cfa9187249bacd3f08b51e8cd8ae9 maplibre_gl: eab61cca6e1cfa9187249bacd3f08b51e8cd8ae9
native_video_player: b65c58951ede2f93d103a25366bdebca95081265 native_video_player: b65c58951ede2f93d103a25366bdebca95081265

View file

@ -1,165 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>AppGroupId</key> <key>AppGroupId</key>
<string>$(CUSTOM_GROUP_ID)</string> <string>$(CUSTOM_GROUP_ID)</string>
<key>BGTaskSchedulerPermittedIdentifiers</key> <key>BGTaskSchedulerPermittedIdentifiers</key>
<array> <array>
<string>app.alextran.immich.backgroundFetch</string> <string>app.alextran.immich.backgroundFetch</string>
<string>app.alextran.immich.backgroundProcessing</string> <string>app.alextran.immich.backgroundProcessing</string>
</array> </array>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true />
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string> <string>${PRODUCT_NAME}</string>
<key>CFBundleDocumentTypes</key> <key>CFBundleDocumentTypes</key>
<array> <array>
<dict> <dict>
<key>CFBundleTypeName</key> <key>CFBundleTypeName</key>
<string>ShareHandler</string> <string>ShareHandler</string>
<key>LSHandlerRank</key> <key>LSHandlerRank</key>
<string>Alternate</string> <string>Alternate</string>
<key>LSItemContentTypes</key> <key>LSItemContentTypes</key>
<array> <array>
<string>public.file-url</string> <string>public.file-url</string>
<string>public.image</string> <string>public.image</string>
<string>public.text</string> <string>public.text</string>
<string>public.movie</string> <string>public.movie</string>
<string>public.url</string> <string>public.url</string>
<string>public.data</string> <string>public.data</string>
</array> </array>
</dict> </dict>
</array> </array>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleLocalizations</key> <key>CFBundleLocalizations</key>
<array> <array>
<string>en</string> <string>en</string>
<string>ar</string> <string>ar</string>
<string>ca</string> <string>ca</string>
<string>cs</string> <string>cs</string>
<string>da</string> <string>da</string>
<string>de</string> <string>de</string>
<string>es</string> <string>es</string>
<string>fi</string> <string>fi</string>
<string>fr</string> <string>fr</string>
<string>he</string> <string>he</string>
<string>hi</string> <string>hi</string>
<string>hu</string> <string>hu</string>
<string>it</string> <string>it</string>
<string>ja</string> <string>ja</string>
<string>ko</string> <string>ko</string>
<string>lv</string> <string>lv</string>
<string>mn</string> <string>mn</string>
<string>nb</string> <string>nb</string>
<string>nl</string> <string>nl</string>
<string>pl</string> <string>pl</string>
<string>pt</string> <string>pt</string>
<string>ro</string> <string>ro</string>
<string>ru</string> <string>ru</string>
<string>sk</string> <string>sk</string>
<string>sl</string> <string>sl</string>
<string>sr</string> <string>sr</string>
<string>sv</string> <string>sv</string>
<string>th</string> <string>th</string>
<string>uk</string> <string>uk</string>
<string>vi</string> <string>vi</string>
<string>zh</string> <string>zh</string>
</array> </array>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>immich_mobile</string> <string>immich_mobile</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.132.3</string> <string>1.132.3</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
<array> <array>
<dict> <dict>
<key>CFBundleTypeRole</key> <key>CFBundleTypeRole</key>
<string>Editor</string> <string>Editor</string>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array> </array>
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>205</string> <string>205</string>
<key>FLTEnableImpeller</key> <key>FLTEnableImpeller</key>
<true/> <true />
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false />
<key>LSApplicationQueriesSchemes</key> <key>LSApplicationQueriesSchemes</key>
<array> <array>
<string>https</string> <string>https</string>
</array> </array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true />
<key>LSSupportsOpeningDocumentsInPlace</key> <key>LSSupportsOpeningDocumentsInPlace</key>
<string>No</string> <string>No</string>
<key>MGLMapboxMetricsEnabledSettingShownInApp</key> <key>MGLMapboxMetricsEnabledSettingShownInApp</key>
<true/> <true />
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
<dict> <dict>
<key>NSAllowsArbitraryLoads</key> <key>NSAllowsArbitraryLoads</key>
<true/> <true />
</dict> </dict>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>We need to access the camera to let you take beautiful video using this app</string> <string>We need to access the camera to let you take beautiful video using this app</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We require this permission to access the local WiFi name for background upload mechanism</string> <string>We require this permission to access the local WiFi name for background upload mechanism</string>
<key>NSLocationUsageDescription</key> <key>NSLocationUsageDescription</key>
<string>We require this permission to access the local WiFi name</string> <string>We require this permission to access the local WiFi name</string>
<key>NSLocationWhenInUseUsageDescription</key> <key>NSLocationWhenInUseUsageDescription</key>
<string>We require this permission to access the local WiFi name</string> <string>We require this permission to access the local WiFi name</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>We need to access the microphone to let you take beautiful video using this app</string> <string>We need to access the microphone to let you take beautiful video using this app</string>
<key>NSPhotoLibraryAddUsageDescription</key> <key>NSPhotoLibraryAddUsageDescription</key>
<string>We need to manage backup your photos album</string> <string>We need to manage backup your photos album</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>We need to manage backup your photos album</string> <string>We need to manage backup your photos album</string>
<key>NSUserActivityTypes</key> <key>NSUserActivityTypes</key>
<array> <array>
<string>INSendMessageIntent</string> <string>INSendMessageIntent</string>
</array> </array>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true />
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>
<string>processing</string> <string>processing</string>
</array> </array>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>Main</string>
<key>UIStatusBarHidden</key> <key>UIStatusBarHidden</key>
<false/> <false />
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UISupportedInterfaceOrientations~ipad</key> <key>UISupportedInterfaceOrientations~ipad</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<true/> <true />
<key>io.flutter.embedded_views_preview</key> <key>io.flutter.embedded_views_preview</key>
<true/> <true />
</dict> <key>NSFaceIDUsageDescription</key>
</plist> <string>We need to use FaceID to allow access to your locked folder</string>
</dict>
</plist>

View file

@ -11,3 +11,6 @@ const int kSyncEventBatchSize = 5000;
// Hash batch limits // Hash batch limits
const int kBatchHashFileLimit = 128; const int kBatchHashFileLimit = 128;
const int kBatchHashSizeLimit = 1024 * 1024 * 1024; // 1GB const int kBatchHashSizeLimit = 1024 * 1024 * 1024; // 1GB
// Secure storage keys
const String kSecuredPinCode = "secured_pin_code";

View file

@ -8,3 +8,5 @@ enum TextSearchType {
filename, filename,
description, description,
} }
enum AssetVisibilityEnum { timeline, hidden, archive, locked }

View file

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart';
import 'package:immich_mobile/extensions/string_extensions.dart'; import 'package:immich_mobile/extensions/string_extensions.dart';
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart' import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'
@ -45,7 +46,8 @@ class Asset {
: remote.stack?.primaryAssetId, : remote.stack?.primaryAssetId,
stackCount = remote.stack?.assetCount ?? 0, stackCount = remote.stack?.assetCount ?? 0,
stackId = remote.stack?.id, stackId = remote.stack?.id,
thumbhash = remote.thumbhash; thumbhash = remote.thumbhash,
visibility = getVisibility(remote.visibility);
Asset({ Asset({
this.id = Isar.autoIncrement, this.id = Isar.autoIncrement,
@ -71,6 +73,7 @@ class Asset {
this.stackCount = 0, this.stackCount = 0,
this.isOffline = false, this.isOffline = false,
this.thumbhash, this.thumbhash,
this.visibility = AssetVisibilityEnum.timeline,
}); });
@ignore @ignore
@ -173,6 +176,9 @@ class Asset {
int stackCount; int stackCount;
@Enumerated(EnumType.ordinal)
AssetVisibilityEnum visibility;
/// Returns null if the asset has no sync access to the exif info /// Returns null if the asset has no sync access to the exif info
@ignore @ignore
double? get aspectRatio { double? get aspectRatio {
@ -349,7 +355,8 @@ class Asset {
a.thumbhash != thumbhash || a.thumbhash != thumbhash ||
stackId != a.stackId || stackId != a.stackId ||
stackCount != a.stackCount || stackCount != a.stackCount ||
stackPrimaryAssetId == null && a.stackPrimaryAssetId != null; stackPrimaryAssetId == null && a.stackPrimaryAssetId != null ||
visibility != a.visibility;
} }
/// Returns a new [Asset] with values from this and merged & updated with [a] /// Returns a new [Asset] with values from this and merged & updated with [a]
@ -452,6 +459,7 @@ class Asset {
String? stackPrimaryAssetId, String? stackPrimaryAssetId,
int? stackCount, int? stackCount,
String? thumbhash, String? thumbhash,
AssetVisibilityEnum? visibility,
}) => }) =>
Asset( Asset(
id: id ?? this.id, id: id ?? this.id,
@ -477,6 +485,7 @@ class Asset {
stackPrimaryAssetId: stackPrimaryAssetId ?? this.stackPrimaryAssetId, stackPrimaryAssetId: stackPrimaryAssetId ?? this.stackPrimaryAssetId,
stackCount: stackCount ?? this.stackCount, stackCount: stackCount ?? this.stackCount,
thumbhash: thumbhash ?? this.thumbhash, thumbhash: thumbhash ?? this.thumbhash,
visibility: visibility ?? this.visibility,
); );
Future<void> put(Isar db) async { Future<void> put(Isar db) async {
@ -541,8 +550,22 @@ class Asset {
"isArchived": $isArchived, "isArchived": $isArchived,
"isTrashed": $isTrashed, "isTrashed": $isTrashed,
"isOffline": $isOffline, "isOffline": $isOffline,
"visibility": "$visibility",
}"""; }""";
} }
static getVisibility(AssetVisibility visibility) {
switch (visibility) {
case AssetVisibility.timeline:
return AssetVisibilityEnum.timeline;
case AssetVisibility.archive:
return AssetVisibilityEnum.archive;
case AssetVisibility.hidden:
return AssetVisibilityEnum.hidden;
case AssetVisibility.locked:
return AssetVisibilityEnum.locked;
}
}
} }
enum AssetType { enum AssetType {

View file

@ -118,8 +118,14 @@ const AssetSchema = CollectionSchema(
name: r'updatedAt', name: r'updatedAt',
type: IsarType.dateTime, type: IsarType.dateTime,
), ),
r'width': PropertySchema( r'visibility': PropertySchema(
id: 20, id: 20,
name: r'visibility',
type: IsarType.byte,
enumMap: _AssetvisibilityEnumValueMap,
),
r'width': PropertySchema(
id: 21,
name: r'width', name: r'width',
type: IsarType.int, type: IsarType.int,
) )
@ -256,7 +262,8 @@ void _assetSerialize(
writer.writeString(offsets[17], object.thumbhash); writer.writeString(offsets[17], object.thumbhash);
writer.writeByte(offsets[18], object.type.index); writer.writeByte(offsets[18], object.type.index);
writer.writeDateTime(offsets[19], object.updatedAt); writer.writeDateTime(offsets[19], object.updatedAt);
writer.writeInt(offsets[20], object.width); writer.writeByte(offsets[20], object.visibility.index);
writer.writeInt(offsets[21], object.width);
} }
Asset _assetDeserialize( Asset _assetDeserialize(
@ -288,7 +295,10 @@ Asset _assetDeserialize(
type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[18])] ?? type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[18])] ??
AssetType.other, AssetType.other,
updatedAt: reader.readDateTime(offsets[19]), updatedAt: reader.readDateTime(offsets[19]),
width: reader.readIntOrNull(offsets[20]), visibility:
_AssetvisibilityValueEnumMap[reader.readByteOrNull(offsets[20])] ??
AssetVisibilityEnum.timeline,
width: reader.readIntOrNull(offsets[21]),
); );
return object; return object;
} }
@ -342,6 +352,9 @@ P _assetDeserializeProp<P>(
case 19: case 19:
return (reader.readDateTime(offset)) as P; return (reader.readDateTime(offset)) as P;
case 20: case 20:
return (_AssetvisibilityValueEnumMap[reader.readByteOrNull(offset)] ??
AssetVisibilityEnum.timeline) as P;
case 21:
return (reader.readIntOrNull(offset)) as P; return (reader.readIntOrNull(offset)) as P;
default: default:
throw IsarError('Unknown property with id $propertyId'); throw IsarError('Unknown property with id $propertyId');
@ -360,6 +373,18 @@ const _AssettypeValueEnumMap = {
2: AssetType.video, 2: AssetType.video,
3: AssetType.audio, 3: AssetType.audio,
}; };
const _AssetvisibilityEnumValueMap = {
'timeline': 0,
'hidden': 1,
'archive': 2,
'locked': 3,
};
const _AssetvisibilityValueEnumMap = {
0: AssetVisibilityEnum.timeline,
1: AssetVisibilityEnum.hidden,
2: AssetVisibilityEnum.archive,
3: AssetVisibilityEnum.locked,
};
Id _assetGetId(Asset object) { Id _assetGetId(Asset object) {
return object.id; return object.id;
@ -2477,6 +2502,59 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
}); });
} }
QueryBuilder<Asset, Asset, QAfterFilterCondition> visibilityEqualTo(
AssetVisibilityEnum value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'visibility',
value: value,
));
});
}
QueryBuilder<Asset, Asset, QAfterFilterCondition> visibilityGreaterThan(
AssetVisibilityEnum value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'visibility',
value: value,
));
});
}
QueryBuilder<Asset, Asset, QAfterFilterCondition> visibilityLessThan(
AssetVisibilityEnum value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'visibility',
value: value,
));
});
}
QueryBuilder<Asset, Asset, QAfterFilterCondition> visibilityBetween(
AssetVisibilityEnum lower,
AssetVisibilityEnum upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'visibility',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<Asset, Asset, QAfterFilterCondition> widthIsNull() { QueryBuilder<Asset, Asset, QAfterFilterCondition> widthIsNull() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull( return query.addFilterCondition(const FilterCondition.isNull(
@ -2791,6 +2869,18 @@ extension AssetQuerySortBy on QueryBuilder<Asset, Asset, QSortBy> {
}); });
} }
QueryBuilder<Asset, Asset, QAfterSortBy> sortByVisibility() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'visibility', Sort.asc);
});
}
QueryBuilder<Asset, Asset, QAfterSortBy> sortByVisibilityDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'visibility', Sort.desc);
});
}
QueryBuilder<Asset, Asset, QAfterSortBy> sortByWidth() { QueryBuilder<Asset, Asset, QAfterSortBy> sortByWidth() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'width', Sort.asc); return query.addSortBy(r'width', Sort.asc);
@ -3057,6 +3147,18 @@ extension AssetQuerySortThenBy on QueryBuilder<Asset, Asset, QSortThenBy> {
}); });
} }
QueryBuilder<Asset, Asset, QAfterSortBy> thenByVisibility() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'visibility', Sort.asc);
});
}
QueryBuilder<Asset, Asset, QAfterSortBy> thenByVisibilityDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'visibility', Sort.desc);
});
}
QueryBuilder<Asset, Asset, QAfterSortBy> thenByWidth() { QueryBuilder<Asset, Asset, QAfterSortBy> thenByWidth() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'width', Sort.asc); return query.addSortBy(r'width', Sort.asc);
@ -3201,6 +3303,12 @@ extension AssetQueryWhereDistinct on QueryBuilder<Asset, Asset, QDistinct> {
}); });
} }
QueryBuilder<Asset, Asset, QDistinct> distinctByVisibility() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'visibility');
});
}
QueryBuilder<Asset, Asset, QDistinct> distinctByWidth() { QueryBuilder<Asset, Asset, QDistinct> distinctByWidth() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'width'); return query.addDistinctBy(r'width');
@ -3335,6 +3443,13 @@ extension AssetQueryProperty on QueryBuilder<Asset, Asset, QQueryProperty> {
}); });
} }
QueryBuilder<Asset, AssetVisibilityEnum, QQueryOperations>
visibilityProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'visibility');
});
}
QueryBuilder<Asset, int?, QQueryOperations> widthProperty() { QueryBuilder<Asset, int?, QQueryOperations> widthProperty() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'width'); return query.addPropertyName(r'width');

View file

@ -1,3 +1,4 @@
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
abstract interface class IAssetApiRepository { abstract interface class IAssetApiRepository {
@ -15,4 +16,9 @@ abstract interface class IAssetApiRepository {
// Future<void> delete(String id); // Future<void> delete(String id);
Future<List<Asset>> search({List<String> personIds = const []}); Future<List<Asset>> search({List<String> personIds = const []});
Future<void> updateVisibility(
List<String> list,
AssetVisibilityEnum visibility,
);
} }

View file

@ -6,4 +6,9 @@ abstract interface class IAuthApiRepository {
Future<void> logout(); Future<void> logout();
Future<void> changePassword(String newPassword); Future<void> changePassword(String newPassword);
Future<bool> unlockPinCode(String pinCode);
Future<void> lockPinCode();
Future<void> setupPinCode(String pinCode);
} }

View file

@ -0,0 +1,6 @@
import 'package:immich_mobile/models/auth/biometric_status.model.dart';
abstract interface class IBiometricRepository {
Future<BiometricStatus> getStatus();
Future<bool> authenticate(String? message);
}

View file

@ -0,0 +1,5 @@
abstract interface class ISecureStorageRepository {
Future<String?> read(String key);
Future<void> write(String key, String value);
Future<void> delete(String key);
}

View file

@ -31,4 +31,9 @@ abstract class ITimelineRepository {
); );
Stream<RenderList> watchAssetSelectionTimeline(String userId); Stream<RenderList> watchAssetSelectionTimeline(String userId);
Stream<RenderList> watchLockedTimeline(
String userId,
GroupAssetsBy groupAssetsBy,
);
} }

View file

@ -19,7 +19,7 @@ import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
import 'package:immich_mobile/providers/locale_provider.dart'; import 'package:immich_mobile/providers/locale_provider.dart';
import 'package:immich_mobile/providers/theme.provider.dart'; import 'package:immich_mobile/providers/theme.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/routing/tab_navigation_observer.dart'; import 'package:immich_mobile/routing/app_navigation_observer.dart';
import 'package:immich_mobile/services/background.service.dart'; import 'package:immich_mobile/services/background.service.dart';
import 'package:immich_mobile/services/local_notification.service.dart'; import 'package:immich_mobile/services/local_notification.service.dart';
import 'package:immich_mobile/theme/dynamic_theme.dart'; import 'package:immich_mobile/theme/dynamic_theme.dart';
@ -219,7 +219,7 @@ class ImmichAppState extends ConsumerState<ImmichApp>
), ),
routeInformationParser: router.defaultRouteParser(), routeInformationParser: router.defaultRouteParser(),
routerDelegate: router.delegate( routerDelegate: router.delegate(
navigatorObservers: () => [TabNavigationObserver(ref: ref)], navigatorObservers: () => [AppNavigationObserver(ref: ref)],
), ),
), ),
), ),

View file

@ -0,0 +1,38 @@
import 'package:collection/collection.dart';
import 'package:local_auth/local_auth.dart';
class BiometricStatus {
final List<BiometricType> availableBiometrics;
final bool canAuthenticate;
const BiometricStatus({
required this.availableBiometrics,
required this.canAuthenticate,
});
@override
String toString() =>
'BiometricStatus(availableBiometrics: $availableBiometrics, canAuthenticate: $canAuthenticate)';
BiometricStatus copyWith({
List<BiometricType>? availableBiometrics,
bool? canAuthenticate,
}) {
return BiometricStatus(
availableBiometrics: availableBiometrics ?? this.availableBiometrics,
canAuthenticate: canAuthenticate ?? this.canAuthenticate,
);
}
@override
bool operator ==(covariant BiometricStatus other) {
if (identical(this, other)) return true;
final listEquals = const DeepCollectionEquality().equals;
return listEquals(other.availableBiometrics, availableBiometrics) &&
other.canAuthenticate == canAuthenticate;
}
@override
int get hashCode => availableBiometrics.hashCode ^ canAuthenticate.hashCode;
}

View file

@ -140,6 +140,19 @@ class QuickAccessButtons extends ConsumerWidget {
), ),
onTap: () => context.pushRoute(FolderRoute()), onTap: () => context.pushRoute(FolderRoute()),
), ),
ListTile(
leading: const Icon(
Icons.lock_outline_rounded,
size: 26,
),
title: Text(
'locked_folder'.tr(),
style: context.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w500,
),
),
onTap: () => context.pushRoute(const LockedRoute()),
),
ListTile( ListTile(
leading: const Icon( leading: const Icon(
Icons.group_outlined, Icons.group_outlined,

View file

@ -0,0 +1,95 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/providers/multiselect.provider.dart';
import 'package:immich_mobile/providers/timeline.provider.dart';
import 'package:immich_mobile/widgets/asset_grid/multiselect_grid.dart';
@RoutePage()
class LockedPage extends HookConsumerWidget {
const LockedPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final appLifeCycle = useAppLifecycleState();
final showOverlay = useState(false);
final authProviderNotifier = ref.read(authProvider.notifier);
// lock the page when it is destroyed
useEffect(
() {
return () {
authProviderNotifier.lockPinCode();
};
},
[],
);
useEffect(
() {
if (context.mounted) {
if (appLifeCycle == AppLifecycleState.resumed) {
showOverlay.value = false;
} else {
showOverlay.value = true;
}
}
return null;
},
[appLifeCycle],
);
return Scaffold(
appBar: ref.watch(multiselectProvider) ? null : const LockPageAppBar(),
body: showOverlay.value
? const SizedBox()
: MultiselectGrid(
renderListProvider: lockedTimelineProvider,
topWidget: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Text(
'no_locked_photos_message'.tr(),
style: context.textTheme.labelLarge,
),
),
),
editEnabled: false,
favoriteEnabled: false,
unfavorite: false,
archiveEnabled: false,
stackEnabled: false,
unarchive: false,
),
);
}
}
class LockPageAppBar extends ConsumerWidget implements PreferredSizeWidget {
const LockPageAppBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return AppBar(
leading: IconButton(
onPressed: () {
ref.read(authProvider.notifier).lockPinCode();
context.maybePop();
},
icon: const Icon(Icons.arrow_back_ios_rounded),
),
centerTitle: true,
automaticallyImplyLeading: false,
title: const Text(
'locked_folder',
).tr(),
);
}
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

View file

@ -0,0 +1,127 @@
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/local_auth.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/widgets/forms/pin_registration_form.dart';
import 'package:immich_mobile/widgets/forms/pin_verification_form.dart';
@RoutePage()
class PinAuthPage extends HookConsumerWidget {
final bool createPinCode;
const PinAuthPage({super.key, this.createPinCode = false});
@override
Widget build(BuildContext context, WidgetRef ref) {
final localAuthState = ref.watch(localAuthProvider);
final showPinRegistrationForm = useState(createPinCode);
Future<void> registerBiometric(String pinCode) async {
final isRegistered =
await ref.read(localAuthProvider.notifier).registerBiometric(
context,
pinCode,
);
if (isRegistered) {
context.showSnackBar(
SnackBar(
content: Text(
'biometric_auth_enabled'.tr(),
style: context.textTheme.labelLarge,
),
duration: const Duration(seconds: 3),
backgroundColor: context.colorScheme.primaryContainer,
),
);
context.replaceRoute(const LockedRoute());
}
}
enableBiometricAuth() {
showDialog(
context: context,
builder: (buildContext) {
return SimpleDialog(
children: [
Container(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
PinVerificationForm(
description: 'enable_biometric_auth_description'.tr(),
onSuccess: (pinCode) {
Navigator.pop(buildContext);
registerBiometric(pinCode);
},
autoFocus: true,
icon: Icons.fingerprint_rounded,
successIcon: Icons.fingerprint_rounded,
),
],
),
),
],
);
},
);
}
return Scaffold(
appBar: AppBar(
title: Text('locked_folder'.tr()),
),
body: ListView(
shrinkWrap: true,
children: [
Padding(
padding: const EdgeInsets.only(top: 36.0),
child: showPinRegistrationForm.value
? Center(
child: PinRegistrationForm(
onDone: () => showPinRegistrationForm.value = false,
),
)
: Column(
children: [
Center(
child: PinVerificationForm(
autoFocus: true,
onSuccess: (_) =>
context.replaceRoute(const LockedRoute()),
),
),
const SizedBox(height: 24),
if (localAuthState.canAuthenticate) ...[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: TextButton.icon(
icon: const Icon(
Icons.fingerprint,
size: 28,
),
onPressed: enableBiometricAuth,
label: Text(
'use_biometric'.tr(),
style: context.textTheme.labelLarge?.copyWith(
color: context.primaryColor,
fontSize: 18,
),
),
),
),
],
],
),
),
],
),
);
}
}

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/domain/services/user.service.dart'; import 'package:immich_mobile/domain/services/user.service.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
@ -170,6 +171,13 @@ class AssetNotifier extends StateNotifier<bool> {
status ??= !assets.every((a) => a.isArchived); status ??= !assets.every((a) => a.isArchived);
return _assetService.changeArchiveStatus(assets, status); return _assetService.changeArchiveStatus(assets, status);
} }
Future<void> setLockedView(
List<Asset> selection,
AssetVisibilityEnum visibility,
) {
return _assetService.setVisibility(selection, visibility);
}
} }
final assetDetailProvider = final assetDetailProvider =

View file

@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_udid/flutter_udid.dart'; import 'package:flutter_udid/flutter_udid.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/constants.dart';
import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/domain/models/user.model.dart';
import 'package:immich_mobile/domain/services/user.service.dart'; import 'package:immich_mobile/domain/services/user.service.dart';
@ -11,6 +12,7 @@ import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/auth.service.dart'; import 'package:immich_mobile/services/auth.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:immich_mobile/utils/hash.dart'; import 'package:immich_mobile/utils/hash.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:openapi/api.dart'; import 'package:openapi/api.dart';
@ -20,6 +22,7 @@ final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
ref.watch(authServiceProvider), ref.watch(authServiceProvider),
ref.watch(apiServiceProvider), ref.watch(apiServiceProvider),
ref.watch(userServiceProvider), ref.watch(userServiceProvider),
ref.watch(secureStorageServiceProvider),
); );
}); });
@ -27,12 +30,17 @@ class AuthNotifier extends StateNotifier<AuthState> {
final AuthService _authService; final AuthService _authService;
final ApiService _apiService; final ApiService _apiService;
final UserService _userService; final UserService _userService;
final SecureStorageService _secureStorageService;
final _log = Logger("AuthenticationNotifier"); final _log = Logger("AuthenticationNotifier");
static const Duration _timeoutDuration = Duration(seconds: 7); static const Duration _timeoutDuration = Duration(seconds: 7);
AuthNotifier(this._authService, this._apiService, this._userService) AuthNotifier(
: super( this._authService,
this._apiService,
this._userService,
this._secureStorageService,
) : super(
AuthState( AuthState(
deviceId: "", deviceId: "",
userId: "", userId: "",
@ -67,6 +75,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
Future<void> logout() async { Future<void> logout() async {
try { try {
await _secureStorageService.delete(kSecuredPinCode);
await _authService.logout(); await _authService.logout();
} finally { } finally {
await _cleanUp(); await _cleanUp();
@ -188,4 +197,16 @@ class AuthNotifier extends StateNotifier<AuthState> {
Future<String?> setOpenApiServiceEndpoint() { Future<String?> setOpenApiServiceEndpoint() {
return _authService.setOpenApiServiceEndpoint(); return _authService.setOpenApiServiceEndpoint();
} }
Future<bool> unlockPinCode(String pinCode) {
return _authService.unlockPinCode(pinCode);
}
Future<void> lockPinCode() {
return _authService.lockPinCode();
}
Future<void> setupPinCode(String pinCode) {
return _authService.setupPinCode(pinCode);
}
} }

View file

@ -0,0 +1,97 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/constants.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/models/auth/biometric_status.model.dart';
import 'package:immich_mobile/services/local_auth.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:logging/logging.dart';
final localAuthProvider =
StateNotifierProvider<LocalAuthNotifier, BiometricStatus>((ref) {
return LocalAuthNotifier(
ref.watch(localAuthServiceProvider),
ref.watch(secureStorageServiceProvider),
);
});
class LocalAuthNotifier extends StateNotifier<BiometricStatus> {
final LocalAuthService _localAuthService;
final SecureStorageService _secureStorageService;
final _log = Logger("LocalAuthNotifier");
LocalAuthNotifier(this._localAuthService, this._secureStorageService)
: super(
const BiometricStatus(
availableBiometrics: [],
canAuthenticate: false,
),
) {
_localAuthService.getStatus().then((value) {
state = state.copyWith(
canAuthenticate: value.canAuthenticate,
availableBiometrics: value.availableBiometrics,
);
});
}
Future<bool> registerBiometric(BuildContext context, String pinCode) async {
final isAuthenticated =
await authenticate(context, 'Authenticate to enable biometrics');
if (!isAuthenticated) {
return false;
}
await _secureStorageService.write(kSecuredPinCode, pinCode);
return true;
}
Future<bool> authenticate(BuildContext context, String? message) async {
String errorMessage = "";
try {
return await _localAuthService.authenticate(message);
} on PlatformException catch (error) {
switch (error.code) {
case "NotEnrolled":
_log.warning("User is not enrolled in biometrics");
errorMessage = "biometric_no_options".tr();
break;
case "NotAvailable":
_log.warning("Biometric authentication is not available");
errorMessage = "biometric_not_available".tr();
break;
case "LockedOut":
_log.warning("User is locked out of biometric authentication");
errorMessage = "biometric_locked_out".tr();
break;
default:
_log.warning("Failed to authenticate with unknown reason");
errorMessage = 'failed_to_authenticate'.tr();
}
} catch (error) {
_log.warning("Error during authentication: $error");
errorMessage = 'failed_to_authenticate'.tr();
} finally {
if (errorMessage.isNotEmpty) {
context.showSnackBar(
SnackBar(
content: Text(
errorMessage,
style: context.textTheme.labelLarge,
),
duration: const Duration(seconds: 3),
backgroundColor: context.colorScheme.errorContainer,
),
);
}
}
return false;
}
}

View file

@ -0,0 +1,3 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
final inLockedViewProvider = StateProvider<bool>((ref) => false);

View file

@ -0,0 +1,10 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
final secureStorageProvider =
StateNotifierProvider<SecureStorageProvider, void>((ref) {
return SecureStorageProvider();
});
class SecureStorageProvider extends StateNotifier<void> {
SecureStorageProvider() : super(null);
}

View file

@ -73,3 +73,8 @@ final assetsTimelineProvider =
null, null,
); );
}); });
final lockedTimelineProvider = StreamProvider<RenderList>((ref) {
final timelineService = ref.watch(timelineServiceProvider);
return timelineService.watchLockedTimelineProvider();
});

View file

@ -1,4 +1,5 @@
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/interfaces/asset_api.interface.dart'; import 'package:immich_mobile/interfaces/asset_api.interface.dart';
import 'package:immich_mobile/providers/api.provider.dart'; import 'package:immich_mobile/providers/api.provider.dart';
@ -48,4 +49,27 @@ class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
} }
return result; return result;
} }
@override
Future<void> updateVisibility(
List<String> ids,
AssetVisibilityEnum visibility,
) async {
return _api.updateAssets(
AssetBulkUpdateDto(ids: ids, visibility: _mapVisibility(visibility)),
);
}
_mapVisibility(AssetVisibilityEnum visibility) {
switch (visibility) {
case AssetVisibilityEnum.timeline:
return AssetVisibility.timeline;
case AssetVisibilityEnum.hidden:
return AssetVisibility.hidden;
case AssetVisibilityEnum.locked:
return AssetVisibility.locked;
case AssetVisibilityEnum.archive:
return AssetVisibility.archive;
}
}
} }

View file

@ -55,4 +55,26 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
userId: dto.userId, userId: dto.userId,
); );
} }
@override
Future<bool> unlockPinCode(String pinCode) async {
try {
await _apiService.authenticationApi
.unlockAuthSession(SessionUnlockDto(pinCode: pinCode));
return true;
} catch (_) {
return false;
}
}
@override
Future<void> setupPinCode(String pinCode) {
return _apiService.authenticationApi
.setupPinCode(PinCodeSetupDto(pinCode: pinCode));
}
@override
Future<void> lockPinCode() {
return _apiService.authenticationApi.lockAuthSession();
}
} }

View file

@ -0,0 +1,35 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/interfaces/biometric.interface.dart';
import 'package:immich_mobile/models/auth/biometric_status.model.dart';
import 'package:local_auth/local_auth.dart';
final biometricRepositoryProvider =
Provider((ref) => BiometricRepository(LocalAuthentication()));
class BiometricRepository implements IBiometricRepository {
final LocalAuthentication _localAuth;
BiometricRepository(this._localAuth);
@override
Future<BiometricStatus> getStatus() async {
final bool canAuthenticateWithBiometrics =
await _localAuth.canCheckBiometrics;
final bool canAuthenticate =
canAuthenticateWithBiometrics || await _localAuth.isDeviceSupported();
final availableBiometric = await _localAuth.getAvailableBiometrics();
return BiometricStatus(
canAuthenticate: canAuthenticate,
availableBiometrics: availableBiometric,
);
}
@override
Future<bool> authenticate(String? message) async {
return _localAuth.authenticate(
localizedReason: message ?? 'please_auth_to_access'.tr(),
);
}
}

View file

@ -0,0 +1,27 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/interfaces/secure_storage.interface.dart';
final secureStorageRepositoryProvider =
Provider((ref) => SecureStorageRepository(const FlutterSecureStorage()));
class SecureStorageRepository implements ISecureStorageRepository {
final FlutterSecureStorage _secureStorage;
SecureStorageRepository(this._secureStorage);
@override
Future<String?> read(String key) {
return _secureStorage.read(key: key);
}
@override
Future<void> write(String key, String value) {
return _secureStorage.write(key: key, value: value);
}
@override
Future<void> delete(String key) {
return _secureStorage.delete(key: key);
}
}

View file

@ -45,8 +45,8 @@ class TimelineRepository extends DatabaseRepository
.where() .where()
.ownerIdEqualToAnyChecksum(fastHash(userId)) .ownerIdEqualToAnyChecksum(fastHash(userId))
.filter() .filter()
.isArchivedEqualTo(true)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.visibilityEqualTo(AssetVisibilityEnum.archive)
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
return _watchRenderList(query, GroupAssetsBy.none); return _watchRenderList(query, GroupAssetsBy.none);
@ -59,6 +59,8 @@ class TimelineRepository extends DatabaseRepository
.ownerIdEqualToAnyChecksum(fastHash(userId)) .ownerIdEqualToAnyChecksum(fastHash(userId))
.filter() .filter()
.isFavoriteEqualTo(true) .isFavoriteEqualTo(true)
.not()
.visibilityEqualTo(AssetVisibilityEnum.locked)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
@ -94,8 +96,8 @@ class TimelineRepository extends DatabaseRepository
Stream<RenderList> watchAllVideosTimeline() { Stream<RenderList> watchAllVideosTimeline() {
final query = db.assets final query = db.assets
.filter() .filter()
.isArchivedEqualTo(false)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.visibilityEqualTo(AssetVisibilityEnum.timeline)
.typeEqualTo(AssetType.video) .typeEqualTo(AssetType.video)
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
@ -111,9 +113,9 @@ class TimelineRepository extends DatabaseRepository
.where() .where()
.ownerIdEqualToAnyChecksum(fastHash(userId)) .ownerIdEqualToAnyChecksum(fastHash(userId))
.filter() .filter()
.isArchivedEqualTo(false)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.stackPrimaryAssetIdIsNull() .stackPrimaryAssetIdIsNull()
.visibilityEqualTo(AssetVisibilityEnum.timeline)
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
return _watchRenderList(query, groupAssetByOption); return _watchRenderList(query, groupAssetByOption);
@ -129,8 +131,8 @@ class TimelineRepository extends DatabaseRepository
.where() .where()
.anyOf(isarUserIds, (qb, id) => qb.ownerIdEqualToAnyChecksum(id)) .anyOf(isarUserIds, (qb, id) => qb.ownerIdEqualToAnyChecksum(id))
.filter() .filter()
.isArchivedEqualTo(false)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.visibilityEqualTo(AssetVisibilityEnum.timeline)
.stackPrimaryAssetIdIsNull() .stackPrimaryAssetIdIsNull()
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
return _watchRenderList(query, groupAssetByOption); return _watchRenderList(query, groupAssetByOption);
@ -151,6 +153,7 @@ class TimelineRepository extends DatabaseRepository
.remoteIdIsNotNull() .remoteIdIsNotNull()
.filter() .filter()
.ownerIdEqualTo(fastHash(userId)) .ownerIdEqualTo(fastHash(userId))
.visibilityEqualTo(AssetVisibilityEnum.timeline)
.isTrashedEqualTo(false) .isTrashedEqualTo(false)
.stackPrimaryAssetIdIsNull() .stackPrimaryAssetIdIsNull()
.sortByFileCreatedAtDesc(); .sortByFileCreatedAtDesc();
@ -158,6 +161,22 @@ class TimelineRepository extends DatabaseRepository
return _watchRenderList(query, GroupAssetsBy.none); return _watchRenderList(query, GroupAssetsBy.none);
} }
@override
Stream<RenderList> watchLockedTimeline(
String userId,
GroupAssetsBy getGroupByOption,
) {
final query = db.assets
.where()
.ownerIdEqualToAnyChecksum(fastHash(userId))
.filter()
.visibilityEqualTo(AssetVisibilityEnum.locked)
.isTrashedEqualTo(false)
.sortByFileCreatedAtDesc();
return _watchRenderList(query, getGroupByOption);
}
Stream<RenderList> _watchRenderList( Stream<RenderList> _watchRenderList(
QueryBuilder<Asset, Asset, QAfterSortBy> query, QueryBuilder<Asset, Asset, QAfterSortBy> query,
GroupAssetsBy groupAssetsBy, GroupAssetsBy groupAssetsBy,

View file

@ -0,0 +1,52 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
import 'package:immich_mobile/routing/router.dart';
class AppNavigationObserver extends AutoRouterObserver {
/// Riverpod Instance
final WidgetRef ref;
AppNavigationObserver({
required this.ref,
});
@override
Future<void> didChangeTabRoute(
TabPageRoute route,
TabPageRoute previousRoute,
) async {
Future(
() => ref.read(inLockedViewProvider.notifier).state = false,
);
}
@override
void didPush(Route route, Route? previousRoute) {
_handleLockedViewState(route, previousRoute);
}
_handleLockedViewState(Route route, Route? previousRoute) {
final isInLockedView = ref.read(inLockedViewProvider);
final isFromLockedViewToDetailView =
route.settings.name == GalleryViewerRoute.name &&
previousRoute?.settings.name == LockedRoute.name;
final isFromDetailViewToInfoPanelView = route.settings.name == null &&
previousRoute?.settings.name == GalleryViewerRoute.name &&
isInLockedView;
if (route.settings.name == LockedRoute.name ||
isFromLockedViewToDetailView ||
isFromDetailViewToInfoPanelView) {
Future(
() => ref.read(inLockedViewProvider.notifier).state = true,
);
} else {
Future(
() => ref.read(inLockedViewProvider.notifier).state = false,
);
}
}
}

View file

@ -0,0 +1,89 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/services.dart';
import 'package:immich_mobile/constants/constants.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/local_auth.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:local_auth/error_codes.dart' as auth_error;
import 'package:logging/logging.dart';
// ignore: import_rule_openapi
import 'package:openapi/api.dart';
class LockedGuard extends AutoRouteGuard {
final ApiService _apiService;
final SecureStorageService _secureStorageService;
final LocalAuthService _localAuth;
final _log = Logger("AuthGuard");
LockedGuard(
this._apiService,
this._secureStorageService,
this._localAuth,
);
@override
void onNavigation(NavigationResolver resolver, StackRouter router) async {
final authStatus = await _apiService.authenticationApi.getAuthStatus();
if (authStatus == null) {
resolver.next(false);
return;
}
/// Check if a pincode has been created but this user. Show the form to create if not exist
if (!authStatus.pinCode) {
router.push(PinAuthRoute(createPinCode: true));
}
if (authStatus.isElevated) {
resolver.next(true);
return;
}
/// Check if the user has the pincode saved in secure storage, meaning
/// the user has enabled the biometric authentication
final securePinCode = await _secureStorageService.read(kSecuredPinCode);
if (securePinCode == null) {
router.push(PinAuthRoute());
return;
}
try {
final bool isAuth = await _localAuth.authenticate();
if (!isAuth) {
resolver.next(false);
return;
}
await _apiService.authenticationApi.unlockAuthSession(
SessionUnlockDto(pinCode: securePinCode),
);
resolver.next(true);
} on PlatformException catch (error) {
switch (error.code) {
case auth_error.notAvailable:
_log.severe("notAvailable: $error");
break;
case auth_error.notEnrolled:
_log.severe("not enrolled");
break;
default:
_log.severe("error");
break;
}
resolver.next(false);
} on ApiException {
// PIN code has changed, need to re-enter to access
await _secureStorageService.delete(kSecuredPinCode);
router.push(PinAuthRoute());
} catch (error) {
_log.severe("Failed to access locked page", error);
resolver.next(false);
}
}
}

View file

@ -39,6 +39,8 @@ import 'package:immich_mobile/pages/library/favorite.page.dart';
import 'package:immich_mobile/pages/library/folder/folder.page.dart'; import 'package:immich_mobile/pages/library/folder/folder.page.dart';
import 'package:immich_mobile/pages/library/library.page.dart'; import 'package:immich_mobile/pages/library/library.page.dart';
import 'package:immich_mobile/pages/library/local_albums.page.dart'; import 'package:immich_mobile/pages/library/local_albums.page.dart';
import 'package:immich_mobile/pages/library/locked/locked.page.dart';
import 'package:immich_mobile/pages/library/locked/pin_auth.page.dart';
import 'package:immich_mobile/pages/library/partner/partner.page.dart'; import 'package:immich_mobile/pages/library/partner/partner.page.dart';
import 'package:immich_mobile/pages/library/partner/partner_detail.page.dart'; import 'package:immich_mobile/pages/library/partner/partner_detail.page.dart';
import 'package:immich_mobile/pages/library/people/people_collection.page.dart'; import 'package:immich_mobile/pages/library/people/people_collection.page.dart';
@ -67,24 +69,41 @@ import 'package:immich_mobile/routing/auth_guard.dart';
import 'package:immich_mobile/routing/backup_permission_guard.dart'; import 'package:immich_mobile/routing/backup_permission_guard.dart';
import 'package:immich_mobile/routing/custom_transition_builders.dart'; import 'package:immich_mobile/routing/custom_transition_builders.dart';
import 'package:immich_mobile/routing/duplicate_guard.dart'; import 'package:immich_mobile/routing/duplicate_guard.dart';
import 'package:immich_mobile/routing/locked_guard.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/local_auth.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
import 'package:maplibre_gl/maplibre_gl.dart'; import 'package:maplibre_gl/maplibre_gl.dart';
part 'router.gr.dart'; part 'router.gr.dart';
final appRouterProvider = Provider(
(ref) => AppRouter(
ref.watch(apiServiceProvider),
ref.watch(galleryPermissionNotifier.notifier),
ref.watch(secureStorageServiceProvider),
ref.watch(localAuthServiceProvider),
),
);
@AutoRouterConfig(replaceInRouteName: 'Page,Route') @AutoRouterConfig(replaceInRouteName: 'Page,Route')
class AppRouter extends RootStackRouter { class AppRouter extends RootStackRouter {
late final AuthGuard _authGuard; late final AuthGuard _authGuard;
late final DuplicateGuard _duplicateGuard; late final DuplicateGuard _duplicateGuard;
late final BackupPermissionGuard _backupPermissionGuard; late final BackupPermissionGuard _backupPermissionGuard;
late final LockedGuard _lockedGuard;
AppRouter( AppRouter(
ApiService apiService, ApiService apiService,
GalleryPermissionNotifier galleryPermissionNotifier, GalleryPermissionNotifier galleryPermissionNotifier,
SecureStorageService secureStorageService,
LocalAuthService localAuthService,
) { ) {
_authGuard = AuthGuard(apiService); _authGuard = AuthGuard(apiService);
_duplicateGuard = DuplicateGuard(); _duplicateGuard = DuplicateGuard();
_lockedGuard =
LockedGuard(apiService, secureStorageService, localAuthService);
_backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier); _backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier);
} }
@ -289,12 +308,13 @@ class AppRouter extends RootStackRouter {
page: ShareIntentRoute.page, page: ShareIntentRoute.page,
guards: [_authGuard, _duplicateGuard], guards: [_authGuard, _duplicateGuard],
), ),
AutoRoute(
page: LockedRoute.page,
guards: [_authGuard, _lockedGuard, _duplicateGuard],
),
AutoRoute(
page: PinAuthRoute.page,
guards: [_authGuard, _duplicateGuard],
),
]; ];
} }
final appRouterProvider = Provider(
(ref) => AppRouter(
ref.watch(apiServiceProvider),
ref.watch(galleryPermissionNotifier.notifier),
),
);

View file

@ -956,6 +956,25 @@ class LocalAlbumsRoute extends PageRouteInfo<void> {
); );
} }
/// generated route for
/// [LockedPage]
class LockedRoute extends PageRouteInfo<void> {
const LockedRoute({List<PageRouteInfo>? children})
: super(
LockedRoute.name,
initialChildren: children,
);
static const String name = 'LockedRoute';
static PageInfo page = PageInfo(
name,
builder: (data) {
return const LockedPage();
},
);
}
/// generated route for /// generated route for
/// [LoginPage] /// [LoginPage]
class LoginRoute extends PageRouteInfo<void> { class LoginRoute extends PageRouteInfo<void> {
@ -1359,6 +1378,53 @@ class PhotosRoute extends PageRouteInfo<void> {
); );
} }
/// generated route for
/// [PinAuthPage]
class PinAuthRoute extends PageRouteInfo<PinAuthRouteArgs> {
PinAuthRoute({
Key? key,
bool createPinCode = false,
List<PageRouteInfo>? children,
}) : super(
PinAuthRoute.name,
args: PinAuthRouteArgs(
key: key,
createPinCode: createPinCode,
),
initialChildren: children,
);
static const String name = 'PinAuthRoute';
static PageInfo page = PageInfo(
name,
builder: (data) {
final args =
data.argsAs<PinAuthRouteArgs>(orElse: () => const PinAuthRouteArgs());
return PinAuthPage(
key: args.key,
createPinCode: args.createPinCode,
);
},
);
}
class PinAuthRouteArgs {
const PinAuthRouteArgs({
this.key,
this.createPinCode = false,
});
final Key? key;
final bool createPinCode;
@override
String toString() {
return 'PinAuthRouteArgs{key: $key, createPinCode: $createPinCode}';
}
}
/// generated route for /// generated route for
/// [PlacesCollectionPage] /// [PlacesCollectionPage]
class PlacesCollectionRoute extends PageRouteInfo<PlacesCollectionRouteArgs> { class PlacesCollectionRoute extends PageRouteInfo<PlacesCollectionRouteArgs> {

View file

@ -1,35 +0,0 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/asset.provider.dart';
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
import 'package:immich_mobile/providers/memory.provider.dart';
import 'package:immich_mobile/providers/server_info.provider.dart';
class TabNavigationObserver extends AutoRouterObserver {
/// Riverpod Instance
final WidgetRef ref;
TabNavigationObserver({
required this.ref,
});
@override
Future<void> didChangeTabRoute(
TabPageRoute route,
TabPageRoute previousRoute,
) async {
if (route.name == 'HomeRoute') {
ref.invalidate(memoryFutureProvider);
Future(() => ref.read(assetProvider.notifier).getAllAsset());
// Update user info
try {
ref.read(userServiceProvider).refreshMyUser();
ref.read(serverInfoProvider.notifier).getServerVersion();
} catch (e) {
debugPrint("Error refreshing user info $e");
}
}
}
}

View file

@ -3,6 +3,7 @@ import 'dart:async';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/domain/interfaces/exif.interface.dart'; import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
import 'package:immich_mobile/domain/interfaces/user.interface.dart'; import 'package:immich_mobile/domain/interfaces/user.interface.dart';
import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/domain/models/user.model.dart';
@ -239,6 +240,9 @@ class AssetService {
for (var element in assets) { for (var element in assets) {
element.isArchived = isArchived; element.isArchived = isArchived;
element.visibility = isArchived
? AssetVisibilityEnum.archive
: AssetVisibilityEnum.timeline;
} }
await _syncService.upsertAssetsWithExif(assets); await _syncService.upsertAssetsWithExif(assets);
@ -458,6 +462,7 @@ class AssetService {
bool shouldDeletePermanently = false, bool shouldDeletePermanently = false,
}) async { }) async {
final candidates = assets.where((a) => a.isRemote); final candidates = assets.where((a) => a.isRemote);
if (candidates.isEmpty) { if (candidates.isEmpty) {
return; return;
} }
@ -475,6 +480,7 @@ class AssetService {
.where((asset) => asset.storage == AssetState.merged) .where((asset) => asset.storage == AssetState.merged)
.map((asset) { .map((asset) {
asset.remoteId = null; asset.remoteId = null;
asset.visibility = AssetVisibilityEnum.timeline;
return asset; return asset;
}) })
: assets.where((asset) => asset.isRemote).map((asset) { : assets.where((asset) => asset.isRemote).map((asset) {
@ -529,4 +535,21 @@ class AssetService {
final me = _userService.getMyUser(); final me = _userService.getMyUser();
return _assetRepository.getMotionAssets(me.id); return _assetRepository.getMotionAssets(me.id);
} }
Future<void> setVisibility(
List<Asset> assets,
AssetVisibilityEnum visibility,
) async {
await _assetApiRepository.updateVisibility(
assets.map((asset) => asset.remoteId!).toList(),
visibility,
);
final updatedAssets = assets.map((asset) {
asset.visibility = visibility;
return asset;
}).toList();
await _assetRepository.updateAll(updatedAssets);
}
} }

View file

@ -201,4 +201,16 @@ class AuthService {
return null; return null;
} }
Future<bool> unlockPinCode(String pinCode) {
return _authApiRepository.unlockPinCode(pinCode);
}
Future<void> lockPinCode() {
return _authApiRepository.lockPinCode();
}
Future<void> setupPinCode(String pinCode) {
return _authApiRepository.setupPinCode(pinCode);
}
} }

View file

@ -0,0 +1,26 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/interfaces/biometric.interface.dart';
import 'package:immich_mobile/models/auth/biometric_status.model.dart';
import 'package:immich_mobile/repositories/biometric.repository.dart';
final localAuthServiceProvider = Provider(
(ref) => LocalAuthService(
ref.watch(biometricRepositoryProvider),
),
);
class LocalAuthService {
// final _log = Logger("LocalAuthService");
final IBiometricRepository _biometricRepository;
LocalAuthService(this._biometricRepository);
Future<BiometricStatus> getStatus() {
return _biometricRepository.getStatus();
}
Future<bool> authenticate([String? message]) async {
return _biometricRepository.authenticate(message);
}
}

View file

@ -1,10 +1,10 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/interfaces/asset.interface.dart'; import 'package:immich_mobile/interfaces/asset.interface.dart';
import 'package:immich_mobile/models/memories/memory.model.dart'; import 'package:immich_mobile/models/memories/memory.model.dart';
import 'package:immich_mobile/providers/api.provider.dart'; import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/repositories/asset.repository.dart'; import 'package:immich_mobile/repositories/asset.repository.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/utils/translation.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
final memoryServiceProvider = StateProvider<MemoryService>((ref) { final memoryServiceProvider = StateProvider<MemoryService>((ref) {
@ -40,10 +40,7 @@ class MemoryService {
.getAllByRemoteId(memory.assets.map((e) => e.id)); .getAllByRemoteId(memory.assets.map((e) => e.id));
final yearsAgo = now.year - memory.data.year; final yearsAgo = now.year - memory.data.year;
if (dbAssets.isNotEmpty) { if (dbAssets.isNotEmpty) {
final String title = yearsAgo <= 1 final String title = t('years_ago', {'years': yearsAgo.toString()});
? 'memories_year_ago'.tr()
: 'memories_years_ago'
.tr(namedArgs: {'years': yearsAgo.toString()});
memories.add( memories.add(
Memory( Memory(
title: title, title: title,

View file

@ -0,0 +1,29 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/interfaces/secure_storage.interface.dart';
import 'package:immich_mobile/repositories/secure_storage.repository.dart';
final secureStorageServiceProvider = Provider(
(ref) => SecureStorageService(
ref.watch(secureStorageRepositoryProvider),
),
);
class SecureStorageService {
// final _log = Logger("LocalAuthService");
final ISecureStorageRepository _secureStorageRepository;
SecureStorageService(this._secureStorageRepository);
Future<void> write(String key, String value) async {
await _secureStorageRepository.write(key, value);
}
Future<void> delete(String key) async {
await _secureStorageRepository.delete(key);
}
Future<String?> read(String key) async {
return _secureStorageRepository.read(key);
}
}

View file

@ -105,4 +105,13 @@ class TimelineService {
return GroupAssetsBy return GroupAssetsBy
.values[_appSettingsService.getSetting(AppSettingsEnum.groupAssetsBy)]; .values[_appSettingsService.getSetting(AppSettingsEnum.groupAssetsBy)];
} }
Stream<RenderList> watchLockedTimelineProvider() async* {
final user = _userService.getMyUser();
yield* _timelineRepository.watchLockedTimeline(
user.id,
_getGroupByOption(),
);
}
} }

View file

@ -42,7 +42,7 @@ ThemeData getThemeData({
titleTextStyle: TextStyle( titleTextStyle: TextStyle(
color: colorScheme.primary, color: colorScheme.primary,
fontFamily: _getFontFamilyFromLocale(locale), fontFamily: _getFontFamilyFromLocale(locale),
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
fontSize: 18, fontSize: 18,
), ),
backgroundColor: backgroundColor:
@ -54,28 +54,28 @@ ThemeData getThemeData({
), ),
textTheme: const TextTheme( textTheme: const TextTheme(
displayLarge: TextStyle( displayLarge: TextStyle(
fontSize: 26, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
displayMedium: TextStyle( displayMedium: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
displaySmall: TextStyle( displaySmall: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
titleSmall: TextStyle( titleSmall: TextStyle(
fontSize: 16.0, fontSize: 16.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
titleMedium: TextStyle( titleMedium: TextStyle(
fontSize: 18.0, fontSize: 18.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
titleLarge: TextStyle( titleLarge: TextStyle(
fontSize: 26.0, fontSize: 26.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
), ),
), ),
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(

View file

@ -20,7 +20,7 @@ import 'package:isar/isar.dart';
// ignore: import_rule_photo_manager // ignore: import_rule_photo_manager
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
const int targetVersion = 10; const int targetVersion = 11;
Future<void> migrateDatabaseIfNeeded(Isar db) async { Future<void> migrateDatabaseIfNeeded(Isar db) async {
final int version = Store.get(StoreKey.version, targetVersion); final int version = Store.get(StoreKey.version, targetVersion);

View file

@ -29,7 +29,11 @@ dynamic upgradeDto(dynamic value, String targetType) {
case 'UserResponseDto': case 'UserResponseDto':
if (value is Map) { if (value is Map) {
addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String()); addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String());
addDefault(value, 'visibility', AssetVisibility.timeline); }
break;
case 'AssetResponseDto':
if (value is Map) {
addDefault(value, 'visibility', 'timeline');
} }
break; break;
case 'UserAdminResponseDto': case 'UserAdminResponseDto':

View file

@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/asset_extensions.dart'; import 'package:immich_mobile/extensions/asset_extensions.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
@ -157,3 +158,29 @@ Future<void> handleEditLocation(
ref.read(assetServiceProvider).changeLocation(selection.toList(), location); ref.read(assetServiceProvider).changeLocation(selection.toList(), location);
} }
Future<void> handleSetAssetsVisibility(
WidgetRef ref,
BuildContext context,
AssetVisibilityEnum visibility,
List<Asset> selection, {
ToastGravity toastGravity = ToastGravity.BOTTOM,
}) async {
if (selection.isNotEmpty) {
await ref
.watch(assetProvider.notifier)
.setLockedView(selection, visibility);
final assetOrAssets = selection.length > 1 ? 'assets' : 'asset';
final toastMessage = visibility == AssetVisibilityEnum.locked
? 'Added ${selection.length} $assetOrAssets to locked folder'
: 'Removed ${selection.length} $assetOrAssets from locked folder';
if (context.mounted) {
ImmichToast.show(
context: context,
msg: toastMessage,
gravity: ToastGravity.BOTTOM,
);
}
}
}

View file

@ -6,6 +6,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/album/album.provider.dart'; import 'package:immich_mobile/providers/album/album.provider.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
import 'package:immich_mobile/widgets/album/add_to_album_sliverlist.dart'; import 'package:immich_mobile/widgets/album/add_to_album_sliverlist.dart';
import 'package:immich_mobile/models/asset_selection_state.dart'; import 'package:immich_mobile/models/asset_selection_state.dart';
import 'package:immich_mobile/widgets/asset_grid/delete_dialog.dart'; import 'package:immich_mobile/widgets/asset_grid/delete_dialog.dart';
@ -37,6 +38,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
final void Function()? onEditTime; final void Function()? onEditTime;
final void Function()? onEditLocation; final void Function()? onEditLocation;
final void Function()? onRemoveFromAlbum; final void Function()? onRemoveFromAlbum;
final void Function()? onToggleLocked;
final bool enabled; final bool enabled;
final bool unfavorite; final bool unfavorite;
@ -58,6 +60,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
this.onEditTime, this.onEditTime,
this.onEditLocation, this.onEditLocation,
this.onRemoveFromAlbum, this.onRemoveFromAlbum,
this.onToggleLocked,
this.selectionAssetState = const AssetSelectionState(), this.selectionAssetState = const AssetSelectionState(),
this.enabled = true, this.enabled = true,
this.unarchive = false, this.unarchive = false,
@ -77,6 +80,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
ref.watch(albumProvider).where((a) => a.shared).toList(); ref.watch(albumProvider).where((a) => a.shared).toList();
const bottomPadding = 0.20; const bottomPadding = 0.20;
final scrollController = useDraggableScrollController(); final scrollController = useDraggableScrollController();
final isInLockedView = ref.watch(inLockedViewProvider);
void minimize() { void minimize() {
scrollController.animateTo( scrollController.animateTo(
@ -133,11 +137,12 @@ class ControlBottomAppBar extends HookConsumerWidget {
label: "share".tr(), label: "share".tr(),
onPressed: enabled ? () => onShare(true) : null, onPressed: enabled ? () => onShare(true) : null,
), ),
ControlBoxButton( if (!isInLockedView)
iconData: Icons.link_rounded, ControlBoxButton(
label: "control_bottom_app_bar_share_link".tr(), iconData: Icons.link_rounded,
onPressed: enabled ? () => onShare(false) : null, label: "share_link".tr(),
), onPressed: enabled ? () => onShare(false) : null,
),
if (hasRemote && onArchive != null) if (hasRemote && onArchive != null)
ControlBoxButton( ControlBoxButton(
iconData: iconData:
@ -153,7 +158,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
label: (unfavorite ? "unfavorite" : "favorite").tr(), label: (unfavorite ? "unfavorite" : "favorite").tr(),
onPressed: enabled ? onFavorite : null, onPressed: enabled ? onFavorite : null,
), ),
if (hasLocal && hasRemote && onDelete != null) if (hasLocal && hasRemote && onDelete != null && !isInLockedView)
ConstrainedBox( ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 90), constraints: const BoxConstraints(maxWidth: 90),
child: ControlBoxButton( child: ControlBoxButton(
@ -166,7 +171,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
enabled ? () => showForceDeleteDialog(onDelete!) : null, enabled ? () => showForceDeleteDialog(onDelete!) : null,
), ),
), ),
if (hasRemote && onDeleteServer != null) if (hasRemote && onDeleteServer != null && !isInLockedView)
ConstrainedBox( ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 85), constraints: const BoxConstraints(maxWidth: 85),
child: ControlBoxButton( child: ControlBoxButton(
@ -189,9 +194,23 @@ class ControlBottomAppBar extends HookConsumerWidget {
: null, : null,
), ),
), ),
if (hasLocal && onDeleteLocal != null) if (isInLockedView)
ConstrainedBox( ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 85), constraints: const BoxConstraints(maxWidth: 110),
child: ControlBoxButton(
iconData: Icons.delete_forever,
label: "delete_dialog_title".tr(),
onPressed: enabled
? () => showForceDeleteDialog(
onDeleteServer!,
alertMsg: "delete_dialog_alert_remote",
)
: null,
),
),
if (hasLocal && onDeleteLocal != null && !isInLockedView)
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 95),
child: ControlBoxButton( child: ControlBoxButton(
iconData: Icons.no_cell_outlined, iconData: Icons.no_cell_outlined,
label: "control_bottom_app_bar_delete_from_local".tr(), label: "control_bottom_app_bar_delete_from_local".tr(),
@ -231,6 +250,19 @@ class ControlBottomAppBar extends HookConsumerWidget {
onPressed: enabled ? onEditLocation : null, onPressed: enabled ? onEditLocation : null,
), ),
), ),
if (hasRemote)
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: ControlBoxButton(
iconData: isInLockedView
? Icons.lock_open_rounded
: Icons.lock_outline_rounded,
label: isInLockedView
? "remove_from_locked_folder".tr()
: "move_to_locked_folder".tr(),
onPressed: enabled ? onToggleLocked : null,
),
),
if (!selectionAssetState.hasLocal && if (!selectionAssetState.hasLocal &&
selectionAssetState.selectedCount > 1 && selectionAssetState.selectedCount > 1 &&
onStack != null) onStack != null)
@ -269,20 +301,40 @@ class ControlBottomAppBar extends HookConsumerWidget {
]; ];
} }
getInitialSize() {
if (isInLockedView) {
return 0.20;
}
if (hasRemote) {
return 0.35;
}
return bottomPadding;
}
getMaxChildSize() {
if (isInLockedView) {
return 0.20;
}
if (hasRemote) {
return 0.65;
}
return bottomPadding;
}
return DraggableScrollableSheet( return DraggableScrollableSheet(
controller: scrollController, controller: scrollController,
initialChildSize: hasRemote ? 0.35 : bottomPadding, initialChildSize: getInitialSize(),
minChildSize: bottomPadding, minChildSize: bottomPadding,
maxChildSize: hasRemote ? 0.65 : bottomPadding, maxChildSize: getMaxChildSize(),
snap: true, snap: true,
builder: ( builder: (
BuildContext context, BuildContext context,
ScrollController scrollController, ScrollController scrollController,
) { ) {
return Card( return Card(
color: context.colorScheme.surfaceContainerLow, color: context.colorScheme.surfaceContainerHigh,
surfaceTintColor: Colors.transparent, surfaceTintColor: context.colorScheme.surfaceContainerHigh,
elevation: 18.0, elevation: 6.0,
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(12), topLeft: Radius.circular(12),
@ -300,27 +352,27 @@ class ControlBottomAppBar extends HookConsumerWidget {
const CustomDraggingHandle(), const CustomDraggingHandle(),
const SizedBox(height: 12), const SizedBox(height: 12),
SizedBox( SizedBox(
height: 100, height: 120,
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
children: renderActionButtons(), children: renderActionButtons(),
), ),
), ),
if (hasRemote) if (hasRemote && !isInLockedView) ...[
const Divider( const Divider(
indent: 16, indent: 16,
endIndent: 16, endIndent: 16,
thickness: 1, thickness: 1,
), ),
if (hasRemote)
_AddToAlbumTitleRow( _AddToAlbumTitleRow(
onCreateNewAlbum: enabled ? onCreateNewAlbum : null, onCreateNewAlbum: enabled ? onCreateNewAlbum : null,
), ),
],
], ],
), ),
), ),
if (hasRemote) if (hasRemote && !isInLockedView)
SliverPadding( SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
sliver: AddToAlbumSliverList( sliver: AddToAlbumSliverList(
@ -352,12 +404,9 @@ class _AddToAlbumTitleRow extends StatelessWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Text(
"add_to_album", "add_to_album",
style: TextStyle( style: context.textTheme.titleSmall,
fontSize: 14,
fontWeight: FontWeight.bold,
),
).tr(), ).tr(),
TextButton.icon( TextButton.icon(
onPressed: onCreateNewAlbum, onPressed: onCreateNewAlbum,

View file

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/entities/album.entity.dart'; import 'package:immich_mobile/entities/album.entity.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:immich_mobile/extensions/collection_extensions.dart';
@ -15,6 +16,7 @@ import 'package:immich_mobile/providers/album/album.provider.dart';
import 'package:immich_mobile/providers/asset.provider.dart'; import 'package:immich_mobile/providers/asset.provider.dart';
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart'; import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
import 'package:immich_mobile/providers/multiselect.provider.dart'; import 'package:immich_mobile/providers/multiselect.provider.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/services/album.service.dart'; import 'package:immich_mobile/services/album.service.dart';
@ -395,6 +397,32 @@ class MultiselectGrid extends HookConsumerWidget {
} }
} }
void onToggleLockedVisibility() async {
processing.value = true;
try {
final remoteAssets = ownedRemoteSelection(
localErrorMessage: 'home_page_locked_error_local'.tr(),
ownerErrorMessage: 'home_page_locked_error_partner'.tr(),
);
if (remoteAssets.isNotEmpty) {
final isInLockedView = ref.read(inLockedViewProvider);
final visibility = isInLockedView
? AssetVisibilityEnum.timeline
: AssetVisibilityEnum.locked;
await handleSetAssetsVisibility(
ref,
context,
visibility,
remoteAssets.toList(),
);
}
} finally {
processing.value = false;
selectionEnabledHook.value = false;
}
}
Future<T> Function() wrapLongRunningFun<T>( Future<T> Function() wrapLongRunningFun<T>(
Future<T> Function() fun, { Future<T> Function() fun, {
bool showOverlay = true, bool showOverlay = true,
@ -460,6 +488,7 @@ class MultiselectGrid extends HookConsumerWidget {
onEditLocation: editEnabled ? onEditLocation : null, onEditLocation: editEnabled ? onEditLocation : null,
unfavorite: unfavorite, unfavorite: unfavorite,
unarchive: unarchive, unarchive: unarchive,
onToggleLocked: onToggleLockedVisibility,
onRemoveFromAlbum: onRemoveFromAlbum != null onRemoveFromAlbum: onRemoveFromAlbum != null
? wrapLongRunningFun( ? wrapLongRunningFun(
() => onRemoveFromAlbum!(selection.value), () => onRemoveFromAlbum!(selection.value),

View file

@ -15,6 +15,7 @@ import 'package:immich_mobile/providers/asset_viewer/asset_stack.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/download.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/download.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
@ -46,6 +47,7 @@ class BottomGalleryBar extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final isInLockedView = ref.watch(inLockedViewProvider);
final asset = ref.watch(currentAssetProvider); final asset = ref.watch(currentAssetProvider);
if (asset == null) { if (asset == null) {
return const SizedBox(); return const SizedBox();
@ -277,7 +279,7 @@ class BottomGalleryBar extends ConsumerWidget {
tooltip: 'share'.tr(), tooltip: 'share'.tr(),
): (_) => shareAsset(), ): (_) => shareAsset(),
}, },
if (asset.isImage) if (asset.isImage && !isInLockedView)
{ {
BottomNavigationBarItem( BottomNavigationBarItem(
icon: const Icon(Icons.tune_outlined), icon: const Icon(Icons.tune_outlined),
@ -285,7 +287,7 @@ class BottomGalleryBar extends ConsumerWidget {
tooltip: 'edit'.tr(), tooltip: 'edit'.tr(),
): (_) => handleEdit(), ): (_) => handleEdit(),
}, },
if (isOwner) if (isOwner && !isInLockedView)
{ {
asset.isArchived asset.isArchived
? BottomNavigationBarItem( ? BottomNavigationBarItem(
@ -299,7 +301,7 @@ class BottomGalleryBar extends ConsumerWidget {
tooltip: 'archive'.tr(), tooltip: 'archive'.tr(),
): (_) => handleArchive(), ): (_) => handleArchive(),
}, },
if (isOwner && asset.stackCount > 0) if (isOwner && asset.stackCount > 0 && !isInLockedView)
{ {
BottomNavigationBarItem( BottomNavigationBarItem(
icon: const Icon(Icons.burst_mode_outlined), icon: const Icon(Icons.burst_mode_outlined),

View file

@ -5,6 +5,7 @@ import 'package:immich_mobile/providers/activity_statistics.provider.dart';
import 'package:immich_mobile/providers/album/current_album.provider.dart'; import 'package:immich_mobile/providers/album/current_album.provider.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/providers/asset.provider.dart'; import 'package:immich_mobile/providers/asset.provider.dart';
import 'package:immich_mobile/providers/routes.provider.dart';
import 'package:immich_mobile/providers/tab.provider.dart'; import 'package:immich_mobile/providers/tab.provider.dart';
import 'package:immich_mobile/widgets/asset_viewer/motion_photo_button.dart'; import 'package:immich_mobile/widgets/asset_viewer/motion_photo_button.dart';
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
@ -39,6 +40,7 @@ class TopControlAppBar extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final isInLockedView = ref.watch(inLockedViewProvider);
const double iconSize = 22.0; const double iconSize = 22.0;
final a = ref.watch(assetWatcher(asset)).value ?? asset; final a = ref.watch(assetWatcher(asset)).value ?? asset;
final album = ref.watch(currentAlbumProvider); final album = ref.watch(currentAlbumProvider);
@ -178,15 +180,22 @@ class TopControlAppBar extends HookConsumerWidget {
shape: const Border(), shape: const Border(),
actions: [ actions: [
if (asset.isRemote && isOwner) buildFavoriteButton(a), if (asset.isRemote && isOwner) buildFavoriteButton(a),
if (isOwner && !isInHomePage && !(isInTrash ?? false)) if (isOwner &&
!isInHomePage &&
!(isInTrash ?? false) &&
!isInLockedView)
buildLocateButton(), buildLocateButton(),
if (asset.livePhotoVideoId != null) const MotionPhotoButton(), if (asset.livePhotoVideoId != null) const MotionPhotoButton(),
if (asset.isLocal && !asset.isRemote) buildUploadButton(), if (asset.isLocal && !asset.isRemote) buildUploadButton(),
if (asset.isRemote && !asset.isLocal && isOwner) buildDownloadButton(), if (asset.isRemote && !asset.isLocal && isOwner) buildDownloadButton(),
if (asset.isRemote && (isOwner || isPartner) && !asset.isTrashed) if (asset.isRemote &&
(isOwner || isPartner) &&
!asset.isTrashed &&
!isInLockedView)
buildAddToAlbumButton(), buildAddToAlbumButton(),
if (asset.isTrashed) buildRestoreButton(), if (asset.isTrashed) buildRestoreButton(),
if (album != null && album.shared) buildActivitiesButton(), if (album != null && album.shared && !isInLockedView)
buildActivitiesButton(),
buildMoreInfoButton(), buildMoreInfoButton(),
], ],
); );

View file

@ -35,7 +35,9 @@ class ControlBoxButton extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialButton( return MaterialButton(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(10),
shape: const CircleBorder(), shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
onPressed: onPressed, onPressed: onPressed,
onLongPress: onLongPressed, onLongPress: onLongPressed,
minWidth: 75.0, minWidth: 75.0,
@ -47,8 +49,8 @@ class ControlBoxButton extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
label, label,
style: const TextStyle(fontSize: 12.0), style: const TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400),
maxLines: 2, maxLines: 3,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],

View file

@ -40,7 +40,7 @@ class ImmichToast {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0), padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0), borderRadius: const BorderRadius.all(Radius.circular(16.0)),
color: context.colorScheme.surfaceContainer, color: context.colorScheme.surfaceContainer,
border: Border.all( border: Border.all(
color: context.colorScheme.outline.withValues(alpha: .5), color: context.colorScheme.outline.withValues(alpha: .5),
@ -59,14 +59,23 @@ class ImmichToast {
msg, msg,
style: TextStyle( style: TextStyle(
color: getColor(toastType, context), color: getColor(toastType, context),
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
fontSize: 15, fontSize: 14,
), ),
), ),
), ),
], ],
), ),
), ),
positionedToastBuilder: (context, child, gravity) {
return Positioned(
top: gravity == ToastGravity.TOP ? 150 : null,
bottom: gravity == ToastGravity.BOTTOM ? 150 : null,
left: MediaQuery.of(context).size.width / 2 - 150,
right: MediaQuery.of(context).size.width / 2 - 150,
child: child,
);
},
gravity: gravity, gravity: gravity,
toastDuration: Duration(seconds: durationInSecond), toastDuration: Duration(seconds: durationInSecond),
); );

View file

@ -0,0 +1,124 @@
import 'package:flutter/material.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:pinput/pinput.dart';
class PinInput extends StatelessWidget {
final Function(String)? onCompleted;
final Function(String)? onChanged;
final int? length;
final bool? obscureText;
final bool? autoFocus;
final bool? hasError;
final String? label;
final TextEditingController? controller;
const PinInput({
super.key,
this.onCompleted,
this.onChanged,
this.length,
this.obscureText,
this.autoFocus,
this.hasError,
this.label,
this.controller,
});
@override
Widget build(BuildContext context) {
getPinSize() {
final minimumPadding = 18.0;
final gapWidth = 3.0;
final screenWidth = context.width;
final pinWidth =
(screenWidth - (minimumPadding * 2) - (gapWidth * 5)) / (length ?? 6);
if (pinWidth > 60) {
return const Size(60, 64);
}
final pinHeight = pinWidth / (60 / 64);
return Size(pinWidth, pinHeight);
}
final defaultPinTheme = PinTheme(
width: getPinSize().width,
height: getPinSize().height,
textStyle: TextStyle(
fontSize: 24,
color: context.colorScheme.onSurface,
fontFamily: 'Overpass Mono',
),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(19)),
border: Border.all(color: context.colorScheme.surfaceBright),
color: context.colorScheme.surfaceContainerHigh,
),
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (label != null) ...[
Text(
label!,
style: context.textTheme.displayLarge
?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)),
),
const SizedBox(height: 4),
],
Pinput(
controller: controller,
forceErrorState: hasError ?? false,
autofocus: autoFocus ?? false,
obscureText: obscureText ?? false,
obscuringWidget: Icon(
Icons.vpn_key_rounded,
color: context.primaryColor,
size: 20,
),
separatorBuilder: (index) => const SizedBox(
height: 64,
width: 3,
),
cursor: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
margin: const EdgeInsets.only(bottom: 9),
width: 18,
height: 2,
color: context.primaryColor,
),
],
),
defaultPinTheme: defaultPinTheme,
focusedPinTheme: defaultPinTheme.copyWith(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(19)),
border: Border.all(
color: context.primaryColor.withValues(alpha: 0.5),
width: 2,
),
color: context.colorScheme.surfaceContainerHigh,
),
),
errorPinTheme: defaultPinTheme.copyWith(
decoration: BoxDecoration(
color: context.colorScheme.error.withAlpha(15),
borderRadius: const BorderRadius.all(Radius.circular(19)),
border: Border.all(
color: context.colorScheme.error.withAlpha(100),
width: 2,
),
),
),
pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,
length: length ?? 6,
onChanged: onChanged,
onCompleted: onCompleted,
),
],
);
}
}

View file

@ -0,0 +1,128 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/widgets/forms/pin_input.dart';
class PinRegistrationForm extends HookConsumerWidget {
final Function() onDone;
const PinRegistrationForm({
super.key,
required this.onDone,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final hasError = useState(false);
final newPinCodeController = useTextEditingController();
final confirmPinCodeController = useTextEditingController();
bool validatePinCode() {
if (confirmPinCodeController.text.length != 6) {
return false;
}
if (newPinCodeController.text != confirmPinCodeController.text) {
return false;
}
return true;
}
createNewPinCode() async {
final isValid = validatePinCode();
if (!isValid) {
hasError.value = true;
return;
}
try {
await ref.read(authProvider.notifier).setupPinCode(
newPinCodeController.text,
);
onDone();
} catch (error) {
hasError.value = true;
context.showSnackBar(
SnackBar(content: Text(error.toString())),
);
}
}
return Form(
child: Column(
children: [
Icon(
Icons.pin_outlined,
size: 64,
color: context.primaryColor,
),
const SizedBox(height: 32),
SizedBox(
width: context.width * 0.7,
child: Text(
'setup_pin_code'.tr(),
style: context.textTheme.labelLarge!.copyWith(
fontSize: 24,
),
textAlign: TextAlign.center,
),
),
SizedBox(
width: context.width * 0.8,
child: Text(
'new_pin_code_subtitle'.tr(),
style: context.textTheme.bodyLarge!.copyWith(
fontSize: 16,
),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 32),
PinInput(
controller: newPinCodeController,
label: 'new_pin_code'.tr(),
length: 6,
autoFocus: true,
hasError: hasError.value,
onChanged: (input) {
if (input.length < 6) {
hasError.value = false;
}
},
),
const SizedBox(height: 32),
PinInput(
controller: confirmPinCodeController,
label: 'confirm_new_pin_code'.tr(),
length: 6,
hasError: hasError.value,
onChanged: (input) {
if (input.length < 6) {
hasError.value = false;
}
},
),
const SizedBox(height: 48),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: createNewPinCode,
child: Text('create'.tr()),
),
),
],
),
),
],
),
);
}
}

View file

@ -0,0 +1,94 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/widgets/forms/pin_input.dart';
class PinVerificationForm extends HookConsumerWidget {
final Function(String) onSuccess;
final VoidCallback? onError;
final bool? autoFocus;
final String? description;
final IconData? icon;
final IconData? successIcon;
const PinVerificationForm({
super.key,
required this.onSuccess,
this.onError,
this.autoFocus,
this.description,
this.icon,
this.successIcon,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final hasError = useState(false);
final isVerified = useState(false);
verifyPin(String pinCode) async {
final isUnlocked =
await ref.read(authProvider.notifier).unlockPinCode(pinCode);
if (isUnlocked) {
isVerified.value = true;
await Future.delayed(const Duration(seconds: 1));
onSuccess(pinCode);
} else {
hasError.value = true;
onError?.call();
}
}
return Form(
child: Column(
children: [
AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
child: isVerified.value
? Icon(
successIcon ?? Icons.lock_open_rounded,
size: 64,
color: Colors.green[300],
)
: Icon(
icon ?? Icons.lock_outline_rounded,
size: 64,
color: hasError.value
? context.colorScheme.error
: context.primaryColor,
),
),
const SizedBox(height: 36),
SizedBox(
width: context.width * 0.7,
child: Text(
description ?? 'enter_your_pin_code_subtitle'.tr(),
style: context.textTheme.labelLarge!.copyWith(
fontSize: 18,
),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 18),
PinInput(
obscureText: true,
autoFocus: autoFocus,
hasError: hasError.value,
length: 6,
onChanged: (pinCode) {
if (pinCode.length < 6) {
hasError.value = false;
}
},
onCompleted: verifyPin,
),
],
),
);
}
}

View file

@ -133,7 +133,7 @@ class AssetResponseDto {
DateTime updatedAt; DateTime updatedAt;
AssetResponseDtoVisibilityEnum visibility; AssetVisibility visibility;
@override @override
bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto && bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto &&
@ -318,7 +318,7 @@ class AssetResponseDto {
type: AssetTypeEnum.fromJson(json[r'type'])!, type: AssetTypeEnum.fromJson(json[r'type'])!,
unassignedFaces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'unassignedFaces']), unassignedFaces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'unassignedFaces']),
updatedAt: mapDateTime(json, r'updatedAt', r'')!, updatedAt: mapDateTime(json, r'updatedAt', r'')!,
visibility: AssetResponseDtoVisibilityEnum.fromJson(json[r'visibility'])!, visibility: AssetVisibility.fromJson(json[r'visibility'])!,
); );
} }
return null; return null;
@ -389,83 +389,3 @@ class AssetResponseDto {
}; };
} }
class AssetResponseDtoVisibilityEnum {
/// Instantiate a new enum with the provided [value].
const AssetResponseDtoVisibilityEnum._(this.value);
/// The underlying value of this enum member.
final String value;
@override
String toString() => value;
String toJson() => value;
static const archive = AssetResponseDtoVisibilityEnum._(r'archive');
static const timeline = AssetResponseDtoVisibilityEnum._(r'timeline');
static const hidden = AssetResponseDtoVisibilityEnum._(r'hidden');
static const locked = AssetResponseDtoVisibilityEnum._(r'locked');
/// List of all possible values in this [enum][AssetResponseDtoVisibilityEnum].
static const values = <AssetResponseDtoVisibilityEnum>[
archive,
timeline,
hidden,
locked,
];
static AssetResponseDtoVisibilityEnum? fromJson(dynamic value) => AssetResponseDtoVisibilityEnumTypeTransformer().decode(value);
static List<AssetResponseDtoVisibilityEnum> listFromJson(dynamic json, {bool growable = false,}) {
final result = <AssetResponseDtoVisibilityEnum>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = AssetResponseDtoVisibilityEnum.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
}
/// Transformation class that can [encode] an instance of [AssetResponseDtoVisibilityEnum] to String,
/// and [decode] dynamic data back to [AssetResponseDtoVisibilityEnum].
class AssetResponseDtoVisibilityEnumTypeTransformer {
factory AssetResponseDtoVisibilityEnumTypeTransformer() => _instance ??= const AssetResponseDtoVisibilityEnumTypeTransformer._();
const AssetResponseDtoVisibilityEnumTypeTransformer._();
String encode(AssetResponseDtoVisibilityEnum data) => data.value;
/// Decodes a [dynamic value][data] to a AssetResponseDtoVisibilityEnum.
///
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
///
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
/// and users are still using an old app with the old code.
AssetResponseDtoVisibilityEnum? decode(dynamic data, {bool allowNull = true}) {
if (data != null) {
switch (data) {
case r'archive': return AssetResponseDtoVisibilityEnum.archive;
case r'timeline': return AssetResponseDtoVisibilityEnum.timeline;
case r'hidden': return AssetResponseDtoVisibilityEnum.hidden;
case r'locked': return AssetResponseDtoVisibilityEnum.locked;
default:
if (!allowNull) {
throw ArgumentError('Unknown enum value to decode: $data');
}
}
}
return null;
}
/// Singleton [AssetResponseDtoVisibilityEnumTypeTransformer] instance.
static AssetResponseDtoVisibilityEnumTypeTransformer? _instance;
}

View file

@ -621,6 +621,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.1" version: "2.6.1"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
url: "https://pub.dev"
source: hosted
version: "9.2.4"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
url: "https://pub.dev"
source: hosted
version: "1.2.3"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
url: "https://pub.dev"
source: hosted
version: "3.1.3"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
url: "https://pub.dev"
source: hosted
version: "1.2.1"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
url: "https://pub.dev"
source: hosted
version: "3.1.2"
flutter_svg: flutter_svg:
dependency: "direct main" dependency: "direct main"
description: description:
@ -976,6 +1024,46 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.1" version: "5.1.1"
local_auth:
dependency: "direct main"
description:
name: local_auth
sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
local_auth_android:
dependency: transitive
description:
name: local_auth_android
sha256: "63ad7ca6396290626dc0cb34725a939e4cfe965d80d36112f08d49cf13a8136e"
url: "https://pub.dev"
source: hosted
version: "1.0.49"
local_auth_darwin:
dependency: transitive
description:
name: local_auth_darwin
sha256: "630996cd7b7f28f5ab92432c4b35d055dd03a747bc319e5ffbb3c4806a3e50d2"
url: "https://pub.dev"
source: hosted
version: "1.4.3"
local_auth_platform_interface:
dependency: transitive
description:
name: local_auth_platform_interface
sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a"
url: "https://pub.dev"
source: hosted
version: "1.0.10"
local_auth_windows:
dependency: transitive
description:
name: local_auth_windows
sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5
url: "https://pub.dev"
source: hosted
version: "1.0.11"
logging: logging:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1264,6 +1352,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.0"
pinput:
dependency: "direct main"
description:
name: pinput
sha256: "8a73be426a91fefec90a7f130763ca39772d547e92f19a827cf4aa02e323d35a"
url: "https://pub.dev"
source: hosted
version: "5.0.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -1741,6 +1837,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
universal_platform:
dependency: transitive
description:
name: universal_platform
sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -64,6 +64,9 @@ dependencies:
uuid: ^4.5.1 uuid: ^4.5.1
wakelock_plus: ^1.2.10 wakelock_plus: ^1.2.10
worker_manager: ^7.2.3 worker_manager: ^7.2.3
local_auth: ^2.3.0
pinput: ^5.0.1
flutter_secure_storage: ^9.2.4
native_video_player: native_video_player:
git: git:

View file

@ -9366,13 +9366,11 @@
"type": "string" "type": "string"
}, },
"visibility": { "visibility": {
"enum": [ "allOf": [
"archive", {
"timeline", "$ref": "#/components/schemas/AssetVisibility"
"hidden", }
"locked" ]
],
"type": "string"
} }
}, },
"required": [ "required": [

View file

@ -1 +1 @@
22.15.0 22.15.1

View file

@ -12,7 +12,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@ -23,9 +23,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.15.17", "version": "22.15.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==", "integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View file

@ -19,7 +19,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"repository": { "repository": {
@ -28,6 +28,6 @@
"directory": "open-api/typescript-sdk" "directory": "open-api/typescript-sdk"
}, },
"volta": { "volta": {
"node": "22.15.0" "node": "22.15.1"
} }
} }

View file

@ -329,7 +329,7 @@ export type AssetResponseDto = {
"type": AssetTypeEnum; "type": AssetTypeEnum;
unassignedFaces?: AssetFaceWithoutPersonResponseDto[]; unassignedFaces?: AssetFaceWithoutPersonResponseDto[];
updatedAt: string; updatedAt: string;
visibility: Visibility; visibility: AssetVisibility;
}; };
export type AlbumResponseDto = { export type AlbumResponseDto = {
albumName: string; albumName: string;
@ -3697,12 +3697,6 @@ export enum AssetTypeEnum {
Audio = "AUDIO", Audio = "AUDIO",
Other = "OTHER" Other = "OTHER"
} }
export enum Visibility {
Archive = "archive",
Timeline = "timeline",
Hidden = "hidden",
Locked = "locked"
}
export enum AssetOrder { export enum AssetOrder {
Asc = "asc", Asc = "asc",
Desc = "desc" Desc = "desc"

View file

@ -1 +1 @@
22.15.0 22.15.1

View file

@ -92,7 +92,7 @@
"@types/lodash": "^4.14.197", "@types/lodash": "^4.14.197",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/multer": "^1.4.7", "@types/multer": "^1.4.7",
"@types/node": "^22.15.16", "@types/node": "^22.15.18",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/picomatch": "^4.0.0", "@types/picomatch": "^4.0.0",
"@types/pngjs": "^6.0.5", "@types/pngjs": "^6.0.5",
@ -5439,9 +5439,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.15.17", "version": "22.15.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==", "integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.21.0" "undici-types": "~6.21.0"

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