mirror of
https://github.com/immich-app/immich.git
synced 2025-06-10 21:38:30 +02:00
Merge branch 'main' into feat/duplicates-grid-view
This commit is contained in:
commit
0496c69ccf
145 changed files with 2626 additions and 4919 deletions
.github
cli
docker
docs
e2e
i18n
az.jsonbi.jsonen.jsonfa.jsonfil.jsonhi.jsonhy.jsonka.jsonkmr.jsonlt.jsonlv.jsonmn.jsonta.jsonth.json
mobile
android/app/src/main
ios
lib
constants
entities
interfaces
asset_api.interface.dartauth_api.interface.dartbiometric.interface.dartsecure_storage.interface.darttimeline.interface.dart
main.dartmodels/auth
pages/library
providers
asset.provider.dartauth.provider.dartlocal_auth.provider.dartroutes.provider.dartsecure_storage.provider.darttimeline.provider.dart
repositories
asset_api.repository.dartauth_api.repository.dartbiometric.repository.dartsecure_storage.repository.darttimeline.repository.dart
routing
services
asset.service.dartauth.service.dartlocal_auth.service.dartmemory.service.dartsecure_storage.service.darttimeline.service.dart
theme
utils
widgets
openapi/lib/model
pubspec.lockpubspec.yamlopen-api
server
2
.github/.nvmrc
vendored
2
.github/.nvmrc
vendored
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
2
.github/actions/image-build/action.yml
vendored
2
.github/actions/image-build/action.yml
vendored
|
@ -84,7 +84,7 @@ runs:
|
|||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
||||
with:
|
||||
context: ${{ inputs.context }}
|
||||
file: ${{ inputs.dockerfile }}
|
||||
|
|
2
.github/workflows/cli.yml
vendored
2
.github/workflows/cli.yml
vendored
|
@ -96,7 +96,7 @@ jobs:
|
|||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
||||
with:
|
||||
file: cli/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
|
6
.github/workflows/docs-deploy.yml
vendored
6
.github/workflows/docs-deploy.yml
vendored
|
@ -150,7 +150,7 @@ jobs:
|
|||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
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:
|
||||
tg_version: '0.58.12'
|
||||
tofu_version: '1.7.1'
|
||||
|
@ -165,7 +165,7 @@ jobs:
|
|||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
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:
|
||||
tg_version: '0.58.12'
|
||||
tofu_version: '1.7.1'
|
||||
|
@ -199,7 +199,7 @@ jobs:
|
|||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
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:
|
||||
tg_version: '0.58.12'
|
||||
tofu_version: '1.7.1'
|
||||
|
|
2
.github/workflows/docs-destroy.yml
vendored
2
.github/workflows/docs-destroy.yml
vendored
|
@ -25,7 +25,7 @@ jobs:
|
|||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
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:
|
||||
tg_version: '0.58.12'
|
||||
tofu_version: '1.7.1'
|
||||
|
|
2
.github/workflows/multi-runner-build.yml
vendored
2
.github/workflows/multi-runner-build.yml
vendored
|
@ -115,7 +115,7 @@ jobs:
|
|||
packages: write
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: ${{ needs.matrix.outputs.key }}-*
|
||||
|
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -643,7 +643,7 @@ jobs:
|
|||
contents: read
|
||||
services:
|
||||
postgres:
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
image: ghcr.io/immich-app/postgres:14@sha256:14bec5d02e8704081eafd566029204a4eb6bb75f3056cfb34e81c5ab1657a490
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
10
cli/package-lock.json
generated
10
cli/package-lock.json
generated
|
@ -27,7 +27,7 @@
|
|||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/micromatch": "^4.0.9",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
"byte-size": "^9.0.0",
|
||||
"cli-progress": "^3.12.0",
|
||||
|
@ -61,7 +61,7 @@
|
|||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
|
@ -1372,9 +1372,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.15.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
|
||||
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
|
||||
"version": "22.15.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
|
||||
"integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/micromatch": "^4.0.9",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
"byte-size": "^9.0.0",
|
||||
"cli-progress": "^3.12.0",
|
||||
|
@ -69,6 +69,6 @@
|
|||
"micromatch": "^4.0.8"
|
||||
},
|
||||
"volta": {
|
||||
"node": "22.15.0"
|
||||
"node": "22.15.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ services:
|
|||
|
||||
database:
|
||||
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
|
||||
environment:
|
||||
|
@ -134,24 +134,6 @@ services:
|
|||
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 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
|
||||
# immich-prometheus:
|
||||
|
|
|
@ -63,7 +63,7 @@ services:
|
|||
|
||||
database:
|
||||
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
|
||||
environment:
|
||||
|
@ -75,24 +75,6 @@ services:
|
|||
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 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
|
||||
|
||||
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
||||
|
@ -100,7 +82,7 @@ services:
|
|||
container_name: immich_prometheus
|
||||
ports:
|
||||
- 9090:9090
|
||||
image: prom/prometheus@sha256:e2b8aa62b64855956e3ec1e18b4f9387fb6203174a4471936f4662f437f04405
|
||||
image: prom/prometheus@sha256:78ed1f9050eb9eaf766af6e580230b1c4965728650e332cd1ee918c0c4699775
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- prometheus-data:/prometheus
|
||||
|
|
|
@ -56,7 +56,7 @@ services:
|
|||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
POSTGRES_USER: ${DB_USERNAME}
|
||||
|
@ -65,24 +65,8 @@ services:
|
|||
volumes:
|
||||
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
|
||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: >-
|
||||
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
|
||||
Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
|
||||
--command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
|
||||
echo "checksum failure count is $$Chksum";
|
||||
[ "$$Chksum" = '0' ] || exit 1
|
||||
interval: 5m
|
||||
start_interval: 30s
|
||||
start_period: 5m
|
||||
command: >-
|
||||
postgres
|
||||
-c shared_preload_libraries=vectors.so
|
||||
-c 'search_path="$$user", public, vectors'
|
||||
-c logging_collector=on
|
||||
-c max_wal_size=2GB
|
||||
-c shared_buffers=512MB
|
||||
-c wal_compression=on
|
||||
# change ssd below to hdd if you are using a hard disk drive or other slow storage
|
||||
command: postgres -c config_file=/etc/postgresql/postgresql.ssd.conf
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
|
@ -10,12 +10,12 @@ Running with a pre-existing Postgres server can unlock powerful administrative f
|
|||
|
||||
## 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
|
||||
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
|
||||
|
@ -53,16 +53,75 @@ CREATE DATABASE <immichdatabasename>;
|
|||
\c <immichdatabasename>
|
||||
BEGIN;
|
||||
ALTER DATABASE <immichdatabasename> OWNER TO <immichdbusername>;
|
||||
CREATE EXTENSION vectors;
|
||||
CREATE EXTENSION vchord CASCADE;
|
||||
CREATE EXTENSION earthdistance CASCADE;
|
||||
ALTER DATABASE <immichdatabasename> SET search_path TO "$user", public, vectors;
|
||||
ALTER SCHEMA vectors OWNER TO <immichdbusername>;
|
||||
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
|
||||
|
||||
|
@ -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>;`.
|
||||
|
||||
[vectors-install]: https://docs.vectorchord.ai/getting-started/installation.html
|
||||
[vchord-install]: https://docs.vectorchord.ai/vectorchord/getting-started/installation.html
|
||||
|
|
|
@ -5,7 +5,7 @@ import TabItem from '@theme/TabItem';
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -72,21 +72,21 @@ Information on the current workers can be found [here](/docs/administration/jobs
|
|||
|
||||
## Database
|
||||
|
||||
| Variable | Description | Default | Containers |
|
||||
| :---------------------------------- | :----------------------------------------------------------------------- | :----------: | :----------------------------- |
|
||||
| `DB_URL` | Database URL | | server |
|
||||
| `DB_HOSTNAME` | Database host | `database` | server |
|
||||
| `DB_PORT` | Database port | `5432` | server |
|
||||
| `DB_USERNAME` | Database user | `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_SSL_MODE` | Database SSL mode | | server |
|
||||
| `DB_VECTOR_EXTENSION`<sup>\*2</sup> | Database vector extension (one of [`pgvector`, `pgvecto.rs`]) | `pgvecto.rs` | server |
|
||||
| `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server |
|
||||
| Variable | Description | Default | Containers |
|
||||
| :---------------------------------- | :--------------------------------------------------------------------------- | :--------: | :----------------------------- |
|
||||
| `DB_URL` | Database URL | | server |
|
||||
| `DB_HOSTNAME` | Database host | `database` | server |
|
||||
| `DB_PORT` | Database port | `5432` | server |
|
||||
| `DB_USERNAME` | Database user | `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_SSL_MODE` | Database SSL mode | | 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 |
|
||||
|
||||
\*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
|
||||
|
||||
|
|
|
@ -57,6 +57,6 @@
|
|||
"node": ">=20"
|
||||
},
|
||||
"volta": {
|
||||
"node": "22.15.0"
|
||||
"node": "22.15.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
|
@ -37,8 +37,8 @@ services:
|
|||
image: redis:6.2-alpine@sha256:3211c33a618c457e5d241922c975dbc4f446d0bdb2dc75694f5573ef8e2d01fa
|
||||
|
||||
database:
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
|
||||
command: -c fsync=off -c shared_preload_libraries=vectors.so
|
||||
image: ghcr.io/immich-app/postgres:14
|
||||
command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
|
|
12
e2e/package-lock.json
generated
12
e2e/package-lock.json
generated
|
@ -15,7 +15,7 @@
|
|||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@types/oidc-provider": "^8.5.1",
|
||||
"@types/pg": "^8.15.1",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/micromatch": "^4.0.9",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
"byte-size": "^9.0.0",
|
||||
"cli-progress": "^3.12.0",
|
||||
|
@ -100,7 +100,7 @@
|
|||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
|
@ -1593,9 +1593,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.15.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
|
||||
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
|
||||
"version": "22.15.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
|
||||
"integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@types/oidc-provider": "^8.5.1",
|
||||
"@types/pg": "^8.15.1",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
|
@ -52,6 +52,6 @@
|
|||
"vitest": "^3.0.0"
|
||||
},
|
||||
"volta": {
|
||||
"node": "22.15.0"
|
||||
"node": "22.15.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
"library_watching_settings_description": "Dəyişdirilən faylları avtomatik olaraq yoxla",
|
||||
"logging_enable_description": "Jurnalı aktivləşdir",
|
||||
"logging_level_description": "Aktiv edildikdə hansı jurnal səviyyəsi istifadə olunur.",
|
||||
"logging_settings": "",
|
||||
"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_duplicate_detection": "Dublikat Aşkarlama",
|
||||
|
|
844
i18n/bi.json
844
i18n/bi.json
|
@ -3,8 +3,6 @@
|
|||
"account": "Akaont",
|
||||
"account_settings": "Seting blo Akaont",
|
||||
"acknowledge": "Akcept",
|
||||
"action": "",
|
||||
"actions": "",
|
||||
"active": "Stap Mekem",
|
||||
"activity": "Wanem hemi Mekem",
|
||||
"activity_changed": "WAnem hemi Mekem hemi",
|
||||
|
@ -16,845 +14,5 @@
|
|||
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
|
||||
"add_import_path": "Putem wan pat blo import",
|
||||
"add_location": "Putem wan place blo hem",
|
||||
"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": ""
|
||||
"add_more_users": "Putem mor man"
|
||||
}
|
||||
|
|
13
i18n/en.json
13
i18n/en.json
|
@ -564,6 +564,10 @@
|
|||
"backup_options_page_title": "Backup options",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"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_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.",
|
||||
"blurred_background": "Blurred background",
|
||||
|
@ -825,6 +829,7 @@
|
|||
"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!",
|
||||
"enable": "Enable",
|
||||
"enable_biometric_auth_description": "Enter your PIN code to enable biometric authentication",
|
||||
"enabled": "Enabled",
|
||||
"end_date": "End date",
|
||||
"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",
|
||||
"face_unassigned": "Unassigned",
|
||||
"failed": "Failed",
|
||||
"failed_to_authenticate": "Failed to authenticate",
|
||||
"failed_to_load_assets": "Failed to load assets",
|
||||
"failed_to_load_folder": "Failed to load folder",
|
||||
"favorite": "Favorite",
|
||||
|
@ -1064,6 +1070,8 @@
|
|||
"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_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_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
|
||||
"host": "Host",
|
||||
|
@ -1231,8 +1239,6 @@
|
|||
"memories_setting_description": "Manage what you see in your memories",
|
||||
"memories_start_over": "Start Over",
|
||||
"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_lane_title": "Memory Lane {title}",
|
||||
"menu": "Menu",
|
||||
|
@ -1404,6 +1410,7 @@
|
|||
"play_memories": "Play memories",
|
||||
"play_motion_photo": "Play Motion Photo",
|
||||
"play_or_pause_video": "Play or pause video",
|
||||
"please_auth_to_access": "Please authenticate to access",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Preferences",
|
||||
|
@ -1665,6 +1672,7 @@
|
|||
"share_add_photos": "Add photos",
|
||||
"share_assets_selected": "{count} selected",
|
||||
"share_dialog_preparing": "Preparing...",
|
||||
"share_link": "Share Link",
|
||||
"shared": "Shared",
|
||||
"shared_album_activities_input_disable": "Comment is disabled",
|
||||
"shared_album_activity_remove_content": "Do you want to delete this activity?",
|
||||
|
@ -1888,6 +1896,7 @@
|
|||
"uploading": "Uploading",
|
||||
"url": "URL",
|
||||
"usage": "Usage",
|
||||
"use_biometric": "Use biometric",
|
||||
"use_current_connection": "use current connection",
|
||||
"use_custom_date_range": "Use custom date range instead",
|
||||
"user": "User",
|
||||
|
|
183
i18n/fa.json
183
i18n/fa.json
|
@ -65,8 +65,6 @@
|
|||
"job_settings": "تنظیمات کار",
|
||||
"job_settings_description": "مدیریت همزمانی کار",
|
||||
"job_status": "وضعیت کار",
|
||||
"jobs_delayed": "",
|
||||
"jobs_failed": "",
|
||||
"library_created": "کتابخانه ایجاد شده: {library}",
|
||||
"library_deleted": "کتابخانه حذف شد",
|
||||
"library_import_path_description": "یک پوشه برای وارد کردن مشخص کنید. این پوشه، به همراه زیرپوشهها، برای یافتن تصاویر و ویدیوها اسکن خواهد شد.",
|
||||
|
@ -128,7 +126,6 @@
|
|||
"metadata_extraction_job": "استخراج فرا داده",
|
||||
"metadata_extraction_job_description": "استخراج اطلاعات ابرداده، مانند موقعیت جغرافیایی و کیفیت از هر فایل",
|
||||
"migration_job": "مهاجرت",
|
||||
"migration_job_description": "",
|
||||
"no_paths_added": "هیچ مسیری اضافه نشده",
|
||||
"no_pattern_added": "هیچ الگوی اضافه نشده",
|
||||
"note_apply_storage_label_previous_assets": "توجه: برای اعمال برچسب ذخیره سازی به دارایی هایی که قبلاً بارگذاری شده اند، دستور زیر را اجرا کنید",
|
||||
|
@ -178,8 +175,6 @@
|
|||
"registration": "ثبت نام مدیر",
|
||||
"registration_description": "از آنجایی که شما اولین کاربر در سیستم هستید، به عنوان مدیر تعیین شدهاید و مسئولیت انجام وظایف مدیریتی بر عهده شما خواهد بود و کاربران اضافی توسط شما ایجاد خواهند شد.",
|
||||
"repair_all": "بازسازی همه",
|
||||
"repair_matched_items": "",
|
||||
"repaired_items": "",
|
||||
"require_password_change_on_login": "الزام کاربر به تغییر گذرواژه در اولین ورود",
|
||||
"reset_settings_to_default": "بازنشانی تنظیمات به حالت پیشفرض",
|
||||
"reset_settings_to_recent_saved": "بازنشانی تنظیمات به آخرین تنظیمات ذخیره شده",
|
||||
|
@ -196,7 +191,6 @@
|
|||
"smart_search_job_description": "اجرای یادگیری ماشینی بر روی داراییها برای پشتیبانی از جستجوی هوشمند",
|
||||
"storage_template_date_time_description": "زمانبندی ایجاد دارایی برای اطلاعات تاریخ و زمان استفاده میشود",
|
||||
"storage_template_date_time_sample": "نمونه زمان {date}",
|
||||
"storage_template_enable_description": "",
|
||||
"storage_template_hash_verification_enabled": "تأیید هَش فعال شد",
|
||||
"storage_template_hash_verification_enabled_description": "تأیید هَش را فعال میکند؛ این گزینه را غیرفعال نکنید مگر اینکه از عواقب آن مطمئن باشید",
|
||||
"storage_template_migration": "انتقال الگوی ذخیره سازی",
|
||||
|
@ -242,7 +236,6 @@
|
|||
"transcoding_hardware_acceleration": "شتاب دهنده سخت افزاری",
|
||||
"transcoding_hardware_acceleration_description": "آزمایشی؛ بسیار سریعتر است، اما در همان بیتریت کیفیت کمتری خواهد داشت",
|
||||
"transcoding_hardware_decoding": "رمزگشایی سخت افزاری",
|
||||
"transcoding_hardware_decoding_setting_description": "",
|
||||
"transcoding_hevc_codec": "کدک HEVC",
|
||||
"transcoding_max_b_frames": "بیشترین B-frames",
|
||||
"transcoding_max_b_frames_description": "مقادیر بالاتر کارایی فشرده سازی را بهبود میبخشند، اما کدگذاری را کند میکنند. ممکن است با شتاب دهی سختافزاری در دستگاههای قدیمی سازگار نباشد. مقدار( 0 ) B-frames را غیرفعال میکند، در حالی که مقدار ( 1 ) این مقدار را به صورت خودکار تنظیم میکند.",
|
||||
|
@ -266,7 +259,6 @@
|
|||
"transcoding_temporal_aq_description": "این مورد فقط برای NVENC اعمال می شود. افزایش کیفیت در صحنه های با جزئیات بالا و حرکت کم. ممکن است با دستگاه های قدیمی تر سازگار نباشد.",
|
||||
"transcoding_threads": "رشته ها ( موضوعات )",
|
||||
"transcoding_threads_description": "مقادیر بالاتر منجر به رمزگذاری سریع تر می شود، اما فضای کمتری برای پردازش سایر وظایف سرور در حین فعالیت باقی می گذارد. این مقدار نباید بیشتر از تعداد هسته های CPU باشد. اگر روی 0 تنظیم شود، بیشترین استفاده را خواهد داشت.",
|
||||
"transcoding_tone_mapping": "",
|
||||
"transcoding_tone_mapping_description": "تلاش برای حفظ ظاهر ویدیوهای HDR هنگام تبدیل به SDR. هر الگوریتم تعادل های متفاوتی را برای رنگ، جزئیات و روشنایی ایجاد می کند. Hable جزئیات را حفظ می کند، Mobius رنگ را حفظ می کند و Reinhard روشنایی را حفظ می کند.",
|
||||
"transcoding_transcode_policy": "سیاست رمزگذاری",
|
||||
"transcoding_transcode_policy_description": "سیاست برای زمانی که ویدیویی باید مجددا تبدیل (رمزگذاری) شود. ویدیوهای HDR همیشه تبدیل (رمزگذاری) مجدد خواهند شد (مگر رمزگذاری مجدد غیرفعال باشد).",
|
||||
|
@ -306,15 +298,12 @@
|
|||
"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": "اجازه دادن به حالت تاریک",
|
||||
|
@ -324,18 +313,13 @@
|
|||
"app_settings": "تنظیمات برنامه",
|
||||
"appears_in": "ظاهر میشود در",
|
||||
"archive": "بایگانی",
|
||||
"archive_or_unarchive_photo": "",
|
||||
"archive_size": "اندازه بایگانی",
|
||||
"archive_size_description": "",
|
||||
"asset_offline": "محتوا آفلاین",
|
||||
"assets": "محتواها",
|
||||
"authorized_devices": "دستگاههای مجاز",
|
||||
"back": "بازگشت",
|
||||
"backward": "عقب",
|
||||
"blurred_background": "پسزمینه محو",
|
||||
"bulk_delete_duplicates_confirmation": "",
|
||||
"bulk_keep_duplicates_confirmation": "",
|
||||
"bulk_trash_duplicates_confirmation": "",
|
||||
"camera": "دوربین",
|
||||
"camera_brand": "برند دوربین",
|
||||
"camera_model": "مدل دوربین",
|
||||
|
@ -350,10 +334,8 @@
|
|||
"change_name_successfully": "نام با موفقیت تغییر یافت",
|
||||
"change_password": "تغییر رمز عبور",
|
||||
"change_your_password": "رمز عبور خود را تغییر دهید",
|
||||
"changed_visibility_successfully": "",
|
||||
"check_all": "انتخاب همه",
|
||||
"check_logs": "بررسی لاگها",
|
||||
"choose_matching_people_to_merge": "",
|
||||
"city": "شهر",
|
||||
"clear": "پاک کردن",
|
||||
"clear_all": "پاک کردن همه",
|
||||
|
@ -366,7 +348,6 @@
|
|||
"comments_are_disabled": "نظرات غیرفعال هستند",
|
||||
"confirm": "تأیید",
|
||||
"confirm_admin_password": "تأیید رمز عبور مدیر",
|
||||
"confirm_delete_shared_link": "",
|
||||
"confirm_password": "تأیید رمز عبور",
|
||||
"contain": "شامل",
|
||||
"context": "زمینه",
|
||||
|
@ -393,8 +374,6 @@
|
|||
"create_user": "ایجاد کاربر",
|
||||
"created": "ایجاد شد",
|
||||
"current_device": "دستگاه فعلی",
|
||||
"custom_locale": "",
|
||||
"custom_locale_description": "",
|
||||
"dark": "تاریک",
|
||||
"date_after": "تاریخ پس از",
|
||||
"date_and_time": "تاریخ و زمان",
|
||||
|
@ -402,12 +381,8 @@
|
|||
"date_range": "بازه زمانی",
|
||||
"day": "روز",
|
||||
"deduplicate_all": "حذف تکراریها به صورت کامل",
|
||||
"default_locale": "",
|
||||
"default_locale_description": "",
|
||||
"delete": "حذف",
|
||||
"delete_album": "حذف آلبوم",
|
||||
"delete_api_key_prompt": "",
|
||||
"delete_duplicates_confirmation": "",
|
||||
"delete_key": "حذف کلید",
|
||||
"delete_library": "حذف کتابخانه",
|
||||
"delete_link": "حذف لینک",
|
||||
|
@ -425,14 +400,12 @@
|
|||
"display_options": "گزینههای نمایش",
|
||||
"display_order": "ترتیب نمایش",
|
||||
"display_original_photos": "نمایش عکسهای اصلی",
|
||||
"display_original_photos_setting_description": "",
|
||||
"done": "انجام شد",
|
||||
"download": "دانلود",
|
||||
"download_settings": "تنظیمات دانلود",
|
||||
"download_settings_description": "مدیریت تنظیمات مرتبط با دانلود محتوا",
|
||||
"downloading": "در حال دانلود",
|
||||
"duplicates": "تکراریها",
|
||||
"duplicates_description": "",
|
||||
"duration": "مدت زمان",
|
||||
"edit_album": "ویرایش آلبوم",
|
||||
"edit_avatar": "ویرایش آواتار",
|
||||
|
@ -440,8 +413,6 @@
|
|||
"edit_date_and_time": "ویرایش تاریخ و زمان",
|
||||
"edit_exclusion_pattern": "ویرایش الگوی استثناء",
|
||||
"edit_faces": "ویرایش چهرهها",
|
||||
"edit_import_path": "",
|
||||
"edit_import_paths": "",
|
||||
"edit_key": "ویرایش کلید",
|
||||
"edit_link": "ویرایش لینک",
|
||||
"edit_location": "ویرایش مکان",
|
||||
|
@ -456,73 +427,6 @@
|
|||
"end_date": "تاریخ پایان",
|
||||
"error": "خطا",
|
||||
"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": "خروج از نمایش اسلاید",
|
||||
"expand_all": "باز کردن همه",
|
||||
"expire_after": "منقضی شدن بعد از",
|
||||
|
@ -534,15 +438,12 @@
|
|||
"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": "عمومی",
|
||||
|
@ -562,19 +463,11 @@
|
|||
"immich_web_interface": "رابط وب Immich",
|
||||
"import_from_json": "وارد کردن از JSON",
|
||||
"import_path": "مسیر وارد کردن",
|
||||
"in_albums": "",
|
||||
"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": "وظایف",
|
||||
|
@ -601,28 +494,22 @@
|
|||
"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": "مدیریت کلیدهای API شما",
|
||||
"manage_your_devices": "مدیریت دستگاههای متصل",
|
||||
"manage_your_oauth_connection": "مدیریت اتصال OAuth شما",
|
||||
"map": "نقشه",
|
||||
"map_marker_with_image": "",
|
||||
"map_settings": "تنظیمات نقشه",
|
||||
"matches": "تطابقها",
|
||||
"media_type": "نوع رسانه",
|
||||
"memories": "خاطرات",
|
||||
"memories_setting_description": "",
|
||||
"memory": "خاطره",
|
||||
"menu": "منو",
|
||||
"merge": "ادغام",
|
||||
"merge_people": "ادغام افراد",
|
||||
"merge_people_limit": "",
|
||||
"merge_people_prompt": "",
|
||||
"merge_people_successfully": "ادغام افراد با موفقیت انجام شد",
|
||||
"minimize": "کوچک کردن",
|
||||
"minute": "دقیقه",
|
||||
|
@ -643,20 +530,12 @@
|
|||
"next": "بعدی",
|
||||
"next_memory": "خاطره بعدی",
|
||||
"no": "خیر",
|
||||
"no_albums_message": "",
|
||||
"no_archived_assets_message": "",
|
||||
"no_assets_message": "",
|
||||
"no_duplicates_found": "هیچ تکراری یافت نشد.",
|
||||
"no_exif_info_available": "اطلاعات EXIF موجود نیست",
|
||||
"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": "اعلانها",
|
||||
|
@ -664,7 +543,6 @@
|
|||
"oauth": "OAuth",
|
||||
"offline": "آفلاین",
|
||||
"offline_paths": "مسیرهای آفلاین",
|
||||
"offline_paths_description": "",
|
||||
"ok": "تأیید",
|
||||
"oldest_first": "قدیمیترین ابتدا",
|
||||
"online": "آنلاین",
|
||||
|
@ -679,7 +557,6 @@
|
|||
"owner": "مالک",
|
||||
"partner": "شریک",
|
||||
"partner_can_access": "{partner} میتواند دسترسی داشته باشد",
|
||||
"partner_can_access_assets": "",
|
||||
"partner_can_access_location": "مکانهایی که عکسهای شما گرفته شدهاند",
|
||||
"partner_sharing": "اشتراکگذاری با شریک",
|
||||
"partners": "شرکا",
|
||||
|
@ -687,11 +564,6 @@
|
|||
"password_does_not_match": "رمز عبور مطابقت ندارد",
|
||||
"password_required": "رمز عبور مورد نیاز است",
|
||||
"password_reset_success": "بازنشانی رمز عبور موفقیتآمیز بود",
|
||||
"past_durations": {
|
||||
"days": "",
|
||||
"hours": "",
|
||||
"years": ""
|
||||
},
|
||||
"path": "مسیر",
|
||||
"pattern": "الگو",
|
||||
"pause": "توقف",
|
||||
|
@ -699,14 +571,12 @@
|
|||
"paused": "متوقف شده",
|
||||
"pending": "در انتظار",
|
||||
"people": "افراد",
|
||||
"people_sidebar_description": "",
|
||||
"permanent_deletion_warning": "هشدار حذف دائمی",
|
||||
"permanent_deletion_warning_setting_description": "نمایش هشدار هنگام حذف دائمی محتواها",
|
||||
"permanently_delete": "حذف دائمی",
|
||||
"permanently_deleted_asset": "محتوای حذف شده دائمی",
|
||||
"person": "فرد",
|
||||
"photos": "عکسها",
|
||||
"photos_count": "",
|
||||
"photos_from_previous_years": "عکسهای سالهای گذشته",
|
||||
"pick_a_location": "یک مکان انتخاب کنید",
|
||||
"place": "مکان",
|
||||
|
@ -730,38 +600,27 @@
|
|||
"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": "",
|
||||
"resolved_all_duplicates": "",
|
||||
"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": "تنظیمات اسکن",
|
||||
"scanning_for_album": "",
|
||||
"search": "جستجو",
|
||||
"search_albums": "جستجوی آلبومها",
|
||||
"search_by_context": "جستجو براساس زمینه",
|
||||
|
@ -775,8 +634,6 @@
|
|||
"search_state": "جستجوی ایالت...",
|
||||
"search_timezone": "جستجوی منطقه زمانی...",
|
||||
"search_type": "نوع جستجو",
|
||||
"search_your_photos": "",
|
||||
"searching_locales": "",
|
||||
"second": "ثانیه",
|
||||
"select_album_cover": "انتخاب جلد آلبوم",
|
||||
"select_all": "انتخاب همه",
|
||||
|
@ -787,41 +644,28 @@
|
|||
"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": "عکسها از {partner}",
|
||||
"shared_links": "لینکهای اشتراکی",
|
||||
"shared_photos_and_videos_count": "",
|
||||
"shared_with_partner": "مشترک با {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": "تصادفی",
|
||||
|
@ -831,60 +675,39 @@
|
|||
"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": "به علاقهمندیها",
|
||||
"to_trash": "",
|
||||
"toggle_settings": "تغییر تنظیمات",
|
||||
"toggle_theme": "تغییر تم تاریک",
|
||||
"total_usage": "استفاده کلی",
|
||||
"trash": "سطل زباله",
|
||||
"trash_all": "",
|
||||
"trash_count": "",
|
||||
"trash_no_results_message": "",
|
||||
"trashed_items_will_be_permanently_deleted_after": "",
|
||||
"type": "نوع",
|
||||
"unarchive": "",
|
||||
"unfavorite": "حذف از علاقهمندیها",
|
||||
"unhide_person": "آشکار کردن فرد",
|
||||
"unknown": "ناشناخته",
|
||||
"unknown_year": "سال نامشخص",
|
||||
"unlimited": "نامحدود",
|
||||
"unlink_oauth": "لغو اتصال OAuth",
|
||||
"unlinked_oauth_account": "",
|
||||
"unnamed_album": "آلبوم بدون نام",
|
||||
"unnamed_share": "اشتراک بدون نام",
|
||||
"unselect_all": "لغو انتخاب همه",
|
||||
"unstack": "",
|
||||
"untracked_files": "",
|
||||
"untracked_files_decription": "",
|
||||
"up_next": "مورد بعدی",
|
||||
"updated_password": "",
|
||||
"upload": "آپلود",
|
||||
"upload_concurrency": "تعداد آپلود همزمان",
|
||||
"url": "آدرس",
|
||||
|
@ -898,12 +721,8 @@
|
|||
"validate": "اعتبارسنجی",
|
||||
"variables": "متغیرها",
|
||||
"version": "نسخه",
|
||||
"version_announcement_message": "",
|
||||
"video": "ویدیو",
|
||||
"video_hover_setting": "",
|
||||
"video_hover_setting_description": "",
|
||||
"videos": "ویدیوها",
|
||||
"videos_count": "",
|
||||
"view": "مشاهده",
|
||||
"view_all": "مشاهده همه",
|
||||
"view_all_users": "مشاهده همه کاربران",
|
||||
|
@ -913,9 +732,7 @@
|
|||
"waiting": "در انتظار",
|
||||
"week": "هفته",
|
||||
"welcome": "خوش آمدید",
|
||||
"welcome_to_immich": "",
|
||||
"year": "سال",
|
||||
"yes": "بله",
|
||||
"you_dont_have_any_shared_links": "",
|
||||
"zoom_image": "بزرگنمایی تصویر"
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
},
|
||||
"album_user_left": "Umalis sa {album}",
|
||||
"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.",
|
||||
"are_these_the_same_person": "Itong tao na ito ay parehas?",
|
||||
"asset_adding_to_album": "Dinadagdag sa album...",
|
||||
|
|
|
@ -689,7 +689,6 @@
|
|||
"edit_title": "शीर्षक संपादित करें",
|
||||
"edit_user": "यूजर को संपादित करो",
|
||||
"edited": "संपादित",
|
||||
"editor": "",
|
||||
"email": "ईमेल",
|
||||
"empty_folder": "This folder is empty",
|
||||
"empty_trash": "कूड़ेदान खाली करें",
|
||||
|
@ -922,7 +921,6 @@
|
|||
"info": "जानकारी",
|
||||
"interval": {
|
||||
"day_at_onepm": "हर दिन दोपहर 1 बजे",
|
||||
"hours": "",
|
||||
"night_at_midnight": "हर रात आधी रात को",
|
||||
"night_at_twoam": "हर रात 2 बजे"
|
||||
},
|
||||
|
@ -1142,11 +1140,6 @@
|
|||
"password_does_not_match": "पासवर्ड मैच नहीं कर रहा है",
|
||||
"password_required": "पासवर्ड आवश्यक",
|
||||
"password_reset_success": "पासवर्ड रीसेट सफल",
|
||||
"past_durations": {
|
||||
"days": "",
|
||||
"hours": "",
|
||||
"years": ""
|
||||
},
|
||||
"path": "पथ",
|
||||
"pattern": "नमूना",
|
||||
"pause": "विराम",
|
||||
|
|
832
i18n/hy.json
832
i18n/hy.json
|
@ -1,784 +1,52 @@
|
|||
{
|
||||
"about": "Մասին",
|
||||
"account": "",
|
||||
"account_settings": "",
|
||||
"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_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": "Հետ",
|
||||
"backup_all": "Բոլոր",
|
||||
"backup_controller_page_background_battery_info_link": "Ցույց տուր ինչպես",
|
||||
"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_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": "",
|
||||
"client_cert_dialog_msg_confirm": "Լավ",
|
||||
"close": "",
|
||||
"collapse_all": "",
|
||||
"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": "Փոխել Տեղը",
|
||||
"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": "ՍՏԵՂԾԵԼ ՆՈՐ",
|
||||
"create_new_person": "Ստեղծել նոր անձ",
|
||||
"create_new_user": "",
|
||||
"create_shared_album_page_share_select_photos": "Ընտրե Նկարներ",
|
||||
"create_user": "",
|
||||
"created": "",
|
||||
"curated_object_page_title": "Բաներ",
|
||||
"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": "",
|
||||
"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": "",
|
||||
"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_age": "Տարիք {}",
|
||||
"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})",
|
||||
"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_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_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_library": "Նայե",
|
||||
"scan_settings": "",
|
||||
"search": "Փնտրե",
|
||||
"search_albums": "",
|
||||
"search_by_context": "",
|
||||
"search_camera_make": "",
|
||||
"search_camera_model": "",
|
||||
"search_city": "Որոնե քաղաք…",
|
||||
"search_country": "",
|
||||
"search_filter_date": "Ամսաթիվ",
|
||||
"search_filter_date_interval": "{start} մինչեւ {end}",
|
||||
"search_filter_location": "Տեղ",
|
||||
"search_filter_location_title": "Ընտրե տեղ",
|
||||
"search_for_existing_person": "",
|
||||
"search_no_people": "Ոչ մի անձ",
|
||||
"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_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_seconds": "{} վայրկյան",
|
||||
"settings": "",
|
||||
"settings_saved": "",
|
||||
"share": "",
|
||||
"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_days": "{} օր",
|
||||
"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_months": "{} ամիս",
|
||||
"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_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": "Ժամային գոտի",
|
||||
"to_archive": "",
|
||||
"to_favorite": "",
|
||||
"to_trash": "Աղբ",
|
||||
"toggle_settings": "",
|
||||
"toggle_theme": "",
|
||||
"total_usage": "",
|
||||
"trash": "Աղբ",
|
||||
"trash_all": "",
|
||||
"trash_no_results_message": "",
|
||||
"trash_page_title": "Աղբ ({})",
|
||||
"trashed_items_will_be_permanently_deleted_after": "",
|
||||
"type": "Տեսակ",
|
||||
"unarchive": "",
|
||||
"unfavorite": "",
|
||||
"unhide_person": "",
|
||||
"unknown": "Անհայտ",
|
||||
"unknown_country": "Անհայտ Երկիր",
|
||||
"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": "Սխալներ",
|
||||
"url": "",
|
||||
"usage": "",
|
||||
"user": "",
|
||||
"user_id": "",
|
||||
"user_usage_detail": "",
|
||||
"username": "",
|
||||
"users": "",
|
||||
"utilities": "",
|
||||
"validate": "",
|
||||
"variables": "",
|
||||
"version": "",
|
||||
"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": "Շաբաթ",
|
||||
"welcome": "Բարի գալուստ",
|
||||
"welcome_to_immich": "",
|
||||
"year": "Տարի",
|
||||
"yes": "Այո",
|
||||
"you_dont_have_any_shared_links": "",
|
||||
"zoom_image": ""
|
||||
"yes": "Այո"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
"add_a_location": "დაამატე ადგილი",
|
||||
"add_a_name": "დაამატე სახელი",
|
||||
"add_a_title": "დაასათაურე",
|
||||
"add_endpoint": "",
|
||||
"add_exclusion_pattern": "დაამატე გამონაკლისი ნიმუში",
|
||||
"add_import_path": "დაამატე საიმპორტო მისამართი",
|
||||
"add_location": "დაამატე ადგილი",
|
||||
|
|
865
i18n/kmr.json
865
i18n/kmr.json
|
@ -2,868 +2,5 @@
|
|||
"about": "دەربارە",
|
||||
"account": "هەژمار",
|
||||
"account_settings": "ڕێکخستنی هەژمار",
|
||||
"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": ""
|
||||
"acknowledge": "دانپێدانان"
|
||||
}
|
||||
|
|
190
i18n/lt.json
190
i18n/lt.json
|
@ -71,9 +71,7 @@
|
|||
"image_format": "Formatas",
|
||||
"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_setting_description": "",
|
||||
"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_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",
|
||||
|
@ -109,22 +107,18 @@
|
|||
"machine_learning_clip_model": "CLIP modelis",
|
||||
"machine_learning_duplicate_detection": "Dublikatų aptikimas",
|
||||
"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_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_facial_recognition": "Veidų atpažinimas",
|
||||
"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_description": "",
|
||||
"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_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_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_description": "",
|
||||
"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_settings": "Mašininio mokymosi nustatymai",
|
||||
|
@ -158,7 +152,6 @@
|
|||
"metadata_settings": "Metaduomenų nustatymai",
|
||||
"metadata_settings_description": "Tvarkyti metaduomenų nustatymus",
|
||||
"migration_job": "Migracija",
|
||||
"migration_job_description": "",
|
||||
"no_paths_added": "Keliai nepridėti",
|
||||
"no_pattern_added": "Šablonas nepridėtas",
|
||||
"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_description": "Tvarkyti OAuth prisijungimo nustatymus",
|
||||
"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_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",
|
||||
|
@ -217,93 +204,42 @@
|
|||
"server_settings_description": "Tvarkyti serverio nustatymus",
|
||||
"server_welcome_message": "Sveikinimo pranešimas",
|
||||
"server_welcome_message_description": "Žinutė, rodoma prisijungimo puslapyje.",
|
||||
"sidecar_job_description": "",
|
||||
"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",
|
||||
"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",
|
||||
"tag_cleanup_job": "Žymų išvalymas",
|
||||
"theme_custom_css_settings": "Individualizuotas CSS",
|
||||
"theme_custom_css_settings_description": "",
|
||||
"theme_settings": "Temos nustatymai",
|
||||
"theme_settings_description": "",
|
||||
"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",
|
||||
"transcoding_acceleration_api": "Spartinimo API",
|
||||
"transcoding_acceleration_api_description": "",
|
||||
"transcoding_acceleration_nvenc": "NVENC (reikalinga NVIDIA GPU)",
|
||||
"transcoding_acceleration_qsv": "",
|
||||
"transcoding_acceleration_rkmpp": "",
|
||||
"transcoding_acceleration_vaapi": "VAAPI",
|
||||
"transcoding_accepted_audio_codecs": "",
|
||||
"transcoding_accepted_audio_codecs_description": "",
|
||||
"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_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_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_description": "",
|
||||
"transcoding_constant_rate_factor": "",
|
||||
"transcoding_constant_rate_factor_description": "",
|
||||
"transcoding_disabled_description": "",
|
||||
"transcoding_hardware_acceleration": "Techninės įrangos spartinimas",
|
||||
"transcoding_hardware_acceleration_description": "",
|
||||
"transcoding_hardware_decoding": "Aparatinis dekodavimas",
|
||||
"transcoding_hardware_decoding_setting_description": "",
|
||||
"transcoding_hevc_codec": "HEVC kodekas",
|
||||
"transcoding_max_b_frames": "",
|
||||
"transcoding_max_b_frames_description": "",
|
||||
"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_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_description": "",
|
||||
"trash_enabled_description": "Įgalinti šiukšliadėžės funkcijas",
|
||||
"trash_number_of_days": "Dienų skaičius",
|
||||
"trash_number_of_days_description": "",
|
||||
"trash_settings": "Šiukšliadėžės nustatymai",
|
||||
"trash_settings_description": "Tvarkyti šiukšliadėžės nustatymus",
|
||||
"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ą",
|
||||
"user_delete_delay_settings": "Ištrynimo delsa",
|
||||
"user_delete_delay_settings_description": "",
|
||||
"user_management": "Naudotojų valdymas",
|
||||
"user_password_has_been_reset": "Naudotojo slaptažodis buvo iš naujo nustatytas:",
|
||||
"user_restore_description": "Naudotojo <b>{user}</b> paskyra bus atkurta.",
|
||||
"user_settings": "Naudotojo nustatymai",
|
||||
"user_settings_description": "Valdyti naudotojo nustatymus",
|
||||
"user_successfully_removed": "Naudotojas {email} sėkmingai pašalintas.",
|
||||
"version_check_enabled_description": "",
|
||||
"version_check_settings": "Versijos tikrinimas",
|
||||
"version_check_settings_description": "Įjungti/išjungti naujos versijos pranešimus",
|
||||
"video_conversion_job": "Vaizdo įrašų konvertavimas",
|
||||
|
@ -312,7 +248,6 @@
|
|||
"admin_email": "Administratoriaus el. paštas",
|
||||
"admin_password": "Administratoriaus slaptažodis",
|
||||
"administration": "Administravimas",
|
||||
"advanced": "",
|
||||
"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_title": "Prefer remote images",
|
||||
|
@ -370,7 +305,6 @@
|
|||
"app_bar_signout_dialog_ok": "Yes",
|
||||
"app_bar_signout_dialog_title": "Sign out",
|
||||
"app_settings": "Programos nustatymai",
|
||||
"appears_in": "",
|
||||
"archive": "Archyvas",
|
||||
"archive_or_unarchive_photo": "Archyvuoti arba išarchyvuoti nuotrauką",
|
||||
"archive_page_no_archived_assets": "No archived assets found",
|
||||
|
@ -488,7 +422,6 @@
|
|||
"backup_manual_title": "Upload status",
|
||||
"backup_options_page_title": "Backup options",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"backward": "",
|
||||
"birthdate_saved": "Sėkmingai išsaugota gimimo data",
|
||||
"blurred_background": "Neryškus fonas",
|
||||
"bugs_and_feature_requests": "Klaidų ir funkcijų užklausos",
|
||||
|
@ -527,7 +460,6 @@
|
|||
"change_expiration_time": "Pakeisti galiojimo trukmę",
|
||||
"change_location": "Pakeisti vietovę",
|
||||
"change_name": "Pakeisti vardą",
|
||||
"change_name_successfully": "",
|
||||
"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_form_confirm_password": "Confirm Password",
|
||||
|
@ -570,7 +502,6 @@
|
|||
"confirm_admin_password": "Patvirtinti administratoriaus slaptažodį",
|
||||
"confirm_delete_shared_link": "Ar tikrai norite ištrinti šią bendrinimo nuorodą?",
|
||||
"confirm_password": "Patvirtinti slaptažodį",
|
||||
"contain": "",
|
||||
"context": "Kontekstas",
|
||||
"continue": "Tęsti",
|
||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
||||
|
@ -592,8 +523,6 @@
|
|||
"copy_password": "Kopijuoti slaptažodį",
|
||||
"copy_to_clipboard": "Kopijuoti į iškarpinę",
|
||||
"country": "Šalis",
|
||||
"cover": "",
|
||||
"covers": "",
|
||||
"create": "Sukurti",
|
||||
"create_album": "Sukurti albumą",
|
||||
"create_album_page_untitled": "Untitled",
|
||||
|
@ -615,24 +544,20 @@
|
|||
"curated_object_page_title": "Things",
|
||||
"current_device": "Dabartinis įrenginys",
|
||||
"current_server_address": "Current server address",
|
||||
"custom_locale": "",
|
||||
"custom_locale_description": "Formatuoti datas ir skaičius pagal kalbą ir regioną",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||
"dark": "",
|
||||
"date_after": "Data po",
|
||||
"date_and_time": "Data ir laikas",
|
||||
"date_before": "Data prieš",
|
||||
"date_format": "E, LLL d, y • h:mm a",
|
||||
"date_of_birth_saved": "Gimimo data sėkmingai išsaugota",
|
||||
"date_range": "",
|
||||
"day": "Diena",
|
||||
"deduplicate_all": "Šalinti visus dublikatus",
|
||||
"deduplication_criteria_1": "Failo dydis baitais",
|
||||
"deduplication_criteria_2": "EXIF metaduomenų įrašų skaičius",
|
||||
"deduplication_info": "Dublikatų šalinimo informacija",
|
||||
"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ę",
|
||||
"delete": "Ištrinti",
|
||||
"delete_album": "Ištrinti albumą",
|
||||
|
@ -665,13 +590,10 @@
|
|||
"discover": "Atrasti",
|
||||
"dismiss_all_errors": "Nepaisyti visų klaidų",
|
||||
"dismiss_error": "Nepaisyti klaidos",
|
||||
"display_options": "",
|
||||
"display_order": "Atvaizdavimo tvarka",
|
||||
"display_original_photos": "Rodyti originalias nuotraukas",
|
||||
"display_original_photos_setting_description": "",
|
||||
"do_not_show_again": "Daugiau nerodyti šio pranešimo",
|
||||
"documentation": "Dokumentacija",
|
||||
"done": "",
|
||||
"download": "Atsisiųsti",
|
||||
"download_canceled": "Download canceled",
|
||||
"download_complete": "Download complete",
|
||||
|
@ -711,7 +633,6 @@
|
|||
"edit_title": "Redaguoti antraštę",
|
||||
"edit_user": "Redaguoti naudotoją",
|
||||
"edited": "Redaguota",
|
||||
"editor": "",
|
||||
"email": "El. paštas",
|
||||
"empty_folder": "This folder is empty",
|
||||
"empty_trash": "Ištuštinti šiukšliadėžę",
|
||||
|
@ -763,56 +684,37 @@
|
|||
"unable_to_create_library": "Nepavyko sukurti bibliotekos",
|
||||
"unable_to_create_user": "Nepavyko sukurti naudotojo",
|
||||
"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_import_path": "Nepavyksta ištrinti importavimo kelio",
|
||||
"unable_to_delete_shared_link": "Nepavyko ištrinti bendrinimo nuorodos",
|
||||
"unable_to_delete_user": "Nepavyksta ištrinti naudotojo",
|
||||
"unable_to_edit_exclusion_pattern": "Nepavyksta redaguoti išimčių šablono",
|
||||
"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_exit_fullscreen": "Nepavyksta išeiti iš viso ekrano režimo",
|
||||
"unable_to_get_shared_link": "Nepavyko gauti bendrinimo nuorodos",
|
||||
"unable_to_hide_person": "Nepavyksta paslėpti žmogaus",
|
||||
"unable_to_link_oauth_account": "Nepavyko susieti su OAuth paskyra",
|
||||
"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_device": "Nepavyksta atjungti įrenginio",
|
||||
"unable_to_login_with_oauth": "Nepavyko prisijungti su OAuth",
|
||||
"unable_to_play_video": "Nepavyksta paleisti vaizdo įrašo",
|
||||
"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_assets_from_shared_link": "Nepavyko iš bendrinimo nuorodos pašalinti elementų",
|
||||
"unable_to_remove_deleted_assets": "Nepavyko pašalinti nepasiekiamų elementų",
|
||||
"unable_to_remove_library": "Nepavyksta pašalinti bibliotekos",
|
||||
"unable_to_remove_partner": "Nepavyksta pašalinti partnerio",
|
||||
"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_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_settings": "Nepavyksta išsaugoti nustatymų",
|
||||
"unable_to_scan_libraries": "Nepavyksta nuskaityti bibliotekų",
|
||||
"unable_to_scan_library": "Nepavyksta nuskaityti bibliotekos",
|
||||
"unable_to_set_feature_photo": "Nepavyksta nustatyti mėgstamiausios nuotraukos",
|
||||
"unable_to_set_profile_picture": "Nepavyksta nustatyti profilio nuotraukos",
|
||||
"unable_to_submit_job": "",
|
||||
"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"
|
||||
},
|
||||
"exif": "Exif",
|
||||
|
@ -831,7 +733,6 @@
|
|||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||
"experimental_settings_subtitle": "Use at your own risk!",
|
||||
"experimental_settings_title": "Experimental",
|
||||
"expire_after": "",
|
||||
"expired": "Nebegalioja",
|
||||
"expires_date": "Nebegalios už {date}",
|
||||
"explore": "Naršyti",
|
||||
|
@ -850,27 +751,19 @@
|
|||
"favorite_or_unfavorite_photo": "Įtraukti prie arba pašalinti iš mėgstamiausių",
|
||||
"favorites": "Mėgstamiausi",
|
||||
"favorites_page_no_favorites": "No favorite assets found",
|
||||
"feature_photo_updated": "",
|
||||
"features": "Funkcijos",
|
||||
"features_setting_description": "Valdyti aplikacijos funkcijas",
|
||||
"file_name": "Failo pavadinimas",
|
||||
"file_name_or_extension": "Failo pavadinimas arba plėtinys",
|
||||
"filename": "",
|
||||
"filetype": "Failo tipas",
|
||||
"filter": "Filter",
|
||||
"filter_people": "Filtruoti žmones",
|
||||
"fix_incorrect_match": "",
|
||||
"folder": "Folder",
|
||||
"folder_not_found": "Folder not found",
|
||||
"folders": "Aplankai",
|
||||
"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_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",
|
||||
"group_albums_by": "Grupuoti albumus pagal...",
|
||||
"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_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",
|
||||
"host": "",
|
||||
"hour": "Valanda",
|
||||
"ignore_icloud_photos": "Ignore iCloud photos",
|
||||
"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_shared_albums": "Įtraukti bendrinamus albumus",
|
||||
"include_shared_partner_assets": "Įtraukti partnerio pasidalintus elementus",
|
||||
"individual_share": "",
|
||||
"info": "Informacija",
|
||||
"interval": {
|
||||
"day_at_onepm": "Kiekvieną dieną 13:00",
|
||||
"hours": "",
|
||||
"night_at_midnight": "Kiekvieną vidurnaktį",
|
||||
"night_at_twoam": "Kiekvieną naktį 02:00"
|
||||
},
|
||||
|
@ -955,7 +845,6 @@
|
|||
"library_page_sort_created": "Created date",
|
||||
"library_page_sort_last_modified": "Last modified",
|
||||
"library_page_sort_title": "Album title",
|
||||
"light": "",
|
||||
"link_options": "Nuorodų parinktys",
|
||||
"link_to_oauth": "Susieti su OAuth",
|
||||
"linked_oauth_account": "Susieta OAuth paskyra",
|
||||
|
@ -1000,9 +889,7 @@
|
|||
"logout_all_device_confirmation": "Ar tikrai norite atsijungti iš visų įrenginių?",
|
||||
"logout_this_device_confirmation": "Ar tikrai norite atsijungti iš šio prietaiso?",
|
||||
"longitude": "Ilguma",
|
||||
"look": "",
|
||||
"loop_videos": "Kartoti vaizdo įrašus",
|
||||
"loop_videos_description": "",
|
||||
"make": "Gamintojas",
|
||||
"manage_shared_links": "Bendrinimo nuorodų tvarkymas",
|
||||
"manage_sharing_with_partners": "Valdyti dalijimąsi su partneriais",
|
||||
|
@ -1019,7 +906,6 @@
|
|||
"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_title": "Location Service disabled",
|
||||
"map_marker_with_image": "",
|
||||
"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_title": "Location Permission denied",
|
||||
|
@ -1086,15 +972,11 @@
|
|||
"no_assets_message": "SPUSTELĖKITE NORĖDAMI ĮKELTI PIRMĄJĄ NUOTRAUKĄ",
|
||||
"no_assets_to_show": "No assets to show",
|
||||
"no_duplicates_found": "Dublikatų nerasta.",
|
||||
"no_exif_info_available": "",
|
||||
"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_name": "Be vardo",
|
||||
"no_places": "",
|
||||
"no_results": "Nerasta",
|
||||
"no_results_description": "Pabandykite sinonimą arba bendresnį raktažodį",
|
||||
"no_shared_albums_message": "",
|
||||
"not_in_any_album": "Nė viename albume",
|
||||
"not_selected": "Not selected",
|
||||
"notes": "Pastabos",
|
||||
|
@ -1120,7 +1002,6 @@
|
|||
"or": "arba",
|
||||
"organize_your_library": "Tvarkykite savo biblioteką",
|
||||
"original": "Originalas",
|
||||
"other": "",
|
||||
"other_devices": "Kiti įrenginiai",
|
||||
"other_variables": "Kiti kintamieji",
|
||||
"owned": "Nuosavi",
|
||||
|
@ -1137,19 +1018,12 @@
|
|||
"partner_page_select_partner": "Select partner",
|
||||
"partner_page_shared_to_title": "Shared to",
|
||||
"partner_page_stop_sharing_content": "{} will no longer be able to access your photos.",
|
||||
"partner_sharing": "",
|
||||
"partners": "Partneriai",
|
||||
"password": "Slaptažodis",
|
||||
"password_does_not_match": "Slaptažodis nesutampa",
|
||||
"password_required": "Reikalingas slaptažodis",
|
||||
"password_reset_success": "Slaptažodis sėkmingai atkurtas",
|
||||
"past_durations": {
|
||||
"days": "",
|
||||
"hours": "",
|
||||
"years": ""
|
||||
},
|
||||
"path": "Kelias",
|
||||
"pattern": "",
|
||||
"pause": "Sustabdyti",
|
||||
"pause_memories": "Pristabdyti atsiminimus",
|
||||
"paused": "Sustabdyta",
|
||||
|
@ -1158,11 +1032,8 @@
|
|||
"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_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_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ų}}",
|
||||
"permission_onboarding_back": "Back",
|
||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
||||
|
@ -1176,22 +1047,11 @@
|
|||
"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_from_previous_years": "Ankstesnių metų nuotraukos",
|
||||
"pick_a_location": "",
|
||||
"place": "Vieta",
|
||||
"places": "Vietos",
|
||||
"play": "",
|
||||
"play_memories": "Leisti atsiminimus",
|
||||
"play_motion_photo": "",
|
||||
"play_or_pause_video": "",
|
||||
"port": "",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Preferences",
|
||||
"preset": "",
|
||||
"preview": "",
|
||||
"previous": "",
|
||||
"previous_memory": "",
|
||||
"previous_or_next_photo": "",
|
||||
"primary": "",
|
||||
"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_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_picture_set": "Profilio nuotrauka nustatyta.",
|
||||
"public_album": "Viešas albumas",
|
||||
"public_share": "",
|
||||
"purchase_account_info": "Rėmėjas",
|
||||
"purchase_activated_subtitle": "Dėkojame, kad remiate Immich ir atviro kodo programinę įrangą",
|
||||
"purchase_activated_time": "Suaktyvinta {date}",
|
||||
|
@ -1237,10 +1096,6 @@
|
|||
"rating": "Įvertinimas žvaigždutėmis",
|
||||
"rating_count": "{count, plural, one {# įvertinimas} few {# įvertinimai} other {# įvertinimų}}",
|
||||
"rating_description": "Rodyti EXIF įvertinimus informacijos skydelyje",
|
||||
"reaction_options": "",
|
||||
"read_changelog": "",
|
||||
"recent": "",
|
||||
"recent_searches": "",
|
||||
"recently_added": "Recently added",
|
||||
"recently_added_page_title": "Recently Added",
|
||||
"refresh": "Atnaujinti",
|
||||
|
@ -1255,7 +1110,6 @@
|
|||
"refreshing_metadata": "Perkraunami metaduomenys",
|
||||
"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_deleted_assets": "",
|
||||
"remove_from_album": "Pašalinti iš albumo",
|
||||
"remove_from_favorites": "Pašalinti iš mėgstamiausių",
|
||||
"remove_from_shared_link": "Pašalinti iš bendrinimo nuorodos",
|
||||
|
@ -1273,16 +1127,12 @@
|
|||
"replace_with_upload": "Pakeisti naujai įkeltu failu",
|
||||
"require_password": "Reikalauti slaptažodžio",
|
||||
"reset": "Atstatyti",
|
||||
"reset_password": "",
|
||||
"reset_people_visibility": "",
|
||||
"resolve_duplicates": "Sutvarkyti dublikatus",
|
||||
"resolved_all_duplicates": "Sutvarkyti visi dublikatai",
|
||||
"restore": "Atkurti",
|
||||
"restore_all": "Atkurti visus",
|
||||
"restore_user": "Atkurti naudotoją",
|
||||
"retry_upload": "",
|
||||
"review_duplicates": "Peržiūrėti dublikatus",
|
||||
"role": "",
|
||||
"save": "Išsaugoti",
|
||||
"save_to_gallery": "Save to gallery",
|
||||
"saved_api_key": "Išsaugotas API raktas",
|
||||
|
@ -1294,14 +1144,10 @@
|
|||
"scan_library": "Skenuoti",
|
||||
"scan_settings": "Skenavimo nustatymai",
|
||||
"search": "Ieškoti",
|
||||
"search_albums": "",
|
||||
"search_by_context": "Ieškoti pagal kontekstą",
|
||||
"search_by_description_example": "Žygio diena Sapoje",
|
||||
"search_by_filename": "Ieškoti pagal failo pavadinimą arba plėtinį",
|
||||
"search_by_filename_example": "pvz. IMG_1234.JPG arba PNG",
|
||||
"search_camera_make": "",
|
||||
"search_camera_model": "",
|
||||
"search_city": "",
|
||||
"search_country": "Ieškoti šalies...",
|
||||
"search_filter_apply": "Apply filter",
|
||||
"search_filter_camera_title": "Select camera type",
|
||||
|
@ -1316,7 +1162,6 @@
|
|||
"search_filter_media_type": "Media Type",
|
||||
"search_filter_media_type_title": "Select media type",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_for_existing_person": "",
|
||||
"search_no_more_result": "No more results",
|
||||
"search_no_people_named": "Nėra žmonių vardu „{name}“",
|
||||
"search_no_result": "No results found, try a different search term or combination",
|
||||
|
@ -1335,25 +1180,17 @@
|
|||
"search_places": "Ieškoti vietų",
|
||||
"search_result_page_new_search_hint": "New Search",
|
||||
"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_2": "m:your-search-term",
|
||||
"search_tags": "Ieškoti žymų...",
|
||||
"search_timezone": "",
|
||||
"search_type": "Paieškos tipas",
|
||||
"search_your_photos": "Ieškoti nuotraukų",
|
||||
"searching_locales": "",
|
||||
"second": "",
|
||||
"select_album_cover": "",
|
||||
"select_all": "",
|
||||
"select_all_duplicates": "Pasirinkti visus dublikatus",
|
||||
"select_avatar_color": "Pasirinkti avataro spalvą",
|
||||
"select_face": "Pasirinkti veidą",
|
||||
"select_featured_photo": "Pasirinkti rodomą nuotrauką",
|
||||
"select_keep_all": "Visus pažymėti \"Palikti\"",
|
||||
"select_library_owner": "Pasirinkti bibliotekos savininką",
|
||||
"select_new_face": "",
|
||||
"select_photos": "",
|
||||
"select_trash_all": "Visus pažymėti \"Išmesti\"",
|
||||
"select_user_for_sharing_page_err_album": "Failed to create album",
|
||||
"selected": "Pasirinkta",
|
||||
|
@ -1368,7 +1205,6 @@
|
|||
"server_stats": "Serverio statistika",
|
||||
"server_version": "Serverio versija",
|
||||
"set": "Nustatyti",
|
||||
"set_as_album_cover": "",
|
||||
"set_as_profile_picture": "Nustatyti kaip profilio nuotrauką",
|
||||
"set_date_of_birth": "Nustatyti gimimo datą",
|
||||
"set_profile_picture": "Nustatyti profilio nuotrauką",
|
||||
|
@ -1398,7 +1234,6 @@
|
|||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"settings": "Nustatymai",
|
||||
"settings_require_restart": "Please restart Immich to apply this setting",
|
||||
"settings_saved": "",
|
||||
"share": "Dalintis",
|
||||
"share_add_photos": "Add photos",
|
||||
"share_assets_selected": "{} selected",
|
||||
|
@ -1411,8 +1246,6 @@
|
|||
"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_title": "PEOPLE",
|
||||
"shared_by": "",
|
||||
"shared_by_you": "",
|
||||
"shared_intent_upload_button_progress_text": "{} / {} Uploaded",
|
||||
"shared_link_app_bar_title": "Shared Links",
|
||||
"shared_link_clipboard_copied_massage": "Copied to clipboard",
|
||||
|
@ -1458,20 +1291,15 @@
|
|||
"show_album_options": "Rodyti albumo parinktis",
|
||||
"show_file_location": "Rodyti rinkmenos vietą",
|
||||
"show_gallery": "Rodyti galeriją",
|
||||
"show_hidden_people": "",
|
||||
"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_keyboard_shortcuts": "",
|
||||
"show_metadata": "Rodyti metaduomenis",
|
||||
"show_or_hide_info": "Rodyti arba slėpti informaciją",
|
||||
"show_password": "Rodyti slaptažodį",
|
||||
"show_person_options": "",
|
||||
"show_progress_bar": "",
|
||||
"show_search_options": "Rodyti paieškos parinktis",
|
||||
"show_slideshow_transition": "Rodyti perėjimą tarp skaidrių",
|
||||
"show_supporter_badge": "Rėmėjo ženklelis",
|
||||
"show_supporter_badge_description": "Rodyti rėmėjo ženklelį",
|
||||
"shuffle": "",
|
||||
"sidebar": "Šoninė juosta",
|
||||
"sidebar_display_description": "Rodyti rodinio nuorodą šoninėje juostoje",
|
||||
"sign_out": "Atsijungti",
|
||||
|
@ -1480,7 +1308,6 @@
|
|||
"skip_to_content": "Pereiti prie turinio",
|
||||
"slideshow": "Skaidrių peržiūra",
|
||||
"slideshow_settings": "Skaidrių peržiūros nustatymai",
|
||||
"sort_albums_by": "",
|
||||
"sort_created": "Sukūrimo data",
|
||||
"sort_modified": "Keitimo data",
|
||||
"sort_oldest": "Seniausia nuotrauka",
|
||||
|
@ -1492,20 +1319,14 @@
|
|||
"stack_select_one_photo": "Pasirinkti pagrindinę grupės nuotrauką",
|
||||
"stack_selected_photos": "Grupuoti pasirinktas nuotraukas",
|
||||
"stacked_assets_count": "{count, plural, one {Sugrupuotas # elementas} few {Sugrupuoti # elementai} other {Sugrupuota # elementų}}",
|
||||
"stacktrace": "",
|
||||
"start": "Pradėti",
|
||||
"start_date": "Pradžios data",
|
||||
"state": "",
|
||||
"status": "Statusas",
|
||||
"stop_motion_photo": "",
|
||||
"storage": "Saugykla",
|
||||
"storage_label": "",
|
||||
"storage_usage": "Naudojama {used} iš {available}",
|
||||
"submit": "Pateikti",
|
||||
"suggestions": "",
|
||||
"sunrise_on_the_beach": "Saulėtekis paplūdimyje",
|
||||
"support_and_feedback": "Palaikymas ir atsiliepimai",
|
||||
"swap_merge_direction": "",
|
||||
"sync": "Sinchronizuoti",
|
||||
"sync_albums": "Sync albums",
|
||||
"sync_albums_manual_subtitle": "Sync all uploaded videos and photos to the selected backup albums",
|
||||
|
@ -1519,8 +1340,6 @@
|
|||
"tags": "Žymos",
|
||||
"template": "Šablonas",
|
||||
"theme": "Tema",
|
||||
"theme_selection": "",
|
||||
"theme_selection_description": "",
|
||||
"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_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||
|
@ -1541,9 +1360,6 @@
|
|||
"to_change_password": "Pakeisti slaptažodį",
|
||||
"to_favorite": "Įtraukti prie mėgstamiausių",
|
||||
"to_trash": "Išmesti",
|
||||
"toggle_settings": "",
|
||||
"toggle_theme": "",
|
||||
"total_usage": "",
|
||||
"trash": "Šiukšliadėžė",
|
||||
"trash_all": "Perkelti visus į šiukšliadėžę",
|
||||
"trash_count": "Perkelti {count, number} į šiukšliadėžę",
|
||||
|
@ -1561,8 +1377,6 @@
|
|||
"unarchive": "Išarchyvuoti",
|
||||
"unarchived_count": "{count, plural, other {# išarchyvuota}}",
|
||||
"unfavorite": "Pašalinti iš mėgstamiausių",
|
||||
"unhide_person": "",
|
||||
"unknown": "",
|
||||
"unknown_year": "Nežinomi metai",
|
||||
"unlink_oauth": "Atsieti OAuth",
|
||||
"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ų}}",
|
||||
"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ą",
|
||||
"up_next": "",
|
||||
"updated_at": "Atnaujintas",
|
||||
"updated_password": "Slaptažodis atnaujintas",
|
||||
"upload": "Įkelti",
|
||||
|
@ -1597,7 +1410,6 @@
|
|||
"user_id": "Naudotojo ID",
|
||||
"user_pin_code_settings": "PIN kodas",
|
||||
"user_pin_code_settings_description": "Tvarkykite savo PIN kodą",
|
||||
"user_usage_detail": "",
|
||||
"user_usage_stats": "Paskyros naudojimo statistika",
|
||||
"user_usage_stats_description": "Žiūrėti paskyros naudojimo statistiką",
|
||||
"username": "Naudotojo vardas",
|
||||
|
@ -1625,8 +1437,6 @@
|
|||
"view_all_users": "Peržiūrėti visus naudotojus",
|
||||
"view_in_timeline": "Žiūrėti laiko skalėje",
|
||||
"view_links": "Žiūrėti nuorodas",
|
||||
"view_next_asset": "",
|
||||
"view_previous_asset": "",
|
||||
"view_stack": "Peržiūrėti grupę",
|
||||
"viewer_remove_from_stack": "Remove from Stack",
|
||||
"viewer_stack_use_as_main_asset": "Use as Main Asset",
|
||||
|
|
377
i18n/lv.json
377
i18n/lv.json
|
@ -56,10 +56,6 @@
|
|||
"face_detection": "Seju noteikšana",
|
||||
"image_format": "Formāts",
|
||||
"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_resolution": "Izšķirtspēja",
|
||||
"image_settings": "Attēla Iestatījumi",
|
||||
|
@ -70,98 +66,43 @@
|
|||
"job_settings_description": "Uzdevumu izpildes vienlaicīguma pārvaldība",
|
||||
"job_status": "Uzdevumu statuss",
|
||||
"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_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_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_description": "",
|
||||
"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_description": "Mašīnmācīšanās funkciju un iestatījumu pārvaldība",
|
||||
"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",
|
||||
"manage_concurrency": "Vienlaicīgas darbības 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_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_reverse_geocoding": "",
|
||||
"map_reverse_geocoding_enable_description": "",
|
||||
"map_reverse_geocoding_settings": "",
|
||||
"map_settings": "Karte",
|
||||
"map_settings_description": "Kartes iestatījumu pārvaldība",
|
||||
"map_style_description": "",
|
||||
"metadata_extraction_job": "Metadatu iegūšana",
|
||||
"metadata_extraction_job_description": "",
|
||||
"metadata_settings": "Metadatu iestatījumi",
|
||||
"metadata_settings_description": "Metadatu iestatījumu pārvaldība",
|
||||
"migration_job": "Migrācija",
|
||||
"migration_job_description": "",
|
||||
"no_paths_added": "Nav pievienots neviens ceļš",
|
||||
"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!",
|
||||
"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_host_description": "",
|
||||
"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_password_description": "",
|
||||
"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_setting_description": "",
|
||||
"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_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_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_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_description": "",
|
||||
"password_enable_description": "Pieteikšanās ar e-pasta adresi un paroli",
|
||||
"password_settings": "Pieteikšanās ar paroli",
|
||||
"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",
|
||||
"scanning_library": "Skenē bibliotēku",
|
||||
"search_jobs": "Meklēt uzdevumus…",
|
||||
"server_external_domain_settings": "",
|
||||
"server_external_domain_settings_description": "",
|
||||
"server_settings": "Servera iestatījumi",
|
||||
"server_settings_description": "Servera iestatījumu pārvaldība",
|
||||
"server_welcome_message": "Sveiciena ziņa",
|
||||
"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_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_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_settings": "Krātuves veidne",
|
||||
"storage_template_settings_description": "",
|
||||
"system_settings": "Sistēmas iestatījumi",
|
||||
"template_email_preview": "Priekšskatījums",
|
||||
"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",
|
||||
"theme_custom_css_settings": "Pielāgots CSS",
|
||||
"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",
|
||||
"thumbnail_generation_job": "Sīktēlu ģenerēšana",
|
||||
"thumbnail_generation_job_description": "",
|
||||
"transcoding_acceleration_api": "Paātrināšanas API",
|
||||
"transcoding_acceleration_api_description": "",
|
||||
"transcoding_acceleration_nvenc": "NVENC (nepieciešams NVIDIA GPU)",
|
||||
"transcoding_acceleration_qsv": "Quick Sync (nepieciešams 7. paaudzes vai jaunāks Intel procesors)",
|
||||
"transcoding_acceleration_rkmpp": "RKMPP (tikai Rockchip SOC)",
|
||||
"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_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_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_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_description": "",
|
||||
"trash_enabled_description": "",
|
||||
"trash_number_of_days": "Dienu skaits",
|
||||
"trash_number_of_days_description": "",
|
||||
"trash_settings": "",
|
||||
"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_password_has_been_reset": "Lietotāja parole ir atiestatīta:",
|
||||
"user_restore_description": "<b>{user}</b> konts tiks atjaunots.",
|
||||
"user_settings": "",
|
||||
"user_settings_description": "Lietotāju iestatījumu pārvaldība",
|
||||
"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_settings": "Versijas pārbaude",
|
||||
"version_check_settings_description": "",
|
||||
"video_conversion_job_description": ""
|
||||
"version_check_settings": "Versijas pārbaude"
|
||||
},
|
||||
"admin_email": "Administratora e-pasts",
|
||||
"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_years": "{years, plural, zero {# gadu} one {# gads} other {# gadi}}",
|
||||
"album_added": "Albums pievienots",
|
||||
"album_added_notification_setting_description": "",
|
||||
"album_cover_updated": "Albuma attēls atjaunināts",
|
||||
"album_info_card_backup_album_excluded": "NEIEKĻAUTS",
|
||||
"album_info_card_backup_album_included": "IEKĻAUTS",
|
||||
"album_info_updated": "Albuma informācija atjaunināta",
|
||||
"album_leave": "Pamest albumu?",
|
||||
"album_name": "Albuma nosaukums",
|
||||
"album_options": "",
|
||||
"album_remove_user": "Noņemt lietotāju?",
|
||||
"album_thumbnail_card_item": "1 vienums",
|
||||
"album_thumbnail_card_items": "{count} vienumi",
|
||||
"album_thumbnail_card_shared": " · Kopīgots",
|
||||
"album_thumbnail_shared_by": "Kopīgoja {user}",
|
||||
"album_updated": "Albums atjaunināts",
|
||||
"album_updated_setting_description": "",
|
||||
"album_user_left": "Pameta {album}",
|
||||
"album_user_removed": "Noņēma {user}",
|
||||
"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_ok": "Jā",
|
||||
"app_bar_signout_dialog_title": "Izrakstīties",
|
||||
"app_settings": "",
|
||||
"appears_in": "",
|
||||
"archive": "Arhīvs",
|
||||
"archive_or_unarchive_photo": "",
|
||||
"archive_page_no_archived_assets": "Nav atrasts neviens arhivēts aktīvs",
|
||||
"archive_page_title": "Arhīvs ({count})",
|
||||
"archive_size": "Arhīva izmērs",
|
||||
|
@ -351,7 +223,6 @@
|
|||
"asset_list_layout_sub_title": "Izvietojums",
|
||||
"asset_list_settings_subtitle": "Fotorežģa izkārtojuma iestatījumi",
|
||||
"asset_list_settings_title": "Fotorežģis",
|
||||
"asset_offline": "",
|
||||
"asset_restored_successfully": "Asset restored successfully",
|
||||
"asset_uploading": "Augšupielādē…",
|
||||
"asset_viewer_settings_subtitle": "Manage your gallery viewer settings",
|
||||
|
@ -431,10 +302,8 @@
|
|||
"backup_manual_title": "Augšupielādes statuss",
|
||||
"backup_options_page_title": "Dublēšanas iestatījumi",
|
||||
"backup_setting_subtitle": "Manage background and foreground upload settings",
|
||||
"backward": "",
|
||||
"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ī.",
|
||||
"blurred_background": "",
|
||||
"bugs_and_feature_requests": "Kļūdas un funkciju pieprasījumi",
|
||||
"build": "Būvējums",
|
||||
"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_title": "Lokālā Krātuve",
|
||||
"cache_settings_title": "Kešdarbes iestatījumi",
|
||||
"camera": "",
|
||||
"camera_brand": "",
|
||||
"camera_model": "",
|
||||
"cancel": "Atcelt",
|
||||
"cancel_search": "",
|
||||
"canceled": "Canceled",
|
||||
"cannot_merge_people": "Nevar apvienot cilvēkus",
|
||||
"cannot_update_the_description": "",
|
||||
"change_date": "Mainīt datumu",
|
||||
"change_display_order": "Change display order",
|
||||
"change_expiration_time": "Izmainīt derīguma termiņu",
|
||||
|
@ -477,17 +341,13 @@
|
|||
"change_password_form_password_mismatch": "Paroles nesakrīt",
|
||||
"change_password_form_reenter_new_password": "Atkārtoti ievadīt jaunu paroli",
|
||||
"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_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_logs": "",
|
||||
"choose_matching_people_to_merge": "Izvēlies atbilstošus cilvēkus apvienošanai",
|
||||
"city": "Pilsēta",
|
||||
"clear": "Notīrīt",
|
||||
"clear_all": "Notīrīt visu",
|
||||
"clear_message": "",
|
||||
"clear_value": "Notīrīt vērtību",
|
||||
"client_cert_dialog_msg_confirm": "OK",
|
||||
"client_cert_enter_password": "Enter Password",
|
||||
|
@ -504,16 +364,12 @@
|
|||
"color": "Krāsa",
|
||||
"color_theme": "Krāsu tēma",
|
||||
"comment_deleted": "Komentārs dzēsts",
|
||||
"comment_options": "",
|
||||
"comments_are_disabled": "",
|
||||
"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.",
|
||||
"completed": "Completed",
|
||||
"confirm": "Apstiprināt",
|
||||
"confirm_admin_password": "",
|
||||
"confirm_new_pin_code": "Apstiprināt jauno PIN kodu",
|
||||
"confirm_password": "Apstiprināt paroli",
|
||||
"contain": "",
|
||||
"context": "Konteksts",
|
||||
"continue": "Turpināt",
|
||||
"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_to": "Kopīgot Uz",
|
||||
"control_bottom_app_bar_trash_from_immich": "Pārvietot uz Atkritni",
|
||||
"copied_image_to_clipboard": "",
|
||||
"copy_error": "Kopēšanas kļūda",
|
||||
"copy_file_path": "",
|
||||
"copy_image": "",
|
||||
"copy_link": "",
|
||||
"copy_link_to_clipboard": "",
|
||||
"copy_password": "",
|
||||
"copy_to_clipboard": "",
|
||||
"country": "Valsts",
|
||||
"cover": "",
|
||||
"covers": "",
|
||||
"create": "Izveidot",
|
||||
"create_album": "Izveidot albumu",
|
||||
"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_select_photos": "Fotoattēlu Izvēle",
|
||||
"create_user": "Izveidot lietotāju",
|
||||
"created": "",
|
||||
"crop": "Crop",
|
||||
"curated_object_page_title": "Lietas",
|
||||
"current_device": "",
|
||||
"current_pin_code": "Esošais PIN kods",
|
||||
"current_server_address": "Current server address",
|
||||
"custom_locale": "",
|
||||
"custom_locale_description": "",
|
||||
"daily_title_text_date": "E, MMM dd",
|
||||
"daily_title_text_date_year": "E, MMM dd, gggg",
|
||||
"dark": "",
|
||||
"date_after": "Datums pēc",
|
||||
"date_and_time": "Datums un Laiks",
|
||||
"date_before": "Datums pirms",
|
||||
|
@ -567,8 +409,6 @@
|
|||
"date_range": "Datumu diapazons",
|
||||
"day": "Diena",
|
||||
"deduplication_criteria_1": "Attēla izmērs baitos",
|
||||
"default_locale": "",
|
||||
"default_locale_description": "",
|
||||
"delete": "Dzēst",
|
||||
"delete_album": "Dzēst albumu",
|
||||
"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ā",
|
||||
"details": "INFORMĀCIJA",
|
||||
"direction": "Virziens",
|
||||
"disallow_edits": "",
|
||||
"discord": "Discord",
|
||||
"discover": "",
|
||||
"dismiss_all_errors": "",
|
||||
"dismiss_error": "",
|
||||
"display_options": "",
|
||||
"display_order": "Attēlošanas secība",
|
||||
"display_original_photos": "",
|
||||
"display_original_photos_setting_description": "",
|
||||
"documentation": "Dokumentācija",
|
||||
"done": "Gatavs",
|
||||
"download": "Lejupielādēt",
|
||||
|
@ -624,13 +457,10 @@
|
|||
"downloading_asset_filename": "Lejupielādē failu {filename}",
|
||||
"downloading_media": "Downloading media",
|
||||
"duplicates": "Dublikāti",
|
||||
"duration": "",
|
||||
"edit": "Labot",
|
||||
"edit_album": "Labot albumu",
|
||||
"edit_avatar": "",
|
||||
"edit_date": "Labot datumu",
|
||||
"edit_date_and_time": "Labot datumu un laiku",
|
||||
"edit_exclusion_pattern": "",
|
||||
"edit_faces": "Labot sejas",
|
||||
"edit_import_path": "Labot importa ceļu",
|
||||
"edit_import_paths": "Labot importa ceļus",
|
||||
|
@ -650,66 +480,18 @@
|
|||
"email_notifications": "E-pasta paziņojumi",
|
||||
"empty_folder": "This folder is empty",
|
||||
"empty_trash": "Iztukšot atkritni",
|
||||
"enable": "",
|
||||
"enabled": "",
|
||||
"end_date": "",
|
||||
"enqueued": "Enqueued",
|
||||
"enter_wifi_name": "Enter WiFi name",
|
||||
"error": "",
|
||||
"error_change_sort_album": "Failed to change album sort order",
|
||||
"error_loading_image": "",
|
||||
"error_saving_image": "Kļūda: {error}",
|
||||
"errors": {
|
||||
"cant_get_faces": "Nevar iegūt sejas",
|
||||
"cant_search_people": "Neizdevās veikt peronu meklēšanu",
|
||||
"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_delete_album": "",
|
||||
"unable_to_delete_asset": "",
|
||||
"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_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_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": ""
|
||||
"unable_to_save_date_of_birth": "Neizdevās saglabāt dzimšanas datumu"
|
||||
},
|
||||
"exif_bottom_sheet_description": "Pievienot Aprakstu...",
|
||||
"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_years": "Vecums {years}",
|
||||
"exit_slideshow": "Iziet no slīdrādes",
|
||||
"expand_all": "",
|
||||
"experimental_settings_new_asset_list_subtitle": "Izstrādes posmā",
|
||||
"experimental_settings_new_asset_list_title": "Iespējot eksperimentālo fotorežģi",
|
||||
"experimental_settings_subtitle": "Izmanto uzņemoties risku!",
|
||||
|
@ -729,38 +510,21 @@
|
|||
"expire_after": "Derīguma termiņš beidzas pēc",
|
||||
"expired": "Derīguma termiņš beidzās",
|
||||
"explore": "Izpētīt",
|
||||
"extension": "",
|
||||
"external_libraries": "",
|
||||
"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",
|
||||
"failed": "Failed",
|
||||
"failed_to_load_assets": "Failed to load assets",
|
||||
"failed_to_load_folder": "Failed to load folder",
|
||||
"favorite": "Izlase",
|
||||
"favorite_or_unfavorite_photo": "",
|
||||
"favorites": "Izlase",
|
||||
"favorites_page_no_favorites": "Nav atrasti iecienītākie aktīvi",
|
||||
"feature_photo_updated": "",
|
||||
"features_setting_description": "Lietotnes funkciju pārvaldība",
|
||||
"file_name": "",
|
||||
"file_name_or_extension": "",
|
||||
"filename": "",
|
||||
"filetype": "",
|
||||
"filter": "Filter",
|
||||
"filter_people": "",
|
||||
"fix_incorrect_match": "",
|
||||
"folder": "Folder",
|
||||
"folder_not_found": "Folder not found",
|
||||
"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",
|
||||
"getting_started": "",
|
||||
"go_back": "",
|
||||
"go_to_search": "",
|
||||
"grant_permission": "Grant permission",
|
||||
"group_albums_by": "",
|
||||
"haptic_feedback_switch": "Iestatīt haptisku reakciju",
|
||||
"haptic_feedback_title": "Haptiska Reakcija",
|
||||
"has_quota": "Ir kvota",
|
||||
|
@ -770,9 +534,7 @@
|
|||
"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_title": "Custom proxy headers",
|
||||
"hide_gallery": "",
|
||||
"hide_named_person": "Paslēpt personu {name}",
|
||||
"hide_password": "",
|
||||
"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_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_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",
|
||||
"host": "",
|
||||
"hour": "",
|
||||
"ignore_icloud_photos": "Ignore iCloud photos",
|
||||
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
|
||||
"image": "Attēls",
|
||||
|
@ -804,12 +564,9 @@
|
|||
"in_archive": "Arhīvā",
|
||||
"include_archived": "Iekļaut arhivētos",
|
||||
"include_shared_albums": "Iekļaut koplietotos albumus",
|
||||
"include_shared_partner_assets": "",
|
||||
"individual_share": "",
|
||||
"info": "Informācija",
|
||||
"interval": {
|
||||
"day_at_onepm": "Katru dienu 13.00",
|
||||
"hours": "",
|
||||
"night_at_midnight": "Katru dienu pusnaktī",
|
||||
"night_at_twoam": "Katru dienu 2.00 naktī"
|
||||
},
|
||||
|
@ -830,20 +587,14 @@
|
|||
"let_others_respond": "Ļaut citiem atbildēt",
|
||||
"level": "Līmenis",
|
||||
"library": "Bibliotēka",
|
||||
"library_options": "",
|
||||
"library_page_device_albums": "Albumi ierīcē",
|
||||
"library_page_new_album": "Jauns albums",
|
||||
"library_page_sort_asset_count": "Daudzums ar aktīviem",
|
||||
"library_page_sort_created": "Jaunākais izveidotais",
|
||||
"library_page_sort_last_modified": "Pēdējo reizi modificēts",
|
||||
"library_page_sort_title": "Albuma virsraksts",
|
||||
"light": "",
|
||||
"link_options": "",
|
||||
"link_to_oauth": "",
|
||||
"linked_oauth_account": "",
|
||||
"list": "Saraksts",
|
||||
"loading": "Ielādē",
|
||||
"loading_search_results_failed": "",
|
||||
"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",
|
||||
"location_permission": "Location permission",
|
||||
|
@ -854,7 +605,6 @@
|
|||
"location_picker_longitude_error": "Ievadiet korektu ģeogrāfisko garumu",
|
||||
"location_picker_longitude_hint": "Ievadiet savu ģeogrāfisko garumu šeit",
|
||||
"log_out": "Izrakstīties",
|
||||
"log_out_all_devices": "",
|
||||
"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_back_button_text": "Atpakaļ",
|
||||
|
@ -874,12 +624,10 @@
|
|||
"login_form_save_login": "Palikt pieteiktam",
|
||||
"login_form_server_empty": "Ieraksties servera URL.",
|
||||
"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_success": "Parole veiksmīgi atjaunota",
|
||||
"longitude": "Ģeogrāfiskais garums",
|
||||
"look": "Izskats",
|
||||
"loop_videos": "",
|
||||
"loop_videos_description": "Iespējot, lai automātiski videoklips tiktu cikliski palaists detaļu skatītājā.",
|
||||
"make": "Firma",
|
||||
"manage_shared_links": "Kopīgoto saišu pārvaldība",
|
||||
|
@ -919,7 +667,6 @@
|
|||
"memories": "Atmiņas",
|
||||
"memories_all_caught_up": "Šobrīd, tas arī viss",
|
||||
"memories_check_back_tomorrow": "Priekš vairāk atmiņām atgriezieties rītdien.",
|
||||
"memories_setting_description": "",
|
||||
"memories_start_over": "Sākt no jauna",
|
||||
"memories_swipe_to_close": "Pavelciet uz augšu, lai aizvērtu",
|
||||
"memories_year_ago": "A year ago",
|
||||
|
@ -955,25 +702,19 @@
|
|||
"new_pin_code": "Jaunais PIN kods",
|
||||
"new_user_created": "Izveidots jauns lietotājs",
|
||||
"new_version_available": "PIEEJAMA JAUNA VERSIJA",
|
||||
"newest_first": "",
|
||||
"next": "Nākošais",
|
||||
"next_memory": "Nākamā atmiņa",
|
||||
"no": "Nē",
|
||||
"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_to_show": "Nav uzrādāmo aktīvu",
|
||||
"no_duplicates_found": "Dublikāti netika atrasti.",
|
||||
"no_exif_info_available": "Nav pieejama exif informācija",
|
||||
"no_explore_results_message": "",
|
||||
"no_favorites_message": "",
|
||||
"no_libraries_message": "",
|
||||
"no_name": "Nav nosaukuma",
|
||||
"no_notifications": "Nav paziņojumu",
|
||||
"no_places": "Nav atrašanās vietu",
|
||||
"no_results": "Nav rezultātu",
|
||||
"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_selected": "Not selected",
|
||||
"notes": "Piezīmes",
|
||||
|
@ -988,7 +729,6 @@
|
|||
"official_immich_resources": "Oficiālie Immich resursi",
|
||||
"offline": "Bezsaistē",
|
||||
"ok": "Labi",
|
||||
"oldest_first": "",
|
||||
"on_this_device": "On this device",
|
||||
"online": "Tiešsaistē",
|
||||
"only_favorites": "Tikai izlase",
|
||||
|
@ -997,7 +737,6 @@
|
|||
"open_the_search_filters": "Atvērt meklēšanas filtrus",
|
||||
"options": "Iestatījumi",
|
||||
"or": "vai",
|
||||
"organize_your_library": "",
|
||||
"original": "oriģināls",
|
||||
"other": "Citi",
|
||||
"other_devices": "Citas ierīces",
|
||||
|
@ -1013,29 +752,11 @@
|
|||
"partner_page_select_partner": "Izvēlēties partneri",
|
||||
"partner_page_shared_to_title": "Kopīgots uz",
|
||||
"partner_page_stop_sharing_content": "{partner} vairs nevarēs piekļūt jūsu fotoattēliem.",
|
||||
"partner_sharing": "",
|
||||
"partners": "Partneri",
|
||||
"password": "Parole",
|
||||
"password_does_not_match": "Parole nesakrīt",
|
||||
"password_required": "",
|
||||
"password_reset_success": "",
|
||||
"past_durations": {
|
||||
"days": "",
|
||||
"hours": "",
|
||||
"years": ""
|
||||
},
|
||||
"path": "Ceļš",
|
||||
"pattern": "",
|
||||
"pause": "",
|
||||
"pause_memories": "",
|
||||
"paused": "",
|
||||
"pending": "",
|
||||
"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_continue_anyway": "Tomēr turpināt",
|
||||
"permission_onboarding_get_started": "Darba sākšana",
|
||||
|
@ -1047,22 +768,11 @@
|
|||
"person": "Persona",
|
||||
"photos": "Fotoattēli",
|
||||
"photos_from_previous_years": "Fotogrāfijas no iepriekšējiem gadiem",
|
||||
"pick_a_location": "",
|
||||
"place": "",
|
||||
"places": "Vietas",
|
||||
"play": "",
|
||||
"play_memories": "",
|
||||
"play_motion_photo": "",
|
||||
"play_or_pause_video": "",
|
||||
"port": "Ports",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
"preferences_settings_title": "Iestatījumi",
|
||||
"preset": "",
|
||||
"preview": "Priekšskatījums",
|
||||
"previous": "",
|
||||
"previous_memory": "",
|
||||
"previous_or_next_photo": "",
|
||||
"primary": "",
|
||||
"privacy": "Privātums",
|
||||
"profile": "Profils",
|
||||
"profile_drawer_app_logs": "Žurnāli",
|
||||
|
@ -1072,8 +782,6 @@
|
|||
"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_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_reminder": "Atgādināt man pēc 30 dienām",
|
||||
"purchase_button_remove_key": "Noņemt atslēgu",
|
||||
|
@ -1091,33 +799,20 @@
|
|||
"purchase_server_title": "Serveris",
|
||||
"purchase_settings_server_activated": "Servera produkta atslēgu pārvalda administrators",
|
||||
"rating_clear": "Noņemt vērtējumu",
|
||||
"reaction_options": "",
|
||||
"read_changelog": "Lasīt izmaiņu sarakstu",
|
||||
"recent": "",
|
||||
"recent_searches": "",
|
||||
"recently_added": "Recently added",
|
||||
"recently_added_page_title": "Nesen Pievienotais",
|
||||
"refresh": "",
|
||||
"refreshed": "",
|
||||
"refreshes_every_file": "",
|
||||
"remove": "Noņemt",
|
||||
"remove_deleted_assets": "",
|
||||
"remove_from_album": "Noņemt no albuma",
|
||||
"remove_from_favorites": "Noņemt no izlases",
|
||||
"remove_from_shared_link": "",
|
||||
"remove_user": "Noņemt lietotāju",
|
||||
"removed_api_key": "Noņēma API atslēgu: {name}",
|
||||
"removed_from_archive": "Noņēma no arhīva",
|
||||
"removed_from_favorites": "Noņēma no izlases",
|
||||
"rename": "Pārsaukt",
|
||||
"repair": "Remonts",
|
||||
"repair_no_results_message": "",
|
||||
"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",
|
||||
"reset": "",
|
||||
"reset_password": "",
|
||||
"reset_people_visibility": "",
|
||||
"resolve_duplicates": "Atrisināt dublēšanās gadījumus",
|
||||
"resolved_all_duplicates": "Visi dublikāti ir atrisināti",
|
||||
"restore": "Atjaunot",
|
||||
|
@ -1136,16 +831,9 @@
|
|||
"saved_settings": "Iestatījumi saglabāti",
|
||||
"say_something": "Teikt kaut ko",
|
||||
"scaffold_body_error_occurred": "Radās kļūda",
|
||||
"scan_all_libraries": "",
|
||||
"scan_settings": "",
|
||||
"search": "Meklēt",
|
||||
"search_albums": "Meklēt albumus",
|
||||
"search_by_context": "",
|
||||
"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_camera_title": "Select camera type",
|
||||
"search_filter_date": "Date",
|
||||
|
@ -1159,7 +847,6 @@
|
|||
"search_filter_media_type": "Media Type",
|
||||
"search_filter_media_type_title": "Select media type",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_for_existing_person": "",
|
||||
"search_no_more_result": "No more results",
|
||||
"search_no_people": "Nav cilvēku",
|
||||
"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_map": "Jūsu Karte",
|
||||
"search_people": "Meklēt cilvēkus",
|
||||
"search_places": "",
|
||||
"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_2": "m:jūsu-meklēšanas-frāze",
|
||||
"search_timezone": "",
|
||||
"search_type": "",
|
||||
"search_your_photos": "Meklēt Jūsu fotoattēlus",
|
||||
"searching_locales": "",
|
||||
"second": "Sekunde",
|
||||
"select_album_cover": "Izvēlieties albuma vāciņu",
|
||||
"select_all": "",
|
||||
"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_user_for_sharing_page_err_album": "Neizdevās izveidot albumu",
|
||||
"selected": "",
|
||||
"send_message": "",
|
||||
"server_endpoint": "Server Endpoint",
|
||||
"server_info_box_app_version": "Aplikācijas Versija",
|
||||
"server_info_box_server_url": "Servera URL",
|
||||
"server_online": "Serveris tiešsaistē",
|
||||
"server_stats": "Servera statistika",
|
||||
"server_version": "Servera versija",
|
||||
"set": "",
|
||||
"set_as_album_cover": "",
|
||||
"set_as_profile_picture": "",
|
||||
"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_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",
|
||||
|
@ -1235,7 +904,6 @@
|
|||
"setting_video_viewer_original_video_title": "Force original video",
|
||||
"settings": "Iestatījumi",
|
||||
"settings_require_restart": "Lūdzu, restartējiet Immich, lai lietotu šo iestatījumu",
|
||||
"settings_saved": "",
|
||||
"setup_pin_code": "Uzstādīt PIN kodu",
|
||||
"share": "Kopīgot",
|
||||
"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_remove_user": "Noņemt lietotāju no albuma",
|
||||
"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_link_app_bar_title": "Kopīgotas Saites",
|
||||
"shared_link_clipboard_copied_massage": "Ievietots starpliktuvē",
|
||||
|
@ -1286,7 +952,6 @@
|
|||
"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_empty_list": "TUKŠS SARAKSTS",
|
||||
"sharing_sidebar_description": "",
|
||||
"sharing_silver_appbar_create_shared_album": "Izveidot kopīgotu albumu",
|
||||
"sharing_silver_appbar_share_partner": "Dalīties ar partneri",
|
||||
"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_gallery": "Rādīt galeriju",
|
||||
"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_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_description": "Rādīt atbalstītāja nozīmīti",
|
||||
"shuffle": "",
|
||||
"sign_up": "",
|
||||
"size": "Izmērs",
|
||||
"skip_to_content": "",
|
||||
"slideshow": "Slīdrāde",
|
||||
"slideshow_settings": "Slīdrādes iestatījumi",
|
||||
"sort_albums_by": "Kārtot albumus pēc...",
|
||||
|
@ -1322,30 +976,21 @@
|
|||
"sort_title": "Nosaukums",
|
||||
"source": "Pirmkods",
|
||||
"stack": "Apvienot kaudzē",
|
||||
"stack_selected_photos": "",
|
||||
"stacktrace": "",
|
||||
"start_date": "",
|
||||
"state": "Štats",
|
||||
"status": "Statuss",
|
||||
"stop_motion_photo": "",
|
||||
"stop_photo_sharing": "Beigt kopīgot jūsu fotogrāfijas?",
|
||||
"storage": "Vieta krātuvē",
|
||||
"storage_label": "",
|
||||
"storage_usage": "{used} no {available} izmantoti",
|
||||
"submit": "Iesniegt",
|
||||
"suggestions": "Ieteikumi",
|
||||
"sunrise_on_the_beach": "Saullēkts pludmalē",
|
||||
"support": "Atbalsts",
|
||||
"support_and_feedback": "Atbalsts un atsauksmes",
|
||||
"swap_merge_direction": "",
|
||||
"sync": "Sinhronizēt",
|
||||
"sync_albums": "Sync 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",
|
||||
"template": "",
|
||||
"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_tiles_per_row_title": "Failu skaits rindā ({count})",
|
||||
"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_title": "Iespējot trīspakāpju ielādi",
|
||||
"they_will_be_merged_together": "Tās tiks apvienotas",
|
||||
"time_based_memories": "",
|
||||
"timezone": "Laika zona",
|
||||
"to_archive": "Arhivēt",
|
||||
"to_change_password": "Mainīt paroli",
|
||||
"toggle_settings": "Pārslēgt iestatījumus",
|
||||
"toggle_theme": "",
|
||||
"total_usage": "Kopējais lietojums",
|
||||
"trash": "Atkritne",
|
||||
"trash_all": "Dzēst Visu",
|
||||
"trash_emptied": "Emptied trash",
|
||||
"trash_no_results_message": "",
|
||||
"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_info": "Atkritnes vienumi tiks neatgriezeniski dzēsti pēc {days} dienām",
|
||||
|
@ -1378,26 +1020,19 @@
|
|||
"trash_page_restore_all": "Atjaunot Visu",
|
||||
"trash_page_select_assets_btn": "Atlasīt aktīvus",
|
||||
"trash_page_title": "Atkritne ({count})",
|
||||
"type": "",
|
||||
"unable_to_change_pin_code": "Neizdevās nomainīt PIN kodu",
|
||||
"unable_to_setup_pin_code": "Neizdevās uzstādīt PIN kodu",
|
||||
"unarchive": "Atarhivēt",
|
||||
"unfavorite": "Noņemt no izlases",
|
||||
"unhide_person": "Atcelt personas slēpšanu",
|
||||
"unknown": "",
|
||||
"unknown_country": "Nezināma Valsts",
|
||||
"unknown_year": "Nezināms gads",
|
||||
"unlimited": "Neierobežots",
|
||||
"unlink_oauth": "",
|
||||
"unlinked_oauth_account": "",
|
||||
"unnamed_album": "Albums bez nosaukuma",
|
||||
"unsaved_change": "Nesaglabāta izmaiņa",
|
||||
"unselect_all": "",
|
||||
"unstack": "At-Stekot",
|
||||
"up_next": "",
|
||||
"updated_password": "Parole ir atjaunināta",
|
||||
"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_title": "Augšupielādēt Aktīvu",
|
||||
"upload_status_duplicates": "Dublikāti",
|
||||
|
@ -1405,7 +1040,6 @@
|
|||
"upload_status_uploaded": "Augšupielādēts",
|
||||
"upload_to_immich": "Augšupielādēt Immich ({count})",
|
||||
"uploading": "Uploading",
|
||||
"url": "",
|
||||
"usage": "Lietojums",
|
||||
"use_current_connection": "use current connection",
|
||||
"user": "Lietotājs",
|
||||
|
@ -1416,9 +1050,7 @@
|
|||
"username": "Lietotājvārds",
|
||||
"users": "Lietotāji",
|
||||
"utilities": "Rīki",
|
||||
"validate": "",
|
||||
"validate_endpoint_error": "Please enter a valid URL",
|
||||
"variables": "",
|
||||
"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_overlay_release_notes": "informācija par laidienu",
|
||||
|
@ -1429,20 +1061,15 @@
|
|||
"version_history": "Versiju vēsture",
|
||||
"version_history_item": "{version} uzstādīta {date}",
|
||||
"video": "Videoklips",
|
||||
"video_hover_setting_description": "",
|
||||
"videos": "Videoklipi",
|
||||
"view_album": "Skatīt Albumu",
|
||||
"view_all": "Apskatīt visu",
|
||||
"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_stack_use_as_main_asset": "Izmantot kā Galveno Aktīvu",
|
||||
"viewer_unstack": "At-Stekot",
|
||||
"waiting": "Gaida",
|
||||
"week": "Nedēļa",
|
||||
"welcome_to_immich": "",
|
||||
"wifi_name": "WiFi Name",
|
||||
"year": "Gads",
|
||||
"years_ago": "Pirms {years, plural, one {# gada} other {# gadiem}}",
|
||||
|
|
639
i18n/mn.json
639
i18n/mn.json
File diff suppressed because it is too large
Load diff
|
@ -301,7 +301,6 @@
|
|||
"transcoding_reference_frames_description": "கொடுக்கப்பட்ட சட்டகத்தை சுருக்கும்போது குறிப்பிட வேண்டிய பிரேம்களின் எண்ணிக்கை. அதிக மதிப்புகள் சுருக்க செயல்திறனை மேம்படுத்துகின்றன, ஆனால் குறியாக்கத்தை மெதுவாக்குகின்றன. 0 இந்த மதிப்பை தானாக அமைக்கிறது.",
|
||||
"transcoding_required_description": "ஏற்றுக்கொள்ளப்பட்ட வடிவத்தில் இல்லாத வீடியோக்கள் மட்டுமே",
|
||||
"transcoding_settings": "வீடியோ டிரான்ச்கோடிங் அமைப்புகள்",
|
||||
"transcoding_settings_description": "",
|
||||
"transcoding_target_resolution": "இலக்கு தீர்மானம்",
|
||||
"transcoding_target_resolution_description": "அதிக தீர்மானங்கள் அதிக விவரங்களை பாதுகாக்க முடியும், ஆனால் குறியாக்க அதிக நேரம் எடுக்கும், பெரிய கோப்பு அளவுகளைக் கொண்டிருக்கலாம், மேலும் பயன்பாட்டு மறுமொழியைக் குறைக்கலாம்.",
|
||||
"transcoding_temporal_aq": "தம்போர்ல்",
|
||||
|
@ -314,7 +313,6 @@
|
|||
"transcoding_transcode_policy_description": "ஒரு வீடியோ எப்போது மாற்றப்பட வேண்டும் என்பதற்கான கொள்கை. எச்.டி.ஆர் வீடியோக்கள் எப்போதும் டிரான்ச்கோட் செய்யப்படும் (டிரான்ச்கோடிங் முடக்கப்பட்டிருந்தால் தவிர).",
|
||||
"transcoding_two_pass_encoding": "இரண்டு-பாச் குறியாக்கம்",
|
||||
"transcoding_two_pass_encoding_setting_description": "சிறந்த குறியாக்கப்பட்ட வீடியோக்களை உருவாக்க இரண்டு பாச்களில் டிரான்ச்கோட். மேக்ச் பிட்ரேட் இயக்கப்பட்டிருக்கும்போது (H.264 மற்றும் HEVC உடன் வேலை செய்ய இது தேவைப்படுகிறது), இந்த பயன்முறை அதிகபட்ச பிட்ரேட்டை அடிப்படையாகக் கொண்ட பிட்ரேட் வரம்பைப் பயன்படுத்துகிறது மற்றும் CRF ஐ புறக்கணிக்கிறது. VP9 ஐப் பொறுத்தவரை, அதிகபட்ச பிட்ரேட் முடக்கப்பட்டிருந்தால் CRF ஐப் பயன்படுத்தலாம்.",
|
||||
"transcoding_video_codec": "",
|
||||
"transcoding_video_codec_description": "VP9 அதிக செயல்திறன் மற்றும் வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது, ஆனால் டிரான்ச்கோடிற்கு அதிக நேரம் எடுக்கும். HEVC இதேபோல் செயல்படுகிறது, ஆனால் குறைந்த வலை பொருந்தக்கூடிய தன்மையைக் கொண்டுள்ளது. H.264 பரவலாக இணக்கமானது மற்றும் டிரான்ச்கோடு விரைவானது, ஆனால் மிகப் பெரிய கோப்புகளை உருவாக்குகிறது. ஏ.வி 1 மிகவும் திறமையான கோடெக் ஆனால் பழைய சாதனங்களில் உதவி இல்லை.",
|
||||
"trash_enabled_description": "குப்பை அம்சங்களை இயக்கவும்",
|
||||
"trash_number_of_days": "நாட்களின் எண்ணிக்கை",
|
||||
|
|
|
@ -1700,7 +1700,6 @@
|
|||
"stack_duplicates": "นำสิ่งที่ซ้ำมาซ้อนอยู่ด้วยกัน",
|
||||
"stack_select_one_photo": "เลือกรูปหลักหนึ่งรูปสำหรับรูปที่ซ้อนกันนี้",
|
||||
"stack_selected_photos": "ซ้อนรูปที่ถูกเลือก",
|
||||
"stacktrace": "",
|
||||
"start": "เริ่มต้น",
|
||||
"start_date": "วันที่เริ่ม",
|
||||
"state": "รัฐ",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<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_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
|
||||
<!-- Foreground service permission -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package app.alextran.immich
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import androidx.annotation.NonNull
|
||||
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
|
||||
class MainActivity : FlutterActivity() {
|
||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
flutterEngine.plugins.add(BackgroundServicePlugin())
|
||||
flutterEngine.plugins.add(HttpSSLOptionsPlugin())
|
||||
// No need to set up method channel here as it's now handled in the plugin
|
||||
}
|
||||
class MainActivity : FlutterFragmentActivity() {
|
||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
flutterEngine.plugins.add(BackgroundServicePlugin())
|
||||
flutterEngine.plugins.add(HttpSSLOptionsPlugin())
|
||||
// No need to set up method channel here as it's now handled in the plugin
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode
|
||||
setting is off -->
|
||||
<style name="LaunchTheme" parent="Theme.AppCompat.DayNight">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:windowFullscreen">false</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -44,6 +44,8 @@ PODS:
|
|||
- Flutter
|
||||
- flutter_native_splash (2.4.3):
|
||||
- Flutter
|
||||
- flutter_secure_storage (6.0.0):
|
||||
- Flutter
|
||||
- flutter_udid (0.0.1):
|
||||
- Flutter
|
||||
- SAMKeychain
|
||||
|
@ -59,6 +61,9 @@ PODS:
|
|||
- Flutter
|
||||
- isar_flutter_libs (1.0.0):
|
||||
- Flutter
|
||||
- local_auth_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- MapLibre (6.5.0)
|
||||
- maplibre_gl (0.0.1):
|
||||
- Flutter
|
||||
|
@ -130,6 +135,7 @@ DEPENDENCIES:
|
|||
- Flutter (from `Flutter`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/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_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
|
@ -137,6 +143,7 @@ DEPENDENCIES:
|
|||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- integration_test (from `.symlinks/plugins/integration_test/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`)
|
||||
- native_video_player (from `.symlinks/plugins/native_video_player/ios`)
|
||||
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
|
||||
|
@ -178,6 +185,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||
flutter_native_splash:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
flutter_secure_storage:
|
||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||
flutter_udid:
|
||||
:path: ".symlinks/plugins/flutter_udid/ios"
|
||||
flutter_web_auth_2:
|
||||
|
@ -192,6 +201,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/integration_test/ios"
|
||||
isar_flutter_libs:
|
||||
:path: ".symlinks/plugins/isar_flutter_libs/ios"
|
||||
local_auth_darwin:
|
||||
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||
maplibre_gl:
|
||||
:path: ".symlinks/plugins/maplibre_gl/ios"
|
||||
native_video_player:
|
||||
|
@ -233,6 +244,7 @@ SPEC CHECKSUMS:
|
|||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
|
||||
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
|
||||
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
||||
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
|
||||
flutter_web_auth_2: 5c8d9dcd7848b5a9efb086d24e7a9adcae979c80
|
||||
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||
|
@ -240,6 +252,7 @@ SPEC CHECKSUMS:
|
|||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||
isar_flutter_libs: bc909e72c3d756c2759f14c8776c13b5b0556e26
|
||||
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
|
||||
MapLibre: 0ebfa9329d313cec8bf0a5ba5a336a1dc903785e
|
||||
maplibre_gl: eab61cca6e1cfa9187249bacd3f08b51e8cd8ae9
|
||||
native_video_player: b65c58951ede2f93d103a25366bdebca95081265
|
||||
|
|
|
@ -1,165 +1,167 @@
|
|||
<?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">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AppGroupId</key>
|
||||
<string>$(CUSTOM_GROUP_ID)</string>
|
||||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||
<array>
|
||||
<string>app.alextran.immich.backgroundFetch</string>
|
||||
<string>app.alextran.immich.backgroundProcessing</string>
|
||||
</array>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ShareHandler</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.file-url</string>
|
||||
<string>public.image</string>
|
||||
<string>public.text</string>
|
||||
<string>public.movie</string>
|
||||
<string>public.url</string>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
<string>ar</string>
|
||||
<string>ca</string>
|
||||
<string>cs</string>
|
||||
<string>da</string>
|
||||
<string>de</string>
|
||||
<string>es</string>
|
||||
<string>fi</string>
|
||||
<string>fr</string>
|
||||
<string>he</string>
|
||||
<string>hi</string>
|
||||
<string>hu</string>
|
||||
<string>it</string>
|
||||
<string>ja</string>
|
||||
<string>ko</string>
|
||||
<string>lv</string>
|
||||
<string>mn</string>
|
||||
<string>nb</string>
|
||||
<string>nl</string>
|
||||
<string>pl</string>
|
||||
<string>pt</string>
|
||||
<string>ro</string>
|
||||
<string>ru</string>
|
||||
<string>sk</string>
|
||||
<string>sl</string>
|
||||
<string>sr</string>
|
||||
<string>sv</string>
|
||||
<string>th</string>
|
||||
<string>uk</string>
|
||||
<string>vi</string>
|
||||
<string>zh</string>
|
||||
</array>
|
||||
<key>CFBundleName</key>
|
||||
<string>immich_mobile</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.132.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>205</string>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<string>No</string>
|
||||
<key>MGLMapboxMetricsEnabledSettingShownInApp</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need to access the camera to let you take beautiful video using this app</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name for background upload mechanism</string>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need to access the microphone to let you take beautiful video using this app</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>INSendMessageIntent</string>
|
||||
</array>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>processing</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<dict>
|
||||
<key>AppGroupId</key>
|
||||
<string>$(CUSTOM_GROUP_ID)</string>
|
||||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||
<array>
|
||||
<string>app.alextran.immich.backgroundFetch</string>
|
||||
<string>app.alextran.immich.backgroundProcessing</string>
|
||||
</array>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true />
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>ShareHandler</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.file-url</string>
|
||||
<string>public.image</string>
|
||||
<string>public.text</string>
|
||||
<string>public.movie</string>
|
||||
<string>public.url</string>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
<string>ar</string>
|
||||
<string>ca</string>
|
||||
<string>cs</string>
|
||||
<string>da</string>
|
||||
<string>de</string>
|
||||
<string>es</string>
|
||||
<string>fi</string>
|
||||
<string>fr</string>
|
||||
<string>he</string>
|
||||
<string>hi</string>
|
||||
<string>hu</string>
|
||||
<string>it</string>
|
||||
<string>ja</string>
|
||||
<string>ko</string>
|
||||
<string>lv</string>
|
||||
<string>mn</string>
|
||||
<string>nb</string>
|
||||
<string>nl</string>
|
||||
<string>pl</string>
|
||||
<string>pt</string>
|
||||
<string>ro</string>
|
||||
<string>ru</string>
|
||||
<string>sk</string>
|
||||
<string>sl</string>
|
||||
<string>sr</string>
|
||||
<string>sv</string>
|
||||
<string>th</string>
|
||||
<string>uk</string>
|
||||
<string>vi</string>
|
||||
<string>zh</string>
|
||||
</array>
|
||||
<key>CFBundleName</key>
|
||||
<string>immich_mobile</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.132.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>205</string>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true />
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false />
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true />
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<string>No</string>
|
||||
<key>MGLMapboxMetricsEnabledSettingShownInApp</key>
|
||||
<true />
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true />
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need to access the camera to let you take beautiful video using this app</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name for background upload mechanism</string>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>We require this permission to access the local WiFi name</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need to access the microphone to let you take beautiful video using this app</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need to manage backup your photos album</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>INSendMessageIntent</string>
|
||||
</array>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true />
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>processing</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false />
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true />
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true />
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>We need to use FaceID to allow access to your locked folder</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -11,3 +11,6 @@ const int kSyncEventBatchSize = 5000;
|
|||
// Hash batch limits
|
||||
const int kBatchHashFileLimit = 128;
|
||||
const int kBatchHashSizeLimit = 1024 * 1024 * 1024; // 1GB
|
||||
|
||||
// Secure storage keys
|
||||
const String kSecuredPinCode = "secured_pin_code";
|
||||
|
|
|
@ -8,3 +8,5 @@ enum TextSearchType {
|
|||
filename,
|
||||
description,
|
||||
}
|
||||
|
||||
enum AssetVisibilityEnum { timeline, hidden, archive, locked }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:immich_mobile/constants/enums.dart';
|
||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
||||
import 'package:immich_mobile/extensions/string_extensions.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'
|
||||
|
@ -45,7 +46,8 @@ class Asset {
|
|||
: remote.stack?.primaryAssetId,
|
||||
stackCount = remote.stack?.assetCount ?? 0,
|
||||
stackId = remote.stack?.id,
|
||||
thumbhash = remote.thumbhash;
|
||||
thumbhash = remote.thumbhash,
|
||||
visibility = getVisibility(remote.visibility);
|
||||
|
||||
Asset({
|
||||
this.id = Isar.autoIncrement,
|
||||
|
@ -71,6 +73,7 @@ class Asset {
|
|||
this.stackCount = 0,
|
||||
this.isOffline = false,
|
||||
this.thumbhash,
|
||||
this.visibility = AssetVisibilityEnum.timeline,
|
||||
});
|
||||
|
||||
@ignore
|
||||
|
@ -173,6 +176,9 @@ class Asset {
|
|||
|
||||
int stackCount;
|
||||
|
||||
@Enumerated(EnumType.ordinal)
|
||||
AssetVisibilityEnum visibility;
|
||||
|
||||
/// Returns null if the asset has no sync access to the exif info
|
||||
@ignore
|
||||
double? get aspectRatio {
|
||||
|
@ -349,7 +355,8 @@ class Asset {
|
|||
a.thumbhash != thumbhash ||
|
||||
stackId != a.stackId ||
|
||||
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]
|
||||
|
@ -452,6 +459,7 @@ class Asset {
|
|||
String? stackPrimaryAssetId,
|
||||
int? stackCount,
|
||||
String? thumbhash,
|
||||
AssetVisibilityEnum? visibility,
|
||||
}) =>
|
||||
Asset(
|
||||
id: id ?? this.id,
|
||||
|
@ -477,6 +485,7 @@ class Asset {
|
|||
stackPrimaryAssetId: stackPrimaryAssetId ?? this.stackPrimaryAssetId,
|
||||
stackCount: stackCount ?? this.stackCount,
|
||||
thumbhash: thumbhash ?? this.thumbhash,
|
||||
visibility: visibility ?? this.visibility,
|
||||
);
|
||||
|
||||
Future<void> put(Isar db) async {
|
||||
|
@ -541,8 +550,22 @@ class Asset {
|
|||
"isArchived": $isArchived,
|
||||
"isTrashed": $isTrashed,
|
||||
"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 {
|
||||
|
|
121
mobile/lib/entities/asset.entity.g.dart
generated
121
mobile/lib/entities/asset.entity.g.dart
generated
|
@ -118,8 +118,14 @@ const AssetSchema = CollectionSchema(
|
|||
name: r'updatedAt',
|
||||
type: IsarType.dateTime,
|
||||
),
|
||||
r'width': PropertySchema(
|
||||
r'visibility': PropertySchema(
|
||||
id: 20,
|
||||
name: r'visibility',
|
||||
type: IsarType.byte,
|
||||
enumMap: _AssetvisibilityEnumValueMap,
|
||||
),
|
||||
r'width': PropertySchema(
|
||||
id: 21,
|
||||
name: r'width',
|
||||
type: IsarType.int,
|
||||
)
|
||||
|
@ -256,7 +262,8 @@ void _assetSerialize(
|
|||
writer.writeString(offsets[17], object.thumbhash);
|
||||
writer.writeByte(offsets[18], object.type.index);
|
||||
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(
|
||||
|
@ -288,7 +295,10 @@ Asset _assetDeserialize(
|
|||
type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[18])] ??
|
||||
AssetType.other,
|
||||
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;
|
||||
}
|
||||
|
@ -342,6 +352,9 @@ P _assetDeserializeProp<P>(
|
|||
case 19:
|
||||
return (reader.readDateTime(offset)) as P;
|
||||
case 20:
|
||||
return (_AssetvisibilityValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||
AssetVisibilityEnum.timeline) as P;
|
||||
case 21:
|
||||
return (reader.readIntOrNull(offset)) as P;
|
||||
default:
|
||||
throw IsarError('Unknown property with id $propertyId');
|
||||
|
@ -360,6 +373,18 @@ const _AssettypeValueEnumMap = {
|
|||
2: AssetType.video,
|
||||
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) {
|
||||
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() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
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() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
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() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
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() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
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() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'width');
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:immich_mobile/constants/enums.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
|
||||
abstract interface class IAssetApiRepository {
|
||||
|
@ -15,4 +16,9 @@ abstract interface class IAssetApiRepository {
|
|||
// Future<void> delete(String id);
|
||||
|
||||
Future<List<Asset>> search({List<String> personIds = const []});
|
||||
|
||||
Future<void> updateVisibility(
|
||||
List<String> list,
|
||||
AssetVisibilityEnum visibility,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,4 +6,9 @@ abstract interface class IAuthApiRepository {
|
|||
Future<void> logout();
|
||||
|
||||
Future<void> changePassword(String newPassword);
|
||||
|
||||
Future<bool> unlockPinCode(String pinCode);
|
||||
Future<void> lockPinCode();
|
||||
|
||||
Future<void> setupPinCode(String pinCode);
|
||||
}
|
||||
|
|
6
mobile/lib/interfaces/biometric.interface.dart
Normal file
6
mobile/lib/interfaces/biometric.interface.dart
Normal 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);
|
||||
}
|
5
mobile/lib/interfaces/secure_storage.interface.dart
Normal file
5
mobile/lib/interfaces/secure_storage.interface.dart
Normal 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);
|
||||
}
|
|
@ -31,4 +31,9 @@ abstract class ITimelineRepository {
|
|||
);
|
||||
|
||||
Stream<RenderList> watchAssetSelectionTimeline(String userId);
|
||||
|
||||
Stream<RenderList> watchLockedTimeline(
|
||||
String userId,
|
||||
GroupAssetsBy groupAssetsBy,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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/theme.provider.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/local_notification.service.dart';
|
||||
import 'package:immich_mobile/theme/dynamic_theme.dart';
|
||||
|
@ -219,7 +219,7 @@ class ImmichAppState extends ConsumerState<ImmichApp>
|
|||
),
|
||||
routeInformationParser: router.defaultRouteParser(),
|
||||
routerDelegate: router.delegate(
|
||||
navigatorObservers: () => [TabNavigationObserver(ref: ref)],
|
||||
navigatorObservers: () => [AppNavigationObserver(ref: ref)],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
38
mobile/lib/models/auth/biometric_status.model.dart
Normal file
38
mobile/lib/models/auth/biometric_status.model.dart
Normal 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;
|
||||
}
|
|
@ -140,6 +140,19 @@ class QuickAccessButtons extends ConsumerWidget {
|
|||
),
|
||||
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(
|
||||
leading: const Icon(
|
||||
Icons.group_outlined,
|
||||
|
|
95
mobile/lib/pages/library/locked/locked.page.dart
Normal file
95
mobile/lib/pages/library/locked/locked.page.dart
Normal 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);
|
||||
}
|
127
mobile/lib/pages/library/locked/pin_auth.page.dart
Normal file
127
mobile/lib/pages/library/locked/pin_auth.page.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.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/services/user.service.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
|
@ -170,6 +171,13 @@ class AssetNotifier extends StateNotifier<bool> {
|
|||
status ??= !assets.every((a) => a.isArchived);
|
||||
return _assetService.changeArchiveStatus(assets, status);
|
||||
}
|
||||
|
||||
Future<void> setLockedView(
|
||||
List<Asset> selection,
|
||||
AssetVisibilityEnum visibility,
|
||||
) {
|
||||
return _assetService.setVisibility(selection, visibility);
|
||||
}
|
||||
}
|
||||
|
||||
final assetDetailProvider =
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_udid/flutter_udid.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/user.model.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/services/api.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:logging/logging.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
@ -20,6 +22,7 @@ final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
|
|||
ref.watch(authServiceProvider),
|
||||
ref.watch(apiServiceProvider),
|
||||
ref.watch(userServiceProvider),
|
||||
ref.watch(secureStorageServiceProvider),
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -27,12 +30,17 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
final AuthService _authService;
|
||||
final ApiService _apiService;
|
||||
final UserService _userService;
|
||||
final SecureStorageService _secureStorageService;
|
||||
final _log = Logger("AuthenticationNotifier");
|
||||
|
||||
static const Duration _timeoutDuration = Duration(seconds: 7);
|
||||
|
||||
AuthNotifier(this._authService, this._apiService, this._userService)
|
||||
: super(
|
||||
AuthNotifier(
|
||||
this._authService,
|
||||
this._apiService,
|
||||
this._userService,
|
||||
this._secureStorageService,
|
||||
) : super(
|
||||
AuthState(
|
||||
deviceId: "",
|
||||
userId: "",
|
||||
|
@ -67,6 +75,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
|
||||
Future<void> logout() async {
|
||||
try {
|
||||
await _secureStorageService.delete(kSecuredPinCode);
|
||||
await _authService.logout();
|
||||
} finally {
|
||||
await _cleanUp();
|
||||
|
@ -188,4 +197,16 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||
Future<String?> 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);
|
||||
}
|
||||
}
|
||||
|
|
97
mobile/lib/providers/local_auth.provider.dart
Normal file
97
mobile/lib/providers/local_auth.provider.dart
Normal 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;
|
||||
}
|
||||
}
|
3
mobile/lib/providers/routes.provider.dart
Normal file
3
mobile/lib/providers/routes.provider.dart
Normal file
|
@ -0,0 +1,3 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
final inLockedViewProvider = StateProvider<bool>((ref) => false);
|
10
mobile/lib/providers/secure_storage.provider.dart
Normal file
10
mobile/lib/providers/secure_storage.provider.dart
Normal 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);
|
||||
}
|
|
@ -73,3 +73,8 @@ final assetsTimelineProvider =
|
|||
null,
|
||||
);
|
||||
});
|
||||
|
||||
final lockedTimelineProvider = StreamProvider<RenderList>((ref) {
|
||||
final timelineService = ref.watch(timelineServiceProvider);
|
||||
return timelineService.watchLockedTimelineProvider();
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
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/interfaces/asset_api.interface.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
|
@ -48,4 +49,27 @@ class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,4 +55,26 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
35
mobile/lib/repositories/biometric.repository.dart
Normal file
35
mobile/lib/repositories/biometric.repository.dart
Normal 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(),
|
||||
);
|
||||
}
|
||||
}
|
27
mobile/lib/repositories/secure_storage.repository.dart
Normal file
27
mobile/lib/repositories/secure_storage.repository.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -45,8 +45,8 @@ class TimelineRepository extends DatabaseRepository
|
|||
.where()
|
||||
.ownerIdEqualToAnyChecksum(fastHash(userId))
|
||||
.filter()
|
||||
.isArchivedEqualTo(true)
|
||||
.isTrashedEqualTo(false)
|
||||
.visibilityEqualTo(AssetVisibilityEnum.archive)
|
||||
.sortByFileCreatedAtDesc();
|
||||
|
||||
return _watchRenderList(query, GroupAssetsBy.none);
|
||||
|
@ -59,6 +59,8 @@ class TimelineRepository extends DatabaseRepository
|
|||
.ownerIdEqualToAnyChecksum(fastHash(userId))
|
||||
.filter()
|
||||
.isFavoriteEqualTo(true)
|
||||
.not()
|
||||
.visibilityEqualTo(AssetVisibilityEnum.locked)
|
||||
.isTrashedEqualTo(false)
|
||||
.sortByFileCreatedAtDesc();
|
||||
|
||||
|
@ -94,8 +96,8 @@ class TimelineRepository extends DatabaseRepository
|
|||
Stream<RenderList> watchAllVideosTimeline() {
|
||||
final query = db.assets
|
||||
.filter()
|
||||
.isArchivedEqualTo(false)
|
||||
.isTrashedEqualTo(false)
|
||||
.visibilityEqualTo(AssetVisibilityEnum.timeline)
|
||||
.typeEqualTo(AssetType.video)
|
||||
.sortByFileCreatedAtDesc();
|
||||
|
||||
|
@ -111,9 +113,9 @@ class TimelineRepository extends DatabaseRepository
|
|||
.where()
|
||||
.ownerIdEqualToAnyChecksum(fastHash(userId))
|
||||
.filter()
|
||||
.isArchivedEqualTo(false)
|
||||
.isTrashedEqualTo(false)
|
||||
.stackPrimaryAssetIdIsNull()
|
||||
.visibilityEqualTo(AssetVisibilityEnum.timeline)
|
||||
.sortByFileCreatedAtDesc();
|
||||
|
||||
return _watchRenderList(query, groupAssetByOption);
|
||||
|
@ -129,8 +131,8 @@ class TimelineRepository extends DatabaseRepository
|
|||
.where()
|
||||
.anyOf(isarUserIds, (qb, id) => qb.ownerIdEqualToAnyChecksum(id))
|
||||
.filter()
|
||||
.isArchivedEqualTo(false)
|
||||
.isTrashedEqualTo(false)
|
||||
.visibilityEqualTo(AssetVisibilityEnum.timeline)
|
||||
.stackPrimaryAssetIdIsNull()
|
||||
.sortByFileCreatedAtDesc();
|
||||
return _watchRenderList(query, groupAssetByOption);
|
||||
|
@ -151,6 +153,7 @@ class TimelineRepository extends DatabaseRepository
|
|||
.remoteIdIsNotNull()
|
||||
.filter()
|
||||
.ownerIdEqualTo(fastHash(userId))
|
||||
.visibilityEqualTo(AssetVisibilityEnum.timeline)
|
||||
.isTrashedEqualTo(false)
|
||||
.stackPrimaryAssetIdIsNull()
|
||||
.sortByFileCreatedAtDesc();
|
||||
|
@ -158,6 +161,22 @@ class TimelineRepository extends DatabaseRepository
|
|||
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(
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> query,
|
||||
GroupAssetsBy groupAssetsBy,
|
||||
|
|
52
mobile/lib/routing/app_navigation_observer.dart
Normal file
52
mobile/lib/routing/app_navigation_observer.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
89
mobile/lib/routing/locked_guard.dart
Normal file
89
mobile/lib/routing/locked_guard.dart
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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/library.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_detail.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/custom_transition_builders.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/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:maplibre_gl/maplibre_gl.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')
|
||||
class AppRouter extends RootStackRouter {
|
||||
late final AuthGuard _authGuard;
|
||||
late final DuplicateGuard _duplicateGuard;
|
||||
late final BackupPermissionGuard _backupPermissionGuard;
|
||||
late final LockedGuard _lockedGuard;
|
||||
|
||||
AppRouter(
|
||||
ApiService apiService,
|
||||
GalleryPermissionNotifier galleryPermissionNotifier,
|
||||
SecureStorageService secureStorageService,
|
||||
LocalAuthService localAuthService,
|
||||
) {
|
||||
_authGuard = AuthGuard(apiService);
|
||||
_duplicateGuard = DuplicateGuard();
|
||||
_lockedGuard =
|
||||
LockedGuard(apiService, secureStorageService, localAuthService);
|
||||
_backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier);
|
||||
}
|
||||
|
||||
|
@ -289,12 +308,13 @@ class AppRouter extends RootStackRouter {
|
|||
page: ShareIntentRoute.page,
|
||||
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),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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
|
||||
/// [LoginPage]
|
||||
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
|
||||
/// [PlacesCollectionPage]
|
||||
class PlacesCollectionRoute extends PageRouteInfo<PlacesCollectionRouteArgs> {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ import 'dart:async';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.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/user.interface.dart';
|
||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||
|
@ -239,6 +240,9 @@ class AssetService {
|
|||
|
||||
for (var element in assets) {
|
||||
element.isArchived = isArchived;
|
||||
element.visibility = isArchived
|
||||
? AssetVisibilityEnum.archive
|
||||
: AssetVisibilityEnum.timeline;
|
||||
}
|
||||
|
||||
await _syncService.upsertAssetsWithExif(assets);
|
||||
|
@ -458,6 +462,7 @@ class AssetService {
|
|||
bool shouldDeletePermanently = false,
|
||||
}) async {
|
||||
final candidates = assets.where((a) => a.isRemote);
|
||||
|
||||
if (candidates.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
@ -475,6 +480,7 @@ class AssetService {
|
|||
.where((asset) => asset.storage == AssetState.merged)
|
||||
.map((asset) {
|
||||
asset.remoteId = null;
|
||||
asset.visibility = AssetVisibilityEnum.timeline;
|
||||
return asset;
|
||||
})
|
||||
: assets.where((asset) => asset.isRemote).map((asset) {
|
||||
|
@ -529,4 +535,21 @@ class AssetService {
|
|||
final me = _userService.getMyUser();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,4 +201,16 @@ class AuthService {
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
26
mobile/lib/services/local_auth.service.dart
Normal file
26
mobile/lib/services/local_auth.service.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset.repository.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
import 'package:immich_mobile/utils/translation.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
final memoryServiceProvider = StateProvider<MemoryService>((ref) {
|
||||
|
@ -40,10 +40,7 @@ class MemoryService {
|
|||
.getAllByRemoteId(memory.assets.map((e) => e.id));
|
||||
final yearsAgo = now.year - memory.data.year;
|
||||
if (dbAssets.isNotEmpty) {
|
||||
final String title = yearsAgo <= 1
|
||||
? 'memories_year_ago'.tr()
|
||||
: 'memories_years_ago'
|
||||
.tr(namedArgs: {'years': yearsAgo.toString()});
|
||||
final String title = t('years_ago', {'years': yearsAgo.toString()});
|
||||
memories.add(
|
||||
Memory(
|
||||
title: title,
|
||||
|
|
29
mobile/lib/services/secure_storage.service.dart
Normal file
29
mobile/lib/services/secure_storage.service.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -105,4 +105,13 @@ class TimelineService {
|
|||
return GroupAssetsBy
|
||||
.values[_appSettingsService.getSetting(AppSettingsEnum.groupAssetsBy)];
|
||||
}
|
||||
|
||||
Stream<RenderList> watchLockedTimelineProvider() async* {
|
||||
final user = _userService.getMyUser();
|
||||
|
||||
yield* _timelineRepository.watchLockedTimeline(
|
||||
user.id,
|
||||
_getGroupByOption(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ ThemeData getThemeData({
|
|||
titleTextStyle: TextStyle(
|
||||
color: colorScheme.primary,
|
||||
fontFamily: _getFontFamilyFromLocale(locale),
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
),
|
||||
backgroundColor:
|
||||
|
@ -54,28 +54,28 @@ ThemeData getThemeData({
|
|||
),
|
||||
textTheme: const TextTheme(
|
||||
displayLarge: TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
displayMedium: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
displaySmall: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
titleSmall: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
titleMedium: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
titleLarge: TextStyle(
|
||||
fontSize: 26.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
|
|
|
@ -20,7 +20,7 @@ import 'package:isar/isar.dart';
|
|||
// ignore: import_rule_photo_manager
|
||||
import 'package:photo_manager/photo_manager.dart';
|
||||
|
||||
const int targetVersion = 10;
|
||||
const int targetVersion = 11;
|
||||
|
||||
Future<void> migrateDatabaseIfNeeded(Isar db) async {
|
||||
final int version = Store.get(StoreKey.version, targetVersion);
|
||||
|
|
|
@ -29,7 +29,11 @@ dynamic upgradeDto(dynamic value, String targetType) {
|
|||
case 'UserResponseDto':
|
||||
if (value is Map) {
|
||||
addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String());
|
||||
addDefault(value, 'visibility', AssetVisibility.timeline);
|
||||
}
|
||||
break;
|
||||
case 'AssetResponseDto':
|
||||
if (value is Map) {
|
||||
addDefault(value, 'visibility', 'timeline');
|
||||
}
|
||||
break;
|
||||
case 'UserAdminResponseDto':
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.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/extensions/asset_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);
|
||||
}
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ 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/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/models/asset_selection_state.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()? onEditLocation;
|
||||
final void Function()? onRemoveFromAlbum;
|
||||
final void Function()? onToggleLocked;
|
||||
|
||||
final bool enabled;
|
||||
final bool unfavorite;
|
||||
|
@ -58,6 +60,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
this.onEditTime,
|
||||
this.onEditLocation,
|
||||
this.onRemoveFromAlbum,
|
||||
this.onToggleLocked,
|
||||
this.selectionAssetState = const AssetSelectionState(),
|
||||
this.enabled = true,
|
||||
this.unarchive = false,
|
||||
|
@ -77,6 +80,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
ref.watch(albumProvider).where((a) => a.shared).toList();
|
||||
const bottomPadding = 0.20;
|
||||
final scrollController = useDraggableScrollController();
|
||||
final isInLockedView = ref.watch(inLockedViewProvider);
|
||||
|
||||
void minimize() {
|
||||
scrollController.animateTo(
|
||||
|
@ -133,11 +137,12 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
label: "share".tr(),
|
||||
onPressed: enabled ? () => onShare(true) : null,
|
||||
),
|
||||
ControlBoxButton(
|
||||
iconData: Icons.link_rounded,
|
||||
label: "control_bottom_app_bar_share_link".tr(),
|
||||
onPressed: enabled ? () => onShare(false) : null,
|
||||
),
|
||||
if (!isInLockedView)
|
||||
ControlBoxButton(
|
||||
iconData: Icons.link_rounded,
|
||||
label: "share_link".tr(),
|
||||
onPressed: enabled ? () => onShare(false) : null,
|
||||
),
|
||||
if (hasRemote && onArchive != null)
|
||||
ControlBoxButton(
|
||||
iconData:
|
||||
|
@ -153,7 +158,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
label: (unfavorite ? "unfavorite" : "favorite").tr(),
|
||||
onPressed: enabled ? onFavorite : null,
|
||||
),
|
||||
if (hasLocal && hasRemote && onDelete != null)
|
||||
if (hasLocal && hasRemote && onDelete != null && !isInLockedView)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 90),
|
||||
child: ControlBoxButton(
|
||||
|
@ -166,7 +171,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
enabled ? () => showForceDeleteDialog(onDelete!) : null,
|
||||
),
|
||||
),
|
||||
if (hasRemote && onDeleteServer != null)
|
||||
if (hasRemote && onDeleteServer != null && !isInLockedView)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 85),
|
||||
child: ControlBoxButton(
|
||||
|
@ -189,9 +194,23 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
: null,
|
||||
),
|
||||
),
|
||||
if (hasLocal && onDeleteLocal != null)
|
||||
if (isInLockedView)
|
||||
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(
|
||||
iconData: Icons.no_cell_outlined,
|
||||
label: "control_bottom_app_bar_delete_from_local".tr(),
|
||||
|
@ -231,6 +250,19 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
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 &&
|
||||
selectionAssetState.selectedCount > 1 &&
|
||||
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(
|
||||
controller: scrollController,
|
||||
initialChildSize: hasRemote ? 0.35 : bottomPadding,
|
||||
initialChildSize: getInitialSize(),
|
||||
minChildSize: bottomPadding,
|
||||
maxChildSize: hasRemote ? 0.65 : bottomPadding,
|
||||
maxChildSize: getMaxChildSize(),
|
||||
snap: true,
|
||||
builder: (
|
||||
BuildContext context,
|
||||
ScrollController scrollController,
|
||||
) {
|
||||
return Card(
|
||||
color: context.colorScheme.surfaceContainerLow,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
elevation: 18.0,
|
||||
color: context.colorScheme.surfaceContainerHigh,
|
||||
surfaceTintColor: context.colorScheme.surfaceContainerHigh,
|
||||
elevation: 6.0,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
|
@ -300,27 +352,27 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||
const CustomDraggingHandle(),
|
||||
const SizedBox(height: 12),
|
||||
SizedBox(
|
||||
height: 100,
|
||||
height: 120,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: renderActionButtons(),
|
||||
),
|
||||
),
|
||||
if (hasRemote)
|
||||
if (hasRemote && !isInLockedView) ...[
|
||||
const Divider(
|
||||
indent: 16,
|
||||
endIndent: 16,
|
||||
thickness: 1,
|
||||
),
|
||||
if (hasRemote)
|
||||
_AddToAlbumTitleRow(
|
||||
onCreateNewAlbum: enabled ? onCreateNewAlbum : null,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
if (hasRemote)
|
||||
if (hasRemote && !isInLockedView)
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
sliver: AddToAlbumSliverList(
|
||||
|
@ -352,12 +404,9 @@ class _AddToAlbumTitleRow extends StatelessWidget {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
"add_to_album",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: context.textTheme.titleSmall,
|
||||
).tr(),
|
||||
TextButton.icon(
|
||||
onPressed: onCreateNewAlbum,
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:fluttertoast/fluttertoast.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/asset.entity.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/backup/manual_upload.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/routing/router.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() fun, {
|
||||
bool showOverlay = true,
|
||||
|
@ -460,6 +488,7 @@ class MultiselectGrid extends HookConsumerWidget {
|
|||
onEditLocation: editEnabled ? onEditLocation : null,
|
||||
unfavorite: unfavorite,
|
||||
unarchive: unarchive,
|
||||
onToggleLocked: onToggleLockedVisibility,
|
||||
onRemoveFromAlbum: onRemoveFromAlbum != null
|
||||
? wrapLongRunningFun(
|
||||
() => onRemoveFromAlbum!(selection.value),
|
||||
|
|
|
@ -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/download.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/user.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
|
@ -46,6 +47,7 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isInLockedView = ref.watch(inLockedViewProvider);
|
||||
final asset = ref.watch(currentAssetProvider);
|
||||
if (asset == null) {
|
||||
return const SizedBox();
|
||||
|
@ -277,7 +279,7 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||
tooltip: 'share'.tr(),
|
||||
): (_) => shareAsset(),
|
||||
},
|
||||
if (asset.isImage)
|
||||
if (asset.isImage && !isInLockedView)
|
||||
{
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.tune_outlined),
|
||||
|
@ -285,7 +287,7 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||
tooltip: 'edit'.tr(),
|
||||
): (_) => handleEdit(),
|
||||
},
|
||||
if (isOwner)
|
||||
if (isOwner && !isInLockedView)
|
||||
{
|
||||
asset.isArchived
|
||||
? BottomNavigationBarItem(
|
||||
|
@ -299,7 +301,7 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||
tooltip: 'archive'.tr(),
|
||||
): (_) => handleArchive(),
|
||||
},
|
||||
if (isOwner && asset.stackCount > 0)
|
||||
if (isOwner && asset.stackCount > 0 && !isInLockedView)
|
||||
{
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.burst_mode_outlined),
|
||||
|
|
|
@ -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/entities/asset.entity.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/widgets/asset_viewer/motion_photo_button.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
|
@ -39,6 +40,7 @@ class TopControlAppBar extends HookConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isInLockedView = ref.watch(inLockedViewProvider);
|
||||
const double iconSize = 22.0;
|
||||
final a = ref.watch(assetWatcher(asset)).value ?? asset;
|
||||
final album = ref.watch(currentAlbumProvider);
|
||||
|
@ -178,15 +180,22 @@ class TopControlAppBar extends HookConsumerWidget {
|
|||
shape: const Border(),
|
||||
actions: [
|
||||
if (asset.isRemote && isOwner) buildFavoriteButton(a),
|
||||
if (isOwner && !isInHomePage && !(isInTrash ?? false))
|
||||
if (isOwner &&
|
||||
!isInHomePage &&
|
||||
!(isInTrash ?? false) &&
|
||||
!isInLockedView)
|
||||
buildLocateButton(),
|
||||
if (asset.livePhotoVideoId != null) const MotionPhotoButton(),
|
||||
if (asset.isLocal && !asset.isRemote) buildUploadButton(),
|
||||
if (asset.isRemote && !asset.isLocal && isOwner) buildDownloadButton(),
|
||||
if (asset.isRemote && (isOwner || isPartner) && !asset.isTrashed)
|
||||
if (asset.isRemote &&
|
||||
(isOwner || isPartner) &&
|
||||
!asset.isTrashed &&
|
||||
!isInLockedView)
|
||||
buildAddToAlbumButton(),
|
||||
if (asset.isTrashed) buildRestoreButton(),
|
||||
if (album != null && album.shared) buildActivitiesButton(),
|
||||
if (album != null && album.shared && !isInLockedView)
|
||||
buildActivitiesButton(),
|
||||
buildMoreInfoButton(),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -35,7 +35,9 @@ class ControlBoxButton extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return MaterialButton(
|
||||
padding: const EdgeInsets.all(10),
|
||||
shape: const CircleBorder(),
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
onPressed: onPressed,
|
||||
onLongPress: onLongPressed,
|
||||
minWidth: 75.0,
|
||||
|
@ -47,8 +49,8 @@ class ControlBoxButton extends StatelessWidget {
|
|||
const SizedBox(height: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12.0),
|
||||
maxLines: 2,
|
||||
style: const TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400),
|
||||
maxLines: 3,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -40,7 +40,7 @@ class ImmichToast {
|
|||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
|
||||
color: context.colorScheme.surfaceContainer,
|
||||
border: Border.all(
|
||||
color: context.colorScheme.outline.withValues(alpha: .5),
|
||||
|
@ -59,14 +59,23 @@ class ImmichToast {
|
|||
msg,
|
||||
style: TextStyle(
|
||||
color: getColor(toastType, context),
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
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,
|
||||
toastDuration: Duration(seconds: durationInSecond),
|
||||
);
|
||||
|
|
124
mobile/lib/widgets/forms/pin_input.dart
Normal file
124
mobile/lib/widgets/forms/pin_input.dart
Normal 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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
128
mobile/lib/widgets/forms/pin_registration_form.dart
Normal file
128
mobile/lib/widgets/forms/pin_registration_form.dart
Normal 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()),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
94
mobile/lib/widgets/forms/pin_verification_form.dart
Normal file
94
mobile/lib/widgets/forms/pin_verification_form.dart
Normal 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,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
84
mobile/openapi/lib/model/asset_response_dto.dart
generated
84
mobile/openapi/lib/model/asset_response_dto.dart
generated
|
@ -133,7 +133,7 @@ class AssetResponseDto {
|
|||
|
||||
DateTime updatedAt;
|
||||
|
||||
AssetResponseDtoVisibilityEnum visibility;
|
||||
AssetVisibility visibility;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto &&
|
||||
|
@ -318,7 +318,7 @@ class AssetResponseDto {
|
|||
type: AssetTypeEnum.fromJson(json[r'type'])!,
|
||||
unassignedFaces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'unassignedFaces']),
|
||||
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
|
||||
visibility: AssetResponseDtoVisibilityEnum.fromJson(json[r'visibility'])!,
|
||||
visibility: AssetVisibility.fromJson(json[r'visibility'])!,
|
||||
);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -621,6 +621,54 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -976,6 +1024,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1264,6 +1352,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
pinput:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pinput
|
||||
sha256: "8a73be426a91fefec90a7f130763ca39772d547e92f19a827cf4aa02e323d35a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.1"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1741,6 +1837,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -64,6 +64,9 @@ dependencies:
|
|||
uuid: ^4.5.1
|
||||
wakelock_plus: ^1.2.10
|
||||
worker_manager: ^7.2.3
|
||||
local_auth: ^2.3.0
|
||||
pinput: ^5.0.1
|
||||
flutter_secure_storage: ^9.2.4
|
||||
|
||||
native_video_player:
|
||||
git:
|
||||
|
|
|
@ -9366,13 +9366,11 @@
|
|||
"type": "string"
|
||||
},
|
||||
"visibility": {
|
||||
"enum": [
|
||||
"archive",
|
||||
"timeline",
|
||||
"hidden",
|
||||
"locked"
|
||||
],
|
||||
"type": "string"
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/AssetVisibility"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
8
open-api/typescript-sdk/package-lock.json
generated
8
open-api/typescript-sdk/package-lock.json
generated
|
@ -12,7 +12,7 @@
|
|||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
|
@ -23,9 +23,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.15.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
|
||||
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
|
||||
"version": "22.15.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
|
||||
"integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -28,6 +28,6 @@
|
|||
"directory": "open-api/typescript-sdk"
|
||||
},
|
||||
"volta": {
|
||||
"node": "22.15.0"
|
||||
"node": "22.15.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ export type AssetResponseDto = {
|
|||
"type": AssetTypeEnum;
|
||||
unassignedFaces?: AssetFaceWithoutPersonResponseDto[];
|
||||
updatedAt: string;
|
||||
visibility: Visibility;
|
||||
visibility: AssetVisibility;
|
||||
};
|
||||
export type AlbumResponseDto = {
|
||||
albumName: string;
|
||||
|
@ -3697,12 +3697,6 @@ export enum AssetTypeEnum {
|
|||
Audio = "AUDIO",
|
||||
Other = "OTHER"
|
||||
}
|
||||
export enum Visibility {
|
||||
Archive = "archive",
|
||||
Timeline = "timeline",
|
||||
Hidden = "hidden",
|
||||
Locked = "locked"
|
||||
}
|
||||
export enum AssetOrder {
|
||||
Asc = "asc",
|
||||
Desc = "desc"
|
||||
|
|
|
@ -1 +1 @@
|
|||
22.15.0
|
||||
22.15.1
|
||||
|
|
8
server/package-lock.json
generated
8
server/package-lock.json
generated
|
@ -92,7 +92,7 @@
|
|||
"@types/lodash": "^4.14.197",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^22.15.16",
|
||||
"@types/node": "^22.15.18",
|
||||
"@types/nodemailer": "^6.4.14",
|
||||
"@types/picomatch": "^4.0.0",
|
||||
"@types/pngjs": "^6.0.5",
|
||||
|
@ -5439,9 +5439,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.15.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
|
||||
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
|
||||
"version": "22.15.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.19.tgz",
|
||||
"integrity": "sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue