Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f4993350a | |||
| f9b1d1edaf | |||
| cab5477656 | |||
| b8de668f5f | |||
| c5234731d6 | |||
| ef86a77946 | |||
| 1b301984dd | |||
| 9807f76aff | |||
| 47673dd773 | |||
| a9fb1d435a | |||
| 422ad20641 | |||
| 3ea2fe1c48 | |||
| 038e064e60 | |||
| 800f010383 | |||
| 4350f9363d | |||
| 76a1629e75 | |||
| 2493dfaba3 | |||
| 656dc08406 | |||
| 631f13cf2f | |||
| 9730bf0acc | |||
| 9f2b5ea86e | |||
| 5702442783 | |||
| 74c2f446e9 | |||
| da1710bcd2 | |||
| 2dfd56b49b | |||
| 6538e599dd | |||
| 789e3e3924 | |||
| 3d505e425d | |||
| e7122d7a72 | |||
| 94d0705607 | |||
| caba462703 | |||
| ffe397247e | |||
| e7ad622c02 | |||
| bca4626708 | |||
| 7f0ad8e2d2 | |||
| 6c6c5ef651 | |||
| a460940430 | |||
| fc2455be80 | |||
| fd4357cf23 | |||
| e41e0df27e | |||
| f370dc3929 | |||
| 1c2d83e2c7 | |||
| d6756f3d81 | |||
| 71ef7685c5 | |||
| b7516f31c6 | |||
| 065fb166c2 | |||
| 4cc6e3b966 | |||
| 1c293a2759 | |||
| 062e2eca6f | |||
| bcc2c34eef | |||
| 1613ae9185 | |||
| d827a6182b | |||
| 83df14d379 | |||
| 7c1dae918d | |||
| 1b54c4f8e7 | |||
| 49b74e9091 | |||
| a1f1e5bc37 | |||
| 2dc8a93685 | |||
| c2145cbe11 | |||
| 50a792a81a | |||
| e2bd7e1e08 | |||
| 11a5a990d0 | |||
| ecc894ac82 | |||
| 50b649cd3e | |||
| 99b018cd49 | |||
| 6aa2800275 | |||
| cd7fc7e026 | |||
| b4d312efb6 | |||
| e9722710ac | |||
| f1384fea58 | |||
| feadc45e75 | |||
| eefe5266a8 | |||
| 74353193f8 | |||
| 0ccb73cf2b | |||
| 356f4424df | |||
| 85c6cf4309 | |||
| 96fb68135e | |||
| a7b9adc692 | |||
| e028cf9002 | |||
| f984be8ea0 | |||
| 3d426b55d3 | |||
| 02b8b2c125 | |||
| dc7b0f75bb | |||
| a089d9891d | |||
| a1183f4b4b | |||
| 84cfa38510 | |||
| 89edbcacfa | |||
| c8e649f190 | |||
| 790e43dd6e | |||
| 59f6b2ff2e | |||
| 829defbf61 | |||
| 70a0f4ae48 | |||
| c7c0ef6abc | |||
| 2fc8a0db92 | |||
| b50c621be8 |
@@ -96,7 +96,11 @@ jobs:
|
|||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run svelte checks
|
- name: Run svelte checks
|
||||||
run: npm run check
|
run: npm run check:svelte
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
|
- name: Run tsc
|
||||||
|
run: npm run check:typescript
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Run unit tests & coverage
|
- name: Run unit tests & coverage
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
dev:
|
dev:
|
||||||
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
docker-compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
||||||
|
|
||||||
dev-new:
|
dev-new:
|
||||||
rm -rf ./server/dist && docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans
|
||||||
|
|
||||||
dev-new-update:
|
dev-new-update:
|
||||||
rm -rf ./server/dist && docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
dev-update:
|
dev-update:
|
||||||
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
dev-scale:
|
dev-scale:
|
||||||
rm -rf ./server/dist && docker-compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
|
docker-compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans
|
||||||
|
|
||||||
stage:
|
stage:
|
||||||
docker-compose -f ./docker/docker-compose.staging.yml up --build -V --remove-orphans
|
docker-compose -f ./docker/docker-compose.staging.yml up --build -V --remove-orphans
|
||||||
|
|||||||
@@ -60,25 +60,30 @@ Spec: Free-tier Oracle VM - Amsterdam - 2.4Ghz quad-core ARM64 CPU, 24GB RAM
|
|||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
| Features | Mobile | Web |
|
| Features | Mobile | Web |
|
||||||
| ------------------------------------------- | ------ | --- |
|
| -------------------------------------------- | ------ | --- |
|
||||||
| Upload and view videos and photos | Yes | Yes |
|
| Upload and view videos and photos | Yes | Yes |
|
||||||
| Auto backup when the app is opened | Yes | N/A |
|
| Auto backup when the app is opened | Yes | N/A |
|
||||||
| Selective album(s) for backup | Yes | N/A |
|
| Selective album(s) for backup | Yes | N/A |
|
||||||
| Download photos and videos to local device | Yes | Yes |
|
| Download photos and videos to local device | Yes | Yes |
|
||||||
| Multi-user support | Yes | Yes |
|
| Multi-user support | Yes | Yes |
|
||||||
| Album and Shared albums | Yes | Yes |
|
| Album and Shared albums | Yes | Yes |
|
||||||
| Scrubbable/draggable scrollbar | Yes | Yes |
|
| Scrubbable/draggable scrollbar | Yes | Yes |
|
||||||
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes |
|
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes |
|
||||||
| Metadata view (EXIF, map) | Yes | Yes |
|
| Metadata view (EXIF, map) | Yes | Yes |
|
||||||
| Search by metadata, objects and CLIP | Yes | Yes |
|
| Search by metadata, objects, faces, and CLIP | Yes | Yes |
|
||||||
| Administrative functions (user management) | N/A | Yes |
|
| Administrative functions (user management) | No | Yes |
|
||||||
| Background backup | Yes | N/A |
|
| Background backup | Yes | N/A |
|
||||||
| Virtual scroll | Yes | Yes |
|
| Virtual scroll | Yes | Yes |
|
||||||
| OAuth support | Yes | Yes |
|
| OAuth support | Yes | Yes |
|
||||||
| LivePhoto backup and playback | iOS | Yes |
|
| API Keys | N/A | Yes |
|
||||||
| User-defined storage structure | Yes | Yes |
|
| LivePhoto backup and playback | iOS | Yes |
|
||||||
| Public Sharing | N/A | Yes |
|
| User-defined storage structure | Yes | Yes |
|
||||||
|
| Public Sharing | No | Yes |
|
||||||
|
| Archive and Favorites | Yes | Yes |
|
||||||
|
| Global Map | No | Yes |
|
||||||
|
| Partner Sharing | No | Yes |
|
||||||
|
| Facial recognition and clustering | No | Yes |
|
||||||
|
|
||||||
# Support the project
|
# Support the project
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
# Development Setup
|
|
||||||
|
|
||||||
## Lint / format extensions
|
|
||||||
|
|
||||||
Setting these in the IDE give a better developer experience auto-formatting code on save and providing instant feedback on lint issues.
|
|
||||||
|
|
||||||
### VSCode
|
|
||||||
Install Prettier, ESLint and Svelte extensions.
|
|
||||||
|
|
||||||
in User `settings.json` (`cmd + shift + p` and search for Open User Settings JSON) add the following:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"[javascript][typescript][css]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.formatOnSave": true
|
|
||||||
},
|
|
||||||
"[svelte]": {
|
|
||||||
"editor.defaultFormatter": "svelte.svelte-vscode",
|
|
||||||
"editor.tabSize": 2
|
|
||||||
},
|
|
||||||
"svelte.enable-ts-plugin": true,
|
|
||||||
"eslint.validate": ["javascript", "svelte"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running tests / checks
|
|
||||||
|
|
||||||
In both server and web:
|
|
||||||
`npm run check:all`
|
|
||||||
@@ -135,8 +135,6 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 2283:8080
|
- 2283:8080
|
||||||
logging:
|
|
||||||
driver: none
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- immich-server
|
- immich-server
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
immich-server:
|
immich-server:
|
||||||
container_name: immich_server
|
container_name: immich_server
|
||||||
image: ghcr.io/immich-app/immich-server:release
|
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||||
entrypoint: ["/bin/sh", "./start-server.sh"]
|
command: ["start-server.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
env_file:
|
env_file:
|
||||||
@@ -17,8 +17,8 @@ services:
|
|||||||
|
|
||||||
immich-microservices:
|
immich-microservices:
|
||||||
container_name: immich_microservices
|
container_name: immich_microservices
|
||||||
image: ghcr.io/immich-app/immich-server:release
|
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||||
entrypoint: ["/bin/sh", "./start-microservices.sh"]
|
command: ["start-microservices.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
env_file:
|
env_file:
|
||||||
@@ -31,7 +31,7 @@ services:
|
|||||||
|
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
image: ghcr.io/immich-app/immich-machine-learning:release
|
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||||
volumes:
|
volumes:
|
||||||
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||||
- model-cache:/cache
|
- model-cache:/cache
|
||||||
@@ -41,8 +41,7 @@ services:
|
|||||||
|
|
||||||
immich-web:
|
immich-web:
|
||||||
container_name: immich_web
|
container_name: immich_web
|
||||||
image: ghcr.io/immich-app/immich-web:release
|
image: ghcr.io/immich-app/immich-web:${IMMICH_VERSION:-release}
|
||||||
entrypoint: ["/bin/sh", "./entrypoint.sh"]
|
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
restart: always
|
restart: always
|
||||||
@@ -80,15 +79,13 @@ services:
|
|||||||
|
|
||||||
immich-proxy:
|
immich-proxy:
|
||||||
container_name: immich_proxy
|
container_name: immich_proxy
|
||||||
image: ghcr.io/immich-app/immich-proxy:release
|
image: ghcr.io/immich-app/immich-proxy:${IMMICH_VERSION:-release}
|
||||||
environment:
|
environment:
|
||||||
# Make sure these values get passed through from the env file
|
# Make sure these values get passed through from the env file
|
||||||
- IMMICH_SERVER_URL
|
- IMMICH_SERVER_URL
|
||||||
- IMMICH_WEB_URL
|
- IMMICH_WEB_URL
|
||||||
ports:
|
ports:
|
||||||
- 2283:8080
|
- 2283:8080
|
||||||
logging:
|
|
||||||
driver: none
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- immich-server
|
- immich-server
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
@@ -105,3 +105,12 @@ IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003
|
|||||||
####################################################################################
|
####################################################################################
|
||||||
|
|
||||||
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
|
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
# Immich Version - Optional
|
||||||
|
#
|
||||||
|
# This allows all immich docker images to be pinned to a specific version. By default,
|
||||||
|
# the version is "release" but could be a specific version, like "v1.59.0".
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
#IMMICH_VERSION=
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Database Migrations
|
||||||
|
|
||||||
|
After making any changes in the `server/libs/database/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
|
||||||
|
|
||||||
|
1. Run the command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run typeorm:migrations:generate ./libs/infra/src/<migration-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Check if the migration file makes sense.
|
||||||
|
3. Move the migration file to folder `server/libs/database/src/migrations` in your code editor.
|
||||||
|
|
||||||
|
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
---
|
|
||||||
sidebar_position: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
# Open API
|
# Open API
|
||||||
|
|
||||||
Immich uses the [Open API](https://swagger.io/specification/) standard to generate API documentation. To view the published docs see [here](/docs/api).
|
Immich uses the [Open API](https://swagger.io/specification/) standard to generate API documentation. To view the published docs see [here](/docs/api).
|
||||||
|
|
||||||
|
## Generator
|
||||||
|
|
||||||
|
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the command below to update the client SDK.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run api:generate # Run from the `server/` directory
|
||||||
|
```
|
||||||
|
|
||||||
|
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
This can also be run via `make api` from the project root directory (not in the `server` folder)
|
||||||
|
:::
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
---
|
# PR Checklist
|
||||||
sidebar_position: 3
|
|
||||||
---
|
|
||||||
|
|
||||||
# Contributing
|
|
||||||
|
|
||||||
Contributions are welcome!
|
|
||||||
|
|
||||||
## PR Checklist
|
|
||||||
|
|
||||||
When contributing code through a pull request, please check the following:
|
When contributing code through a pull request, please check the following:
|
||||||
|
|
||||||
### Web Checks
|
## Web Checks
|
||||||
|
|
||||||
- [ ] `npm run lint` (linting via ESLint)
|
- [ ] `npm run lint` (linting via ESLint)
|
||||||
- [ ] `npm run format` (formatting via Prettier)
|
- [ ] `npm run format` (formatting via Prettier)
|
||||||
@@ -21,7 +13,7 @@ When contributing code through a pull request, please check the following:
|
|||||||
Run all web checks with `npm run check:all`
|
Run all web checks with `npm run check:all`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Server Checks
|
## Server Checks
|
||||||
|
|
||||||
- [ ] `npm run lint` (linting via ESLint)
|
- [ ] `npm run lint` (linting via ESLint)
|
||||||
- [ ] `npm run format` (formatting via Prettier)
|
- [ ] `npm run format` (formatting via Prettier)
|
||||||
@@ -32,12 +24,10 @@ Run all web checks with `npm run check:all`
|
|||||||
Run all server checks with `npm run check:all`
|
Run all server checks with `npm run check:all`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Open API
|
## Open API
|
||||||
|
|
||||||
The Open API client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file.
|
The Open API client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file. See [Open API](/docs/developer/open-api.md) for more details.
|
||||||
|
|
||||||
- [ ] `npm run api:generate`
|
## Database Migrations
|
||||||
|
|
||||||
:::tip
|
A database migration needs to be generated whenever there are changes to `server/libs/infra/src/entities`. See [Database Migration](/docs/developer/database-migrations.md) for more details.
|
||||||
This can also be run via `make api` from the project root directory (not in the `server` folder)
|
|
||||||
:::
|
|
||||||
@@ -92,27 +92,3 @@ in User `settings.json` (`cmd + shift + p` and search for `Open User Settings JS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## OpenAPI generator
|
|
||||||
|
|
||||||
OpenAPI is used to generate the client (Typescript, Dart) SDK. `openapi-generator-cli` can be installed [here](https://openapi-generator.tech/docs/installation/). When you add a new or modify an existing endpoint, you must run the command below to update the client SDK.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run api:generate # Run from the `server` directory
|
|
||||||
```
|
|
||||||
|
|
||||||
You can find the generated client SDK in the `web/src/api` for Typescript SDK and `mobile/openapi` for Dart SDK.
|
|
||||||
|
|
||||||
## Database migrations
|
|
||||||
|
|
||||||
After making any changes in the `server/libs/database/src/entities`, a database migration need to run in order to register the changes in the database. Follow the steps below to create a new migration.
|
|
||||||
|
|
||||||
1. Attached to the server container shell.
|
|
||||||
2. Run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run typeorm -- migration:generate ./libs/infra/src/db/<migration-name> -d ./libs/infra/src/db/config/database.config.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Check if the migration file makes sense.
|
|
||||||
4. Move the migration file to folder `server/libs/database/src/migrations` in your code editor.
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Facial Recognition
|
||||||
|
|
||||||
|
Immich recognizes faces in your photos and videos and groups them together. You can then assign names to the faces and search for them.
|
||||||
|
|
||||||
|
The list of people is shown in the Explore page.
|
||||||
|
|
||||||
|
<img src={require('./img/facial-recognition-1.png').default} title='Facial Recognition 1' />
|
||||||
|
|
||||||
|
Upon clicking on a person, a list of assets that contain their face will be shown.
|
||||||
|
|
||||||
|
<img src={require('./img/facial-recognition-2.png').default} title='Facial Recognition 2' />
|
||||||
|
|
||||||
|
The asset detail view will also show the faces that are recognized in the asset.
|
||||||
|
|
||||||
|
<img src={require('./img/facial-recognition-3.png').default} title='Facial Recognition 3' />
|
||||||
|
After Width: | Height: | Size: 524 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 183 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
# Partner Sharing
|
||||||
|
|
||||||
|
Immich allows you to share your library with other users. They can then view your library and download the assets.
|
||||||
|
|
||||||
|
You can manage one or multiple users to have access to your library from the [User Settings](docs/features/user-settings.md) page.
|
||||||
|
|
||||||
|
<img src={require('./img/partner-sharing-1.png').default} title='Partner Sharing 1' />
|
||||||
|
|
||||||
|
<img src={require('./img/partner-sharing-2.png').default} title='Partner Sharing 2' />
|
||||||
|
|
||||||
|
Accessing the shared library can be done from the Sharing page.
|
||||||
|
|
||||||
|
<img src={require('./img/partner-sharing-3.png').default} title='Partner Sharing 3' />
|
||||||
|
|
||||||
|
:::tip Sharing specific assets
|
||||||
|
For sharing a specific set of assets, you can use the shared album feature of Immich.
|
||||||
|
:::
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# XMP Sidecars
|
||||||
|
|
||||||
|
Immich can ingest XMP sidecars on file upload (via the CLI) as well as detect new sidecars that are placed in the filesystem for existing images.
|
||||||
|
|
||||||
|
<img src={require('./img/xmp-sidecars.png').default} title='XMP sidecars' />
|
||||||
|
|
||||||
|
XMP sidecars are external XML files that contain metadata related to media files. Many applications read and write these files either exclusively or in addition to the metadata written to image files. They can be a powerful tool for editing and storing metadata of a media file without modifying the mdia file itself. When Immich receives or detects an XMP sidecar for a media file, it will attempt to extract the metadata from both the sidecar as well as the media file. It will prioritize the metadata for fields in the sidecar but will fall back and use the metadata in the media file if necessary.
|
||||||
|
|
||||||
|
When importing files via the CLI bulk uploader, Immich will automatically detect XMP sidecar files as files that exist next to the original media file and have the exact same name with an additional `.xmp` file extension (i.e., `PXL_20230401_203352928.MP.jpg` and `PXL_20230401_203352928.MP.jpg.xmp`).
|
||||||
|
|
||||||
|
There are 2 administrator jobs associated with sidecar files: `SYNC` and `DISCOVER`. The sync job will re-scan all media with existing sidecar files and queue them for a metadata refresh. This is a great use case when third-party applications are used to modify the metadata of media. The discover job will attempt to scan the filesystem for new sidecar files for all media that does not currently have a sidecar file associated with it.
|
||||||
|
|
||||||
|
<img src={require('./img/sidecar-jobs.png').default} title='Sidecar Administrator Jobs' />
|
||||||
@@ -136,6 +136,15 @@ IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003
|
|||||||
####################################################################################
|
####################################################################################
|
||||||
|
|
||||||
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
|
#IMMICH_API_URL_EXTERNAL=http://localhost:3001
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
# Immich Version - Optional
|
||||||
|
#
|
||||||
|
# This allows all immich docker images to be pinned to a specific version. By default,
|
||||||
|
# the version is "release" but could be a specific version, like "v1.59.0".
|
||||||
|
###################################################################################
|
||||||
|
|
||||||
|
#IMMICH_VERSION=
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
@@ -159,6 +168,8 @@ For more information on how to use the application, please refer to the [Post In
|
|||||||
|
|
||||||
### Step 4 - Upgrading
|
### Step 4 - Upgrading
|
||||||
|
|
||||||
|
If `IMMICH_VERSION` is set, it will need to be updated to the latest or desired version.
|
||||||
|
|
||||||
When a new version of Immich is [released](https://github.com/immich-app/immich/releases), the application can be upgraded with the following commands, run in the directory with the `docker-compose.yml` file:
|
When a new version of Immich is [released](https://github.com/immich-app/immich/releases), the application can be upgraded with the following commands, run in the directory with the `docker-compose.yml` file:
|
||||||
|
|
||||||
```bash title="Upgrade Immich"
|
```bash title="Upgrade Immich"
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ You can also use Podman to run the application. However, additional configuratio
|
|||||||
## Hardware
|
## Hardware
|
||||||
|
|
||||||
- **OS**: Preferred unix-based operating system (Ubuntu, Debian, MacOS, etc). Windows works too, with [Docker Desktop on Windows](https://docs.docker.com/desktop/install/windows-install/)
|
- **OS**: Preferred unix-based operating system (Ubuntu, Debian, MacOS, etc). Windows works too, with [Docker Desktop on Windows](https://docs.docker.com/desktop/install/windows-install/)
|
||||||
- **RAM**: At least 2GB, preferred 4GB.
|
- **RAM**: At least 4GB, preferred 6GB.
|
||||||
- **CPU**: At least 2 cores, preferred 4 cores.
|
- **CPU**: At least 2 cores, preferred 4 cores.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
{ "source": "/docs/features/password-login", "destination": "/docs/administration/password-login" },
|
{ "source": "/docs/features/password-login", "destination": "/docs/administration/password-login" },
|
||||||
{ "source": "/docs/features/server-commands", "destination": "/docs/administration/server-commands" },
|
{ "source": "/docs/features/server-commands", "destination": "/docs/administration/server-commands" },
|
||||||
{ "source": "/docs/features/storage-template", "destination": "/docs/administration/storage-template" },
|
{ "source": "/docs/features/storage-template", "destination": "/docs/administration/storage-template" },
|
||||||
{ "source": "/docs/features/user-management", "destination": "/docs/administration/user-management" }
|
{ "source": "/docs/features/user-management", "destination": "/docs/administration/user-management" },
|
||||||
|
{ "source": "/docs/developer/contributing", "destination": "/docs/developer/pr-checklist" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import uvicorn
|
|||||||
|
|
||||||
from insightface.app import FaceAnalysis
|
from insightface.app import FaceAnalysis
|
||||||
from transformers import pipeline
|
from transformers import pipeline
|
||||||
from sentence_transformers import SentenceTransformer, util
|
from sentence_transformers import SentenceTransformer
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@@ -20,22 +20,44 @@ class ClipRequestBody(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
classification_model = os.getenv(
|
classification_model = os.getenv(
|
||||||
'MACHINE_LEARNING_CLASSIFICATION_MODEL', 'microsoft/resnet-50')
|
"MACHINE_LEARNING_CLASSIFICATION_MODEL", "microsoft/resnet-50"
|
||||||
object_model = os.getenv('MACHINE_LEARNING_OBJECT_MODEL', 'hustvl/yolos-tiny')
|
)
|
||||||
clip_image_model = os.getenv(
|
clip_image_model = os.getenv("MACHINE_LEARNING_CLIP_IMAGE_MODEL", "clip-ViT-B-32")
|
||||||
'MACHINE_LEARNING_CLIP_IMAGE_MODEL', 'clip-ViT-B-32')
|
clip_text_model = os.getenv("MACHINE_LEARNING_CLIP_TEXT_MODEL", "clip-ViT-B-32")
|
||||||
clip_text_model = os.getenv(
|
|
||||||
'MACHINE_LEARNING_CLIP_TEXT_MODEL', 'clip-ViT-B-32')
|
|
||||||
facial_recognition_model = os.getenv(
|
facial_recognition_model = os.getenv(
|
||||||
'MACHINE_LEARNING_FACIAL_RECOGNITION_MODEL', 'buffalo_l')
|
"MACHINE_LEARNING_FACIAL_RECOGNITION_MODEL", "buffalo_l"
|
||||||
|
)
|
||||||
|
|
||||||
cache_folder = os.getenv('MACHINE_LEARNING_CACHE_FOLDER', '/cache')
|
min_face_score = float(os.getenv("MACHINE_LEARNING_MIN_FACE_SCORE", 0.7))
|
||||||
|
min_tag_score = float(os.getenv("MACHINE_LEARNING_MIN_TAG_SCORE", 0.9))
|
||||||
|
eager_startup = (
|
||||||
|
os.getenv("MACHINE_LEARNING_EAGER_STARTUP", "true") == "true"
|
||||||
|
) # loads all models at startup
|
||||||
|
|
||||||
|
cache_folder = os.getenv("MACHINE_LEARNING_CACHE_FOLDER", "/cache")
|
||||||
|
|
||||||
_model_cache = {}
|
_model_cache = {}
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event("startup")
|
||||||
|
async def startup_event():
|
||||||
|
models = [
|
||||||
|
(classification_model, "image-classification"),
|
||||||
|
(clip_image_model, "clip"),
|
||||||
|
(clip_text_model, "clip"),
|
||||||
|
(facial_recognition_model, "facial-recognition"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get all models
|
||||||
|
for model_name, model_type in models:
|
||||||
|
if eager_startup:
|
||||||
|
get_cached_model(model_name, model_type)
|
||||||
|
else:
|
||||||
|
_get_model(model_name, model_type)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
async def root():
|
async def root():
|
||||||
return {"message": "Immich ML"}
|
return {"message": "Immich ML"}
|
||||||
@@ -46,61 +68,55 @@ def ping():
|
|||||||
return "pong"
|
return "pong"
|
||||||
|
|
||||||
|
|
||||||
@app.post("/object-detection/detect-object", status_code=200)
|
|
||||||
def object_detection(payload: MlRequestBody):
|
|
||||||
model = _get_model(object_model, 'object-detection')
|
|
||||||
assetPath = payload.thumbnailPath
|
|
||||||
return run_engine(model, assetPath)
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/image-classifier/tag-image", status_code=200)
|
@app.post("/image-classifier/tag-image", status_code=200)
|
||||||
def image_classification(payload: MlRequestBody):
|
def image_classification(payload: MlRequestBody):
|
||||||
model = _get_model(classification_model, 'image-classification')
|
model = get_cached_model(classification_model, "image-classification")
|
||||||
assetPath = payload.thumbnailPath
|
assetPath = payload.thumbnailPath
|
||||||
return run_engine(model, assetPath)
|
return run_engine(model, assetPath)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/sentence-transformer/encode-image", status_code=200)
|
@app.post("/sentence-transformer/encode-image", status_code=200)
|
||||||
def clip_encode_image(payload: MlRequestBody):
|
def clip_encode_image(payload: MlRequestBody):
|
||||||
model = _get_model(clip_image_model)
|
model = get_cached_model(clip_image_model, "clip")
|
||||||
assetPath = payload.thumbnailPath
|
assetPath = payload.thumbnailPath
|
||||||
return model.encode(Image.open(assetPath)).tolist()
|
return model.encode(Image.open(assetPath)).tolist()
|
||||||
|
|
||||||
|
|
||||||
@app.post("/sentence-transformer/encode-text", status_code=200)
|
@app.post("/sentence-transformer/encode-text", status_code=200)
|
||||||
def clip_encode_text(payload: ClipRequestBody):
|
def clip_encode_text(payload: ClipRequestBody):
|
||||||
model = _get_model(clip_text_model)
|
model = get_cached_model(clip_text_model, "clip")
|
||||||
text = payload.text
|
text = payload.text
|
||||||
return model.encode(text).tolist()
|
return model.encode(text).tolist()
|
||||||
|
|
||||||
|
|
||||||
@app.post("/facial-recognition/detect-faces", status_code=200)
|
@app.post("/facial-recognition/detect-faces", status_code=200)
|
||||||
def facial_recognition(payload: MlRequestBody):
|
def facial_recognition(payload: MlRequestBody):
|
||||||
model = _get_model(facial_recognition_model, 'facial-recognition')
|
model = get_cached_model(facial_recognition_model, "facial-recognition")
|
||||||
assetPath = payload.thumbnailPath
|
assetPath = payload.thumbnailPath
|
||||||
img = cv.imread(assetPath)
|
img = cv.imread(assetPath)
|
||||||
height, width, _ = img.shape
|
height, width, _ = img.shape
|
||||||
results = []
|
results = []
|
||||||
faces = model.get(img)
|
faces = model.get(img)
|
||||||
|
|
||||||
for face in faces:
|
for face in faces:
|
||||||
if face.det_score < 0.7:
|
if face.det_score < min_face_score:
|
||||||
continue
|
continue
|
||||||
x1, y1, x2, y2 = face.bbox
|
x1, y1, x2, y2 = face.bbox
|
||||||
# min face size as percent of original image
|
|
||||||
# if (x2 - x1) / width < 0.03 or (y2 - y1) / height < 0.05:
|
results.append(
|
||||||
# continue
|
{
|
||||||
results.append({
|
"imageWidth": width,
|
||||||
"imageWidth": width,
|
"imageHeight": height,
|
||||||
"imageHeight": height,
|
"boundingBox": {
|
||||||
"boundingBox": {
|
"x1": round(x1),
|
||||||
"x1": round(x1),
|
"y1": round(y1),
|
||||||
"y1": round(y1),
|
"x2": round(x2),
|
||||||
"x2": round(x2),
|
"y2": round(y2),
|
||||||
"y2": round(y2),
|
},
|
||||||
},
|
"score": face.det_score.item(),
|
||||||
"score": face.det_score.item(),
|
"embedding": face.normed_embedding.tolist(),
|
||||||
"embedding": face.normed_embedding.tolist()
|
}
|
||||||
})
|
)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
@@ -109,37 +125,45 @@ def run_engine(engine, path):
|
|||||||
predictions = engine(path)
|
predictions = engine(path)
|
||||||
|
|
||||||
for index, pred in enumerate(predictions):
|
for index, pred in enumerate(predictions):
|
||||||
tags = pred['label'].split(', ')
|
tags = pred["label"].split(", ")
|
||||||
if (pred['score'] > 0.9):
|
if pred["score"] > min_tag_score:
|
||||||
result = [*result, *tags]
|
result = [*result, *tags]
|
||||||
|
|
||||||
if (len(result) > 1):
|
if len(result) > 1:
|
||||||
result = list(set(result))
|
result = list(set(result))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _get_model(model, task=None):
|
def get_cached_model(model, task):
|
||||||
global _model_cache
|
global _model_cache
|
||||||
key = '|'.join([model, str(task)])
|
key = "|".join([model, str(task)])
|
||||||
if key not in _model_cache:
|
if key not in _model_cache:
|
||||||
if task:
|
model = _get_model(model, task)
|
||||||
if task == 'facial-recognition':
|
_model_cache[key] = model
|
||||||
face_model = FaceAnalysis(
|
|
||||||
name=model, root=cache_folder, allowed_modules=["detection", "recognition"])
|
|
||||||
face_model.prepare(ctx_id=0, det_size=(640, 640))
|
|
||||||
_model_cache[key] = face_model
|
|
||||||
else:
|
|
||||||
_model_cache[key] = pipeline(model=model, task=task)
|
|
||||||
else:
|
|
||||||
_model_cache[key] = SentenceTransformer(
|
|
||||||
model, cache_folder=cache_folder)
|
|
||||||
return _model_cache[key]
|
return _model_cache[key]
|
||||||
|
|
||||||
|
|
||||||
|
def _get_model(model, task):
|
||||||
|
match task:
|
||||||
|
case "facial-recognition":
|
||||||
|
model = FaceAnalysis(
|
||||||
|
name=model,
|
||||||
|
root=cache_folder,
|
||||||
|
allowed_modules=["detection", "recognition"],
|
||||||
|
)
|
||||||
|
model.prepare(ctx_id=0, det_size=(640, 640))
|
||||||
|
case "clip":
|
||||||
|
model = SentenceTransformer(model, cache_folder=cache_folder)
|
||||||
|
case _:
|
||||||
|
model = pipeline(model=model, task=task)
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
host = os.getenv('MACHINE_LEARNING_HOST', '0.0.0.0')
|
host = os.getenv("MACHINE_LEARNING_HOST", "0.0.0.0")
|
||||||
port = int(os.getenv('MACHINE_LEARNING_PORT', 3003))
|
port = int(os.getenv("MACHINE_LEARNING_PORT", 3003))
|
||||||
is_dev = os.getenv('NODE_ENV') == 'development'
|
is_dev = os.getenv("NODE_ENV") == "development"
|
||||||
|
|
||||||
uvicorn.run("main:app", host=host, port=port, reload=is_dev, workers=1)
|
uvicorn.run("main:app", host=host, port=port, reload=is_dev, workers=1)
|
||||||
|
|||||||
@@ -49,3 +49,8 @@ app.*.map.json
|
|||||||
|
|
||||||
# Fastlane
|
# Fastlane
|
||||||
ios/fastlane/report.xml
|
ios/fastlane/report.xml
|
||||||
|
|
||||||
|
# Isar
|
||||||
|
default.isar
|
||||||
|
default.isar.lock
|
||||||
|
libisar.so
|
||||||
@@ -35,8 +35,8 @@ platform :android do
|
|||||||
task: 'bundle',
|
task: 'bundle',
|
||||||
build_type: 'Release',
|
build_type: 'Release',
|
||||||
properties: {
|
properties: {
|
||||||
"android.injected.version.code" => 79,
|
"android.injected.version.code" => 83,
|
||||||
"android.injected.version.name" => "1.56.0",
|
"android.injected.version.name" => "1.60.0",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
* Upgrade to Flutter 3.10
|
||||||
|
* Lazy loading of timeline
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
* Remove Hive box
|
||||||
@@ -5,19 +5,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.00032">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000296">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="29.247439">
|
<testcase classname="fastlane.lanes" name="1: bundleRelease" time="64.042552">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="22.794249">
|
<testcase classname="fastlane.lanes" name="2: upload_to_play_store" time="29.676557">
|
||||||
|
|
||||||
<failure message="/usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:229:in `chdir' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:229:in `execute_action' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing' Fastfile:42:in `block (2 levels) in parsing_binding' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane.rb:33:in `call' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:49:in `block in execute' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `chdir' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `execute' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:354:in `run' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:43:in `start' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off' /usr/local/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/bin/fastlane:23:in `<top (required)>' /usr/local/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `load' /usr/local/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `<main>' Google Api Error: Invalid request - APK specifies a version code that has already been used." />
|
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Přidáno do {album}",
|
"add_to_album_bottom_sheet_added": "Přidáno do {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Již v {album}",
|
"add_to_album_bottom_sheet_already_exists": "Již v {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Pokročilé uživatelské nastavení",
|
||||||
|
"advanced_settings_tile_title": "Pokročilé",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Povolit dodatečné funkce pro řešení problémů",
|
||||||
|
"advanced_settings_troubleshooting_title": "Řešení problémů",
|
||||||
"album_info_card_backup_album_excluded": "VYLOUČENO",
|
"album_info_card_backup_album_excluded": "VYLOUČENO",
|
||||||
"album_info_card_backup_album_included": "ZAHRNUTO",
|
"album_info_card_backup_album_included": "ZAHRNUTO",
|
||||||
"album_thumbnail_card_item": "1 položka",
|
"album_thumbnail_card_item": "1 položka",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Odstranit z alba",
|
"album_viewer_appbar_share_remove": "Odstranit z alba",
|
||||||
"album_viewer_page_share_add_users": "Přidat uživatele",
|
"album_viewer_page_share_add_users": "Přidat uživatele",
|
||||||
"all_videos_page_title": "Videa",
|
"all_videos_page_title": "Videa",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archív ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamické rozložení",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamické rozložení",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Seskupit položky podle",
|
"asset_list_layout_settings_group_by": "Seskupit položky podle",
|
||||||
"asset_list_layout_settings_group_by_month": "Měsíc",
|
"asset_list_layout_settings_group_by_month": "Měsíc",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Měsíc + den",
|
"asset_list_layout_settings_group_by_month_day": "Měsíc + den",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Přidat do alba",
|
"control_bottom_app_bar_add_to_album": "Přidat do alba",
|
||||||
"control_bottom_app_bar_album_info": "{} položek",
|
"control_bottom_app_bar_album_info": "{} položek",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} položky - sdílené",
|
"control_bottom_app_bar_album_info_shared": "{} položky - sdílené",
|
||||||
|
"control_bottom_app_bar_archive": "Archív",
|
||||||
"control_bottom_app_bar_create_new_album": "Vytvořit nové album",
|
"control_bottom_app_bar_create_new_album": "Vytvořit nové album",
|
||||||
"control_bottom_app_bar_delete": "Vymazat",
|
"control_bottom_app_bar_delete": "Vymazat",
|
||||||
"control_bottom_app_bar_favorite": "Oblíbené",
|
"control_bottom_app_bar_favorite": "Oblíbené",
|
||||||
"control_bottom_app_bar_share": "Sdílet",
|
"control_bottom_app_bar_share": "Sdílet",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Bez názvu",
|
"create_album_page_untitled": "Bez názvu",
|
||||||
"create_shared_album_page_create": "Vytvořit",
|
"create_shared_album_page_create": "Vytvořit",
|
||||||
"create_shared_album_page_share": "Sdílet",
|
"create_shared_album_page_share": "Sdílet",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Zrušit",
|
"delete_dialog_cancel": "Zrušit",
|
||||||
"delete_dialog_ok": "Vymazat",
|
"delete_dialog_ok": "Vymazat",
|
||||||
"delete_dialog_title": "Vymazat trvale",
|
"delete_dialog_title": "Vymazat trvale",
|
||||||
|
"description_input_hint_text": "Přidat popis...",
|
||||||
|
"description_input_submit_error": "Chyba aktualizace popisu, další podrobnosti najdete v logu",
|
||||||
"exif_bottom_sheet_description": "Přidat popis...",
|
"exif_bottom_sheet_description": "Přidat popis...",
|
||||||
"exif_bottom_sheet_details": "PODROBNOSTI",
|
"exif_bottom_sheet_details": "PODROBNOSTI",
|
||||||
"exif_bottom_sheet_location": "LOKALITA",
|
"exif_bottom_sheet_location": "LOKALITA",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Povolení experimentální mřížky fotografií",
|
"experimental_settings_new_asset_list_title": "Povolení experimentální mřížky fotografií",
|
||||||
"experimental_settings_subtitle": "Používejte na vlastní riziko!",
|
"experimental_settings_subtitle": "Používejte na vlastní riziko!",
|
||||||
"experimental_settings_title": "Experimentální",
|
"experimental_settings_title": "Experimentální",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Oblíbené",
|
"favorites_page_title": "Oblíbené",
|
||||||
"home_page_add_to_album_conflicts": "Přidáno {added} položek do alba {album}. {failed} položek již je v albu.",
|
"home_page_add_to_album_conflicts": "Přidáno {added} položek do alba {album}. {failed} položek již je v albu.",
|
||||||
"home_page_add_to_album_err_local": "Zatím není možné přidat lokální média do alb, přeskakuje se",
|
"home_page_add_to_album_err_local": "Zatím není možné přidat lokální média do alb, přeskakuje se",
|
||||||
"home_page_add_to_album_success": "Přidány položky {added} do alba {album}.",
|
"home_page_add_to_album_success": "Přidány položky {added} do alba {album}.",
|
||||||
|
"home_page_archive_err_local": "Zatím nemohu archivovat lokální média, přeskakuji",
|
||||||
"home_page_building_timeline": "Vytváření časové osy",
|
"home_page_building_timeline": "Vytváření časové osy",
|
||||||
"home_page_favorite_err_local": "Zatím není možné zařadit lokální média mezi oblíbená, přeskakuje se",
|
"home_page_favorite_err_local": "Zatím není možné zařadit lokální média mezi oblíbená, přeskakuje se",
|
||||||
"home_page_first_time_notice": "Pokud aplikaci používáte poprvé, nezapomeňte si vybrat zálohovaná alba, aby se na časové ose mohly nacházet fotografie a videa z vybraných albech.",
|
"home_page_first_time_notice": "Pokud aplikaci používáte poprvé, nezapomeňte si vybrat zálohovaná alba, aby se na časové ose mohly nacházet fotografie a videa z vybraných albech.",
|
||||||
"image_viewer_page_state_provider_download_error": "Chyba stahování",
|
"image_viewer_page_state_provider_download_error": "Chyba stahování",
|
||||||
"image_viewer_page_state_provider_download_success": "Stahování bylo úspěšné",
|
"image_viewer_page_state_provider_download_success": "Stahování bylo úspěšné",
|
||||||
"library_page_albums": "Alba",
|
"library_page_albums": "Alba",
|
||||||
|
"library_page_archive": "Archív",
|
||||||
"library_page_device_albums": "Alba v zařízení",
|
"library_page_device_albums": "Alba v zařízení",
|
||||||
"library_page_favorites": "Oblíbené",
|
"library_page_favorites": "Oblíbené",
|
||||||
"library_page_new_album": "Nové album",
|
"library_page_new_album": "Nové album",
|
||||||
@@ -206,7 +220,7 @@
|
|||||||
"search_page_view_all_button": "Zobrazit vše",
|
"search_page_view_all_button": "Zobrazit vše",
|
||||||
"search_page_your_activity": "Vaše aktivita",
|
"search_page_your_activity": "Vaše aktivita",
|
||||||
"search_result_page_new_search_hint": "Nové vyhledávání",
|
"search_result_page_new_search_hint": "Nové vyhledávání",
|
||||||
"search_suggestion_list_smart_search_hint_1": "Ve výchozím nastavení je chytré vyhledávání zapnuto, pro vyhledávání metadat použijte syntaxi",
|
"search_suggestion_list_smart_search_hint_1": "Ve výchozím nastavení je chytré vyhledávání zapnuto, pro vyhledávání metadat použijte syntaxi ",
|
||||||
"search_suggestion_list_smart_search_hint_2": "m:vaše-vyhledávaná-fráze",
|
"search_suggestion_list_smart_search_hint_2": "m:vaše-vyhledávaná-fráze",
|
||||||
"select_additional_user_for_sharing_page_suggestions": "Návrhy",
|
"select_additional_user_for_sharing_page_suggestions": "Návrhy",
|
||||||
"select_user_for_sharing_page_err_album": "Nepodařilo se vytvořit album",
|
"select_user_for_sharing_page_err_album": "Nepodařilo se vytvořit album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Tilføjet til {album}",
|
"add_to_album_bottom_sheet_added": "Tilføjet til {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
|
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Avancerede brugerindstillinger",
|
||||||
|
"advanced_settings_tile_title": "Arkivér",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Slå ekstra funktioner for fejlsøgning til",
|
||||||
|
"advanced_settings_troubleshooting_title": "Fejlsøgning",
|
||||||
"album_info_card_backup_album_excluded": "EKSKLUDERET",
|
"album_info_card_backup_album_excluded": "EKSKLUDERET",
|
||||||
"album_info_card_backup_album_included": "INKLUDERET",
|
"album_info_card_backup_album_included": "INKLUDERET",
|
||||||
"album_thumbnail_card_item": "1 genstand",
|
"album_thumbnail_card_item": "1 genstand",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Fjern fra album",
|
"album_viewer_appbar_share_remove": "Fjern fra album",
|
||||||
"album_viewer_page_share_add_users": "Tilføj brugere",
|
"album_viewer_page_share_add_users": "Tilføj brugere",
|
||||||
"all_videos_page_title": "Videoer",
|
"all_videos_page_title": "Videoer",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Arkivér ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Gruppér elementer pr. ",
|
"asset_list_layout_settings_group_by": "Gruppér elementer pr. ",
|
||||||
"asset_list_layout_settings_group_by_month": "Måned",
|
"asset_list_layout_settings_group_by_month": "Måned",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
|
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Tilføj til album",
|
"control_bottom_app_bar_add_to_album": "Tilføj til album",
|
||||||
"control_bottom_app_bar_album_info": "{} genstande",
|
"control_bottom_app_bar_album_info": "{} genstande",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} genstande • Delt",
|
"control_bottom_app_bar_album_info_shared": "{} genstande • Delt",
|
||||||
|
"control_bottom_app_bar_archive": "Arkiv",
|
||||||
"control_bottom_app_bar_create_new_album": "Opret nyt album",
|
"control_bottom_app_bar_create_new_album": "Opret nyt album",
|
||||||
"control_bottom_app_bar_delete": "Slet",
|
"control_bottom_app_bar_delete": "Slet",
|
||||||
"control_bottom_app_bar_favorite": "Favorit",
|
"control_bottom_app_bar_favorite": "Favorit",
|
||||||
"control_bottom_app_bar_share": "Del",
|
"control_bottom_app_bar_share": "Del",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Uden titel",
|
"create_album_page_untitled": "Uden titel",
|
||||||
"create_shared_album_page_create": "Opret",
|
"create_shared_album_page_create": "Opret",
|
||||||
"create_shared_album_page_share": "Del",
|
"create_shared_album_page_share": "Del",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Annuller",
|
"delete_dialog_cancel": "Annuller",
|
||||||
"delete_dialog_ok": "Slet",
|
"delete_dialog_ok": "Slet",
|
||||||
"delete_dialog_title": "Slet permanent",
|
"delete_dialog_title": "Slet permanent",
|
||||||
|
"description_input_hint_text": "Tilføj en beskrivelse...",
|
||||||
|
"description_input_submit_error": "Fejl med at opdatere beskrivelsen. Tjek loggen for flere detaljer",
|
||||||
"exif_bottom_sheet_description": "Tilføj beskrivelse...",
|
"exif_bottom_sheet_description": "Tilføj beskrivelse...",
|
||||||
"exif_bottom_sheet_details": "DETALJER",
|
"exif_bottom_sheet_details": "DETALJER",
|
||||||
"exif_bottom_sheet_location": "LOKATION",
|
"exif_bottom_sheet_location": "LOKATION",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Aktiver eksperimentelt fotogitter",
|
"experimental_settings_new_asset_list_title": "Aktiver eksperimentelt fotogitter",
|
||||||
"experimental_settings_subtitle": "Brug på eget ansvar!",
|
"experimental_settings_subtitle": "Brug på eget ansvar!",
|
||||||
"experimental_settings_title": "Eksperimentelle",
|
"experimental_settings_title": "Eksperimentelle",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favoritter",
|
"favorites_page_title": "Favoritter",
|
||||||
"home_page_add_to_album_conflicts": "Tilføjede {added} elementer til album {album}. {failed} elementer er allerede i albummet.",
|
"home_page_add_to_album_conflicts": "Tilføjede {added} elementer til album {album}. {failed} elementer er allerede i albummet.",
|
||||||
"home_page_add_to_album_err_local": "Kan endnu ikke tilføje lokale elementer til album. Springer over..",
|
"home_page_add_to_album_err_local": "Kan endnu ikke tilføje lokale elementer til album. Springer over..",
|
||||||
"home_page_add_to_album_success": "Tilføjede {added} elementer til album {album}.",
|
"home_page_add_to_album_success": "Tilføjede {added} elementer til album {album}.",
|
||||||
|
"home_page_archive_err_local": "Kan ikke arkivere lokalt element endnu.. Springer over",
|
||||||
"home_page_building_timeline": "Bygger tidslinjen",
|
"home_page_building_timeline": "Bygger tidslinjen",
|
||||||
"home_page_favorite_err_local": "Kan endnu ikke gøre lokale elementer til favoritter. Springer over..",
|
"home_page_favorite_err_local": "Kan endnu ikke gøre lokale elementer til favoritter. Springer over..",
|
||||||
"home_page_first_time_notice": "Hvis dette er din første gang i appen, bedes du vælge en backup af albummer så tidlinjen kan blive fyldt med billeder og videoer fra albummerne.",
|
"home_page_first_time_notice": "Hvis dette er din første gang i appen, bedes du vælge en backup af albummer så tidlinjen kan blive fyldt med billeder og videoer fra albummerne.",
|
||||||
"image_viewer_page_state_provider_download_error": "Fejl ved download",
|
"image_viewer_page_state_provider_download_error": "Fejl ved download",
|
||||||
"image_viewer_page_state_provider_download_success": "Download succesfuld",
|
"image_viewer_page_state_provider_download_success": "Download succesfuld",
|
||||||
"library_page_albums": "Albummer",
|
"library_page_albums": "Albummer",
|
||||||
|
"library_page_archive": "Arkiv",
|
||||||
"library_page_device_albums": "Albummer på enhed",
|
"library_page_device_albums": "Albummer på enhed",
|
||||||
"library_page_favorites": "Favoritter",
|
"library_page_favorites": "Favoritter",
|
||||||
"library_page_new_album": "Nyt album",
|
"library_page_new_album": "Nyt album",
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Zu {album} hinzugefügt",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Bereits in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Erweiterte Benutzereinstellungen",
|
||||||
|
"advanced_settings_tile_title": "Sonstige",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Aktiviere erweiterte Funktionen zur Fehlersuche",
|
||||||
|
"advanced_settings_troubleshooting_title": "Fehlersuche",
|
||||||
"album_info_card_backup_album_excluded": "AUSGESCHLOSSEN",
|
"album_info_card_backup_album_excluded": "AUSGESCHLOSSEN",
|
||||||
"album_info_card_backup_album_included": "EINGESCHLOSSEN",
|
"album_info_card_backup_album_included": "EINGESCHLOSSEN",
|
||||||
"album_thumbnail_card_item": "1 Element",
|
"album_thumbnail_card_item": "1 Element",
|
||||||
"album_thumbnail_card_items": "{} Elemente",
|
"album_thumbnail_card_items": "{} Elemente",
|
||||||
"album_thumbnail_card_shared": " · Geteilt",
|
"album_thumbnail_card_shared": " · Geteilt",
|
||||||
"album_thumbnail_owned": "Owned",
|
"album_thumbnail_owned": "Owned",
|
||||||
"album_thumbnail_shared_by": "Shared by {}",
|
"album_thumbnail_shared_by": "Geteilt von {}",
|
||||||
"album_viewer_appbar_share_delete": "Album löschen",
|
"album_viewer_appbar_share_delete": "Album löschen",
|
||||||
"album_viewer_appbar_share_err_delete": "Album konnte nicht gelöscht werden",
|
"album_viewer_appbar_share_err_delete": "Album konnte nicht gelöscht werden",
|
||||||
"album_viewer_appbar_share_err_leave": "Album konnte nicht verlassen werden",
|
"album_viewer_appbar_share_err_leave": "Album konnte nicht verlassen werden",
|
||||||
@@ -17,12 +21,15 @@
|
|||||||
"album_viewer_appbar_share_remove": "Entferne vom Album",
|
"album_viewer_appbar_share_remove": "Entferne vom Album",
|
||||||
"album_viewer_page_share_add_users": "Nutzer hinzufügen",
|
"album_viewer_page_share_add_users": "Nutzer hinzufügen",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
"asset_list_layout_settings_group_by": "Group assets by",
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_group_by_month": "Month",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamisches Layout",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_settings_subtitle": "Photo grid layout settings",
|
"asset_list_layout_settings_group_by": "Gruppiere Elemente nach",
|
||||||
"asset_list_settings_title": "Photo Grid",
|
"asset_list_layout_settings_group_by_month": "Monat",
|
||||||
|
"asset_list_layout_settings_group_by_month_day": "Monat + Tag",
|
||||||
|
"asset_list_settings_subtitle": "Einstellungen für das Fotogitter-Layout",
|
||||||
|
"asset_list_settings_title": "Fotogitter",
|
||||||
"backup_album_selection_page_albums_device": "Alben auf dem Gerät ({})",
|
"backup_album_selection_page_albums_device": "Alben auf dem Gerät ({})",
|
||||||
"backup_album_selection_page_albums_tap": "Tippen um einzuschließen, doppelt tippen um zu entfernen",
|
"backup_album_selection_page_albums_tap": "Tippen um einzuschließen, doppelt tippen um zu entfernen",
|
||||||
"backup_album_selection_page_assets_scatter": "Elemente können sich über mehrere Alben verteilen. Daher können diese vor der Sicherung eingeschlossen oder ausgeschlossen werden",
|
"backup_album_selection_page_assets_scatter": "Elemente können sich über mehrere Alben verteilen. Daher können diese vor der Sicherung eingeschlossen oder ausgeschlossen werden",
|
||||||
@@ -31,21 +38,21 @@
|
|||||||
"backup_album_selection_page_total_assets": "Elemente",
|
"backup_album_selection_page_total_assets": "Elemente",
|
||||||
"backup_all": "Alle",
|
"backup_all": "Alle",
|
||||||
"backup_background_service_backup_failed_message": "Failed to backup assets. Retrying…",
|
"backup_background_service_backup_failed_message": "Failed to backup assets. Retrying…",
|
||||||
"backup_background_service_connection_failed_message": "Failed to connect to the server. Retrying…",
|
"backup_background_service_connection_failed_message": "Konnte keine Verbindung zum Server herstellen. Neuer Versuch...",
|
||||||
"backup_background_service_current_upload_notification": "Uploading {}",
|
"backup_background_service_current_upload_notification": "Lädt {} hoch",
|
||||||
"backup_background_service_default_notification": "Suche nach neuen assets…",
|
"backup_background_service_default_notification": "Suche nach neuen Elementen…",
|
||||||
"backup_background_service_error_title": "Backup error",
|
"backup_background_service_error_title": "Fehler bei der Sicherung",
|
||||||
"backup_background_service_in_progress_notification": "Backing up your assets…",
|
"backup_background_service_in_progress_notification": "Elemente werden gesichert...",
|
||||||
"backup_background_service_upload_failure_notification": "Failed to upload {}",
|
"backup_background_service_upload_failure_notification": "Konnte {} nicht hochladen",
|
||||||
"backup_controller_page_albums": "Gesicherte Alben",
|
"backup_controller_page_albums": "Gesicherte Alben",
|
||||||
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
|
"backup_controller_page_background_app_refresh_disabled_content": "Aktiviere Hintergrundaktualisierungen in Einstellungen -> Allgemein -> Hintergrundaktualisierungen um Sicherungen im Hintergrund zu ermöglichen. ",
|
||||||
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
|
"backup_controller_page_background_app_refresh_disabled_title": "Hintergrundaktualisierungen sind deaktiviert.",
|
||||||
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
|
"backup_controller_page_background_app_refresh_enable_button_text": "Gehe zu Einstellungen",
|
||||||
"backup_controller_page_background_battery_info_link": "Show me how",
|
"backup_controller_page_background_battery_info_link": "Zeige mir wie",
|
||||||
"backup_controller_page_background_battery_info_message": "For the best background backup experience, please disable any battery optimizations restricting background activity for Immich.\n\nSince this is device-specific, please lookup the required information for your device manufacturer.",
|
"backup_controller_page_background_battery_info_message": "For the best background backup experience, please disable any battery optimizations restricting background activity for Immich.\n\nSince this is device-specific, please lookup the required information for your device manufacturer.",
|
||||||
"backup_controller_page_background_battery_info_ok": "OK",
|
"backup_controller_page_background_battery_info_ok": "OK",
|
||||||
"backup_controller_page_background_battery_info_title": "Battery optimizations",
|
"backup_controller_page_background_battery_info_title": "Batterieoptimierungen",
|
||||||
"backup_controller_page_background_charging": "Only while charging",
|
"backup_controller_page_background_charging": "Nur während des Ladens",
|
||||||
"backup_controller_page_background_configure_error": "Failed to configure the background service",
|
"backup_controller_page_background_configure_error": "Failed to configure the background service",
|
||||||
"backup_controller_page_background_delay": "Delay new assets backup: {}",
|
"backup_controller_page_background_delay": "Delay new assets backup: {}",
|
||||||
"backup_controller_page_background_description": "Turn on the background service to automatically backup any new assets without needing to open the app",
|
"backup_controller_page_background_description": "Turn on the background service to automatically backup any new assets without needing to open the app",
|
||||||
@@ -53,7 +60,7 @@
|
|||||||
"backup_controller_page_background_is_on": "Automatic background backup is on",
|
"backup_controller_page_background_is_on": "Automatic background backup is on",
|
||||||
"backup_controller_page_background_turn_off": "Turn off background service",
|
"backup_controller_page_background_turn_off": "Turn off background service",
|
||||||
"backup_controller_page_background_turn_on": "Turn on background service",
|
"backup_controller_page_background_turn_on": "Turn on background service",
|
||||||
"backup_controller_page_background_wifi": "Only on WiFi",
|
"backup_controller_page_background_wifi": "Nur im WLAN",
|
||||||
"backup_controller_page_backup": "Sicherung",
|
"backup_controller_page_backup": "Sicherung",
|
||||||
"backup_controller_page_backup_selected": "Ausgewählt: ",
|
"backup_controller_page_backup_selected": "Ausgewählt: ",
|
||||||
"backup_controller_page_backup_sub": "Gesicherte Fotos und Videos",
|
"backup_controller_page_backup_sub": "Gesicherte Fotos und Videos",
|
||||||
@@ -83,42 +90,44 @@
|
|||||||
"backup_err_only_album": "Das einzige Album kann nicht entfernt werden",
|
"backup_err_only_album": "Das einzige Album kann nicht entfernt werden",
|
||||||
"backup_info_card_assets": "Elemente",
|
"backup_info_card_assets": "Elemente",
|
||||||
"cache_settings_album_thumbnails": "Library page thumbnails ({} assets)",
|
"cache_settings_album_thumbnails": "Library page thumbnails ({} assets)",
|
||||||
"cache_settings_clear_cache_button": "Clear cache",
|
"cache_settings_clear_cache_button": "Zwischenspeicher löschen",
|
||||||
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
|
"cache_settings_clear_cache_button_title": "Löscht den Zwischenspeicher der App. Dies wird die Leistungsfähigkeit der App deutlich einschränken, bis der Zwischenspeicher wieder aufgebaut wurde.",
|
||||||
"cache_settings_image_cache_size": "Image cache size ({} assets)",
|
"cache_settings_image_cache_size": "Image cache size ({} assets)",
|
||||||
"cache_settings_statistics_album": "Library thumbnails",
|
"cache_settings_statistics_album": "Library thumbnails",
|
||||||
"cache_settings_statistics_assets": "{} assets ({})",
|
"cache_settings_statistics_assets": "{} assets ({})",
|
||||||
"cache_settings_statistics_full": "Full images",
|
"cache_settings_statistics_full": "Full images",
|
||||||
"cache_settings_statistics_shared": "Shared album thumbnails",
|
"cache_settings_statistics_shared": "Shared album thumbnails",
|
||||||
"cache_settings_statistics_thumbnail": "Vorschaubilder",
|
"cache_settings_statistics_thumbnail": "Vorschaubilder",
|
||||||
"cache_settings_statistics_title": "Cache usage",
|
"cache_settings_statistics_title": "Zwischenspeicher Nutzung",
|
||||||
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
|
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
|
||||||
"cache_settings_thumbnail_size": "Thumbnail cache size ({} assets)",
|
"cache_settings_thumbnail_size": "Thumbnail cache size ({} assets)",
|
||||||
"cache_settings_title": "Caching Settings",
|
"cache_settings_title": "Zwischenspeicher Einstellungen",
|
||||||
"change_password_form_confirm_password": "Confirm Password",
|
"change_password_form_confirm_password": "Passwort bestätigen",
|
||||||
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
|
"change_password_form_description": "Hallo {firstName} {lastName}\n\nDas ist entweder das erste Mal dass du dich einloggst oder eine Anfrage zur Änderung deines Passwortes wurde gestellt. Bitte gebe das neue Passwort ein.",
|
||||||
"change_password_form_new_password": "New Password",
|
"change_password_form_new_password": "Neues Passwort",
|
||||||
"change_password_form_password_mismatch": "Passwords do not match",
|
"change_password_form_password_mismatch": "Passwörter stimmen nicht überein",
|
||||||
"change_password_form_reenter_new_password": "Re-enter New Password",
|
"change_password_form_reenter_new_password": "Passwort erneut eingeben",
|
||||||
"common_add_to_album": "Add to album",
|
"common_add_to_album": "Zu Album hinzufügen",
|
||||||
"common_change_password": "Change Password",
|
"common_change_password": "Passwort ändern",
|
||||||
"common_create_new_album": "Create new album",
|
"common_create_new_album": "Erstelle ein neues Album",
|
||||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
"common_server_error": "Bitte überprüfe Deine Netzwerkverbindung und stelle sicher, dass die App und Server Versionen kompatibel sind.",
|
||||||
"common_shared": "Shared",
|
"common_shared": "Geteilt",
|
||||||
"control_bottom_app_bar_add_to_album": "Add to album",
|
"control_bottom_app_bar_add_to_album": "Zu Album hinzufügen",
|
||||||
"control_bottom_app_bar_album_info": "{} items",
|
"control_bottom_app_bar_album_info": "{} Elemente",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
"control_bottom_app_bar_album_info_shared": "{} Elemente · geteilt",
|
||||||
|
"control_bottom_app_bar_archive": "Archiv",
|
||||||
"control_bottom_app_bar_create_new_album": "Neues Album erstellen",
|
"control_bottom_app_bar_create_new_album": "Neues Album erstellen",
|
||||||
"control_bottom_app_bar_delete": "Löschen",
|
"control_bottom_app_bar_delete": "Löschen",
|
||||||
"control_bottom_app_bar_favorite": "Favorite",
|
"control_bottom_app_bar_favorite": "Favorit",
|
||||||
"control_bottom_app_bar_share": "Teilen",
|
"control_bottom_app_bar_share": "Teilen",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Unbenannt",
|
"create_album_page_untitled": "Unbenannt",
|
||||||
"create_shared_album_page_create": "Erstellen",
|
"create_shared_album_page_create": "Erstellen",
|
||||||
"create_shared_album_page_share": "Teilen",
|
"create_shared_album_page_share": "Teilen",
|
||||||
"create_shared_album_page_share_add_assets": "ELEMENTE HINZUFÜGEN",
|
"create_shared_album_page_share_add_assets": "ELEMENTE HINZUFÜGEN",
|
||||||
"create_shared_album_page_share_select_photos": "Fotos auswählen",
|
"create_shared_album_page_share_select_photos": "Fotos auswählen",
|
||||||
"curated_location_page_title": "Places",
|
"curated_location_page_title": "Orte",
|
||||||
"curated_object_page_title": "Things",
|
"curated_object_page_title": "Dinge",
|
||||||
"daily_title_text_date": "E, dd MMM",
|
"daily_title_text_date": "E, dd MMM",
|
||||||
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
"daily_title_text_date_year": "E, dd MMM, yyyy",
|
||||||
"date_format": "E d. LLL y • hh:mm",
|
"date_format": "E d. LLL y • hh:mm",
|
||||||
@@ -126,110 +135,115 @@
|
|||||||
"delete_dialog_cancel": "Abbrechen",
|
"delete_dialog_cancel": "Abbrechen",
|
||||||
"delete_dialog_ok": "Löschen",
|
"delete_dialog_ok": "Löschen",
|
||||||
"delete_dialog_title": "Für immer löschen",
|
"delete_dialog_title": "Für immer löschen",
|
||||||
|
"description_input_hint_text": "Beschreibung hinzufügen...",
|
||||||
|
"description_input_submit_error": "Beschreibung konnte nicht geändert werden, bitte im Log für mehr Details nachsehen.",
|
||||||
"exif_bottom_sheet_description": "Beschreibung hinzufügen...",
|
"exif_bottom_sheet_description": "Beschreibung hinzufügen...",
|
||||||
"exif_bottom_sheet_details": "DETAILS",
|
"exif_bottom_sheet_details": "DETAILS",
|
||||||
"exif_bottom_sheet_location": "STANDORT",
|
"exif_bottom_sheet_location": "STANDORT",
|
||||||
"experimental_settings_new_asset_list_subtitle": "In Arbeit",
|
"experimental_settings_new_asset_list_subtitle": "In Arbeit",
|
||||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
"experimental_settings_new_asset_list_title": "Experimentelle Fotogitter aktivieren",
|
||||||
"experimental_settings_subtitle": "Use at your own risk!",
|
"experimental_settings_subtitle": "Benutzung auf eigene Gefahr!",
|
||||||
"experimental_settings_title": "Experimentell",
|
"experimental_settings_title": "Experimentell",
|
||||||
"favorites_page_title": "Favorites",
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
"favorites_page_title": "Favoriten",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_conflicts": "{added} Elemente zu {album} hinzugefügt. {failed} Elemente sind bereits vorhanden.",
|
||||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
"home_page_add_to_album_err_local": "Kann lokale Elemente noch nicht zu Alben hinzufügen, überspringe",
|
||||||
"home_page_building_timeline": "Building the timeline",
|
"home_page_add_to_album_success": "{added} Elemente zu {album} hinzugefügt.",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_archive_err_local": "Kann lokale Elemente nicht archvieren, überspringe",
|
||||||
"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_building_timeline": "Zeitachse wird erstellt.",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"home_page_favorite_err_local": "Kann lokale Elemente noch nicht favorisieren, überspringe",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"home_page_first_time_notice": "Wenn dies das erste Mal ist dass Du Immich nutzt, stelle bitte sicher, dass mindestens ein Album zur Sicherung ausgewählt ist, sodass die Zeitachse mit Fotos und Videos gefüllt werden kann.",
|
||||||
|
"image_viewer_page_state_provider_download_error": "Fehler beim Herunterladen",
|
||||||
|
"image_viewer_page_state_provider_download_success": "Erfolgreich heruntergeladen",
|
||||||
"library_page_albums": "Alben",
|
"library_page_albums": "Alben",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_archive": "Archiv",
|
||||||
"library_page_favorites": "Favorites",
|
"library_page_device_albums": "Alben auf dem Gerät.",
|
||||||
|
"library_page_favorites": "Favoriten",
|
||||||
"library_page_new_album": "Neues Album",
|
"library_page_new_album": "Neues Album",
|
||||||
"library_page_sharing": "Sharing",
|
"library_page_sharing": "Teilen",
|
||||||
"library_page_sort_created": "Most recently created",
|
"library_page_sort_created": "Zuletzt erstellt",
|
||||||
"library_page_sort_title": "Album title",
|
"library_page_sort_title": "Albumtitel",
|
||||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
"login_form_api_exception": "API Fehler. Bitte die Serveradresse überprüfen und erneut versuchen.",
|
||||||
"login_form_button_text": "Anmelden",
|
"login_form_button_text": "Anmelden",
|
||||||
"login_form_email_hint": "deine@email.de",
|
"login_form_email_hint": "deine@email.de",
|
||||||
"login_form_endpoint_hint": "http://deine-server-ip:port/api",
|
"login_form_endpoint_hint": "http://deine-server-ip:port/api",
|
||||||
"login_form_endpoint_url": "Server URL",
|
"login_form_endpoint_url": "Server URL",
|
||||||
"login_form_err_http": "Bitte gebe http:// oder https:// an",
|
"login_form_err_http": "Bitte gebe http:// oder https:// an",
|
||||||
"login_form_err_invalid_email": "Ungültige E-Mail",
|
"login_form_err_invalid_email": "Ungültige E-Mail",
|
||||||
"login_form_err_invalid_url": "Invalid URL",
|
"login_form_err_invalid_url": "Ungültige URL",
|
||||||
"login_form_err_leading_whitespace": "Führendes Leerzichen",
|
"login_form_err_leading_whitespace": "Führendes Leerzichen",
|
||||||
"login_form_err_trailing_whitespace": "Folgendes Leerzeichen",
|
"login_form_err_trailing_whitespace": "Folgendes Leerzeichen",
|
||||||
"login_form_failed_get_oauth_server_config": "Error logging using OAuth, check server URL",
|
"login_form_failed_get_oauth_server_config": "Fehler beim Login per OAuth, Server-URL überprüfen",
|
||||||
"login_form_failed_get_oauth_server_disable": "OAuth feature is not available on this server",
|
"login_form_failed_get_oauth_server_disable": "OAuth-Funktion nicht verfügbar auf diesem Server.",
|
||||||
"login_form_failed_login": "Error logging you in, check server url, email and password",
|
"login_form_failed_login": "Error logging you in, check server url, email and password",
|
||||||
"login_form_label_email": "E-Mail",
|
"login_form_label_email": "E-Mail",
|
||||||
"login_form_label_password": "Passwort",
|
"login_form_label_password": "Passwort",
|
||||||
"login_form_next_button": "Next",
|
"login_form_next_button": "Weiter",
|
||||||
"login_form_password_hint": "password",
|
"login_form_password_hint": "password",
|
||||||
"login_form_save_login": "Angemeldet bleiben",
|
"login_form_save_login": "Angemeldet bleiben",
|
||||||
"login_form_server_empty": "Enter a server URL.",
|
"login_form_server_empty": "Serveradresse eingeben.",
|
||||||
"login_form_server_error": "Could not connect to server.",
|
"login_form_server_error": "Konnte nicht mit Server verbinden.",
|
||||||
"monthly_title_text_date_format": "MMMM y",
|
"monthly_title_text_date_format": "MMMM y",
|
||||||
"motion_photos_page_title": "Motion Photos",
|
"motion_photos_page_title": "Live Photos",
|
||||||
"notification_permission_dialog_cancel": "Cancel",
|
"notification_permission_dialog_cancel": "Abbrechen",
|
||||||
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
"notification_permission_dialog_content": "Um Benachrichtigungen zu aktivieren, navigiere zu Einstellungen und klicke \"Erlauben\"",
|
||||||
"notification_permission_dialog_settings": "Settings",
|
"notification_permission_dialog_settings": "Einstellungen",
|
||||||
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
|
"notification_permission_list_tile_content": "Erlaube Berechtigung für Benachrichtigungen",
|
||||||
"notification_permission_list_tile_enable_button": "Enable Notifications",
|
"notification_permission_list_tile_enable_button": "Aktiviere Benachrichtigungen",
|
||||||
"notification_permission_list_tile_title": "Notification Permission",
|
"notification_permission_list_tile_title": "Benachrichtigungs-Berechtigung",
|
||||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
"permission_onboarding_continue_anyway": "Trotzdem fortfahren",
|
||||||
"permission_onboarding_get_started": "Get started",
|
"permission_onboarding_get_started": "Get started",
|
||||||
"permission_onboarding_go_to_settings": "Go to settings",
|
"permission_onboarding_go_to_settings": "Gehe zu Einstellungen",
|
||||||
"permission_onboarding_grant_permission": "Grant permission",
|
"permission_onboarding_grant_permission": "Berechtigung erteilen",
|
||||||
"permission_onboarding_log_out": "Log out",
|
"permission_onboarding_log_out": "Abmelden",
|
||||||
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_denied": "Berechtigungen verweigert. Um Immich zu benutzen, Zugriff auf Fotos und Videos in Einstellungen erlauben.",
|
||||||
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
|
"permission_onboarding_permission_granted": "Berechtigung erteilt! Du bist startklar.",
|
||||||
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_limited": "Berechtigungen unzureichend. Um Immich das Sichern von ganzen Sammlungen zu ermöglichen, muss der Zugriff auf alle Fotos und Videos in den Einstellungen erlaubt werden.",
|
||||||
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
|
"permission_onboarding_request": "Immich benötigt Berechtigung um auf deine Fotos und Videos zuzugreifen.",
|
||||||
"profile_drawer_app_logs": "Logs",
|
"profile_drawer_app_logs": "Logs",
|
||||||
"profile_drawer_client_server_up_to_date": "App und Server sind aktuell",
|
"profile_drawer_client_server_up_to_date": "App und Server sind aktuell",
|
||||||
"profile_drawer_settings": "Einstellungen",
|
"profile_drawer_settings": "Einstellungen",
|
||||||
"profile_drawer_sign_out": "Abmelden",
|
"profile_drawer_sign_out": "Abmelden",
|
||||||
"recently_added_page_title": "Recently Added",
|
"recently_added_page_title": "Zuletzt hinzugefügt",
|
||||||
"search_bar_hint": "Durchsuche deine Fotos",
|
"search_bar_hint": "Durchsuche deine Fotos",
|
||||||
"search_page_categories": "Categories",
|
"search_page_categories": "Kategorien",
|
||||||
"search_page_favorites": "Favorites",
|
"search_page_favorites": "Favoriten",
|
||||||
"search_page_motion_photos": "Motion Photos",
|
"search_page_motion_photos": "Live Photos",
|
||||||
"search_page_no_objects": "Keine Objektinformationen verfügbar",
|
"search_page_no_objects": "Keine Objektinformationen verfügbar",
|
||||||
"search_page_no_places": "Keine Informationen über Orte verfügbar",
|
"search_page_no_places": "Keine Informationen über Orte verfügbar",
|
||||||
"search_page_places": "Orte",
|
"search_page_places": "Orte",
|
||||||
"search_page_recently_added": "Recently added",
|
"search_page_recently_added": "Zuletzt hinzugefügt",
|
||||||
"search_page_screenshots": "Screenshots",
|
"search_page_screenshots": "Bildschirmfotos",
|
||||||
"search_page_selfies": "Selfies",
|
"search_page_selfies": "Selfies",
|
||||||
"search_page_things": "Dinge",
|
"search_page_things": "Dinge",
|
||||||
"search_page_videos": "Videos",
|
"search_page_videos": "Videos",
|
||||||
"search_page_view_all_button": "View all",
|
"search_page_view_all_button": "Alle anzeigen",
|
||||||
"search_page_your_activity": "Your activity",
|
"search_page_your_activity": "Deine Aktivität",
|
||||||
"search_result_page_new_search_hint": "Neue Suche",
|
"search_result_page_new_search_hint": "Neue Suche",
|
||||||
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
|
"search_suggestion_list_smart_search_hint_1": "Intelligente Suche ist standardmäßig aktiviert; um nach Metadaten zu suchen Syntax benutzen",
|
||||||
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
|
"search_suggestion_list_smart_search_hint_2": "m:dein-suchbegriff",
|
||||||
"select_additional_user_for_sharing_page_suggestions": "Vorschläge",
|
"select_additional_user_for_sharing_page_suggestions": "Vorschläge",
|
||||||
"select_user_for_sharing_page_err_album": "Album konnte nicht erstellt werden",
|
"select_user_for_sharing_page_err_album": "Album konnte nicht erstellt werden",
|
||||||
"select_user_for_sharing_page_share_suggestions": "Suggestions",
|
"select_user_for_sharing_page_share_suggestions": "Suggestions",
|
||||||
"server_info_box_app_version": "App Version",
|
"server_info_box_app_version": "App Version",
|
||||||
"server_info_box_server_version": "Server Version",
|
"server_info_box_server_version": "Server Version",
|
||||||
"setting_image_viewer_help": "The detail viewer loads the small thumbnail first, then loads the medium-size preview (if enabled), finally loads the original (if enabled).",
|
"setting_image_viewer_help": "Der Detailviewer lädt zuerst die kleine Miniaturansicht, dann die Vorschau in mittlerer Größe (falls aktiviert) und schließlich das Original (falls aktiviert).",
|
||||||
"setting_image_viewer_original_subtitle": "Enable to load the original full-resolution image (large!). Disable to reduce data usage (both network and on device cache).",
|
"setting_image_viewer_original_subtitle": "Aktivieren, um das Originalbild in voller Auflösung (groß!) zu laden. Deaktivieren, um den Datenverbrauch zu reduzieren (sowohl im Netzwerk als auch im Gerätespeicher).",
|
||||||
"setting_image_viewer_original_title": "Load original image",
|
"setting_image_viewer_original_title": "Original laden",
|
||||||
"setting_image_viewer_preview_subtitle": "Enable to load a medium-resolution image. Disable to either directly load the original or only use the thumbnail.",
|
"setting_image_viewer_preview_subtitle": "Aktivieren, um ein Bild mit mittlerer Auflösung zu laden. Deaktivieren, um entweder das Original direkt zu laden oder nur die Miniaturansicht zu verwenden.",
|
||||||
"setting_image_viewer_preview_title": "Load preview image",
|
"setting_image_viewer_preview_title": "Vorschaubild laden",
|
||||||
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
|
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {}",
|
||||||
"setting_notifications_notify_hours": "{} hours",
|
"setting_notifications_notify_hours": "{} Stunden",
|
||||||
"setting_notifications_notify_immediately": "immediately",
|
"setting_notifications_notify_immediately": "sofort",
|
||||||
"setting_notifications_notify_minutes": "{} minutes",
|
"setting_notifications_notify_minutes": "{} Minuten",
|
||||||
"setting_notifications_notify_never": "never",
|
"setting_notifications_notify_never": "niemals",
|
||||||
"setting_notifications_notify_seconds": "{} seconds",
|
"setting_notifications_notify_seconds": "{} Sekunden",
|
||||||
"setting_notifications_single_progress_subtitle": "Detaillierte Upload Informationen für jedes Element.",
|
"setting_notifications_single_progress_subtitle": "Detaillierte Upload Informationen für jedes Element.",
|
||||||
"setting_notifications_single_progress_title": "Show background backup detail progress",
|
"setting_notifications_single_progress_title": "Zeige Hintergrund-Sicherungs Detailfortschritt",
|
||||||
"setting_notifications_subtitle": "Adjust your notification preferences",
|
"setting_notifications_subtitle": "Adjust your notification preferences",
|
||||||
"setting_notifications_title": "Notifications",
|
"setting_notifications_title": "Benachrichtigungen",
|
||||||
"setting_notifications_total_progress_subtitle": "Overall upload progress (done/total assets)",
|
"setting_notifications_total_progress_subtitle": "Gesamter Upload-Fortschritt (abgeschlossen/Anzahl Elemente)",
|
||||||
"setting_notifications_total_progress_title": "Show background backup total progress",
|
"setting_notifications_total_progress_title": "Zeige Hintergrundsicherungsfortschritt",
|
||||||
"setting_pages_app_bar_settings": "Einstellungen",
|
"setting_pages_app_bar_settings": "Einstellungen",
|
||||||
"settings_require_restart": "Bitte starte Immich neu, um diese Einstellung anzuwenden.",
|
"settings_require_restart": "Bitte starte Immich neu, um diese Einstellung anzuwenden.",
|
||||||
"share_add": "Hinzufügen",
|
"share_add": "Hinzufügen",
|
||||||
@@ -247,8 +261,8 @@
|
|||||||
"tab_controller_nav_photos": "Fotos",
|
"tab_controller_nav_photos": "Fotos",
|
||||||
"tab_controller_nav_search": "Suche",
|
"tab_controller_nav_search": "Suche",
|
||||||
"tab_controller_nav_sharing": "Teilen",
|
"tab_controller_nav_sharing": "Teilen",
|
||||||
"theme_setting_asset_list_storage_indicator_title": "Show storage indicator on asset tiles",
|
"theme_setting_asset_list_storage_indicator_title": "Zeige Sicherungsstatus auf Miniaturbild",
|
||||||
"theme_setting_asset_list_tiles_per_row_title": "Number of assets per row ({})",
|
"theme_setting_asset_list_tiles_per_row_title": "Anzahl der Elemente pro Reihe ({})",
|
||||||
"theme_setting_dark_mode_switch": "Dunkler Modus",
|
"theme_setting_dark_mode_switch": "Dunkler Modus",
|
||||||
"theme_setting_image_viewer_quality_subtitle": "Einstellen der Qualität des Detailbildbetrachters",
|
"theme_setting_image_viewer_quality_subtitle": "Einstellen der Qualität des Detailbildbetrachters",
|
||||||
"theme_setting_image_viewer_quality_title": "Qualität des Bildbetrachters",
|
"theme_setting_image_viewer_quality_title": "Qualität des Bildbetrachters",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "EXCLUDED",
|
"album_info_card_backup_album_excluded": "EXCLUDED",
|
||||||
"album_info_card_backup_album_included": "INCLUDED",
|
"album_info_card_backup_album_included": "INCLUDED",
|
||||||
"album_thumbnail_card_item": "1 item",
|
"album_thumbnail_card_item": "1 item",
|
||||||
@@ -17,11 +21,13 @@
|
|||||||
"album_viewer_appbar_share_remove": "Remove from album",
|
"album_viewer_appbar_share_remove": "Remove from album",
|
||||||
"album_viewer_page_share_add_users": "Add users",
|
"album_viewer_page_share_add_users": "Add users",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Group assets by",
|
"asset_list_layout_settings_group_by": "Group assets by",
|
||||||
"asset_list_layout_settings_group_by_month": "Month",
|
"asset_list_layout_settings_group_by_month": "Month",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
||||||
"asset_list_layout_settings_group_automatically": "Automatic",
|
|
||||||
"asset_list_settings_subtitle": "Photo grid layout settings",
|
"asset_list_settings_subtitle": "Photo grid layout settings",
|
||||||
"asset_list_settings_title": "Photo Grid",
|
"asset_list_settings_title": "Photo Grid",
|
||||||
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
"backup_album_selection_page_albums_device": "Albums on device ({})",
|
||||||
@@ -109,12 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Add to album",
|
"control_bottom_app_bar_add_to_album": "Add to album",
|
||||||
"control_bottom_app_bar_album_info": "{} items",
|
"control_bottom_app_bar_album_info": "{} items",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Create new album",
|
"control_bottom_app_bar_create_new_album": "Create new album",
|
||||||
"control_bottom_app_bar_delete": "Delete",
|
"control_bottom_app_bar_delete": "Delete",
|
||||||
"control_bottom_app_bar_favorite": "Favorite",
|
"control_bottom_app_bar_favorite": "Favorite",
|
||||||
"control_bottom_app_bar_archive": "Archive",
|
|
||||||
"control_bottom_app_bar_unarchive": "Unarchive",
|
|
||||||
"control_bottom_app_bar_share": "Share",
|
"control_bottom_app_bar_share": "Share",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Untitled",
|
"create_album_page_untitled": "Untitled",
|
||||||
"create_shared_album_page_create": "Create",
|
"create_shared_album_page_create": "Create",
|
||||||
"create_shared_album_page_share": "Share",
|
"create_shared_album_page_share": "Share",
|
||||||
@@ -129,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Cancel",
|
"delete_dialog_cancel": "Cancel",
|
||||||
"delete_dialog_ok": "Delete",
|
"delete_dialog_ok": "Delete",
|
||||||
"delete_dialog_title": "Delete Permanently",
|
"delete_dialog_title": "Delete Permanently",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Add Description...",
|
"exif_bottom_sheet_description": "Add Description...",
|
||||||
"exif_bottom_sheet_details": "DETAILS",
|
"exif_bottom_sheet_details": "DETAILS",
|
||||||
"exif_bottom_sheet_location": "LOCATION",
|
"exif_bottom_sheet_location": "LOCATION",
|
||||||
@@ -136,23 +144,23 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||||
"experimental_settings_subtitle": "Use at your own risk!",
|
"experimental_settings_subtitle": "Use at your own risk!",
|
||||||
"experimental_settings_title": "Experimental",
|
"experimental_settings_title": "Experimental",
|
||||||
"favorites_page_title": "Favorites",
|
|
||||||
"favorites_page_no_favorites": "No favorite assets found",
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
|
"favorites_page_title": "Favorites",
|
||||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Building the timeline",
|
"home_page_building_timeline": "Building the timeline",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||||
"home_page_archive_err_local": "Can not archive local 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(s) so that the timeline can populate photos and videos in the album(s).",
|
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||||
"library_page_albums": "Albums",
|
"library_page_albums": "Albums",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Favorites",
|
"library_page_favorites": "Favorites",
|
||||||
"library_page_new_album": "New album",
|
"library_page_new_album": "New album",
|
||||||
"library_page_sharing": "Sharing",
|
"library_page_sharing": "Sharing",
|
||||||
"library_page_archive": "Archive",
|
|
||||||
"library_page_sort_created": "Most recently created",
|
"library_page_sort_created": "Most recently created",
|
||||||
"library_page_sort_title": "Album title",
|
"library_page_sort_title": "Album title",
|
||||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
||||||
@@ -249,6 +257,15 @@
|
|||||||
"sharing_page_empty_list": "EMPTY LIST",
|
"sharing_page_empty_list": "EMPTY LIST",
|
||||||
"sharing_silver_appbar_create_shared_album": "Create shared album",
|
"sharing_silver_appbar_create_shared_album": "Create shared album",
|
||||||
"sharing_silver_appbar_share_partner": "Share with partner",
|
"sharing_silver_appbar_share_partner": "Share with partner",
|
||||||
|
"partner_page_title": "Partner",
|
||||||
|
"partner_page_no_more_users": "No more users to add",
|
||||||
|
"partner_page_empty_message": "Your photos are not yet shared with any partner.",
|
||||||
|
"partner_page_shared_to_title": "Shared to",
|
||||||
|
"partner_page_select_partner": "Select partner",
|
||||||
|
"partner_page_add_partner": "Add partner",
|
||||||
|
"partner_page_partner_add_failed": "Failed to add partner",
|
||||||
|
"partner_page_stop_sharing_title": "Stop sharing your photos?",
|
||||||
|
"partner_page_stop_sharing_content": "{} will no longer be able to access your photos.",
|
||||||
"tab_controller_nav_library": "Library",
|
"tab_controller_nav_library": "Library",
|
||||||
"tab_controller_nav_photos": "Photos",
|
"tab_controller_nav_photos": "Photos",
|
||||||
"tab_controller_nav_search": "Search",
|
"tab_controller_nav_search": "Search",
|
||||||
@@ -268,13 +285,5 @@
|
|||||||
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
|
"version_announcement_overlay_text_1": "Hi friend, there is a new release of",
|
||||||
"version_announcement_overlay_text_2": "please take your time to visit the ",
|
"version_announcement_overlay_text_2": "please take your time to visit the ",
|
||||||
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
|
"version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
|
||||||
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89",
|
"version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89"
|
||||||
"advanced_settings_tile_title": "Advanced",
|
|
||||||
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
|
||||||
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
|
||||||
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
|
||||||
"description_input_submit_error": "Error updating description, check the log for more details",
|
|
||||||
"description_input_hint_text": "Add description...",
|
|
||||||
"archive_page_title": "Archive ({})",
|
|
||||||
"archive_page_no_archived_assets": "No archived assets found"
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "EXCLUIDOS",
|
"album_info_card_backup_album_excluded": "EXCLUIDOS",
|
||||||
"album_info_card_backup_album_included": "INCLUIDOS",
|
"album_info_card_backup_album_included": "INCLUIDOS",
|
||||||
"album_thumbnail_card_item": "1 item",
|
"album_thumbnail_card_item": "1 item",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Eliminar del álbum ",
|
"album_viewer_appbar_share_remove": "Eliminar del álbum ",
|
||||||
"album_viewer_page_share_add_users": "Añadir usuarios",
|
"album_viewer_page_share_add_users": "Añadir usuarios",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Disposición dinámica",
|
"asset_list_layout_settings_dynamic_layout_title": "Disposición dinámica",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Agrupar recursos por",
|
"asset_list_layout_settings_group_by": "Agrupar recursos por",
|
||||||
"asset_list_layout_settings_group_by_month": "Mes",
|
"asset_list_layout_settings_group_by_month": "Mes",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Mes + día",
|
"asset_list_layout_settings_group_by_month_day": "Mes + día",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Añadir al álbum",
|
"control_bottom_app_bar_add_to_album": "Añadir al álbum",
|
||||||
"control_bottom_app_bar_album_info": "{} elementos",
|
"control_bottom_app_bar_album_info": "{} elementos",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} elementos · Compartido",
|
"control_bottom_app_bar_album_info_shared": "{} elementos · Compartido",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Crear nuevo álbum",
|
"control_bottom_app_bar_create_new_album": "Crear nuevo álbum",
|
||||||
"control_bottom_app_bar_delete": "Eliminar",
|
"control_bottom_app_bar_delete": "Eliminar",
|
||||||
"control_bottom_app_bar_favorite": "Favorite",
|
"control_bottom_app_bar_favorite": "Favorite",
|
||||||
"control_bottom_app_bar_share": "Share",
|
"control_bottom_app_bar_share": "Share",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Untitled",
|
"create_album_page_untitled": "Untitled",
|
||||||
"create_shared_album_page_create": "Create",
|
"create_shared_album_page_create": "Create",
|
||||||
"create_shared_album_page_share": "Compartir",
|
"create_shared_album_page_share": "Compartir",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Cancelar",
|
"delete_dialog_cancel": "Cancelar",
|
||||||
"delete_dialog_ok": "Eliminar",
|
"delete_dialog_ok": "Eliminar",
|
||||||
"delete_dialog_title": "Eliminar Permanentemente",
|
"delete_dialog_title": "Eliminar Permanentemente",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Añadir Descripción...",
|
"exif_bottom_sheet_description": "Añadir Descripción...",
|
||||||
"exif_bottom_sheet_details": "DETALLES",
|
"exif_bottom_sheet_details": "DETALLES",
|
||||||
"exif_bottom_sheet_location": "LOCALZACIÓN",
|
"exif_bottom_sheet_location": "LOCALZACIÓN",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||||
"experimental_settings_subtitle": "Use at your own risk!",
|
"experimental_settings_subtitle": "Use at your own risk!",
|
||||||
"experimental_settings_title": "Experimental",
|
"experimental_settings_title": "Experimental",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favoritos",
|
"favorites_page_title": "Favoritos",
|
||||||
"home_page_add_to_album_conflicts": "Añadidos {added} elementos al álbum {album}. {failed} elementos ya están añadidos.",
|
"home_page_add_to_album_conflicts": "Añadidos {added} elementos al álbum {album}. {failed} elementos ya están añadidos.",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||||
"home_page_add_to_album_success": "Añadidos {added} elementos al álbum {album}.",
|
"home_page_add_to_album_success": "Añadidos {added} elementos al álbum {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Construyendo la línea de tiempo",
|
"home_page_building_timeline": "Construyendo la línea de tiempo",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||||
"home_page_first_time_notice": "Si esta es la primera vez que usas la app, por favor, asegúrate de elegir un álbum de respaldo para que la línea de tiempo pueda cargar fotos y videos en los álbumes.",
|
"home_page_first_time_notice": "Si esta es la primera vez que usas la app, por favor, asegúrate de elegir un álbum de respaldo para que la línea de tiempo pueda cargar fotos y videos en los álbumes.",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||||
"library_page_albums": "Albums",
|
"library_page_albums": "Albums",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Favoritos",
|
"library_page_favorites": "Favoritos",
|
||||||
"library_page_new_album": "New album",
|
"library_page_new_album": "New album",
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Lisätty albumiin {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Kohde on jo albumissa {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Edistyneen käyttäjän asetukset",
|
||||||
|
"advanced_settings_tile_title": "Edistyneet",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Kytke vianetsinnän lisäominaisuudet päälle",
|
||||||
|
"advanced_settings_troubleshooting_title": "Vianetsintä",
|
||||||
"album_info_card_backup_album_excluded": "JÄTETTY POIS",
|
"album_info_card_backup_album_excluded": "JÄTETTY POIS",
|
||||||
"album_info_card_backup_album_included": "SISÄLLYTETTY",
|
"album_info_card_backup_album_included": "SISÄLLYTETTY",
|
||||||
"album_thumbnail_card_item": "1 kohde",
|
"album_thumbnail_card_item": "1 kohde",
|
||||||
"album_thumbnail_card_items": "{} kohdetta",
|
"album_thumbnail_card_items": "{} kohdetta",
|
||||||
"album_thumbnail_card_shared": "Jaettu",
|
"album_thumbnail_card_shared": "Jaettu",
|
||||||
"album_thumbnail_owned": "Owned",
|
"album_thumbnail_owned": "Omistettu",
|
||||||
"album_thumbnail_shared_by": "Shared by {}",
|
"album_thumbnail_shared_by": "Jakanut {}",
|
||||||
"album_viewer_appbar_share_delete": "Poista albumi",
|
"album_viewer_appbar_share_delete": "Poista albumi",
|
||||||
"album_viewer_appbar_share_err_delete": "Albumin poistaminen epäonnistui",
|
"album_viewer_appbar_share_err_delete": "Albumin poistaminen epäonnistui",
|
||||||
"album_viewer_appbar_share_err_leave": "Albumista poistuminen epäonnistui",
|
"album_viewer_appbar_share_err_leave": "Albumista poistuminen epäonnistui",
|
||||||
@@ -16,8 +20,11 @@
|
|||||||
"album_viewer_appbar_share_leave": "Poistu albumista",
|
"album_viewer_appbar_share_leave": "Poistu albumista",
|
||||||
"album_viewer_appbar_share_remove": "Poista albumista",
|
"album_viewer_appbar_share_remove": "Poista albumista",
|
||||||
"album_viewer_page_share_add_users": "Lisää käyttäjiä",
|
"album_viewer_page_share_add_users": "Lisää käyttäjiä",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videot",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Arkisto ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynaaminen asetelma",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynaaminen asetelma",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Ryhmittele",
|
"asset_list_layout_settings_group_by": "Ryhmittele",
|
||||||
"asset_list_layout_settings_group_by_month": "Kuukauden mukaan",
|
"asset_list_layout_settings_group_by_month": "Kuukauden mukaan",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Kuukauden ja päivän mukaan",
|
"asset_list_layout_settings_group_by_month_day": "Kuukauden ja päivän mukaan",
|
||||||
@@ -38,9 +45,9 @@
|
|||||||
"backup_background_service_in_progress_notification": "Varmuuskopioidaan kohteita...",
|
"backup_background_service_in_progress_notification": "Varmuuskopioidaan kohteita...",
|
||||||
"backup_background_service_upload_failure_notification": "Lähetys palvelimelle epäonnistui {}",
|
"backup_background_service_upload_failure_notification": "Lähetys palvelimelle epäonnistui {}",
|
||||||
"backup_controller_page_albums": "Varmuuskopioi albumit",
|
"backup_controller_page_albums": "Varmuuskopioi albumit",
|
||||||
"backup_controller_page_background_app_refresh_disabled_content": "Enable background app refresh in Settings > General > Background App Refresh in order to use background backup.",
|
"backup_controller_page_background_app_refresh_disabled_content": "Salli sovelluksen päivittäminen taustalla suorittaaksesi varmuuskopiointia taustalla: Asetukset > Yleiset > Appien päivitys taustalla",
|
||||||
"backup_controller_page_background_app_refresh_disabled_title": "Background app refresh disabled",
|
"backup_controller_page_background_app_refresh_disabled_title": "Sovelluksen päivittäminen taustalla on pois päältä",
|
||||||
"backup_controller_page_background_app_refresh_enable_button_text": "Go to settings",
|
"backup_controller_page_background_app_refresh_enable_button_text": "Siirry asetuksiin",
|
||||||
"backup_controller_page_background_battery_info_link": "Näytä minulle miten",
|
"backup_controller_page_background_battery_info_link": "Näytä minulle miten",
|
||||||
"backup_controller_page_background_battery_info_message": "Kytke pois päältä kaikki Immichin taustatyöskentelyyn liittyvät akun optimoinnit, jotta varmistat taustavarmuuskopioinnin parhaan mahdollisen toiminnan.\n\nKoska tämä on laitekohtaista, tarkista tarvittavat toimet laitevalmistajan ohjeista.",
|
"backup_controller_page_background_battery_info_message": "Kytke pois päältä kaikki Immichin taustatyöskentelyyn liittyvät akun optimoinnit, jotta varmistat taustavarmuuskopioinnin parhaan mahdollisen toiminnan.\n\nKoska tämä on laitekohtaista, tarkista tarvittavat toimet laitevalmistajan ohjeista.",
|
||||||
"backup_controller_page_background_battery_info_ok": "OK",
|
"backup_controller_page_background_battery_info_ok": "OK",
|
||||||
@@ -95,30 +102,32 @@
|
|||||||
"cache_settings_subtitle": "Hallitse Immich-mobiilisovelluksen välimuistin käyttöä",
|
"cache_settings_subtitle": "Hallitse Immich-mobiilisovelluksen välimuistin käyttöä",
|
||||||
"cache_settings_thumbnail_size": "Esikatselukuvien välimuistin koko ({} kohdetta)",
|
"cache_settings_thumbnail_size": "Esikatselukuvien välimuistin koko ({} kohdetta)",
|
||||||
"cache_settings_title": "Välimuistin asetukset",
|
"cache_settings_title": "Välimuistin asetukset",
|
||||||
"change_password_form_confirm_password": "Confirm Password",
|
"change_password_form_confirm_password": "Vahvista salasana",
|
||||||
"change_password_form_description": "Hi {firstName} {lastName},\n\nThis is either the first time you are signing into the system or a request has been made to change your password. Please enter the new password below.",
|
"change_password_form_description": "Hei {firstName} {lastName},\n\nTämä on joko ensimmäinen kirjautumisesi järjestelmään tai salasanan vaihtaminen vaihtaminen on pakotettu. Ole hyvä ja syötä uusi salasana alle.",
|
||||||
"change_password_form_new_password": "New Password",
|
"change_password_form_new_password": "Uusi salasana",
|
||||||
"change_password_form_password_mismatch": "Passwords do not match",
|
"change_password_form_password_mismatch": "Salasanat eivät täsmää",
|
||||||
"change_password_form_reenter_new_password": "Re-enter New Password",
|
"change_password_form_reenter_new_password": "Uusi salasana uudelleen",
|
||||||
"common_add_to_album": "Add to album",
|
"common_add_to_album": "Lisää albumiin",
|
||||||
"common_change_password": "Change Password",
|
"common_change_password": "Vaihda salasana",
|
||||||
"common_create_new_album": "Create new album",
|
"common_create_new_album": "Luo uusi albumi",
|
||||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
"common_server_error": "Tarkista internet-yhteytesi. Varmista että palvelin on saavutettavissa ja sovellus-/palvelinversiot ovat yhteensopivia.",
|
||||||
"common_shared": "Shared",
|
"common_shared": "Jaettu",
|
||||||
"control_bottom_app_bar_add_to_album": "Lisää albumiin",
|
"control_bottom_app_bar_add_to_album": "Lisää albumiin",
|
||||||
"control_bottom_app_bar_album_info": "{} kohdetta",
|
"control_bottom_app_bar_album_info": "{} kohdetta",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} kohdetta · Jaettu",
|
"control_bottom_app_bar_album_info_shared": "{} kohdetta · Jaettu",
|
||||||
|
"control_bottom_app_bar_archive": "Arkistoi",
|
||||||
"control_bottom_app_bar_create_new_album": "Luo uusi albumi",
|
"control_bottom_app_bar_create_new_album": "Luo uusi albumi",
|
||||||
"control_bottom_app_bar_delete": "Poista",
|
"control_bottom_app_bar_delete": "Poista",
|
||||||
"control_bottom_app_bar_favorite": "Favorite",
|
"control_bottom_app_bar_favorite": "Suosikki",
|
||||||
"control_bottom_app_bar_share": "Jaa",
|
"control_bottom_app_bar_share": "Jaa",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Nimetön",
|
"create_album_page_untitled": "Nimetön",
|
||||||
"create_shared_album_page_create": "Luo",
|
"create_shared_album_page_create": "Luo",
|
||||||
"create_shared_album_page_share": "Jaa",
|
"create_shared_album_page_share": "Jaa",
|
||||||
"create_shared_album_page_share_add_assets": "LISÄÄ KOHTEITA",
|
"create_shared_album_page_share_add_assets": "LISÄÄ KOHTEITA",
|
||||||
"create_shared_album_page_share_select_photos": "Valitse kuvat",
|
"create_shared_album_page_share_select_photos": "Valitse kuvat",
|
||||||
"curated_location_page_title": "Places",
|
"curated_location_page_title": "Paikat",
|
||||||
"curated_object_page_title": "Things",
|
"curated_object_page_title": "Asiat",
|
||||||
"daily_title_text_date": "E, MMM dd",
|
"daily_title_text_date": "E, MMM dd",
|
||||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||||
"date_format": "E, LLL d, y • h:mm a",
|
"date_format": "E, LLL d, y • h:mm a",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Peruuta",
|
"delete_dialog_cancel": "Peruuta",
|
||||||
"delete_dialog_ok": "Poista",
|
"delete_dialog_ok": "Poista",
|
||||||
"delete_dialog_title": "Poista pysyvästi",
|
"delete_dialog_title": "Poista pysyvästi",
|
||||||
|
"description_input_hint_text": "Lisää kuvaus...",
|
||||||
|
"description_input_submit_error": "Virhe kuvauksen päivittämisessä, tarkista lisätiedot lokista",
|
||||||
"exif_bottom_sheet_description": "Lisää kuvaus…",
|
"exif_bottom_sheet_description": "Lisää kuvaus…",
|
||||||
"exif_bottom_sheet_details": "TIEDOT",
|
"exif_bottom_sheet_details": "TIEDOT",
|
||||||
"exif_bottom_sheet_location": "SIJAINTI",
|
"exif_bottom_sheet_location": "SIJAINTI",
|
||||||
@@ -133,23 +144,26 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Ota käyttöön kokeellinen kuvaruudukko",
|
"experimental_settings_new_asset_list_title": "Ota käyttöön kokeellinen kuvaruudukko",
|
||||||
"experimental_settings_subtitle": "Käyttö omalla vastuulla!",
|
"experimental_settings_subtitle": "Käyttö omalla vastuulla!",
|
||||||
"experimental_settings_title": "Kokeellinen",
|
"experimental_settings_title": "Kokeellinen",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Suosikit",
|
"favorites_page_title": "Suosikit",
|
||||||
"home_page_add_to_album_conflicts": "Lisätty {added} kohdetta albumiin {album}. {failed} kohdetta on jo albumissa.",
|
"home_page_add_to_album_conflicts": "Lisätty {added} kohdetta albumiin {album}. {failed} kohdetta on jo albumissa.",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_err_local": "Paikallisten kohteiden lisääminen albumeihin ei ole mahdollista, ohitetaan",
|
||||||
"home_page_add_to_album_success": "Lisätty {added} kohdetta albumiin {album}.",
|
"home_page_add_to_album_success": "Lisätty {added} kohdetta albumiin {album}.",
|
||||||
|
"home_page_archive_err_local": "Paikallisten kohteiden arkistointi ei ole mahdollista, ohitetaan",
|
||||||
"home_page_building_timeline": "Rakennetaan aikajanaa",
|
"home_page_building_timeline": "Rakennetaan aikajanaa",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_favorite_err_local": "Paikallisten kohteiden lisääminen suosikkeihin ei ole mahdollista, ohitetaan",
|
||||||
"home_page_first_time_notice": "Jos käytät sovellusta ensimmäistä kertaa, muista valita varmuuskopioitavat albumi(t), jotta aikajanalla voi olla kuvia ja videoita.",
|
"home_page_first_time_notice": "Jos käytät sovellusta ensimmäistä kertaa, muista valita varmuuskopioitavat albumi(t), jotta aikajanalla voi olla kuvia ja videoita.",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"image_viewer_page_state_provider_download_error": "Lataus epäonnistui",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"image_viewer_page_state_provider_download_success": "Lataus onnistui",
|
||||||
"library_page_albums": "Albumit",
|
"library_page_albums": "Albumit",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_archive": "Arkisto",
|
||||||
|
"library_page_device_albums": "Laitteen albumit",
|
||||||
"library_page_favorites": "Suosikit",
|
"library_page_favorites": "Suosikit",
|
||||||
"library_page_new_album": "Uusi albumi",
|
"library_page_new_album": "Uusi albumi",
|
||||||
"library_page_sharing": "Jakaminen",
|
"library_page_sharing": "Jakaminen",
|
||||||
"library_page_sort_created": "Viimeisin luotu",
|
"library_page_sort_created": "Viimeisin luotu",
|
||||||
"library_page_sort_title": "Albumin otsikko",
|
"library_page_sort_title": "Albumin otsikko",
|
||||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
"login_form_api_exception": "API-virhe. Tarkista palvelimen URL-osoite ja yritä uudelleen.",
|
||||||
"login_form_button_text": "Kirjaudu",
|
"login_form_button_text": "Kirjaudu",
|
||||||
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
|
"login_form_email_hint": "sahkopostisi@esimerkki.fi",
|
||||||
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti/api",
|
"login_form_endpoint_hint": "http://palvelimesi-osoite:portti/api",
|
||||||
@@ -164,55 +178,55 @@
|
|||||||
"login_form_failed_login": "Virhe kirjautumisessa. Tarkista palvelimen URL, sähköpostiosoite ja salasana.",
|
"login_form_failed_login": "Virhe kirjautumisessa. Tarkista palvelimen URL, sähköpostiosoite ja salasana.",
|
||||||
"login_form_label_email": "Sähköposti",
|
"login_form_label_email": "Sähköposti",
|
||||||
"login_form_label_password": "Salasana",
|
"login_form_label_password": "Salasana",
|
||||||
"login_form_next_button": "Next",
|
"login_form_next_button": "Seuraava",
|
||||||
"login_form_password_hint": "salasana",
|
"login_form_password_hint": "salasana",
|
||||||
"login_form_save_login": "Pysy kirjautuneena",
|
"login_form_save_login": "Pysy kirjautuneena",
|
||||||
"login_form_server_empty": "Enter a server URL.",
|
"login_form_server_empty": "Syötä palvelimen URL-osoite.",
|
||||||
"login_form_server_error": "Could not connect to server.",
|
"login_form_server_error": "Palvelimeen ei saatu yhteyttä.",
|
||||||
"monthly_title_text_date_format": "MMMM y",
|
"monthly_title_text_date_format": "MMMM y",
|
||||||
"motion_photos_page_title": "Motion Photos",
|
"motion_photos_page_title": "Liikekuvat",
|
||||||
"notification_permission_dialog_cancel": "Cancel",
|
"notification_permission_dialog_cancel": "Peruuta",
|
||||||
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
|
"notification_permission_dialog_content": "Ottaaksesi ilmoitukset käyttöön, siirry asetuksiin ja valitse 'salli'.",
|
||||||
"notification_permission_dialog_settings": "Settings",
|
"notification_permission_dialog_settings": "Asetukset",
|
||||||
"notification_permission_list_tile_content": "Grant permission to enable notifications.",
|
"notification_permission_list_tile_content": "Myönnä käyttöoikeus ottaaksesi ilmoitukset käyttöön.",
|
||||||
"notification_permission_list_tile_enable_button": "Enable Notifications",
|
"notification_permission_list_tile_enable_button": "Ota ilmoitukset käyttöön",
|
||||||
"notification_permission_list_tile_title": "Notification Permission",
|
"notification_permission_list_tile_title": "Ilmoitusten käyttöoikeus",
|
||||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
"permission_onboarding_continue_anyway": "Jatka silti",
|
||||||
"permission_onboarding_get_started": "Get started",
|
"permission_onboarding_get_started": "Aloittaminen",
|
||||||
"permission_onboarding_go_to_settings": "Go to settings",
|
"permission_onboarding_go_to_settings": "Siirry asetuksiin",
|
||||||
"permission_onboarding_grant_permission": "Grant permission",
|
"permission_onboarding_grant_permission": "Käyttöoikeuden myöntäminen",
|
||||||
"permission_onboarding_log_out": "Log out",
|
"permission_onboarding_log_out": "Kirjaudu ulos",
|
||||||
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_denied": "Kielletty käyttöoikeus. Käyttääksesi Immichiä, myönnä oikeus kuviin ja videoihin asetuksista.",
|
||||||
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
|
"permission_onboarding_permission_granted": "Käyttöoikeus myönnetty! Kaikki valmista.",
|
||||||
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_limited": "Rajoitettu käyttöoikeus. Salliaksesi Immichin varmuuskopioida ja hallita koko kuvakirjastoasi, myönnä oikeus kuviin ja videoihin asetuksista.",
|
||||||
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
|
"permission_onboarding_request": "Immich vaatii käyttöoikeuden kuvien ja videoiden käyttämiseen.",
|
||||||
"profile_drawer_app_logs": "Lokit",
|
"profile_drawer_app_logs": "Lokit",
|
||||||
"profile_drawer_client_server_up_to_date": "Asiakassovellus ja palvelin ovat ajan tasalla",
|
"profile_drawer_client_server_up_to_date": "Asiakassovellus ja palvelin ovat ajan tasalla",
|
||||||
"profile_drawer_settings": "Asetukset",
|
"profile_drawer_settings": "Asetukset",
|
||||||
"profile_drawer_sign_out": "Kirjaudu ulos",
|
"profile_drawer_sign_out": "Kirjaudu ulos",
|
||||||
"recently_added_page_title": "Recently Added",
|
"recently_added_page_title": "Viimeksi lisätyt",
|
||||||
"search_bar_hint": "Etsi kuvia",
|
"search_bar_hint": "Etsi kuvia",
|
||||||
"search_page_categories": "Categories",
|
"search_page_categories": "Kategoriat",
|
||||||
"search_page_favorites": "Favorites",
|
"search_page_favorites": "Suosikit",
|
||||||
"search_page_motion_photos": "Motion Photos",
|
"search_page_motion_photos": "Liikekuvat",
|
||||||
"search_page_no_objects": "Objektitietoja ei ole saatavilla",
|
"search_page_no_objects": "Objektitietoja ei ole saatavilla",
|
||||||
"search_page_no_places": "Paikkatietoja ei ole saatavilla",
|
"search_page_no_places": "Paikkatietoja ei ole saatavilla",
|
||||||
"search_page_places": "Paikat",
|
"search_page_places": "Paikat",
|
||||||
"search_page_recently_added": "Recently added",
|
"search_page_recently_added": "Viimeksi lisätyt",
|
||||||
"search_page_screenshots": "Screenshots",
|
"search_page_screenshots": "Näyttökuvat",
|
||||||
"search_page_selfies": "Selfies",
|
"search_page_selfies": "Selfiet",
|
||||||
"search_page_things": "Asiat",
|
"search_page_things": "Asiat",
|
||||||
"search_page_videos": "Videos",
|
"search_page_videos": "Videot",
|
||||||
"search_page_view_all_button": "View all",
|
"search_page_view_all_button": "Näytä kaikki",
|
||||||
"search_page_your_activity": "Your activity",
|
"search_page_your_activity": "Toimintasi",
|
||||||
"search_result_page_new_search_hint": "Uusi haku",
|
"search_result_page_new_search_hint": "Uusi haku",
|
||||||
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
|
"search_suggestion_list_smart_search_hint_1": "Älykäs haku on oletuksena käytössä. Käytä metatietojen etsimiseen syntaksia",
|
||||||
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
|
"search_suggestion_list_smart_search_hint_2": "m:hakusana",
|
||||||
"select_additional_user_for_sharing_page_suggestions": "Ehdotukset",
|
"select_additional_user_for_sharing_page_suggestions": "Ehdotukset",
|
||||||
"select_user_for_sharing_page_err_album": "Albumin luonti epäonnistui",
|
"select_user_for_sharing_page_err_album": "Albumin luonti epäonnistui",
|
||||||
"select_user_for_sharing_page_share_suggestions": "Ehdotukset",
|
"select_user_for_sharing_page_share_suggestions": "Ehdotukset",
|
||||||
"server_info_box_app_version": "App Version",
|
"server_info_box_app_version": "Sovelluksen versio",
|
||||||
"server_info_box_server_version": "Server Version",
|
"server_info_box_server_version": "Palvelimen versio",
|
||||||
"setting_image_viewer_help": "Sovellus lataa ensin pienen esikatselukuvan, toisena keskitarkkuuksisen kuvan (jos käytössä) ja kolmantena alkuperäisen täysitarkkuuksisen kuvan (jos käytössä)",
|
"setting_image_viewer_help": "Sovellus lataa ensin pienen esikatselukuvan, toisena keskitarkkuuksisen kuvan (jos käytössä) ja kolmantena alkuperäisen täysitarkkuuksisen kuvan (jos käytössä)",
|
||||||
"setting_image_viewer_original_subtitle": "Ota käyttöön ladataksesi alkuperäinen täysitarkkuuksinen kuva (suuri!). Poista käytöstä vähentääksesi datan käyttöä (sekä verkossa että laitteen välimuistissa).",
|
"setting_image_viewer_original_subtitle": "Ota käyttöön ladataksesi alkuperäinen täysitarkkuuksinen kuva (suuri!). Poista käytöstä vähentääksesi datan käyttöä (sekä verkossa että laitteen välimuistissa).",
|
||||||
"setting_image_viewer_original_title": "Lataa alkuperäinen kuva",
|
"setting_image_viewer_original_title": "Lataa alkuperäinen kuva",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Ajouté à {album}",
|
"add_to_album_bottom_sheet_added": "Ajouté à {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Déjà dans {album}",
|
"add_to_album_bottom_sheet_already_exists": "Déjà dans {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "EXCLU",
|
"album_info_card_backup_album_excluded": "EXCLU",
|
||||||
"album_info_card_backup_album_included": "INCLUS",
|
"album_info_card_backup_album_included": "INCLUS",
|
||||||
"album_thumbnail_card_item": "1 élément",
|
"album_thumbnail_card_item": "1 élément",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Retirer de l'album",
|
"album_viewer_appbar_share_remove": "Retirer de l'album",
|
||||||
"album_viewer_page_share_add_users": "Ajouter des utilisateurs",
|
"album_viewer_page_share_add_users": "Ajouter des utilisateurs",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Affichage dynamique",
|
"asset_list_layout_settings_dynamic_layout_title": "Affichage dynamique",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Grouper les éléments par",
|
"asset_list_layout_settings_group_by": "Grouper les éléments par",
|
||||||
"asset_list_layout_settings_group_by_month": "Mois",
|
"asset_list_layout_settings_group_by_month": "Mois",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Mois + jour",
|
"asset_list_layout_settings_group_by_month_day": "Mois + jour",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Ajouter à l'album",
|
"control_bottom_app_bar_add_to_album": "Ajouter à l'album",
|
||||||
"control_bottom_app_bar_album_info": "{} éléments",
|
"control_bottom_app_bar_album_info": "{} éléments",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} éléments - Partagés",
|
"control_bottom_app_bar_album_info_shared": "{} éléments - Partagés",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Créer un nouvel album",
|
"control_bottom_app_bar_create_new_album": "Créer un nouvel album",
|
||||||
"control_bottom_app_bar_delete": "Supprimer",
|
"control_bottom_app_bar_delete": "Supprimer",
|
||||||
"control_bottom_app_bar_favorite": "Favoris",
|
"control_bottom_app_bar_favorite": "Favoris",
|
||||||
"control_bottom_app_bar_share": "Partager",
|
"control_bottom_app_bar_share": "Partager",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Sans titre",
|
"create_album_page_untitled": "Sans titre",
|
||||||
"create_shared_album_page_create": "Créer",
|
"create_shared_album_page_create": "Créer",
|
||||||
"create_shared_album_page_share": "Partager",
|
"create_shared_album_page_share": "Partager",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Annuler",
|
"delete_dialog_cancel": "Annuler",
|
||||||
"delete_dialog_ok": "Supprimer",
|
"delete_dialog_ok": "Supprimer",
|
||||||
"delete_dialog_title": "Supprimer définitivement",
|
"delete_dialog_title": "Supprimer définitivement",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Ajouter une description...",
|
"exif_bottom_sheet_description": "Ajouter une description...",
|
||||||
"exif_bottom_sheet_details": "DÉTAILS",
|
"exif_bottom_sheet_details": "DÉTAILS",
|
||||||
"exif_bottom_sheet_location": "LOCALISATION",
|
"exif_bottom_sheet_location": "LOCALISATION",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Activer la grille de photos expérimentale",
|
"experimental_settings_new_asset_list_title": "Activer la grille de photos expérimentale",
|
||||||
"experimental_settings_subtitle": "Utilisez à vos dépends !",
|
"experimental_settings_subtitle": "Utilisez à vos dépends !",
|
||||||
"experimental_settings_title": "Expérimental",
|
"experimental_settings_title": "Expérimental",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favoris",
|
"favorites_page_title": "Favoris",
|
||||||
"home_page_add_to_album_conflicts": "{added} éléments ajoutés à l'album {album}. Les éléments {failed} sont déjà dans l'album.",
|
"home_page_add_to_album_conflicts": "{added} éléments ajoutés à l'album {album}. Les éléments {failed} sont déjà dans l'album.",
|
||||||
"home_page_add_to_album_err_local": "Impossible d'ajouter des éléments locaux aux albums pour le moment, étape ignorée",
|
"home_page_add_to_album_err_local": "Impossible d'ajouter des éléments locaux aux albums pour le moment, étape ignorée",
|
||||||
"home_page_add_to_album_success": "{added} éléments ajoutés à l'album {album}.",
|
"home_page_add_to_album_success": "{added} éléments ajoutés à l'album {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Construction de la chronologie",
|
"home_page_building_timeline": "Construction de la chronologie",
|
||||||
"home_page_favorite_err_local": "Impossible d'ajouter des éléments locaux aux favoris pour le moment, étape ignorée",
|
"home_page_favorite_err_local": "Impossible d'ajouter des éléments locaux aux favoris pour le moment, étape ignorée",
|
||||||
"home_page_first_time_notice": "Si c'est la première fois que vous utilisez l'application, veillez à choisir un ou plusieurs albums de sauvegarde afin que la chronologie puisse alimenter les photos et les vidéos de cet ou ces albums.",
|
"home_page_first_time_notice": "Si c'est la première fois que vous utilisez l'application, veillez à choisir un ou plusieurs albums de sauvegarde afin que la chronologie puisse alimenter les photos et les vidéos de cet ou ces albums.",
|
||||||
"image_viewer_page_state_provider_download_error": "Erreur de téléchargement",
|
"image_viewer_page_state_provider_download_error": "Erreur de téléchargement",
|
||||||
"image_viewer_page_state_provider_download_success": "Téléchargement réussi",
|
"image_viewer_page_state_provider_download_success": "Téléchargement réussi",
|
||||||
"library_page_albums": "Albums",
|
"library_page_albums": "Albums",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Favoris",
|
"library_page_favorites": "Favoris",
|
||||||
"library_page_new_album": "Nouvel album",
|
"library_page_new_album": "Nouvel album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Aggiunto in {album}",
|
"add_to_album_bottom_sheet_added": "Aggiunto in {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Già presente in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Già presente in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "ESCLUSI",
|
"album_info_card_backup_album_excluded": "ESCLUSI",
|
||||||
"album_info_card_backup_album_included": "INCLUSI",
|
"album_info_card_backup_album_included": "INCLUSI",
|
||||||
"album_thumbnail_card_item": "1 elemento ",
|
"album_thumbnail_card_item": "1 elemento ",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Rimuovere dall'album ",
|
"album_viewer_appbar_share_remove": "Rimuovere dall'album ",
|
||||||
"album_viewer_page_share_add_users": "Aggiungi utenti",
|
"album_viewer_page_share_add_users": "Aggiungi utenti",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Layout dinamico",
|
"asset_list_layout_settings_dynamic_layout_title": "Layout dinamico",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Raggruppa le immagini per",
|
"asset_list_layout_settings_group_by": "Raggruppa le immagini per",
|
||||||
"asset_list_layout_settings_group_by_month": "Mese",
|
"asset_list_layout_settings_group_by_month": "Mese",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Mese + giorno",
|
"asset_list_layout_settings_group_by_month_day": "Mese + giorno",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Aggiungi all'album",
|
"control_bottom_app_bar_add_to_album": "Aggiungi all'album",
|
||||||
"control_bottom_app_bar_album_info": "{} elementi",
|
"control_bottom_app_bar_album_info": "{} elementi",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} elementi · Condivisi",
|
"control_bottom_app_bar_album_info_shared": "{} elementi · Condivisi",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Crea nuovo album",
|
"control_bottom_app_bar_create_new_album": "Crea nuovo album",
|
||||||
"control_bottom_app_bar_delete": "Elimina",
|
"control_bottom_app_bar_delete": "Elimina",
|
||||||
"control_bottom_app_bar_favorite": "Preferiti",
|
"control_bottom_app_bar_favorite": "Preferiti",
|
||||||
"control_bottom_app_bar_share": "Condividi",
|
"control_bottom_app_bar_share": "Condividi",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Senza titolo",
|
"create_album_page_untitled": "Senza titolo",
|
||||||
"create_shared_album_page_create": "Crea",
|
"create_shared_album_page_create": "Crea",
|
||||||
"create_shared_album_page_share": "Condividi",
|
"create_shared_album_page_share": "Condividi",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Annulla",
|
"delete_dialog_cancel": "Annulla",
|
||||||
"delete_dialog_ok": "Elimina",
|
"delete_dialog_ok": "Elimina",
|
||||||
"delete_dialog_title": "Cancella definitivamente",
|
"delete_dialog_title": "Cancella definitivamente",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Aggiungi una descrizione...",
|
"exif_bottom_sheet_description": "Aggiungi una descrizione...",
|
||||||
"exif_bottom_sheet_details": "DETTAGLI",
|
"exif_bottom_sheet_details": "DETTAGLI",
|
||||||
"exif_bottom_sheet_location": "POSIZIONE",
|
"exif_bottom_sheet_location": "POSIZIONE",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Attiva griglia di foto sperimentale",
|
"experimental_settings_new_asset_list_title": "Attiva griglia di foto sperimentale",
|
||||||
"experimental_settings_subtitle": "Usalo a tuo rischio!",
|
"experimental_settings_subtitle": "Usalo a tuo rischio!",
|
||||||
"experimental_settings_title": "Sperimentale",
|
"experimental_settings_title": "Sperimentale",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Preferiti",
|
"favorites_page_title": "Preferiti",
|
||||||
"home_page_add_to_album_conflicts": "Aggiunti {added} elementi all'album {album}. {failed} elementi erano già presenti nell'album.",
|
"home_page_add_to_album_conflicts": "Aggiunti {added} elementi all'album {album}. {failed} elementi erano già presenti nell'album.",
|
||||||
"home_page_add_to_album_err_local": "Non puoi aggiungere negli album foto ancora non caricate",
|
"home_page_add_to_album_err_local": "Non puoi aggiungere negli album foto ancora non caricate",
|
||||||
"home_page_add_to_album_success": "Aggiunti {added} elementi all'album {album}",
|
"home_page_add_to_album_success": "Aggiunti {added} elementi all'album {album}",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Costruendo il Timeline",
|
"home_page_building_timeline": "Costruendo il Timeline",
|
||||||
"home_page_favorite_err_local": "Non puoi aggiungere tra i preferiti le foto ancora non caricate",
|
"home_page_favorite_err_local": "Non puoi aggiungere tra i preferiti le foto ancora non caricate",
|
||||||
"home_page_first_time_notice": "Se è la prima volta che usi l'app, assicurati di scegliere gli album per avere il Timeline con immagini e video",
|
"home_page_first_time_notice": "Se è la prima volta che usi l'app, assicurati di scegliere gli album per avere il Timeline con immagini e video",
|
||||||
"image_viewer_page_state_provider_download_error": "Errore nel Download",
|
"image_viewer_page_state_provider_download_error": "Errore nel Download",
|
||||||
"image_viewer_page_state_provider_download_success": "Download con successo",
|
"image_viewer_page_state_provider_download_success": "Download con successo",
|
||||||
"library_page_albums": "Album",
|
"library_page_albums": "Album",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Preferiti",
|
"library_page_favorites": "Preferiti",
|
||||||
"library_page_new_album": "Nuovo Album",
|
"library_page_new_album": "Nuovo Album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "{album}に追加しました",
|
"add_to_album_bottom_sheet_added": "{album}に追加しました",
|
||||||
"add_to_album_bottom_sheet_already_exists": "{album}にもう存在してます",
|
"add_to_album_bottom_sheet_already_exists": "{album}にもう存在してます",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "除外中",
|
"album_info_card_backup_album_excluded": "除外中",
|
||||||
"album_info_card_backup_album_included": "選択中",
|
"album_info_card_backup_album_included": "選択中",
|
||||||
"album_thumbnail_card_item": "項目数: 1",
|
"album_thumbnail_card_item": "項目数: 1",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "アルバムから除外",
|
"album_viewer_appbar_share_remove": "アルバムから除外",
|
||||||
"album_viewer_page_share_add_users": "ユーザーを追加",
|
"album_viewer_page_share_add_users": "ユーザーを追加",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "ダイナミックレイアウト",
|
"asset_list_layout_settings_dynamic_layout_title": "ダイナミックレイアウト",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "写真をグループ分けする方法:",
|
"asset_list_layout_settings_group_by": "写真をグループ分けする方法:",
|
||||||
"asset_list_layout_settings_group_by_month": "月",
|
"asset_list_layout_settings_group_by_month": "月",
|
||||||
"asset_list_layout_settings_group_by_month_day": "月+日",
|
"asset_list_layout_settings_group_by_month_day": "月+日",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "アルバムに追加",
|
"control_bottom_app_bar_add_to_album": "アルバムに追加",
|
||||||
"control_bottom_app_bar_album_info": "{}枚の写真",
|
"control_bottom_app_bar_album_info": "{}枚の写真",
|
||||||
"control_bottom_app_bar_album_info_shared": "{}枚の共有中の写真",
|
"control_bottom_app_bar_album_info_shared": "{}枚の共有中の写真",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "新しいアルバムを作成",
|
"control_bottom_app_bar_create_new_album": "新しいアルバムを作成",
|
||||||
"control_bottom_app_bar_delete": "削除",
|
"control_bottom_app_bar_delete": "削除",
|
||||||
"control_bottom_app_bar_favorite": "お気に入り",
|
"control_bottom_app_bar_favorite": "お気に入り",
|
||||||
"control_bottom_app_bar_share": "共有",
|
"control_bottom_app_bar_share": "共有",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "タイトル無し",
|
"create_album_page_untitled": "タイトル無し",
|
||||||
"create_shared_album_page_create": "作成",
|
"create_shared_album_page_create": "作成",
|
||||||
"create_shared_album_page_share": "共有",
|
"create_shared_album_page_share": "共有",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "キャンセル",
|
"delete_dialog_cancel": "キャンセル",
|
||||||
"delete_dialog_ok": "削除",
|
"delete_dialog_ok": "削除",
|
||||||
"delete_dialog_title": "永久的に削除",
|
"delete_dialog_title": "永久的に削除",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "概要を追加",
|
"exif_bottom_sheet_description": "概要を追加",
|
||||||
"exif_bottom_sheet_details": "詳細な情報",
|
"exif_bottom_sheet_details": "詳細な情報",
|
||||||
"exif_bottom_sheet_location": "撮影地",
|
"exif_bottom_sheet_location": "撮影地",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "試験的なグリッドを有効",
|
"experimental_settings_new_asset_list_title": "試験的なグリッドを有効",
|
||||||
"experimental_settings_subtitle": "試験的だから自己責任でね",
|
"experimental_settings_subtitle": "試験的だから自己責任でね",
|
||||||
"experimental_settings_title": "試験的",
|
"experimental_settings_title": "試験的",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "お気に入り",
|
"favorites_page_title": "お気に入り",
|
||||||
"home_page_add_to_album_conflicts": "{album}に{added}枚写真を追加しました。{failed}枚の写真は常に存在してたよ",
|
"home_page_add_to_album_conflicts": "{album}に{added}枚写真を追加しました。{failed}枚の写真は常に存在してたよ",
|
||||||
"home_page_add_to_album_err_local": "まだアップロードされてない写真はアルバムに登録できないよ",
|
"home_page_add_to_album_err_local": "まだアップロードされてない写真はアルバムに登録できないよ",
|
||||||
"home_page_add_to_album_success": "{album}に{added}枚写真を追加しました",
|
"home_page_add_to_album_success": "{album}に{added}枚写真を追加しました",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "タイムラインを構築中",
|
"home_page_building_timeline": "タイムラインを構築中",
|
||||||
"home_page_favorite_err_local": "まだアップロードされてない写真はお気に入り登録できないよ",
|
"home_page_favorite_err_local": "まだアップロードされてない写真はお気に入り登録できないよ",
|
||||||
"home_page_first_time_notice": "アプリを使うのがはじめての場合タイムラインに写真を表示するためにアルバムを選択してね",
|
"home_page_first_time_notice": "アプリを使うのがはじめての場合タイムラインに写真を表示するためにアルバムを選択してね",
|
||||||
"image_viewer_page_state_provider_download_error": "ダウンロードエラー",
|
"image_viewer_page_state_provider_download_error": "ダウンロードエラー",
|
||||||
"image_viewer_page_state_provider_download_success": "ダウンロードできました",
|
"image_viewer_page_state_provider_download_success": "ダウンロードできました",
|
||||||
"library_page_albums": "アルバム",
|
"library_page_albums": "アルバム",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "お気に入り",
|
"library_page_favorites": "お気に入り",
|
||||||
"library_page_new_album": "新しいアルバム",
|
"library_page_new_album": "新しいアルバム",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "{album}에 추가",
|
"add_to_album_bottom_sheet_added": "{album}에 추가",
|
||||||
"add_to_album_bottom_sheet_already_exists": "{album}에 이미 포함되어 있습니다",
|
"add_to_album_bottom_sheet_already_exists": "{album}에 이미 포함되어 있습니다",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "제외됨",
|
"album_info_card_backup_album_excluded": "제외됨",
|
||||||
"album_info_card_backup_album_included": "포함됨",
|
"album_info_card_backup_album_included": "포함됨",
|
||||||
"album_thumbnail_card_item": "1개 항목",
|
"album_thumbnail_card_item": "1개 항목",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "앨범에서 제거",
|
"album_viewer_appbar_share_remove": "앨범에서 제거",
|
||||||
"album_viewer_page_share_add_users": "사용자 추가",
|
"album_viewer_page_share_add_users": "사용자 추가",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "다이나믹 레이아웃",
|
"asset_list_layout_settings_dynamic_layout_title": "다이나믹 레이아웃",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "다음으로 그룹화",
|
"asset_list_layout_settings_group_by": "다음으로 그룹화",
|
||||||
"asset_list_layout_settings_group_by_month": "월",
|
"asset_list_layout_settings_group_by_month": "월",
|
||||||
"asset_list_layout_settings_group_by_month_day": "월 + 일",
|
"asset_list_layout_settings_group_by_month_day": "월 + 일",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "앨범에 추가",
|
"control_bottom_app_bar_add_to_album": "앨범에 추가",
|
||||||
"control_bottom_app_bar_album_info": "{} 항목",
|
"control_bottom_app_bar_album_info": "{} 항목",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} 항목 · 공유됨",
|
"control_bottom_app_bar_album_info_shared": "{} 항목 · 공유됨",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "앨범 생성",
|
"control_bottom_app_bar_create_new_album": "앨범 생성",
|
||||||
"control_bottom_app_bar_delete": "삭제",
|
"control_bottom_app_bar_delete": "삭제",
|
||||||
"control_bottom_app_bar_favorite": "즐겨찾기",
|
"control_bottom_app_bar_favorite": "즐겨찾기",
|
||||||
"control_bottom_app_bar_share": "공유",
|
"control_bottom_app_bar_share": "공유",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "제목없음",
|
"create_album_page_untitled": "제목없음",
|
||||||
"create_shared_album_page_create": "만들기",
|
"create_shared_album_page_create": "만들기",
|
||||||
"create_shared_album_page_share": "공유",
|
"create_shared_album_page_share": "공유",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "취소",
|
"delete_dialog_cancel": "취소",
|
||||||
"delete_dialog_ok": "삭제",
|
"delete_dialog_ok": "삭제",
|
||||||
"delete_dialog_title": "영구적으로 삭제",
|
"delete_dialog_title": "영구적으로 삭제",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "설명 추가...",
|
"exif_bottom_sheet_description": "설명 추가...",
|
||||||
"exif_bottom_sheet_details": "상세정보",
|
"exif_bottom_sheet_details": "상세정보",
|
||||||
"exif_bottom_sheet_location": "위치",
|
"exif_bottom_sheet_location": "위치",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "실험적 사진 그리드 적용",
|
"experimental_settings_new_asset_list_title": "실험적 사진 그리드 적용",
|
||||||
"experimental_settings_subtitle": "문제시 책임지지 않습니다!",
|
"experimental_settings_subtitle": "문제시 책임지지 않습니다!",
|
||||||
"experimental_settings_title": "실험적기능",
|
"experimental_settings_title": "실험적기능",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "즐겨찾기",
|
"favorites_page_title": "즐겨찾기",
|
||||||
"home_page_add_to_album_conflicts": "{album} 앨범에 {added} 미디어를 추가했습니다. {failed} 이미 앨범에 있는 항목입니다.",
|
"home_page_add_to_album_conflicts": "{album} 앨범에 {added} 미디어를 추가했습니다. {failed} 이미 앨범에 있는 항목입니다.",
|
||||||
"home_page_add_to_album_err_local": "앨범에 미디어파일을 추가할 수 없어, 건너뜁니다.",
|
"home_page_add_to_album_err_local": "앨범에 미디어파일을 추가할 수 없어, 건너뜁니다.",
|
||||||
"home_page_add_to_album_success": "{album} 앨범에 {added} 미디어를 추가했습니다. ",
|
"home_page_add_to_album_success": "{album} 앨범에 {added} 미디어를 추가했습니다. ",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "타임라인 생성",
|
"home_page_building_timeline": "타임라인 생성",
|
||||||
"home_page_favorite_err_local": "미디어파일을 즐겨찾기에 추가할 수 없어, 건너뜁니다.",
|
"home_page_favorite_err_local": "미디어파일을 즐겨찾기에 추가할 수 없어, 건너뜁니다.",
|
||||||
"home_page_first_time_notice": "앱을 처음 사용하는 경우 타임라인이 앨범의 사진과 비디오를 채울 수 있도록 백업대상 앨범을 선택해야 합니다.",
|
"home_page_first_time_notice": "앱을 처음 사용하는 경우 타임라인이 앨범의 사진과 비디오를 채울 수 있도록 백업대상 앨범을 선택해야 합니다.",
|
||||||
"image_viewer_page_state_provider_download_error": "다운로드 에러",
|
"image_viewer_page_state_provider_download_error": "다운로드 에러",
|
||||||
"image_viewer_page_state_provider_download_success": "다운로드 완료",
|
"image_viewer_page_state_provider_download_success": "다운로드 완료",
|
||||||
"library_page_albums": "앨범",
|
"library_page_albums": "앨범",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "즐겨찾기",
|
"library_page_favorites": "즐겨찾기",
|
||||||
"library_page_new_album": "새 앨범",
|
"library_page_new_album": "새 앨범",
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Lagt til i {album}",
|
"add_to_album_bottom_sheet_added": "Lagt til i {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
|
"add_to_album_bottom_sheet_already_exists": "Allerede i {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Avanserte brukerinnstillinger",
|
||||||
|
"advanced_settings_tile_title": "Avansert",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Aktiver ekstra funksjoner for feilsøking",
|
||||||
|
"advanced_settings_troubleshooting_title": "Feilsøking",
|
||||||
"album_info_card_backup_album_excluded": "EKSKLUDERT",
|
"album_info_card_backup_album_excluded": "EKSKLUDERT",
|
||||||
"album_info_card_backup_album_included": "INKLUDERT",
|
"album_info_card_backup_album_included": "INKLUDERT",
|
||||||
"album_thumbnail_card_item": "1 objekt",
|
"album_thumbnail_card_item": "1 objekt",
|
||||||
"album_thumbnail_card_items": "{} objekter",
|
"album_thumbnail_card_items": "{} objekter",
|
||||||
"album_thumbnail_card_shared": "Delt",
|
"album_thumbnail_card_shared": "Delt",
|
||||||
"album_thumbnail_owned": "Owned",
|
"album_thumbnail_owned": "Eid",
|
||||||
"album_thumbnail_shared_by": "Shared by {}",
|
"album_thumbnail_shared_by": "Delt av {}",
|
||||||
"album_viewer_appbar_share_delete": "Slett album",
|
"album_viewer_appbar_share_delete": "Slett album",
|
||||||
"album_viewer_appbar_share_err_delete": "Feilet ved sletting av album",
|
"album_viewer_appbar_share_err_delete": "Feilet ved sletting av album",
|
||||||
"album_viewer_appbar_share_err_leave": "Kunne ikke forlate albumet",
|
"album_viewer_appbar_share_err_leave": "Kunne ikke forlate albumet",
|
||||||
@@ -16,8 +20,11 @@
|
|||||||
"album_viewer_appbar_share_leave": "Forlat album",
|
"album_viewer_appbar_share_leave": "Forlat album",
|
||||||
"album_viewer_appbar_share_remove": "Fjern fra album",
|
"album_viewer_appbar_share_remove": "Fjern fra album",
|
||||||
"album_viewer_page_share_add_users": "Legg til brukere",
|
"album_viewer_page_share_add_users": "Legg til brukere",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videoer",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Arkiv ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Grupper bilder etter",
|
"asset_list_layout_settings_group_by": "Grupper bilder etter",
|
||||||
"asset_list_layout_settings_group_by_month": "Måned",
|
"asset_list_layout_settings_group_by_month": "Måned",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
|
"asset_list_layout_settings_group_by_month_day": "Måned + dag",
|
||||||
@@ -103,22 +110,24 @@
|
|||||||
"common_add_to_album": "Legg til i album",
|
"common_add_to_album": "Legg til i album",
|
||||||
"common_change_password": "Endre passord",
|
"common_change_password": "Endre passord",
|
||||||
"common_create_new_album": "Lag nytt album",
|
"common_create_new_album": "Lag nytt album",
|
||||||
"common_server_error": "Please check your network connection, make sure the server is reachable and app/server versions are compatible.",
|
"common_server_error": "Sjekk nettverkstilkobling, vær sikker på at serveren er mulig å nå og at app/server-versjoner er kompatible.",
|
||||||
"common_shared": "Delt",
|
"common_shared": "Delt",
|
||||||
"control_bottom_app_bar_add_to_album": "Legg til i album",
|
"control_bottom_app_bar_add_to_album": "Legg til i album",
|
||||||
"control_bottom_app_bar_album_info": "{} objekter",
|
"control_bottom_app_bar_album_info": "{} objekter",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} objekter · Delt",
|
"control_bottom_app_bar_album_info_shared": "{} objekter · Delt",
|
||||||
|
"control_bottom_app_bar_archive": "Arkiver",
|
||||||
"control_bottom_app_bar_create_new_album": "Lag nytt album",
|
"control_bottom_app_bar_create_new_album": "Lag nytt album",
|
||||||
"control_bottom_app_bar_delete": "Slett",
|
"control_bottom_app_bar_delete": "Slett",
|
||||||
"control_bottom_app_bar_favorite": "Favoritt",
|
"control_bottom_app_bar_favorite": "Favoritt",
|
||||||
"control_bottom_app_bar_share": "Del",
|
"control_bottom_app_bar_share": "Del",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Uten navn",
|
"create_album_page_untitled": "Uten navn",
|
||||||
"create_shared_album_page_create": "Opprett",
|
"create_shared_album_page_create": "Opprett",
|
||||||
"create_shared_album_page_share": "Del",
|
"create_shared_album_page_share": "Del",
|
||||||
"create_shared_album_page_share_add_assets": "LEGG TIL OBJEKTER",
|
"create_shared_album_page_share_add_assets": "LEGG TIL OBJEKTER",
|
||||||
"create_shared_album_page_share_select_photos": "Velg bilder",
|
"create_shared_album_page_share_select_photos": "Velg bilder",
|
||||||
"curated_location_page_title": "Places",
|
"curated_location_page_title": "Plasseringer",
|
||||||
"curated_object_page_title": "Things",
|
"curated_object_page_title": "Ting",
|
||||||
"daily_title_text_date": "E, MMM dd",
|
"daily_title_text_date": "E, MMM dd",
|
||||||
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
"daily_title_text_date_year": "E, MMM dd, yyyy",
|
||||||
"date_format": "E, LLL d, y • h:mm a",
|
"date_format": "E, LLL d, y • h:mm a",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Avbryt",
|
"delete_dialog_cancel": "Avbryt",
|
||||||
"delete_dialog_ok": "Slett",
|
"delete_dialog_ok": "Slett",
|
||||||
"delete_dialog_title": "Slett permanent",
|
"delete_dialog_title": "Slett permanent",
|
||||||
|
"description_input_hint_text": "Legg til beskrivelse...",
|
||||||
|
"description_input_submit_error": "Feil ved oppdatering av beskrivelse, sjekk loggen for flere detaljer",
|
||||||
"exif_bottom_sheet_description": "Legg til beskrivelse...",
|
"exif_bottom_sheet_description": "Legg til beskrivelse...",
|
||||||
"exif_bottom_sheet_details": "DETALJER",
|
"exif_bottom_sheet_details": "DETALJER",
|
||||||
"exif_bottom_sheet_location": "PLASSERING",
|
"exif_bottom_sheet_location": "PLASSERING",
|
||||||
@@ -133,23 +144,26 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Aktiver eksperimentell grid-visning",
|
"experimental_settings_new_asset_list_title": "Aktiver eksperimentell grid-visning",
|
||||||
"experimental_settings_subtitle": "Bruk på egen risiko!",
|
"experimental_settings_subtitle": "Bruk på egen risiko!",
|
||||||
"experimental_settings_title": "Eksperimentelt",
|
"experimental_settings_title": "Eksperimentelt",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favoritter",
|
"favorites_page_title": "Favoritter",
|
||||||
"home_page_add_to_album_conflicts": "Lagt til {added} objekter til album {album}. {failed} objekter er allerede i albumet.",
|
"home_page_add_to_album_conflicts": "Lagt til {added} objekter til album {album}. {failed} objekter er allerede i albumet.",
|
||||||
"home_page_add_to_album_err_local": "Kan ikke legge til lokale objekter til album enda, hopper over",
|
"home_page_add_to_album_err_local": "Kan ikke legge til lokale objekter til album enda, hopper over",
|
||||||
"home_page_add_to_album_success": "Lagt til {added} objekter til album {album}.",
|
"home_page_add_to_album_success": "Lagt til {added} objekter til album {album}.",
|
||||||
|
"home_page_archive_err_local": "Kan ikke arkivere lokale objekter enda, hopper over",
|
||||||
"home_page_building_timeline": "Genererer tidslinjen",
|
"home_page_building_timeline": "Genererer tidslinjen",
|
||||||
"home_page_favorite_err_local": "Kan ikke sette favoritt på lokale objekter enda, hopper over",
|
"home_page_favorite_err_local": "Kan ikke sette favoritt på lokale objekter enda, hopper over",
|
||||||
"home_page_first_time_notice": "Hvis dette er første gangen du benytter appen, så velg ett album(eller flere) slik at tidslinjen kan genereres med dine bilder og videoer.",
|
"home_page_first_time_notice": "Hvis dette er første gangen du benytter appen, så velg ett album(eller flere) slik at tidslinjen kan genereres med dine bilder og videoer.",
|
||||||
"image_viewer_page_state_provider_download_error": "Nedlasting feilet",
|
"image_viewer_page_state_provider_download_error": "Nedlasting feilet",
|
||||||
"image_viewer_page_state_provider_download_success": "Nedlasting vellykket",
|
"image_viewer_page_state_provider_download_success": "Nedlasting vellykket",
|
||||||
"library_page_albums": "Albumer",
|
"library_page_albums": "Albumer",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_archive": "Arkiv",
|
||||||
|
"library_page_device_albums": "Albumer på enheten",
|
||||||
"library_page_favorites": "Favoritter",
|
"library_page_favorites": "Favoritter",
|
||||||
"library_page_new_album": "Nytt album",
|
"library_page_new_album": "Nytt album",
|
||||||
"library_page_sharing": "Deling",
|
"library_page_sharing": "Deling",
|
||||||
"library_page_sort_created": "Nylig opplastet",
|
"library_page_sort_created": "Nylig opplastet",
|
||||||
"library_page_sort_title": "Album tittel",
|
"library_page_sort_title": "Album tittel",
|
||||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
"login_form_api_exception": "API feil. Sjekk server URL og prøv igjen.",
|
||||||
"login_form_button_text": "Logg inn",
|
"login_form_button_text": "Logg inn",
|
||||||
"login_form_email_hint": "dinepost@epost.no",
|
"login_form_email_hint": "dinepost@epost.no",
|
||||||
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
"login_form_endpoint_hint": "http://din-server-ip:port/api",
|
||||||
@@ -164,59 +178,59 @@
|
|||||||
"login_form_failed_login": "Feil ved innlogging, sjekk server URL, epost og passord",
|
"login_form_failed_login": "Feil ved innlogging, sjekk server URL, epost og passord",
|
||||||
"login_form_label_email": "Epostadresse",
|
"login_form_label_email": "Epostadresse",
|
||||||
"login_form_label_password": "Passord",
|
"login_form_label_password": "Passord",
|
||||||
"login_form_next_button": "Next",
|
"login_form_next_button": "Neste",
|
||||||
"login_form_password_hint": "passord",
|
"login_form_password_hint": "passord",
|
||||||
"login_form_save_login": "Forbli innlogget",
|
"login_form_save_login": "Forbli innlogget",
|
||||||
"login_form_server_empty": "Enter a server URL.",
|
"login_form_server_empty": "Skriv inn en server URL.",
|
||||||
"login_form_server_error": "Could not connect to server.",
|
"login_form_server_error": "Kan ikke koble til server.",
|
||||||
"monthly_title_text_date_format": "MMMM y",
|
"monthly_title_text_date_format": "MMMM y",
|
||||||
"motion_photos_page_title": "Motion Photos",
|
"motion_photos_page_title": "Bevegelige bilder",
|
||||||
"notification_permission_dialog_cancel": "Avbryt",
|
"notification_permission_dialog_cancel": "Avbryt",
|
||||||
"notification_permission_dialog_content": "For å aktivere notifikasjoner, gå til Innstillinger og velg tillat.",
|
"notification_permission_dialog_content": "For å aktivere notifikasjoner, gå til Innstillinger og velg tillat.",
|
||||||
"notification_permission_dialog_settings": "Innstillinger",
|
"notification_permission_dialog_settings": "Innstillinger",
|
||||||
"notification_permission_list_tile_content": "Tillat tilgang for å aktivere notifikasjoner",
|
"notification_permission_list_tile_content": "Tillat tilgang for å aktivere notifikasjoner",
|
||||||
"notification_permission_list_tile_enable_button": "Aktiver notifikasjoner",
|
"notification_permission_list_tile_enable_button": "Aktiver notifikasjoner",
|
||||||
"notification_permission_list_tile_title": "Notifikasjonstilgang",
|
"notification_permission_list_tile_title": "Notifikasjonstilgang",
|
||||||
"permission_onboarding_continue_anyway": "Continue anyway",
|
"permission_onboarding_continue_anyway": "Fortsett uansett",
|
||||||
"permission_onboarding_get_started": "Get started",
|
"permission_onboarding_get_started": "Kom i gang",
|
||||||
"permission_onboarding_go_to_settings": "Go to settings",
|
"permission_onboarding_go_to_settings": "Gå til innstillinger",
|
||||||
"permission_onboarding_grant_permission": "Grant permission",
|
"permission_onboarding_grant_permission": "Gi tilgang",
|
||||||
"permission_onboarding_log_out": "Log out",
|
"permission_onboarding_log_out": "Logg ut",
|
||||||
"permission_onboarding_permission_denied": "Permission denied. To use Immich, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_denied": "Tilgang avvist. For å bruke Immich, tillat å vise bilde og videoer i Innstillinger.",
|
||||||
"permission_onboarding_permission_granted": "Permission granted! You are all set.",
|
"permission_onboarding_permission_granted": "Tilgang gitt! Du er i gang.",
|
||||||
"permission_onboarding_permission_limited": "Permission limited. To let Immich backup and manage your entire gallery collection, grant photo and video permissions in Settings.",
|
"permission_onboarding_permission_limited": "Tilgang begrenset. For å la Immich ta backup og håndtere galleriet, tillatt bilde og video-tilgang i Innstillinger.",
|
||||||
"permission_onboarding_request": "Immich requires permission to view your photos and videos.",
|
"permission_onboarding_request": "Immich trenger tilgang til å se dine bilder og videoer",
|
||||||
"profile_drawer_app_logs": "Logg",
|
"profile_drawer_app_logs": "Logg",
|
||||||
"profile_drawer_client_server_up_to_date": "Klient og Server er oppdatert",
|
"profile_drawer_client_server_up_to_date": "Klient og Server er oppdatert",
|
||||||
"profile_drawer_settings": "Innstillinger",
|
"profile_drawer_settings": "Innstillinger",
|
||||||
"profile_drawer_sign_out": "Logg ut",
|
"profile_drawer_sign_out": "Logg ut",
|
||||||
"recently_added_page_title": "Recently Added",
|
"recently_added_page_title": "Nylig lagt til",
|
||||||
"search_bar_hint": "Søk i dine bilder",
|
"search_bar_hint": "Søk i dine bilder",
|
||||||
"search_page_categories": "Categories",
|
"search_page_categories": "Kategorier",
|
||||||
"search_page_favorites": "Favorites",
|
"search_page_favorites": "Favoritter",
|
||||||
"search_page_motion_photos": "Motion Photos",
|
"search_page_motion_photos": "Bevegelige bilder",
|
||||||
"search_page_no_objects": "Ingen objektinfo tilgjengelig",
|
"search_page_no_objects": "Ingen objektinfo tilgjengelig",
|
||||||
"search_page_no_places": "Ingen plasseringsinfo tilgjengelig",
|
"search_page_no_places": "Ingen plasseringsinfo tilgjengelig",
|
||||||
"search_page_places": "Plasser",
|
"search_page_places": "Plasser",
|
||||||
"search_page_recently_added": "Recently added",
|
"search_page_recently_added": "Nylig lagt til",
|
||||||
"search_page_screenshots": "Screenshots",
|
"search_page_screenshots": "Skjermbilder",
|
||||||
"search_page_selfies": "Selfies",
|
"search_page_selfies": "Selfier",
|
||||||
"search_page_things": "Ting",
|
"search_page_things": "Ting",
|
||||||
"search_page_videos": "Videos",
|
"search_page_videos": "Videoer",
|
||||||
"search_page_view_all_button": "View all",
|
"search_page_view_all_button": "Vis alle",
|
||||||
"search_page_your_activity": "Your activity",
|
"search_page_your_activity": "Din aktivitet",
|
||||||
"search_result_page_new_search_hint": "Nytt søk",
|
"search_result_page_new_search_hint": "Nytt søk",
|
||||||
"search_suggestion_list_smart_search_hint_1": "Smart search is enabled by default, to search for metadata use the syntax ",
|
"search_suggestion_list_smart_search_hint_1": "Smartsøk er aktivert som standard, for å søke etter metadata bruk syntaks ",
|
||||||
"search_suggestion_list_smart_search_hint_2": "m:your-search-term",
|
"search_suggestion_list_smart_search_hint_2": "m:ditt-søkeord",
|
||||||
"select_additional_user_for_sharing_page_suggestions": "Forslag",
|
"select_additional_user_for_sharing_page_suggestions": "Forslag",
|
||||||
"select_user_for_sharing_page_err_album": "Feilet ved oppretting av album",
|
"select_user_for_sharing_page_err_album": "Feilet ved oppretting av album",
|
||||||
"select_user_for_sharing_page_share_suggestions": "Forslag",
|
"select_user_for_sharing_page_share_suggestions": "Forslag",
|
||||||
"server_info_box_app_version": "App versjon",
|
"server_info_box_app_version": "App versjon",
|
||||||
"server_info_box_server_version": "Server versjon",
|
"server_info_box_server_version": "Server versjon",
|
||||||
"setting_image_viewer_help": "Først lastes mikrobilder, deretter middels-oppløsningbildet (hvis aktivert), til slutt lastes original (hvis aktivert).",
|
"setting_image_viewer_help": "Først lastes mikrobilder, deretter forhåndsvisningsbildet (hvis aktivert), til slutt lastes original (hvis aktivert).",
|
||||||
"setting_image_viewer_original_subtitle": "Aktiver for å laste originalbildet i full oppløsning (Stort!). Deaktiver for å spare databruk (både nettverksbruk og bufferdata på enheten).",
|
"setting_image_viewer_original_subtitle": "Aktiver for å laste originalbildet i full oppløsning (Stort!). Deaktiver for å spare databruk (både nettverksbruk og bufferdata på enheten).",
|
||||||
"setting_image_viewer_original_title": "Last originalbildet",
|
"setting_image_viewer_original_title": "Last originalbildet",
|
||||||
"setting_image_viewer_preview_subtitle": "Aktiver for å laste ett bilde av middels-oppløsning. Deaktiver for å enten direkte laste inn originalen eller kun benytte miniatyrbilde.",
|
"setting_image_viewer_preview_subtitle": "Aktiver for å laste ett bilde av medium oppløsning. Deaktiver for å enten direkte laste inn originalen eller kun benytte miniatyrbilde.",
|
||||||
"setting_image_viewer_preview_title": "Last forhåndsvisningsbilde",
|
"setting_image_viewer_preview_title": "Last forhåndsvisningsbilde",
|
||||||
"setting_notifications_notify_failures_grace_period": "Varsle om sikkerhetskopieringsfeil i bakgrunnen: {}",
|
"setting_notifications_notify_failures_grace_period": "Varsle om sikkerhetskopieringsfeil i bakgrunnen: {}",
|
||||||
"setting_notifications_notify_hours": "{} timer",
|
"setting_notifications_notify_hours": "{} timer",
|
||||||
@@ -251,7 +265,7 @@
|
|||||||
"theme_setting_asset_list_tiles_per_row_title": "Antall ressurser per rad ({})",
|
"theme_setting_asset_list_tiles_per_row_title": "Antall ressurser per rad ({})",
|
||||||
"theme_setting_dark_mode_switch": "Mørk modus",
|
"theme_setting_dark_mode_switch": "Mørk modus",
|
||||||
"theme_setting_image_viewer_quality_subtitle": "Juster kvaliteten på detaljer med bildeviser",
|
"theme_setting_image_viewer_quality_subtitle": "Juster kvaliteten på detaljer med bildeviser",
|
||||||
"theme_setting_image_viewer_quality_title": "Bilderviser-kvalitet",
|
"theme_setting_image_viewer_quality_title": "Kvalitet på bildevisning",
|
||||||
"theme_setting_system_theme_switch": "Automatisk (følg system)",
|
"theme_setting_system_theme_switch": "Automatisk (følg system)",
|
||||||
"theme_setting_theme_subtitle": "Velg app'ens temainnstilling",
|
"theme_setting_theme_subtitle": "Velg app'ens temainnstilling",
|
||||||
"theme_setting_theme_title": "Tema",
|
"theme_setting_theme_title": "Tema",
|
||||||
@@ -261,6 +275,6 @@
|
|||||||
"version_announcement_overlay_release_notes": "Endringslogg",
|
"version_announcement_overlay_release_notes": "Endringslogg",
|
||||||
"version_announcement_overlay_text_1": "Hei, det er en ny versjon av",
|
"version_announcement_overlay_text_1": "Hei, det er en ny versjon av",
|
||||||
"version_announcement_overlay_text_2": "vennligst ta deg tid til å besøke",
|
"version_announcement_overlay_text_2": "vennligst ta deg tid til å besøke",
|
||||||
"version_announcement_overlay_text_3": "og verifiser at din docker-compose og .env oppsett er oppdatert for å forhindre en eventuell miskonfigurasjon. Spesielt hvis du benytter WatchTower eller en annen tjeneste som håndterer oppdatering av applikasjoner på serveren automatisk.",
|
"version_announcement_overlay_text_3": " og verifiser at din docker-compose og .env oppsett er oppdatert for å forhindre en eventuell miskonfigurasjon. Spesielt hvis du benytter WatchTower eller en annen tjeneste som håndterer oppdatering av applikasjoner på serveren automatisk.",
|
||||||
"version_announcement_overlay_title": "Ny serverversjon tilgjengelig"
|
"version_announcement_overlay_title": "Ny serverversjon tilgjengelig"
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Toegevoegd aan {album}",
|
"add_to_album_bottom_sheet_added": "Toegevoegd aan {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Staat al in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Staat al in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Geavanceerde gebruikersinstellingen",
|
||||||
|
"advanced_settings_tile_title": "Geavanceerd",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Schakel extra functies in voor probleemoplossing",
|
||||||
|
"advanced_settings_troubleshooting_title": "Probleemoplossing",
|
||||||
"album_info_card_backup_album_excluded": "UITGESLOTEN",
|
"album_info_card_backup_album_excluded": "UITGESLOTEN",
|
||||||
"album_info_card_backup_album_included": "INGESLOTEN",
|
"album_info_card_backup_album_included": "INGESLOTEN",
|
||||||
"album_thumbnail_card_item": "1 item",
|
"album_thumbnail_card_item": "1 item",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Verwijder uit album",
|
"album_viewer_appbar_share_remove": "Verwijder uit album",
|
||||||
"album_viewer_page_share_add_users": "Gebruikers toevoegen",
|
"album_viewer_page_share_add_users": "Gebruikers toevoegen",
|
||||||
"all_videos_page_title": "Video's",
|
"all_videos_page_title": "Video's",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archief ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamische layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamische layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Groupeer items per",
|
"asset_list_layout_settings_group_by": "Groupeer items per",
|
||||||
"asset_list_layout_settings_group_by_month": "Maand",
|
"asset_list_layout_settings_group_by_month": "Maand",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Maand + dag",
|
"asset_list_layout_settings_group_by_month_day": "Maand + dag",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Toevoegen aan album",
|
"control_bottom_app_bar_add_to_album": "Toevoegen aan album",
|
||||||
"control_bottom_app_bar_album_info": "{} items",
|
"control_bottom_app_bar_album_info": "{} items",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} items · Gedeeld",
|
"control_bottom_app_bar_album_info_shared": "{} items · Gedeeld",
|
||||||
|
"control_bottom_app_bar_archive": "Archiveren",
|
||||||
"control_bottom_app_bar_create_new_album": "Maak nieuw album",
|
"control_bottom_app_bar_create_new_album": "Maak nieuw album",
|
||||||
"control_bottom_app_bar_delete": "Verwijderen",
|
"control_bottom_app_bar_delete": "Verwijderen",
|
||||||
"control_bottom_app_bar_favorite": "Favoriet",
|
"control_bottom_app_bar_favorite": "Favoriet",
|
||||||
"control_bottom_app_bar_share": "Delen",
|
"control_bottom_app_bar_share": "Delen",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Naamloos",
|
"create_album_page_untitled": "Naamloos",
|
||||||
"create_shared_album_page_create": "Aanmaken",
|
"create_shared_album_page_create": "Aanmaken",
|
||||||
"create_shared_album_page_share": "Delen",
|
"create_shared_album_page_share": "Delen",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Annuleren",
|
"delete_dialog_cancel": "Annuleren",
|
||||||
"delete_dialog_ok": "Verwijderen",
|
"delete_dialog_ok": "Verwijderen",
|
||||||
"delete_dialog_title": "Permanent verwijderen",
|
"delete_dialog_title": "Permanent verwijderen",
|
||||||
|
"description_input_hint_text": "Beschrijving toevoegen...",
|
||||||
|
"description_input_submit_error": "Beschrijving bijwerken mislukt, controleer het logboek voor meer details",
|
||||||
"exif_bottom_sheet_description": "Beschrijving toevoegen...",
|
"exif_bottom_sheet_description": "Beschrijving toevoegen...",
|
||||||
"exif_bottom_sheet_details": "DETAILS",
|
"exif_bottom_sheet_details": "DETAILS",
|
||||||
"exif_bottom_sheet_location": "LOCATIE",
|
"exif_bottom_sheet_location": "LOCATIE",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Experimenteel foto grid inschakelen",
|
"experimental_settings_new_asset_list_title": "Experimenteel foto grid inschakelen",
|
||||||
"experimental_settings_subtitle": "Gebruik op eigen risico!",
|
"experimental_settings_subtitle": "Gebruik op eigen risico!",
|
||||||
"experimental_settings_title": "Experimenteel",
|
"experimental_settings_title": "Experimenteel",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favorieten",
|
"favorites_page_title": "Favorieten",
|
||||||
"home_page_add_to_album_conflicts": "{added} items toegevoegd aan album {album}. {failed} items staan al in het album.",
|
"home_page_add_to_album_conflicts": "{added} items toegevoegd aan album {album}. {failed} items staan al in het album.",
|
||||||
"home_page_add_to_album_err_local": "Lokale items kunnen nog niet aan albums worden toegevoegd, overslaan",
|
"home_page_add_to_album_err_local": "Lokale items kunnen nog niet aan albums worden toegevoegd, overslaan",
|
||||||
"home_page_add_to_album_success": "{added} items toegevoegd aan album {album}.",
|
"home_page_add_to_album_success": "{added} items toegevoegd aan album {album}.",
|
||||||
|
"home_page_archive_err_local": "Lokale items kunnen nog niet gearchiveerd worden, overslaan",
|
||||||
"home_page_building_timeline": "Tijdlijn opbouwen",
|
"home_page_building_timeline": "Tijdlijn opbouwen",
|
||||||
"home_page_favorite_err_local": "Lokale items kunnen nog niet als favoriet worden aangemerkt, overslaan",
|
"home_page_favorite_err_local": "Lokale items kunnen nog niet als favoriet worden aangemerkt, overslaan",
|
||||||
"home_page_first_time_notice": "Als dit de eerste keer is dat je de app gebruikt, zorg er dan voor dat je een back-up album kiest, zodat de tijdlijn gevuld kan worden met foto's en video's uit het album.",
|
"home_page_first_time_notice": "Als dit de eerste keer is dat je de app gebruikt, zorg er dan voor dat je een back-up album kiest, zodat de tijdlijn gevuld kan worden met foto's en video's uit het album.",
|
||||||
"image_viewer_page_state_provider_download_error": "Download mislukt",
|
"image_viewer_page_state_provider_download_error": "Download mislukt",
|
||||||
"image_viewer_page_state_provider_download_success": "Download succesvol",
|
"image_viewer_page_state_provider_download_success": "Download succesvol",
|
||||||
"library_page_albums": "Albums",
|
"library_page_albums": "Albums",
|
||||||
|
"library_page_archive": "Archief",
|
||||||
"library_page_device_albums": "Albums op apparaat",
|
"library_page_device_albums": "Albums op apparaat",
|
||||||
"library_page_favorites": "Favorieten",
|
"library_page_favorites": "Favorieten",
|
||||||
"library_page_new_album": "Nieuw album",
|
"library_page_new_album": "Nieuw album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "WYKLUCZONE",
|
"album_info_card_backup_album_excluded": "WYKLUCZONE",
|
||||||
"album_info_card_backup_album_included": "WŁĄCZONE",
|
"album_info_card_backup_album_included": "WŁĄCZONE",
|
||||||
"album_thumbnail_card_item": "1 pozycja",
|
"album_thumbnail_card_item": "1 pozycja",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Usuń z albumu",
|
"album_viewer_appbar_share_remove": "Usuń z albumu",
|
||||||
"album_viewer_page_share_add_users": "Dodaj użytkowników",
|
"album_viewer_page_share_add_users": "Dodaj użytkowników",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamic layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Group assets by",
|
"asset_list_layout_settings_group_by": "Group assets by",
|
||||||
"asset_list_layout_settings_group_by_month": "Month",
|
"asset_list_layout_settings_group_by_month": "Month",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
"asset_list_layout_settings_group_by_month_day": "Month + day",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Add to album",
|
"control_bottom_app_bar_add_to_album": "Add to album",
|
||||||
"control_bottom_app_bar_album_info": "{} items",
|
"control_bottom_app_bar_album_info": "{} items",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
"control_bottom_app_bar_album_info_shared": "{} items · Shared",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Create new album",
|
"control_bottom_app_bar_create_new_album": "Create new album",
|
||||||
"control_bottom_app_bar_delete": "Usuń",
|
"control_bottom_app_bar_delete": "Usuń",
|
||||||
"control_bottom_app_bar_favorite": "Favorite",
|
"control_bottom_app_bar_favorite": "Favorite",
|
||||||
"control_bottom_app_bar_share": "Udostępnij",
|
"control_bottom_app_bar_share": "Udostępnij",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Bez tytułu",
|
"create_album_page_untitled": "Bez tytułu",
|
||||||
"create_shared_album_page_create": "Utwórz",
|
"create_shared_album_page_create": "Utwórz",
|
||||||
"create_shared_album_page_share": "Udostępnij",
|
"create_shared_album_page_share": "Udostępnij",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Anuluj",
|
"delete_dialog_cancel": "Anuluj",
|
||||||
"delete_dialog_ok": "Usuń",
|
"delete_dialog_ok": "Usuń",
|
||||||
"delete_dialog_title": "Usuń trwale",
|
"delete_dialog_title": "Usuń trwale",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Dodaj Opis...",
|
"exif_bottom_sheet_description": "Dodaj Opis...",
|
||||||
"exif_bottom_sheet_details": "SZCZEGÓŁY",
|
"exif_bottom_sheet_details": "SZCZEGÓŁY",
|
||||||
"exif_bottom_sheet_location": "LOKALIZACJA",
|
"exif_bottom_sheet_location": "LOKALIZACJA",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
"experimental_settings_new_asset_list_title": "Enable experimental photo grid",
|
||||||
"experimental_settings_subtitle": "Use at your own risk!",
|
"experimental_settings_subtitle": "Use at your own risk!",
|
||||||
"experimental_settings_title": "Experimental",
|
"experimental_settings_title": "Experimental",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favorites",
|
"favorites_page_title": "Favorites",
|
||||||
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||||
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
"home_page_add_to_album_success": "Added {added} assets to album {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Building the timeline",
|
"home_page_building_timeline": "Building the timeline",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||||
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
|
"home_page_first_time_notice": "If this is your first time using the app, please make sure to choose a backup album(s) so that the timeline can populate photos and videos in the album(s).",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||||
"library_page_albums": "Albumy",
|
"library_page_albums": "Albumy",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Favorites",
|
"library_page_favorites": "Favorites",
|
||||||
"library_page_new_album": "Nowy album",
|
"library_page_new_album": "Nowy album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Добавлено в {album}",
|
"add_to_album_bottom_sheet_added": "Добавлено в {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Уже в {album}",
|
"add_to_album_bottom_sheet_already_exists": "Уже в {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "ИСКЛЮЧЕН",
|
"album_info_card_backup_album_excluded": "ИСКЛЮЧЕН",
|
||||||
"album_info_card_backup_album_included": "ВКЛЮЧЕН",
|
"album_info_card_backup_album_included": "ВКЛЮЧЕН",
|
||||||
"album_thumbnail_card_item": "1 объект",
|
"album_thumbnail_card_item": "1 объект",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Удалить из альбома",
|
"album_viewer_appbar_share_remove": "Удалить из альбома",
|
||||||
"album_viewer_page_share_add_users": "Добавить пользователей",
|
"album_viewer_page_share_add_users": "Добавить пользователей",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Динамическое расположение",
|
"asset_list_layout_settings_dynamic_layout_title": "Динамическое расположение",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Группировать объекты по",
|
"asset_list_layout_settings_group_by": "Группировать объекты по",
|
||||||
"asset_list_layout_settings_group_by_month": "месяцу",
|
"asset_list_layout_settings_group_by_month": "месяцу",
|
||||||
"asset_list_layout_settings_group_by_month_day": "месяцу и дню",
|
"asset_list_layout_settings_group_by_month_day": "месяцу и дню",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Добавить в альбом",
|
"control_bottom_app_bar_add_to_album": "Добавить в альбом",
|
||||||
"control_bottom_app_bar_album_info": "{} файлов",
|
"control_bottom_app_bar_album_info": "{} файлов",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} файлов · Общий",
|
"control_bottom_app_bar_album_info_shared": "{} файлов · Общий",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "\nСоздать новый альбом",
|
"control_bottom_app_bar_create_new_album": "\nСоздать новый альбом",
|
||||||
"control_bottom_app_bar_delete": "Удалить",
|
"control_bottom_app_bar_delete": "Удалить",
|
||||||
"control_bottom_app_bar_favorite": "Избранное",
|
"control_bottom_app_bar_favorite": "Избранное",
|
||||||
"control_bottom_app_bar_share": "Поделиться",
|
"control_bottom_app_bar_share": "Поделиться",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Без названия",
|
"create_album_page_untitled": "Без названия",
|
||||||
"create_shared_album_page_create": "Создать",
|
"create_shared_album_page_create": "Создать",
|
||||||
"create_shared_album_page_share": "Поделиться",
|
"create_shared_album_page_share": "Поделиться",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Отменить",
|
"delete_dialog_cancel": "Отменить",
|
||||||
"delete_dialog_ok": "Удалить",
|
"delete_dialog_ok": "Удалить",
|
||||||
"delete_dialog_title": "Удалить навсегда",
|
"delete_dialog_title": "Удалить навсегда",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Добавить описание...",
|
"exif_bottom_sheet_description": "Добавить описание...",
|
||||||
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
|
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
|
||||||
"exif_bottom_sheet_location": "МЕСТОПОЛОЖЕНИЕ",
|
"exif_bottom_sheet_location": "МЕСТОПОЛОЖЕНИЕ",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Включить экспериментальную сетку фотографий",
|
"experimental_settings_new_asset_list_title": "Включить экспериментальную сетку фотографий",
|
||||||
"experimental_settings_subtitle": "Используйте на свой страх и риск!",
|
"experimental_settings_subtitle": "Используйте на свой страх и риск!",
|
||||||
"experimental_settings_title": "Экспериментальные функции",
|
"experimental_settings_title": "Экспериментальные функции",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Избранное",
|
"favorites_page_title": "Избранное",
|
||||||
"home_page_add_to_album_conflicts": "Добавлено {added} объектов в альбом {album}. Объекты {failed} уже есть в альбоме.",
|
"home_page_add_to_album_conflicts": "Добавлено {added} объектов в альбом {album}. Объекты {failed} уже есть в альбоме.",
|
||||||
"home_page_add_to_album_err_local": "Пока нельзя добавлять локальные объекты в альбомы, пропускаем",
|
"home_page_add_to_album_err_local": "Пока нельзя добавлять локальные объекты в альбомы, пропускаем",
|
||||||
"home_page_add_to_album_success": "Добавлено {added} объектов в альбом {album}.",
|
"home_page_add_to_album_success": "Добавлено {added} объектов в альбом {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Построение временной шкалы",
|
"home_page_building_timeline": "Построение временной шкалы",
|
||||||
"home_page_favorite_err_local": "Пока не удается добавить в избранное локальные объекты, пропускаем",
|
"home_page_favorite_err_local": "Пока не удается добавить в избранное локальные объекты, пропускаем",
|
||||||
"home_page_first_time_notice": "Если вы используете приложение впервые, убедитесь, что вы выбрали резервный(е) альбом(ы), чтобы временная шкала могла заполнить фотографии и видео в альбоме(ах).",
|
"home_page_first_time_notice": "Если вы используете приложение впервые, убедитесь, что вы выбрали резервный(е) альбом(ы), чтобы временная шкала могла заполнить фотографии и видео в альбоме(ах).",
|
||||||
"image_viewer_page_state_provider_download_error": "Ошибка загрузки",
|
"image_viewer_page_state_provider_download_error": "Ошибка загрузки",
|
||||||
"image_viewer_page_state_provider_download_success": "Успешно загружено",
|
"image_viewer_page_state_provider_download_success": "Успешно загружено",
|
||||||
"library_page_albums": "Альбомы",
|
"library_page_albums": "Альбомы",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Избранное",
|
"library_page_favorites": "Избранное",
|
||||||
"library_page_new_album": "Новый альбом",
|
"library_page_new_album": "Новый альбом",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Pridané do {album}",
|
"add_to_album_bottom_sheet_added": "Pridané do {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Už v {album}",
|
"add_to_album_bottom_sheet_already_exists": "Už v {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "VYLÚČENÉ",
|
"album_info_card_backup_album_excluded": "VYLÚČENÉ",
|
||||||
"album_info_card_backup_album_included": "ZAHRNUTÉ",
|
"album_info_card_backup_album_included": "ZAHRNUTÉ",
|
||||||
"album_thumbnail_card_item": "1 položka",
|
"album_thumbnail_card_item": "1 položka",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Odstrániť z albumu",
|
"album_viewer_appbar_share_remove": "Odstrániť z albumu",
|
||||||
"album_viewer_page_share_add_users": "Pridať používateľov",
|
"album_viewer_page_share_add_users": "Pridať používateľov",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamické rozloženie",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamické rozloženie",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Zoskupiť položky podľa",
|
"asset_list_layout_settings_group_by": "Zoskupiť položky podľa",
|
||||||
"asset_list_layout_settings_group_by_month": "Mesiac",
|
"asset_list_layout_settings_group_by_month": "Mesiac",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Mesiac + deň",
|
"asset_list_layout_settings_group_by_month_day": "Mesiac + deň",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Pridať do albumu",
|
"control_bottom_app_bar_add_to_album": "Pridať do albumu",
|
||||||
"control_bottom_app_bar_album_info": "{} položiek",
|
"control_bottom_app_bar_album_info": "{} položiek",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} položky - zdieľané",
|
"control_bottom_app_bar_album_info_shared": "{} položky - zdieľané",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Vytvoriť nový album",
|
"control_bottom_app_bar_create_new_album": "Vytvoriť nový album",
|
||||||
"control_bottom_app_bar_delete": "Vymazať",
|
"control_bottom_app_bar_delete": "Vymazať",
|
||||||
"control_bottom_app_bar_favorite": "Obľúbené",
|
"control_bottom_app_bar_favorite": "Obľúbené",
|
||||||
"control_bottom_app_bar_share": "Zdieľať",
|
"control_bottom_app_bar_share": "Zdieľať",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Bez názvu",
|
"create_album_page_untitled": "Bez názvu",
|
||||||
"create_shared_album_page_create": "Vytvoriť",
|
"create_shared_album_page_create": "Vytvoriť",
|
||||||
"create_shared_album_page_share": "Zdieľať",
|
"create_shared_album_page_share": "Zdieľať",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Zrušiť",
|
"delete_dialog_cancel": "Zrušiť",
|
||||||
"delete_dialog_ok": "Vymazať",
|
"delete_dialog_ok": "Vymazať",
|
||||||
"delete_dialog_title": "Vymazať natrvalo",
|
"delete_dialog_title": "Vymazať natrvalo",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Pridať popis...",
|
"exif_bottom_sheet_description": "Pridať popis...",
|
||||||
"exif_bottom_sheet_details": "PODROBNOSTI",
|
"exif_bottom_sheet_details": "PODROBNOSTI",
|
||||||
"exif_bottom_sheet_location": "LOKALITA",
|
"exif_bottom_sheet_location": "LOKALITA",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Povolenie experimentálnej mriežky fotografií",
|
"experimental_settings_new_asset_list_title": "Povolenie experimentálnej mriežky fotografií",
|
||||||
"experimental_settings_subtitle": "Používajte na vlastné riziko!",
|
"experimental_settings_subtitle": "Používajte na vlastné riziko!",
|
||||||
"experimental_settings_title": "Experimentálne",
|
"experimental_settings_title": "Experimentálne",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Obľúbené",
|
"favorites_page_title": "Obľúbené",
|
||||||
"home_page_add_to_album_conflicts": "Pridané {added} položiek do albumu {album}. {failed} položiek už je v albume.",
|
"home_page_add_to_album_conflicts": "Pridané {added} položiek do albumu {album}. {failed} položiek už je v albume.",
|
||||||
"home_page_add_to_album_err_local": "Zatiaľ nie je možné pridať lokálne média do albumov, preskakuje sa",
|
"home_page_add_to_album_err_local": "Zatiaľ nie je možné pridať lokálne média do albumov, preskakuje sa",
|
||||||
"home_page_add_to_album_success": "Pridané {added} položky do albumu {album}.",
|
"home_page_add_to_album_success": "Pridané {added} položky do albumu {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Vytváranie časovej osi",
|
"home_page_building_timeline": "Vytváranie časovej osi",
|
||||||
"home_page_favorite_err_local": "Zatiaľ nie je možné zaradiť lokálne média medzi obľúbené, preskakuje sa",
|
"home_page_favorite_err_local": "Zatiaľ nie je možné zaradiť lokálne média medzi obľúbené, preskakuje sa",
|
||||||
"home_page_first_time_notice": "Ak aplikáciu používate prvý krát, nezabudnite si vybrať zálohované albumy, aby sa na časovej osi mohli nachádzať fotografie a videá z vybraných albumoch.",
|
"home_page_first_time_notice": "Ak aplikáciu používate prvý krát, nezabudnite si vybrať zálohované albumy, aby sa na časovej osi mohli nachádzať fotografie a videá z vybraných albumoch.",
|
||||||
"image_viewer_page_state_provider_download_error": "Chyba sťahovania",
|
"image_viewer_page_state_provider_download_error": "Chyba sťahovania",
|
||||||
"image_viewer_page_state_provider_download_success": "Sťahovanie bolo úspešné",
|
"image_viewer_page_state_provider_download_success": "Sťahovanie bolo úspešné",
|
||||||
"library_page_albums": "Albumy",
|
"library_page_albums": "Albumy",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Obľúbené",
|
"library_page_favorites": "Obľúbené",
|
||||||
"library_page_new_album": "Nový album",
|
"library_page_new_album": "Nový album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "Added to {album}",
|
"add_to_album_bottom_sheet_added": "Added to {album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "EXKLUDERAD",
|
"album_info_card_backup_album_excluded": "EXKLUDERAD",
|
||||||
"album_info_card_backup_album_included": "INKLUDERAD",
|
"album_info_card_backup_album_included": "INKLUDERAD",
|
||||||
"album_thumbnail_card_item": "1 objekt",
|
"album_thumbnail_card_item": "1 objekt",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "Ta bort från album",
|
"album_viewer_appbar_share_remove": "Ta bort från album",
|
||||||
"album_viewer_page_share_add_users": "Lägg till användare",
|
"album_viewer_page_share_add_users": "Lägg till användare",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
"asset_list_layout_settings_dynamic_layout_title": "Dynamisk layout",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "Gruppera bilder efter",
|
"asset_list_layout_settings_group_by": "Gruppera bilder efter",
|
||||||
"asset_list_layout_settings_group_by_month": "Månad",
|
"asset_list_layout_settings_group_by_month": "Månad",
|
||||||
"asset_list_layout_settings_group_by_month_day": "Månad + dag",
|
"asset_list_layout_settings_group_by_month_day": "Månad + dag",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "Lägg till i album",
|
"control_bottom_app_bar_add_to_album": "Lägg till i album",
|
||||||
"control_bottom_app_bar_album_info": "{} objekt",
|
"control_bottom_app_bar_album_info": "{} objekt",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} objekt • Delat",
|
"control_bottom_app_bar_album_info_shared": "{} objekt • Delat",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "Skapa nytt album",
|
"control_bottom_app_bar_create_new_album": "Skapa nytt album",
|
||||||
"control_bottom_app_bar_delete": "Radera",
|
"control_bottom_app_bar_delete": "Radera",
|
||||||
"control_bottom_app_bar_favorite": "Favorit",
|
"control_bottom_app_bar_favorite": "Favorit",
|
||||||
"control_bottom_app_bar_share": "Dela",
|
"control_bottom_app_bar_share": "Dela",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "Namnlös",
|
"create_album_page_untitled": "Namnlös",
|
||||||
"create_shared_album_page_create": "Skapa",
|
"create_shared_album_page_create": "Skapa",
|
||||||
"create_shared_album_page_share": "Dela",
|
"create_shared_album_page_share": "Dela",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "Avbryt",
|
"delete_dialog_cancel": "Avbryt",
|
||||||
"delete_dialog_ok": "Radera",
|
"delete_dialog_ok": "Radera",
|
||||||
"delete_dialog_title": "Radera permanent",
|
"delete_dialog_title": "Radera permanent",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "Lägg till beskrivning...",
|
"exif_bottom_sheet_description": "Lägg till beskrivning...",
|
||||||
"exif_bottom_sheet_details": "DETALJER",
|
"exif_bottom_sheet_details": "DETALJER",
|
||||||
"exif_bottom_sheet_location": "PLATS",
|
"exif_bottom_sheet_location": "PLATS",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "Aktivera experimentellt fotorutnät",
|
"experimental_settings_new_asset_list_title": "Aktivera experimentellt fotorutnät",
|
||||||
"experimental_settings_subtitle": "Använd på egen risk!",
|
"experimental_settings_subtitle": "Använd på egen risk!",
|
||||||
"experimental_settings_title": "Experimentellt",
|
"experimental_settings_title": "Experimentellt",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "Favoriter",
|
"favorites_page_title": "Favoriter",
|
||||||
"home_page_add_to_album_conflicts": "Lade till {added} foton och videor i albumet {album}. {failed} foton och videor finns redan i albumet.",
|
"home_page_add_to_album_conflicts": "Lade till {added} foton och videor i albumet {album}. {failed} foton och videor finns redan i albumet.",
|
||||||
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
|
||||||
"home_page_add_to_album_success": "Lade till {added} foton och videor i albumet {album}.",
|
"home_page_add_to_album_success": "Lade till {added} foton och videor i albumet {album}.",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "Bygger tidslinjen",
|
"home_page_building_timeline": "Bygger tidslinjen",
|
||||||
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
"home_page_favorite_err_local": "Can not favorite local assets yet, skipping",
|
||||||
"home_page_first_time_notice": "Om det här är första gången du använder appen, välj ett eller flera backup-album så att tidslinjen kan fyllas med foton och videor från albumen.",
|
"home_page_first_time_notice": "Om det här är första gången du använder appen, välj ett eller flera backup-album så att tidslinjen kan fyllas med foton och videor från albumen.",
|
||||||
"image_viewer_page_state_provider_download_error": "Download Error",
|
"image_viewer_page_state_provider_download_error": "Download Error",
|
||||||
"image_viewer_page_state_provider_download_success": "Download Success",
|
"image_viewer_page_state_provider_download_success": "Download Success",
|
||||||
"library_page_albums": "Album",
|
"library_page_albums": "Album",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "Favoriter",
|
"library_page_favorites": "Favoriter",
|
||||||
"library_page_new_album": "Nytt album",
|
"library_page_new_album": "Nytt album",
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"add_to_album_bottom_sheet_added": "添加到{album}",
|
"add_to_album_bottom_sheet_added": "添加到{album}",
|
||||||
"add_to_album_bottom_sheet_already_exists": "已经在{album}中了",
|
"add_to_album_bottom_sheet_already_exists": "已经在{album}中了",
|
||||||
|
"advanced_settings_tile_subtitle": "Advanced user's settings",
|
||||||
|
"advanced_settings_tile_title": "Advanced",
|
||||||
|
"advanced_settings_troubleshooting_subtitle": "Enable additional features for troubleshooting",
|
||||||
|
"advanced_settings_troubleshooting_title": "Troubleshooting",
|
||||||
"album_info_card_backup_album_excluded": "排除",
|
"album_info_card_backup_album_excluded": "排除",
|
||||||
"album_info_card_backup_album_included": "已选",
|
"album_info_card_backup_album_included": "已选",
|
||||||
"album_thumbnail_card_item": "1张",
|
"album_thumbnail_card_item": "1张",
|
||||||
@@ -17,7 +21,10 @@
|
|||||||
"album_viewer_appbar_share_remove": "从相册中移除",
|
"album_viewer_appbar_share_remove": "从相册中移除",
|
||||||
"album_viewer_page_share_add_users": "新增用户",
|
"album_viewer_page_share_add_users": "新增用户",
|
||||||
"all_videos_page_title": "Videos",
|
"all_videos_page_title": "Videos",
|
||||||
|
"archive_page_no_archived_assets": "No archived assets found",
|
||||||
|
"archive_page_title": "Archive ({})",
|
||||||
"asset_list_layout_settings_dynamic_layout_title": "动态布局",
|
"asset_list_layout_settings_dynamic_layout_title": "动态布局",
|
||||||
|
"asset_list_layout_settings_group_automatically": "Automatic",
|
||||||
"asset_list_layout_settings_group_by": "分组照片或视频由",
|
"asset_list_layout_settings_group_by": "分组照片或视频由",
|
||||||
"asset_list_layout_settings_group_by_month": "月",
|
"asset_list_layout_settings_group_by_month": "月",
|
||||||
"asset_list_layout_settings_group_by_month_day": "月和日",
|
"asset_list_layout_settings_group_by_month_day": "月和日",
|
||||||
@@ -108,10 +115,12 @@
|
|||||||
"control_bottom_app_bar_add_to_album": "添加到相册",
|
"control_bottom_app_bar_add_to_album": "添加到相册",
|
||||||
"control_bottom_app_bar_album_info": "{}张",
|
"control_bottom_app_bar_album_info": "{}张",
|
||||||
"control_bottom_app_bar_album_info_shared": "{} 张已分享",
|
"control_bottom_app_bar_album_info_shared": "{} 张已分享",
|
||||||
|
"control_bottom_app_bar_archive": "Archive",
|
||||||
"control_bottom_app_bar_create_new_album": "新建相册",
|
"control_bottom_app_bar_create_new_album": "新建相册",
|
||||||
"control_bottom_app_bar_delete": "删除",
|
"control_bottom_app_bar_delete": "删除",
|
||||||
"control_bottom_app_bar_favorite": "收藏",
|
"control_bottom_app_bar_favorite": "收藏",
|
||||||
"control_bottom_app_bar_share": "分享",
|
"control_bottom_app_bar_share": "分享",
|
||||||
|
"control_bottom_app_bar_unarchive": "Unarchive",
|
||||||
"create_album_page_untitled": "未命名",
|
"create_album_page_untitled": "未命名",
|
||||||
"create_shared_album_page_create": "新建",
|
"create_shared_album_page_create": "新建",
|
||||||
"create_shared_album_page_share": "分享",
|
"create_shared_album_page_share": "分享",
|
||||||
@@ -126,6 +135,8 @@
|
|||||||
"delete_dialog_cancel": "取消",
|
"delete_dialog_cancel": "取消",
|
||||||
"delete_dialog_ok": "删除",
|
"delete_dialog_ok": "删除",
|
||||||
"delete_dialog_title": "永久删除",
|
"delete_dialog_title": "永久删除",
|
||||||
|
"description_input_hint_text": "Add description...",
|
||||||
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"exif_bottom_sheet_description": "增加描述...",
|
"exif_bottom_sheet_description": "增加描述...",
|
||||||
"exif_bottom_sheet_details": "详情",
|
"exif_bottom_sheet_details": "详情",
|
||||||
"exif_bottom_sheet_location": "位置",
|
"exif_bottom_sheet_location": "位置",
|
||||||
@@ -133,16 +144,19 @@
|
|||||||
"experimental_settings_new_asset_list_title": "启用实验性的照片宫格",
|
"experimental_settings_new_asset_list_title": "启用实验性的照片宫格",
|
||||||
"experimental_settings_subtitle": "使用风险自负!",
|
"experimental_settings_subtitle": "使用风险自负!",
|
||||||
"experimental_settings_title": "实验功能",
|
"experimental_settings_title": "实验功能",
|
||||||
|
"favorites_page_no_favorites": "No favorite assets found",
|
||||||
"favorites_page_title": "收藏",
|
"favorites_page_title": "收藏",
|
||||||
"home_page_add_to_album_conflicts": "添加{added}张到相册{album}。{failed} 项已经处于该相册中。",
|
"home_page_add_to_album_conflicts": "添加{added}张到相册{album}。{failed} 项已经处于该相册中。",
|
||||||
"home_page_add_to_album_err_local": "无法在相册中收藏本地的照片或视频,跳过",
|
"home_page_add_to_album_err_local": "无法在相册中收藏本地的照片或视频,跳过",
|
||||||
"home_page_add_to_album_success": "添加了{added}张到相册{album}。",
|
"home_page_add_to_album_success": "添加了{added}张到相册{album}。",
|
||||||
|
"home_page_archive_err_local": "Can not archive local assets yet, skipping",
|
||||||
"home_page_building_timeline": "生成时间线",
|
"home_page_building_timeline": "生成时间线",
|
||||||
"home_page_favorite_err_local": "还不能收藏本地的照片或视频,跳过",
|
"home_page_favorite_err_local": "还不能收藏本地的照片或视频,跳过",
|
||||||
"home_page_first_time_notice": "如果这是您第一次使用该应用程序,请确保选择一个想要备份的本地相册,以便可以在时间线中预览该相册中的照片和视频。",
|
"home_page_first_time_notice": "如果这是您第一次使用该应用程序,请确保选择一个想要备份的本地相册,以便可以在时间线中预览该相册中的照片和视频。",
|
||||||
"image_viewer_page_state_provider_download_error": "下载出现错误",
|
"image_viewer_page_state_provider_download_error": "下载出现错误",
|
||||||
"image_viewer_page_state_provider_download_success": "下载成功",
|
"image_viewer_page_state_provider_download_success": "下载成功",
|
||||||
"library_page_albums": "相册",
|
"library_page_albums": "相册",
|
||||||
|
"library_page_archive": "Archive",
|
||||||
"library_page_device_albums": "Albums on Device",
|
"library_page_device_albums": "Albums on Device",
|
||||||
"library_page_favorites": "收藏",
|
"library_page_favorites": "收藏",
|
||||||
"library_page_new_album": "新建相册",
|
"library_page_new_album": "新建相册",
|
||||||
|
|||||||
@@ -379,7 +379,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 95;
|
CURRENT_PROJECT_VERSION = 97;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -515,7 +515,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 95;
|
CURRENT_PROJECT_VERSION = 97;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -543,7 +543,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 95;
|
CURRENT_PROJECT_VERSION = 97;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|||||||
@@ -45,11 +45,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.55.0</string>
|
<string>1.57.0</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>95</string>
|
<string>97</string>
|
||||||
<key>FLTEnableImpeller</key>
|
<key>FLTEnableImpeller</key>
|
||||||
<true />
|
<true />
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ platform :ios do
|
|||||||
desc "iOS Beta"
|
desc "iOS Beta"
|
||||||
lane :beta do
|
lane :beta do
|
||||||
increment_version_number(
|
increment_version_number(
|
||||||
version_number: "1.56.0"
|
version_number: "1.60.0"
|
||||||
)
|
)
|
||||||
increment_build_number(
|
increment_build_number(
|
||||||
build_number: latest_testflight_build_number + 1,
|
build_number: latest_testflight_build_number + 1,
|
||||||
|
|||||||
@@ -5,29 +5,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000282">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000407">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="2.815995">
|
<testcase classname="fastlane.lanes" name="1: increment_version_number" time="2.988375">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="30.927419">
|
<testcase classname="fastlane.lanes" name="2: latest_testflight_build_number" time="45.42439">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="1.464698">
|
<testcase classname="fastlane.lanes" name="3: increment_build_number" time="2.381359">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="4: build_app" time="66.988561">
|
<testcase classname="fastlane.lanes" name="4: build_app" time="94.653021">
|
||||||
|
|
||||||
<failure message="/usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/actions/actions_helper.rb:67:in `execute_action' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:255:in `block in execute_action' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:229:in `chdir' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:229:in `execute_action' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:157:in `trigger_action_by_name' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/fast_file.rb:159:in `method_missing' Fastfile:27:in `block (2 levels) in parsing_binding' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/lane.rb:33:in `call' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:49:in `block in execute' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:45:in `chdir' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/runner.rb:45:in `execute' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:354:in `run' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/commands_generator.rb:43:in `start' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off' /usr/local/Cellar/fastlane/2.212.1/libexec/gems/fastlane-2.212.1/bin/fastlane:23:in `<top (required)>' /usr/local/Cellar/fastlane/2.212.1/libexec/bin/fastlane:25:in `load' /usr/local/Cellar/fastlane/2.212.1/libexec/bin/fastlane:25:in `<main>' Error packaging up the application" />
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
|
<testcase classname="fastlane.lanes" name="5: upload_to_testflight" time="58.237354">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
// Access token
|
|
||||||
const String userInfoBox = "immichBoxUserInfo"; // Box
|
|
||||||
const String accessTokenKey = "immichBoxAccessTokenKey"; // Key 1
|
|
||||||
const String deviceIdKey = 'immichBoxDeviceIdKey'; // Key 2
|
|
||||||
const String isLoggedInKey = 'immichIsLoggedInKey'; // Key 3
|
|
||||||
const String serverEndpointKey = 'immichBoxServerEndpoint'; // Key 4
|
|
||||||
const String assetEtagKey = 'immichAssetEtagKey'; // Key 5
|
|
||||||
const String userIdKey = 'immichUserIdKey'; // Key 6
|
|
||||||
|
|
||||||
// Login Info
|
|
||||||
const String hiveLoginInfoBox = "immichLoginInfoBox"; // Box
|
|
||||||
const String savedLoginInfoKey = "immichSavedLoginInfoKey"; // Key 1
|
|
||||||
|
|
||||||
// Backup Info
|
|
||||||
const String hiveBackupInfoBox = "immichBackupAlbumInfoBox"; // Box
|
|
||||||
const String backupInfoKey = "immichBackupAlbumInfoKey"; // Key 1
|
|
||||||
|
|
||||||
// Github Release Info
|
|
||||||
const String hiveGithubReleaseInfoBox = "immichGithubReleaseInfoBox"; // Box
|
|
||||||
const String githubReleaseInfoKey = "immichGithubReleaseInfoKey"; // Key 1
|
|
||||||
|
|
||||||
// User Setting Info
|
|
||||||
const String userSettingInfoBox = "immichUserSettingInfoBox";
|
|
||||||
|
|
||||||
// Background backup Info
|
|
||||||
const String backgroundBackupInfoBox = "immichBackgroundBackupInfoBox"; // Box
|
|
||||||
const String backupFailedSince = "immichBackupFailedSince"; // Key 1
|
|
||||||
const String backupRequireWifi = "immichBackupRequireWifi"; // Key 2
|
|
||||||
const String backupRequireCharging = "immichBackupRequireCharging"; // Key 3
|
|
||||||
const String backupTriggerDelay = "immichBackupTriggerDelay"; // Key 4
|
|
||||||
|
|
||||||
// Duplicate asset
|
|
||||||
const String duplicatedAssetsBox = "immichDuplicatedAssetsBox"; // Box
|
|
||||||
const String duplicatedAssetsKey = "immichDuplicatedAssetsKey"; // Key 1
|
|
||||||
|
|
||||||
// In app logger
|
|
||||||
const String immichLoggerBox = "immichInAppLogger"; // Box
|
|
||||||
@@ -6,17 +6,13 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/locales.dart';
|
import 'package:immich_mobile/constants/locales.dart';
|
||||||
import 'package:immich_mobile/modules/backup/background_service/background.service.dart';
|
import 'package:immich_mobile/modules/backup/background_service/background.service.dart';
|
||||||
import 'package:immich_mobile/modules/backup/models/backup_album.model.dart';
|
import 'package:immich_mobile/modules/backup/models/backup_album.model.dart';
|
||||||
import 'package:immich_mobile/modules/backup/models/duplicated_asset.model.dart';
|
import 'package:immich_mobile/modules/backup/models/duplicated_asset.model.dart';
|
||||||
import 'package:immich_mobile/modules/backup/models/hive_backup_albums.model.dart';
|
|
||||||
import 'package:immich_mobile/modules/backup/models/hive_duplicated_assets.model.dart';
|
|
||||||
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
|
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
|
||||||
import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart';
|
import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart';
|
||||||
import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart';
|
|
||||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||||
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
|
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
|
||||||
import 'package:immich_mobile/modules/settings/providers/notification_permission.provider.dart';
|
import 'package:immich_mobile/modules/settings/providers/notification_permission.provider.dart';
|
||||||
@@ -24,8 +20,8 @@ import 'package:immich_mobile/routing/router.dart';
|
|||||||
import 'package:immich_mobile/routing/tab_navigation_observer.dart';
|
import 'package:immich_mobile/routing/tab_navigation_observer.dart';
|
||||||
import 'package:immich_mobile/shared/models/album.dart';
|
import 'package:immich_mobile/shared/models/album.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/etag.dart';
|
||||||
import 'package:immich_mobile/shared/models/exif_info.dart';
|
import 'package:immich_mobile/shared/models/exif_info.dart';
|
||||||
import 'package:immich_mobile/shared/models/immich_logger_message.model.dart';
|
|
||||||
import 'package:immich_mobile/shared/models/logger_message.model.dart';
|
import 'package:immich_mobile/shared/models/logger_message.model.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart';
|
import 'package:immich_mobile/shared/models/store.dart';
|
||||||
import 'package:immich_mobile/shared/models/user.dart';
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
@@ -50,18 +46,11 @@ void main() async {
|
|||||||
|
|
||||||
final db = await loadDb();
|
final db = await loadDb();
|
||||||
await initApp();
|
await initApp();
|
||||||
await migrateHiveToStoreIfNecessary();
|
|
||||||
await migrateJsonCacheIfNecessary();
|
|
||||||
await migrateDatabaseIfNeeded(db);
|
await migrateDatabaseIfNeeded(db);
|
||||||
runApp(getMainWidget(db));
|
runApp(getMainWidget(db));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initApp() async {
|
Future<void> initApp() async {
|
||||||
await Hive.initFlutter();
|
|
||||||
Hive.registerAdapter(HiveSavedLoginInfoAdapter());
|
|
||||||
Hive.registerAdapter(HiveBackupAlbumsAdapter());
|
|
||||||
Hive.registerAdapter(HiveDuplicatedAssetsAdapter());
|
|
||||||
Hive.registerAdapter(ImmichLoggerMessageAdapter());
|
|
||||||
await EasyLocalization.ensureInitialized();
|
await EasyLocalization.ensureInitialized();
|
||||||
|
|
||||||
if (kReleaseMode && Platform.isAndroid) {
|
if (kReleaseMode && Platform.isAndroid) {
|
||||||
@@ -101,6 +90,7 @@ Future<Isar> loadDb() async {
|
|||||||
BackupAlbumSchema,
|
BackupAlbumSchema,
|
||||||
DuplicatedAssetSchema,
|
DuplicatedAssetSchema,
|
||||||
LoggerMessageSchema,
|
LoggerMessageSchema,
|
||||||
|
ETagSchema,
|
||||||
],
|
],
|
||||||
directory: dir.path,
|
directory: dir.path,
|
||||||
maxSizeMiB: 256,
|
maxSizeMiB: 256,
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
|
||||||
|
|
||||||
class AssetSelectionState {
|
|
||||||
final Set<String> selectedMonths;
|
|
||||||
final Set<Asset> selectedNewAssetsForAlbum;
|
|
||||||
final Set<Asset> selectedAdditionalAssetsForAlbum;
|
|
||||||
final Set<Asset> selectedAssetsInAlbumViewer;
|
|
||||||
final bool isMultiselectEnable;
|
|
||||||
|
|
||||||
/// Indicate the asset selection page is navigated from existing album
|
|
||||||
final bool isAlbumExist;
|
|
||||||
AssetSelectionState({
|
|
||||||
required this.selectedMonths,
|
|
||||||
required this.selectedNewAssetsForAlbum,
|
|
||||||
required this.selectedAdditionalAssetsForAlbum,
|
|
||||||
required this.selectedAssetsInAlbumViewer,
|
|
||||||
required this.isMultiselectEnable,
|
|
||||||
required this.isAlbumExist,
|
|
||||||
});
|
|
||||||
|
|
||||||
AssetSelectionState copyWith({
|
|
||||||
Set<String>? selectedMonths,
|
|
||||||
Set<Asset>? selectedNewAssetsForAlbum,
|
|
||||||
Set<Asset>? selectedAdditionalAssetsForAlbum,
|
|
||||||
Set<Asset>? selectedAssetsInAlbumViewer,
|
|
||||||
bool? isMultiselectEnable,
|
|
||||||
bool? isAlbumExist,
|
|
||||||
}) {
|
|
||||||
return AssetSelectionState(
|
|
||||||
selectedMonths: selectedMonths ?? this.selectedMonths,
|
|
||||||
selectedNewAssetsForAlbum:
|
|
||||||
selectedNewAssetsForAlbum ?? this.selectedNewAssetsForAlbum,
|
|
||||||
selectedAdditionalAssetsForAlbum: selectedAdditionalAssetsForAlbum ??
|
|
||||||
this.selectedAdditionalAssetsForAlbum,
|
|
||||||
selectedAssetsInAlbumViewer:
|
|
||||||
selectedAssetsInAlbumViewer ?? this.selectedAssetsInAlbumViewer,
|
|
||||||
isMultiselectEnable: isMultiselectEnable ?? this.isMultiselectEnable,
|
|
||||||
isAlbumExist: isAlbumExist ?? this.isAlbumExist,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'AssetSelectionState(selectedMonths: $selectedMonths, selectedNewAssetsForAlbum: $selectedNewAssetsForAlbum, selectedAdditionalAssetsForAlbum: $selectedAdditionalAssetsForAlbum, selectedAssetsInAlbumViewer: $selectedAssetsInAlbumViewer, isMultiselectEnable: $isMultiselectEnable, isAlbumExist: $isAlbumExist)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
final setEquals = const DeepCollectionEquality().equals;
|
|
||||||
|
|
||||||
return other is AssetSelectionState &&
|
|
||||||
setEquals(other.selectedMonths, selectedMonths) &&
|
|
||||||
setEquals(other.selectedNewAssetsForAlbum, selectedNewAssetsForAlbum) &&
|
|
||||||
setEquals(
|
|
||||||
other.selectedAdditionalAssetsForAlbum,
|
|
||||||
selectedAdditionalAssetsForAlbum,
|
|
||||||
) &&
|
|
||||||
setEquals(
|
|
||||||
other.selectedAssetsInAlbumViewer,
|
|
||||||
selectedAssetsInAlbumViewer,
|
|
||||||
) &&
|
|
||||||
other.isMultiselectEnable == isMultiselectEnable &&
|
|
||||||
other.isAlbumExist == isAlbumExist;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return selectedMonths.hashCode ^
|
|
||||||
selectedNewAssetsForAlbum.hashCode ^
|
|
||||||
selectedAdditionalAssetsForAlbum.hashCode ^
|
|
||||||
selectedAssetsInAlbumViewer.hashCode ^
|
|
||||||
isMultiselectEnable.hashCode ^
|
|
||||||
isAlbumExist.hashCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ import 'package:immich_mobile/shared/models/album.dart';
|
|||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/models/user.dart';
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
class SharedAlbumNotifier extends StateNotifier<List<Album>> {
|
class SharedAlbumNotifier extends StateNotifier<List<Album>> {
|
||||||
@@ -73,7 +74,9 @@ final sharedAlbumProvider =
|
|||||||
});
|
});
|
||||||
|
|
||||||
final sharedAlbumDetailProvider =
|
final sharedAlbumDetailProvider =
|
||||||
StreamProvider.autoDispose.family<Album, int>((ref, albumId) async* {
|
StreamProvider.family<Album, int>((ref, albumId) async* {
|
||||||
|
final user = ref.watch(currentUserProvider);
|
||||||
|
if (user == null) return;
|
||||||
final AlbumService sharedAlbumService = ref.watch(albumServiceProvider);
|
final AlbumService sharedAlbumService = ref.watch(albumServiceProvider);
|
||||||
|
|
||||||
await for (final a in sharedAlbumService.watchAlbum(albumId)) {
|
await for (final a in sharedAlbumService.watchAlbum(albumId)) {
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/shared/models/user.dart';
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
import 'package:immich_mobile/shared/services/user.service.dart';
|
import 'package:immich_mobile/shared/services/user.service.dart';
|
||||||
|
|
||||||
final suggestedSharedUsersProvider =
|
final otherUsersProvider = FutureProvider.autoDispose<List<User>>((ref) {
|
||||||
FutureProvider.autoDispose<List<User>>((ref) {
|
|
||||||
UserService userService = ref.watch(userServiceProvider);
|
UserService userService = ref.watch(userServiceProvider);
|
||||||
|
|
||||||
return userService.getUsersInDb();
|
return userService.getUsersInDb();
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import 'package:immich_mobile/shared/models/album.dart';
|
|
||||||
import 'package:immich_mobile/shared/services/json_cache.dart';
|
|
||||||
|
|
||||||
@Deprecated("only kept to remove its files after migration")
|
|
||||||
class _BaseAlbumCacheService extends JsonCache<List<Album>> {
|
|
||||||
_BaseAlbumCacheService(super.cacheFileName);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void put(List<Album> data) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Album>?> get() => Future.value(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("only kept to remove its files after migration")
|
|
||||||
class AlbumCacheService extends _BaseAlbumCacheService {
|
|
||||||
AlbumCacheService() : super("album_cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("only kept to remove its files after migration")
|
|
||||||
class SharedAlbumCacheService extends _BaseAlbumCacheService {
|
|
||||||
SharedAlbumCacheService() : super("shared_album_cache");
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
|
||||||
|
|
||||||
class SharingSliverAppBar extends StatelessWidget {
|
|
||||||
const SharingSliverAppBar({
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SliverAppBar(
|
|
||||||
centerTitle: true,
|
|
||||||
floating: false,
|
|
||||||
pinned: true,
|
|
||||||
snap: false,
|
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
title: Text(
|
|
||||||
'IMMICH',
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'SnowburstOne',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 22,
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
bottom: PreferredSize(
|
|
||||||
preferredSize: const Size.fromHeight(50.0),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
onPressed: () {
|
|
||||||
AutoRouter.of(context)
|
|
||||||
.push(CreateAlbumRoute(isSharedAlbum: true));
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.photo_album_outlined,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
label: const Text(
|
|
||||||
"sharing_silver_appbar_create_shared_album",
|
|
||||||
maxLines: 1,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 11,
|
|
||||||
// color: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 4.0),
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
onPressed: null,
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.swap_horizontal_circle_outlined,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
label: const Text(
|
|
||||||
"sharing_silver_appbar_share_partner",
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 11,
|
|
||||||
),
|
|
||||||
maxLines: 1,
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structu
|
|||||||
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
|
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
|
|
||||||
class AssetSelectionPage extends HookConsumerWidget {
|
class AssetSelectionPage extends HookConsumerWidget {
|
||||||
const AssetSelectionPage({
|
const AssetSelectionPage({
|
||||||
@@ -21,7 +22,8 @@ class AssetSelectionPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final renderList = ref.watch(remoteAssetsProvider);
|
final currentUser = ref.watch(currentUserProvider);
|
||||||
|
final renderList = ref.watch(remoteAssetsProvider(currentUser?.isarId));
|
||||||
final selected = useState<Set<Asset>>(existingAssets);
|
final selected = useState<Set<Asset>>(existingAssets);
|
||||||
final selectionEnabledHook = useState(true);
|
final selectionEnabledHook = useState(true);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final AsyncValue<List<User>> suggestedShareUsers =
|
final AsyncValue<List<User>> suggestedShareUsers =
|
||||||
ref.watch(suggestedSharedUsersProvider);
|
ref.watch(otherUsersProvider);
|
||||||
final sharedUsersList = useState<Set<User>>({});
|
final sharedUsersList = useState<Set<User>>({});
|
||||||
|
|
||||||
addNewUsersHandler() {
|
addNewUsersHandler() {
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ class SelectUserForSharingPage extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final sharedUsersList = useState<Set<User>>({});
|
final sharedUsersList = useState<Set<User>>({});
|
||||||
AsyncValue<List<User>> suggestedShareUsers =
|
final suggestedShareUsers = ref.watch(otherUsersProvider);
|
||||||
ref.watch(suggestedSharedUsersProvider);
|
|
||||||
|
|
||||||
createSharedAlbum() async {
|
createSharedAlbum() async {
|
||||||
var newAlbum =
|
var newAlbum =
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
||||||
import 'package:immich_mobile/modules/album/ui/album_thumbnail_card.dart';
|
import 'package:immich_mobile/modules/album/ui/album_thumbnail_card.dart';
|
||||||
import 'package:immich_mobile/modules/album/ui/sharing_sliver_appbar.dart';
|
import 'package:immich_mobile/modules/partner/providers/partner.provider.dart';
|
||||||
|
import 'package:immich_mobile/modules/partner/ui/partner_list.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/shared/models/album.dart';
|
import 'package:immich_mobile/shared/models/album.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart' as store;
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||||
|
|
||||||
class SharingPage extends HookConsumerWidget {
|
class SharingPage extends HookConsumerWidget {
|
||||||
@@ -17,7 +18,8 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final List<Album> sharedAlbums = ref.watch(sharedAlbumProvider);
|
final List<Album> sharedAlbums = ref.watch(sharedAlbumProvider);
|
||||||
final userId = store.Store.get(store.StoreKey.currentUser).id;
|
final userId = ref.watch(currentUserProvider)?.id;
|
||||||
|
final partner = ref.watch(partnerSharedWithProvider);
|
||||||
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
@@ -63,8 +65,7 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
final isOwner = album.ownerId == userId;
|
final isOwner = album.ownerId == userId;
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding:
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
|
|
||||||
leading: ClipRRect(
|
leading: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: ImmichImage(
|
child: ImmichImage(
|
||||||
@@ -93,7 +94,8 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
: album.ownerName != null
|
: album.ownerName != null
|
||||||
? Text(
|
? Text(
|
||||||
'album_thumbnail_shared_by'.tr(args: [album.ownerName!]),
|
'album_thumbnail_shared_by'
|
||||||
|
.tr(args: [album.ownerName!]),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12.0,
|
fontSize: 12.0,
|
||||||
),
|
),
|
||||||
@@ -110,6 +112,75 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildTopBottons() {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 12.0,
|
||||||
|
right: 12.0,
|
||||||
|
bottom: 12.0,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
AutoRouter.of(context)
|
||||||
|
.push(CreateAlbumRoute(isSharedAlbum: true));
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.photo_album_outlined,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
label: const Text(
|
||||||
|
"sharing_silver_appbar_create_shared_album",
|
||||||
|
maxLines: 1,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 11,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12.0),
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () =>
|
||||||
|
AutoRouter.of(context).push(const PartnerRoute()),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.swap_horizontal_circle_outlined,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
label: const Text(
|
||||||
|
"sharing_silver_appbar_share_partner",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 11,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
AppBar buildAppBar() {
|
||||||
|
return AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
title: const Text(
|
||||||
|
'IMMICH',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'SnowburstOne',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 22,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
buildEmptyListIndication() {
|
buildEmptyListIndication() {
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@@ -123,7 +194,6 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// color: Colors.transparent,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(18.0),
|
padding: const EdgeInsets.all(18.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -160,11 +230,27 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
appBar: buildAppBar(),
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
const SharingSliverAppBar(),
|
SliverToBoxAdapter(child: buildTopBottons()),
|
||||||
|
if (partner.isNotEmpty)
|
||||||
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.only(left: 12, right: 12, bottom: 4),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: const Text(
|
||||||
|
"partner_page_title",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (partner.isNotEmpty) PartnerList(partner: partner),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
padding: EdgeInsets.only(
|
||||||
|
left: 12,
|
||||||
|
right: 12,
|
||||||
|
top: partner.isEmpty ? 0 : 16,
|
||||||
|
),
|
||||||
sliver: SliverToBoxAdapter(
|
sliver: SliverToBoxAdapter(
|
||||||
child: const Text(
|
child: const Text(
|
||||||
"sharing_page_album",
|
"sharing_page_album",
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structu
|
|||||||
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
||||||
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart';
|
|
||||||
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
final archiveProvider = StreamProvider<RenderList>((ref) async* {
|
final archiveProvider = StreamProvider<RenderList>((ref) async* {
|
||||||
|
final user = ref.watch(currentUserProvider);
|
||||||
|
if (user == null) return;
|
||||||
final query = ref
|
final query = ref
|
||||||
.watch(dbProvider)
|
.watch(dbProvider)
|
||||||
.assets
|
.assets
|
||||||
.filter()
|
.filter()
|
||||||
.ownerIdEqualTo(Store.get(StoreKey.currentUser).isarId)
|
.ownerIdEqualTo(user.isarId)
|
||||||
.isArchivedEqualTo(true)
|
.isArchivedEqualTo(true)
|
||||||
.sortByFileCreatedAt();
|
.sortByFileCreatedAt();
|
||||||
final settings = ref.watch(appSettingsServiceProvider);
|
final settings = ref.watch(appSettingsServiceProvider);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/asset_viewer/providers/asset_description.provider.dart';
|
import 'package:immich_mobile/modules/asset_viewer/providers/asset_description.provider.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart' as store;
|
|
||||||
|
|
||||||
class DescriptionInput extends HookConsumerWidget {
|
class DescriptionInput extends HookConsumerWidget {
|
||||||
DescriptionInput({
|
DescriptionInput({
|
||||||
@@ -25,9 +25,10 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
final focusNode = useFocusNode();
|
final focusNode = useFocusNode();
|
||||||
final isFocus = useState(false);
|
final isFocus = useState(false);
|
||||||
final isTextEmpty = useState(controller.text.isEmpty);
|
final isTextEmpty = useState(controller.text.isEmpty);
|
||||||
final descriptionProvider = ref.watch(assetDescriptionProvider(asset).notifier);
|
final descriptionProvider =
|
||||||
|
ref.watch(assetDescriptionProvider(asset).notifier);
|
||||||
final description = ref.watch(assetDescriptionProvider(asset));
|
final description = ref.watch(assetDescriptionProvider(asset));
|
||||||
final owner = store.Store.get(store.StoreKey.currentUser);
|
final owner = ref.watch(currentUserProvider);
|
||||||
final hasError = useState(false);
|
final hasError = useState(false);
|
||||||
|
|
||||||
controller.text = description;
|
controller.text = description;
|
||||||
@@ -67,7 +68,7 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return TextField(
|
return TextField(
|
||||||
enabled: owner.isarId == asset.ownerId,
|
enabled: owner?.isarId == asset.ownerId,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
onTap: () => isFocus.value = true,
|
onTap: () => isFocus.value = true,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'backup_album.model.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
extension GetBackupAlbumCollection on Isar {
|
extension GetBackupAlbumCollection on Isar {
|
||||||
IsarCollection<BackupAlbum> get backupAlbums => this.collection();
|
IsarCollection<BackupAlbum> get backupAlbums => this.collection();
|
||||||
@@ -45,7 +45,7 @@ const BackupAlbumSchema = CollectionSchema(
|
|||||||
getId: _backupAlbumGetId,
|
getId: _backupAlbumGetId,
|
||||||
getLinks: _backupAlbumGetLinks,
|
getLinks: _backupAlbumGetLinks,
|
||||||
attach: _backupAlbumAttach,
|
attach: _backupAlbumAttach,
|
||||||
version: '3.0.5',
|
version: '3.1.0+1',
|
||||||
);
|
);
|
||||||
|
|
||||||
int _backupAlbumEstimateSize(
|
int _backupAlbumEstimateSize(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'duplicated_asset.model.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
extension GetDuplicatedAssetCollection on Isar {
|
extension GetDuplicatedAssetCollection on Isar {
|
||||||
IsarCollection<DuplicatedAsset> get duplicatedAssets => this.collection();
|
IsarCollection<DuplicatedAsset> get duplicatedAssets => this.collection();
|
||||||
@@ -34,7 +34,7 @@ const DuplicatedAssetSchema = CollectionSchema(
|
|||||||
getId: _duplicatedAssetGetId,
|
getId: _duplicatedAssetGetId,
|
||||||
getLinks: _duplicatedAssetGetLinks,
|
getLinks: _duplicatedAssetGetLinks,
|
||||||
attach: _duplicatedAssetAttach,
|
attach: _duplicatedAssetAttach,
|
||||||
version: '3.0.5',
|
version: '3.1.0+1',
|
||||||
);
|
);
|
||||||
|
|
||||||
int _duplicatedAssetEstimateSize(
|
int _duplicatedAssetEstimateSize(
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
|
|
||||||
part 'hive_backup_albums.model.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 1)
|
|
||||||
class HiveBackupAlbums {
|
|
||||||
@HiveField(0)
|
|
||||||
List<String> selectedAlbumIds;
|
|
||||||
|
|
||||||
@HiveField(1)
|
|
||||||
List<String> excludedAlbumsIds;
|
|
||||||
|
|
||||||
@HiveField(2, defaultValue: [])
|
|
||||||
List<DateTime> lastSelectedBackupTime;
|
|
||||||
|
|
||||||
@HiveField(3, defaultValue: [])
|
|
||||||
List<DateTime> lastExcludedBackupTime;
|
|
||||||
|
|
||||||
HiveBackupAlbums({
|
|
||||||
required this.selectedAlbumIds,
|
|
||||||
required this.excludedAlbumsIds,
|
|
||||||
required this.lastSelectedBackupTime,
|
|
||||||
required this.lastExcludedBackupTime,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() =>
|
|
||||||
'HiveBackupAlbums(selectedAlbumIds: $selectedAlbumIds, excludedAlbumsIds: $excludedAlbumsIds)';
|
|
||||||
|
|
||||||
HiveBackupAlbums copyWith({
|
|
||||||
List<String>? selectedAlbumIds,
|
|
||||||
List<String>? excludedAlbumsIds,
|
|
||||||
List<DateTime>? lastSelectedBackupTime,
|
|
||||||
List<DateTime>? lastExcludedBackupTime,
|
|
||||||
}) {
|
|
||||||
return HiveBackupAlbums(
|
|
||||||
selectedAlbumIds: selectedAlbumIds ?? this.selectedAlbumIds,
|
|
||||||
excludedAlbumsIds: excludedAlbumsIds ?? this.excludedAlbumsIds,
|
|
||||||
lastSelectedBackupTime:
|
|
||||||
lastSelectedBackupTime ?? this.lastSelectedBackupTime,
|
|
||||||
lastExcludedBackupTime:
|
|
||||||
lastExcludedBackupTime ?? this.lastExcludedBackupTime,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a deep copy to allow safe modification without changing the global
|
|
||||||
/// state of [HiveBackupAlbums] before actually saving the changes
|
|
||||||
HiveBackupAlbums deepCopy() {
|
|
||||||
return HiveBackupAlbums(
|
|
||||||
selectedAlbumIds: selectedAlbumIds.toList(),
|
|
||||||
excludedAlbumsIds: excludedAlbumsIds.toList(),
|
|
||||||
lastSelectedBackupTime: lastSelectedBackupTime.toList(),
|
|
||||||
lastExcludedBackupTime: lastExcludedBackupTime.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
final result = <String, dynamic>{};
|
|
||||||
|
|
||||||
result.addAll({'selectedAlbumIds': selectedAlbumIds});
|
|
||||||
result.addAll({'excludedAlbumsIds': excludedAlbumsIds});
|
|
||||||
result.addAll({'lastSelectedBackupTime': lastSelectedBackupTime});
|
|
||||||
result.addAll({'lastExcludedBackupTime': lastExcludedBackupTime});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory HiveBackupAlbums.fromMap(Map<String, dynamic> map) {
|
|
||||||
return HiveBackupAlbums(
|
|
||||||
selectedAlbumIds: List<String>.from(map['selectedAlbumIds']),
|
|
||||||
excludedAlbumsIds: List<String>.from(map['excludedAlbumsIds']),
|
|
||||||
lastSelectedBackupTime:
|
|
||||||
List<DateTime>.from(map['lastSelectedBackupTime']),
|
|
||||||
lastExcludedBackupTime:
|
|
||||||
List<DateTime>.from(map['lastExcludedBackupTime']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory HiveBackupAlbums.fromJson(String source) =>
|
|
||||||
HiveBackupAlbums.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
final listEquals = const DeepCollectionEquality().equals;
|
|
||||||
|
|
||||||
return other is HiveBackupAlbums &&
|
|
||||||
listEquals(other.selectedAlbumIds, selectedAlbumIds) &&
|
|
||||||
listEquals(other.excludedAlbumsIds, excludedAlbumsIds) &&
|
|
||||||
listEquals(other.lastSelectedBackupTime, lastSelectedBackupTime) &&
|
|
||||||
listEquals(other.lastExcludedBackupTime, lastExcludedBackupTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
selectedAlbumIds.hashCode ^
|
|
||||||
excludedAlbumsIds.hashCode ^
|
|
||||||
lastSelectedBackupTime.hashCode ^
|
|
||||||
lastExcludedBackupTime.hashCode;
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'hive_backup_albums.model.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// TypeAdapterGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
class HiveBackupAlbumsAdapter extends TypeAdapter<HiveBackupAlbums> {
|
|
||||||
@override
|
|
||||||
final int typeId = 1;
|
|
||||||
|
|
||||||
@override
|
|
||||||
HiveBackupAlbums read(BinaryReader reader) {
|
|
||||||
final numOfFields = reader.readByte();
|
|
||||||
final fields = <int, dynamic>{
|
|
||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
|
||||||
};
|
|
||||||
return HiveBackupAlbums(
|
|
||||||
selectedAlbumIds: (fields[0] as List).cast<String>(),
|
|
||||||
excludedAlbumsIds: (fields[1] as List).cast<String>(),
|
|
||||||
lastSelectedBackupTime:
|
|
||||||
fields[2] == null ? [] : (fields[2] as List).cast<DateTime>(),
|
|
||||||
lastExcludedBackupTime:
|
|
||||||
fields[3] == null ? [] : (fields[3] as List).cast<DateTime>(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void write(BinaryWriter writer, HiveBackupAlbums obj) {
|
|
||||||
writer
|
|
||||||
..writeByte(4)
|
|
||||||
..writeByte(0)
|
|
||||||
..write(obj.selectedAlbumIds)
|
|
||||||
..writeByte(1)
|
|
||||||
..write(obj.excludedAlbumsIds)
|
|
||||||
..writeByte(2)
|
|
||||||
..write(obj.lastSelectedBackupTime)
|
|
||||||
..writeByte(3)
|
|
||||||
..write(obj.lastExcludedBackupTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => typeId.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is HiveBackupAlbumsAdapter &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
typeId == other.typeId;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
|
|
||||||
part 'hive_duplicated_assets.model.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 2)
|
|
||||||
class HiveDuplicatedAssets {
|
|
||||||
@HiveField(0, defaultValue: [])
|
|
||||||
List<String> duplicatedAssetIds;
|
|
||||||
|
|
||||||
HiveDuplicatedAssets({
|
|
||||||
required this.duplicatedAssetIds,
|
|
||||||
});
|
|
||||||
|
|
||||||
HiveDuplicatedAssets copyWith({
|
|
||||||
List<String>? duplicatedAssetIds,
|
|
||||||
}) {
|
|
||||||
return HiveDuplicatedAssets(
|
|
||||||
duplicatedAssetIds: duplicatedAssetIds ?? this.duplicatedAssetIds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {
|
|
||||||
'duplicatedAssetIds': duplicatedAssetIds,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory HiveDuplicatedAssets.fromMap(Map<String, dynamic> map) {
|
|
||||||
return HiveDuplicatedAssets(
|
|
||||||
duplicatedAssetIds: List<String>.from(map['duplicatedAssetIds']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory HiveDuplicatedAssets.fromJson(String source) =>
|
|
||||||
HiveDuplicatedAssets.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() =>
|
|
||||||
'HiveDuplicatedAssets(duplicatedAssetIds: $duplicatedAssetIds)';
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
final listEquals = const DeepCollectionEquality().equals;
|
|
||||||
|
|
||||||
return other is HiveDuplicatedAssets &&
|
|
||||||
listEquals(other.duplicatedAssetIds, duplicatedAssetIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => duplicatedAssetIds.hashCode;
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'hive_duplicated_assets.model.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// TypeAdapterGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
class HiveDuplicatedAssetsAdapter extends TypeAdapter<HiveDuplicatedAssets> {
|
|
||||||
@override
|
|
||||||
final int typeId = 2;
|
|
||||||
|
|
||||||
@override
|
|
||||||
HiveDuplicatedAssets read(BinaryReader reader) {
|
|
||||||
final numOfFields = reader.readByte();
|
|
||||||
final fields = <int, dynamic>{
|
|
||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
|
||||||
};
|
|
||||||
return HiveDuplicatedAssets(
|
|
||||||
duplicatedAssetIds:
|
|
||||||
fields[0] == null ? [] : (fields[0] as List).cast<String>(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void write(BinaryWriter writer, HiveDuplicatedAssets obj) {
|
|
||||||
writer
|
|
||||||
..writeByte(1)
|
|
||||||
..writeByte(0)
|
|
||||||
..write(obj.duplicatedAssetIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => typeId.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is HiveDuplicatedAssetsAdapter &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
typeId == other.typeId;
|
|
||||||
}
|
|
||||||
@@ -219,8 +219,6 @@ class BackupService {
|
|||||||
|
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
String originalFileName = await entity.titleAsync;
|
String originalFileName = await entity.titleAsync;
|
||||||
String fileNameWithoutPath =
|
|
||||||
originalFileName.toString().split(".")[0];
|
|
||||||
var fileExtension = p.extension(file.path);
|
var fileExtension = p.extension(file.path);
|
||||||
var mimeType = FileHelper.getMimeType(file.path);
|
var mimeType = FileHelper.getMimeType(file.path);
|
||||||
var fileStream = file.openRead();
|
var fileStream = file.openRead();
|
||||||
@@ -228,7 +226,7 @@ class BackupService {
|
|||||||
"assetData",
|
"assetData",
|
||||||
fileStream,
|
fileStream,
|
||||||
file.lengthSync(),
|
file.lengthSync(),
|
||||||
filename: fileNameWithoutPath,
|
filename: originalFileName,
|
||||||
contentType: MediaType(
|
contentType: MediaType(
|
||||||
mimeType["type"],
|
mimeType["type"],
|
||||||
mimeType["subType"],
|
mimeType["subType"],
|
||||||
@@ -334,14 +332,13 @@ class BackupService {
|
|||||||
var motionFile = File(validPath);
|
var motionFile = File(validPath);
|
||||||
var fileStream = motionFile.openRead();
|
var fileStream = motionFile.openRead();
|
||||||
String originalFileName = await entity.titleAsync;
|
String originalFileName = await entity.titleAsync;
|
||||||
String fileNameWithoutPath = originalFileName.toString().split(".")[0];
|
|
||||||
var mimeType = FileHelper.getMimeType(validPath);
|
var mimeType = FileHelper.getMimeType(validPath);
|
||||||
|
|
||||||
return http.MultipartFile(
|
return http.MultipartFile(
|
||||||
"livePhotoData",
|
"livePhotoData",
|
||||||
fileStream,
|
fileStream,
|
||||||
motionFile.lengthSync(),
|
motionFile.lengthSync(),
|
||||||
filename: fileNameWithoutPath,
|
filename: originalFileName,
|
||||||
contentType: MediaType(
|
contentType: MediaType(
|
||||||
mimeType["type"],
|
mimeType["type"],
|
||||||
mimeType["subType"],
|
mimeType["subType"],
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
.read(backgroundServiceProvider)
|
.read(backgroundServiceProvider)
|
||||||
.getIOSBackgroundAppRefreshEnabled(),
|
.getIOSBackgroundAppRefreshEnabled(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
final enabled = snapshot.data as bool?;
|
final enabled = snapshot.data;
|
||||||
// If it's not enabled, show them some kind of alert that says
|
// If it's not enabled, show them some kind of alert that says
|
||||||
// background refresh is not enabled
|
// background refresh is not enabled
|
||||||
if (enabled != null && !enabled) {}
|
if (enabled != null && !enabled) {}
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structu
|
|||||||
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart';
|
||||||
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/models/store.dart';
|
|
||||||
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
final favoriteAssetsProvider = StreamProvider<RenderList>((ref) async* {
|
final favoriteAssetsProvider = StreamProvider<RenderList>((ref) async* {
|
||||||
|
final user = ref.watch(currentUserProvider);
|
||||||
|
if (user == null) return;
|
||||||
final query = ref
|
final query = ref
|
||||||
.watch(dbProvider)
|
.watch(dbProvider)
|
||||||
.assets
|
.assets
|
||||||
.filter()
|
.filter()
|
||||||
.ownerIdEqualTo(Store.get(StoreKey.currentUser).isarId)
|
.ownerIdEqualTo(user.isarId)
|
||||||
.isFavoriteEqualTo(true)
|
.isFavoriteEqualTo(true)
|
||||||
.sortByFileCreatedAt();
|
.sortByFileCreatedAt();
|
||||||
final settings = ref.watch(appSettingsServiceProvider);
|
final settings = ref.watch(appSettingsServiceProvider);
|
||||||
|
|||||||
@@ -1,47 +1,16 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
|
||||||
|
|
||||||
class DeleteDialog extends ConsumerWidget {
|
class DeleteDialog extends ConfirmDialog {
|
||||||
final Function onDelete;
|
final Function onDelete;
|
||||||
|
|
||||||
const DeleteDialog({Key? key, required this.onDelete}) : super(key: key);
|
const DeleteDialog({Key? key, required this.onDelete})
|
||||||
|
: super(
|
||||||
@override
|
key: key,
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
title: "delete_dialog_title",
|
||||||
|
content: "delete_dialog_alert",
|
||||||
return AlertDialog(
|
cancel: "delete_dialog_cancel",
|
||||||
// backgroundColor: Colors.grey[200],
|
ok: "delete_dialog_ok",
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
onOk: onDelete,
|
||||||
title: const Text("delete_dialog_title").tr(),
|
);
|
||||||
content: const Text("delete_dialog_alert").tr(),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
"delete_dialog_cancel",
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
onDelete();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
"delete_dialog_ok",
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.red[400],
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import 'package:immich_mobile/shared/models/album.dart';
|
|||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
||||||
import 'package:immich_mobile/shared/services/share.service.dart';
|
import 'package:immich_mobile/shared/services/share.service.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
||||||
@@ -38,6 +39,7 @@ class HomePage extends HookConsumerWidget {
|
|||||||
final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
|
final albums = ref.watch(albumProvider).where((a) => a.isRemote).toList();
|
||||||
final sharedAlbums = ref.watch(sharedAlbumProvider);
|
final sharedAlbums = ref.watch(sharedAlbumProvider);
|
||||||
final albumService = ref.watch(albumServiceProvider);
|
final albumService = ref.watch(albumServiceProvider);
|
||||||
|
final currentUser = ref.watch(currentUserProvider);
|
||||||
|
|
||||||
final tipOneOpacity = useState(0.0);
|
final tipOneOpacity = useState(0.0);
|
||||||
final refreshCount = useState(0);
|
final refreshCount = useState(0);
|
||||||
@@ -300,7 +302,7 @@ class HomePage extends HookConsumerWidget {
|
|||||||
bottom: false,
|
bottom: false,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
ref.watch(assetsProvider).when(
|
ref.watch(assetsProvider(currentUser?.isarId)).when(
|
||||||
data: (data) => data.isEmpty
|
data: (data) => data.isEmpty
|
||||||
? buildLoadingIndicator()
|
? buildLoadingIndicator()
|
||||||
: ImmichAssetGrid(
|
: ImmichAssetGrid(
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import 'package:hive/hive.dart';
|
|
||||||
|
|
||||||
part 'hive_saved_login_info.model.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 0)
|
|
||||||
class HiveSavedLoginInfo {
|
|
||||||
@HiveField(0)
|
|
||||||
String email; // DEPRECATED
|
|
||||||
|
|
||||||
@HiveField(1)
|
|
||||||
String password; // DEPRECATED
|
|
||||||
|
|
||||||
@HiveField(2)
|
|
||||||
String serverUrl;
|
|
||||||
|
|
||||||
@HiveField(4, defaultValue: "")
|
|
||||||
String accessToken;
|
|
||||||
|
|
||||||
HiveSavedLoginInfo({
|
|
||||||
required this.email,
|
|
||||||
required this.password,
|
|
||||||
required this.serverUrl,
|
|
||||||
required this.accessToken,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'hive_saved_login_info.model.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// TypeAdapterGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
class HiveSavedLoginInfoAdapter extends TypeAdapter<HiveSavedLoginInfo> {
|
|
||||||
@override
|
|
||||||
final int typeId = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
HiveSavedLoginInfo read(BinaryReader reader) {
|
|
||||||
final numOfFields = reader.readByte();
|
|
||||||
final fields = <int, dynamic>{
|
|
||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
|
||||||
};
|
|
||||||
return HiveSavedLoginInfo(
|
|
||||||
email: fields[0] as String,
|
|
||||||
password: fields[1] as String,
|
|
||||||
serverUrl: fields[2] as String,
|
|
||||||
accessToken: fields[4] == null ? '' : fields[4] as String,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void write(BinaryWriter writer, HiveSavedLoginInfo obj) {
|
|
||||||
writer
|
|
||||||
..writeByte(4)
|
|
||||||
..writeByte(0)
|
|
||||||
..write(obj.email)
|
|
||||||
..writeByte(1)
|
|
||||||
..write(obj.password)
|
|
||||||
..writeByte(2)
|
|
||||||
..write(obj.serverUrl)
|
|
||||||
..writeByte(4)
|
|
||||||
..write(obj.accessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => typeId.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is HiveSavedLoginInfoAdapter &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
typeId == other.typeId;
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
class LogInReponse {
|
|
||||||
final String accessToken;
|
|
||||||
final String userId;
|
|
||||||
final String userEmail;
|
|
||||||
final String firstName;
|
|
||||||
final String lastName;
|
|
||||||
final String profileImagePath;
|
|
||||||
final bool isAdmin;
|
|
||||||
final bool shouldChangePassword;
|
|
||||||
|
|
||||||
LogInReponse({
|
|
||||||
required this.accessToken,
|
|
||||||
required this.userId,
|
|
||||||
required this.userEmail,
|
|
||||||
required this.firstName,
|
|
||||||
required this.lastName,
|
|
||||||
required this.profileImagePath,
|
|
||||||
required this.isAdmin,
|
|
||||||
required this.shouldChangePassword,
|
|
||||||
});
|
|
||||||
|
|
||||||
LogInReponse copyWith({
|
|
||||||
String? accessToken,
|
|
||||||
String? userId,
|
|
||||||
String? userEmail,
|
|
||||||
String? firstName,
|
|
||||||
String? lastName,
|
|
||||||
String? profileImagePath,
|
|
||||||
bool? isAdmin,
|
|
||||||
bool? shouldChangePassword,
|
|
||||||
}) {
|
|
||||||
return LogInReponse(
|
|
||||||
accessToken: accessToken ?? this.accessToken,
|
|
||||||
userId: userId ?? this.userId,
|
|
||||||
userEmail: userEmail ?? this.userEmail,
|
|
||||||
firstName: firstName ?? this.firstName,
|
|
||||||
lastName: lastName ?? this.lastName,
|
|
||||||
profileImagePath: profileImagePath ?? this.profileImagePath,
|
|
||||||
isAdmin: isAdmin ?? this.isAdmin,
|
|
||||||
shouldChangePassword: shouldChangePassword ?? this.shouldChangePassword,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
final result = <String, dynamic>{};
|
|
||||||
|
|
||||||
result.addAll({'accessToken': accessToken});
|
|
||||||
result.addAll({'userId': userId});
|
|
||||||
result.addAll({'userEmail': userEmail});
|
|
||||||
result.addAll({'firstName': firstName});
|
|
||||||
result.addAll({'lastName': lastName});
|
|
||||||
result.addAll({'profileImagePath': profileImagePath});
|
|
||||||
result.addAll({'isAdmin': isAdmin});
|
|
||||||
result.addAll({'shouldChangePassword': shouldChangePassword});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory LogInReponse.fromMap(Map<String, dynamic> map) {
|
|
||||||
return LogInReponse(
|
|
||||||
accessToken: map['accessToken'] ?? '',
|
|
||||||
userId: map['userId'] ?? '',
|
|
||||||
userEmail: map['userEmail'] ?? '',
|
|
||||||
firstName: map['firstName'] ?? '',
|
|
||||||
lastName: map['lastName'] ?? '',
|
|
||||||
profileImagePath: map['profileImagePath'] ?? '',
|
|
||||||
isAdmin: map['isAdmin'] ?? false,
|
|
||||||
shouldChangePassword: map['shouldChangePassword'] ?? false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory LogInReponse.fromJson(String source) =>
|
|
||||||
LogInReponse.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'LogInReponse(accessToken: $accessToken, userId: $userId, userEmail: $userEmail, firstName: $firstName, lastName: $lastName, profileImagePath: $profileImagePath, isAdmin: $isAdmin, shouldChangePassword: $shouldChangePassword)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
|
|
||||||
return other is LogInReponse &&
|
|
||||||
other.accessToken == accessToken &&
|
|
||||||
other.userId == userId &&
|
|
||||||
other.userEmail == userEmail &&
|
|
||||||
other.firstName == firstName &&
|
|
||||||
other.lastName == lastName &&
|
|
||||||
other.profileImagePath == profileImagePath &&
|
|
||||||
other.isAdmin == isAdmin &&
|
|
||||||
other.shouldChangePassword == shouldChangePassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return accessToken.hashCode ^
|
|
||||||
userId.hashCode ^
|
|
||||||
userEmail.hashCode ^
|
|
||||||
firstName.hashCode ^
|
|
||||||
lastName.hashCode ^
|
|
||||||
profileImagePath.hashCode ^
|
|
||||||
isAdmin.hashCode ^
|
|
||||||
shouldChangePassword.hashCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/modules/album/providers/suggested_shared_users.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
class PartnerSharedWithNotifier extends StateNotifier<List<User>> {
|
||||||
|
PartnerSharedWithNotifier(Isar db) : super([]) {
|
||||||
|
final query = db.users.filter().isPartnerSharedWithEqualTo(true);
|
||||||
|
query.findAll().then((partners) => state = partners);
|
||||||
|
query.watch().listen((partners) => state = partners);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final partnerSharedWithProvider =
|
||||||
|
StateNotifierProvider<PartnerSharedWithNotifier, List<User>>((ref) {
|
||||||
|
return PartnerSharedWithNotifier(ref.watch(dbProvider));
|
||||||
|
});
|
||||||
|
|
||||||
|
class PartnerSharedByNotifier extends StateNotifier<List<User>> {
|
||||||
|
PartnerSharedByNotifier(Isar db) : super([]) {
|
||||||
|
final query = db.users.filter().isPartnerSharedByEqualTo(true);
|
||||||
|
query.findAll().then((partners) => state = partners);
|
||||||
|
streamSub = query.watch().listen((partners) => state = partners);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final StreamSubscription<List<User>> streamSub;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
streamSub.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final partnerSharedByProvider =
|
||||||
|
StateNotifierProvider<PartnerSharedByNotifier, List<User>>((ref) {
|
||||||
|
return PartnerSharedByNotifier(ref.watch(dbProvider));
|
||||||
|
});
|
||||||
|
|
||||||
|
final partnerAvailableProvider =
|
||||||
|
FutureProvider.autoDispose<List<User>>((ref) async {
|
||||||
|
final otherUsers = await ref.watch(otherUsersProvider.future);
|
||||||
|
final currentPartners = ref.watch(partnerSharedByProvider);
|
||||||
|
final available = Set<User>.of(otherUsers);
|
||||||
|
available.removeAll(currentPartners);
|
||||||
|
return available.toList();
|
||||||
|
});
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/api.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/db.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/services/api.service.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
|
final partnerServiceProvider = Provider(
|
||||||
|
(ref) => PartnerService(
|
||||||
|
ref.watch(apiServiceProvider),
|
||||||
|
ref.watch(dbProvider),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
enum PartnerDirection {
|
||||||
|
sharedWith("shared-with"),
|
||||||
|
sharedBy("shared-by");
|
||||||
|
|
||||||
|
const PartnerDirection(
|
||||||
|
this._value,
|
||||||
|
);
|
||||||
|
|
||||||
|
final String _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PartnerService {
|
||||||
|
final ApiService _apiService;
|
||||||
|
final Isar _db;
|
||||||
|
final Logger _log = Logger("PartnerService");
|
||||||
|
|
||||||
|
PartnerService(this._apiService, this._db);
|
||||||
|
|
||||||
|
Future<List<User>?> getPartners(PartnerDirection direction) async {
|
||||||
|
try {
|
||||||
|
final userDtos =
|
||||||
|
await _apiService.partnerApi.getPartners(direction._value);
|
||||||
|
if (userDtos != null) {
|
||||||
|
return userDtos.map((u) => User.fromDto(u)).toList();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_log.warning("failed to get partners for direction $direction:\n$e");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> removePartner(User partner) async {
|
||||||
|
try {
|
||||||
|
await _apiService.partnerApi.removePartner(partner.id);
|
||||||
|
partner.isPartnerSharedBy = false;
|
||||||
|
await _db.writeTxn(() => _db.users.put(partner));
|
||||||
|
} catch (e) {
|
||||||
|
_log.warning("failed to remove partner ${partner.id}:\n$e");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> addPartner(User partner) async {
|
||||||
|
try {
|
||||||
|
final dto = await _apiService.partnerApi.createPartner(partner.id);
|
||||||
|
if (dto != null) {
|
||||||
|
partner.isPartnerSharedBy = true;
|
||||||
|
await _db.writeTxn(() => _db.users.put(partner));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_log.warning("failed to add partner ${partner.id}:\n$e");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/ui/user_avatar.dart';
|
||||||
|
|
||||||
|
class PartnerList extends HookConsumerWidget {
|
||||||
|
const PartnerList({Key? key, required this.partner}) : super(key: key);
|
||||||
|
|
||||||
|
final List<User> partner;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return SliverList(
|
||||||
|
delegate:
|
||||||
|
SliverChildBuilderDelegate(listEntry, childCount: partner.length),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget listEntry(BuildContext context, int index) {
|
||||||
|
final User p = partner[index];
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
leading: userAvatar(context, p, radius: 30),
|
||||||
|
title: Text("${p.firstName} ${p.lastName}"),
|
||||||
|
onTap: () => AutoRouter.of(context).push(PartnerDetailRoute(partner: p)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
||||||
|
|
||||||
|
class PartnerDetailPage extends HookConsumerWidget {
|
||||||
|
const PartnerDetailPage({Key? key, required this.partner}) : super(key: key);
|
||||||
|
|
||||||
|
final User partner;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final assets = ref.watch(assetsProvider(partner.isarId));
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("${partner.firstName} ${partner.lastName}"),
|
||||||
|
elevation: 0,
|
||||||
|
centerTitle: false,
|
||||||
|
),
|
||||||
|
body: assets.when(
|
||||||
|
data: (renderList) => renderList.isEmpty
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Text(
|
||||||
|
"It seems ${partner.firstName} does not have any photos...\n"
|
||||||
|
"Or your server version does not match the app version."),
|
||||||
|
)
|
||||||
|
: ImmichAssetGrid(
|
||||||
|
renderList: renderList,
|
||||||
|
onRefresh: () => ref.read(assetProvider.notifier).getAllAsset(),
|
||||||
|
),
|
||||||
|
error: (e, _) => Text("Error loading partners:\n$e"),
|
||||||
|
loading: () => const Center(child: ImmichLoadingIndicator()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/modules/partner/providers/partner.provider.dart';
|
||||||
|
import 'package:immich_mobile/modules/partner/services/partner.service.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/ui/confirm_dialog.dart';
|
||||||
|
import 'package:immich_mobile/shared/ui/immich_toast.dart';
|
||||||
|
import 'package:immich_mobile/shared/ui/user_avatar.dart';
|
||||||
|
|
||||||
|
class PartnerPage extends HookConsumerWidget {
|
||||||
|
const PartnerPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final List<User> partners = ref.watch(partnerSharedByProvider);
|
||||||
|
final availableUsers = ref.watch(partnerAvailableProvider);
|
||||||
|
|
||||||
|
addNewUsersHandler() async {
|
||||||
|
final users = availableUsers.value;
|
||||||
|
if (users == null || users.isEmpty) {
|
||||||
|
ImmichToast.show(
|
||||||
|
context: context,
|
||||||
|
msg: "partner_page_no_more_users".tr(),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final selectedUser = await showDialog<User>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return SimpleDialog(
|
||||||
|
title: const Text("partner_page_select_partner").tr(),
|
||||||
|
children: [
|
||||||
|
for (User u in users)
|
||||||
|
SimpleDialogOption(
|
||||||
|
onPressed: () => Navigator.pop(context, u),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: userAvatar(context, u),
|
||||||
|
),
|
||||||
|
Text("${u.firstName} ${u.lastName}"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (selectedUser != null) {
|
||||||
|
final ok =
|
||||||
|
await ref.read(partnerServiceProvider).addPartner(selectedUser);
|
||||||
|
if (ok) {
|
||||||
|
ref.invalidate(partnerSharedByProvider);
|
||||||
|
} else {
|
||||||
|
ImmichToast.show(
|
||||||
|
context: context,
|
||||||
|
msg: "partner_page_partner_add_failed".tr(),
|
||||||
|
toastType: ToastType.error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteUser(User u) {
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return ConfirmDialog(
|
||||||
|
title: "partner_page_stop_sharing_title",
|
||||||
|
content:
|
||||||
|
"partner_page_stop_sharing_content".tr(args: [u.firstName]),
|
||||||
|
onOk: () => ref.read(partnerServiceProvider).removePartner(u),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildUserList(List<User> users) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
|
||||||
|
child: const Text(
|
||||||
|
"partner_page_shared_to_title",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
|
if (users.isNotEmpty)
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: users.length,
|
||||||
|
itemBuilder: ((context, index) {
|
||||||
|
return ListTile(
|
||||||
|
leading: userAvatar(context, users[index]),
|
||||||
|
title: Text(
|
||||||
|
users[index].email,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.person_remove),
|
||||||
|
onPressed: () => onDeleteUser(users[index]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
if (users.isEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: const Text(
|
||||||
|
"partner_page_empty_message",
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
|
ElevatedButton.icon(
|
||||||
|
onPressed: availableUsers.whenOrNull(
|
||||||
|
data: (data) => addNewUsersHandler,
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.person_add),
|
||||||
|
label: const Text("partner_page_add_partner").tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("partner_page_title").tr(),
|
||||||
|
elevation: 0,
|
||||||
|
centerTitle: false,
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed:
|
||||||
|
availableUsers.whenOrNull(data: (data) => addNewUsersHandler),
|
||||||
|
icon: const Icon(Icons.person_add),
|
||||||
|
tooltip: "partner_page_add_partner".tr(),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: buildUserList(partners),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
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/modules/settings/services/app_settings.service.dart';
|
|
||||||
import 'package:immich_mobile/modules/settings/ui/cache_settings/cache_settings_slider_pref.dart';
|
|
||||||
import 'package:immich_mobile/shared/services/cache.service.dart';
|
|
||||||
import 'package:immich_mobile/utils/bytes_units.dart';
|
|
||||||
|
|
||||||
class CacheSettings extends HookConsumerWidget {
|
|
||||||
const CacheSettings({
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
final CacheService cacheService = ref.watch(cacheServiceProvider);
|
|
||||||
final clearCacheState = useState(false);
|
|
||||||
|
|
||||||
Future<void> clearCache() async {
|
|
||||||
await cacheService.emptyAllCaches();
|
|
||||||
clearCacheState.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget cacheStatisticsRow(String name, CacheType type) {
|
|
||||||
final cacheSize = useState(0);
|
|
||||||
final cacheAssets = useState(0);
|
|
||||||
|
|
||||||
if (!clearCacheState.value) {
|
|
||||||
final repo = cacheService.getCacheRepo(type);
|
|
||||||
|
|
||||||
repo.open().then((_) {
|
|
||||||
cacheSize.value = repo.getCacheSize();
|
|
||||||
cacheAssets.value = repo.getNumberOfCachedObjects();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cacheSize.value = 0;
|
|
||||||
cacheAssets.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
margin: const EdgeInsets.only(left: 20, bottom: 10),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
name,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Text(
|
|
||||||
"cache_settings_statistics_assets",
|
|
||||||
style: TextStyle(color: Colors.grey),
|
|
||||||
).tr(
|
|
||||||
args: ["${cacheAssets.value}", formatBytes(cacheSize.value)],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ExpansionTile(
|
|
||||||
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
textColor: Theme.of(context).primaryColor,
|
|
||||||
title: const Text(
|
|
||||||
'cache_settings_title',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
subtitle: const Text(
|
|
||||||
'cache_settings_subtitle',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
children: [
|
|
||||||
const CacheSettingsSliderPref(
|
|
||||||
setting: AppSettingsEnum.thumbnailCacheSize,
|
|
||||||
translationKey: "cache_settings_thumbnail_size",
|
|
||||||
min: 1000,
|
|
||||||
max: 20000,
|
|
||||||
divisions: 19,
|
|
||||||
),
|
|
||||||
const CacheSettingsSliderPref(
|
|
||||||
setting: AppSettingsEnum.imageCacheSize,
|
|
||||||
translationKey: "cache_settings_image_cache_size",
|
|
||||||
min: 0,
|
|
||||||
max: 1000,
|
|
||||||
divisions: 20,
|
|
||||||
),
|
|
||||||
const CacheSettingsSliderPref(
|
|
||||||
setting: AppSettingsEnum.albumThumbnailCacheSize,
|
|
||||||
translationKey: "cache_settings_album_thumbnails",
|
|
||||||
min: 0,
|
|
||||||
max: 1000,
|
|
||||||
divisions: 20,
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: const Text(
|
|
||||||
"cache_settings_statistics_title",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
cacheStatisticsRow(
|
|
||||||
"cache_settings_statistics_thumbnail".tr(),
|
|
||||||
CacheType.thumbnail,
|
|
||||||
),
|
|
||||||
cacheStatisticsRow(
|
|
||||||
"cache_settings_statistics_album".tr(),
|
|
||||||
CacheType.albumThumbnail,
|
|
||||||
),
|
|
||||||
cacheStatisticsRow(
|
|
||||||
"cache_settings_statistics_shared".tr(),
|
|
||||||
CacheType.sharedAlbumThumbnail,
|
|
||||||
),
|
|
||||||
cacheStatisticsRow(
|
|
||||||
"cache_settings_statistics_full".tr(),
|
|
||||||
CacheType.imageViewerFull,
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: const Text(
|
|
||||||
"cache_settings_clear_cache_button_title",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: ElevatedButton(
|
|
||||||
onPressed: clearCache,
|
|
||||||
child: const Text(
|
|
||||||
"cache_settings_clear_cache_button",
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
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/modules/settings/providers/app_settings.provider.dart';
|
|
||||||
import 'package:immich_mobile/modules/settings/services/app_settings.service.dart';
|
|
||||||
|
|
||||||
class CacheSettingsSliderPref extends HookConsumerWidget {
|
|
||||||
final AppSettingsEnum<int> setting;
|
|
||||||
final String translationKey;
|
|
||||||
final int min;
|
|
||||||
final int max;
|
|
||||||
final int divisions;
|
|
||||||
|
|
||||||
const CacheSettingsSliderPref({
|
|
||||||
Key? key,
|
|
||||||
required this.setting,
|
|
||||||
required this.translationKey,
|
|
||||||
required this.min,
|
|
||||||
required this.max,
|
|
||||||
required this.divisions,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
final appSettingService = ref.watch(appSettingsServiceProvider);
|
|
||||||
|
|
||||||
final itemsValue = useState(appSettingService.getSetting<int>(setting));
|
|
||||||
|
|
||||||
void sliderChanged(double value) {
|
|
||||||
itemsValue.value = value.toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sliderChangedEnd(double value) {
|
|
||||||
appSettingService.setSetting(setting, value.toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
translationKey,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(args: ["${itemsValue.value.toInt()}"]),
|
|
||||||
),
|
|
||||||
Slider(
|
|
||||||
onChangeEnd: sliderChangedEnd,
|
|
||||||
onChanged: sliderChanged,
|
|
||||||
value: itemsValue.value.toDouble(),
|
|
||||||
min: min.toDouble(),
|
|
||||||
max: max.toDouble(),
|
|
||||||
divisions: divisions,
|
|
||||||
label: "${itemsValue.value.toInt()}",
|
|
||||||
activeColor: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
|
|
||||||
class ExperimentalSettings extends HookConsumerWidget {
|
|
||||||
const ExperimentalSettings({
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
return ExpansionTile(
|
|
||||||
textColor: Theme.of(context).primaryColor,
|
|
||||||
title: const Text(
|
|
||||||
'experimental_settings_title',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
subtitle: const Text(
|
|
||||||
'experimental_settings_subtitle',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
children: const [
|
|
||||||
// SwitchListTile.adaptive(
|
|
||||||
// activeColor: Theme.of(context).primaryColor,
|
|
||||||
// title: const Text(
|
|
||||||
// "experimental_settings_new_asset_list_title",
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 12,
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// ),
|
|
||||||
// ).tr(),
|
|
||||||
// subtitle: const Text(
|
|
||||||
// "experimental_settings_new_asset_list_subtitle",
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 12,
|
|
||||||
// ),
|
|
||||||
// ).tr(),
|
|
||||||
// value: useExperimentalAssetGrid.value,
|
|
||||||
// onChanged: changeUseExperimentalAssetGrid,
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,8 @@ import 'package:immich_mobile/modules/album/views/album_viewer_page.dart';
|
|||||||
import 'package:immich_mobile/modules/album/views/asset_selection_page.dart';
|
import 'package:immich_mobile/modules/album/views/asset_selection_page.dart';
|
||||||
import 'package:immich_mobile/modules/album/views/create_album_page.dart';
|
import 'package:immich_mobile/modules/album/views/create_album_page.dart';
|
||||||
import 'package:immich_mobile/modules/album/views/library_page.dart';
|
import 'package:immich_mobile/modules/album/views/library_page.dart';
|
||||||
|
import 'package:immich_mobile/modules/partner/views/partner_detail_page.dart';
|
||||||
|
import 'package:immich_mobile/modules/partner/views/partner_page.dart';
|
||||||
import 'package:immich_mobile/modules/album/views/select_additional_user_for_sharing_page.dart';
|
import 'package:immich_mobile/modules/album/views/select_additional_user_for_sharing_page.dart';
|
||||||
import 'package:immich_mobile/modules/album/views/select_user_for_sharing_page.dart';
|
import 'package:immich_mobile/modules/album/views/select_user_for_sharing_page.dart';
|
||||||
import 'package:immich_mobile/modules/album/views/sharing_page.dart';
|
import 'package:immich_mobile/modules/album/views/sharing_page.dart';
|
||||||
@@ -35,6 +37,7 @@ import 'package:immich_mobile/routing/duplicate_guard.dart';
|
|||||||
import 'package:immich_mobile/routing/gallery_permission_guard.dart';
|
import 'package:immich_mobile/routing/gallery_permission_guard.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/models/album.dart';
|
import 'package:immich_mobile/shared/models/album.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
import 'package:immich_mobile/shared/models/logger_message.model.dart';
|
import 'package:immich_mobile/shared/models/logger_message.model.dart';
|
||||||
import 'package:immich_mobile/shared/providers/api.provider.dart';
|
import 'package:immich_mobile/shared/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/shared/services/api.service.dart';
|
import 'package:immich_mobile/shared/services/api.service.dart';
|
||||||
@@ -136,6 +139,8 @@ part 'router.gr.dart';
|
|||||||
DuplicateGuard,
|
DuplicateGuard,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
AutoRoute(page: PartnerPage, guards: [AuthGuard, DuplicateGuard]),
|
||||||
|
AutoRoute(page: PartnerDetailPage, guards: [AuthGuard, DuplicateGuard])
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
class AppRouter extends _$AppRouter {
|
class AppRouter extends _$AppRouter {
|
||||||
|
|||||||
@@ -256,6 +256,22 @@ class _$AppRouter extends RootStackRouter {
|
|||||||
child: const ArchivePage(),
|
child: const ArchivePage(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
PartnerRoute.name: (routeData) {
|
||||||
|
return MaterialPageX<dynamic>(
|
||||||
|
routeData: routeData,
|
||||||
|
child: const PartnerPage(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
PartnerDetailRoute.name: (routeData) {
|
||||||
|
final args = routeData.argsAs<PartnerDetailRouteArgs>();
|
||||||
|
return MaterialPageX<dynamic>(
|
||||||
|
routeData: routeData,
|
||||||
|
child: PartnerDetailPage(
|
||||||
|
key: args.key,
|
||||||
|
partner: args.partner,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
HomeRoute.name: (routeData) {
|
HomeRoute.name: (routeData) {
|
||||||
return MaterialPageX<dynamic>(
|
return MaterialPageX<dynamic>(
|
||||||
routeData: routeData,
|
routeData: routeData,
|
||||||
@@ -523,6 +539,22 @@ class _$AppRouter extends RootStackRouter {
|
|||||||
duplicateGuard,
|
duplicateGuard,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
RouteConfig(
|
||||||
|
PartnerRoute.name,
|
||||||
|
path: '/partner-page',
|
||||||
|
guards: [
|
||||||
|
authGuard,
|
||||||
|
duplicateGuard,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
RouteConfig(
|
||||||
|
PartnerDetailRoute.name,
|
||||||
|
path: '/partner-detail-page',
|
||||||
|
guards: [
|
||||||
|
authGuard,
|
||||||
|
duplicateGuard,
|
||||||
|
],
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,6 +1145,52 @@ class ArchiveRoute extends PageRouteInfo<void> {
|
|||||||
static const String name = 'ArchiveRoute';
|
static const String name = 'ArchiveRoute';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [PartnerPage]
|
||||||
|
class PartnerRoute extends PageRouteInfo<void> {
|
||||||
|
const PartnerRoute()
|
||||||
|
: super(
|
||||||
|
PartnerRoute.name,
|
||||||
|
path: '/partner-page',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'PartnerRoute';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [PartnerDetailPage]
|
||||||
|
class PartnerDetailRoute extends PageRouteInfo<PartnerDetailRouteArgs> {
|
||||||
|
PartnerDetailRoute({
|
||||||
|
Key? key,
|
||||||
|
required User partner,
|
||||||
|
}) : super(
|
||||||
|
PartnerDetailRoute.name,
|
||||||
|
path: '/partner-detail-page',
|
||||||
|
args: PartnerDetailRouteArgs(
|
||||||
|
key: key,
|
||||||
|
partner: partner,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'PartnerDetailRoute';
|
||||||
|
}
|
||||||
|
|
||||||
|
class PartnerDetailRouteArgs {
|
||||||
|
const PartnerDetailRouteArgs({
|
||||||
|
this.key,
|
||||||
|
required this.partner,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Key? key;
|
||||||
|
|
||||||
|
final User partner;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PartnerDetailRouteArgs{key: $key, partner: $partner}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [HomePage]
|
/// [HomePage]
|
||||||
class HomeRoute extends PageRouteInfo<void> {
|
class HomeRoute extends PageRouteInfo<void> {
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ class Album {
|
|||||||
remoteId == other.remoteId &&
|
remoteId == other.remoteId &&
|
||||||
localId == other.localId &&
|
localId == other.localId &&
|
||||||
name == other.name &&
|
name == other.name &&
|
||||||
createdAt == other.createdAt &&
|
createdAt.isAtSameMomentAs(other.createdAt) &&
|
||||||
modifiedAt == other.modifiedAt &&
|
modifiedAt.isAtSameMomentAs(other.modifiedAt) &&
|
||||||
shared == other.shared &&
|
shared == other.shared &&
|
||||||
owner.value == other.owner.value &&
|
owner.value == other.owner.value &&
|
||||||
thumbnail.value == other.thumbnail.value &&
|
thumbnail.value == other.thumbnail.value &&
|
||||||
@@ -128,8 +128,8 @@ class Album {
|
|||||||
final Album a = Album(
|
final Album a = Album(
|
||||||
remoteId: dto.id,
|
remoteId: dto.id,
|
||||||
name: dto.albumName,
|
name: dto.albumName,
|
||||||
createdAt: DateTime.parse(dto.createdAt),
|
createdAt: dto.createdAt,
|
||||||
modifiedAt: DateTime.parse(dto.updatedAt),
|
modifiedAt: dto.updatedAt,
|
||||||
shared: dto.shared,
|
shared: dto.shared,
|
||||||
);
|
);
|
||||||
a.owner.value = await db.users.getById(dto.ownerId);
|
a.owner.value = await db.users.getById(dto.ownerId);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'album.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
extension GetAlbumCollection on Isar {
|
extension GetAlbumCollection on Isar {
|
||||||
IsarCollection<Album> get albums => this.collection();
|
IsarCollection<Album> get albums => this.collection();
|
||||||
@@ -111,7 +111,7 @@ const AlbumSchema = CollectionSchema(
|
|||||||
getId: _albumGetId,
|
getId: _albumGetId,
|
||||||
getLinks: _albumGetLinks,
|
getLinks: _albumGetLinks,
|
||||||
attach: _albumAttach,
|
attach: _albumAttach,
|
||||||
version: '3.0.5',
|
version: '3.1.0+1',
|
||||||
);
|
);
|
||||||
|
|
||||||
int _albumEstimateSize(
|
int _albumEstimateSize(
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ class Asset {
|
|||||||
Asset.remote(AssetResponseDto remote)
|
Asset.remote(AssetResponseDto remote)
|
||||||
: remoteId = remote.id,
|
: remoteId = remote.id,
|
||||||
isLocal = false,
|
isLocal = false,
|
||||||
fileCreatedAt = DateTime.parse(remote.fileCreatedAt),
|
fileCreatedAt = remote.fileCreatedAt,
|
||||||
fileModifiedAt = DateTime.parse(remote.fileModifiedAt),
|
fileModifiedAt = remote.fileModifiedAt,
|
||||||
updatedAt = DateTime.parse(remote.updatedAt),
|
updatedAt = remote.updatedAt,
|
||||||
durationInSeconds = remote.duration.toDuration()?.inSeconds ?? 0,
|
durationInSeconds = remote.duration.toDuration()?.inSeconds ?? 0,
|
||||||
type = remote.type.toAssetType(),
|
type = remote.type.toAssetType(),
|
||||||
fileName = p.basename(remote.originalPath),
|
fileName = p.basename(remote.originalPath),
|
||||||
@@ -179,9 +179,9 @@ class Asset {
|
|||||||
localId == other.localId &&
|
localId == other.localId &&
|
||||||
deviceId == other.deviceId &&
|
deviceId == other.deviceId &&
|
||||||
ownerId == other.ownerId &&
|
ownerId == other.ownerId &&
|
||||||
fileCreatedAt == other.fileCreatedAt &&
|
fileCreatedAt.isAtSameMomentAs(other.fileCreatedAt) &&
|
||||||
fileModifiedAt == other.fileModifiedAt &&
|
fileModifiedAt.isAtSameMomentAs(other.fileModifiedAt) &&
|
||||||
updatedAt == other.updatedAt &&
|
updatedAt.isAtSameMomentAs(other.updatedAt) &&
|
||||||
durationInSeconds == other.durationInSeconds &&
|
durationInSeconds == other.durationInSeconds &&
|
||||||
type == other.type &&
|
type == other.type &&
|
||||||
width == other.width &&
|
width == other.width &&
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'asset.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
extension GetAssetCollection on Isar {
|
extension GetAssetCollection on Isar {
|
||||||
IsarCollection<Asset> get assets => this.collection();
|
IsarCollection<Asset> get assets => this.collection();
|
||||||
@@ -142,7 +142,7 @@ const AssetSchema = CollectionSchema(
|
|||||||
getId: _assetGetId,
|
getId: _assetGetId,
|
||||||
getLinks: _assetGetLinks,
|
getLinks: _assetGetLinks,
|
||||||
attach: _assetAttach,
|
attach: _assetAttach,
|
||||||
version: '3.0.5',
|
version: '3.1.0+1',
|
||||||
);
|
);
|
||||||
|
|
||||||
int _assetEstimateSize(
|
int _assetEstimateSize(
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:immich_mobile/utils/hash.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
part 'etag.g.dart';
|
||||||
|
|
||||||
|
@Collection(inheritance: false)
|
||||||
|
class ETag {
|
||||||
|
ETag({required this.id, this.value});
|
||||||
|
Id get isarId => fastHash(id);
|
||||||
|
@Index(unique: true, replace: true, type: IndexType.hash)
|
||||||
|
String id;
|
||||||
|
String? value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,724 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'etag.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// IsarCollectionGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
|
extension GetETagCollection on Isar {
|
||||||
|
IsarCollection<ETag> get eTags => this.collection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ETagSchema = CollectionSchema(
|
||||||
|
name: r'ETag',
|
||||||
|
id: -644290296585643859,
|
||||||
|
properties: {
|
||||||
|
r'id': PropertySchema(
|
||||||
|
id: 0,
|
||||||
|
name: r'id',
|
||||||
|
type: IsarType.string,
|
||||||
|
),
|
||||||
|
r'value': PropertySchema(
|
||||||
|
id: 1,
|
||||||
|
name: r'value',
|
||||||
|
type: IsarType.string,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
estimateSize: _eTagEstimateSize,
|
||||||
|
serialize: _eTagSerialize,
|
||||||
|
deserialize: _eTagDeserialize,
|
||||||
|
deserializeProp: _eTagDeserializeProp,
|
||||||
|
idName: r'isarId',
|
||||||
|
indexes: {
|
||||||
|
r'id': IndexSchema(
|
||||||
|
id: -3268401673993471357,
|
||||||
|
name: r'id',
|
||||||
|
unique: true,
|
||||||
|
replace: true,
|
||||||
|
properties: [
|
||||||
|
IndexPropertySchema(
|
||||||
|
name: r'id',
|
||||||
|
type: IndexType.hash,
|
||||||
|
caseSensitive: true,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
links: {},
|
||||||
|
embeddedSchemas: {},
|
||||||
|
getId: _eTagGetId,
|
||||||
|
getLinks: _eTagGetLinks,
|
||||||
|
attach: _eTagAttach,
|
||||||
|
version: '3.1.0+1',
|
||||||
|
);
|
||||||
|
|
||||||
|
int _eTagEstimateSize(
|
||||||
|
ETag object,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
var bytesCount = offsets.last;
|
||||||
|
bytesCount += 3 + object.id.length * 3;
|
||||||
|
{
|
||||||
|
final value = object.value;
|
||||||
|
if (value != null) {
|
||||||
|
bytesCount += 3 + value.length * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _eTagSerialize(
|
||||||
|
ETag object,
|
||||||
|
IsarWriter writer,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
writer.writeString(offsets[0], object.id);
|
||||||
|
writer.writeString(offsets[1], object.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ETag _eTagDeserialize(
|
||||||
|
Id id,
|
||||||
|
IsarReader reader,
|
||||||
|
List<int> offsets,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
final object = ETag(
|
||||||
|
id: reader.readString(offsets[0]),
|
||||||
|
value: reader.readStringOrNull(offsets[1]),
|
||||||
|
);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
P _eTagDeserializeProp<P>(
|
||||||
|
IsarReader reader,
|
||||||
|
int propertyId,
|
||||||
|
int offset,
|
||||||
|
Map<Type, List<int>> allOffsets,
|
||||||
|
) {
|
||||||
|
switch (propertyId) {
|
||||||
|
case 0:
|
||||||
|
return (reader.readString(offset)) as P;
|
||||||
|
case 1:
|
||||||
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
default:
|
||||||
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Id _eTagGetId(ETag object) {
|
||||||
|
return object.isarId;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IsarLinkBase<dynamic>> _eTagGetLinks(ETag object) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _eTagAttach(IsarCollection<dynamic> col, Id id, ETag object) {}
|
||||||
|
|
||||||
|
extension ETagByIndex on IsarCollection<ETag> {
|
||||||
|
Future<ETag?> getById(String id) {
|
||||||
|
return getByIndex(r'id', [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ETag? getByIdSync(String id) {
|
||||||
|
return getByIndexSync(r'id', [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> deleteById(String id) {
|
||||||
|
return deleteByIndex(r'id', [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deleteByIdSync(String id) {
|
||||||
|
return deleteByIndexSync(r'id', [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ETag?>> getAllById(List<String> idValues) {
|
||||||
|
final values = idValues.map((e) => [e]).toList();
|
||||||
|
return getAllByIndex(r'id', values);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ETag?> getAllByIdSync(List<String> idValues) {
|
||||||
|
final values = idValues.map((e) => [e]).toList();
|
||||||
|
return getAllByIndexSync(r'id', values);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> deleteAllById(List<String> idValues) {
|
||||||
|
final values = idValues.map((e) => [e]).toList();
|
||||||
|
return deleteAllByIndex(r'id', values);
|
||||||
|
}
|
||||||
|
|
||||||
|
int deleteAllByIdSync(List<String> idValues) {
|
||||||
|
final values = idValues.map((e) => [e]).toList();
|
||||||
|
return deleteAllByIndexSync(r'id', values);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Id> putById(ETag object) {
|
||||||
|
return putByIndex(r'id', object);
|
||||||
|
}
|
||||||
|
|
||||||
|
Id putByIdSync(ETag object, {bool saveLinks = true}) {
|
||||||
|
return putByIndexSync(r'id', object, saveLinks: saveLinks);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Id>> putAllById(List<ETag> objects) {
|
||||||
|
return putAllByIndex(r'id', objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Id> putAllByIdSync(List<ETag> objects, {bool saveLinks = true}) {
|
||||||
|
return putAllByIndexSync(r'id', objects, saveLinks: saveLinks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryWhereSort on QueryBuilder<ETag, ETag, QWhere> {
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhere> anyIsarId() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(const IdWhereClause.any());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryWhere on QueryBuilder<ETag, ETag, QWhereClause> {
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> isarIdEqualTo(Id isarId) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: isarId,
|
||||||
|
upper: isarId,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> isarIdNotEqualTo(Id isarId) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
if (query.whereSort == Sort.asc) {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: isarId, includeUpper: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: isarId, includeLower: false),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return query
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: isarId, includeLower: false),
|
||||||
|
)
|
||||||
|
.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: isarId, includeUpper: false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> isarIdGreaterThan(Id isarId,
|
||||||
|
{bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.greaterThan(lower: isarId, includeLower: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> isarIdLessThan(Id isarId,
|
||||||
|
{bool include = false}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(
|
||||||
|
IdWhereClause.lessThan(upper: isarId, includeUpper: include),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> isarIdBetween(
|
||||||
|
Id lowerIsarId,
|
||||||
|
Id upperIsarId, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IdWhereClause.between(
|
||||||
|
lower: lowerIsarId,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upperIsarId,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> idEqualTo(String id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addWhereClause(IndexWhereClause.equalTo(
|
||||||
|
indexName: r'id',
|
||||||
|
value: [id],
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterWhereClause> idNotEqualTo(String id) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
if (query.whereSort == Sort.asc) {
|
||||||
|
return query
|
||||||
|
.addWhereClause(IndexWhereClause.between(
|
||||||
|
indexName: r'id',
|
||||||
|
lower: [],
|
||||||
|
upper: [id],
|
||||||
|
includeUpper: false,
|
||||||
|
))
|
||||||
|
.addWhereClause(IndexWhereClause.between(
|
||||||
|
indexName: r'id',
|
||||||
|
lower: [id],
|
||||||
|
includeLower: false,
|
||||||
|
upper: [],
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return query
|
||||||
|
.addWhereClause(IndexWhereClause.between(
|
||||||
|
indexName: r'id',
|
||||||
|
lower: [id],
|
||||||
|
includeLower: false,
|
||||||
|
upper: [],
|
||||||
|
))
|
||||||
|
.addWhereClause(IndexWhereClause.between(
|
||||||
|
indexName: r'id',
|
||||||
|
lower: [],
|
||||||
|
upper: [id],
|
||||||
|
includeUpper: false,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryFilter on QueryBuilder<ETag, ETag, QFilterCondition> {
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idBetween(
|
||||||
|
String lower,
|
||||||
|
String upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'id',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idContains(String value,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'id',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idMatches(String pattern,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'id',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'id',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> idIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'id',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> isarIdEqualTo(Id value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'isarId',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> isarIdGreaterThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'isarId',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> isarIdLessThan(
|
||||||
|
Id value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'isarId',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> isarIdBetween(
|
||||||
|
Id lower,
|
||||||
|
Id upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'isarId',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'value',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'value',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueEqualTo(
|
||||||
|
String? value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueGreaterThan(
|
||||||
|
String? value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueLessThan(
|
||||||
|
String? value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueBetween(
|
||||||
|
String? lower,
|
||||||
|
String? upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'value',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueContains(String value,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'value',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueMatches(String pattern,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'value',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'value',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterFilterCondition> valueIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'value',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryObject on QueryBuilder<ETag, ETag, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension ETagQueryLinks on QueryBuilder<ETag, ETag, QFilterCondition> {}
|
||||||
|
|
||||||
|
extension ETagQuerySortBy on QueryBuilder<ETag, ETag, QSortBy> {
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> sortById() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> sortByIdDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> sortByValue() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'value', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> sortByValueDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'value', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQuerySortThenBy on QueryBuilder<ETag, ETag, QSortThenBy> {
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenById() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenByIdDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'id', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenByIsarId() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isarId', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenByIsarIdDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isarId', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenByValue() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'value', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QAfterSortBy> thenByValueDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'value', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryWhereDistinct on QueryBuilder<ETag, ETag, QDistinct> {
|
||||||
|
QueryBuilder<ETag, ETag, QDistinct> distinctById(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'id', caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, ETag, QDistinct> distinctByValue(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'value', caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ETagQueryProperty on QueryBuilder<ETag, ETag, QQueryProperty> {
|
||||||
|
QueryBuilder<ETag, int, QQueryOperations> isarIdProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'isarId');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, String, QQueryOperations> idProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<ETag, String?, QQueryOperations> valueProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'value');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ part of 'exif_info.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters
|
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||||
|
|
||||||
extension GetExifInfoCollection on Isar {
|
extension GetExifInfoCollection on Isar {
|
||||||
IsarCollection<ExifInfo> get exifInfos => this.collection();
|
IsarCollection<ExifInfo> get exifInfos => this.collection();
|
||||||
@@ -99,7 +99,7 @@ const ExifInfoSchema = CollectionSchema(
|
|||||||
getId: _exifInfoGetId,
|
getId: _exifInfoGetId,
|
||||||
getLinks: _exifInfoGetLinks,
|
getLinks: _exifInfoGetLinks,
|
||||||
attach: _exifInfoAttach,
|
attach: _exifInfoAttach,
|
||||||
version: '3.0.5',
|
version: '3.1.0+1',
|
||||||
);
|
);
|
||||||
|
|
||||||
int _exifInfoEstimateSize(
|
int _exifInfoEstimateSize(
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
class ImageViewerPageData {
|
|
||||||
final String heroTag;
|
|
||||||
final String imageUrl;
|
|
||||||
final String thumbnailUrl;
|
|
||||||
|
|
||||||
ImageViewerPageData({
|
|
||||||
required this.heroTag,
|
|
||||||
required this.imageUrl,
|
|
||||||
required this.thumbnailUrl,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import 'package:hive/hive.dart';
|
|
||||||
|
|
||||||
part 'immich_logger_message.model.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 3)
|
|
||||||
class ImmichLoggerMessage {
|
|
||||||
@HiveField(0)
|
|
||||||
String message;
|
|
||||||
|
|
||||||
@HiveField(1, defaultValue: "INFO")
|
|
||||||
String level;
|
|
||||||
|
|
||||||
@HiveField(2)
|
|
||||||
DateTime createdAt;
|
|
||||||
|
|
||||||
@HiveField(3)
|
|
||||||
String? context1;
|
|
||||||
|
|
||||||
@HiveField(4)
|
|
||||||
String? context2;
|
|
||||||
|
|
||||||
ImmichLoggerMessage({
|
|
||||||
required this.message,
|
|
||||||
required this.level,
|
|
||||||
required this.createdAt,
|
|
||||||
required this.context1,
|
|
||||||
required this.context2,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'InAppLoggerMessage(message: $message, level: $level, createdAt: $createdAt)';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'immich_logger_message.model.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// TypeAdapterGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
class ImmichLoggerMessageAdapter extends TypeAdapter<ImmichLoggerMessage> {
|
|
||||||
@override
|
|
||||||
final int typeId = 3;
|
|
||||||
|
|
||||||
@override
|
|
||||||
ImmichLoggerMessage read(BinaryReader reader) {
|
|
||||||
final numOfFields = reader.readByte();
|
|
||||||
final fields = <int, dynamic>{
|
|
||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
|
||||||
};
|
|
||||||
return ImmichLoggerMessage(
|
|
||||||
message: fields[0] as String,
|
|
||||||
level: fields[1] == null ? 'INFO' : fields[1] as String,
|
|
||||||
createdAt: fields[2] as DateTime,
|
|
||||||
context1: fields[3] as String?,
|
|
||||||
context2: fields[4] as String?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void write(BinaryWriter writer, ImmichLoggerMessage obj) {
|
|
||||||
writer
|
|
||||||
..writeByte(5)
|
|
||||||
..writeByte(0)
|
|
||||||
..write(obj.message)
|
|
||||||
..writeByte(1)
|
|
||||||
..write(obj.level)
|
|
||||||
..writeByte(2)
|
|
||||||
..write(obj.createdAt)
|
|
||||||
..writeByte(3)
|
|
||||||
..write(obj.context1)
|
|
||||||
..writeByte(4)
|
|
||||||
..write(obj.context2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => typeId.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) =>
|
|
||||||
identical(this, other) ||
|
|
||||||
other is ImmichLoggerMessageAdapter &&
|
|
||||||
runtimeType == other.runtimeType &&
|
|
||||||
typeId == other.typeId;
|
|
||||||
}
|
|
||||||