mirror of
https://github.com/immich-app/immich.git
synced 2025-12-08 05:41:04 -08:00
Compare commits
1 Commits
feat/rotat
...
asset-user
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7277ea3d7a |
1
.github/PULL_REQUEST_TEMPLATE/config.yml
vendored
1
.github/PULL_REQUEST_TEMPLATE/config.yml
vendored
@@ -1 +1,2 @@
|
||||
blank_issues_enabled: false
|
||||
blank_pull_request_template_enabled: false
|
||||
|
||||
22
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
22
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration -->
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
## Screenshots (if appropriate):
|
||||
|
||||
|
||||
## Checklist:
|
||||
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have made corresponding changes to the documentation if applicable
|
||||
36
.github/pull_request_template.md
vendored
36
.github/pull_request_template.md
vendored
@@ -1,36 +0,0 @@
|
||||
## Description
|
||||
|
||||
<!--- Describe your changes in detail -->
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration -->
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
<details><summary><h2>Screenshots (if appropriate)</h2></summary>
|
||||
|
||||
<!-- Images go below this line. -->
|
||||
|
||||
</details>
|
||||
|
||||
<!-- API endpoint changes (if relevant)
|
||||
## API Changes
|
||||
The `/api/something` endpoint is now `/api/something-else`
|
||||
-->
|
||||
|
||||
## Checklist:
|
||||
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have made corresponding changes to the documentation if applicable
|
||||
- [ ] I have no unrelated changes in the PR.
|
||||
- [ ] I have confirmed that any new dependencies are strictly necessary.
|
||||
- [ ] I have written tests for new code (if applicable)
|
||||
- [ ] I have followed naming conventions/patterns in the surrounding code
|
||||
- [ ] All code in `src/services` uses repositories implementations for database calls, filesystem operations, etc.
|
||||
- [ ] All code in `src/repositories/` is pretty basic/simple and does not have any immich specific logic (that belongs in `src/services`)
|
||||
6
.github/workflows/cli.yml
vendored
6
.github/workflows/cli.yml
vendored
@@ -56,10 +56,10 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3.4.0
|
||||
uses: docker/setup-qemu-action@v3.3.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.9.0
|
||||
uses: docker/setup-buildx-action@v3.8.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6.13.0
|
||||
uses: docker/build-push-action@v6.12.0
|
||||
with:
|
||||
file: cli/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
135
.github/workflows/docker.yml
vendored
135
.github/workflows/docker.yml
vendored
@@ -87,6 +87,7 @@ jobs:
|
||||
TAG_NEW=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_NEW $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||
|
||||
|
||||
build_and_push_ml:
|
||||
name: Build and Push ML
|
||||
needs: pre-job
|
||||
@@ -121,10 +122,10 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3.4.0
|
||||
uses: docker/setup-qemu-action@v3.3.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3.9.0
|
||||
uses: docker/setup-buildx-action@v3.8.0
|
||||
|
||||
- name: Login to Docker Hub
|
||||
# Only push to Docker Hub when making a release
|
||||
@@ -173,7 +174,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6.13.0
|
||||
uses: docker/build-push-action@v6.12.0
|
||||
with:
|
||||
context: ${{ env.context }}
|
||||
file: ${{ env.file }}
|
||||
@@ -194,38 +195,33 @@ jobs:
|
||||
|
||||
build_and_push_server:
|
||||
name: Build and Push Server
|
||||
runs-on: ${{ matrix.runner }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre-job
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
||||
env:
|
||||
image: immich-server
|
||||
context: .
|
||||
file: server/Dockerfile
|
||||
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-server
|
||||
DOCKER_REPO: altran1502/immich-server
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
runner: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
- platforms: linux/amd64,linux/arm64
|
||||
device: cpu
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3.3.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v3.8.0
|
||||
|
||||
- name: Login to Docker Hub
|
||||
# Only push to Docker Hub when making a release
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
uses: docker/login-action@v3
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -239,81 +235,16 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
uses: docker/build-push-action@v6.13.0
|
||||
with:
|
||||
context: ${{ env.context }}
|
||||
file: ${{ env.file }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
# Skip pushing when PR from a fork
|
||||
push: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
outputs: type=image,"name=${{ env.GHCR_REPO }},${{ env.DOCKER_REPO }}",push-by-digest=true,name-canonical=true,push=true
|
||||
build-args: |
|
||||
DEVICE=cpu
|
||||
BUILD_ID=${{ github.run_id }}
|
||||
BUILD_IMAGE=${{ github.event_name == 'release' && github.ref_name || steps.metadata.outputs.tags }}
|
||||
BUILD_SOURCE_REF=${{ github.ref_name }}
|
||||
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p ${{ runner.temp }}/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge_server:
|
||||
name: Merge & Push Server
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' && !github.event.pull_request.head.repo.fork }}
|
||||
env:
|
||||
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-server
|
||||
DOCKER_REPO: altran1502/immich-server
|
||||
needs:
|
||||
- build_and_push_server
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Generate docker image tags
|
||||
id: meta
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
flavor: |
|
||||
# Disable latest tag
|
||||
latest=false
|
||||
images: |
|
||||
name=${{ env.GHCR_REPO }}
|
||||
name=${{ env.DOCKER_REPO }},enable=${{ github.event_name == 'release' }}
|
||||
name=ghcr.io/${{ github.repository_owner }}/${{env.image}}
|
||||
name=altran1502/${{env.image}},enable=${{ github.event_name == 'release' }}
|
||||
tags: |
|
||||
# Tag with branch name
|
||||
type=ref,event=branch,suffix=${{ matrix.suffix }}
|
||||
@@ -323,16 +254,38 @@ jobs:
|
||||
type=ref,event=tag,suffix=${{ matrix.suffix }}
|
||||
type=raw,value=release,enable=${{ github.event_name == 'release' }},suffix=${{ matrix.suffix }}
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: ${{ runner.temp }}/digests
|
||||
- name: Determine build cache output
|
||||
id: cache-target
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *) \
|
||||
$(printf '${{ env.DOCKER_REPO }}@sha256:%s ' *)
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
# Essentially just ignore the cache output (PR can't write to registry cache)
|
||||
echo "cache-to=type=local,dest=/tmp/discard,ignore-error=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "cache-to=type=registry,mode=max,ref=ghcr.io/${{ github.repository_owner }}/immich-build-cache:${{ env.image }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6.12.0
|
||||
with:
|
||||
context: ${{ env.context }}
|
||||
file: ${{ env.file }}
|
||||
platforms: ${{ matrix.platforms }}
|
||||
# Skip pushing when PR from a fork
|
||||
push: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/immich-build-cache:${{env.image}}
|
||||
cache-to: ${{ steps.cache-target.outputs.cache-to }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
||||
build-args: |
|
||||
DEVICE=${{ matrix.device }}
|
||||
BUILD_ID=${{ github.run_id }}
|
||||
BUILD_IMAGE=${{ github.event_name == 'release' && github.ref_name || steps.metadata.outputs.tags }}
|
||||
BUILD_SOURCE_REF=${{ github.ref_name }}
|
||||
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
||||
|
||||
success-check-server:
|
||||
name: Docker Build & Push Server Success
|
||||
needs: [merge_server, retag_server]
|
||||
needs: [build_and_push_server, retag_server]
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
steps:
|
||||
|
||||
17
.github/workflows/preview-comment.yaml
vendored
17
.github/workflows/preview-comment.yaml
vendored
@@ -1,17 +0,0 @@
|
||||
name: Preview comment
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
comment-status:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.label.name == 'preview' }}
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: mshick/add-pr-comment@v2
|
||||
with:
|
||||
message-id: "preview-status"
|
||||
message: "Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/"
|
||||
268
cli/package-lock.json
generated
268
cli/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.50",
|
||||
"version": "2.2.47",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.50",
|
||||
"version": "2.2.47",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"fast-glob": "^3.3.2",
|
||||
@@ -24,7 +24,7 @@
|
||||
"@types/cli-progress": "^3.11.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/node": "^22.10.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||
"@typescript-eslint/parser": "^8.15.0",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
@@ -52,14 +52,14 @@
|
||||
},
|
||||
"../open-api/typescript-sdk": {
|
||||
"name": "@immich/sdk",
|
||||
"version": "1.126.1",
|
||||
"version": "1.125.6",
|
||||
"dev": true,
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"dependencies": {
|
||||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/node": "^22.10.9",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
@@ -881,9 +881,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
|
||||
"integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz",
|
||||
"integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -1482,9 +1482,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
|
||||
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
|
||||
"version": "22.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1498,21 +1498,21 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz",
|
||||
"integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz",
|
||||
"integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "8.23.0",
|
||||
"@typescript-eslint/type-utils": "8.23.0",
|
||||
"@typescript-eslint/utils": "8.23.0",
|
||||
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||
"@typescript-eslint/scope-manager": "8.20.0",
|
||||
"@typescript-eslint/type-utils": "8.20.0",
|
||||
"@typescript-eslint/utils": "8.20.0",
|
||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.3.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"ts-api-utils": "^2.0.1"
|
||||
"ts-api-utils": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1528,16 +1528,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz",
|
||||
"integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz",
|
||||
"integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.23.0",
|
||||
"@typescript-eslint/types": "8.23.0",
|
||||
"@typescript-eslint/typescript-estree": "8.23.0",
|
||||
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||
"@typescript-eslint/scope-manager": "8.20.0",
|
||||
"@typescript-eslint/types": "8.20.0",
|
||||
"@typescript-eslint/typescript-estree": "8.20.0",
|
||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1553,14 +1553,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz",
|
||||
"integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz",
|
||||
"integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.23.0",
|
||||
"@typescript-eslint/visitor-keys": "8.23.0"
|
||||
"@typescript-eslint/types": "8.20.0",
|
||||
"@typescript-eslint/visitor-keys": "8.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1571,16 +1571,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz",
|
||||
"integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz",
|
||||
"integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "8.23.0",
|
||||
"@typescript-eslint/utils": "8.23.0",
|
||||
"@typescript-eslint/typescript-estree": "8.20.0",
|
||||
"@typescript-eslint/utils": "8.20.0",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^2.0.1"
|
||||
"ts-api-utils": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1595,9 +1595,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz",
|
||||
"integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz",
|
||||
"integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -1609,20 +1609,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz",
|
||||
"integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz",
|
||||
"integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.23.0",
|
||||
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||
"@typescript-eslint/types": "8.20.0",
|
||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
||||
"debug": "^4.3.4",
|
||||
"fast-glob": "^3.3.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^2.0.1"
|
||||
"ts-api-utils": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1636,16 +1636,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz",
|
||||
"integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz",
|
||||
"integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@typescript-eslint/scope-manager": "8.23.0",
|
||||
"@typescript-eslint/types": "8.23.0",
|
||||
"@typescript-eslint/typescript-estree": "8.23.0"
|
||||
"@typescript-eslint/scope-manager": "8.20.0",
|
||||
"@typescript-eslint/types": "8.20.0",
|
||||
"@typescript-eslint/typescript-estree": "8.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -1660,13 +1660,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz",
|
||||
"integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==",
|
||||
"version": "8.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz",
|
||||
"integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.23.0",
|
||||
"@typescript-eslint/types": "8.20.0",
|
||||
"eslint-visitor-keys": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1691,9 +1691,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.5.tgz",
|
||||
"integrity": "sha512-zOOWIsj5fHh3jjGwQg+P+J1FW3s4jBu1Zqga0qW60yutsBtqEqNEJKWYh7cYn1yGD+1bdPsPdC/eL4eVK56xMg==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.3.tgz",
|
||||
"integrity": "sha512-uVbJ/xhImdNtzPnLyxCZJMTeTIYdgcC2nWtBBBpR1H6z0w8m7D+9/zrDIx2nNxgMg9r+X8+RY2qVpUDeW2b3nw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1714,8 +1714,8 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitest/browser": "3.0.5",
|
||||
"vitest": "3.0.5"
|
||||
"@vitest/browser": "3.0.3",
|
||||
"vitest": "3.0.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vitest/browser": {
|
||||
@@ -1724,14 +1724,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz",
|
||||
"integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.3.tgz",
|
||||
"integrity": "sha512-SbRCHU4qr91xguu+dH3RUdI5dC86zm8aZWydbp961aIR7G8OYNN6ZiayFuf9WAngRbFOfdrLHCGgXTj3GtoMRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "3.0.5",
|
||||
"@vitest/utils": "3.0.5",
|
||||
"@vitest/spy": "3.0.3",
|
||||
"@vitest/utils": "3.0.3",
|
||||
"chai": "^5.1.2",
|
||||
"tinyrainbow": "^2.0.0"
|
||||
},
|
||||
@@ -1740,13 +1740,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz",
|
||||
"integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.3.tgz",
|
||||
"integrity": "sha512-XT2XBc4AN9UdaxJAeIlcSZ0ILi/GzmG5G8XSly4gaiqIvPV3HMTSIDZWJVX6QRJ0PX1m+W8Cy0K9ByXNb/bPIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "3.0.5",
|
||||
"@vitest/spy": "3.0.3",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.17"
|
||||
},
|
||||
@@ -1767,9 +1767,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz",
|
||||
"integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.3.tgz",
|
||||
"integrity": "sha512-gCrM9F7STYdsDoNjGgYXKPq4SkSxwwIU5nkaQvdUxiQ0EcNlez+PdKOVIsUJvh9P9IeIFmjn4IIREWblOBpP2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1780,38 +1780,38 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz",
|
||||
"integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.3.tgz",
|
||||
"integrity": "sha512-Rgi2kOAk5ZxWZlwPguRJFOBmWs6uvvyAAR9k3MvjRvYrG7xYvKChZcmnnpJCS98311CBDMqsW9MzzRFsj2gX3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/utils": "3.0.5",
|
||||
"pathe": "^2.0.2"
|
||||
"@vitest/utils": "3.0.3",
|
||||
"pathe": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz",
|
||||
"integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.3.tgz",
|
||||
"integrity": "sha512-kNRcHlI4txBGztuJfPEJ68VezlPAXLRT1u5UCx219TU3kOG2DplNxhWLwDf2h6emwmTPogzLnGVwP6epDaJN6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "3.0.5",
|
||||
"@vitest/pretty-format": "3.0.3",
|
||||
"magic-string": "^0.30.17",
|
||||
"pathe": "^2.0.2"
|
||||
"pathe": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz",
|
||||
"integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.3.tgz",
|
||||
"integrity": "sha512-7/dgux8ZBbF7lEIKNnEqQlyRaER9nkAL9eTmdKJkDO3hS8p59ATGwKOCUDHcBLKr7h/oi/6hP+7djQk8049T2A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1822,13 +1822,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz",
|
||||
"integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.3.tgz",
|
||||
"integrity": "sha512-f+s8CvyzPtMFY1eZKkIHGhPsQgYo5qCm6O8KZoim9qm1/jT64qBgGpO5tHscNH6BzRHM+edLNOP+3vO8+8pE/A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "3.0.5",
|
||||
"@vitest/pretty-format": "3.0.3",
|
||||
"loupe": "^3.1.2",
|
||||
"tinyrainbow": "^2.0.0"
|
||||
},
|
||||
@@ -2334,9 +2334,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.19.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz",
|
||||
"integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==",
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz",
|
||||
"integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2345,7 +2345,7 @@
|
||||
"@eslint/config-array": "^0.19.0",
|
||||
"@eslint/core": "^0.10.0",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@eslint/js": "9.19.0",
|
||||
"@eslint/js": "9.18.0",
|
||||
"@eslint/plugin-kit": "^0.2.5",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
@@ -2407,9 +2407,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-prettier": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz",
|
||||
"integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.2.tgz",
|
||||
"integrity": "sha512-1yI3/hf35wmlq66C8yOyrujQnel+v5l1Vop5Cl2I6ylyNTT1JbuUUnV3/41PzwTzcyDp/oF0jWE3HXvcH5AQOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2685,9 +2685,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
|
||||
"integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
|
||||
"integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
@@ -3180,9 +3180,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/loupe": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
|
||||
"integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
|
||||
"integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -3285,9 +3285,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mock-fs": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.5.0.tgz",
|
||||
"integrity": "sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==",
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.4.1.tgz",
|
||||
"integrity": "sha512-sz/Q8K1gXXXHR+qr0GZg2ysxCRr323kuN10O7CtQjraJsFDJ4SJ+0I5MzALz7aRp9lHk8Cc/YdsT95h9Ka1aFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -4166,9 +4166,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
|
||||
"integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -4288,15 +4288,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
|
||||
"integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
|
||||
"version": "6.0.11",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
|
||||
"integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.24.2",
|
||||
"postcss": "^8.5.1",
|
||||
"rollup": "^4.30.1"
|
||||
"postcss": "^8.4.49",
|
||||
"rollup": "^4.23.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
@@ -4360,16 +4360,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-node": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz",
|
||||
"integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.3.tgz",
|
||||
"integrity": "sha512-0sQcwhwAEw/UJGojbhOrnq3HtiZ3tC7BzpAa0lx3QaTX0S3YX70iGcik25UBdB96pmdwjyY2uyKNYruxCDmiEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cac": "^6.7.14",
|
||||
"debug": "^4.4.0",
|
||||
"es-module-lexer": "^1.6.0",
|
||||
"pathe": "^2.0.2",
|
||||
"pathe": "^2.0.1",
|
||||
"vite": "^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -4403,31 +4403,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",
|
||||
"integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.3.tgz",
|
||||
"integrity": "sha512-dWdwTFUW9rcnL0LyF2F+IfvNQWB0w9DERySCk8VMG75F8k25C7LsZoh6XfCjPvcR8Nb+Lqi9JKr6vnzH7HSrpQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/expect": "3.0.5",
|
||||
"@vitest/mocker": "3.0.5",
|
||||
"@vitest/pretty-format": "^3.0.5",
|
||||
"@vitest/runner": "3.0.5",
|
||||
"@vitest/snapshot": "3.0.5",
|
||||
"@vitest/spy": "3.0.5",
|
||||
"@vitest/utils": "3.0.5",
|
||||
"@vitest/expect": "3.0.3",
|
||||
"@vitest/mocker": "3.0.3",
|
||||
"@vitest/pretty-format": "^3.0.3",
|
||||
"@vitest/runner": "3.0.3",
|
||||
"@vitest/snapshot": "3.0.3",
|
||||
"@vitest/spy": "3.0.3",
|
||||
"@vitest/utils": "3.0.3",
|
||||
"chai": "^5.1.2",
|
||||
"debug": "^4.4.0",
|
||||
"expect-type": "^1.1.0",
|
||||
"magic-string": "^0.30.17",
|
||||
"pathe": "^2.0.2",
|
||||
"pathe": "^2.0.1",
|
||||
"std-env": "^3.8.0",
|
||||
"tinybench": "^2.9.0",
|
||||
"tinyexec": "^0.3.2",
|
||||
"tinypool": "^1.0.2",
|
||||
"tinyrainbow": "^2.0.0",
|
||||
"vite": "^5.0.0 || ^6.0.0",
|
||||
"vite-node": "3.0.5",
|
||||
"vite-node": "3.0.3",
|
||||
"why-is-node-running": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -4441,10 +4441,9 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edge-runtime/vm": "*",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
||||
"@vitest/browser": "3.0.5",
|
||||
"@vitest/ui": "3.0.5",
|
||||
"@vitest/browser": "3.0.3",
|
||||
"@vitest/ui": "3.0.3",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
},
|
||||
@@ -4452,9 +4451,6 @@
|
||||
"@edge-runtime/vm": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/debug": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.2.50",
|
||||
"version": "2.2.47",
|
||||
"description": "Command Line Interface (CLI) for Immich",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
@@ -20,7 +20,7 @@
|
||||
"@types/cli-progress": "^3.11.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mock-fs": "^4.13.1",
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/node": "^22.10.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||
"@typescript-eslint/parser": "^8.15.0",
|
||||
"@vitest/coverage-v8": "^3.0.0",
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "4.52.0"
|
||||
constraints = "4.52.0"
|
||||
version = "4.50.0"
|
||||
constraints = "4.50.0"
|
||||
hashes = [
|
||||
"h1:2BEJyXJtYC4B4nda/WCYUmuJYDaYk88F8t1pwPzr0iQ=",
|
||||
"h1:4IASk5SESeWKQ7JU0+M7KApuF5mZyklvwMXPBabim3c=",
|
||||
"h1:5ImZxxALSnWfH/4EXw/wFirSmk5Tr0ACmcysy51AafE=",
|
||||
"h1:6TJ3dxLSin4ZKBJLsZDn95H2ZYnGm8S7GGHvvXuuMQU=",
|
||||
"h1:IzTUjg9kQ4N3qizP9CjYLeHwjsuGgtxwXvfUQWyOLcA=",
|
||||
"h1:NTaOQfYINA0YTG/V1/9+SYtgX1it63+cBugj4WK4FWc=",
|
||||
"h1:PXH48LuJn329sCfMXprdMDk51EZaWFyajVvS03qhQLs=",
|
||||
"h1:Pi5M+GeoMSN2eJ6QnIeXjBf19O+rby/74CfB2ocpv20=",
|
||||
"h1:ShXZ2ZjBvm3thfoPPzPT8+OhyismnydQVkUAfI8X12w=",
|
||||
"h1:WQ9hu0Wge2msBbODfottCSKgu8oKUrw4Opz+fDPVVHk=",
|
||||
"h1:Z5yXML2DE0uH9UU+M0ut9JMQAORcwVZz1CxBHzeBmao=",
|
||||
"h1:jqI2qKknpleS3JDSplyGYHMu0u9K/tor1ZOjFwDgEMk=",
|
||||
"h1:kgfutDh14Q5nw4eg6qGFamFxIiY8Ae0FPKRBLDOzpcI=",
|
||||
"h1:zCAO7GZmfYhWb+i6TfqlqhMeDyPZWGio2IzEzAh3YTs=",
|
||||
"zh:19be1a91c982b902c42aba47766860dfa5dc151eed1e95fd39ca642229381ef0",
|
||||
"zh:1de451c4d1ecf7efbe67b6dace3426ba810711afdd644b0f1b870364c8ae91f8",
|
||||
"zh:352b4a2120173298622e669258744554339d959ac3a95607b117a48ee4a83238",
|
||||
"zh:3c6f1346d9154afbd2d558fabb4b0150fc8d559aa961254144fe1bc17fe6032f",
|
||||
"zh:4c4c92d53fb535b1e0eff26f222bbd627b97d3b4c891ec9c321268676d06152f",
|
||||
"zh:53276f68006c9ceb7cdb10a6ccf91a5c1eadd1407a28edb5741e84e88d7e29e8",
|
||||
"zh:7925a97773948171a63d4f65bb81ee92fd6d07a447e36012977313293a5435c9",
|
||||
"zh:7dfb0a4496cfe032437386d0a2cd9229a1956e9c30bd920923c141b0f0440060",
|
||||
"h1:0qvD5ZKn2tMZ8cOjQrUSITIC9tKCZbrSaSswV9lOyiU=",
|
||||
"h1:4N0gplrZ0zOsJv3Kx1VfIx2FwrZHbYU0Un2yfiLZIGQ=",
|
||||
"h1:81AMQq4kNKU/35U8ElQegUxG4E6xB0erIjG5xVmjIyo=",
|
||||
"h1:EEQNADUmV3IL6x00yzy04i7OCSLeOMgM9XQkV3w71gA=",
|
||||
"h1:HD0KI7td6oiSSAnJNn8UPSGf+hKiTo4JVQYfAiU1SqM=",
|
||||
"h1:Hl+o5LtcvZg2f3l1hh9vaG/DFK6k+dTIZSeM0lXyfpo=",
|
||||
"h1:ZUO2oIJ6jtZdvl816h0cEIiIeZ/fFCF64+abGEVxZZM=",
|
||||
"h1:Zio80fnEeUKdlSOhTVskMEFSLUQ6TMsMKnXc+Dy2P2A=",
|
||||
"h1:aLLvg36evTyqjtXGV2MjAV8imktXFmry7p/xCu9GQC4=",
|
||||
"h1:azL05eWyy2V8SWkbZZImPWvv8ynG4eqmrbZhjXBDFug=",
|
||||
"h1:ckMysHY4fJmr7o58XMi+DdgOTB/U/Mf1u1JA9ly3g/I=",
|
||||
"h1:jxOwjDNjt5WCb4YjjiMsman91O8Y+MAPz6UwJ4a6F+0=",
|
||||
"h1:u4OfnjSLa4Wk1IUFAzrvMnGgr8MvRHEWVDHEScPK2E8=",
|
||||
"h1:wQkR1oeSkzlHn3rnVuLJRJLBHlg4EHt7Y64DeTjfkjQ=",
|
||||
"zh:0ef99ed39472a94e6a0d6fa733cf0a46bce3bf66eba2873efae8846efdddc237",
|
||||
"zh:2929cbbffcead171d45c88e4a7a59e9c013ea775dafa68b10da8db7cd04b6140",
|
||||
"zh:462601c87118088e1a718842e367af7d8e7620598d426980a6d6b33de759865e",
|
||||
"zh:56766eb62a74a9d88d9efb8486dd3a0c5c9db873d0a980ae9ef1e8af27d74231",
|
||||
"zh:6b4e8810d99498a5a20a5872982a0f1354e79cfc4a7dfe7cc656f1c7eaae47d8",
|
||||
"zh:6d65bdb4ec94b6eecc8abe26d94e2ca09262dc1e7a9934db829f418be0119920",
|
||||
"zh:71adeaf31e41a358ec6095004062e43f56ee7d4b2504e5613ab351d511695641",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:8d4aa79f0a414bb4163d771063c70cd991c8fac6c766e685bac2ee12903c5bd6",
|
||||
"zh:a67540c13565616a7e7e51ee9366e88b0dc60046e1d75c72680e150bd02725bb",
|
||||
"zh:a936383a4767f5393f38f622e92bf2d0c03fe04b69c284951f27345766c7b31b",
|
||||
"zh:d4887d73c466ff036eecf50ad6404ba38fd82ea4855296b1846d244b0f13c380",
|
||||
"zh:e9093c8bd5b6cd99c81666e315197791781b8f93afa14fc2e0f732d1bb2a44b7",
|
||||
"zh:efd3b3f1ec59a37f635aa1d4efcf178734c2fcf8ddb0d56ea690bec342da8672",
|
||||
"zh:89761c15908ccc2cf9c50bb5cb3be45d3ad0c45fc7c608c6b95f48c0288b7160",
|
||||
"zh:8cc5d7c5939da89cfd01f3e51c84f3576564783acea9db86bd9e32049805ed96",
|
||||
"zh:987cff8225b1dd436cdcb4fc6228689ae7e4281de6896412a2a9a3325c49f05e",
|
||||
"zh:991e83ebb89867d71e01a1c215ed159efb425683b0a44707be8579eb0a337f06",
|
||||
"zh:ab8177ae2d8f5cfa90043a6f867435012cae115f6061b832a7e2462e0ae87a67",
|
||||
"zh:d1ca34df1398f201274a6a18102975148c10ca15aa43cfc56cc9897620929509",
|
||||
"zh:d34946f70201baf6dda03e3b294c6bbe40d95d0278e97b9f636ded94822b24ac",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "4.52.0"
|
||||
version = "4.50.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||
version = "4.52.0"
|
||||
constraints = "4.52.0"
|
||||
version = "4.50.0"
|
||||
constraints = "4.50.0"
|
||||
hashes = [
|
||||
"h1:2BEJyXJtYC4B4nda/WCYUmuJYDaYk88F8t1pwPzr0iQ=",
|
||||
"h1:4IASk5SESeWKQ7JU0+M7KApuF5mZyklvwMXPBabim3c=",
|
||||
"h1:5ImZxxALSnWfH/4EXw/wFirSmk5Tr0ACmcysy51AafE=",
|
||||
"h1:6TJ3dxLSin4ZKBJLsZDn95H2ZYnGm8S7GGHvvXuuMQU=",
|
||||
"h1:IzTUjg9kQ4N3qizP9CjYLeHwjsuGgtxwXvfUQWyOLcA=",
|
||||
"h1:NTaOQfYINA0YTG/V1/9+SYtgX1it63+cBugj4WK4FWc=",
|
||||
"h1:PXH48LuJn329sCfMXprdMDk51EZaWFyajVvS03qhQLs=",
|
||||
"h1:Pi5M+GeoMSN2eJ6QnIeXjBf19O+rby/74CfB2ocpv20=",
|
||||
"h1:ShXZ2ZjBvm3thfoPPzPT8+OhyismnydQVkUAfI8X12w=",
|
||||
"h1:WQ9hu0Wge2msBbODfottCSKgu8oKUrw4Opz+fDPVVHk=",
|
||||
"h1:Z5yXML2DE0uH9UU+M0ut9JMQAORcwVZz1CxBHzeBmao=",
|
||||
"h1:jqI2qKknpleS3JDSplyGYHMu0u9K/tor1ZOjFwDgEMk=",
|
||||
"h1:kgfutDh14Q5nw4eg6qGFamFxIiY8Ae0FPKRBLDOzpcI=",
|
||||
"h1:zCAO7GZmfYhWb+i6TfqlqhMeDyPZWGio2IzEzAh3YTs=",
|
||||
"zh:19be1a91c982b902c42aba47766860dfa5dc151eed1e95fd39ca642229381ef0",
|
||||
"zh:1de451c4d1ecf7efbe67b6dace3426ba810711afdd644b0f1b870364c8ae91f8",
|
||||
"zh:352b4a2120173298622e669258744554339d959ac3a95607b117a48ee4a83238",
|
||||
"zh:3c6f1346d9154afbd2d558fabb4b0150fc8d559aa961254144fe1bc17fe6032f",
|
||||
"zh:4c4c92d53fb535b1e0eff26f222bbd627b97d3b4c891ec9c321268676d06152f",
|
||||
"zh:53276f68006c9ceb7cdb10a6ccf91a5c1eadd1407a28edb5741e84e88d7e29e8",
|
||||
"zh:7925a97773948171a63d4f65bb81ee92fd6d07a447e36012977313293a5435c9",
|
||||
"zh:7dfb0a4496cfe032437386d0a2cd9229a1956e9c30bd920923c141b0f0440060",
|
||||
"h1:0qvD5ZKn2tMZ8cOjQrUSITIC9tKCZbrSaSswV9lOyiU=",
|
||||
"h1:4N0gplrZ0zOsJv3Kx1VfIx2FwrZHbYU0Un2yfiLZIGQ=",
|
||||
"h1:81AMQq4kNKU/35U8ElQegUxG4E6xB0erIjG5xVmjIyo=",
|
||||
"h1:EEQNADUmV3IL6x00yzy04i7OCSLeOMgM9XQkV3w71gA=",
|
||||
"h1:HD0KI7td6oiSSAnJNn8UPSGf+hKiTo4JVQYfAiU1SqM=",
|
||||
"h1:Hl+o5LtcvZg2f3l1hh9vaG/DFK6k+dTIZSeM0lXyfpo=",
|
||||
"h1:ZUO2oIJ6jtZdvl816h0cEIiIeZ/fFCF64+abGEVxZZM=",
|
||||
"h1:Zio80fnEeUKdlSOhTVskMEFSLUQ6TMsMKnXc+Dy2P2A=",
|
||||
"h1:aLLvg36evTyqjtXGV2MjAV8imktXFmry7p/xCu9GQC4=",
|
||||
"h1:azL05eWyy2V8SWkbZZImPWvv8ynG4eqmrbZhjXBDFug=",
|
||||
"h1:ckMysHY4fJmr7o58XMi+DdgOTB/U/Mf1u1JA9ly3g/I=",
|
||||
"h1:jxOwjDNjt5WCb4YjjiMsman91O8Y+MAPz6UwJ4a6F+0=",
|
||||
"h1:u4OfnjSLa4Wk1IUFAzrvMnGgr8MvRHEWVDHEScPK2E8=",
|
||||
"h1:wQkR1oeSkzlHn3rnVuLJRJLBHlg4EHt7Y64DeTjfkjQ=",
|
||||
"zh:0ef99ed39472a94e6a0d6fa733cf0a46bce3bf66eba2873efae8846efdddc237",
|
||||
"zh:2929cbbffcead171d45c88e4a7a59e9c013ea775dafa68b10da8db7cd04b6140",
|
||||
"zh:462601c87118088e1a718842e367af7d8e7620598d426980a6d6b33de759865e",
|
||||
"zh:56766eb62a74a9d88d9efb8486dd3a0c5c9db873d0a980ae9ef1e8af27d74231",
|
||||
"zh:6b4e8810d99498a5a20a5872982a0f1354e79cfc4a7dfe7cc656f1c7eaae47d8",
|
||||
"zh:6d65bdb4ec94b6eecc8abe26d94e2ca09262dc1e7a9934db829f418be0119920",
|
||||
"zh:71adeaf31e41a358ec6095004062e43f56ee7d4b2504e5613ab351d511695641",
|
||||
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||
"zh:8d4aa79f0a414bb4163d771063c70cd991c8fac6c766e685bac2ee12903c5bd6",
|
||||
"zh:a67540c13565616a7e7e51ee9366e88b0dc60046e1d75c72680e150bd02725bb",
|
||||
"zh:a936383a4767f5393f38f622e92bf2d0c03fe04b69c284951f27345766c7b31b",
|
||||
"zh:d4887d73c466ff036eecf50ad6404ba38fd82ea4855296b1846d244b0f13c380",
|
||||
"zh:e9093c8bd5b6cd99c81666e315197791781b8f93afa14fc2e0f732d1bb2a44b7",
|
||||
"zh:efd3b3f1ec59a37f635aa1d4efcf178734c2fcf8ddb0d56ea690bec342da8672",
|
||||
"zh:89761c15908ccc2cf9c50bb5cb3be45d3ad0c45fc7c608c6b95f48c0288b7160",
|
||||
"zh:8cc5d7c5939da89cfd01f3e51c84f3576564783acea9db86bd9e32049805ed96",
|
||||
"zh:987cff8225b1dd436cdcb4fc6228689ae7e4281de6896412a2a9a3325c49f05e",
|
||||
"zh:991e83ebb89867d71e01a1c215ed159efb425683b0a44707be8579eb0a337f06",
|
||||
"zh:ab8177ae2d8f5cfa90043a6f867435012cae115f6061b832a7e2462e0ae87a67",
|
||||
"zh:d1ca34df1398f201274a6a18102975148c10ca15aa43cfc56cc9897620929509",
|
||||
"zh:d34946f70201baf6dda03e3b294c6bbe40d95d0278e97b9f636ded94822b24ac",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
version = "4.52.0"
|
||||
version = "4.50.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ services:
|
||||
command: ['./run.sh', '-disable-reporting']
|
||||
ports:
|
||||
- 3000:3000
|
||||
image: grafana/grafana:11.5.1-ubuntu@sha256:9a4ab78cec1a2ec7d1ca5dfd5aacec6412706a1bc9e971fc7184e2f6696a63f5
|
||||
image: grafana/grafana:11.4.0-ubuntu@sha256:afccec22ba0e4815cca1d2bf3836e414322390dc78d77f1851976ffa8d61051c
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ services:
|
||||
vaapi-wsl: # use this for VAAPI if you're running Immich in WSL2
|
||||
devices:
|
||||
- /dev/dri:/dev/dri
|
||||
- /dev/dxg:/dev/dxg
|
||||
volumes:
|
||||
- /usr/lib/wsl:/usr/lib/wsl
|
||||
environment:
|
||||
|
||||
@@ -77,7 +77,9 @@ docker start immich_postgres # Start Postgres server
|
||||
sleep 10 # Wait for Postgres server to start up
|
||||
docker exec -it immich_postgres bash # Enter the Docker shell and run the following command
|
||||
# Check the database user if you deviated from the default. If your backup ends in `.gz`, replace `cat` with `gunzip`
|
||||
cat < "/dump.sql" | sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" | psql --dbname=postgres --username=<DB_USERNAME>
|
||||
cat < "/dump.sql" \
|
||||
| sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
|
||||
| psql --dbname=postgres --username=<DB_USERNAME> # Restore Backup
|
||||
exit # Exit the Docker shell
|
||||
docker compose up -d # Start remainder of Immich apps
|
||||
```
|
||||
|
||||
@@ -50,18 +50,19 @@ The Immich CLI is an [npm](https://www.npmjs.com/) package that lets users contr
|
||||
|
||||
The Immich backend is divided into several services, which are run as individual docker containers.
|
||||
|
||||
1. `immich-server` - Handle and respond to REST API requests, execute background jobs (thumbnail generation, metadata extraction, transcoding, etc.)
|
||||
1. `immich-server` - Handle and respond to REST API requests
|
||||
1. `immich-microservices` - Execute background jobs (thumbnail generation, metadata extraction, transcoding, etc.)
|
||||
1. `immich-machine-learning` - Execute machine learning models
|
||||
1. `postgres` - Persistent data storage
|
||||
1. `redis`- Queue management for background jobs
|
||||
1. `redis`- Queue management for `immich-microservices`
|
||||
|
||||
### Immich Server
|
||||
|
||||
The Immich Server is a [TypeScript](https://www.typescriptlang.org/) project written for [Node.js](https://nodejs.org/). It uses the [Nest.js](https://nestjs.com) framework, [Express](https://expressjs.com/) server, and the query builder [Kysely](https://kysely.dev/). The server codebase also loosely follows the [Hexagonal Architecture](<https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)>). Specifically, we aim to separate technology specific implementations (`src/repositories`) from core business logic (`src/services`).
|
||||
The Immich Server is a [TypeScript](https://www.typescriptlang.org/) project written for [Node.js](https://nodejs.org/). It uses the [Nest.js](https://nestjs.com) framework, with [TypeORM](https://typeorm.io/) for database management. The server codebase also loosely follows the [Hexagonal Architecture](<https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)>). Specifically, we aim to separate technology specific implementations (`infra/`) from core business logic (`domain/`).
|
||||
|
||||
### API Endpoints
|
||||
#### REST Endpoints
|
||||
|
||||
An incoming HTTP request is mapped to a controller (`src/controllers`). Controllers are collections of HTTP endpoints. Each controller usually implements the following CRUD operations for its respective resource type:
|
||||
The server is a list of HTTP endpoints and associated handlers (controllers). Each controller usually implements the following CRUD operations:
|
||||
|
||||
- `POST` `/<type>` - **Create**
|
||||
- `GET` `/<type>` - **Read** (all)
|
||||
@@ -69,13 +70,13 @@ An incoming HTTP request is mapped to a controller (`src/controllers`). Controll
|
||||
- `PUT` `/<type>/:id` - **Updated** (by id)
|
||||
- `DELETE` `/<type>/:id` - **Delete** (by id)
|
||||
|
||||
### Domain Transfer Objects (DTOs)
|
||||
#### DTOs
|
||||
|
||||
The server uses [Domain Transfer Objects](https://en.wikipedia.org/wiki/Data_transfer_object) as public interfaces for the inputs (query, params, and body) and outputs (response) for each endpoint. DTOs translate to [OpenAPI](./open-api.md) schemas and control the generated code used by each client.
|
||||
|
||||
### Background Jobs
|
||||
### Microservices
|
||||
|
||||
Immich uses a [worker](https://github.com/immich-app/immich/blob/main/server/src/utils/misc.ts#L266) to run background jobs. These jobs include:
|
||||
The Immich Microservices image uses the same `Dockerfile` as the Immich Server, but with a different entrypoint. The Immich Microservices service mainly handles executing jobs, which include the following:
|
||||
|
||||
- Thumbnail Generation
|
||||
- Metadata Extraction
|
||||
|
||||
@@ -76,7 +76,7 @@ To see local changes to `@immich/ui` in Immich, do the following:
|
||||
|
||||
### Mobile app
|
||||
|
||||
The mobile app `(/mobile)` will required Flutter toolchain 3.13.x and FVM to be installed on your system.
|
||||
The mobile app `(/mobile)` will required Flutter toolchain 3.13.x to be installed on your system.
|
||||
|
||||
Please refer to the [Flutter's official documentation](https://flutter.dev/docs/get-started/install) for more information on setting up the toolchain on your machine.
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ If your photos are on a network drive, automatic file watching likely won't work
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
If you encounter an `ENOSPC` error, you need to increase your file watcher limit. In sysctl, this key is called `fs.inotify.max_user_watches` and has a default value of 8192. Increase this number to a suitable value greater than the number of files you will be watching. Note that Immich has to watch all files in your import paths including any ignored files.
|
||||
If you encounter an `ENOSPC` error, you need to increase your file watcher limit. In sysctl, this key is called `fs.inotify.max_user_watched` and has a default value of 8192. Increase this number to a suitable value greater than the number of files you will be watching. Note that Immich has to watch all files in your import paths including any ignored files.
|
||||
|
||||
```
|
||||
ERROR [LibraryService] Library watcher for library c69faf55-f96d-4aa0-b83b-2d80cbc27d98 encountered error: Error: ENOSPC: System limit for number of file watchers reached, watch '/media/photo.jpg'
|
||||
|
||||
@@ -11,7 +11,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
||||
|
||||
- ARM NN (Mali)
|
||||
- CUDA (NVIDIA GPUs with [compute capability](https://developer.nvidia.com/cuda-gpus) 5.2 or higher)
|
||||
- OpenVINO (Intel GPUs such as Iris Xe and Arc)
|
||||
- OpenVINO (Intel discrete GPUs such as Iris Xe and Arc)
|
||||
|
||||
## Limitations
|
||||
|
||||
@@ -43,9 +43,8 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
||||
|
||||
#### OpenVINO
|
||||
|
||||
- Integrated GPUs are more likely to experience issues than discrete GPUs, especially for older processors or servers with low RAM.
|
||||
- The server must have a discrete GPU, i.e. Iris Xe or Arc. Expect issues when attempting to use integrated graphics.
|
||||
- Ensure the server's kernel version is new enough to use the device for hardware accceleration.
|
||||
- Expect higher RAM usage when using OpenVINO compared to CPU processing.
|
||||
|
||||
## Setup
|
||||
|
||||
|
||||
@@ -8,23 +8,22 @@ For the full list, refer to the [Immich source code](https://github.com/immich-a
|
||||
|
||||
## Image formats
|
||||
|
||||
| Format | Extension(s) | Supported? | Notes |
|
||||
| :---------- | :---------------------------- | :----------------: | :-------------- |
|
||||
| `AVIF` | `.avif` | :white_check_mark: | |
|
||||
| `BMP` | `.bmp` | :white_check_mark: | |
|
||||
| `GIF` | `.gif` | :white_check_mark: | |
|
||||
| `HEIC` | `.heic` | :white_check_mark: | |
|
||||
| `HEIF` | `.heif` | :white_check_mark: | |
|
||||
| `JPEG 2000` | `.jp2` | :white_check_mark: | |
|
||||
| `JPEG` | `.webp` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
||||
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
||||
| `PNG` | `.webp` | :white_check_mark: | |
|
||||
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
||||
| `RAW` | `.raw` | :white_check_mark: | |
|
||||
| `RW2` | `.rw2` | :white_check_mark: | |
|
||||
| `SVG` | `.svg` | :white_check_mark: | |
|
||||
| `TIFF` | `.tif` `.tiff` | :white_check_mark: | |
|
||||
| `WEBP` | `.webp` | :white_check_mark: | |
|
||||
| Format | Extension(s) | Supported? | Notes |
|
||||
| :-------- | :---------------------------- | :----------------: | :-------------- |
|
||||
| `AVIF` | `.avif` | :white_check_mark: | |
|
||||
| `BMP` | `.bmp` | :white_check_mark: | |
|
||||
| `GIF` | `.gif` | :white_check_mark: | |
|
||||
| `HEIC` | `.heic` | :white_check_mark: | |
|
||||
| `HEIF` | `.heif` | :white_check_mark: | |
|
||||
| `JPEG` | `.webp` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
||||
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
||||
| `PNG` | `.webp` | :white_check_mark: | |
|
||||
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
||||
| `RAW` | `.raw` | :white_check_mark: | |
|
||||
| `RW2` | `.rw2` | :white_check_mark: | |
|
||||
| `SVG` | `.svg` | :white_check_mark: | |
|
||||
| `TIFF` | `.tif` `.tiff` | :white_check_mark: | |
|
||||
| `WEBP` | `.webp` | :white_check_mark: | |
|
||||
|
||||
## Video formats
|
||||
|
||||
|
||||
@@ -27,10 +27,6 @@ SELECT * FROM "assets" WHERE "originalPath" = 'upload/library/admin/2023/2023-09
|
||||
SELECT * FROM "assets" WHERE "originalPath" LIKE 'upload/library/admin/2023/%';
|
||||
```
|
||||
|
||||
```sql title="Find by ID"
|
||||
SELECT * FROM "assets" WHERE "id" = '9f94e60f-65b6-47b7-ae44-a4df7b57f0e9';
|
||||
```
|
||||
|
||||
:::note
|
||||
You can calculate the checksum for a particular file by using the command `sha1sum <filename>`.
|
||||
:::
|
||||
|
||||
@@ -41,7 +41,7 @@ className="border rounded-xl"
|
||||
:::info Permissions
|
||||
The **pgData** dataset must be owned by the user `netdata` (UID 999) for postgres to start. The other datasets must be owned by the user `root` (UID 0) or a group that includes the user `root` (UID 0) for immich to have the necessary permissions.
|
||||
|
||||
If the **library** dataset uses ACL it must have [ACL mode](https://www.truenas.com/docs/core/coretutorials/storage/pools/permissions/#access-control-lists) set to `Passthrough` if you plan on using a [storage template](/docs/administration/storage-template.mdx) and the dataset is configured for network sharing (its ACL type is set to `SMB/NFSv4`). When the template is applied and files need to be moved from **upload** to **library**, Immich performs `chmod` internally and needs to be allowed to execute the command. [More info.](https://github.com/immich-app/immich/pull/13017)
|
||||
If the **library** dataset uses ACL it must have [ACL mode](https://www.truenas.com/docs/core/coretutorials/storage/pools/permissions/#access-control-lists) set to `Passthrough` if you plan on using a [storage template](/docs/administration/storage-template.mdx) and the dataset is configured for network sharing (its ACL type is set to `SMB/NFSv4`). When the template is applied and files need to be moved from **upload** to **library**, immich performs `chmod` internally and needs to be allowed to execute the command. [More info.](https://github.com/immich-app/immich/pull/13017)
|
||||
:::
|
||||
|
||||
## Installing the Immich Application
|
||||
@@ -160,10 +160,6 @@ The image above has example values.
|
||||
|
||||
### Additional Storage [(External Libraries)](/docs/features/libraries)
|
||||
|
||||
:::danger Advanced Users Only
|
||||
This feature should only be used by advanced users. If this is your first time installing Immich, then DO NOT mount an external library until you have a working setup. Also, your mount path MUST be something unique and should NOT be your library or upload location or a Linux directory like `/lib`. The picture below shows a valid example.
|
||||
:::
|
||||
|
||||
<img
|
||||
src={require('./img/truenas10.webp').default}
|
||||
width="40%"
|
||||
@@ -172,7 +168,7 @@ className="border rounded-xl"
|
||||
/>
|
||||
|
||||
You may configure [External Libraries](/docs/features/libraries) by mounting them using **Additional Storage**.
|
||||
The **Mount Path** is the location you will need to copy and paste into the External Library settings within Immich.
|
||||
The **Mount Path** is the loaction you will need to copy and paste into the External Library settings within Immich.
|
||||
The **Host Path** is the location on the TrueNAS SCALE server where your external library is located.
|
||||
|
||||
<!-- A section for Labels would go here but I don't know what they do. -->
|
||||
|
||||
@@ -72,7 +72,7 @@ alt="Select Plugins > Compose.Manager > Add New Stack > Label it Immich"
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
5. Click "**Save Changes**", you will be prompted to edit stack UI labels, just leave this blank and click "**Ok**"
|
||||
5. Click "**Save Changes**", you will be promoted to edit stack UI labels, just leave this blank and click "**Ok**"
|
||||
6. Select the cog ⚙️ next to Immich, click "**Edit Stack**", then click "**Env File**"
|
||||
7. Paste the entire contents of the [Immich example.env](https://github.com/immich-app/immich/releases/latest/download/example.env) file into the Unraid editor, then **before saving** edit the following:
|
||||
|
||||
|
||||
@@ -110,9 +110,9 @@ const config = {
|
||||
label: 'API',
|
||||
},
|
||||
{
|
||||
href: 'https://immich.store',
|
||||
to: '/blog',
|
||||
position: 'right',
|
||||
label: 'Merch',
|
||||
label: 'Blog',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/immich-app/immich',
|
||||
|
||||
@@ -44,12 +44,12 @@ export default function VersionSwitcher(): JSX.Element {
|
||||
return (
|
||||
versions.length > 0 && (
|
||||
<DropdownNavbarItem
|
||||
className="version-switcher-34ab39"
|
||||
className="navbar__item"
|
||||
label={label}
|
||||
mobile={windowSize === 'mobile'}
|
||||
items={versions.map(({ label, url }) => ({
|
||||
label,
|
||||
to: url + location.pathname + location.hash,
|
||||
to: url,
|
||||
target: '_self',
|
||||
}))}
|
||||
/>
|
||||
|
||||
@@ -75,11 +75,6 @@ div[class^='announcementBar_'] {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* workaround for version switcher PR 15894 */
|
||||
div[class*='navbar__items'] > li:has(a[class*='version-switcher-34ab39']) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
code {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -50,13 +50,6 @@ function HomepageHeader() {
|
||||
>
|
||||
Demo
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
className="flex place-items-center place-content-center py-3 px-8 border bg-immich-primary/10 dark:bg-gray-300 rounded-xl hover:no-underline text-immich-primary dark:text-immich-dark-bg font-bold uppercase"
|
||||
to="https://immich.store"
|
||||
>
|
||||
Buy Merch
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="my-12 flex gap-1 font-medium place-items-center place-content-center text-immich-primary dark:text-immich-dark-primary">
|
||||
|
||||
12
docs/static/archived-versions.json
vendored
12
docs/static/archived-versions.json
vendored
@@ -1,16 +1,4 @@
|
||||
[
|
||||
{
|
||||
"label": "v1.126.1",
|
||||
"url": "https://v1.126.1.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.126.0",
|
||||
"url": "https://v1.126.0.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.7",
|
||||
"url": "https://v1.125.7.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v1.125.6",
|
||||
"url": "https://v1.125.6.archive.immich.app"
|
||||
|
||||
810
e2e/package-lock.json
generated
810
e2e/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "1.126.1",
|
||||
"version": "1.125.6",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
@@ -25,7 +25,7 @@
|
||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/node": "^22.10.9",
|
||||
"@types/oidc-provider": "^8.5.1",
|
||||
"@types/pg": "^8.11.0",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import { JobCommand, JobName, LoginResponseDto } from '@immich/sdk';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { basename } from 'node:path';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, testAssetDir, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterEach, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/jobs', () => {
|
||||
let admin: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup({ onboarding: false });
|
||||
});
|
||||
|
||||
describe('PUT /jobs', () => {
|
||||
afterEach(async () => {
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Resume,
|
||||
force: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/jobs/metadataExtraction');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should queue metadata extraction for missing assets', async () => {
|
||||
const path1 = `${testAssetDir}/formats/raw/Nikon/D700/philadelphia.nef`;
|
||||
const path2 = `${testAssetDir}/formats/raw/Nikon/D80/glarus.nef`;
|
||||
|
||||
await utils.createAsset(admin.accessToken, {
|
||||
assetData: { bytes: await readFile(path1), filename: basename(path1) },
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Pause,
|
||||
force: false,
|
||||
});
|
||||
|
||||
const { id } = await utils.createAsset(admin.accessToken, {
|
||||
assetData: { bytes: await readFile(path2), filename: basename(path2) },
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||
|
||||
{
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, id);
|
||||
|
||||
expect(asset.exifInfo).toBeDefined();
|
||||
expect(asset.exifInfo?.make).toBeNull();
|
||||
}
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Empty,
|
||||
force: false,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Resume,
|
||||
force: false,
|
||||
});
|
||||
|
||||
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
|
||||
command: JobCommand.Start,
|
||||
force: false,
|
||||
});
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||
|
||||
{
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, id);
|
||||
|
||||
expect(asset.exifInfo).toBeDefined();
|
||||
expect(asset.exifInfo?.make).toBe('NIKON CORPORATION');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -298,7 +298,6 @@ describe('/libraries', () => {
|
||||
expect(status).toBe(204);
|
||||
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'library');
|
||||
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||
|
||||
const { assets } = await utils.searchAssets(admin.accessToken, {
|
||||
originalPath: `${testAssetDirInternal}/temp/directoryA/assetA.png`,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getPerson, LoginResponseDto, PersonResponseDto } from '@immich/sdk';
|
||||
import { LoginResponseDto, PersonResponseDto } from '@immich/sdk';
|
||||
import { uuidDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import { app, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
@@ -195,7 +195,6 @@ describe('/people', () => {
|
||||
.send({
|
||||
name: 'New Person',
|
||||
birthDate: '1990-01-01',
|
||||
color: '#333',
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
@@ -204,22 +203,6 @@ describe('/people', () => {
|
||||
birthDate: '1990-01-01T00:00:00.000Z',
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a favorite person', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/people`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
name: 'New Favorite Person',
|
||||
isFavorite: true,
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
expect(body).toMatchObject({
|
||||
id: expect.any(String),
|
||||
name: 'New Favorite Person',
|
||||
isFavorite: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /people/:id', () => {
|
||||
@@ -233,7 +216,6 @@ describe('/people', () => {
|
||||
{ key: 'name', type: 'string' },
|
||||
{ key: 'featureFaceAssetId', type: 'string' },
|
||||
{ key: 'isHidden', type: 'boolean value' },
|
||||
{ key: 'isFavorite', type: 'boolean value' },
|
||||
]) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
@@ -273,42 +255,6 @@ describe('/people', () => {
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ birthDate: null });
|
||||
});
|
||||
|
||||
it('should set a color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ color: '#555' });
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ color: '#555' });
|
||||
});
|
||||
|
||||
it('should clear a color', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ color: null });
|
||||
expect(status).toBe(200);
|
||||
expect(body.color).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should mark a person as favorite', async () => {
|
||||
const person = await utils.createPerson(admin.accessToken, {
|
||||
name: 'visible_person',
|
||||
});
|
||||
|
||||
expect(person.isFavorite).toBe(false);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/people/${person.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ isFavorite: true });
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ isFavorite: true });
|
||||
|
||||
const person2 = await getPerson({ id: person.id }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(person2).toMatchObject({ id: person.id, isFavorite: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /people/:id/merge', () => {
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('/shared-links', () => {
|
||||
await deleteUserAdmin({ id: user2.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
});
|
||||
|
||||
describe('GET /share/:key', () => {
|
||||
describe('GET /share/${key}', () => {
|
||||
it('should have correct asset count in meta tag for non-empty album', async () => {
|
||||
const resp = await request(shareUrl).get(`/${linkWithMetadata.key}`);
|
||||
expect(resp.status).toBe(200);
|
||||
@@ -139,10 +139,7 @@ describe('/shared-links', () => {
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: linkWithAlbum.id }),
|
||||
expect.objectContaining({
|
||||
id: linkWithAssets.id,
|
||||
assets: expect.arrayContaining([expect.objectContaining({ id: asset1.id })]),
|
||||
}),
|
||||
expect.objectContaining({ id: linkWithAssets.id }),
|
||||
expect.objectContaining({ id: linkWithPassword.id }),
|
||||
expect.objectContaining({ id: linkWithMetadata.id }),
|
||||
expect.objectContaining({ id: linkWithoutMetadata.id }),
|
||||
@@ -150,30 +147,6 @@ describe('/shared-links', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should filter on albumId', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/shared-links?albumId=${album.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(2);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: linkWithAlbum.id }),
|
||||
expect.objectContaining({ id: linkWithPassword.id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should find 0 albums', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/shared-links?albumId=${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should not get shared links created by other users', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/shared-links')
|
||||
|
||||
@@ -356,24 +356,5 @@ describe('/admin/users', () => {
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should restore a user', async () => {
|
||||
const user = await utils.userSetup(admin.accessToken, createUserDto.create('restore'));
|
||||
|
||||
await deleteUserAdmin({ id: user.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users/${user.userId}/restore`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: user.userId,
|
||||
email: user.userEmail,
|
||||
status: 'active',
|
||||
deletedAt: null,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,8 +6,6 @@ import {
|
||||
CheckExistingAssetsDto,
|
||||
CreateAlbumDto,
|
||||
CreateLibraryDto,
|
||||
JobCommandDto,
|
||||
JobName,
|
||||
MetadataSearchDto,
|
||||
Permission,
|
||||
PersonCreateDto,
|
||||
@@ -31,7 +29,6 @@ import {
|
||||
getConfigDefaults,
|
||||
login,
|
||||
searchAssets,
|
||||
sendJobCommand,
|
||||
setBaseUrl,
|
||||
signUpAdmin,
|
||||
tagAssets,
|
||||
@@ -478,9 +475,6 @@ export const utils = {
|
||||
tagAssets: (accessToken: string, tagId: string, assetIds: string[]) =>
|
||||
tagAssets({ id: tagId, bulkIdsDto: { ids: assetIds } }, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
jobCommand: async (accessToken: string, jobName: JobName, jobCommandDto: JobCommandDto) =>
|
||||
sendJobCommand({ id: jobName, jobCommandDto }, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
setAuthCookies: async (context: BrowserContext, accessToken: string, domain = '127.0.0.1') =>
|
||||
await context.addCookies([
|
||||
{
|
||||
|
||||
14
i18n/en.json
14
i18n/en.json
@@ -1,6 +1,4 @@
|
||||
{
|
||||
"search_by_description_example": "Hiking day in Sapa",
|
||||
"search_by_description": "Search by description",
|
||||
"about": "About",
|
||||
"account": "Account",
|
||||
"account_settings": "Account Settings",
|
||||
@@ -436,7 +434,6 @@
|
||||
"back_close_deselect": "Back, close, or deselect",
|
||||
"backward": "Backward",
|
||||
"birthdate_saved": "Date of birth saved successfully",
|
||||
"show_shared_links": "Show shared links",
|
||||
"birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.",
|
||||
"blurred_background": "Blurred background",
|
||||
"bugs_and_feature_requests": "Bugs & Feature Requests",
|
||||
@@ -602,8 +599,6 @@
|
||||
"enable": "Enable",
|
||||
"enabled": "Enabled",
|
||||
"end_date": "End date",
|
||||
"rotate_left": "Rotate left",
|
||||
"rotate_right": "Rotate right",
|
||||
"error": "Error",
|
||||
"error_loading_image": "Error loading image",
|
||||
"error_title": "Error - Something went wrong",
|
||||
@@ -646,7 +641,6 @@
|
||||
"quota_higher_than_disk_size": "You set a quota higher than the disk size",
|
||||
"repair_unable_to_check_items": "Unable to check {count, select, one {item} other {items}}",
|
||||
"unable_to_add_album_users": "Unable to add users to album",
|
||||
"unable_to_rotate_image": "Unable to rotate image",
|
||||
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
|
||||
"unable_to_add_comment": "Unable to add comment",
|
||||
"unable_to_add_exclusion_pattern": "Unable to add exclusion pattern",
|
||||
@@ -772,10 +766,8 @@
|
||||
"go_to_search": "Go to search",
|
||||
"go_to_folder": "Go to folder",
|
||||
"group_albums_by": "Group albums by...",
|
||||
"group_country": "Group by country",
|
||||
"group_no": "No grouping",
|
||||
"group_owner": "Group by owner",
|
||||
"group_places_by": "Group places by...",
|
||||
"group_year": "Group by year",
|
||||
"has_quota": "Has quota",
|
||||
"hi_user": "Hi {name} ({email})",
|
||||
@@ -808,7 +800,6 @@
|
||||
"include_shared_albums": "Include shared albums",
|
||||
"include_shared_partner_assets": "Include shared partner assets",
|
||||
"individual_share": "Individual share",
|
||||
"individual_shares": "Individual shares",
|
||||
"info": "Info",
|
||||
"interval": {
|
||||
"day_at_onepm": "Every day at 1pm",
|
||||
@@ -994,7 +985,6 @@
|
||||
"pick_a_location": "Pick a location",
|
||||
"place": "Place",
|
||||
"places": "Places",
|
||||
"places_count": "{count, plural, one {{count, number} Place} other {{count, number} Places}}",
|
||||
"play": "Play",
|
||||
"play_memories": "Play memories",
|
||||
"play_motion_photo": "Play Motion Photo",
|
||||
@@ -1177,7 +1167,6 @@
|
||||
"shared_from_partner": "Photos from {partner}",
|
||||
"shared_link_options": "Shared link options",
|
||||
"shared_links": "Shared links",
|
||||
"shared_links_description": "Share photos and videos with a link",
|
||||
"shared_photos_and_videos_count": "{assetCount, plural, other {# shared photos & videos.}}",
|
||||
"shared_with_partner": "Shared with {partner}",
|
||||
"sharing": "Sharing",
|
||||
@@ -1287,7 +1276,6 @@
|
||||
"unfavorite": "Unfavorite",
|
||||
"unhide_person": "Unhide person",
|
||||
"unknown": "Unknown",
|
||||
"unknown_country": "Unknown Country",
|
||||
"unknown_year": "Unknown Year",
|
||||
"unlimited": "Unlimited",
|
||||
"unlink_motion_video": "Unlink motion video",
|
||||
@@ -1362,4 +1350,4 @@
|
||||
"yes": "Yes",
|
||||
"you_dont_have_any_shared_links": "You don't have any shared links",
|
||||
"zoom_image": "Zoom Image"
|
||||
}
|
||||
}
|
||||
874
i18n/fa.json
874
i18n/fa.json
@@ -312,157 +312,157 @@
|
||||
"admin_password": "رمز عبور مدیر",
|
||||
"administration": "مدیریت",
|
||||
"advanced": "پیشرفته",
|
||||
"album_added": "آلبوم اضافه شد",
|
||||
"album_added": "",
|
||||
"album_added_notification_setting_description": "",
|
||||
"album_cover_updated": "جلد آلبوم بهروزرسانی شد",
|
||||
"album_info_updated": "اطلاعات آلبوم بهروزرسانی شد",
|
||||
"album_name": "نام آلبوم",
|
||||
"album_options": "گزینههای آلبوم",
|
||||
"album_updated": "آلبوم بهروزرسانی شد",
|
||||
"album_cover_updated": "",
|
||||
"album_info_updated": "",
|
||||
"album_name": "",
|
||||
"album_options": "",
|
||||
"album_updated": "",
|
||||
"album_updated_setting_description": "",
|
||||
"albums": "آلبومها",
|
||||
"albums": "",
|
||||
"albums_count": "",
|
||||
"all": "همه",
|
||||
"all_people": "همه افراد",
|
||||
"allow_dark_mode": "اجازه دادن به حالت تاریک",
|
||||
"allow_edits": "اجازه ویرایش",
|
||||
"api_key": "کلید API",
|
||||
"api_keys": "کلیدهای API",
|
||||
"app_settings": "تنظیمات برنامه",
|
||||
"appears_in": "ظاهر میشود در",
|
||||
"archive": "بایگانی",
|
||||
"all": "",
|
||||
"all_people": "",
|
||||
"allow_dark_mode": "",
|
||||
"allow_edits": "",
|
||||
"api_key": "",
|
||||
"api_keys": "",
|
||||
"app_settings": "",
|
||||
"appears_in": "",
|
||||
"archive": "",
|
||||
"archive_or_unarchive_photo": "",
|
||||
"archive_size": "اندازه بایگانی",
|
||||
"archive_size": "",
|
||||
"archive_size_description": "",
|
||||
"asset_offline": "محتوا آفلاین",
|
||||
"assets": "محتواها",
|
||||
"authorized_devices": "دستگاههای مجاز",
|
||||
"back": "بازگشت",
|
||||
"backward": "عقب",
|
||||
"blurred_background": "پسزمینه محو",
|
||||
"asset_offline": "",
|
||||
"assets": "",
|
||||
"authorized_devices": "",
|
||||
"back": "",
|
||||
"backward": "",
|
||||
"blurred_background": "",
|
||||
"bulk_delete_duplicates_confirmation": "",
|
||||
"bulk_keep_duplicates_confirmation": "",
|
||||
"bulk_trash_duplicates_confirmation": "",
|
||||
"camera": "دوربین",
|
||||
"camera_brand": "برند دوربین",
|
||||
"camera_model": "مدل دوربین",
|
||||
"cancel": "لغو",
|
||||
"cancel_search": "لغو جستجو",
|
||||
"cannot_merge_people": "نمیتوان افراد را ادغام کرد",
|
||||
"cannot_update_the_description": "نمیتوان توضیحات را بهروزرسانی کرد",
|
||||
"change_date": "تغییر تاریخ",
|
||||
"change_expiration_time": "تغییر زمان انقضا",
|
||||
"change_location": "تغییر مکان",
|
||||
"change_name": "تغییر نام",
|
||||
"change_name_successfully": "نام با موفقیت تغییر یافت",
|
||||
"change_password": "تغییر رمز عبور",
|
||||
"change_your_password": "رمز عبور خود را تغییر دهید",
|
||||
"camera": "",
|
||||
"camera_brand": "",
|
||||
"camera_model": "",
|
||||
"cancel": "",
|
||||
"cancel_search": "",
|
||||
"cannot_merge_people": "",
|
||||
"cannot_update_the_description": "",
|
||||
"change_date": "",
|
||||
"change_expiration_time": "",
|
||||
"change_location": "",
|
||||
"change_name": "",
|
||||
"change_name_successfully": "",
|
||||
"change_password": "",
|
||||
"change_your_password": "",
|
||||
"changed_visibility_successfully": "",
|
||||
"check_all": "انتخاب همه",
|
||||
"check_logs": "بررسی لاگها",
|
||||
"check_all": "",
|
||||
"check_logs": "",
|
||||
"choose_matching_people_to_merge": "",
|
||||
"city": "شهر",
|
||||
"clear": "پاک کردن",
|
||||
"clear_all": "پاک کردن همه",
|
||||
"clear_message": "پاک کردن پیام",
|
||||
"clear_value": "پاک کردن مقدار",
|
||||
"close": "بستن",
|
||||
"collapse_all": "جمع کردن همه",
|
||||
"color_theme": "تم رنگ",
|
||||
"comment_options": "گزینههای نظر",
|
||||
"comments_are_disabled": "نظرات غیرفعال هستند",
|
||||
"confirm": "تأیید",
|
||||
"confirm_admin_password": "تأیید رمز عبور مدیر",
|
||||
"city": "",
|
||||
"clear": "",
|
||||
"clear_all": "",
|
||||
"clear_message": "",
|
||||
"clear_value": "",
|
||||
"close": "",
|
||||
"collapse_all": "",
|
||||
"color_theme": "",
|
||||
"comment_options": "",
|
||||
"comments_are_disabled": "",
|
||||
"confirm": "",
|
||||
"confirm_admin_password": "",
|
||||
"confirm_delete_shared_link": "",
|
||||
"confirm_password": "تأیید رمز عبور",
|
||||
"contain": "شامل",
|
||||
"context": "زمینه",
|
||||
"continue": "ادامه",
|
||||
"copied_image_to_clipboard": "تصویر به کلیپبورد کپی شد.",
|
||||
"copied_to_clipboard": "به کلیپبورد کپی شد!",
|
||||
"copy_error": "خطا در کپی",
|
||||
"copy_file_path": "کپی مسیر فایل",
|
||||
"copy_image": "کپی تصویر",
|
||||
"copy_link": "کپی لینک",
|
||||
"copy_link_to_clipboard": "کپی لینک به کلیپبورد",
|
||||
"copy_password": "کپی رمز عبور",
|
||||
"copy_to_clipboard": "کپی به کلیپبورد",
|
||||
"country": "کشور",
|
||||
"cover": "جلد",
|
||||
"covers": "جلدها",
|
||||
"create": "ایجاد",
|
||||
"create_album": "ایجاد آلبوم",
|
||||
"create_library": "ایجاد کتابخانه",
|
||||
"create_link": "ایجاد لینک",
|
||||
"create_link_to_share": "ایجاد لینک برای اشتراکگذاری",
|
||||
"create_new_person": "ایجاد فرد جدید",
|
||||
"create_new_user": "ایجاد کاربر جدید",
|
||||
"create_user": "ایجاد کاربر",
|
||||
"created": "ایجاد شد",
|
||||
"current_device": "دستگاه فعلی",
|
||||
"confirm_password": "",
|
||||
"contain": "",
|
||||
"context": "",
|
||||
"continue": "",
|
||||
"copied_image_to_clipboard": "",
|
||||
"copied_to_clipboard": "",
|
||||
"copy_error": "",
|
||||
"copy_file_path": "",
|
||||
"copy_image": "",
|
||||
"copy_link": "",
|
||||
"copy_link_to_clipboard": "",
|
||||
"copy_password": "",
|
||||
"copy_to_clipboard": "",
|
||||
"country": "",
|
||||
"cover": "",
|
||||
"covers": "",
|
||||
"create": "",
|
||||
"create_album": "",
|
||||
"create_library": "",
|
||||
"create_link": "",
|
||||
"create_link_to_share": "",
|
||||
"create_new_person": "",
|
||||
"create_new_user": "",
|
||||
"create_user": "",
|
||||
"created": "",
|
||||
"current_device": "",
|
||||
"custom_locale": "",
|
||||
"custom_locale_description": "",
|
||||
"dark": "تاریک",
|
||||
"date_after": "تاریخ پس از",
|
||||
"date_and_time": "تاریخ و زمان",
|
||||
"date_before": "تاریخ قبل از",
|
||||
"date_range": "بازه زمانی",
|
||||
"day": "روز",
|
||||
"deduplicate_all": "حذف تکراریها به صورت کامل",
|
||||
"dark": "",
|
||||
"date_after": "",
|
||||
"date_and_time": "",
|
||||
"date_before": "",
|
||||
"date_range": "",
|
||||
"day": "",
|
||||
"deduplicate_all": "",
|
||||
"default_locale": "",
|
||||
"default_locale_description": "",
|
||||
"delete": "حذف",
|
||||
"delete_album": "حذف آلبوم",
|
||||
"delete": "",
|
||||
"delete_album": "",
|
||||
"delete_api_key_prompt": "",
|
||||
"delete_duplicates_confirmation": "",
|
||||
"delete_key": "حذف کلید",
|
||||
"delete_library": "حذف کتابخانه",
|
||||
"delete_link": "حذف لینک",
|
||||
"delete_shared_link": "حذف لینک اشتراکی",
|
||||
"delete_user": "حذف کاربر",
|
||||
"deleted_shared_link": "لینک اشتراکی حذف شد",
|
||||
"description": "توضیحات",
|
||||
"details": "جزئیات",
|
||||
"direction": "جهت",
|
||||
"disabled": "غیرفعال",
|
||||
"disallow_edits": "عدم اجازه ویرایش",
|
||||
"discover": "کشف کردن",
|
||||
"dismiss_all_errors": "رد تمام خطاها",
|
||||
"dismiss_error": "رد خطا",
|
||||
"display_options": "گزینههای نمایش",
|
||||
"display_order": "ترتیب نمایش",
|
||||
"display_original_photos": "نمایش عکسهای اصلی",
|
||||
"delete_key": "",
|
||||
"delete_library": "",
|
||||
"delete_link": "",
|
||||
"delete_shared_link": "",
|
||||
"delete_user": "",
|
||||
"deleted_shared_link": "",
|
||||
"description": "",
|
||||
"details": "",
|
||||
"direction": "",
|
||||
"disabled": "",
|
||||
"disallow_edits": "",
|
||||
"discover": "",
|
||||
"dismiss_all_errors": "",
|
||||
"dismiss_error": "",
|
||||
"display_options": "",
|
||||
"display_order": "",
|
||||
"display_original_photos": "",
|
||||
"display_original_photos_setting_description": "",
|
||||
"done": "انجام شد",
|
||||
"download": "دانلود",
|
||||
"download_settings": "تنظیمات دانلود",
|
||||
"download_settings_description": "مدیریت تنظیمات مرتبط با دانلود محتوا",
|
||||
"downloading": "در حال دانلود",
|
||||
"duplicates": "تکراریها",
|
||||
"done": "",
|
||||
"download": "",
|
||||
"download_settings": "",
|
||||
"download_settings_description": "",
|
||||
"downloading": "",
|
||||
"duplicates": "",
|
||||
"duplicates_description": "",
|
||||
"duration": "مدت زمان",
|
||||
"edit_album": "ویرایش آلبوم",
|
||||
"edit_avatar": "ویرایش آواتار",
|
||||
"edit_date": "ویرایش تاریخ",
|
||||
"edit_date_and_time": "ویرایش تاریخ و زمان",
|
||||
"edit_exclusion_pattern": "ویرایش الگوی استثناء",
|
||||
"edit_faces": "ویرایش چهرهها",
|
||||
"duration": "",
|
||||
"edit_album": "",
|
||||
"edit_avatar": "",
|
||||
"edit_date": "",
|
||||
"edit_date_and_time": "",
|
||||
"edit_exclusion_pattern": "",
|
||||
"edit_faces": "",
|
||||
"edit_import_path": "",
|
||||
"edit_import_paths": "",
|
||||
"edit_key": "ویرایش کلید",
|
||||
"edit_link": "ویرایش لینک",
|
||||
"edit_location": "ویرایش مکان",
|
||||
"edit_name": "ویرایش نام",
|
||||
"edit_people": "ویرایش افراد",
|
||||
"edit_title": "ویرایش عنوان",
|
||||
"edit_user": "ویرایش کاربر",
|
||||
"edited": "ویرایش شد",
|
||||
"editor": "ویرایشگر",
|
||||
"email": "ایمیل",
|
||||
"empty_trash": "خالی کردن سطل زباله",
|
||||
"end_date": "تاریخ پایان",
|
||||
"error": "خطا",
|
||||
"error_loading_image": "خطا در بارگذاری تصویر",
|
||||
"edit_key": "",
|
||||
"edit_link": "",
|
||||
"edit_location": "",
|
||||
"edit_name": "",
|
||||
"edit_people": "",
|
||||
"edit_title": "",
|
||||
"edit_user": "",
|
||||
"edited": "",
|
||||
"editor": "",
|
||||
"email": "",
|
||||
"empty_trash": "",
|
||||
"end_date": "",
|
||||
"error": "",
|
||||
"error_loading_image": "",
|
||||
"errors": {
|
||||
"exclusion_pattern_already_exists": "",
|
||||
"import_path_already_exists": "",
|
||||
@@ -530,400 +530,400 @@
|
||||
"unable_to_update_timeline_display_status": "",
|
||||
"unable_to_update_user": ""
|
||||
},
|
||||
"exit_slideshow": "خروج از نمایش اسلاید",
|
||||
"expand_all": "باز کردن همه",
|
||||
"expire_after": "منقضی شدن بعد از",
|
||||
"expired": "منقضی شده",
|
||||
"explore": "کاوش کردن",
|
||||
"export": "صادر کردن",
|
||||
"export_as_json": "صادر کردن بهصورت JSON",
|
||||
"extension": "پسوند",
|
||||
"external": "خارجی",
|
||||
"external_libraries": "کتابخانههای خارجی",
|
||||
"favorite": "علاقهمندی",
|
||||
"exit_slideshow": "",
|
||||
"expand_all": "",
|
||||
"expire_after": "",
|
||||
"expired": "",
|
||||
"explore": "",
|
||||
"export": "",
|
||||
"export_as_json": "",
|
||||
"extension": "",
|
||||
"external": "",
|
||||
"external_libraries": "",
|
||||
"favorite": "",
|
||||
"favorite_or_unfavorite_photo": "",
|
||||
"favorites": "علاقهمندیها",
|
||||
"favorites": "",
|
||||
"feature_photo_updated": "",
|
||||
"file_name": "نام فایل",
|
||||
"file_name_or_extension": "نام فایل یا پسوند",
|
||||
"filename": "نام فایل",
|
||||
"filetype": "نوع فایل",
|
||||
"filter_people": "فیلتر افراد",
|
||||
"file_name": "",
|
||||
"file_name_or_extension": "",
|
||||
"filename": "",
|
||||
"filetype": "",
|
||||
"filter_people": "",
|
||||
"find_them_fast": "",
|
||||
"fix_incorrect_match": "رفع تطابق نادرست",
|
||||
"forward": "جلو",
|
||||
"general": "عمومی",
|
||||
"get_help": "دریافت کمک",
|
||||
"getting_started": "شروع به کار",
|
||||
"go_back": "بازگشت",
|
||||
"go_to_search": "رفتن به جستجو",
|
||||
"group_albums_by": "گروهبندی آلبومها براساس...",
|
||||
"has_quota": "دارای سهمیه",
|
||||
"hide_gallery": "پنهان کردن گالری",
|
||||
"hide_password": "پنهان کردن رمز عبور",
|
||||
"hide_person": "پنهان کردن فرد",
|
||||
"host": "میزبان",
|
||||
"hour": "ساعت",
|
||||
"image": "تصویر",
|
||||
"immich_logo": "لوگوی Immich",
|
||||
"immich_web_interface": "رابط وب Immich",
|
||||
"import_from_json": "وارد کردن از JSON",
|
||||
"import_path": "مسیر وارد کردن",
|
||||
"fix_incorrect_match": "",
|
||||
"forward": "",
|
||||
"general": "",
|
||||
"get_help": "",
|
||||
"getting_started": "",
|
||||
"go_back": "",
|
||||
"go_to_search": "",
|
||||
"group_albums_by": "",
|
||||
"has_quota": "",
|
||||
"hide_gallery": "",
|
||||
"hide_password": "",
|
||||
"hide_person": "",
|
||||
"host": "",
|
||||
"hour": "",
|
||||
"image": "",
|
||||
"immich_logo": "",
|
||||
"immich_web_interface": "",
|
||||
"import_from_json": "",
|
||||
"import_path": "",
|
||||
"in_albums": "",
|
||||
"in_archive": "در بایگانی",
|
||||
"include_archived": "شامل بایگانی شدهها",
|
||||
"include_shared_albums": "شامل آلبومهای اشتراکی",
|
||||
"in_archive": "",
|
||||
"include_archived": "",
|
||||
"include_shared_albums": "",
|
||||
"include_shared_partner_assets": "",
|
||||
"individual_share": "اشتراک فردی",
|
||||
"info": "اطلاعات",
|
||||
"individual_share": "",
|
||||
"info": "",
|
||||
"interval": {
|
||||
"day_at_onepm": "",
|
||||
"hours": "",
|
||||
"night_at_midnight": "",
|
||||
"night_at_twoam": ""
|
||||
},
|
||||
"invite_people": "دعوت افراد",
|
||||
"invite_to_album": "دعوت به آلبوم",
|
||||
"jobs": "وظایف",
|
||||
"keep": "نگه داشتن",
|
||||
"keep_all": "نگه داشتن همه",
|
||||
"keyboard_shortcuts": "میانبرهای صفحهکلید",
|
||||
"language": "زبان",
|
||||
"language_setting_description": "انتخاب زبان دلخواه شما",
|
||||
"last_seen": "آخرین مشاهده",
|
||||
"leave": "ترک کردن",
|
||||
"let_others_respond": "اجازه به دیگران برای پاسخگویی",
|
||||
"level": "سطح",
|
||||
"library": "کتابخانه",
|
||||
"library_options": "گزینههای کتابخانه",
|
||||
"light": "روشن",
|
||||
"link_options": "گزینههای لینک",
|
||||
"link_to_oauth": "اتصال به OAuth",
|
||||
"linked_oauth_account": "حساب OAuth متصل شده",
|
||||
"list": "لیست",
|
||||
"loading": "در حال بارگذاری",
|
||||
"loading_search_results_failed": "بارگذاری نتایج جستجو ناموفق بود",
|
||||
"log_out": "خروج از سیستم",
|
||||
"log_out_all_devices": "خروج از همه دستگاهها",
|
||||
"login_has_been_disabled": "ورود غیرفعال شده است.",
|
||||
"look": "نگاه کردن",
|
||||
"loop_videos": "پخش مداوم ویدئوها",
|
||||
"invite_people": "",
|
||||
"invite_to_album": "",
|
||||
"jobs": "",
|
||||
"keep": "",
|
||||
"keep_all": "",
|
||||
"keyboard_shortcuts": "",
|
||||
"language": "",
|
||||
"language_setting_description": "",
|
||||
"last_seen": "",
|
||||
"leave": "",
|
||||
"let_others_respond": "",
|
||||
"level": "",
|
||||
"library": "",
|
||||
"library_options": "",
|
||||
"light": "",
|
||||
"link_options": "",
|
||||
"link_to_oauth": "",
|
||||
"linked_oauth_account": "",
|
||||
"list": "",
|
||||
"loading": "",
|
||||
"loading_search_results_failed": "",
|
||||
"log_out": "",
|
||||
"log_out_all_devices": "",
|
||||
"login_has_been_disabled": "",
|
||||
"look": "",
|
||||
"loop_videos": "",
|
||||
"loop_videos_description": "",
|
||||
"make": "ساختن",
|
||||
"manage_shared_links": "مدیریت لینکهای اشتراکی",
|
||||
"make": "",
|
||||
"manage_shared_links": "",
|
||||
"manage_sharing_with_partners": "",
|
||||
"manage_the_app_settings": "مدیریت تنظیمات برنامه",
|
||||
"manage_your_account": "مدیریت حساب کاربری شما",
|
||||
"manage_your_api_keys": "مدیریت کلیدهای API شما",
|
||||
"manage_your_devices": "مدیریت دستگاههای متصل",
|
||||
"manage_your_oauth_connection": "مدیریت اتصال OAuth شما",
|
||||
"map": "نقشه",
|
||||
"manage_the_app_settings": "",
|
||||
"manage_your_account": "",
|
||||
"manage_your_api_keys": "",
|
||||
"manage_your_devices": "",
|
||||
"manage_your_oauth_connection": "",
|
||||
"map": "",
|
||||
"map_marker_with_image": "",
|
||||
"map_settings": "تنظیمات نقشه",
|
||||
"matches": "تطابقها",
|
||||
"media_type": "نوع رسانه",
|
||||
"memories": "خاطرات",
|
||||
"map_settings": "",
|
||||
"matches": "",
|
||||
"media_type": "",
|
||||
"memories": "",
|
||||
"memories_setting_description": "",
|
||||
"memory": "خاطره",
|
||||
"menu": "منو",
|
||||
"merge": "ادغام",
|
||||
"merge_people": "ادغام افراد",
|
||||
"memory": "",
|
||||
"menu": "",
|
||||
"merge": "",
|
||||
"merge_people": "",
|
||||
"merge_people_limit": "",
|
||||
"merge_people_prompt": "",
|
||||
"merge_people_successfully": "ادغام افراد با موفقیت انجام شد",
|
||||
"minimize": "کوچک کردن",
|
||||
"minute": "دقیقه",
|
||||
"missing": "گمشده",
|
||||
"model": "مدل",
|
||||
"month": "ماه",
|
||||
"more": "بیشتر",
|
||||
"moved_to_trash": "به سطل زباله منتقل شد",
|
||||
"my_albums": "آلبومهای من",
|
||||
"name": "نام",
|
||||
"name_or_nickname": "نام یا لقب",
|
||||
"never": "هرگز",
|
||||
"new_api_key": "کلید API جدید",
|
||||
"new_password": "رمز عبور جدید",
|
||||
"new_person": "فرد جدید",
|
||||
"new_user_created": "کاربر جدید ایجاد شد",
|
||||
"newest_first": "جدیدترین ابتدا",
|
||||
"next": "بعدی",
|
||||
"next_memory": "خاطره بعدی",
|
||||
"no": "خیر",
|
||||
"merge_people_successfully": "",
|
||||
"minimize": "",
|
||||
"minute": "",
|
||||
"missing": "",
|
||||
"model": "",
|
||||
"month": "",
|
||||
"more": "",
|
||||
"moved_to_trash": "",
|
||||
"my_albums": "",
|
||||
"name": "",
|
||||
"name_or_nickname": "",
|
||||
"never": "",
|
||||
"new_api_key": "",
|
||||
"new_password": "",
|
||||
"new_person": "",
|
||||
"new_user_created": "",
|
||||
"newest_first": "",
|
||||
"next": "",
|
||||
"next_memory": "",
|
||||
"no": "",
|
||||
"no_albums_message": "",
|
||||
"no_archived_assets_message": "",
|
||||
"no_assets_message": "",
|
||||
"no_duplicates_found": "هیچ تکراری یافت نشد.",
|
||||
"no_exif_info_available": "اطلاعات EXIF موجود نیست",
|
||||
"no_duplicates_found": "",
|
||||
"no_exif_info_available": "",
|
||||
"no_explore_results_message": "",
|
||||
"no_favorites_message": "",
|
||||
"no_libraries_message": "",
|
||||
"no_name": "بدون نام",
|
||||
"no_places": "مکانی یافت نشد",
|
||||
"no_results": "نتیجهای یافت نشد",
|
||||
"no_name": "",
|
||||
"no_places": "",
|
||||
"no_results": "",
|
||||
"no_shared_albums_message": "",
|
||||
"not_in_any_album": "در هیچ آلبومی نیست",
|
||||
"not_in_any_album": "",
|
||||
"note_apply_storage_label_to_previously_uploaded assets": "",
|
||||
"note_unlimited_quota": "",
|
||||
"notes": "یادداشتها",
|
||||
"notification_toggle_setting_description": "اعلانهای ایمیلی را فعال کنید",
|
||||
"notifications": "اعلانها",
|
||||
"notifications_setting_description": "مدیریت اعلانها",
|
||||
"oauth": "OAuth",
|
||||
"offline": "آفلاین",
|
||||
"offline_paths": "مسیرهای آفلاین",
|
||||
"notes": "",
|
||||
"notification_toggle_setting_description": "",
|
||||
"notifications": "",
|
||||
"notifications_setting_description": "",
|
||||
"oauth": "",
|
||||
"offline": "",
|
||||
"offline_paths": "",
|
||||
"offline_paths_description": "",
|
||||
"ok": "تأیید",
|
||||
"oldest_first": "قدیمیترین ابتدا",
|
||||
"online": "آنلاین",
|
||||
"only_favorites": "فقط علاقهمندیها",
|
||||
"open_the_search_filters": "باز کردن فیلترهای جستجو",
|
||||
"options": "گزینهها",
|
||||
"organize_your_library": "کتابخانه خود را سازماندهی کنید",
|
||||
"other": "دیگر",
|
||||
"other_devices": "دستگاههای دیگر",
|
||||
"other_variables": "متغیرهای دیگر",
|
||||
"owned": "مالکیت",
|
||||
"owner": "مالک",
|
||||
"partner": "شریک",
|
||||
"partner_can_access": "{partner} میتواند دسترسی داشته باشد",
|
||||
"ok": "",
|
||||
"oldest_first": "",
|
||||
"online": "",
|
||||
"only_favorites": "",
|
||||
"open_the_search_filters": "",
|
||||
"options": "",
|
||||
"organize_your_library": "",
|
||||
"other": "",
|
||||
"other_devices": "",
|
||||
"other_variables": "",
|
||||
"owned": "",
|
||||
"owner": "",
|
||||
"partner": "",
|
||||
"partner_can_access": "",
|
||||
"partner_can_access_assets": "",
|
||||
"partner_can_access_location": "مکانهایی که عکسهای شما گرفته شدهاند",
|
||||
"partner_sharing": "اشتراکگذاری با شریک",
|
||||
"partners": "شرکا",
|
||||
"password": "رمز عبور",
|
||||
"password_does_not_match": "رمز عبور مطابقت ندارد",
|
||||
"password_required": "رمز عبور مورد نیاز است",
|
||||
"password_reset_success": "بازنشانی رمز عبور موفقیتآمیز بود",
|
||||
"partner_can_access_location": "",
|
||||
"partner_sharing": "",
|
||||
"partners": "",
|
||||
"password": "",
|
||||
"password_does_not_match": "",
|
||||
"password_required": "",
|
||||
"password_reset_success": "",
|
||||
"past_durations": {
|
||||
"days": "",
|
||||
"hours": "",
|
||||
"years": ""
|
||||
},
|
||||
"path": "مسیر",
|
||||
"pattern": "الگو",
|
||||
"pause": "توقف",
|
||||
"pause_memories": "توقف خاطرات",
|
||||
"paused": "متوقف شده",
|
||||
"pending": "در انتظار",
|
||||
"people": "افراد",
|
||||
"path": "",
|
||||
"pattern": "",
|
||||
"pause": "",
|
||||
"pause_memories": "",
|
||||
"paused": "",
|
||||
"pending": "",
|
||||
"people": "",
|
||||
"people_sidebar_description": "",
|
||||
"permanent_deletion_warning": "هشدار حذف دائمی",
|
||||
"permanent_deletion_warning_setting_description": "نمایش هشدار هنگام حذف دائمی محتواها",
|
||||
"permanently_delete": "حذف دائمی",
|
||||
"permanently_deleted_asset": "محتوای حذف شده دائمی",
|
||||
"person": "فرد",
|
||||
"photos": "عکسها",
|
||||
"permanent_deletion_warning": "",
|
||||
"permanent_deletion_warning_setting_description": "",
|
||||
"permanently_delete": "",
|
||||
"permanently_deleted_asset": "",
|
||||
"person": "",
|
||||
"photos": "",
|
||||
"photos_count": "",
|
||||
"photos_from_previous_years": "عکسهای سالهای گذشته",
|
||||
"pick_a_location": "یک مکان انتخاب کنید",
|
||||
"place": "مکان",
|
||||
"places": "مکانها",
|
||||
"play": "پخش",
|
||||
"play_memories": "پخش خاطرات",
|
||||
"play_motion_photo": "پخش عکس متحرک",
|
||||
"play_or_pause_video": "پخش یا توقف ویدیو",
|
||||
"port": "پورت",
|
||||
"preset": "پیشفرض",
|
||||
"preview": "پیشنمایش",
|
||||
"previous": "قبلی",
|
||||
"previous_memory": "خاطره قبلی",
|
||||
"previous_or_next_photo": "عکس قبلی یا بعدی",
|
||||
"primary": "اصلی",
|
||||
"profile_picture_set": "تصویر پروفایل تنظیم شد.",
|
||||
"public_share": "اشتراک عمومی",
|
||||
"reaction_options": "گزینههای واکنش",
|
||||
"read_changelog": "مطالعه تغییرات نسخه",
|
||||
"recent": "اخیر",
|
||||
"recent_searches": "جستجوهای اخیر",
|
||||
"refresh": "تازه سازی",
|
||||
"refreshed": "تازه سازی شد",
|
||||
"photos_from_previous_years": "",
|
||||
"pick_a_location": "",
|
||||
"place": "",
|
||||
"places": "",
|
||||
"play": "",
|
||||
"play_memories": "",
|
||||
"play_motion_photo": "",
|
||||
"play_or_pause_video": "",
|
||||
"port": "",
|
||||
"preset": "",
|
||||
"preview": "",
|
||||
"previous": "",
|
||||
"previous_memory": "",
|
||||
"previous_or_next_photo": "",
|
||||
"primary": "",
|
||||
"profile_picture_set": "",
|
||||
"public_share": "",
|
||||
"reaction_options": "",
|
||||
"read_changelog": "",
|
||||
"recent": "",
|
||||
"recent_searches": "",
|
||||
"refresh": "",
|
||||
"refreshed": "",
|
||||
"refreshes_every_file": "",
|
||||
"remove": "حذف",
|
||||
"remove_deleted_assets": "حذف محتواهای حذفشده",
|
||||
"remove_from_album": "حذف از آلبوم",
|
||||
"remove_from_favorites": "حذف از علاقهمندیها",
|
||||
"remove": "",
|
||||
"remove_deleted_assets": "",
|
||||
"remove_from_album": "",
|
||||
"remove_from_favorites": "",
|
||||
"remove_from_shared_link": "",
|
||||
"removed_api_key": "",
|
||||
"rename": "تغییر نام",
|
||||
"repair": "تعمیر",
|
||||
"rename": "",
|
||||
"repair": "",
|
||||
"repair_no_results_message": "",
|
||||
"replace_with_upload": "جایگزینی با آپلود",
|
||||
"replace_with_upload": "",
|
||||
"require_password": "",
|
||||
"require_user_to_change_password_on_first_login": "",
|
||||
"reset": "بازنشانی",
|
||||
"reset_password": "بازنشانی رمز عبور",
|
||||
"reset": "",
|
||||
"reset_password": "",
|
||||
"reset_people_visibility": "",
|
||||
"resolved_all_duplicates": "",
|
||||
"restore": "بازیابی",
|
||||
"restore_all": "بازیابی همه",
|
||||
"restore_user": "بازیابی کاربر",
|
||||
"resume": "ادامه",
|
||||
"restore": "",
|
||||
"restore_all": "",
|
||||
"restore_user": "",
|
||||
"resume": "",
|
||||
"retry_upload": "",
|
||||
"review_duplicates": "بررسی تکراریها",
|
||||
"role": "نقش",
|
||||
"save": "ذخیره",
|
||||
"review_duplicates": "",
|
||||
"role": "",
|
||||
"save": "",
|
||||
"saved_api_key": "",
|
||||
"saved_profile": "پروفایل ذخیره شد",
|
||||
"saved_settings": "تنظیمات ذخیره شد",
|
||||
"say_something": "چیزی بگویید",
|
||||
"scan_all_libraries": "اسکن همه کتابخانهها",
|
||||
"scan_settings": "تنظیمات اسکن",
|
||||
"saved_profile": "",
|
||||
"saved_settings": "",
|
||||
"say_something": "",
|
||||
"scan_all_libraries": "",
|
||||
"scan_settings": "",
|
||||
"scanning_for_album": "",
|
||||
"search": "جستجو",
|
||||
"search_albums": "جستجوی آلبومها",
|
||||
"search_by_context": "جستجو براساس زمینه",
|
||||
"search_camera_make": "جستجوی برند دوربین...",
|
||||
"search_camera_model": "جستجوی مدل دوربین...",
|
||||
"search_city": "جستجوی شهر...",
|
||||
"search_country": "جستجوی کشور...",
|
||||
"search_for_existing_person": "جستجوی فرد موجود",
|
||||
"search_people": "جستجوی افراد",
|
||||
"search_places": "جستجوی مکانها",
|
||||
"search_state": "جستجوی ایالت...",
|
||||
"search_timezone": "جستجوی منطقه زمانی...",
|
||||
"search_type": "نوع جستجو",
|
||||
"search": "",
|
||||
"search_albums": "",
|
||||
"search_by_context": "",
|
||||
"search_camera_make": "",
|
||||
"search_camera_model": "",
|
||||
"search_city": "",
|
||||
"search_country": "",
|
||||
"search_for_existing_person": "",
|
||||
"search_people": "",
|
||||
"search_places": "",
|
||||
"search_state": "",
|
||||
"search_timezone": "",
|
||||
"search_type": "",
|
||||
"search_your_photos": "",
|
||||
"searching_locales": "",
|
||||
"second": "ثانیه",
|
||||
"select_album_cover": "انتخاب جلد آلبوم",
|
||||
"select_all": "انتخاب همه",
|
||||
"select_avatar_color": "انتخاب رنگ آواتار",
|
||||
"select_face": "انتخاب چهره",
|
||||
"select_featured_photo": "انتخاب عکس ویژه",
|
||||
"select_keep_all": "انتخاب نگهداری همه",
|
||||
"select_library_owner": "انتخاب مالک کتابخانه",
|
||||
"select_new_face": "انتخاب چهره جدید",
|
||||
"select_photos": "انتخاب عکسها",
|
||||
"second": "",
|
||||
"select_album_cover": "",
|
||||
"select_all": "",
|
||||
"select_avatar_color": "",
|
||||
"select_face": "",
|
||||
"select_featured_photo": "",
|
||||
"select_keep_all": "",
|
||||
"select_library_owner": "",
|
||||
"select_new_face": "",
|
||||
"select_photos": "",
|
||||
"select_trash_all": "",
|
||||
"selected": "انتخاب شده",
|
||||
"send_message": "ارسال پیام",
|
||||
"send_welcome_email": "ارسال ایمیل خوشآمدگویی",
|
||||
"server_stats": "آمار سرور",
|
||||
"set": "تنظیم",
|
||||
"selected": "",
|
||||
"send_message": "",
|
||||
"send_welcome_email": "",
|
||||
"server_stats": "",
|
||||
"set": "",
|
||||
"set_as_album_cover": "",
|
||||
"set_as_profile_picture": "",
|
||||
"set_date_of_birth": "تنظیم تاریخ تولد",
|
||||
"set_profile_picture": "تنظیم تصویر پروفایل",
|
||||
"set_date_of_birth": "",
|
||||
"set_profile_picture": "",
|
||||
"set_slideshow_to_fullscreen": "",
|
||||
"settings": "تنظیمات",
|
||||
"settings_saved": "تنظیمات ذخیره شد",
|
||||
"share": "اشتراکگذاری",
|
||||
"shared": "مشترک",
|
||||
"shared_by": "مشترک توسط",
|
||||
"settings": "",
|
||||
"settings_saved": "",
|
||||
"share": "",
|
||||
"shared": "",
|
||||
"shared_by": "",
|
||||
"shared_by_you": "",
|
||||
"shared_from_partner": "عکسها از {partner}",
|
||||
"shared_links": "لینکهای اشتراکی",
|
||||
"shared_from_partner": "",
|
||||
"shared_links": "",
|
||||
"shared_photos_and_videos_count": "",
|
||||
"shared_with_partner": "مشترک با {partner}",
|
||||
"sharing": "اشتراکگذاری",
|
||||
"shared_with_partner": "",
|
||||
"sharing": "",
|
||||
"sharing_sidebar_description": "",
|
||||
"show_album_options": "نمایش گزینههای آلبوم",
|
||||
"show_album_options": "",
|
||||
"show_and_hide_people": "",
|
||||
"show_file_location": "نمایش مسیر فایل",
|
||||
"show_gallery": "نمایش گالری",
|
||||
"show_hidden_people": "نمایش افراد پنهان",
|
||||
"show_file_location": "",
|
||||
"show_gallery": "",
|
||||
"show_hidden_people": "",
|
||||
"show_in_timeline": "",
|
||||
"show_in_timeline_setting_description": "",
|
||||
"show_keyboard_shortcuts": "",
|
||||
"show_metadata": "نمایش اطلاعات متا",
|
||||
"show_metadata": "",
|
||||
"show_or_hide_info": "",
|
||||
"show_password": "نمایش رمز عبور",
|
||||
"show_password": "",
|
||||
"show_person_options": "",
|
||||
"show_progress_bar": "نمایش نوار پیشرفت",
|
||||
"show_search_options": "نمایش گزینههای جستجو",
|
||||
"shuffle": "تصادفی",
|
||||
"sign_out": "خروج",
|
||||
"sign_up": "ثبتنام",
|
||||
"size": "اندازه",
|
||||
"skip_to_content": "رفتن به محتوا",
|
||||
"slideshow": "نمایش اسلاید",
|
||||
"slideshow_settings": "تنظیمات نمایش اسلاید",
|
||||
"show_progress_bar": "",
|
||||
"show_search_options": "",
|
||||
"shuffle": "",
|
||||
"sign_out": "",
|
||||
"sign_up": "",
|
||||
"size": "",
|
||||
"skip_to_content": "",
|
||||
"slideshow": "",
|
||||
"slideshow_settings": "",
|
||||
"sort_albums_by": "",
|
||||
"stack": "پشته",
|
||||
"stack": "",
|
||||
"stack_selected_photos": "",
|
||||
"stacktrace": "",
|
||||
"start": "شروع",
|
||||
"start_date": "تاریخ شروع",
|
||||
"state": "ایالت",
|
||||
"status": "وضعیت",
|
||||
"stop_motion_photo": "توقف عکس متحرک",
|
||||
"start": "",
|
||||
"start_date": "",
|
||||
"state": "",
|
||||
"status": "",
|
||||
"stop_motion_photo": "",
|
||||
"stop_photo_sharing": "",
|
||||
"stop_photo_sharing_description": "",
|
||||
"stop_sharing_photos_with_user": "",
|
||||
"storage": "فضای ذخیرهسازی",
|
||||
"storage_label": "برچسب فضای ذخیرهسازی",
|
||||
"storage": "",
|
||||
"storage_label": "",
|
||||
"storage_usage": "",
|
||||
"submit": "ارسال",
|
||||
"suggestions": "پیشنهادات",
|
||||
"submit": "",
|
||||
"suggestions": "",
|
||||
"sunrise_on_the_beach": "",
|
||||
"swap_merge_direction": "تغییر جهت ادغام",
|
||||
"sync": "همگامسازی",
|
||||
"template": "الگو",
|
||||
"theme": "تم",
|
||||
"theme_selection": "انتخاب تم",
|
||||
"swap_merge_direction": "",
|
||||
"sync": "",
|
||||
"template": "",
|
||||
"theme": "",
|
||||
"theme_selection": "",
|
||||
"theme_selection_description": "",
|
||||
"time_based_memories": "",
|
||||
"timezone": "منطقه زمانی",
|
||||
"to_archive": "بایگانی",
|
||||
"to_favorite": "به علاقهمندیها",
|
||||
"timezone": "",
|
||||
"to_archive": "",
|
||||
"to_favorite": "",
|
||||
"to_trash": "",
|
||||
"toggle_settings": "تغییر تنظیمات",
|
||||
"toggle_theme": "تغییر تم تاریک",
|
||||
"total_usage": "استفاده کلی",
|
||||
"trash": "سطل زباله",
|
||||
"toggle_settings": "",
|
||||
"toggle_theme": "",
|
||||
"total_usage": "",
|
||||
"trash": "",
|
||||
"trash_all": "",
|
||||
"trash_count": "",
|
||||
"trash_no_results_message": "",
|
||||
"trashed_items_will_be_permanently_deleted_after": "",
|
||||
"type": "نوع",
|
||||
"type": "",
|
||||
"unarchive": "",
|
||||
"unfavorite": "حذف از علاقهمندیها",
|
||||
"unhide_person": "آشکار کردن فرد",
|
||||
"unknown": "ناشناخته",
|
||||
"unknown_year": "سال نامشخص",
|
||||
"unlimited": "نامحدود",
|
||||
"unlink_oauth": "لغو اتصال OAuth",
|
||||
"unfavorite": "",
|
||||
"unhide_person": "",
|
||||
"unknown": "",
|
||||
"unknown_year": "",
|
||||
"unlimited": "",
|
||||
"unlink_oauth": "",
|
||||
"unlinked_oauth_account": "",
|
||||
"unnamed_album": "آلبوم بدون نام",
|
||||
"unnamed_share": "اشتراک بدون نام",
|
||||
"unselect_all": "لغو انتخاب همه",
|
||||
"unnamed_album": "",
|
||||
"unnamed_share": "",
|
||||
"unselect_all": "",
|
||||
"unstack": "",
|
||||
"untracked_files": "",
|
||||
"untracked_files_decription": "",
|
||||
"up_next": "مورد بعدی",
|
||||
"up_next": "",
|
||||
"updated_password": "",
|
||||
"upload": "آپلود",
|
||||
"upload_concurrency": "تعداد آپلود همزمان",
|
||||
"url": "آدرس",
|
||||
"usage": "استفاده",
|
||||
"user": "کاربر",
|
||||
"user_id": "شناسه کاربر",
|
||||
"user_usage_detail": "جزئیات استفاده کاربر",
|
||||
"username": "نام کاربری",
|
||||
"users": "کاربران",
|
||||
"utilities": "ابزارها",
|
||||
"validate": "اعتبارسنجی",
|
||||
"variables": "متغیرها",
|
||||
"version": "نسخه",
|
||||
"upload": "",
|
||||
"upload_concurrency": "",
|
||||
"url": "",
|
||||
"usage": "",
|
||||
"user": "",
|
||||
"user_id": "",
|
||||
"user_usage_detail": "",
|
||||
"username": "",
|
||||
"users": "",
|
||||
"utilities": "",
|
||||
"validate": "",
|
||||
"variables": "",
|
||||
"version": "",
|
||||
"version_announcement_message": "",
|
||||
"video": "ویدیو",
|
||||
"video": "",
|
||||
"video_hover_setting": "",
|
||||
"video_hover_setting_description": "",
|
||||
"videos": "ویدیوها",
|
||||
"videos": "",
|
||||
"videos_count": "",
|
||||
"view": "مشاهده",
|
||||
"view_all": "مشاهده همه",
|
||||
"view_all_users": "مشاهده همه کاربران",
|
||||
"view_links": "مشاهده لینکها",
|
||||
"view_next_asset": "مشاهده محتوای بعدی",
|
||||
"view_previous_asset": "مشاهده محتوای قبلی",
|
||||
"waiting": "در انتظار",
|
||||
"week": "هفته",
|
||||
"welcome": "خوش آمدید",
|
||||
"view": "",
|
||||
"view_all": "",
|
||||
"view_all_users": "",
|
||||
"view_links": "",
|
||||
"view_next_asset": "",
|
||||
"view_previous_asset": "",
|
||||
"waiting": "",
|
||||
"week": "",
|
||||
"welcome": "",
|
||||
"welcome_to_immich": "",
|
||||
"year": "سال",
|
||||
"yes": "بله",
|
||||
"year": "",
|
||||
"yes": "",
|
||||
"you_dont_have_any_shared_links": "",
|
||||
"zoom_image": "بزرگنمایی تصویر"
|
||||
}
|
||||
|
||||
216
i18n/th.json
216
i18n/th.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"about": "เกี่ยวกับ",
|
||||
"account": "บัญชีผู้ใช้",
|
||||
"account": "บัญชี",
|
||||
"account_settings": "การตั้งค่าบัญชี",
|
||||
"acknowledge": "รับทราบ",
|
||||
"action": "การดำเนินการ",
|
||||
@@ -155,7 +155,7 @@
|
||||
"migration_job_description": "ย้ายภาพตัวอย่างสื่อและใบหน้าไปยังโครงสร้างโฟลเดอร์ล่าสุด",
|
||||
"no_paths_added": "ไม่ได้เพิ่มพาธ",
|
||||
"no_pattern_added": "ไม่ได้เพิ่มรูปแบบ",
|
||||
"note_apply_storage_label_previous_assets": "หากต้องการใช้ Storage Label กับไฟล์ที่อัปโหลดก่อนหน้านี้ ให้รันคำสั่งนี้",
|
||||
"note_apply_storage_label_previous_assets": "หมายเหตุ: หากจะแปะฉลากจัดเก็บใส่สื่อที่อัพโหลดก่อนหน้านี้ ให้",
|
||||
"note_cannot_be_changed_later": "หมายเหตุ: ไม่สามารถเปลี่ยนภายหลังได้!",
|
||||
"note_unlimited_quota": "หมายเหตุ: ใส่เลข 0 สําหรับโควต้าไม่จํากัด",
|
||||
"notification_email_from_address": "จากที่อยู่",
|
||||
@@ -193,8 +193,8 @@
|
||||
"oauth_settings_description": "จัดการการตั้งค่าล็อกอินผ่าน OAuth",
|
||||
"oauth_settings_more_details": "สำหรับรายละเอียดเพิ่มเติม ให้อ้างถึง<link>เอกสาร</link>",
|
||||
"oauth_signing_algorithm": "อัลกอริทึมการลงนาม",
|
||||
"oauth_storage_label_claim": "สิทธิ์ที่ใช้อ้างถึงป้ายกำกับการจัดเก็บ",
|
||||
"oauth_storage_label_claim_description": "ตั้งป้ายกำกับการจัดเก็บของผู้ใช้งานตามสิทธิ์ที่ใช้อ้างถึงโดยอัตโนมัติ",
|
||||
"oauth_storage_label_claim": "สิทธิ์ที่ใช้อ้างถึงฉลากการจัดเก็บ",
|
||||
"oauth_storage_label_claim_description": "ตั้งฉลากการจัดเก็บของผู้ใช้งานตามสิทธิ์ที่ใช้อ้างถึงโดยอัตโนมัติ",
|
||||
"oauth_storage_quota_claim": "สิทธิ์ที่ใช้อ้างถึงโควต้าพื้นที่จัดเก็บ",
|
||||
"oauth_storage_quota_claim_description": "ตั้งโควต้าพื้นที่จัดเก็บของผู้ใช้งานตามสิทธิ์ที่ใช้อ้างถึงโดยอัตโนมัติ",
|
||||
"oauth_storage_quota_default": "โควต้าพื้นที่เก็บข้อมูลเริ่มต้น (GiB)",
|
||||
@@ -235,7 +235,7 @@
|
||||
"storage_template_hash_verification_enabled": "ตรวจสอบ hash ไม่ผ่าน",
|
||||
"storage_template_hash_verification_enabled_description": "เปิดใช้งานการตรวจสอบ hash ห้ามปิดใช้งานเว้นแต่คุณจะเข้าใจผลกระทบ",
|
||||
"storage_template_migration": "การย้ายเทมเพลตที่เก็บข้อมูล",
|
||||
"storage_template_migration_description": "ใช้<link>{template}</link>ปัจจุบันกับสื่อที่อัปโหลดก่อนหน้านี้",
|
||||
"storage_template_migration_description": "ใช้<link>{template}</link>ปัจจุบันกับสื่อที่อัพโหลดก่อนหน้านี้",
|
||||
"storage_template_migration_job": "",
|
||||
"storage_template_path_length": "ขีดจำกัดของความยาวพาธโดยประมาณ: <b>{length, number}</b>/{limit, number}",
|
||||
"storage_template_settings": "เทมเพลตการจัดเก็บข้อมูล",
|
||||
@@ -313,9 +313,6 @@
|
||||
"user_delete_delay_settings_description": "จํานวนวันหลังจากที่เอาออกเพื่อลบบัญชีผู้ใช้และสื่อถาวร งานลบบัญชีผู้ใช้ทํางานทุกเที่ยงคืนเพื่อตรวจสอบผู้ใช้ที่พร้อมที่จะถูกลบข้อมูลแล้ว การตั้งค่าครั้งนี้จะมีผลครั้งต่อไป",
|
||||
"user_delete_immediately": "บัญชีและสื่อของ <b>{user}</b> จะอยู่ในคิวสำหรับการลบถาวร <b>โดยทันที</b>",
|
||||
"user_settings": "การตั้งค่าผู้ใช้",
|
||||
"user_management": "การจัดการผู้ใช้",
|
||||
"user_password_has_been_reset": "รหัสผ่านของผู้ใช้ <b>{user}</b> ถูกตั้งค่าใหม่แล้ว",
|
||||
"user_password_reset_description": "รหัสผ่านของผู้ใช้จะถูกตั้งค่าใหม่และส่งไปยังอีเมลที่ลงทะเบียน",
|
||||
"user_settings_description": "จัดการการตั้งค่าผู้ใช้",
|
||||
"version_check_enabled_description": "เช็ค GitHub เป็นระยะ ๆ เพื่อตรวจสอบรุ่นใหม่",
|
||||
"version_check_settings": "ตรวจสอบรุ่น",
|
||||
@@ -350,14 +347,12 @@
|
||||
"allow_public_user_to_download": "อนุญาตให้ผู้ใช้สาธารณะดาวน์โหลดได้",
|
||||
"allow_public_user_to_upload": "อนุญาตให้ผู้ใช้สาธารณะอัปโหลดได้",
|
||||
"anti_clockwise": "ทวนเข็มนาฬิกา",
|
||||
"api_key": "API key",
|
||||
"api_keys": "API Keys",
|
||||
"api_key": "กุญแจ API",
|
||||
"api_keys": "กุญแจ API",
|
||||
"app_settings": "การตั้งค่าแอป",
|
||||
"appears_in": "อยู่ใน",
|
||||
"archive": "เก็บถาวร",
|
||||
"archive_or_unarchive_photo": "เก็บ/ไม่เก็บภาพถาวร",
|
||||
"archive_size": "ขนาดเก็บถาวร",
|
||||
"archive_size_description": "ตั้งค่าขนาดสูงสุดสำหรับการดาวน์โหลด (GiB)",
|
||||
"are_these_the_same_person": "เป็นคนเดียวกันหรือไม่?",
|
||||
"are_you_sure_to_do_this": "คุณแน่ใจว่าต้องการทำสิ่งนี้หรือไม่?",
|
||||
"asset_added_to_album": "เพิ่มไปยังอัลบั้มแล้ว",
|
||||
@@ -385,19 +380,19 @@
|
||||
"change_name": "เปลี่ยนชื่อ",
|
||||
"change_name_successfully": "เปลี่ยนชื่อเรียบร้อยแล้ว",
|
||||
"change_password": "เปลี่ยนรหัสผ่าน",
|
||||
"change_your_password": "เปลี่ยนรหัสผ่านของคุณ",
|
||||
"changed_visibility_successfully": "เปลี่ยนการมองเห็นเรียบร้อยแล้ว",
|
||||
"check_logs": "ตรวจสอบบันทึก",
|
||||
"change_your_password": "",
|
||||
"changed_visibility_successfully": "",
|
||||
"check_logs": "",
|
||||
"city": "เมือง",
|
||||
"clear": "ล้าง",
|
||||
"clear_all": "ล้างทั้งหมด",
|
||||
"clear_message": "ล้างข้อความ",
|
||||
"clear_value": "ล้างค่า",
|
||||
"clear_all": "",
|
||||
"clear_message": "",
|
||||
"clear_value": "",
|
||||
"close": "ปิด",
|
||||
"collapse": "ย่อ",
|
||||
"collapse_all": "ย่อทั้งหมด",
|
||||
"color": "สี",
|
||||
"color_theme": "สีธีม",
|
||||
"color_theme": "",
|
||||
"comment_deleted": "ลบความคิดเห็นแล้ว",
|
||||
"comment_options": "",
|
||||
"comments_and_likes": "ความคิดเห็นและการถูกใจ",
|
||||
@@ -455,17 +450,13 @@
|
||||
"discover": "ค้นพบ",
|
||||
"dismiss_all_errors": "ปฏิเสธข้อผิดพลาดทั้งหมด",
|
||||
"dismiss_error": "ปฏิเสธข้อผิดพลาด",
|
||||
"display_options": "ตัวเลือกการแสดง",
|
||||
"display_order": "ลำดับการแสดงผล",
|
||||
"display_original_photos": "แสดงภาพต้นฉบับ",
|
||||
"display_original_photos_setting_description": "การตั้งค่าแสดงผลรูปภาพต้นฉบับ เมื่อเปิดรูปภาพ การตั้งค่านี้อาจจะทำให้การแสดงภาพได้ช้าลง",
|
||||
"done": "ดำเนินการสำเร็จ",
|
||||
"display_options": "",
|
||||
"display_order": "",
|
||||
"display_original_photos": "",
|
||||
"display_original_photos_setting_description": "เมื่อดูสื่อให้แสดงภาพต้นฉบับแทนภาพตัวอย่างเมื่อไฟล์สื่อเปิดได้บนเว็บ อาจทําให้แสดง ภาพได้ช้าลง",
|
||||
"done": "เสร็จ",
|
||||
"download": "ดาวน์โหลด",
|
||||
"download_include_embedded_motion_videos": "รวมวิดีโอที่ฝังอยู่ในภาพเคลื่อนไหว",
|
||||
"download_include_embedded_motion_videos_description": "รวมวิดีโอที่ฝังอยู่ในภาพเคลื่อนไหวเมื่อดาวน์โหลดอัลบั้ม",
|
||||
"downloading": "กำลังดาวน์โหลด",
|
||||
"download_settings": "การตั้งค่าการดาวน์โหลด",
|
||||
"download_settings_description": "จัดการการตั้งค่าการดาวน์โหลด",
|
||||
"duration": "ระยะเวลา",
|
||||
"edit_album": "แก้ไขอัลบั้ม",
|
||||
"edit_avatar": "แก้ไขตัวละคร",
|
||||
@@ -492,38 +483,6 @@
|
||||
"error": "เกิดข้อผิดพลาด",
|
||||
"error_loading_image": "เกิดข้อผิดพลาดระหว่างโหลดภาพ",
|
||||
"errors": {
|
||||
"cannot_navigate_next_asset": "ไม่สามารถเปลี่ยนเส้นทางได้",
|
||||
"cannot_navigate_previous_asset": "ไม่สามารถเปลี่ยนเส้นทางก่อนหน้าได้",
|
||||
"cant_apply_changes": "เกิดข้อผิดพลาดในการเปลี่ยนแปลง",
|
||||
"cant_change_activity": "Can't {enabled, select, true {disable} other {enable}} activity",
|
||||
"cant_change_asset_favorite": "ไม่สามารถเปลี่ยนสื่อที่ชื่นชอบได้",
|
||||
"cant_change_metadata_assets_count": "Can't change metadata of {count, plural, one {# asset} other {# assets}}",
|
||||
"cant_get_faces": "เกิดข้อผิดพลาดในการเรียกดูใบหน้า",
|
||||
"cant_get_number_of_comments": "ไม่สามารถเรียกดูจำนวนความคิดเห็นได้",
|
||||
"cant_search_people": "ไม่สามารถค้นหาบุคคลคนได้",
|
||||
"cant_search_places": "ไม่สามารถค้นหาสถานที่ได้",
|
||||
"cleared_jobs": "ล้างงาน: {job} สำเร็จ",
|
||||
"error_adding_assets_to_album": "เกิดข้อผิดพลาดในการเพิ่มสื่อไปยังอัลบั้ม",
|
||||
"error_adding_users_to_album": "เกิดข้อผิดพลาดในการเพิ่มผู้ใช้ไปยังอัลบั้ม",
|
||||
"error_deleting_shared_user": "เกิดข้อผิดพลาดในการลบผู้ใช้ที่แชร์",
|
||||
"error_downloading": "ไม่สามารถดาวน์โหลด {filename} ได้",
|
||||
"error_hiding_buy_button": "Error hiding buy button",
|
||||
"error_removing_assets_from_album": "เกิดข้อผิดพลาดในการลบสื่อจากอัลบั้ม",
|
||||
"error_selecting_all_assets": "เกิดข้อผิดพลาดในการเลือกสื่อทั้งหมด",
|
||||
"exclusion_pattern_already_exists": "ข้อยกเว้นนี้มีอยู่แล้ว",
|
||||
"failed_job_command": "คำสั่ง {command} ผิดพลาด สำหรับ: {job}",
|
||||
"failed_to_create_album": "ไม่สามารถสร้างอัลบั้มได้",
|
||||
"failed_to_create_shared_link": "ไม่สามารถสร้างลิงก์ที่แชร์ได้",
|
||||
"failed_to_edit_shared_link": "ไม่สามารถแก้ไขลิงก์ที่แชร์ได้",
|
||||
"failed_to_get_people": "ไม่สามารถเรียกดูบุคคลได้",
|
||||
"failed_to_keep_this_delete_others": "ไม่สามารถเก็บหรือลบได้",
|
||||
"failed_to_load_asset": "ไม่สามารถโหลดสื่อได้",
|
||||
"failed_to_load_assets": "ไม่สามารถโหลดสื่อได้",
|
||||
"failed_to_load_people": "ไม่สามารถโหลดบุคคลได้",
|
||||
"failed_to_remove_product_key": "Failed to remove product key",
|
||||
"failed_to_stack_assets": "Failed to stack assets",
|
||||
"failed_to_unstack_assets": "Failed to un-stack assets",
|
||||
"incorrect_email_or_password": "อีเมลหรือรหัสผ่านไม่ถูกต้อง",
|
||||
"import_path_already_exists": "พาธนำเข้านี้มีอยู่แล้ว",
|
||||
"unable_to_add_album_users": "ไม่สามารถเพิ่มผู้ใช้ไปยังอัลบั้มได้",
|
||||
"unable_to_add_comment": "ไม่สามารถเพิ่มความเห็นได้",
|
||||
@@ -531,7 +490,7 @@
|
||||
"unable_to_change_album_user_role": "ไม่สามารถเปลี่ยนบทบาทผู้ใช้ในอัลบั้มได้",
|
||||
"unable_to_change_date": "ไม่สามารถเปลี่ยนวันที่ได้",
|
||||
"unable_to_change_location": "ไม่สามารถเปลี่ยนตําแหน่งได้",
|
||||
"unable_to_create_admin_account": "ไม่สามารถสร้างบัญชีผู้ดูแลระบบได้",
|
||||
"unable_to_create_admin_account": "",
|
||||
"unable_to_create_library": "ไม่สามารถสร้างคลังภาพได้",
|
||||
"unable_to_create_user": "ไม่สามารถสร้างผู้ใช้ได้",
|
||||
"unable_to_delete_album": "ไม่สามารถลบอัลบั้มได้",
|
||||
@@ -572,8 +531,8 @@
|
||||
"unable_to_update_settings": "ไม่สามารถอัพเดทการตั้งค่าได้",
|
||||
"unable_to_update_user": "ไม่สามารถอัพเดทผู้ใช้ได้"
|
||||
},
|
||||
"exit_slideshow": "ออกจากการนำเสนอ",
|
||||
"expand_all": "ขยายทั้งหมด",
|
||||
"exit_slideshow": "",
|
||||
"expand_all": "",
|
||||
"expire_after": "หมดอายุหลังจาก",
|
||||
"expired": "หมดอายุแล้ว",
|
||||
"explore": "สํารวจ",
|
||||
@@ -583,25 +542,22 @@
|
||||
"favorite_or_unfavorite_photo": "โปรดหรือไม่โปรดภาพ",
|
||||
"favorites": "รายการโปรด",
|
||||
"feature_photo_updated": "อัพเดทภาพเด่นแล้ว",
|
||||
"file_name": "ชื่อไฟล์",
|
||||
"file_name_or_extension": "นามสกุลหรือชื่อไฟล์",
|
||||
"file_name": "",
|
||||
"file_name_or_extension": "",
|
||||
"filename": "ชื่อไฟล์",
|
||||
"filetype": "ชนิดไฟล์",
|
||||
"filter_people": "กรองผู้คน",
|
||||
"fix_incorrect_match": "แก้ไขการจับคู่ที่ไม่ถูกต้อง",
|
||||
"fix_incorrect_match": "",
|
||||
"forward": "ไปข้างหน้า",
|
||||
"general": "ทั่วไป",
|
||||
"get_help": "ขอความช่วยเหลือ",
|
||||
"getting_started": "เริ่มต้นใช้งาน",
|
||||
"go_back": "กลับ",
|
||||
"go_to_search": "กลับไปยังการค้นหา",
|
||||
"group_albums_by": "จัดกลุ่มอัลบั้มตาม",
|
||||
"group_no": "ไม่จัดกลุ่ม",
|
||||
"group_owner": "จัดกลุ่มโดยเจ้าของ",
|
||||
"group_year": "จัดกลุ่มตามปี",
|
||||
"has_quota": "เหลือพื้นที่",
|
||||
"get_help": "",
|
||||
"getting_started": "",
|
||||
"go_back": "",
|
||||
"go_to_search": "",
|
||||
"group_albums_by": "",
|
||||
"has_quota": "",
|
||||
"hide_gallery": "ซ่อนคลังภาพ",
|
||||
"hide_password": "ซ่อนรหัสผ่าน",
|
||||
"hide_password": "",
|
||||
"hide_person": "ซ่อนบุคคล",
|
||||
"host": "โฮสต์",
|
||||
"hour": "ชั่วโมง",
|
||||
@@ -698,7 +654,7 @@
|
||||
"no_assets_message": "กดเพื่อใส่ภาพคุณภาพแรก",
|
||||
"no_duplicates_found": "ไม่พบรายการที่ซ้ำกัน",
|
||||
"no_exif_info_available": "ไม่มีข้อมูล exif",
|
||||
"no_explore_results_message": "ไม่พบผลลัพธ์ ลองใช้คำค้นหาอื่น ๆ",
|
||||
"no_explore_results_message": "",
|
||||
"no_favorites_message": "เพิ่มรายการโปรดเพื่อค้นหาภาพและวิดีโอที่ดีที่สุดของคุณอย่างรวดเร็ว",
|
||||
"no_libraries_message": "สร้างคลังภาพภายนอกเพื่อดูภาพถ่ายและวิดีโอต่าง ๆ ของคุณ",
|
||||
"no_name": "ไม่มีชื่อ",
|
||||
@@ -714,9 +670,9 @@
|
||||
"oauth": "OAuth",
|
||||
"official_immich_resources": "แหล่งข้อมูล Immich อย่างเป็นทางการ",
|
||||
"offline": "ออฟไลน์",
|
||||
"ok": "ตกลง",
|
||||
"oldest_first": "เรียงเก่าสุดก่อน",
|
||||
"onboarding_welcome_user": "ยินดีต้อนรับคุณ {user}",
|
||||
"ok": "โอเค",
|
||||
"oldest_first": "เก่าสุดก่อน",
|
||||
"onboarding_welcome_user": "ยินดีต้อนรับ {user}",
|
||||
"online": "ออนไลน์",
|
||||
"only_favorites": "รายการโปรดเท่านั้น",
|
||||
"open_in_openstreetmap": "เปิดใน OpenStreetMap",
|
||||
@@ -746,9 +702,9 @@
|
||||
"years": "{years, plural, one {ปี} other {# ปี}}ที่ผ่านมา"
|
||||
},
|
||||
"path": "",
|
||||
"pattern": "รูปแบบ",
|
||||
"pattern": "",
|
||||
"pause": "หยุด",
|
||||
"pause_memories": "หยุดดูความทรงจํา",
|
||||
"pause_memories": "",
|
||||
"paused": "หยุด",
|
||||
"pending": "กำลังรอ",
|
||||
"people": "ผู้คน",
|
||||
@@ -767,7 +723,7 @@
|
||||
"play_motion_photo": "เล่นภาพวัตถุเคลื่อนไหว",
|
||||
"play_or_pause_video": "เล่นหรือหยุดวิดีโอ",
|
||||
"port": "พอร์ต",
|
||||
"preset": "พรีเซ็ต",
|
||||
"preset": "",
|
||||
"preview": "ตัวอย่าง",
|
||||
"previous": "ก่อนหน้า",
|
||||
"previous_memory": "ความทรงจําก่อนหน้า",
|
||||
@@ -783,65 +739,61 @@
|
||||
"refreshed": "รีเฟรช",
|
||||
"refreshes_every_file": "รีเฟรชทุกไฟล์",
|
||||
"remove": "ลบ",
|
||||
"remove_deleted_assets": "ลบสื่อที่ถูกลบ",
|
||||
"remove_deleted_assets": "",
|
||||
"remove_from_album": "ลบออกจากอัลบั้ม",
|
||||
"remove_from_favorites": "เอาออกจากรายการโปรด",
|
||||
"remove_from_shared_link": "ลบออกจากลิงก์ที่แชร์",
|
||||
"repair": "ซ่อม",
|
||||
"repair_no_results_message": "ไม่สามารถซ่อมแซมได้",
|
||||
"replace_with_upload": "อัปโหลดทับรูปหรือวิดีโอนี้",
|
||||
"repair_no_results_message": "",
|
||||
"replace_with_upload": "",
|
||||
"require_password": "ต้องการรหัสผ่าน",
|
||||
"reset": "รีเซ็ต",
|
||||
"reset_password": "ตั้งค่ารหัสผ่านใหม่",
|
||||
"reset_people_visibility": "ปรับการมองเห็นใหม่",
|
||||
"restore": "เรียกคืน",
|
||||
"restore_all": "เรียกคืนทั้งหมด",
|
||||
"restore_user": "เรียกคืนผู้ใช้",
|
||||
"retry_upload": "ลองอัปโหลดใหม่",
|
||||
"review_duplicates": "ตรวจสอบรายการที่ซ้ำกัน",
|
||||
"retry_upload": "ลองอัพโหลดใหม่",
|
||||
"review_duplicates": "",
|
||||
"role": "บทบาท",
|
||||
"save": "บันทึก",
|
||||
"saved_profile": "แก้ไขโปรไฟล์สำเร็จ",
|
||||
"saved_settings": "บันทึกการตั้งค่าสำเร็จ",
|
||||
"saved_profile": "โพรไฟล์ที่บันทึกไว้",
|
||||
"saved_settings": "การตั้งค่าที่บันทึกไว้",
|
||||
"say_something": "พูดอะไรสักอย่าง",
|
||||
"scan_all_libraries": "สแกนคลังภาพทั้งหมด",
|
||||
"scan_settings": "ตั้งค่าการสแกน",
|
||||
"search": "ค้นหา",
|
||||
"search_albums": "ค้นหาอัลบั้ม",
|
||||
"search_by_context": "ค้นหาตามบริบท",
|
||||
"search_albums": "",
|
||||
"search_by_context": "",
|
||||
"search_camera_make": "",
|
||||
"search_camera_model": "",
|
||||
"search_city": "ค้นหาตามเมือง",
|
||||
"search_country": "ค้นหาตามประเทศ",
|
||||
"search_for_existing_person": "ค้นหาบุคคลที่มีอยู่",
|
||||
"search_no_people": "ไม่พบบุคคลคน",
|
||||
"search_no_people_named": "ไม่พบ \"{name}\"",
|
||||
"search_options": "ตัวเลือกการค้นหา",
|
||||
"search_city": "",
|
||||
"search_country": "",
|
||||
"search_for_existing_person": "",
|
||||
"search_people": "ค้นหาผู้คน",
|
||||
"search_places": "ค้นหาสถานที่",
|
||||
"search_state": "ค้นหาตามรัฐ",
|
||||
"search_timezone": "ค้นหาตามวันที่และเวลา",
|
||||
"search_type": "ค้นหาตามประเภท",
|
||||
"search_places": "",
|
||||
"search_state": "",
|
||||
"search_timezone": "",
|
||||
"search_type": "",
|
||||
"search_your_photos": "ค้นหารูปภาพของคุณ",
|
||||
"searching_locales": "ค้นหาตามภูมิภาค",
|
||||
"searching_locales": "",
|
||||
"second": "วินาที",
|
||||
"select_album_cover": "เลือกภาพปกอัลบั้ม",
|
||||
"select_all": "เลือกทั้งหมด",
|
||||
"select_avatar_color": "เลือกสีพื้นหลังของรูปโปรไฟล์",
|
||||
"select_face": "เลือกใบหน้า",
|
||||
"select_album_cover": "",
|
||||
"select_all": "",
|
||||
"select_avatar_color": "",
|
||||
"select_face": "",
|
||||
"select_featured_photo": "เลือกภาพเด่น",
|
||||
"select_library_owner": "เลือกเจ้าของคลังภาพ",
|
||||
"select_new_face": "เลือกใบหน้าใหม่",
|
||||
"select_new_face": "",
|
||||
"select_photos": "เลือกรูปภาพ",
|
||||
"selected": "เลือก",
|
||||
"send_message": "ส่งข้อความ",
|
||||
"server_stats": "สถิติเซิร์ฟเวอร์",
|
||||
"send_message": "",
|
||||
"server_stats": "",
|
||||
"set": "",
|
||||
"set_as_album_cover": "ตั้งเป็นภาพปกอัลบั้ม",
|
||||
"set_as_profile_picture": "ตั้งเป็นรูปโปรไฟล์",
|
||||
"set_date_of_birth": "ตั้งวันเกิด",
|
||||
"set_profile_picture": "ตั้งรูปโปรไฟล์",
|
||||
"set_slideshow_to_fullscreen": "ตั้งค่าการนำเสนอเต็มจอ",
|
||||
"set_as_album_cover": "",
|
||||
"set_as_profile_picture": "",
|
||||
"set_date_of_birth": "",
|
||||
"set_profile_picture": "",
|
||||
"set_slideshow_to_fullscreen": "",
|
||||
"settings": "ตั้งค่า",
|
||||
"settings_saved": "บันทึกการตั้งค่าแล้ว",
|
||||
"share": "แชร์",
|
||||
@@ -865,21 +817,12 @@
|
||||
"show_progress_bar": "แสดงความคืบหน้า แถบ",
|
||||
"show_search_options": "แสดงตัวเลือกการค้นหา",
|
||||
"shuffle": "สับเปลี่ยน",
|
||||
"sidebar": "แถบด้านข้าง",
|
||||
"sidebar_display_description": "เปิดหรือปิดแถบด้านข้าง",
|
||||
"sign_out": "ออกจากระบบ",
|
||||
"sign_up": "ลงทะเบียน",
|
||||
"size": "ขนาด",
|
||||
"skip_to_content": "ข้ามไปยังเนื้อหา",
|
||||
"slideshow": "สไลด์",
|
||||
"slideshow_settings": "ตั้งค่าสไลด์",
|
||||
"sort_created": "จัดเรียงตามวันที่สร้าง",
|
||||
"sort_items": "จัดเรียงรายการ",
|
||||
"sort_modified": "จัดเรียงตามวันที่แก้ไข",
|
||||
"sort_oldest": "จัดเรียงตามเก่าสุด",
|
||||
"sort_people_by_similarity": "จุดเรียงบุคคลตามความคล้ายคลึง",
|
||||
"sort_recent": "จัดเรียงใหม่ล่าสุด",
|
||||
"sort_albums_by": "จัดเรียงอัลบั้มโดย...",
|
||||
"sort_albums_by": "เรียงอัลบั้มโดย...",
|
||||
"stack": "ซ้อน",
|
||||
"stack_selected_photos": "",
|
||||
"stacktrace": "",
|
||||
@@ -888,30 +831,25 @@
|
||||
"status": "สถานะ",
|
||||
"stop_motion_photo": "ภาพวัตถุเคลื่อนไหว",
|
||||
"stop_photo_sharing": "หยุดแชร์รูปภาพ?",
|
||||
"storage": "พื้นที่จัดเก็บ",
|
||||
"storage_label": "เนื้อที่จัดเก็บ",
|
||||
"storage_usage": "ใช้ไป {used} จาก {available} ",
|
||||
"storage": "ที่จัดเก็บ",
|
||||
"storage_label": "ฉลากจัดเก็บ",
|
||||
"submit": "ส่ง",
|
||||
"suggestions": "ข้อเสนอแนะ",
|
||||
"sunrise_on_the_beach": "พระอาทิตย์ขึ้นบนชายหาด",
|
||||
"swap_merge_direction": "สลับด้านรวม",
|
||||
"sync": "ซิงค์",
|
||||
"template": "แทมแพลค",
|
||||
"template": "แม่แบบ",
|
||||
"theme": "ธีม",
|
||||
"theme_selection": "การเลือกธีม",
|
||||
"theme_selection_description": "ตั้งค่าธีมให้สว่างหรือมืดโดยอัตโนมัติ อิงจากค่าของเบราว์เซอร์ของคุณ",
|
||||
"time_based_memories": "ความทรงจําตามเวลา",
|
||||
"timezone": "เขตเวลา",
|
||||
"timeline": "Timeline",
|
||||
"to_archive": "จัดเก็บถาวร",
|
||||
"to_change_password": "Change password",
|
||||
"toggle_settings": "สลับการตั้งค่า",
|
||||
"toggle_theme": "สลับธีม",
|
||||
"total_usage": "การใช้งานรวม",
|
||||
"trash": "ถังขยะ",
|
||||
"trash": "ขยะ",
|
||||
"trash_all": "ทิ้งทั้งหมด",
|
||||
"trash_no_results_message": "รูปภาพหรือวิดีโอที่ถูกลบจะอยู่ที่นี่",
|
||||
"trashed_items_will_be_permanently_deleted_after": "รายการที่ถูกลบจะถูกลบทิ้งภายใน {days, plural, one {# วัน} other {# วัน}}.",
|
||||
"trash_no_results_message": "รูปและวีดีโอที่ถูกทิ้งจะมาโผล่ที่นี่",
|
||||
"type": "ประเภท",
|
||||
"unarchive": "นำออกจากที่เก็บถาวร",
|
||||
"unfavorite": "นำออกจากรายการโปรด",
|
||||
@@ -924,8 +862,8 @@
|
||||
"unstack": "หยุดซ้อน",
|
||||
"up_next": "ต่อไป",
|
||||
"updated_password": "รหัสผ่านเปลี่ยนแล้ว",
|
||||
"upload": "อัปโหลด",
|
||||
"upload_concurrency": "อัปโหลดพร้อมกัน",
|
||||
"upload": "อัพโหลด",
|
||||
"upload_concurrency": "อัพโหลดพร้อมกัน",
|
||||
"url": "URL",
|
||||
"usage": "การใช้งาน",
|
||||
"user": "ผู้ใช้",
|
||||
@@ -935,7 +873,7 @@
|
||||
"user_usage_stats_description": "ดูสถิติการใช้งานบัญชี",
|
||||
"username": "ชื่อผู้ใช้",
|
||||
"users": "ผู้ใช้",
|
||||
"utilities": "เครื่องมือ",
|
||||
"utilities": "",
|
||||
"validate": "ตรวจสอบ",
|
||||
"variables": "ตัวแปร",
|
||||
"version": "รุ่น",
|
||||
|
||||
@@ -51,10 +51,6 @@ start_docker_compose() {
|
||||
show_friendly_message() {
|
||||
local ip_address
|
||||
ip_address=$(hostname -I | awk '{print $1}')
|
||||
# If length of ip_address is 0, then we are on a Mac
|
||||
if [ ${#ip_address} -eq 0 ]; then
|
||||
ip_address=$(ipconfig getifaddr en0)
|
||||
fi
|
||||
cat <<EOF
|
||||
Successfully deployed Immich!
|
||||
You can access the website or the mobile app at http://$ip_address:2283
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG DEVICE=cpu
|
||||
|
||||
FROM python:3.11-bookworm@sha256:14b4620f59a90f163dfa6bd252b68743f9a41d494a9fde935f9d7669d98094bb AS builder-cpu
|
||||
FROM python:3.11-bookworm@sha256:adb581d8ed80edd03efd4dcad66db115b9ce8de8522b01720b9f3e6146f0884c AS builder-cpu
|
||||
|
||||
FROM builder-cpu AS builder-openvino
|
||||
|
||||
@@ -34,7 +34,7 @@ RUN python3 -m venv /opt/venv
|
||||
COPY poetry.lock pyproject.toml ./
|
||||
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
|
||||
|
||||
FROM python:3.11-slim-bookworm@sha256:42420f737ba91d509fc60d5ed65ed0492678a90c561e1fa08786ae8ba8b52eda AS prod-cpu
|
||||
FROM python:3.11-slim-bookworm@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS prod-cpu
|
||||
|
||||
FROM prod-cpu AS prod-openvino
|
||||
|
||||
@@ -106,22 +106,6 @@ COPY --from=builder /opt/venv /opt/venv
|
||||
COPY ann/ann.py /usr/src/ann/ann.py
|
||||
COPY start.sh log_conf.json gunicorn_conf.py ./
|
||||
COPY app .
|
||||
|
||||
ARG BUILD_ID
|
||||
ARG BUILD_IMAGE
|
||||
ARG BUILD_SOURCE_REF
|
||||
ARG BUILD_SOURCE_COMMIT
|
||||
|
||||
ENV IMMICH_BUILD=${BUILD_ID}
|
||||
ENV IMMICH_BUILD_URL=https://github.com/immich-app/immich/actions/runs/${BUILD_ID}
|
||||
ENV IMMICH_BUILD_IMAGE=${BUILD_IMAGE}
|
||||
ENV IMMICH_BUILD_IMAGE_URL=https://github.com/immich-app/immich/pkgs/container/immich-machine-learning
|
||||
ENV IMMICH_REPOSITORY=immich-app/immich
|
||||
ENV IMMICH_REPOSITORY_URL=https://github.com/immich-app/immich
|
||||
ENV IMMICH_SOURCE_REF=${BUILD_SOURCE_REF}
|
||||
ENV IMMICH_SOURCE_COMMIT=${BUILD_SOURCE_COMMIT}
|
||||
ENV IMMICH_SOURCE_URL=https://github.com/immich-app/immich/commit/${BUILD_SOURCE_COMMIT}
|
||||
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
CMD ["./start.sh"]
|
||||
|
||||
|
||||
314
machine-learning/poetry.lock
generated
314
machine-learning/poetry.lock
generated
@@ -758,23 +758,23 @@ test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.115.8"
|
||||
version = "0.115.6"
|
||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf"},
|
||||
{file = "fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9"},
|
||||
{file = "fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305"},
|
||||
{file = "fastapi-0.115.6.tar.gz", hash = "sha256:9ec46f7addc14ea472958a96aae5b5de65f39721a46aaf5705c480d9a8b76654"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
|
||||
starlette = ">=0.40.0,<0.46.0"
|
||||
starlette = ">=0.40.0,<0.42.0"
|
||||
typing-extensions = ">=4.8.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
|
||||
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
@@ -1331,13 +1331,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "huggingface-hub"
|
||||
version = "0.28.1"
|
||||
version = "0.27.1"
|
||||
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "huggingface_hub-0.28.1-py3-none-any.whl", hash = "sha256:aa6b9a3ffdae939b72c464dbb0d7f99f56e649b55c3d52406f49e0a5a620c0a7"},
|
||||
{file = "huggingface_hub-0.28.1.tar.gz", hash = "sha256:893471090c98e3b6efbdfdacafe4052b20b84d59866fb6f54c33d9af18c303ae"},
|
||||
{file = "huggingface_hub-0.27.1-py3-none-any.whl", hash = "sha256:1c5155ca7d60b60c2e2fc38cbb3ffb7f7c3adf48f824015b219af9061771daec"},
|
||||
{file = "huggingface_hub-0.27.1.tar.gz", hash = "sha256:c004463ca870283909d715d20f066ebd6968c2207dae9393fdffb3c1d4d8f98b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1350,13 +1350,13 @@ tqdm = ">=4.42.1"
|
||||
typing-extensions = ">=3.7.4.3"
|
||||
|
||||
[package.extras]
|
||||
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
cli = ["InquirerPy (==0.3.4)"]
|
||||
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||
fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
|
||||
hf-transfer = ["hf-transfer (>=0.1.4)"]
|
||||
inference = ["aiohttp"]
|
||||
quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.9.0)"]
|
||||
quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.5.0)"]
|
||||
tensorflow = ["graphviz", "pydot", "tensorflow"]
|
||||
tensorflow-testing = ["keras (<3.0)", "tensorflow"]
|
||||
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
||||
@@ -1625,13 +1625,13 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "locust"
|
||||
version = "2.32.9"
|
||||
version = "2.32.6"
|
||||
description = "Developer-friendly load testing framework"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "locust-2.32.9-py3-none-any.whl", hash = "sha256:d9447c26d2bbaec5a0ace7cadefa1a31820ed392234257b309965a43d5e8d26f"},
|
||||
{file = "locust-2.32.9.tar.gz", hash = "sha256:4c297afa5cdc3de15dfa79279576e5f33c1d69dd70006b51d079dcbd212201cc"},
|
||||
{file = "locust-2.32.6-py3-none-any.whl", hash = "sha256:d5c0e4f73134415d250087034431cf3ea42ca695d3dee7f10812287cacb6c4ef"},
|
||||
{file = "locust-2.32.6.tar.gz", hash = "sha256:6600cc308398e724764aacc56ccddf6cfcd0127c4c92dedd5c4979dd37ef5b15"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1649,8 +1649,8 @@ psutil = ">=5.9.1"
|
||||
pywin32 = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
pyzmq = ">=25.0.0"
|
||||
requests = [
|
||||
{version = ">=2.26.0", markers = "python_full_version <= \"3.11.0\""},
|
||||
{version = ">=2.32.2", markers = "python_full_version > \"3.11.0\""},
|
||||
{version = ">=2.26.0", markers = "python_full_version <= \"3.11.0\""},
|
||||
]
|
||||
setuptools = ">=70.0.0"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
@@ -1893,43 +1893,49 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.15.0"
|
||||
version = "1.14.1"
|
||||
description = "Optional static typing for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"},
|
||||
{file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"},
|
||||
{file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b"},
|
||||
{file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3"},
|
||||
{file = "mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b"},
|
||||
{file = "mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f"},
|
||||
{file = "mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e"},
|
||||
{file = "mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357"},
|
||||
{file = "mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2"},
|
||||
{file = "mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980"},
|
||||
{file = "mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e"},
|
||||
{file = "mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"},
|
||||
{file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"},
|
||||
{file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"},
|
||||
{file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"},
|
||||
{file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"},
|
||||
{file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"},
|
||||
{file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"},
|
||||
{file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"},
|
||||
{file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2175,98 +2181,94 @@ files = [
|
||||
|
||||
[package.dependencies]
|
||||
numpy = [
|
||||
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
||||
{version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""},
|
||||
{version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""},
|
||||
{version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""},
|
||||
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.10.15"
|
||||
version = "3.10.14"
|
||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab"},
|
||||
{file = "orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e"},
|
||||
{file = "orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665"},
|
||||
{file = "orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890"},
|
||||
{file = "orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5e8afd6200e12771467a1a44e5ad780614b86abb4b11862ec54861a82d677746"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da9a18c500f19273e9e104cca8c1f0b40a6470bcccfc33afcc088045d0bf5ea6"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb00b7bfbdf5d34a13180e4805d76b4567025da19a197645ca746fc2fb536586"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33aedc3d903378e257047fee506f11e0833146ca3e57a1a1fb0ddb789876c1e1"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0099ae6aed5eb1fc84c9eb72b95505a3df4267e6962eb93cdd5af03be71c98"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c864a80a2d467d7786274fce0e4f93ef2a7ca4ff31f7fc5634225aaa4e9e98c"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c25774c9e88a3e0013d7d1a6c8056926b607a61edd423b50eb5c88fd7f2823ae"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e78c211d0074e783d824ce7bb85bf459f93a233eb67a5b5003498232ddfb0e8a"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:43e17289ffdbbac8f39243916c893d2ae41a2ea1a9cbb060a56a4d75286351ae"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:781d54657063f361e89714293c095f506c533582ee40a426cb6489c48a637b81"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6875210307d36c94873f553786a808af2788e362bd0cf4c8e66d976791e7b528"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-win32.whl", hash = "sha256:305b38b2b8f8083cc3d618927d7f424349afce5975b316d33075ef0f73576b60"},
|
||||
{file = "orjson-3.10.15-cp38-cp38-win_amd64.whl", hash = "sha256:5dd9ef1639878cc3efffed349543cbf9372bdbd79f478615a1c633fe4e4180d1"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ffe19f3e8d68111e8644d4f4e267a069ca427926855582ff01fc012496d19969"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d433bf32a363823863a96561a555227c18a522a8217a6f9400f00ddc70139ae2"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da03392674f59a95d03fa5fb9fe3a160b0511ad84b7a3914699ea5a1b3a38da2"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a63bb41559b05360ded9132032239e47983a39b151af1201f07ec9370715c82"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3766ac4702f8f795ff3fa067968e806b4344af257011858cc3d6d8721588b53f"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1c73dcc8fadbd7c55802d9aa093b36878d34a3b3222c41052ce6b0fc65f8e8"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b299383825eafe642cbab34be762ccff9fd3408d72726a6b2a4506d410a71ab3"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:abc7abecdbf67a173ef1316036ebbf54ce400ef2300b4e26a7b843bd446c2480"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3614ea508d522a621384c1d6639016a5a2e4f027f3e4a1c93a51867615d28829"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:295c70f9dc154307777ba30fe29ff15c1bcc9dfc5c48632f37d20a607e9ba85a"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:63309e3ff924c62404923c80b9e2048c1f74ba4b615e7584584389ada50ed428"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-win32.whl", hash = "sha256:a2f708c62d026fb5340788ba94a55c23df4e1869fec74be455e0b2f5363b8507"},
|
||||
{file = "orjson-3.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:efcf6c735c3d22ef60c4aa27a5238f1a477df85e9b15f2142f9d669beb2d13fd"},
|
||||
{file = "orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:849ea7845a55f09965826e816cdc7689d6cf74fe9223d79d758c714af955bcb6"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5947b139dfa33f72eecc63f17e45230a97e741942955a6c9e650069305eb73d"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cde6d76910d3179dae70f164466692f4ea36da124d6fb1a61399ca589e81d69a"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6dfbaeb7afa77ca608a50e2770a0461177b63a99520d4928e27591b142c74b1"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa45e489ef80f28ff0e5ba0a72812b8cfc7c1ef8b46a694723807d1b07c89ebb"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5007abfdbb1d866e2aa8990bd1c465f0f6da71d19e695fc278282be12cffa5"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b49e2af011c84c3f2d541bb5cd1e3c7c2df672223e7e3ea608f09cf295e5f8a"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:164ac155109226b3a2606ee6dda899ccfbe6e7e18b5bdc3fbc00f79cc074157d"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6b1225024cf0ef5d15934b5ffe9baf860fe8bc68a796513f5ea4f5056de30bca"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d6546e8073dc382e60fcae4a001a5a1bc46da5eab4a4878acc2d12072d6166d5"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f1d2942605c894162252d6259b0121bf1cb493071a1ea8cb35d79cb3e6ac5bc"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-win32.whl", hash = "sha256:397083806abd51cf2b3bbbf6c347575374d160331a2d33c5823e22249ad3118b"},
|
||||
{file = "orjson-3.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:fa18f949d3183a8d468367056be989666ac2bef3a72eece0bade9cdb733b3c28"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f506fd666dd1ecd15a832bebc66c4df45c1902fd47526292836c339f7ba665a9"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe5fd254cfb0eeee13b8ef7ecb20f5d5a56ddda8a587f3852ab2cedfefdb5f6"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ddc8c866d7467f5ee2991397d2ea94bcf60d0048bdd8ca555740b56f9042725"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af8e42ae4363773658b8d578d56dedffb4f05ceeb4d1d4dd3fb504950b45526"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84dd83110503bc10e94322bf3ffab8bc49150176b49b4984dc1cce4c0a993bf9"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36f5bfc0399cd4811bf10ec7a759c7ab0cd18080956af8ee138097d5b5296a95"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868943660fb2a1e6b6b965b74430c16a79320b665b28dd4511d15ad5038d37d5"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33449c67195969b1a677533dee9d76e006001213a24501333624623e13c7cc8e"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4c9f60f9fb0b5be66e416dcd8c9d94c3eabff3801d875bdb1f8ffc12cf86905"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0de4d6315cfdbd9ec803b945c23b3a68207fd47cbe43626036d97e8e9561a436"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83adda3db595cb1a7e2237029b3249c85afbe5c747d26b41b802e7482cb3933e"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-win32.whl", hash = "sha256:998019ef74a4997a9d741b1473533cdb8faa31373afc9849b35129b4b8ec048d"},
|
||||
{file = "orjson-3.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:9d034abdd36f0f0f2240f91492684e5043d46f290525d1117712d5b8137784eb"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-win32.whl", hash = "sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1"},
|
||||
{file = "orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:0905ca08a10f7e0e0c97d11359609300eb1437490a7f32bbaa349de757e2e0c7"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92d13292249f9f2a3e418cbc307a9fbbef043c65f4bd8ba1eb620bc2aaba3d15"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90937664e776ad316d64251e2fa2ad69265e4443067668e4727074fe39676414"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9ed3d26c4cb4f6babaf791aa46a029265850e80ec2a566581f5c2ee1a14df4f1"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:56ee546c2bbe9599aba78169f99d1dc33301853e897dbaf642d654248280dc6e"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:901e826cb2f1bdc1fcef3ef59adf0c451e8f7c0b5deb26c1a933fb66fb505eae"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26336c0d4b2d44636e1e1e6ed1002f03c6aae4a8a9329561c8883f135e9ff010"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-win32.whl", hash = "sha256:e2bc525e335a8545c4e48f84dd0328bc46158c9aaeb8a1c2276546e94540ea3d"},
|
||||
{file = "orjson-3.10.14-cp313-cp313-win_amd64.whl", hash = "sha256:eca04dfd792cedad53dc9a917da1a522486255360cb4e77619343a20d9f35364"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9a0fba3b8a587a54c18585f077dcab6dd251c170d85cfa4d063d5746cd595a0f"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:175abf3d20e737fec47261d278f95031736a49d7832a09ab684026528c4d96db"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29ca1a93e035d570e8b791b6c0feddd403c6a5388bfe870bf2aa6bba1b9d9b8e"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f77202c80e8ab5a1d1e9faf642343bee5aaf332061e1ada4e9147dbd9eb00c46"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e2ec73b7099b6a29b40a62e08a23b936423bd35529f8f55c42e27acccde7954"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2d1679df9f9cd9504f8dff24555c1eaabba8aad7f5914f28dab99e3c2552c9d"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691ab9a13834310a263664313e4f747ceb93662d14a8bdf20eb97d27ed488f16"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b11ed82054fce82fb74cea33247d825d05ad6a4015ecfc02af5fbce442fbf361"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:e70a1d62b8288677d48f3bea66c21586a5f999c64ecd3878edb7393e8d1b548d"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:16642f10c1ca5611251bd835de9914a4b03095e28a34c8ba6a5500b5074338bd"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3871bad546aa66c155e3f36f99c459780c2a392d502a64e23fb96d9abf338511"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-win32.whl", hash = "sha256:0293a88815e9bb5c90af4045f81ed364d982f955d12052d989d844d6c4e50945"},
|
||||
{file = "orjson-3.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:6169d3868b190d6b21adc8e61f64e3db30f50559dfbdef34a1cd6c738d409dfc"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:06d4ec218b1ec1467d8d64da4e123b4794c781b536203c309ca0f52819a16c03"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962c2ec0dcaf22b76dee9831fdf0c4a33d4bf9a257a2bc5d4adc00d5c8ad9034"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:21d3be4132f71ef1360385770474f29ea1538a242eef72ac4934fe142800e37f"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c28ed60597c149a9e3f5ad6dd9cebaee6fb2f0e3f2d159a4a2b9b862d4748860"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e947f70167fe18469f2023644e91ab3d24f9aed69a5e1c78e2c81b9cea553fb"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64410696c97a35af2432dea7bdc4ce32416458159430ef1b4beb79fd30093ad6"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8050a5d81c022561ee29cd2739de5b4445f3c72f39423fde80a63299c1892c52"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b49a28e30d3eca86db3fe6f9b7f4152fcacbb4a467953cd1b42b94b479b77956"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ca041ad20291a65d853a9523744eebc3f5a4b2f7634e99f8fe88320695ddf766"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d313a2998b74bb26e9e371851a173a9b9474764916f1fc7971095699b3c6e964"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7796692136a67b3e301ef9052bde6fe8e7bd5200da766811a3a608ffa62aaff0"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-win32.whl", hash = "sha256:eee4bc767f348fba485ed9dc576ca58b0a9eac237f0e160f7a59bce628ed06b3"},
|
||||
{file = "orjson-3.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:96a1c0ee30fb113b3ae3c748fd75ca74a157ff4c58476c47db4d61518962a011"},
|
||||
{file = "orjson-3.10.14.tar.gz", hash = "sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2496,13 +2498,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.10.6"
|
||||
version = "2.10.5"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"},
|
||||
{file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"},
|
||||
{file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"},
|
||||
{file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2710,13 +2712,13 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.25.3"
|
||||
version = "0.25.2"
|
||||
description = "Pytest support for asyncio"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pytest_asyncio-0.25.3-py3-none-any.whl", hash = "sha256:9e89518e0f9bd08928f97a3482fdc4e244df17529460bc038291ccaf8f85c7c3"},
|
||||
{file = "pytest_asyncio-0.25.3.tar.gz", hash = "sha256:fc1da2cf9f125ada7e710b4ddad05518d4cee187ae9412e9ac9271003497f07a"},
|
||||
{file = "pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075"},
|
||||
{file = "pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3047,29 +3049,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.9.6"
|
||||
version = "0.9.2"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"},
|
||||
{file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"},
|
||||
{file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"},
|
||||
{file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"},
|
||||
{file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"},
|
||||
{file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"},
|
||||
{file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"},
|
||||
{file = "ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347"},
|
||||
{file = "ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00"},
|
||||
{file = "ruff-0.9.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df"},
|
||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247"},
|
||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e"},
|
||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe"},
|
||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb"},
|
||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a"},
|
||||
{file = "ruff-0.9.2-py3-none-win32.whl", hash = "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145"},
|
||||
{file = "ruff-0.9.2-py3-none-win_amd64.whl", hash = "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5"},
|
||||
{file = "ruff-0.9.2-py3-none-win_arm64.whl", hash = "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6"},
|
||||
{file = "ruff-0.9.2.tar.gz", hash = "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "machine-learning"
|
||||
version = "1.126.1"
|
||||
version = "1.125.6"
|
||||
description = ""
|
||||
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
echo "Initializing Immich ML $IMMICH_SOURCE_REF"
|
||||
|
||||
lib_path="/usr/lib/$(arch)-linux-gnu/libmimalloc.so.2"
|
||||
# mimalloc seems to increase memory usage dramatically with openvino, need to investigate
|
||||
if ! [ "$DEVICE" = "openvino" ]; then
|
||||
|
||||
@@ -35,8 +35,8 @@ platform :android do
|
||||
task: 'bundle',
|
||||
build_type: 'Release',
|
||||
properties: {
|
||||
"android.injected.version.code" => 184,
|
||||
"android.injected.version.name" => "1.126.1",
|
||||
"android.injected.version.code" => 182,
|
||||
"android.injected.version.name" => "1.125.6",
|
||||
}
|
||||
)
|
||||
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')
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
{
|
||||
"search_filter_contextual": "Search by context",
|
||||
"search_filter_filename": "Search by file name",
|
||||
"search_filter_description": "Search by description",
|
||||
"search_no_result": "No results found, try a different search term or combination",
|
||||
"description_search": "Hiking day in Sapa",
|
||||
"search_no_more_result": "No more results",
|
||||
"action_common_back": "Back",
|
||||
"action_common_cancel": "Cancel",
|
||||
"action_common_clear": "Clear",
|
||||
@@ -288,9 +282,9 @@
|
||||
"header_settings_field_validator_msg": "Value cannot be empty",
|
||||
"header_settings_header_name_input": "Header name",
|
||||
"header_settings_header_value_input": "Header value",
|
||||
"header_settings_page_title": "Proxy Headers",
|
||||
"header_settings_page_title": "Proxy Headers (EXPERIMENTAL)",
|
||||
"headers_settings_tile_subtitle": "Define proxy headers the app should send with each network request",
|
||||
"headers_settings_tile_title": "Custom proxy headers (EXPERIMENTAL)",
|
||||
"headers_settings_tile_title": "Custom proxy headers",
|
||||
"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_success": "Added {added} assets to album {album}.",
|
||||
@@ -482,7 +476,6 @@
|
||||
"search_filter_media_type_video": "Video",
|
||||
"search_filter_people": "People",
|
||||
"search_filter_people_title": "Select people",
|
||||
"search_filter_people_hint": "Filter people",
|
||||
"search_page_categories": "Categories",
|
||||
"search_page_favorites": "Favorites",
|
||||
"search_page_motion_photos": "Motion Photos",
|
||||
|
||||
@@ -541,7 +541,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -685,7 +685,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -715,7 +715,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -748,7 +748,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
@@ -791,7 +791,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
@@ -831,7 +831,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 194;
|
||||
CURRENT_PROJECT_VERSION = 190;
|
||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.126.1</string>
|
||||
<string>1.125.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -93,7 +93,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>194</string>
|
||||
<string>190</string>
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
|
||||
@@ -19,7 +19,7 @@ platform :ios do
|
||||
desc "iOS Release"
|
||||
lane :release do
|
||||
increment_version_number(
|
||||
version_number: "1.126.1"
|
||||
version_number: "1.125.6"
|
||||
)
|
||||
increment_build_number(
|
||||
build_number: latest_testflight_build_number + 1,
|
||||
|
||||
@@ -2,9 +2,3 @@ enum SortOrder {
|
||||
asc,
|
||||
desc,
|
||||
}
|
||||
|
||||
enum TextSearchType {
|
||||
context,
|
||||
filename,
|
||||
description,
|
||||
}
|
||||
|
||||
@@ -545,13 +545,19 @@ enum AssetType {
|
||||
}
|
||||
|
||||
extension AssetTypeEnumHelper on AssetTypeEnum {
|
||||
AssetType toAssetType() => switch (this) {
|
||||
AssetTypeEnum.IMAGE => AssetType.image,
|
||||
AssetTypeEnum.VIDEO => AssetType.video,
|
||||
AssetTypeEnum.AUDIO => AssetType.audio,
|
||||
AssetTypeEnum.OTHER => AssetType.other,
|
||||
_ => throw Exception(),
|
||||
};
|
||||
AssetType toAssetType() {
|
||||
switch (this) {
|
||||
case AssetTypeEnum.IMAGE:
|
||||
return AssetType.image;
|
||||
case AssetTypeEnum.VIDEO:
|
||||
return AssetType.video;
|
||||
case AssetTypeEnum.AUDIO:
|
||||
return AssetType.audio;
|
||||
case AssetTypeEnum.OTHER:
|
||||
return AssetType.other;
|
||||
}
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes where the information of this asset came from:
|
||||
|
||||
@@ -96,16 +96,25 @@ class StoreValue {
|
||||
int? intValue;
|
||||
String? strValue;
|
||||
|
||||
T? _extract<T>(StoreKey<T> key) => switch (key.type) {
|
||||
const (int) => intValue as T?,
|
||||
const (bool) => intValue == null ? null : (intValue! == 1) as T,
|
||||
const (DateTime) => intValue == null
|
||||
T? _extract<T>(StoreKey<T> key) {
|
||||
switch (key.type) {
|
||||
case const (int):
|
||||
return intValue as T?;
|
||||
case const (bool):
|
||||
return intValue == null ? null : (intValue! == 1) as T;
|
||||
case const (DateTime):
|
||||
return intValue == null
|
||||
? null
|
||||
: DateTime.fromMicrosecondsSinceEpoch(intValue!) as T,
|
||||
const (String) => strValue as T?,
|
||||
_ when key.fromDb != null => key.fromDb!.call(Store._db, intValue!),
|
||||
_ => throw TypeError(),
|
||||
};
|
||||
: DateTime.fromMicrosecondsSinceEpoch(intValue!) as T;
|
||||
case const (String):
|
||||
return strValue as T?;
|
||||
default:
|
||||
if (key.fromDb != null) {
|
||||
return key.fromDb!.call(Store._db, intValue!);
|
||||
}
|
||||
}
|
||||
throw TypeError();
|
||||
}
|
||||
|
||||
static Future<StoreValue> _of<T>(T? value, StoreKey<T> key) async {
|
||||
int? i;
|
||||
|
||||
@@ -149,33 +149,56 @@ enum AvatarColorEnum {
|
||||
}
|
||||
|
||||
extension AvatarColorEnumHelper on UserAvatarColor {
|
||||
AvatarColorEnum toAvatarColor() => switch (this) {
|
||||
UserAvatarColor.primary => AvatarColorEnum.primary,
|
||||
UserAvatarColor.pink => AvatarColorEnum.pink,
|
||||
UserAvatarColor.red => AvatarColorEnum.red,
|
||||
UserAvatarColor.yellow => AvatarColorEnum.yellow,
|
||||
UserAvatarColor.blue => AvatarColorEnum.blue,
|
||||
UserAvatarColor.green => AvatarColorEnum.green,
|
||||
UserAvatarColor.purple => AvatarColorEnum.purple,
|
||||
UserAvatarColor.orange => AvatarColorEnum.orange,
|
||||
UserAvatarColor.gray => AvatarColorEnum.gray,
|
||||
UserAvatarColor.amber => AvatarColorEnum.amber,
|
||||
_ => AvatarColorEnum.primary,
|
||||
};
|
||||
AvatarColorEnum toAvatarColor() {
|
||||
switch (this) {
|
||||
case UserAvatarColor.primary:
|
||||
return AvatarColorEnum.primary;
|
||||
case UserAvatarColor.pink:
|
||||
return AvatarColorEnum.pink;
|
||||
case UserAvatarColor.red:
|
||||
return AvatarColorEnum.red;
|
||||
case UserAvatarColor.yellow:
|
||||
return AvatarColorEnum.yellow;
|
||||
case UserAvatarColor.blue:
|
||||
return AvatarColorEnum.blue;
|
||||
case UserAvatarColor.green:
|
||||
return AvatarColorEnum.green;
|
||||
case UserAvatarColor.purple:
|
||||
return AvatarColorEnum.purple;
|
||||
case UserAvatarColor.orange:
|
||||
return AvatarColorEnum.orange;
|
||||
case UserAvatarColor.gray:
|
||||
return AvatarColorEnum.gray;
|
||||
case UserAvatarColor.amber:
|
||||
return AvatarColorEnum.amber;
|
||||
}
|
||||
return AvatarColorEnum.primary;
|
||||
}
|
||||
}
|
||||
|
||||
extension AvatarColorToColorHelper on AvatarColorEnum {
|
||||
Color toColor([bool isDarkTheme = false]) => switch (this) {
|
||||
AvatarColorEnum.primary =>
|
||||
isDarkTheme ? const Color(0xFFABCBFA) : const Color(0xFF4250AF),
|
||||
AvatarColorEnum.pink => const Color.fromARGB(255, 244, 114, 182),
|
||||
AvatarColorEnum.red => const Color.fromARGB(255, 239, 68, 68),
|
||||
AvatarColorEnum.yellow => const Color.fromARGB(255, 234, 179, 8),
|
||||
AvatarColorEnum.blue => const Color.fromARGB(255, 59, 130, 246),
|
||||
AvatarColorEnum.green => const Color.fromARGB(255, 22, 163, 74),
|
||||
AvatarColorEnum.purple => const Color.fromARGB(255, 147, 51, 234),
|
||||
AvatarColorEnum.orange => const Color.fromARGB(255, 234, 88, 12),
|
||||
AvatarColorEnum.gray => const Color.fromARGB(255, 75, 85, 99),
|
||||
AvatarColorEnum.amber => const Color.fromARGB(255, 217, 119, 6),
|
||||
};
|
||||
Color toColor([bool isDarkTheme = false]) {
|
||||
switch (this) {
|
||||
case AvatarColorEnum.primary:
|
||||
return isDarkTheme ? const Color(0xFFABCBFA) : const Color(0xFF4250AF);
|
||||
case AvatarColorEnum.pink:
|
||||
return const Color.fromARGB(255, 244, 114, 182);
|
||||
case AvatarColorEnum.red:
|
||||
return const Color.fromARGB(255, 239, 68, 68);
|
||||
case AvatarColorEnum.yellow:
|
||||
return const Color.fromARGB(255, 234, 179, 8);
|
||||
case AvatarColorEnum.blue:
|
||||
return const Color.fromARGB(255, 59, 130, 246);
|
||||
case AvatarColorEnum.green:
|
||||
return const Color.fromARGB(255, 22, 163, 74);
|
||||
case AvatarColorEnum.purple:
|
||||
return const Color.fromARGB(255, 147, 51, 234);
|
||||
case AvatarColorEnum.orange:
|
||||
return const Color.fromARGB(255, 234, 88, 12);
|
||||
case AvatarColorEnum.gray:
|
||||
return const Color.fromARGB(255, 75, 85, 99);
|
||||
case AvatarColorEnum.amber:
|
||||
return const Color.fromARGB(255, 217, 119, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
abstract interface class IPersonApiRepository {
|
||||
Future<List<Person>> getAll();
|
||||
Future<Person> update(String id, {String? name});
|
||||
@@ -9,10 +6,10 @@ abstract interface class IPersonApiRepository {
|
||||
class Person {
|
||||
Person({
|
||||
required this.id,
|
||||
this.birthDate,
|
||||
required this.isHidden,
|
||||
required this.name,
|
||||
required this.thumbnailPath,
|
||||
this.birthDate,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
@@ -22,80 +19,4 @@ class Person {
|
||||
final String name;
|
||||
final String thumbnailPath;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Person(id: $id, birthDate: $birthDate, isHidden: $isHidden, name: $name, thumbnailPath: $thumbnailPath, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
Person copyWith({
|
||||
String? id,
|
||||
DateTime? birthDate,
|
||||
bool? isHidden,
|
||||
String? name,
|
||||
String? thumbnailPath,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return Person(
|
||||
id: id ?? this.id,
|
||||
birthDate: birthDate ?? this.birthDate,
|
||||
isHidden: isHidden ?? this.isHidden,
|
||||
name: name ?? this.name,
|
||||
thumbnailPath: thumbnailPath ?? this.thumbnailPath,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'id': id,
|
||||
'birthDate': birthDate?.millisecondsSinceEpoch,
|
||||
'isHidden': isHidden,
|
||||
'name': name,
|
||||
'thumbnailPath': thumbnailPath,
|
||||
'updatedAt': updatedAt?.millisecondsSinceEpoch,
|
||||
};
|
||||
}
|
||||
|
||||
factory Person.fromMap(Map<String, dynamic> map) {
|
||||
return Person(
|
||||
id: map['id'] as String,
|
||||
birthDate: map['birthDate'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['birthDate'] as int)
|
||||
: null,
|
||||
isHidden: map['isHidden'] as bool,
|
||||
name: map['name'] as String,
|
||||
thumbnailPath: map['thumbnailPath'] as String,
|
||||
updatedAt: map['updatedAt'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['updatedAt'] as int)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory Person.fromJson(String source) =>
|
||||
Person.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Person other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.id == id &&
|
||||
other.birthDate == birthDate &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name &&
|
||||
other.thumbnailPath == thumbnailPath &&
|
||||
other.updatedAt == updatedAt;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^
|
||||
birthDate.hashCode ^
|
||||
isHidden.hashCode ^
|
||||
name.hashCode ^
|
||||
thumbnailPath.hashCode ^
|
||||
updatedAt.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +235,6 @@ class SearchDisplayFilters {
|
||||
class SearchFilter {
|
||||
String? context;
|
||||
String? filename;
|
||||
String? description;
|
||||
Set<Person> people;
|
||||
SearchLocationFilter location;
|
||||
SearchCameraFilter camera;
|
||||
@@ -248,7 +247,6 @@ class SearchFilter {
|
||||
SearchFilter({
|
||||
this.context,
|
||||
this.filename,
|
||||
this.description,
|
||||
required this.people,
|
||||
required this.location,
|
||||
required this.camera,
|
||||
@@ -257,28 +255,9 @@ class SearchFilter {
|
||||
required this.mediaType,
|
||||
});
|
||||
|
||||
bool get isEmpty {
|
||||
return (context == null || (context != null && context!.isEmpty)) &&
|
||||
(filename == null || (filename!.isEmpty)) &&
|
||||
(description == null || (description!.isEmpty)) &&
|
||||
people.isEmpty &&
|
||||
location.country == null &&
|
||||
location.state == null &&
|
||||
location.city == null &&
|
||||
camera.make == null &&
|
||||
camera.model == null &&
|
||||
date.takenBefore == null &&
|
||||
date.takenAfter == null &&
|
||||
display.isNotInAlbum == false &&
|
||||
display.isArchive == false &&
|
||||
display.isFavorite == false &&
|
||||
mediaType == AssetType.other;
|
||||
}
|
||||
|
||||
SearchFilter copyWith({
|
||||
String? context,
|
||||
String? filename,
|
||||
String? description,
|
||||
Set<Person>? people,
|
||||
SearchLocationFilter? location,
|
||||
SearchCameraFilter? camera,
|
||||
@@ -289,7 +268,6 @@ class SearchFilter {
|
||||
return SearchFilter(
|
||||
context: context ?? this.context,
|
||||
filename: filename ?? this.filename,
|
||||
description: description ?? this.description,
|
||||
people: people ?? this.people,
|
||||
location: location ?? this.location,
|
||||
camera: camera ?? this.camera,
|
||||
@@ -301,7 +279,7 @@ class SearchFilter {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SearchFilter(context: $context, filename: $filename, description: $description, people: $people, location: $location, camera: $camera, date: $date, display: $display, mediaType: $mediaType)';
|
||||
return 'SearchFilter(context: $context, filename: $filename, people: $people, location: $location, camera: $camera, date: $date, display: $display, mediaType: $mediaType)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -310,7 +288,6 @@ class SearchFilter {
|
||||
|
||||
return other.context == context &&
|
||||
other.filename == filename &&
|
||||
other.description == description &&
|
||||
other.people == people &&
|
||||
other.location == location &&
|
||||
other.camera == camera &&
|
||||
@@ -323,7 +300,6 @@ class SearchFilter {
|
||||
int get hashCode {
|
||||
return context.hashCode ^
|
||||
filename.hashCode ^
|
||||
description.hashCode ^
|
||||
people.hashCode ^
|
||||
location.hashCode ^
|
||||
camera.hashCode ^
|
||||
|
||||
@@ -36,19 +36,32 @@ class AppLogPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildLeadingIcon(LogLevel level) => switch (level) {
|
||||
LogLevel.INFO => colorStatusIndicator(context.primaryColor),
|
||||
LogLevel.SEVERE => colorStatusIndicator(Colors.redAccent),
|
||||
LogLevel.WARNING => colorStatusIndicator(Colors.orangeAccent),
|
||||
_ => colorStatusIndicator(Colors.grey),
|
||||
};
|
||||
Widget buildLeadingIcon(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel.INFO:
|
||||
return colorStatusIndicator(context.primaryColor);
|
||||
case LogLevel.SEVERE:
|
||||
return colorStatusIndicator(Colors.redAccent);
|
||||
|
||||
Color getTileColor(LogLevel level) => switch (level) {
|
||||
LogLevel.INFO => Colors.transparent,
|
||||
LogLevel.SEVERE => Colors.redAccent.withOpacity(0.25),
|
||||
LogLevel.WARNING => Colors.orangeAccent.withOpacity(0.25),
|
||||
_ => context.primaryColor.withOpacity(0.1),
|
||||
};
|
||||
case LogLevel.WARNING:
|
||||
return colorStatusIndicator(Colors.orangeAccent);
|
||||
default:
|
||||
return colorStatusIndicator(Colors.grey);
|
||||
}
|
||||
}
|
||||
|
||||
getTileColor(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel.INFO:
|
||||
return Colors.transparent;
|
||||
case LogLevel.SEVERE:
|
||||
return Colors.redAccent.withOpacity(0.25);
|
||||
case LogLevel.WARNING:
|
||||
return Colors.orangeAccent.withOpacity(0.25);
|
||||
default:
|
||||
return context.primaryColor.withOpacity(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
|
||||
@@ -74,16 +74,26 @@ class DownloadTaskTile extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final progressPercent = (progress * 100).round();
|
||||
|
||||
String getStatusText() => switch (status) {
|
||||
TaskStatus.running => 'downloading'.tr(),
|
||||
TaskStatus.complete => 'download_complete'.tr(),
|
||||
TaskStatus.failed => 'download_failed'.tr(),
|
||||
TaskStatus.canceled => 'download_canceled'.tr(),
|
||||
TaskStatus.paused => 'download_paused'.tr(),
|
||||
TaskStatus.enqueued => 'download_enqueue'.tr(),
|
||||
TaskStatus.notFound => 'download_notfound'.tr(),
|
||||
TaskStatus.waitingToRetry => 'download_waiting_to_retry'.tr(),
|
||||
};
|
||||
getStatusText() {
|
||||
switch (status) {
|
||||
case TaskStatus.running:
|
||||
return 'downloading'.tr();
|
||||
case TaskStatus.complete:
|
||||
return 'download_complete'.tr();
|
||||
case TaskStatus.failed:
|
||||
return 'download_failed'.tr();
|
||||
case TaskStatus.canceled:
|
||||
return 'download_canceled'.tr();
|
||||
case TaskStatus.paused:
|
||||
return 'download_paused'.tr();
|
||||
case TaskStatus.enqueued:
|
||||
return 'download_enqueue'.tr();
|
||||
case TaskStatus.notFound:
|
||||
return 'download_notfound'.tr();
|
||||
case TaskStatus.waitingToRetry:
|
||||
return 'download_waiting_to_retry'.tr();
|
||||
}
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
key: const ValueKey('download_progress'),
|
||||
|
||||
@@ -16,8 +16,6 @@ class LargeLeadingTile extends StatelessWidget {
|
||||
this.trailing,
|
||||
this.selected = false,
|
||||
this.disabled = false,
|
||||
this.selectedTileColor,
|
||||
this.tileColor,
|
||||
});
|
||||
|
||||
final Widget leading;
|
||||
@@ -29,9 +27,6 @@ class LargeLeadingTile extends StatelessWidget {
|
||||
final Widget? trailing;
|
||||
final bool selected;
|
||||
final bool disabled;
|
||||
final Color? selectedTileColor;
|
||||
final Color? tileColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
@@ -40,9 +35,8 @@ class LargeLeadingTile extends StatelessWidget {
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: selected
|
||||
? selectedTileColor ??
|
||||
Theme.of(context).primaryColor.withAlpha(30)
|
||||
: tileColor ?? Colors.transparent,
|
||||
? Theme.of(context).primaryColor.withAlpha(30)
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
),
|
||||
child: Row(
|
||||
|
||||
@@ -26,7 +26,6 @@ import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
final Asset asset;
|
||||
final bool showControls;
|
||||
final int playbackDelayFactor;
|
||||
final Widget image;
|
||||
|
||||
const NativeVideoViewerPage({
|
||||
@@ -34,7 +33,6 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
required this.asset,
|
||||
required this.image,
|
||||
this.showControls = true,
|
||||
this.playbackDelayFactor = 1,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -319,16 +317,12 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
// Delay the video playback to avoid a stutter in the swipe animation
|
||||
// Note, in some circumstances a longer delay is needed (eg: memories),
|
||||
// the playbackDelayFactor can be used for this
|
||||
// This delay seems like a hacky way to resolve underlying bugs in video
|
||||
// playback, but other resolutions failed thus far
|
||||
Timer(
|
||||
Platform.isIOS
|
||||
? Duration(milliseconds: 300 * playbackDelayFactor)
|
||||
? const Duration(milliseconds: 300)
|
||||
: imageToVideo
|
||||
? Duration(milliseconds: 200 * playbackDelayFactor)
|
||||
: Duration(milliseconds: 400 * playbackDelayFactor), () {
|
||||
? const Duration(milliseconds: 200)
|
||||
: const Duration(milliseconds: 400), () {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isRefreshingAssets = ref.watch(assetProvider);
|
||||
final isRefreshingRemoteAlbums = ref.watch(isRefreshingRemoteAlbumProvider);
|
||||
final isScreenLandscape =
|
||||
MediaQuery.orientationOf(context) == Orientation.landscape;
|
||||
|
||||
Widget buildIcon({required Widget icon, required bool isProcessing}) {
|
||||
if (!isProcessing) return icon;
|
||||
@@ -47,7 +45,7 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void onNavigationSelected(TabsRouter router, int index) {
|
||||
onNavigationSelected(TabsRouter router, int index) {
|
||||
// On Photos page menu tapped
|
||||
if (router.activeIndex == 0 && index == 0) {
|
||||
scrollToTopNotifierProvider.scrollToTop();
|
||||
@@ -63,82 +61,62 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
ref.read(tabProvider.notifier).state = TabEnum.values[index];
|
||||
}
|
||||
|
||||
final navigationDestinations = [
|
||||
NavigationDestination(
|
||||
label: 'tab_controller_nav_photos'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.photo_library_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingAssets,
|
||||
icon: Icon(
|
||||
Icons.photo_library,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'tab_controller_nav_search'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.search_rounded,
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.search,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'albums'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.photo_album_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingRemoteAlbums,
|
||||
icon: Icon(
|
||||
Icons.photo_album_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'library'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.space_dashboard_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingAssets,
|
||||
icon: Icon(
|
||||
Icons.space_dashboard_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
Widget bottomNavigationBar(TabsRouter tabsRouter) {
|
||||
bottomNavigationBar(TabsRouter tabsRouter) {
|
||||
return NavigationBar(
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
onDestinationSelected: (index) =>
|
||||
onNavigationSelected(tabsRouter, index),
|
||||
destinations: navigationDestinations,
|
||||
);
|
||||
}
|
||||
|
||||
Widget navigationRail(TabsRouter tabsRouter) {
|
||||
return NavigationRail(
|
||||
destinations: navigationDestinations
|
||||
.map(
|
||||
(e) => NavigationRailDestination(
|
||||
icon: e.icon,
|
||||
label: Text(e.label),
|
||||
destinations: [
|
||||
NavigationDestination(
|
||||
label: 'tab_controller_nav_photos'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.photo_library_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingAssets,
|
||||
icon: Icon(
|
||||
Icons.photo_library,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onDestinationSelected: (index) =>
|
||||
onNavigationSelected(tabsRouter, index),
|
||||
selectedIndex: tabsRouter.activeIndex,
|
||||
labelType: NavigationRailLabelType.all,
|
||||
groupAlignment: 0.0,
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'tab_controller_nav_search'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.search_rounded,
|
||||
),
|
||||
selectedIcon: Icon(
|
||||
Icons.search,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'albums'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.photo_album_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingRemoteAlbums,
|
||||
icon: Icon(
|
||||
Icons.photo_album_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
NavigationDestination(
|
||||
label: 'library'.tr(),
|
||||
icon: const Icon(
|
||||
Icons.space_dashboard_outlined,
|
||||
),
|
||||
selectedIcon: buildIcon(
|
||||
isProcessing: isRefreshingAssets,
|
||||
icon: Icon(
|
||||
Icons.space_dashboard_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -157,27 +135,17 @@ class TabControllerPage extends HookConsumerWidget {
|
||||
),
|
||||
builder: (context, child) {
|
||||
final tabsRouter = AutoTabsRouter.of(context);
|
||||
final heroedChild = HeroControllerScope(
|
||||
controller: HeroController(),
|
||||
child: child,
|
||||
);
|
||||
return PopScope(
|
||||
canPop: tabsRouter.activeIndex == 0,
|
||||
onPopInvokedWithResult: (didPop, _) =>
|
||||
!didPop ? tabsRouter.setActiveIndex(0) : null,
|
||||
child: Scaffold(
|
||||
body: isScreenLandscape
|
||||
? Row(
|
||||
children: [
|
||||
navigationRail(tabsRouter),
|
||||
const VerticalDivider(),
|
||||
Expanded(child: heroedChild),
|
||||
],
|
||||
)
|
||||
: heroedChild,
|
||||
bottomNavigationBar: multiselectEnabled || isScreenLandscape
|
||||
? null
|
||||
: bottomNavigationBar(tabsRouter),
|
||||
body: HeroControllerScope(
|
||||
controller: HeroController(),
|
||||
child: child,
|
||||
),
|
||||
bottomNavigationBar:
|
||||
multiselectEnabled ? null : bottomNavigationBar(tabsRouter),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -174,19 +174,33 @@ class _AspectRatioButton extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
IconData iconData;
|
||||
switch (label) {
|
||||
case 'Free':
|
||||
iconData = Icons.crop_free_rounded;
|
||||
break;
|
||||
case '1:1':
|
||||
iconData = Icons.crop_square_rounded;
|
||||
break;
|
||||
case '16:9':
|
||||
iconData = Icons.crop_16_9_rounded;
|
||||
break;
|
||||
case '3:2':
|
||||
iconData = Icons.crop_3_2_rounded;
|
||||
break;
|
||||
case '7:5':
|
||||
iconData = Icons.crop_7_5_rounded;
|
||||
break;
|
||||
default:
|
||||
iconData = Icons.crop_free_rounded;
|
||||
}
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
switch (label) {
|
||||
'Free' => Icons.crop_free_rounded,
|
||||
'1:1' => Icons.crop_square_rounded,
|
||||
'16:9' => Icons.crop_16_9_rounded,
|
||||
'3:2' => Icons.crop_3_2_rounded,
|
||||
'7:5' => Icons.crop_7_5_rounded,
|
||||
_ => Icons.crop_free_rounded,
|
||||
},
|
||||
iconData,
|
||||
color: aspectRatio.value == ratio
|
||||
? context.primaryColor
|
||||
: context.themeData.iconTheme.color,
|
||||
|
||||
@@ -136,16 +136,23 @@ class PermissionOnboardingPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
final Widget child = switch (permission) {
|
||||
PermissionStatus.limited => buildPermissionLimited(),
|
||||
PermissionStatus.denied => buildRequestPermission(),
|
||||
PermissionStatus.granted ||
|
||||
PermissionStatus.provisional =>
|
||||
buildPermissionGranted(),
|
||||
PermissionStatus.restricted ||
|
||||
PermissionStatus.permanentlyDenied =>
|
||||
buildPermissionDenied()
|
||||
};
|
||||
final Widget child;
|
||||
switch (permission) {
|
||||
case PermissionStatus.limited:
|
||||
child = buildPermissionLimited();
|
||||
break;
|
||||
case PermissionStatus.denied:
|
||||
child = buildRequestPermission();
|
||||
break;
|
||||
case PermissionStatus.granted:
|
||||
case PermissionStatus.provisional:
|
||||
child = buildPermissionGranted();
|
||||
break;
|
||||
case PermissionStatus.restricted:
|
||||
case PermissionStatus.permanentlyDenied:
|
||||
child = buildPermissionDenied();
|
||||
break;
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
|
||||
@@ -5,8 +5,6 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_image.dart';
|
||||
import 'package:immich_mobile/widgets/memories/memory_bottom_info.dart';
|
||||
@@ -15,8 +13,6 @@ import 'package:immich_mobile/widgets/memories/memory_epilogue.dart';
|
||||
import 'package:immich_mobile/widgets/memories/memory_progress_indicator.dart';
|
||||
|
||||
@RoutePage()
|
||||
|
||||
/// Expects [currentAssetProvider] to be set before navigating to this page
|
||||
class MemoryPage extends HookConsumerWidget {
|
||||
final List<Memory> memories;
|
||||
final int memoryIndex;
|
||||
@@ -36,7 +32,6 @@ class MemoryPage extends HookConsumerWidget {
|
||||
"${currentAssetPage.value + 1}|${currentMemory.value.assets.length}",
|
||||
);
|
||||
const bgColor = Colors.black;
|
||||
final currentAsset = useState<Asset?>(null);
|
||||
|
||||
/// The list of all of the asset page controllers
|
||||
final memoryAssetPageControllers =
|
||||
@@ -140,14 +135,6 @@ class MemoryPage extends HookConsumerWidget {
|
||||
ref.read(hapticFeedbackProvider.notifier).selectionClick();
|
||||
currentAssetPage.value = otherIndex;
|
||||
updateProgressText();
|
||||
|
||||
final asset = currentMemory.value.assets[otherIndex];
|
||||
currentAsset.value = asset;
|
||||
ref.read(currentAssetProvider.notifier).set(asset);
|
||||
if (asset.isVideo || asset.isMotionPhoto) {
|
||||
ref.read(videoPlaybackValueProvider.notifier).reset();
|
||||
}
|
||||
|
||||
// Wait for page change animation to finish
|
||||
await Future.delayed(const Duration(milliseconds: 400));
|
||||
// And then precache the next asset
|
||||
@@ -287,16 +274,6 @@ class MemoryPage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (currentAsset.value != null &&
|
||||
currentAsset.value!.isVideo)
|
||||
Positioned(
|
||||
bottom: 24,
|
||||
right: 32,
|
||||
child: Icon(
|
||||
Icons.videocam_outlined,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -5,7 +5,6 @@ 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/constants/enums.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||
@@ -32,8 +31,7 @@ class SearchPage extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final textSearchType = useState<TextSearchType>(TextSearchType.context);
|
||||
final searchHintText = useState<String>('contextual_search'.tr());
|
||||
final isContextualSearch = useState(true);
|
||||
final textSearchController = useTextEditingController();
|
||||
final filter = useState<SearchFilter>(
|
||||
SearchFilter(
|
||||
@@ -51,7 +49,7 @@ class SearchPage extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
|
||||
final previousFilter = useState<SearchFilter?>(null);
|
||||
final previousFilter = useState(filter.value);
|
||||
|
||||
final peopleCurrentFilterWidget = useState<Widget?>(null);
|
||||
final dateRangeCurrentFilterWidget = useState<Widget?>(null);
|
||||
@@ -62,55 +60,19 @@ class SearchPage extends HookConsumerWidget {
|
||||
|
||||
final isSearching = useState(false);
|
||||
|
||||
SnackBar searchInfoSnackBar(String message) {
|
||||
return SnackBar(
|
||||
content: Text(
|
||||
message,
|
||||
style: context.textTheme.labelLarge,
|
||||
),
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
closeIconColor: context.colorScheme.onSurface,
|
||||
);
|
||||
}
|
||||
|
||||
search() async {
|
||||
if (filter.value.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefilter == null && filter.value == previousFilter.value) {
|
||||
return;
|
||||
}
|
||||
if (prefilter == null && filter.value == previousFilter.value) return;
|
||||
|
||||
isSearching.value = true;
|
||||
ref.watch(paginatedSearchProvider.notifier).clear();
|
||||
final hasResult = await ref
|
||||
.watch(paginatedSearchProvider.notifier)
|
||||
.search(filter.value);
|
||||
|
||||
if (!hasResult) {
|
||||
context.showSnackBar(
|
||||
searchInfoSnackBar('search_no_result'.tr()),
|
||||
);
|
||||
}
|
||||
|
||||
await ref.watch(paginatedSearchProvider.notifier).search(filter.value);
|
||||
previousFilter.value = filter.value;
|
||||
isSearching.value = false;
|
||||
}
|
||||
|
||||
loadMoreSearchResult() async {
|
||||
isSearching.value = true;
|
||||
final hasResult = await ref
|
||||
.watch(paginatedSearchProvider.notifier)
|
||||
.search(filter.value);
|
||||
|
||||
if (!hasResult) {
|
||||
context.showSnackBar(
|
||||
searchInfoSnackBar('search_no_more_result'.tr()),
|
||||
);
|
||||
}
|
||||
|
||||
await ref.watch(paginatedSearchProvider.notifier).search(filter.value);
|
||||
isSearching.value = false;
|
||||
}
|
||||
|
||||
@@ -480,148 +442,37 @@ class SearchPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
handleTextSubmitted(String value) {
|
||||
switch (textSearchType.value) {
|
||||
case TextSearchType.context:
|
||||
filter.value = filter.value.copyWith(
|
||||
filename: '',
|
||||
context: value,
|
||||
description: '',
|
||||
);
|
||||
|
||||
break;
|
||||
case TextSearchType.filename:
|
||||
filter.value = filter.value.copyWith(
|
||||
filename: value,
|
||||
context: '',
|
||||
description: '',
|
||||
);
|
||||
|
||||
break;
|
||||
case TextSearchType.description:
|
||||
filter.value = filter.value.copyWith(
|
||||
filename: '',
|
||||
context: '',
|
||||
description: value,
|
||||
);
|
||||
break;
|
||||
if (isContextualSearch.value) {
|
||||
filter.value = filter.value.copyWith(
|
||||
filename: '',
|
||||
context: value,
|
||||
);
|
||||
} else {
|
||||
filter.value = filter.value.copyWith(
|
||||
filename: value,
|
||||
context: '',
|
||||
);
|
||||
}
|
||||
|
||||
search();
|
||||
}
|
||||
|
||||
IconData getSearchPrefixIcon() {
|
||||
switch (textSearchType.value) {
|
||||
case TextSearchType.context:
|
||||
return Icons.image_search_rounded;
|
||||
case TextSearchType.filename:
|
||||
return Icons.abc_rounded;
|
||||
case TextSearchType.description:
|
||||
return Icons.text_snippet_outlined;
|
||||
default:
|
||||
return Icons.search_rounded;
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: true,
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 16.0),
|
||||
child: MenuAnchor(
|
||||
style: MenuStyle(
|
||||
elevation: const WidgetStatePropertyAll(1),
|
||||
shape: WidgetStateProperty.all(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
),
|
||||
),
|
||||
padding: const WidgetStatePropertyAll(
|
||||
EdgeInsets.all(4),
|
||||
),
|
||||
),
|
||||
builder: (
|
||||
BuildContext context,
|
||||
MenuController controller,
|
||||
Widget? child,
|
||||
) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.more_vert_rounded),
|
||||
tooltip: 'Show text search menu',
|
||||
);
|
||||
padding: const EdgeInsets.only(right: 14.0),
|
||||
child: IconButton(
|
||||
key: const Key('contextual_search_button'),
|
||||
icon: isContextualSearch.value
|
||||
? const Icon(Icons.abc_rounded)
|
||||
: const Icon(Icons.image_search_rounded),
|
||||
onPressed: () {
|
||||
isContextualSearch.value = !isContextualSearch.value;
|
||||
textSearchController.clear();
|
||||
},
|
||||
menuChildren: [
|
||||
MenuItemButton(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.image_search_rounded),
|
||||
title: Text(
|
||||
'search_filter_contextual'.tr(),
|
||||
style: context.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textSearchType.value == TextSearchType.context
|
||||
? context.colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
),
|
||||
selectedColor: context.colorScheme.primary,
|
||||
selected: textSearchType.value == TextSearchType.context,
|
||||
),
|
||||
onPressed: () {
|
||||
textSearchType.value = TextSearchType.context;
|
||||
searchHintText.value = 'contextual_search'.tr();
|
||||
},
|
||||
),
|
||||
MenuItemButton(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.abc_rounded),
|
||||
title: Text(
|
||||
'search_filter_filename'.tr(),
|
||||
style: context.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textSearchType.value == TextSearchType.filename
|
||||
? context.colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
),
|
||||
selectedColor: context.colorScheme.primary,
|
||||
selected: textSearchType.value == TextSearchType.filename,
|
||||
),
|
||||
onPressed: () {
|
||||
textSearchType.value = TextSearchType.filename;
|
||||
searchHintText.value = 'filename_search'.tr();
|
||||
},
|
||||
),
|
||||
MenuItemButton(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.text_snippet_outlined),
|
||||
title: Text(
|
||||
'search_filter_description'.tr(),
|
||||
style: context.textTheme.bodyLarge?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color:
|
||||
textSearchType.value == TextSearchType.description
|
||||
? context.colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
),
|
||||
selectedColor: context.colorScheme.primary,
|
||||
selected:
|
||||
textSearchType.value == TextSearchType.description,
|
||||
),
|
||||
onPressed: () {
|
||||
textSearchType.value = TextSearchType.description;
|
||||
searchHintText.value = 'description_search'.tr();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -652,10 +503,12 @@ class SearchPage extends HookConsumerWidget {
|
||||
prefixIcon: prefilter != null
|
||||
? null
|
||||
: Icon(
|
||||
getSearchPrefixIcon(),
|
||||
Icons.search_rounded,
|
||||
color: context.colorScheme.primary,
|
||||
),
|
||||
hintText: searchHintText.value,
|
||||
hintText: isContextualSearch.value
|
||||
? 'contextual_search'.tr()
|
||||
: 'filename_search'.tr(),
|
||||
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||
color: context.themeData.colorScheme.onSurfaceSecondary,
|
||||
),
|
||||
@@ -743,15 +596,10 @@ class SearchPage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isSearching.value)
|
||||
const Expanded(
|
||||
child: Center(child: CircularProgressIndicator.adaptive()),
|
||||
)
|
||||
else
|
||||
SearchResultGrid(
|
||||
onScrollEnd: loadMoreSearchResult,
|
||||
isSearching: isSearching.value,
|
||||
),
|
||||
SearchResultGrid(
|
||||
onScrollEnd: loadMoreSearchResult,
|
||||
isSearching: isSearching.value,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -19,23 +19,17 @@ class PaginatedSearchNotifier extends StateNotifier<SearchResult> {
|
||||
PaginatedSearchNotifier(this._searchService)
|
||||
: super(SearchResult(assets: [], nextPage: 1));
|
||||
|
||||
Future<bool> search(SearchFilter filter) async {
|
||||
if (state.nextPage == null) {
|
||||
return false;
|
||||
}
|
||||
search(SearchFilter filter) async {
|
||||
if (state.nextPage == null) return;
|
||||
|
||||
final result = await _searchService.search(filter, state.nextPage!);
|
||||
|
||||
if (result == null) {
|
||||
return false;
|
||||
}
|
||||
if (result == null) return;
|
||||
|
||||
state = SearchResult(
|
||||
assets: [...state.assets, ...result.assets],
|
||||
nextPage: result.nextPage,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
||||
@@ -18,11 +18,15 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
||||
@override
|
||||
Future<int> count({bool? local}) {
|
||||
final baseQuery = db.albums.where();
|
||||
final QueryBuilder<Album, Album, QAfterWhereClause> query = switch (local) {
|
||||
null => baseQuery.noOp(),
|
||||
true => baseQuery.localIdIsNotNull(),
|
||||
false => baseQuery.remoteIdIsNotNull(),
|
||||
};
|
||||
final QueryBuilder<Album, Album, QAfterWhereClause> query;
|
||||
switch (local) {
|
||||
case null:
|
||||
query = baseQuery.noOp();
|
||||
case true:
|
||||
query = baseQuery.localIdIsNotNull();
|
||||
case false:
|
||||
query = baseQuery.remoteIdIsNotNull();
|
||||
}
|
||||
return query.count();
|
||||
}
|
||||
|
||||
@@ -87,11 +91,15 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
||||
if (ownerId != null) {
|
||||
filterQuery = filterQuery.owner((q) => q.isarIdEqualTo(ownerId));
|
||||
}
|
||||
final QueryBuilder<Album, Album, QAfterSortBy> query = switch (sortBy) {
|
||||
null => filterQuery.noOp(),
|
||||
AlbumSort.remoteId => filterQuery.sortByRemoteId(),
|
||||
AlbumSort.localId => filterQuery.sortByLocalId(),
|
||||
};
|
||||
final QueryBuilder<Album, Album, QAfterSortBy> query;
|
||||
switch (sortBy) {
|
||||
case null:
|
||||
query = filterQuery.noOp();
|
||||
case AlbumSort.remoteId:
|
||||
query = filterQuery.sortByRemoteId();
|
||||
case AlbumSort.localId:
|
||||
query = filterQuery.sortByLocalId();
|
||||
}
|
||||
return query.findAll();
|
||||
}
|
||||
|
||||
@@ -142,11 +150,14 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
||||
query = query.owner(
|
||||
(q) => q.not().isarIdEqualTo(Store.get(StoreKey.currentUser).isarId),
|
||||
);
|
||||
break;
|
||||
case QuickFilterMode.myAlbums:
|
||||
query = query.owner(
|
||||
(q) => q.isarIdEqualTo(Store.get(StoreKey.currentUser).isarId),
|
||||
);
|
||||
break;
|
||||
case QuickFilterMode.all:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,20 +38,27 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
||||
query = query.ownerIdEqualTo(ownerId);
|
||||
}
|
||||
|
||||
if (state != null) {
|
||||
query = switch (state) {
|
||||
AssetState.local => query.remoteIdIsNull(),
|
||||
AssetState.remote => query.localIdIsNull(),
|
||||
AssetState.merged => query.localIdIsNotNull().remoteIdIsNotNull(),
|
||||
};
|
||||
switch (state) {
|
||||
case null:
|
||||
break;
|
||||
case AssetState.local:
|
||||
query = query.remoteIdIsNull();
|
||||
case AssetState.remote:
|
||||
query = query.localIdIsNull();
|
||||
case AssetState.merged:
|
||||
query = query.localIdIsNotNull().remoteIdIsNotNull();
|
||||
}
|
||||
|
||||
final QueryBuilder<Asset, Asset, QAfterSortBy> sortedQuery =
|
||||
switch (sortBy) {
|
||||
null => query.noOp(),
|
||||
AssetSort.checksum => query.sortByChecksum(),
|
||||
AssetSort.ownerIdChecksum => query.sortByOwnerId().thenByChecksum(),
|
||||
};
|
||||
final QueryBuilder<Asset, Asset, QAfterSortBy> sortedQuery;
|
||||
|
||||
switch (sortBy) {
|
||||
case null:
|
||||
sortedQuery = query.noOp();
|
||||
case AssetSort.checksum:
|
||||
sortedQuery = query.sortByChecksum();
|
||||
case AssetSort.ownerIdChecksum:
|
||||
sortedQuery = query.sortByOwnerId().thenByChecksum();
|
||||
}
|
||||
|
||||
return sortedQuery.findAll();
|
||||
}
|
||||
@@ -77,12 +84,16 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
||||
AssetState? state,
|
||||
) {
|
||||
final query = db.assets.remote(ids).filter();
|
||||
return switch (state) {
|
||||
null => query.noOp(),
|
||||
AssetState.local => query.remoteIdIsNull(),
|
||||
AssetState.remote => query.localIdIsNull(),
|
||||
AssetState.merged => query.localIdIsNotEmpty().remoteIdIsNotNull(),
|
||||
};
|
||||
switch (state) {
|
||||
case null:
|
||||
return query.noOp();
|
||||
case AssetState.local:
|
||||
return query.remoteIdIsNull();
|
||||
case AssetState.remote:
|
||||
return query.localIdIsNull();
|
||||
case AssetState.merged:
|
||||
return query.localIdIsNotEmpty().remoteIdIsNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -93,32 +104,39 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
||||
int? limit,
|
||||
}) {
|
||||
final baseQuery = db.assets.where();
|
||||
final QueryBuilder<Asset, Asset, QAfterFilterCondition> filteredQuery =
|
||||
switch (state) {
|
||||
null => baseQuery.ownerIdEqualToAnyChecksum(ownerId).noOp(),
|
||||
AssetState.local => baseQuery
|
||||
.remoteIdIsNull()
|
||||
.filter()
|
||||
.localIdIsNotNull()
|
||||
.ownerIdEqualTo(ownerId),
|
||||
AssetState.remote => baseQuery
|
||||
.localIdIsNull()
|
||||
.filter()
|
||||
.remoteIdIsNotNull()
|
||||
.ownerIdEqualTo(ownerId),
|
||||
AssetState.merged => baseQuery
|
||||
.ownerIdEqualToAnyChecksum(ownerId)
|
||||
.filter()
|
||||
.remoteIdIsNotNull()
|
||||
.localIdIsNotNull(),
|
||||
};
|
||||
final QueryBuilder<Asset, Asset, QAfterFilterCondition> filteredQuery;
|
||||
switch (state) {
|
||||
case null:
|
||||
filteredQuery = baseQuery.ownerIdEqualToAnyChecksum(ownerId).noOp();
|
||||
case AssetState.local:
|
||||
filteredQuery = baseQuery
|
||||
.remoteIdIsNull()
|
||||
.filter()
|
||||
.localIdIsNotNull()
|
||||
.ownerIdEqualTo(ownerId);
|
||||
case AssetState.remote:
|
||||
filteredQuery = baseQuery
|
||||
.localIdIsNull()
|
||||
.filter()
|
||||
.remoteIdIsNotNull()
|
||||
.ownerIdEqualTo(ownerId);
|
||||
case AssetState.merged:
|
||||
filteredQuery = baseQuery
|
||||
.ownerIdEqualToAnyChecksum(ownerId)
|
||||
.filter()
|
||||
.remoteIdIsNotNull()
|
||||
.localIdIsNotNull();
|
||||
}
|
||||
|
||||
final QueryBuilder<Asset, Asset, QAfterSortBy> query = switch (sortBy) {
|
||||
null => filteredQuery.noOp(),
|
||||
AssetSort.checksum => filteredQuery.sortByChecksum(),
|
||||
AssetSort.ownerIdChecksum =>
|
||||
filteredQuery.sortByOwnerId().thenByChecksum(),
|
||||
};
|
||||
final QueryBuilder<Asset, Asset, QAfterSortBy> query;
|
||||
switch (sortBy) {
|
||||
case null:
|
||||
query = filteredQuery.noOp();
|
||||
case AssetSort.checksum:
|
||||
query = filteredQuery.sortByChecksum();
|
||||
case AssetSort.ownerIdChecksum:
|
||||
query = filteredQuery.sortByOwnerId().thenByChecksum();
|
||||
}
|
||||
|
||||
return limit == null ? query.findAll() : query.limit(limit).findAll();
|
||||
}
|
||||
@@ -137,16 +155,17 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
||||
int limit = 100,
|
||||
}) {
|
||||
final baseQuery = db.assets.where();
|
||||
final QueryBuilder<Asset, Asset, QAfterFilterCondition> query =
|
||||
switch (state) {
|
||||
null => baseQuery.noOp(),
|
||||
AssetState.local =>
|
||||
baseQuery.remoteIdIsNull().filter().localIdIsNotNull(),
|
||||
AssetState.remote =>
|
||||
baseQuery.localIdIsNull().filter().remoteIdIsNotNull(),
|
||||
AssetState.merged =>
|
||||
baseQuery.localIdIsNotNull().filter().remoteIdIsNotNull(),
|
||||
};
|
||||
final QueryBuilder<Asset, Asset, QAfterFilterCondition> query;
|
||||
switch (state) {
|
||||
case null:
|
||||
query = baseQuery.noOp();
|
||||
case AssetState.local:
|
||||
query = baseQuery.remoteIdIsNull().filter().localIdIsNotNull();
|
||||
case AssetState.remote:
|
||||
query = baseQuery.localIdIsNull().filter().remoteIdIsNotNull();
|
||||
case AssetState.merged:
|
||||
query = baseQuery.localIdIsNotNull().filter().remoteIdIsNotNull();
|
||||
}
|
||||
return _getMatchesImpl(query, ownerId, assets, limit);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,13 @@ class BackupRepository extends DatabaseRepository implements IBackupRepository {
|
||||
@override
|
||||
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
|
||||
final baseQuery = db.backupAlbums.where();
|
||||
final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query =
|
||||
switch (sort) {
|
||||
null => baseQuery.noOp(),
|
||||
BackupAlbumSort.id => baseQuery.sortById(),
|
||||
};
|
||||
final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query;
|
||||
switch (sort) {
|
||||
case null:
|
||||
query = baseQuery.noOp();
|
||||
case BackupAlbumSort.id:
|
||||
query = baseQuery.sortById();
|
||||
}
|
||||
return query.findAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,13 @@ class UserRepository extends DatabaseRepository implements IUserRepository {
|
||||
final int userId = Store.get(StoreKey.currentUser).isarId;
|
||||
final QueryBuilder<User, User, QAfterWhereClause> afterWhere =
|
||||
self ? baseQuery.noOp() : baseQuery.isarIdNotEqualTo(userId);
|
||||
final QueryBuilder<User, User, QAfterSortBy> query = switch (sortBy) {
|
||||
null => afterWhere.noOp(),
|
||||
UserSort.id => afterWhere.sortById(),
|
||||
};
|
||||
final QueryBuilder<User, User, QAfterSortBy> query;
|
||||
switch (sortBy) {
|
||||
case null:
|
||||
query = afterWhere.noOp();
|
||||
case UserSort.id:
|
||||
query = afterWhere.sortById();
|
||||
}
|
||||
return query.findAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -519,12 +519,18 @@ class BackupService {
|
||||
return responseBody.containsKey('id') ? responseBody['id'] : null;
|
||||
}
|
||||
|
||||
String _getAssetType(AssetType assetType) => switch (assetType) {
|
||||
AssetType.audio => "AUDIO",
|
||||
AssetType.image => "IMAGE",
|
||||
AssetType.video => "VIDEO",
|
||||
AssetType.other => "OTHER",
|
||||
};
|
||||
String _getAssetType(AssetType assetType) {
|
||||
switch (assetType) {
|
||||
case AssetType.audio:
|
||||
return "AUDIO";
|
||||
case AssetType.image:
|
||||
return "IMAGE";
|
||||
case AssetType.video:
|
||||
return "VIDEO";
|
||||
case AssetType.other:
|
||||
return "OTHER";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MultipartRequest extends http.MultipartRequest {
|
||||
|
||||
@@ -84,10 +84,6 @@ class SearchService {
|
||||
? filter.filename
|
||||
: null,
|
||||
country: filter.location.country,
|
||||
description:
|
||||
filter.description != null && filter.description!.isNotEmpty
|
||||
? filter.description
|
||||
: null,
|
||||
state: filter.location.state,
|
||||
city: filter.location.city,
|
||||
make: filter.camera.make,
|
||||
@@ -105,7 +101,7 @@ class SearchService {
|
||||
);
|
||||
}
|
||||
|
||||
if (response == null || response.assets.items.isEmpty) {
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ dynamic upgradeDto(dynamic value, String targetType) {
|
||||
addDefault(value, 'ratings', RatingsResponse().toJson());
|
||||
addDefault(value, 'people', PeopleResponse().toJson());
|
||||
addDefault(value, 'tags', TagsResponse().toJson());
|
||||
addDefault(value, 'sharedLinks', SharedLinksResponse().toJson());
|
||||
}
|
||||
break;
|
||||
case 'ServerConfigDto':
|
||||
|
||||
@@ -2,8 +2,13 @@ import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
|
||||
/// Returns the suitable [IconData] to represent an [Asset]s storage location
|
||||
IconData storageIcon(Asset asset) => switch (asset.storage) {
|
||||
AssetState.local => Icons.cloud_off_outlined,
|
||||
AssetState.remote => Icons.cloud_outlined,
|
||||
AssetState.merged => Icons.cloud_done_outlined,
|
||||
};
|
||||
IconData storageIcon(Asset asset) {
|
||||
switch (asset.storage) {
|
||||
case AssetState.local:
|
||||
return Icons.cloud_off_outlined;
|
||||
case AssetState.remote:
|
||||
return Icons.cloud_outlined;
|
||||
case AssetState.merged:
|
||||
return Icons.cloud_done_outlined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,7 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final albumViewerState = ref.watch(albumViewerProvider);
|
||||
|
||||
final titleTextEditController = useTextEditingController(
|
||||
text: albumViewerState.isEditAlbum &&
|
||||
albumViewerState.editTitleText.isNotEmpty
|
||||
? albumViewerState.editTitleText
|
||||
: albumName,
|
||||
);
|
||||
final titleTextEditController = useTextEditingController(text: albumName);
|
||||
|
||||
void onFocusModeChange() {
|
||||
if (!titleFocusNode.hasFocus && titleTextEditController.text.isEmpty) {
|
||||
|
||||
@@ -204,13 +204,6 @@ class ThumbnailImage extends ConsumerWidget {
|
||||
storageIcon(asset),
|
||||
color: Colors.white.withOpacity(.8),
|
||||
size: 16,
|
||||
shadows: [
|
||||
Shadow(
|
||||
blurRadius: 5.0,
|
||||
color: Colors.black.withOpacity(0.6),
|
||||
offset: const Offset(0.0, 0.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (asset.isFavorite)
|
||||
|
||||
@@ -15,26 +15,36 @@ class ImmichToast {
|
||||
final fToast = FToast();
|
||||
fToast.init(context);
|
||||
|
||||
Color getColor(ToastType type, BuildContext context) => switch (type) {
|
||||
ToastType.info => context.primaryColor,
|
||||
ToastType.success => const Color.fromARGB(255, 78, 140, 124),
|
||||
ToastType.error => const Color.fromARGB(255, 220, 48, 85),
|
||||
};
|
||||
Color getColor(ToastType type, BuildContext context) {
|
||||
switch (type) {
|
||||
case ToastType.info:
|
||||
return context.primaryColor;
|
||||
case ToastType.success:
|
||||
return const Color.fromARGB(255, 78, 140, 124);
|
||||
case ToastType.error:
|
||||
return const Color.fromARGB(255, 220, 48, 85);
|
||||
}
|
||||
}
|
||||
|
||||
Icon getIcon(ToastType type) => switch (type) {
|
||||
ToastType.info => Icon(
|
||||
Icons.info_outline_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
ToastType.success => const Icon(
|
||||
Icons.check_circle_rounded,
|
||||
color: Color.fromARGB(255, 78, 140, 124),
|
||||
),
|
||||
ToastType.error => const Icon(
|
||||
Icons.error_outline_rounded,
|
||||
color: Color.fromARGB(255, 240, 162, 156),
|
||||
),
|
||||
};
|
||||
Icon getIcon(ToastType type) {
|
||||
switch (type) {
|
||||
case ToastType.info:
|
||||
return Icon(
|
||||
Icons.info_outline_rounded,
|
||||
color: context.primaryColor,
|
||||
);
|
||||
case ToastType.success:
|
||||
return const Icon(
|
||||
Icons.check_circle_rounded,
|
||||
color: Color.fromARGB(255, 78, 140, 124),
|
||||
);
|
||||
case ToastType.error:
|
||||
return const Icon(
|
||||
Icons.error_outline_rounded,
|
||||
color: Color.fromARGB(255, 240, 162, 156),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fToast.showToast(
|
||||
child: Container(
|
||||
|
||||
@@ -168,7 +168,7 @@ class LoginForm extends HookConsumerWidget {
|
||||
populateTestLoginInfo1() {
|
||||
emailController.text = 'testuser@email.com';
|
||||
passwordController.text = 'password';
|
||||
serverEndpointController.text = 'http://10.1.15.216:2283/api';
|
||||
serverEndpointController.text = 'http://10.1.15.216:3000/api';
|
||||
}
|
||||
|
||||
login() async {
|
||||
|
||||
@@ -59,10 +59,9 @@ class MapBottomSheet extends HookConsumerWidget {
|
||||
child: DraggableScrollableSheet(
|
||||
controller: sheetController,
|
||||
minChildSize: sheetMinExtent,
|
||||
maxChildSize: 0.8,
|
||||
maxChildSize: 0.5,
|
||||
initialChildSize: sheetMinExtent,
|
||||
snap: true,
|
||||
snapSizes: [sheetMinExtent, 0.5, 0.8],
|
||||
shouldCloseOnMinExtent: false,
|
||||
builder: (ctx, scrollController) => MapAssetGrid(
|
||||
controller: scrollController,
|
||||
@@ -79,23 +78,18 @@ class MapBottomSheet extends HookConsumerWidget {
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: bottomSheetOffset,
|
||||
builder: (context, value, child) {
|
||||
return Positioned(
|
||||
right: 0,
|
||||
bottom: context.height * (value + 0.02),
|
||||
child: AnimatedOpacity(
|
||||
opacity: value < 0.8 ? 1 : 0,
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: ElevatedButton(
|
||||
onPressed: onZoomToLocation,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: const CircleBorder(),
|
||||
),
|
||||
child: const Icon(Icons.my_location),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
builder: (ctx, value, child) => Positioned(
|
||||
right: 0,
|
||||
bottom: context.height * (value + 0.02),
|
||||
child: child!,
|
||||
),
|
||||
child: ElevatedButton(
|
||||
onPressed: onZoomToLocation,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: const CircleBorder(),
|
||||
),
|
||||
child: const Icon(Icons.my_location),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -75,12 +75,11 @@ class MemoryCard extends StatelessWidget {
|
||||
key: ValueKey(asset.id),
|
||||
asset: asset,
|
||||
showControls: false,
|
||||
playbackDelayFactor: 2,
|
||||
image: ImmichImage(
|
||||
asset,
|
||||
width: context.width,
|
||||
height: context.height,
|
||||
fit: BoxFit.contain,
|
||||
fit: fit,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -4,8 +4,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/widgets/asset_grid/thumbnail_placeholder.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/providers/memory.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||
@@ -35,13 +33,6 @@ class MemoryLane extends HookConsumerWidget {
|
||||
),
|
||||
onTap: (memoryIndex) {
|
||||
ref.read(hapticFeedbackProvider.notifier).heavyImpact();
|
||||
if (memories[memoryIndex].assets.isNotEmpty) {
|
||||
final asset = memories[memoryIndex].assets[0];
|
||||
ref.read(currentAssetProvider.notifier).set(asset);
|
||||
if (asset.isVideo || asset.isMotionPhoto) {
|
||||
ref.read(videoPlaybackValueProvider.notifier).reset();
|
||||
}
|
||||
}
|
||||
context.pushRoute(
|
||||
MemoryRoute(
|
||||
memories: memories,
|
||||
|
||||
@@ -590,15 +590,21 @@ class _PhotoViewState extends State<PhotoView>
|
||||
}
|
||||
|
||||
/// The default [ScaleStateCycle]
|
||||
PhotoViewScaleState defaultScaleStateCycle(PhotoViewScaleState actual) =>
|
||||
switch (actual) {
|
||||
PhotoViewScaleState.initial => PhotoViewScaleState.covering,
|
||||
PhotoViewScaleState.covering => PhotoViewScaleState.originalSize,
|
||||
PhotoViewScaleState.originalSize => PhotoViewScaleState.initial,
|
||||
PhotoViewScaleState.zoomedIn ||
|
||||
PhotoViewScaleState.zoomedOut =>
|
||||
PhotoViewScaleState.initial,
|
||||
};
|
||||
PhotoViewScaleState defaultScaleStateCycle(PhotoViewScaleState actual) {
|
||||
switch (actual) {
|
||||
case PhotoViewScaleState.initial:
|
||||
return PhotoViewScaleState.covering;
|
||||
case PhotoViewScaleState.covering:
|
||||
return PhotoViewScaleState.originalSize;
|
||||
case PhotoViewScaleState.originalSize:
|
||||
return PhotoViewScaleState.initial;
|
||||
case PhotoViewScaleState.zoomedIn:
|
||||
case PhotoViewScaleState.zoomedOut:
|
||||
return PhotoViewScaleState.initial;
|
||||
default:
|
||||
return PhotoViewScaleState.initial;
|
||||
}
|
||||
}
|
||||
|
||||
/// A type definition for a [Function] that receives the actual [PhotoViewScaleState] and returns the next one
|
||||
/// It is used internally to walk in the "doubletap gesture cycle".
|
||||
|
||||
@@ -9,20 +9,25 @@ double getScaleForScaleState(
|
||||
PhotoViewScaleState scaleState,
|
||||
ScaleBoundaries scaleBoundaries,
|
||||
) {
|
||||
return switch (scaleState) {
|
||||
PhotoViewScaleState.initial ||
|
||||
PhotoViewScaleState.zoomedIn ||
|
||||
PhotoViewScaleState.zoomedOut =>
|
||||
_clampSize(scaleBoundaries.initialScale, scaleBoundaries),
|
||||
PhotoViewScaleState.covering => _clampSize(
|
||||
switch (scaleState) {
|
||||
case PhotoViewScaleState.initial:
|
||||
case PhotoViewScaleState.zoomedIn:
|
||||
case PhotoViewScaleState.zoomedOut:
|
||||
return _clampSize(scaleBoundaries.initialScale, scaleBoundaries);
|
||||
case PhotoViewScaleState.covering:
|
||||
return _clampSize(
|
||||
_scaleForCovering(
|
||||
scaleBoundaries.outerSize,
|
||||
scaleBoundaries.childSize,
|
||||
),
|
||||
scaleBoundaries,
|
||||
),
|
||||
PhotoViewScaleState.originalSize => _clampSize(1.0, scaleBoundaries),
|
||||
};
|
||||
);
|
||||
case PhotoViewScaleState.originalSize:
|
||||
return _clampSize(1.0, scaleBoundaries);
|
||||
// Will never be reached
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal class to wraps custom scale boundaries (min, max and initial)
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||
import 'package:immich_mobile/interfaces/person_api.interface.dart';
|
||||
import 'package:immich_mobile/pages/common/large_leading_tile.dart';
|
||||
import 'package:immich_mobile/providers/search/people.provider.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
@@ -19,138 +16,63 @@ class PeoplePicker extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final formFocus = useFocusNode();
|
||||
final imageSize = 60.0;
|
||||
final searchQuery = useState('');
|
||||
var imageSize = 45.0;
|
||||
final people = ref.watch(getAllPeopleProvider);
|
||||
final headers = ApiService.getRequestHeaders();
|
||||
final selectedPeople = useState<Set<Person>>(filter ?? {});
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
return people.widgetWhen(
|
||||
onData: (people) {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: people.length,
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: TextField(
|
||||
focusNode: formFocus,
|
||||
onChanged: (value) => searchQuery.value = value,
|
||||
onTapOutside: (_) => formFocus.unfocus(),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.only(left: 24),
|
||||
filled: true,
|
||||
fillColor: context.primaryColor.withOpacity(0.1),
|
||||
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||
color: context.themeData.colorScheme.onSurfaceSecondary,
|
||||
itemBuilder: (context, index) {
|
||||
final person = people[index];
|
||||
return Card(
|
||||
elevation: 0,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
borderSide: BorderSide(
|
||||
color: context.colorScheme.surfaceContainerHighest,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
person.name,
|
||||
style: context.textTheme.bodyLarge,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
borderSide: BorderSide(
|
||||
color: context.colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
borderSide: BorderSide(
|
||||
color: context.colorScheme.surfaceContainerHighest,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
borderSide: BorderSide(
|
||||
color: context.colorScheme.primary.withAlpha(150),
|
||||
),
|
||||
),
|
||||
prefixIcon: Icon(
|
||||
Icons.search_rounded,
|
||||
color: context.colorScheme.primary,
|
||||
),
|
||||
hintText: 'search_filter_people_hint'.tr(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 0),
|
||||
child: Divider(
|
||||
color: context.colorScheme.surfaceContainerHighest,
|
||||
thickness: 1,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: people.widgetWhen(
|
||||
onData: (people) {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: people
|
||||
.where(
|
||||
(person) => person.name
|
||||
.toLowerCase()
|
||||
.contains(searchQuery.value.toLowerCase()),
|
||||
)
|
||||
.length,
|
||||
padding: const EdgeInsets.all(8),
|
||||
itemBuilder: (context, index) {
|
||||
final person = people
|
||||
.where(
|
||||
(person) => person.name
|
||||
.toLowerCase()
|
||||
.contains(searchQuery.value.toLowerCase()),
|
||||
)
|
||||
.toList()[index];
|
||||
final isSelected = selectedPeople.value.contains(person);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2.0),
|
||||
child: LargeLeadingTile(
|
||||
title: Text(
|
||||
person.name,
|
||||
style: context.textTheme.bodyLarge?.copyWith(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isSelected
|
||||
? context.colorScheme.onPrimary
|
||||
: context.colorScheme.onSurface,
|
||||
),
|
||||
leading: SizedBox(
|
||||
height: imageSize,
|
||||
child: Material(
|
||||
shape: const CircleBorder(side: BorderSide.none),
|
||||
elevation: 3,
|
||||
child: CircleAvatar(
|
||||
maxRadius: imageSize / 2,
|
||||
backgroundImage: NetworkImage(
|
||||
getFaceThumbnailUrl(person.id),
|
||||
headers: headers,
|
||||
),
|
||||
leading: SizedBox(
|
||||
height: imageSize,
|
||||
child: Material(
|
||||
shape: const CircleBorder(side: BorderSide.none),
|
||||
elevation: 3,
|
||||
child: CircleAvatar(
|
||||
maxRadius: imageSize / 2,
|
||||
backgroundImage: NetworkImage(
|
||||
getFaceThumbnailUrl(person.id),
|
||||
headers: headers,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (selectedPeople.value.contains(person)) {
|
||||
selectedPeople.value.remove(person);
|
||||
} else {
|
||||
selectedPeople.value.add(person);
|
||||
}
|
||||
|
||||
selectedPeople.value = {...selectedPeople.value};
|
||||
onSelect(selectedPeople.value);
|
||||
},
|
||||
selected: isSelected,
|
||||
selectedTileColor: context.primaryColor,
|
||||
tileColor: context.primaryColor.withAlpha(25),
|
||||
),
|
||||
);
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (selectedPeople.value.contains(person)) {
|
||||
selectedPeople.value.remove(person);
|
||||
} else {
|
||||
selectedPeople.value.add(person);
|
||||
}
|
||||
|
||||
selectedPeople.value = {...selectedPeople.value};
|
||||
onSelect(selectedPeople.value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
selected: selectedPeople.value.contains(person),
|
||||
selectedTileColor: context.primaryColor.withOpacity(0.2),
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,20 +220,23 @@ class NetworkStatusIcon extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIcon(BuildContext context) => switch (status) {
|
||||
AuxCheckStatus.loading => Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
child: SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
color: context.primaryColor,
|
||||
strokeWidth: 2,
|
||||
key: const ValueKey('loading'),
|
||||
),
|
||||
Widget _buildIcon(BuildContext context) {
|
||||
switch (status) {
|
||||
case AuxCheckStatus.loading:
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
child: SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
color: context.primaryColor,
|
||||
strokeWidth: 2,
|
||||
key: const ValueKey('loading'),
|
||||
),
|
||||
),
|
||||
AuxCheckStatus.valid => enabled
|
||||
);
|
||||
case AuxCheckStatus.valid:
|
||||
return enabled
|
||||
? const Icon(
|
||||
Icons.check_circle_rounded,
|
||||
color: Colors.green,
|
||||
@@ -243,8 +246,9 @@ class NetworkStatusIcon extends StatelessWidget {
|
||||
Icons.check_circle_rounded,
|
||||
color: context.colorScheme.onSurface.withAlpha(100),
|
||||
key: const ValueKey('success'),
|
||||
),
|
||||
AuxCheckStatus.error => enabled
|
||||
);
|
||||
case AuxCheckStatus.error:
|
||||
return enabled
|
||||
? const Icon(
|
||||
Icons.error_rounded,
|
||||
color: Colors.red,
|
||||
@@ -254,7 +258,9 @@ class NetworkStatusIcon extends StatelessWidget {
|
||||
Icons.error_rounded,
|
||||
color: Colors.grey,
|
||||
key: ValueKey('error'),
|
||||
),
|
||||
_ => const Icon(Icons.circle_outlined, key: ValueKey('unknown')),
|
||||
};
|
||||
);
|
||||
default:
|
||||
return const Icon(Icons.circle_outlined, key: ValueKey('unknown'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
mobile/openapi/README.md
generated
12
mobile/openapi/README.md
generated
@@ -3,7 +3,7 @@ Immich API
|
||||
|
||||
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: 1.126.1
|
||||
- API version: 1.125.6
|
||||
- Generator version: 7.8.0
|
||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||
|
||||
@@ -93,17 +93,17 @@ Class | Method | HTTP request | Description
|
||||
*AlbumsApi* | [**removeUserFromAlbum**](doc//AlbumsApi.md#removeuserfromalbum) | **DELETE** /albums/{id}/user/{userId} |
|
||||
*AlbumsApi* | [**updateAlbumInfo**](doc//AlbumsApi.md#updatealbuminfo) | **PATCH** /albums/{id} |
|
||||
*AlbumsApi* | [**updateAlbumUser**](doc//AlbumsApi.md#updatealbumuser) | **PUT** /albums/{id}/user/{userId} |
|
||||
*AssetsApi* | [**checkBulkUpload**](doc//AssetsApi.md#checkbulkupload) | **POST** /assets/bulk-upload-check | checkBulkUpload
|
||||
*AssetsApi* | [**checkExistingAssets**](doc//AssetsApi.md#checkexistingassets) | **POST** /assets/exist | checkExistingAssets
|
||||
*AssetsApi* | [**checkBulkUpload**](doc//AssetsApi.md#checkbulkupload) | **POST** /assets/bulk-upload-check | Checks if assets exist by checksums
|
||||
*AssetsApi* | [**checkExistingAssets**](doc//AssetsApi.md#checkexistingassets) | **POST** /assets/exist | Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
*AssetsApi* | [**deleteAssets**](doc//AssetsApi.md#deleteassets) | **DELETE** /assets |
|
||||
*AssetsApi* | [**downloadAsset**](doc//AssetsApi.md#downloadasset) | **GET** /assets/{id}/original |
|
||||
*AssetsApi* | [**getAllUserAssetsByDeviceId**](doc//AssetsApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | getAllUserAssetsByDeviceId
|
||||
*AssetsApi* | [**getAllUserAssetsByDeviceId**](doc//AssetsApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | Get all asset of a device that are in the database, ID only.
|
||||
*AssetsApi* | [**getAssetInfo**](doc//AssetsApi.md#getassetinfo) | **GET** /assets/{id} |
|
||||
*AssetsApi* | [**getAssetStatistics**](doc//AssetsApi.md#getassetstatistics) | **GET** /assets/statistics |
|
||||
*AssetsApi* | [**getMemoryLane**](doc//AssetsApi.md#getmemorylane) | **GET** /assets/memory-lane |
|
||||
*AssetsApi* | [**getRandom**](doc//AssetsApi.md#getrandom) | **GET** /assets/random |
|
||||
*AssetsApi* | [**playAssetVideo**](doc//AssetsApi.md#playassetvideo) | **GET** /assets/{id}/video/playback |
|
||||
*AssetsApi* | [**replaceAsset**](doc//AssetsApi.md#replaceasset) | **PUT** /assets/{id}/original | replaceAsset
|
||||
*AssetsApi* | [**replaceAsset**](doc//AssetsApi.md#replaceasset) | **PUT** /assets/{id}/original | Replace the asset with new file, without changing its id
|
||||
*AssetsApi* | [**runAssetJobs**](doc//AssetsApi.md#runassetjobs) | **POST** /assets/jobs |
|
||||
*AssetsApi* | [**updateAsset**](doc//AssetsApi.md#updateasset) | **PUT** /assets/{id} |
|
||||
*AssetsApi* | [**updateAssets**](doc//AssetsApi.md#updateassets) | **PUT** /assets |
|
||||
@@ -408,8 +408,6 @@ Class | Method | HTTP request | Description
|
||||
- [SharedLinkEditDto](doc//SharedLinkEditDto.md)
|
||||
- [SharedLinkResponseDto](doc//SharedLinkResponseDto.md)
|
||||
- [SharedLinkType](doc//SharedLinkType.md)
|
||||
- [SharedLinksResponse](doc//SharedLinksResponse.md)
|
||||
- [SharedLinksUpdate](doc//SharedLinksUpdate.md)
|
||||
- [SignUpDto](doc//SignUpDto.md)
|
||||
- [SmartSearchDto](doc//SmartSearchDto.md)
|
||||
- [SourceType](doc//SourceType.md)
|
||||
|
||||
2
mobile/openapi/lib/api.dart
generated
2
mobile/openapi/lib/api.dart
generated
@@ -221,8 +221,6 @@ part 'model/shared_link_create_dto.dart';
|
||||
part 'model/shared_link_edit_dto.dart';
|
||||
part 'model/shared_link_response_dto.dart';
|
||||
part 'model/shared_link_type.dart';
|
||||
part 'model/shared_links_response.dart';
|
||||
part 'model/shared_links_update.dart';
|
||||
part 'model/sign_up_dto.dart';
|
||||
part 'model/smart_search_dto.dart';
|
||||
part 'model/source_type.dart';
|
||||
|
||||
16
mobile/openapi/lib/api/assets_api.dart
generated
16
mobile/openapi/lib/api/assets_api.dart
generated
@@ -16,8 +16,6 @@ class AssetsApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// checkBulkUpload
|
||||
///
|
||||
/// Checks if assets exist by checksums
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -50,8 +48,6 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// checkBulkUpload
|
||||
///
|
||||
/// Checks if assets exist by checksums
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -72,8 +68,6 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// checkExistingAssets
|
||||
///
|
||||
/// Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -106,8 +100,6 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// checkExistingAssets
|
||||
///
|
||||
/// Checks if multiple assets exist on the server and returns all existing - used by background backup
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -223,8 +215,6 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// getAllUserAssetsByDeviceId
|
||||
///
|
||||
/// Get all asset of a device that are in the database, ID only.
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -258,8 +248,6 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// getAllUserAssetsByDeviceId
|
||||
///
|
||||
/// Get all asset of a device that are in the database, ID only.
|
||||
///
|
||||
/// Parameters:
|
||||
@@ -576,8 +564,6 @@ class AssetsApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// replaceAsset
|
||||
///
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -659,8 +645,6 @@ class AssetsApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// replaceAsset
|
||||
///
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Parameters:
|
||||
|
||||
16
mobile/openapi/lib/api/shared_links_api.dart
generated
16
mobile/openapi/lib/api/shared_links_api.dart
generated
@@ -127,10 +127,7 @@ class SharedLinksApi {
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /shared-links' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] albumId:
|
||||
Future<Response> getAllSharedLinksWithHttpInfo({ String? albumId, }) async {
|
||||
Future<Response> getAllSharedLinksWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-links';
|
||||
|
||||
@@ -141,10 +138,6 @@ class SharedLinksApi {
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
if (albumId != null) {
|
||||
queryParams.addAll(_queryParams('', 'albumId', albumId));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
@@ -159,11 +152,8 @@ class SharedLinksApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] albumId:
|
||||
Future<List<SharedLinkResponseDto>?> getAllSharedLinks({ String? albumId, }) async {
|
||||
final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, );
|
||||
Future<List<SharedLinkResponseDto>?> getAllSharedLinks() async {
|
||||
final response = await getAllSharedLinksWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
|
||||
4
mobile/openapi/lib/api_client.dart
generated
4
mobile/openapi/lib/api_client.dart
generated
@@ -496,10 +496,6 @@ class ApiClient {
|
||||
return SharedLinkResponseDto.fromJson(value);
|
||||
case 'SharedLinkType':
|
||||
return SharedLinkTypeTypeTransformer().decode(value);
|
||||
case 'SharedLinksResponse':
|
||||
return SharedLinksResponse.fromJson(value);
|
||||
case 'SharedLinksUpdate':
|
||||
return SharedLinksUpdate.fromJson(value);
|
||||
case 'SignUpDto':
|
||||
return SignUpDto.fromJson(value);
|
||||
case 'SmartSearchDto':
|
||||
|
||||
105
mobile/openapi/lib/model/asset_bulk_update_dto.dart
generated
105
mobile/openapi/lib/model/asset_bulk_update_dto.dart
generated
@@ -20,7 +20,6 @@ class AssetBulkUpdateDto {
|
||||
this.isFavorite,
|
||||
this.latitude,
|
||||
this.longitude,
|
||||
this.orientation,
|
||||
this.rating,
|
||||
});
|
||||
|
||||
@@ -68,8 +67,6 @@ class AssetBulkUpdateDto {
|
||||
///
|
||||
num? longitude;
|
||||
|
||||
AssetBulkUpdateDtoOrientationEnum? orientation;
|
||||
|
||||
/// Minimum value: -1
|
||||
/// Maximum value: 5
|
||||
///
|
||||
@@ -89,7 +86,6 @@ class AssetBulkUpdateDto {
|
||||
other.isFavorite == isFavorite &&
|
||||
other.latitude == latitude &&
|
||||
other.longitude == longitude &&
|
||||
other.orientation == orientation &&
|
||||
other.rating == rating;
|
||||
|
||||
@override
|
||||
@@ -102,11 +98,10 @@ class AssetBulkUpdateDto {
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(latitude == null ? 0 : latitude!.hashCode) +
|
||||
(longitude == null ? 0 : longitude!.hashCode) +
|
||||
(orientation == null ? 0 : orientation!.hashCode) +
|
||||
(rating == null ? 0 : rating!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, duplicateId=$duplicateId, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, orientation=$orientation, rating=$rating]';
|
||||
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, duplicateId=$duplicateId, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, rating=$rating]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -141,11 +136,6 @@ class AssetBulkUpdateDto {
|
||||
} else {
|
||||
// json[r'longitude'] = null;
|
||||
}
|
||||
if (this.orientation != null) {
|
||||
json[r'orientation'] = this.orientation;
|
||||
} else {
|
||||
// json[r'orientation'] = null;
|
||||
}
|
||||
if (this.rating != null) {
|
||||
json[r'rating'] = this.rating;
|
||||
} else {
|
||||
@@ -172,7 +162,6 @@ class AssetBulkUpdateDto {
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
latitude: num.parse('${json[r'latitude']}'),
|
||||
longitude: num.parse('${json[r'longitude']}'),
|
||||
orientation: AssetBulkUpdateDtoOrientationEnum.fromJson(json[r'orientation']),
|
||||
rating: num.parse('${json[r'rating']}'),
|
||||
);
|
||||
}
|
||||
@@ -225,95 +214,3 @@ class AssetBulkUpdateDto {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class AssetBulkUpdateDtoOrientationEnum {
|
||||
/// Instantiate a new enum with the provided [value].
|
||||
const AssetBulkUpdateDtoOrientationEnum._(this.value);
|
||||
|
||||
/// The underlying value of this enum member.
|
||||
final int value;
|
||||
|
||||
@override
|
||||
String toString() => value.toString();
|
||||
|
||||
int toJson() => value;
|
||||
|
||||
static const number1 = AssetBulkUpdateDtoOrientationEnum._(1);
|
||||
static const number2 = AssetBulkUpdateDtoOrientationEnum._(2);
|
||||
static const number3 = AssetBulkUpdateDtoOrientationEnum._(3);
|
||||
static const number4 = AssetBulkUpdateDtoOrientationEnum._(4);
|
||||
static const number5 = AssetBulkUpdateDtoOrientationEnum._(5);
|
||||
static const number6 = AssetBulkUpdateDtoOrientationEnum._(6);
|
||||
static const number7 = AssetBulkUpdateDtoOrientationEnum._(7);
|
||||
static const number8 = AssetBulkUpdateDtoOrientationEnum._(8);
|
||||
|
||||
/// List of all possible values in this [enum][AssetBulkUpdateDtoOrientationEnum].
|
||||
static const values = <AssetBulkUpdateDtoOrientationEnum>[
|
||||
number1,
|
||||
number2,
|
||||
number3,
|
||||
number4,
|
||||
number5,
|
||||
number6,
|
||||
number7,
|
||||
number8,
|
||||
];
|
||||
|
||||
static AssetBulkUpdateDtoOrientationEnum? fromJson(dynamic value) => AssetBulkUpdateDtoOrientationEnumTypeTransformer().decode(value);
|
||||
|
||||
static List<AssetBulkUpdateDtoOrientationEnum> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <AssetBulkUpdateDtoOrientationEnum>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = AssetBulkUpdateDtoOrientationEnum.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
}
|
||||
|
||||
/// Transformation class that can [encode] an instance of [AssetBulkUpdateDtoOrientationEnum] to int,
|
||||
/// and [decode] dynamic data back to [AssetBulkUpdateDtoOrientationEnum].
|
||||
class AssetBulkUpdateDtoOrientationEnumTypeTransformer {
|
||||
factory AssetBulkUpdateDtoOrientationEnumTypeTransformer() => _instance ??= const AssetBulkUpdateDtoOrientationEnumTypeTransformer._();
|
||||
|
||||
const AssetBulkUpdateDtoOrientationEnumTypeTransformer._();
|
||||
|
||||
int encode(AssetBulkUpdateDtoOrientationEnum data) => data.value;
|
||||
|
||||
/// Decodes a [dynamic value][data] to a AssetBulkUpdateDtoOrientationEnum.
|
||||
///
|
||||
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||
///
|
||||
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||
/// and users are still using an old app with the old code.
|
||||
AssetBulkUpdateDtoOrientationEnum? decode(dynamic data, {bool allowNull = true}) {
|
||||
if (data != null) {
|
||||
switch (data) {
|
||||
case 1: return AssetBulkUpdateDtoOrientationEnum.number1;
|
||||
case 2: return AssetBulkUpdateDtoOrientationEnum.number2;
|
||||
case 3: return AssetBulkUpdateDtoOrientationEnum.number3;
|
||||
case 4: return AssetBulkUpdateDtoOrientationEnum.number4;
|
||||
case 5: return AssetBulkUpdateDtoOrientationEnum.number5;
|
||||
case 6: return AssetBulkUpdateDtoOrientationEnum.number6;
|
||||
case 7: return AssetBulkUpdateDtoOrientationEnum.number7;
|
||||
case 8: return AssetBulkUpdateDtoOrientationEnum.number8;
|
||||
default:
|
||||
if (!allowNull) {
|
||||
throw ArgumentError('Unknown enum value to decode: $data');
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Singleton [AssetBulkUpdateDtoOrientationEnumTypeTransformer] instance.
|
||||
static AssetBulkUpdateDtoOrientationEnumTypeTransformer? _instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
28
mobile/openapi/lib/model/metadata_search_dto.dart
generated
28
mobile/openapi/lib/model/metadata_search_dto.dart
generated
@@ -18,7 +18,6 @@ class MetadataSearchDto {
|
||||
this.country,
|
||||
this.createdAfter,
|
||||
this.createdBefore,
|
||||
this.description,
|
||||
this.deviceAssetId,
|
||||
this.deviceId,
|
||||
this.encodedVideoPath,
|
||||
@@ -42,7 +41,6 @@ class MetadataSearchDto {
|
||||
this.previewPath,
|
||||
this.size,
|
||||
this.state,
|
||||
this.tagIds = const [],
|
||||
this.takenAfter,
|
||||
this.takenBefore,
|
||||
this.thumbnailPath,
|
||||
@@ -86,14 +84,6 @@ class MetadataSearchDto {
|
||||
///
|
||||
DateTime? createdBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? description;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -245,8 +235,6 @@ class MetadataSearchDto {
|
||||
|
||||
String? state;
|
||||
|
||||
List<String> tagIds;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -352,7 +340,6 @@ class MetadataSearchDto {
|
||||
other.country == country &&
|
||||
other.createdAfter == createdAfter &&
|
||||
other.createdBefore == createdBefore &&
|
||||
other.description == description &&
|
||||
other.deviceAssetId == deviceAssetId &&
|
||||
other.deviceId == deviceId &&
|
||||
other.encodedVideoPath == encodedVideoPath &&
|
||||
@@ -376,7 +363,6 @@ class MetadataSearchDto {
|
||||
other.previewPath == previewPath &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
_deepEquality.equals(other.tagIds, tagIds) &&
|
||||
other.takenAfter == takenAfter &&
|
||||
other.takenBefore == takenBefore &&
|
||||
other.thumbnailPath == thumbnailPath &&
|
||||
@@ -399,7 +385,6 @@ class MetadataSearchDto {
|
||||
(country == null ? 0 : country!.hashCode) +
|
||||
(createdAfter == null ? 0 : createdAfter!.hashCode) +
|
||||
(createdBefore == null ? 0 : createdBefore!.hashCode) +
|
||||
(description == null ? 0 : description!.hashCode) +
|
||||
(deviceAssetId == null ? 0 : deviceAssetId!.hashCode) +
|
||||
(deviceId == null ? 0 : deviceId!.hashCode) +
|
||||
(encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) +
|
||||
@@ -423,7 +408,6 @@ class MetadataSearchDto {
|
||||
(previewPath == null ? 0 : previewPath!.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(tagIds.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
(takenBefore == null ? 0 : takenBefore!.hashCode) +
|
||||
(thumbnailPath == null ? 0 : thumbnailPath!.hashCode) +
|
||||
@@ -439,7 +423,7 @@ class MetadataSearchDto {
|
||||
(withStacked == null ? 0 : withStacked!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -468,11 +452,6 @@ class MetadataSearchDto {
|
||||
} else {
|
||||
// json[r'createdBefore'] = null;
|
||||
}
|
||||
if (this.description != null) {
|
||||
json[r'description'] = this.description;
|
||||
} else {
|
||||
// json[r'description'] = null;
|
||||
}
|
||||
if (this.deviceAssetId != null) {
|
||||
json[r'deviceAssetId'] = this.deviceAssetId;
|
||||
} else {
|
||||
@@ -580,7 +559,6 @@ class MetadataSearchDto {
|
||||
} else {
|
||||
// json[r'state'] = null;
|
||||
}
|
||||
json[r'tagIds'] = this.tagIds;
|
||||
if (this.takenAfter != null) {
|
||||
json[r'takenAfter'] = this.takenAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
@@ -659,7 +637,6 @@ class MetadataSearchDto {
|
||||
country: mapValueOfType<String>(json, r'country'),
|
||||
createdAfter: mapDateTime(json, r'createdAfter', r''),
|
||||
createdBefore: mapDateTime(json, r'createdBefore', r''),
|
||||
description: mapValueOfType<String>(json, r'description'),
|
||||
deviceAssetId: mapValueOfType<String>(json, r'deviceAssetId'),
|
||||
deviceId: mapValueOfType<String>(json, r'deviceId'),
|
||||
encodedVideoPath: mapValueOfType<String>(json, r'encodedVideoPath'),
|
||||
@@ -685,9 +662,6 @@ class MetadataSearchDto {
|
||||
previewPath: mapValueOfType<String>(json, r'previewPath'),
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
tagIds: json[r'tagIds'] is Iterable
|
||||
? (json[r'tagIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
takenBefore: mapDateTime(json, r'takenBefore', r''),
|
||||
thumbnailPath: mapValueOfType<String>(json, r'thumbnailPath'),
|
||||
|
||||
30
mobile/openapi/lib/model/people_update_item.dart
generated
30
mobile/openapi/lib/model/people_update_item.dart
generated
@@ -14,10 +14,8 @@ class PeopleUpdateItem {
|
||||
/// Returns a new [PeopleUpdateItem] instance.
|
||||
PeopleUpdateItem({
|
||||
this.birthDate,
|
||||
this.color,
|
||||
this.featureFaceAssetId,
|
||||
required this.id,
|
||||
this.isFavorite,
|
||||
this.isHidden,
|
||||
this.name,
|
||||
});
|
||||
@@ -25,8 +23,6 @@ class PeopleUpdateItem {
|
||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||
DateTime? birthDate;
|
||||
|
||||
String? color;
|
||||
|
||||
/// Asset is used to get the feature face thumbnail.
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
@@ -39,14 +35,6 @@ class PeopleUpdateItem {
|
||||
/// Person id.
|
||||
String id;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
/// Person visibility
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
@@ -68,10 +56,8 @@ class PeopleUpdateItem {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PeopleUpdateItem &&
|
||||
other.birthDate == birthDate &&
|
||||
other.color == color &&
|
||||
other.featureFaceAssetId == featureFaceAssetId &&
|
||||
other.id == id &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name;
|
||||
|
||||
@@ -79,15 +65,13 @@ class PeopleUpdateItem {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(color == null ? 0 : color!.hashCode) +
|
||||
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isHidden == null ? 0 : isHidden!.hashCode) +
|
||||
(name == null ? 0 : name!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PeopleUpdateItem[birthDate=$birthDate, color=$color, featureFaceAssetId=$featureFaceAssetId, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||
String toString() => 'PeopleUpdateItem[birthDate=$birthDate, featureFaceAssetId=$featureFaceAssetId, id=$id, isHidden=$isHidden, name=$name]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -96,22 +80,12 @@ class PeopleUpdateItem {
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.color != null) {
|
||||
json[r'color'] = this.color;
|
||||
} else {
|
||||
// json[r'color'] = null;
|
||||
}
|
||||
if (this.featureFaceAssetId != null) {
|
||||
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
||||
} else {
|
||||
// json[r'featureFaceAssetId'] = null;
|
||||
}
|
||||
json[r'id'] = this.id;
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
if (this.isHidden != null) {
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
} else {
|
||||
@@ -135,10 +109,8 @@ class PeopleUpdateItem {
|
||||
|
||||
return PeopleUpdateItem(
|
||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||
color: mapValueOfType<String>(json, r'color'),
|
||||
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
||||
name: mapValueOfType<String>(json, r'name'),
|
||||
);
|
||||
|
||||
30
mobile/openapi/lib/model/person_create_dto.dart
generated
30
mobile/openapi/lib/model/person_create_dto.dart
generated
@@ -14,8 +14,6 @@ class PersonCreateDto {
|
||||
/// Returns a new [PersonCreateDto] instance.
|
||||
PersonCreateDto({
|
||||
this.birthDate,
|
||||
this.color,
|
||||
this.isFavorite,
|
||||
this.isHidden,
|
||||
this.name,
|
||||
});
|
||||
@@ -23,16 +21,6 @@ class PersonCreateDto {
|
||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||
DateTime? birthDate;
|
||||
|
||||
String? color;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
/// Person visibility
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
@@ -54,8 +42,6 @@ class PersonCreateDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PersonCreateDto &&
|
||||
other.birthDate == birthDate &&
|
||||
other.color == color &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name;
|
||||
|
||||
@@ -63,13 +49,11 @@ class PersonCreateDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(color == null ? 0 : color!.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isHidden == null ? 0 : isHidden!.hashCode) +
|
||||
(name == null ? 0 : name!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PersonCreateDto[birthDate=$birthDate, color=$color, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||
String toString() => 'PersonCreateDto[birthDate=$birthDate, isHidden=$isHidden, name=$name]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -78,16 +62,6 @@ class PersonCreateDto {
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.color != null) {
|
||||
json[r'color'] = this.color;
|
||||
} else {
|
||||
// json[r'color'] = null;
|
||||
}
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
if (this.isHidden != null) {
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
} else {
|
||||
@@ -111,8 +85,6 @@ class PersonCreateDto {
|
||||
|
||||
return PersonCreateDto(
|
||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||
color: mapValueOfType<String>(json, r'color'),
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
||||
name: mapValueOfType<String>(json, r'name'),
|
||||
);
|
||||
|
||||
38
mobile/openapi/lib/model/person_response_dto.dart
generated
38
mobile/openapi/lib/model/person_response_dto.dart
generated
@@ -14,9 +14,7 @@ class PersonResponseDto {
|
||||
/// Returns a new [PersonResponseDto] instance.
|
||||
PersonResponseDto({
|
||||
required this.birthDate,
|
||||
this.color,
|
||||
required this.id,
|
||||
this.isFavorite,
|
||||
required this.isHidden,
|
||||
required this.name,
|
||||
required this.thumbnailPath,
|
||||
@@ -25,26 +23,8 @@ class PersonResponseDto {
|
||||
|
||||
DateTime? birthDate;
|
||||
|
||||
/// This property was added in v1.126.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? color;
|
||||
|
||||
String id;
|
||||
|
||||
/// This property was added in v1.126.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
bool isHidden;
|
||||
|
||||
String name;
|
||||
@@ -63,9 +43,7 @@ class PersonResponseDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PersonResponseDto &&
|
||||
other.birthDate == birthDate &&
|
||||
other.color == color &&
|
||||
other.id == id &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name &&
|
||||
other.thumbnailPath == thumbnailPath &&
|
||||
@@ -75,16 +53,14 @@ class PersonResponseDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(color == null ? 0 : color!.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isHidden.hashCode) +
|
||||
(name.hashCode) +
|
||||
(thumbnailPath.hashCode) +
|
||||
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PersonResponseDto[birthDate=$birthDate, color=$color, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||
String toString() => 'PersonResponseDto[birthDate=$birthDate, id=$id, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -92,18 +68,8 @@ class PersonResponseDto {
|
||||
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.color != null) {
|
||||
json[r'color'] = this.color;
|
||||
} else {
|
||||
// json[r'color'] = null;
|
||||
}
|
||||
json[r'id'] = this.id;
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
json[r'name'] = this.name;
|
||||
json[r'thumbnailPath'] = this.thumbnailPath;
|
||||
@@ -125,9 +91,7 @@ class PersonResponseDto {
|
||||
|
||||
return PersonResponseDto(
|
||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||
color: mapValueOfType<String>(json, r'color'),
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden')!,
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
thumbnailPath: mapValueOfType<String>(json, r'thumbnailPath')!,
|
||||
|
||||
30
mobile/openapi/lib/model/person_update_dto.dart
generated
30
mobile/openapi/lib/model/person_update_dto.dart
generated
@@ -14,9 +14,7 @@ class PersonUpdateDto {
|
||||
/// Returns a new [PersonUpdateDto] instance.
|
||||
PersonUpdateDto({
|
||||
this.birthDate,
|
||||
this.color,
|
||||
this.featureFaceAssetId,
|
||||
this.isFavorite,
|
||||
this.isHidden,
|
||||
this.name,
|
||||
});
|
||||
@@ -24,8 +22,6 @@ class PersonUpdateDto {
|
||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||
DateTime? birthDate;
|
||||
|
||||
String? color;
|
||||
|
||||
/// Asset is used to get the feature face thumbnail.
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
@@ -35,14 +31,6 @@ class PersonUpdateDto {
|
||||
///
|
||||
String? featureFaceAssetId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
/// Person visibility
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
@@ -64,9 +52,7 @@ class PersonUpdateDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PersonUpdateDto &&
|
||||
other.birthDate == birthDate &&
|
||||
other.color == color &&
|
||||
other.featureFaceAssetId == featureFaceAssetId &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name;
|
||||
|
||||
@@ -74,14 +60,12 @@ class PersonUpdateDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(color == null ? 0 : color!.hashCode) +
|
||||
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isHidden == null ? 0 : isHidden!.hashCode) +
|
||||
(name == null ? 0 : name!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PersonUpdateDto[birthDate=$birthDate, color=$color, featureFaceAssetId=$featureFaceAssetId, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||
String toString() => 'PersonUpdateDto[birthDate=$birthDate, featureFaceAssetId=$featureFaceAssetId, isHidden=$isHidden, name=$name]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -90,21 +74,11 @@ class PersonUpdateDto {
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.color != null) {
|
||||
json[r'color'] = this.color;
|
||||
} else {
|
||||
// json[r'color'] = null;
|
||||
}
|
||||
if (this.featureFaceAssetId != null) {
|
||||
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
||||
} else {
|
||||
// json[r'featureFaceAssetId'] = null;
|
||||
}
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
if (this.isHidden != null) {
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
} else {
|
||||
@@ -128,9 +102,7 @@ class PersonUpdateDto {
|
||||
|
||||
return PersonUpdateDto(
|
||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||
color: mapValueOfType<String>(json, r'color'),
|
||||
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
||||
name: mapValueOfType<String>(json, r'name'),
|
||||
);
|
||||
|
||||
@@ -14,10 +14,8 @@ class PersonWithFacesResponseDto {
|
||||
/// Returns a new [PersonWithFacesResponseDto] instance.
|
||||
PersonWithFacesResponseDto({
|
||||
required this.birthDate,
|
||||
this.color,
|
||||
this.faces = const [],
|
||||
required this.id,
|
||||
this.isFavorite,
|
||||
required this.isHidden,
|
||||
required this.name,
|
||||
required this.thumbnailPath,
|
||||
@@ -26,28 +24,10 @@ class PersonWithFacesResponseDto {
|
||||
|
||||
DateTime? birthDate;
|
||||
|
||||
/// This property was added in v1.126.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? color;
|
||||
|
||||
List<AssetFaceWithoutPersonResponseDto> faces;
|
||||
|
||||
String id;
|
||||
|
||||
/// This property was added in v1.126.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
bool isHidden;
|
||||
|
||||
String name;
|
||||
@@ -66,10 +46,8 @@ class PersonWithFacesResponseDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PersonWithFacesResponseDto &&
|
||||
other.birthDate == birthDate &&
|
||||
other.color == color &&
|
||||
_deepEquality.equals(other.faces, faces) &&
|
||||
other.id == id &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name &&
|
||||
other.thumbnailPath == thumbnailPath &&
|
||||
@@ -79,17 +57,15 @@ class PersonWithFacesResponseDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||
(color == null ? 0 : color!.hashCode) +
|
||||
(faces.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isHidden.hashCode) +
|
||||
(name.hashCode) +
|
||||
(thumbnailPath.hashCode) +
|
||||
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PersonWithFacesResponseDto[birthDate=$birthDate, color=$color, faces=$faces, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||
String toString() => 'PersonWithFacesResponseDto[birthDate=$birthDate, faces=$faces, id=$id, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -97,19 +73,9 @@ class PersonWithFacesResponseDto {
|
||||
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
||||
} else {
|
||||
// json[r'birthDate'] = null;
|
||||
}
|
||||
if (this.color != null) {
|
||||
json[r'color'] = this.color;
|
||||
} else {
|
||||
// json[r'color'] = null;
|
||||
}
|
||||
json[r'faces'] = this.faces;
|
||||
json[r'id'] = this.id;
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
json[r'isHidden'] = this.isHidden;
|
||||
json[r'name'] = this.name;
|
||||
json[r'thumbnailPath'] = this.thumbnailPath;
|
||||
@@ -131,10 +97,8 @@ class PersonWithFacesResponseDto {
|
||||
|
||||
return PersonWithFacesResponseDto(
|
||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||
color: mapValueOfType<String>(json, r'color'),
|
||||
faces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'faces']),
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isHidden: mapValueOfType<bool>(json, r'isHidden')!,
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
thumbnailPath: mapValueOfType<String>(json, r'thumbnailPath')!,
|
||||
|
||||
11
mobile/openapi/lib/model/random_search_dto.dart
generated
11
mobile/openapi/lib/model/random_search_dto.dart
generated
@@ -32,7 +32,6 @@ class RandomSearchDto {
|
||||
this.personIds = const [],
|
||||
this.size,
|
||||
this.state,
|
||||
this.tagIds = const [],
|
||||
this.takenAfter,
|
||||
this.takenBefore,
|
||||
this.trashedAfter,
|
||||
@@ -159,8 +158,6 @@ class RandomSearchDto {
|
||||
|
||||
String? state;
|
||||
|
||||
List<String> tagIds;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -272,7 +269,6 @@ class RandomSearchDto {
|
||||
_deepEquality.equals(other.personIds, personIds) &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
_deepEquality.equals(other.tagIds, tagIds) &&
|
||||
other.takenAfter == takenAfter &&
|
||||
other.takenBefore == takenBefore &&
|
||||
other.trashedAfter == trashedAfter &&
|
||||
@@ -308,7 +304,6 @@ class RandomSearchDto {
|
||||
(personIds.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(tagIds.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
(takenBefore == null ? 0 : takenBefore!.hashCode) +
|
||||
(trashedAfter == null ? 0 : trashedAfter!.hashCode) +
|
||||
@@ -323,7 +318,7 @@ class RandomSearchDto {
|
||||
(withStacked == null ? 0 : withStacked!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'RandomSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
String toString() => 'RandomSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, personIds=$personIds, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -418,7 +413,6 @@ class RandomSearchDto {
|
||||
} else {
|
||||
// json[r'state'] = null;
|
||||
}
|
||||
json[r'tagIds'] = this.tagIds;
|
||||
if (this.takenAfter != null) {
|
||||
json[r'takenAfter'] = this.takenAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
@@ -508,9 +502,6 @@ class RandomSearchDto {
|
||||
: const [],
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
tagIds: json[r'tagIds'] is Iterable
|
||||
? (json[r'tagIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
takenBefore: mapDateTime(json, r'takenBefore', r''),
|
||||
trashedAfter: mapDateTime(json, r'trashedAfter', r''),
|
||||
|
||||
107
mobile/openapi/lib/model/shared_links_response.dart
generated
107
mobile/openapi/lib/model/shared_links_response.dart
generated
@@ -1,107 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class SharedLinksResponse {
|
||||
/// Returns a new [SharedLinksResponse] instance.
|
||||
SharedLinksResponse({
|
||||
this.enabled = true,
|
||||
this.sidebarWeb = false,
|
||||
});
|
||||
|
||||
bool enabled;
|
||||
|
||||
bool sidebarWeb;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is SharedLinksResponse &&
|
||||
other.enabled == enabled &&
|
||||
other.sidebarWeb == sidebarWeb;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(enabled.hashCode) +
|
||||
(sidebarWeb.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SharedLinksResponse[enabled=$enabled, sidebarWeb=$sidebarWeb]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'enabled'] = this.enabled;
|
||||
json[r'sidebarWeb'] = this.sidebarWeb;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [SharedLinksResponse] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static SharedLinksResponse? fromJson(dynamic value) {
|
||||
upgradeDto(value, "SharedLinksResponse");
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return SharedLinksResponse(
|
||||
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||
sidebarWeb: mapValueOfType<bool>(json, r'sidebarWeb')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<SharedLinksResponse> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <SharedLinksResponse>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = SharedLinksResponse.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, SharedLinksResponse> mapFromJson(dynamic json) {
|
||||
final map = <String, SharedLinksResponse>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = SharedLinksResponse.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of SharedLinksResponse-objects as value to a dart map
|
||||
static Map<String, List<SharedLinksResponse>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<SharedLinksResponse>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = SharedLinksResponse.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'enabled',
|
||||
'sidebarWeb',
|
||||
};
|
||||
}
|
||||
|
||||
125
mobile/openapi/lib/model/shared_links_update.dart
generated
125
mobile/openapi/lib/model/shared_links_update.dart
generated
@@ -1,125 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class SharedLinksUpdate {
|
||||
/// Returns a new [SharedLinksUpdate] instance.
|
||||
SharedLinksUpdate({
|
||||
this.enabled,
|
||||
this.sidebarWeb,
|
||||
});
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? enabled;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? sidebarWeb;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is SharedLinksUpdate &&
|
||||
other.enabled == enabled &&
|
||||
other.sidebarWeb == sidebarWeb;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(enabled == null ? 0 : enabled!.hashCode) +
|
||||
(sidebarWeb == null ? 0 : sidebarWeb!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SharedLinksUpdate[enabled=$enabled, sidebarWeb=$sidebarWeb]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
if (this.enabled != null) {
|
||||
json[r'enabled'] = this.enabled;
|
||||
} else {
|
||||
// json[r'enabled'] = null;
|
||||
}
|
||||
if (this.sidebarWeb != null) {
|
||||
json[r'sidebarWeb'] = this.sidebarWeb;
|
||||
} else {
|
||||
// json[r'sidebarWeb'] = null;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [SharedLinksUpdate] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static SharedLinksUpdate? fromJson(dynamic value) {
|
||||
upgradeDto(value, "SharedLinksUpdate");
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return SharedLinksUpdate(
|
||||
enabled: mapValueOfType<bool>(json, r'enabled'),
|
||||
sidebarWeb: mapValueOfType<bool>(json, r'sidebarWeb'),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<SharedLinksUpdate> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <SharedLinksUpdate>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = SharedLinksUpdate.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, SharedLinksUpdate> mapFromJson(dynamic json) {
|
||||
final map = <String, SharedLinksUpdate>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = SharedLinksUpdate.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of SharedLinksUpdate-objects as value to a dart map
|
||||
static Map<String, List<SharedLinksUpdate>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<SharedLinksUpdate>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = SharedLinksUpdate.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
};
|
||||
}
|
||||
|
||||
11
mobile/openapi/lib/model/smart_search_dto.dart
generated
11
mobile/openapi/lib/model/smart_search_dto.dart
generated
@@ -34,7 +34,6 @@ class SmartSearchDto {
|
||||
required this.query,
|
||||
this.size,
|
||||
this.state,
|
||||
this.tagIds = const [],
|
||||
this.takenAfter,
|
||||
this.takenBefore,
|
||||
this.trashedAfter,
|
||||
@@ -170,8 +169,6 @@ class SmartSearchDto {
|
||||
|
||||
String? state;
|
||||
|
||||
List<String> tagIds;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -269,7 +266,6 @@ class SmartSearchDto {
|
||||
other.query == query &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
_deepEquality.equals(other.tagIds, tagIds) &&
|
||||
other.takenAfter == takenAfter &&
|
||||
other.takenBefore == takenBefore &&
|
||||
other.trashedAfter == trashedAfter &&
|
||||
@@ -305,7 +301,6 @@ class SmartSearchDto {
|
||||
(query.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(tagIds.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
(takenBefore == null ? 0 : takenBefore!.hashCode) +
|
||||
(trashedAfter == null ? 0 : trashedAfter!.hashCode) +
|
||||
@@ -318,7 +313,7 @@ class SmartSearchDto {
|
||||
(withExif == null ? 0 : withExif!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, personIds=$personIds, query=$query, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif]';
|
||||
String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, personIds=$personIds, query=$query, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -419,7 +414,6 @@ class SmartSearchDto {
|
||||
} else {
|
||||
// json[r'state'] = null;
|
||||
}
|
||||
json[r'tagIds'] = this.tagIds;
|
||||
if (this.takenAfter != null) {
|
||||
json[r'takenAfter'] = this.takenAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
@@ -501,9 +495,6 @@ class SmartSearchDto {
|
||||
query: mapValueOfType<String>(json, r'query')!,
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
tagIds: json[r'tagIds'] is Iterable
|
||||
? (json[r'tagIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
takenBefore: mapDateTime(json, r'takenBefore', r''),
|
||||
trashedAfter: mapDateTime(json, r'trashedAfter', r''),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user