mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2365c4b79c | |||
| 33713cf1d5 | |||
| 33107fce08 | |||
| 87be5e846f | |||
| 1459dc7c4e | |||
| 9fb2a1a02a | |||
| 80378a42a7 | |||
| 03395d9249 | |||
| 64e2a66136 | |||
| e7d225dcc5 | |||
| 296b696be9 | |||
| ca95fbb47d | |||
| 68a718fab4 | |||
| 6fdb841732 | |||
| 3a10b438ce | |||
| 7386226235 | |||
| 8eb14555dc | |||
| 4c36716d57 | |||
| 5933664862 | |||
| cc56f86333 | |||
| 8cff5883b5 | |||
| 3d320d9751 | |||
| b9e0e65bdb | |||
| 88e5e8d6ea | |||
| ee107c98d5 | |||
| affe0ac5ee | |||
| f1d8ab8aae | |||
| c0898b96ca | |||
| 5e9bda7fab | |||
| b60e9c6771 | |||
| b554664791 | |||
| 97c62136b7 | |||
| c1051c7ed2 | |||
| 65bd0a9320 | |||
| bf32864644 | |||
| 7ef7ecec5b | |||
| bc4abd18e4 | |||
| b74cfd4424 | |||
| 7dc84f56c0 | |||
| 92634f923b | |||
| 96b6165bd3 | |||
| 2624f3884f | |||
| f9b7ce9407 | |||
| 013ea37a0d | |||
| b2b4385271 | |||
| 081c75bb21 | |||
| da337578fb | |||
| acf4109171 | |||
| 66601a1fdc | |||
| 02ff077367 | |||
| 94bb6c1a5e | |||
| fe9e5afcf4 | |||
| 5e89efba64 | |||
| 5a457d72c9 | |||
| 45ccdb37fb | |||
| 9263e2f2e1 | |||
| a3ee615c5b | |||
| 39cfad7136 | |||
| 350056dd1a | |||
| f0835d06f8 | |||
| 03b70cf029 | |||
| 4bfb8b36c2 | |||
| dfacde5af8 | |||
| 317afe9e3b | |||
| 1fb5f13237 | |||
| 793a7054fb | |||
| 3a874dd441 | |||
| 3dc7dc93d8 | |||
| 70397dc5a6 | |||
| a16d233a0c | |||
| bb0872afef | |||
| b9ca68f6e4 | |||
| 837305da7e | |||
| e20fb44142 | |||
| c2786978cd | |||
| 312bb91a4f | |||
| c1934b904c | |||
| 47752d158a | |||
| 6267322b9c | |||
| 93c3cd49f3 | |||
| f52825ab08 | |||
| d74dc74f92 | |||
| 539a39ae49 | |||
| f68cd424a7 | |||
| 20c0cc7e73 | |||
| be1b9a5f67 | |||
| d9011c0829 |
+1
-1
@@ -1 +1 @@
|
|||||||
24.14.1
|
24.15.0
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Restore Gradle Cache
|
- name: Restore Gradle Cache
|
||||||
id: cache-gradle-restore
|
id: cache-gradle-restore
|
||||||
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
~/.gradle/caches
|
||||||
@@ -160,7 +160,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Save Gradle Cache
|
- name: Save Gradle Cache
|
||||||
id: cache-gradle-save
|
id: cache-gradle-save
|
||||||
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -210,7 +210,7 @@ jobs:
|
|||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
|
|
||||||
- name: Setup Ruby
|
- name: Setup Ruby
|
||||||
uses: ruby/setup-ruby@e65c17d16e57e481586a6a5a0282698790062f92 # v1.300.0
|
uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0
|
||||||
with:
|
with:
|
||||||
ruby-version: '3.3'
|
ruby-version: '3.3'
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Check for breaking API changes
|
- name: Check for breaking API changes
|
||||||
uses: oasdiff/oasdiff-action/breaking@e6faebce24cf20ac38653d0d2c7f4aa80aaafc79 # v0.0.38
|
uses: oasdiff/oasdiff-action/breaking@f8cb9308b42121e793f835bd14c0b8090420430c # v0.0.39
|
||||||
with:
|
with:
|
||||||
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
|
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
|
||||||
revision: open-api/immich-openapi-specs.json
|
revision: open-api/immich-openapi-specs.json
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
uses: github/codeql-action/autobuild@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -83,6 +83,6 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ jobs:
|
|||||||
run: 'mise run //deployment:tf apply'
|
run: 'mise run //deployment:tf apply'
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
|
||||||
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
run: 'mise run //deployment:tf destroy -- -refresh=false'
|
run: 'mise run //deployment:tf destroy -- -refresh=false'
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
uses: actions-cool/maintain-one-comment@909842216bc8e8658364c572ec52100f4c2cc50a # v3.3.0
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
number: ${{ github.event.number }}
|
number: ${{ github.event.number }}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ jobs:
|
|||||||
github-token: ${{ steps.generate-token.outputs.token }}
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Create draft release
|
||||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
|
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
tag_name: ${{ needs.bump_version.outputs.version }}
|
tag_name: ${{ needs.bump_version.outputs.version }}
|
||||||
|
|||||||
@@ -392,6 +392,8 @@ jobs:
|
|||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
- name: Setup Mise
|
||||||
|
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
|
||||||
- name: Run pnpm install
|
- name: Run pnpm install
|
||||||
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
|
run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile
|
||||||
- name: Run medium tests
|
- name: Run medium tests
|
||||||
|
|||||||
Vendored
+2
-13
@@ -13,10 +13,6 @@
|
|||||||
"editor.wordBasedSuggestions": "off"
|
"editor.wordBasedSuggestions": "off"
|
||||||
},
|
},
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports": "explicit",
|
|
||||||
"source.removeUnusedImports": "explicit"
|
|
||||||
},
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
@@ -29,18 +25,11 @@
|
|||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"[svelte]": {
|
"[svelte]": {
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports": "explicit",
|
|
||||||
"source.removeUnusedImports": "explicit"
|
|
||||||
},
|
|
||||||
"editor.defaultFormatter": "svelte.svelte-vscode",
|
"editor.defaultFormatter": "svelte.svelte-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true,
|
||||||
|
"tailwindCSS.lint.suggestCanonicalClasses": "ignore"
|
||||||
},
|
},
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.organizeImports": "explicit",
|
|
||||||
"source.removeUnusedImports": "explicit"
|
|
||||||
},
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
24.14.1
|
24.15.0
|
||||||
|
|||||||
+1
-1
@@ -68,6 +68,6 @@
|
|||||||
"micromatch": "^4.0.8"
|
"micromatch": "^4.0.8"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "24.14.1"
|
"node": "24.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tools]
|
[tools]
|
||||||
terragrunt = "1.0.0"
|
terragrunt = "1.0.2"
|
||||||
opentofu = "1.11.5"
|
opentofu = "1.11.6"
|
||||||
|
|
||||||
[tasks."tg:fmt"]
|
[tasks."tg:fmt"]
|
||||||
run = "terragrunt hclfmt"
|
run = "terragrunt hclfmt"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ services:
|
|||||||
container_name: immich_prometheus
|
container_name: immich_prometheus
|
||||||
ports:
|
ports:
|
||||||
- 9090:9090
|
- 9090:9090
|
||||||
image: prom/prometheus@sha256:dda13e28bf95a5e5ca5b8ed56852006094c1c8e8871d9c9dbeed30aa6e55271f
|
image: prom/prometheus@sha256:e4254400b85610324913f0dc4acf92603d9984e7519414c5a12811aa6146acc3
|
||||||
volumes:
|
volumes:
|
||||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- prometheus-data:/prometheus
|
- prometheus-data:/prometheus
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
24.14.1
|
24.15.0
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ VectorChord is the successor extension to pgvecto.rs, allowing for higher perfor
|
|||||||
|
|
||||||
### Migrating from pgvecto.rs
|
### Migrating from pgvecto.rs
|
||||||
|
|
||||||
Support for pgvecto.rs will be dropped in a later release, hence we recommend all users currently using pgvecto.rs to migrate to VectorChord at their convenience. There are two primary approaches to do so.
|
Support for pgvecto.rs has been dropped as of 3.0, hence all users currently using pgvecto.rs should migrate to VectorChord. There are two primary approaches to do so.
|
||||||
|
|
||||||
The easiest option is to have both extensions installed during the migration:
|
The easiest option is to have both extensions installed during the migration:
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ For the full list, refer to the [Immich source code](https://github.com/immich-a
|
|||||||
| `JPEG 2000` | `.jp2` | :white_check_mark: | |
|
| `JPEG 2000` | `.jp2` | :white_check_mark: | |
|
||||||
| `JPEG` | `.jpeg` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
| `JPEG` | `.jpeg` `.jpg` `.jpe` `.insp` | :white_check_mark: | |
|
||||||
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
| `JPEG XL` | `.jxl` | :white_check_mark: | |
|
||||||
|
| `MPO` | `.mpo` | :white_check_mark: | Multi-Picture |
|
||||||
| `PNG` | `.png` | :white_check_mark: | |
|
| `PNG` | `.png` | :white_check_mark: | |
|
||||||
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
| `PSD` | `.psd` | :white_check_mark: | Adobe Photoshop |
|
||||||
| `RAW` | `.raw` | :white_check_mark: | |
|
| `RAW` | `.raw` | :white_check_mark: | |
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ You can learn how to set up Tailscale together with Immich with the [tutorial vi
|
|||||||
### Cons
|
### Cons
|
||||||
|
|
||||||
- The Tailscale client usually needs to run as root on your devices and it increases the attack surface slightly compared to a minimal Wireguard server. e.g., an [RCE vulnerability](https://github.com/tailscale/tailscale/security/advisories/GHSA-vqp6-rc3h-83cp) was discovered in the Windows Tailscale client in November 2022.
|
- The Tailscale client usually needs to run as root on your devices and it increases the attack surface slightly compared to a minimal Wireguard server. e.g., an [RCE vulnerability](https://github.com/tailscale/tailscale/security/advisories/GHSA-vqp6-rc3h-83cp) was discovered in the Windows Tailscale client in November 2022.
|
||||||
- Tailscale is a paid service. However, there is a generous [free tier](https://tailscale.com/pricing/) that permits up to 3 users and up to 100 devices.
|
- Tailscale is a paid service. However, there is a generous [free tier](https://tailscale.com/pricing/) suitable for personal use.
|
||||||
- Tailscale needs to be installed and running on both server-side and client-side.
|
- Tailscale needs to be installed and running on both server-side and client-side.
|
||||||
|
|
||||||
## Option 3: Reverse Proxy
|
## Option 3: Reverse Proxy
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ Information on the current workers can be found [here](/administration/jobs-work
|
|||||||
| `DB_PASSWORD` | Database password | `postgres` | server, database<sup>\*1</sup> |
|
| `DB_PASSWORD` | Database password | `postgres` | server, database<sup>\*1</sup> |
|
||||||
| `DB_DATABASE_NAME` | Database name | `immich` | server, database<sup>\*1</sup> |
|
| `DB_DATABASE_NAME` | Database name | `immich` | server, database<sup>\*1</sup> |
|
||||||
| `DB_SSL_MODE` | Database SSL mode | | server |
|
| `DB_SSL_MODE` | Database SSL mode | | server |
|
||||||
| `DB_VECTOR_EXTENSION`<sup>\*2</sup> | Database vector extension (one of [`vectorchord`, `pgvector`, `pgvecto.rs`]) | | server |
|
| `DB_VECTOR_EXTENSION`<sup>\*2</sup> | Database vector extension (one of [`vectorchord`, `pgvector`]) | | server |
|
||||||
| `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server |
|
| `DB_SKIP_MIGRATIONS` | Whether to skip running migrations on startup (one of [`true`, `false`]) | `false` | server |
|
||||||
| `DB_STORAGE_TYPE` | Optimize concurrent IO on SSDs or sequential IO on HDDs ([`SSD`, `HDD`])<sup>\*3</sup> | `SSD` | database |
|
| `DB_STORAGE_TYPE` | Optimize concurrent IO on SSDs or sequential IO on HDDs ([`SSD`, `HDD`])<sup>\*3</sup> | `SSD` | database |
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,3 @@ These storage mediums have different performance characteristics. As a result, t
|
|||||||
#### Can I use the new database image as a general PostgreSQL image outside of Immich?
|
#### Can I use the new database image as a general PostgreSQL image outside of Immich?
|
||||||
|
|
||||||
It’s a standard PostgreSQL container image that additionally contains the VectorChord, pgvector, and (optionally) pgvecto.rs extensions. If you were using the previous pgvecto.rs image for other purposes, you can similarly do so with this image.
|
It’s a standard PostgreSQL container image that additionally contains the VectorChord, pgvector, and (optionally) pgvecto.rs extensions. If you were using the previous pgvecto.rs image for other purposes, you can similarly do so with this image.
|
||||||
|
|
||||||
#### If pgvecto.rs and pgvector still work, why should I switch to VectorChord?
|
|
||||||
|
|
||||||
VectorChord is faster, more stable, uses less RAM, and (with the settings Immich uses) offers higher-quality results than pgvector and pgvecto.rs. This translates to better search and facial recognition experiences. In addition, pgvecto.rs support will be dropped in the future, so changing it sooner will avoid disruption.
|
|
||||||
|
|||||||
+7
-7
@@ -17,10 +17,10 @@
|
|||||||
"write-heading-ids": "docusaurus write-heading-ids"
|
"write-heading-ids": "docusaurus write-heading-ids"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "~3.9.0",
|
"@docusaurus/core": "~3.10.0",
|
||||||
"@docusaurus/preset-classic": "~3.9.0",
|
"@docusaurus/preset-classic": "~3.10.0",
|
||||||
"@docusaurus/theme-common": "~3.9.0",
|
"@docusaurus/theme-common": "~3.10.0",
|
||||||
"@docusaurus/theme-mermaid": "~3.9.0",
|
"@docusaurus/theme-mermaid": "~3.10.0",
|
||||||
"@mdi/js": "^7.3.67",
|
"@mdi/js": "^7.3.67",
|
||||||
"@mdi/react": "^1.6.1",
|
"@mdi/react": "^1.6.1",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
@@ -36,9 +36,9 @@
|
|||||||
"url": "^0.11.0"
|
"url": "^0.11.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "~3.9.0",
|
"@docusaurus/module-type-aliases": "~3.10.0",
|
||||||
"@docusaurus/tsconfig": "^3.10.0",
|
"@docusaurus/tsconfig": "^3.10.0",
|
||||||
"@docusaurus/types": "^3.7.0",
|
"@docusaurus/types": "^3.10.0",
|
||||||
"prettier": "^3.7.4",
|
"prettier": "^3.7.4",
|
||||||
"typescript": "^6.0.0"
|
"typescript": "^6.0.0"
|
||||||
},
|
},
|
||||||
@@ -58,6 +58,6 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "24.14.1"
|
"node": "24.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
24.14.1
|
24.15.0
|
||||||
|
|||||||
+1
-1
@@ -58,6 +58,6 @@
|
|||||||
"vitest": "^4.0.0"
|
"vitest": "^4.0.0"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "24.14.1"
|
"node": "24.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,82 +2,43 @@ import { expect } from 'vitest';
|
|||||||
|
|
||||||
export const errorDto = {
|
export const errorDto = {
|
||||||
unauthorized: {
|
unauthorized: {
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message: 'Authentication required',
|
message: 'Authentication required',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
unauthorizedWithMessage: (message: string) => ({
|
unauthorizedWithMessage: (message: string) => ({
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message,
|
message,
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
forbidden: {
|
forbidden: {
|
||||||
error: 'Forbidden',
|
|
||||||
statusCode: 403,
|
|
||||||
message: expect.any(String),
|
message: expect.any(String),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
missingPermission: (permission: string) => ({
|
missingPermission: (permission: string) => ({
|
||||||
error: 'Forbidden',
|
|
||||||
statusCode: 403,
|
|
||||||
message: `Missing required permission: ${permission}`,
|
message: `Missing required permission: ${permission}`,
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
wrongPassword: {
|
wrongPassword: {
|
||||||
error: 'Bad Request',
|
|
||||||
statusCode: 400,
|
|
||||||
message: 'Wrong password',
|
message: 'Wrong password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidToken: {
|
invalidToken: {
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message: 'Invalid user token',
|
message: 'Invalid user token',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidShareKey: {
|
invalidShareKey: {
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message: 'Invalid share key',
|
message: 'Invalid share key',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
passwordRequired: {
|
passwordRequired: {
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message: 'Password required',
|
message: 'Password required',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
badRequest: (message: any = null) => ({
|
badRequest: (message: any = null) => ({
|
||||||
error: 'Bad Request',
|
|
||||||
statusCode: 400,
|
|
||||||
message: message ?? expect.anything(),
|
message: message ?? expect.anything(),
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
noPermission: {
|
noPermission: {
|
||||||
error: 'Bad Request',
|
|
||||||
statusCode: 400,
|
|
||||||
message: expect.stringContaining('Not found or no'),
|
message: expect.stringContaining('Not found or no'),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
incorrectLogin: {
|
incorrectLogin: {
|
||||||
error: 'Unauthorized',
|
|
||||||
statusCode: 401,
|
|
||||||
message: 'Incorrect email or password',
|
message: 'Incorrect email or password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
alreadyHasAdmin: {
|
alreadyHasAdmin: {
|
||||||
error: 'Bad Request',
|
|
||||||
statusCode: 400,
|
|
||||||
message: 'The server already has an admin',
|
message: 'The server already has an admin',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidEmail: {
|
invalidEmail: {
|
||||||
error: 'Bad Request',
|
|
||||||
statusCode: 400,
|
|
||||||
message: ['email must be an email'],
|
message: ['email must be an email'],
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -154,23 +154,31 @@ describe('/albums', () => {
|
|||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedLink,
|
albumName: user1SharedLink,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedEditorUser,
|
albumName: user1SharedEditorUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedViewerUser,
|
albumName: user1SharedViewerUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user2.userId,
|
|
||||||
albumName: user2SharedUser,
|
albumName: user2SharedUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@@ -184,23 +192,31 @@ describe('/albums', () => {
|
|||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedEditorUser,
|
albumName: user1SharedEditorUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedViewerUser,
|
albumName: user1SharedViewerUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedLink,
|
albumName: user1SharedLink,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1NotShared,
|
albumName: user1NotShared,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: false,
|
shared: false,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@@ -216,23 +232,31 @@ describe('/albums', () => {
|
|||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedEditorUser,
|
albumName: user1SharedEditorUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedViewerUser,
|
albumName: user1SharedViewerUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1SharedLink,
|
albumName: user1SharedLink,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user2.userId,
|
|
||||||
albumName: user2SharedUser,
|
albumName: user2SharedUser,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user2.userId }) },
|
||||||
|
]),
|
||||||
shared: true,
|
shared: true,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@@ -248,8 +272,10 @@ describe('/albums', () => {
|
|||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: user1NotShared,
|
albumName: user1NotShared,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) },
|
||||||
|
]),
|
||||||
shared: false,
|
shared: false,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@@ -286,13 +312,17 @@ describe('/albums', () => {
|
|||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user4.userId,
|
|
||||||
albumName: user4DeletedAsset,
|
albumName: user4DeletedAsset,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user4.userId }) },
|
||||||
|
]),
|
||||||
shared: false,
|
shared: false,
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ownerId: user4.userId,
|
|
||||||
albumName: user4Empty,
|
albumName: user4Empty,
|
||||||
|
albumUsers: expect.arrayContaining([
|
||||||
|
{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user4.userId }) },
|
||||||
|
]),
|
||||||
shared: false,
|
shared: false,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@@ -362,16 +392,17 @@ describe('/albums', () => {
|
|||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(200);
|
||||||
expect(body).toEqual({
|
expect(body).toEqual(
|
||||||
...user2Albums[0],
|
expect.objectContaining({
|
||||||
contributorCounts: [{ userId: user1.userId, assetCount: 1 }],
|
contributorCounts: [{ userId: user1.userId, assetCount: 1 }],
|
||||||
assetCount: 1,
|
assetCount: 1,
|
||||||
lastModifiedAssetTimestamp: expect.any(String),
|
lastModifiedAssetTimestamp: expect.any(String),
|
||||||
endDate: expect.any(String),
|
endDate: expect.any(String),
|
||||||
startDate: expect.any(String),
|
startDate: expect.any(String),
|
||||||
albumUsers: expect.any(Array),
|
albumUsers: expect.any(Array),
|
||||||
shared: true,
|
shared: true,
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -397,15 +428,13 @@ describe('/albums', () => {
|
|||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
createdAt: expect.any(String),
|
createdAt: expect.any(String),
|
||||||
updatedAt: expect.any(String),
|
updatedAt: expect.any(String),
|
||||||
ownerId: user1.userId,
|
|
||||||
albumName: 'New album',
|
albumName: 'New album',
|
||||||
description: '',
|
description: '',
|
||||||
albumThumbnailAssetId: null,
|
albumThumbnailAssetId: null,
|
||||||
shared: false,
|
shared: false,
|
||||||
albumUsers: [],
|
albumUsers: [{ role: AlbumUserRole.Owner, user: expect.objectContaining({ id: user1.userId }) }],
|
||||||
hasSharedLink: false,
|
hasSharedLink: false,
|
||||||
assetCount: 0,
|
assetCount: 0,
|
||||||
owner: expect.objectContaining({ email: user1.userEmail }),
|
|
||||||
isActivityEnabled: true,
|
isActivityEnabled: true,
|
||||||
order: AssetOrder.Desc,
|
order: AssetOrder.Desc,
|
||||||
});
|
});
|
||||||
@@ -621,11 +650,11 @@ describe('/albums', () => {
|
|||||||
expect(status).toBe(200);
|
expect(status).toBe(200);
|
||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
albumUsers: [
|
albumUsers: expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
user: expect.objectContaining({ id: user2.userId }),
|
user: expect.objectContaining({ id: user2.userId }),
|
||||||
}),
|
}),
|
||||||
],
|
]),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -637,7 +666,7 @@ describe('/albums', () => {
|
|||||||
.send({ albumUsers: [{ userId: user1.userId, role: AlbumUserRole.Editor }] });
|
.send({ albumUsers: [{ userId: user1.userId, role: AlbumUserRole.Editor }] });
|
||||||
|
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
expect(body).toEqual(errorDto.badRequest('Cannot be shared with owner'));
|
expect(body).toEqual(errorDto.badRequest('User already added'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to add existing user to shared album', async () => {
|
it('should not be able to add existing user to shared album', async () => {
|
||||||
@@ -663,7 +692,7 @@ describe('/albums', () => {
|
|||||||
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(album.albumUsers[0].role).toEqual(AlbumUserRole.Viewer);
|
expect(album.albumUsers[1].role).toEqual(AlbumUserRole.Viewer);
|
||||||
|
|
||||||
const { status } = await request(app)
|
const { status } = await request(app)
|
||||||
.put(`/albums/${album.id}/user/${user2.userId}`)
|
.put(`/albums/${album.id}/user/${user2.userId}`)
|
||||||
@@ -678,7 +707,10 @@ describe('/albums', () => {
|
|||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
albumUsers: [expect.objectContaining({ role: AlbumUserRole.Editor })],
|
albumUsers: [
|
||||||
|
expect.objectContaining({ role: AlbumUserRole.Owner }),
|
||||||
|
expect.objectContaining({ role: AlbumUserRole.Editor }),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -689,7 +721,7 @@ describe('/albums', () => {
|
|||||||
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Viewer }],
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(album.albumUsers[0].role).toEqual(AlbumUserRole.Viewer);
|
expect(album.albumUsers[1].role).toEqual(AlbumUserRole.Viewer);
|
||||||
|
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.put(`/albums/${album.id}/user/${user2.userId}`)
|
.put(`/albums/${album.id}/user/${user2.userId}`)
|
||||||
|
|||||||
@@ -332,9 +332,7 @@ describe(`/oauth`, () => {
|
|||||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||||
expect(status).toBe(500);
|
expect(status).toBe(500);
|
||||||
expect(body).toMatchObject({
|
expect(body).toMatchObject({
|
||||||
error: 'Internal Server Error',
|
|
||||||
message: 'Failed to finish oauth',
|
message: 'Failed to finish oauth',
|
||||||
statusCode: 500,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -353,7 +351,7 @@ describe(`/oauth`, () => {
|
|||||||
const callbackParams = await loginWithOAuth('oauth-no-auto-register');
|
const callbackParams = await loginWithOAuth('oauth-no-auto-register');
|
||||||
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
const { status, body } = await request(app).post('/oauth/callback').send(callbackParams);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
expect(body).toEqual(errorDto.badRequest('User does not exist and auto registering is disabled.'));
|
expect(body).toEqual(errorDto.badRequest('OAuth authentication failed'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should link to an existing user by email', async () => {
|
it('should link to an existing user by email', async () => {
|
||||||
@@ -495,11 +493,10 @@ describe(`/oauth`, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should reject OAuth discovery over HTTP', async () => {
|
it('should reject OAuth discovery over HTTP', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status } = await request(app)
|
||||||
.post('/oauth/authorize')
|
.post('/oauth/authorize')
|
||||||
.send({ redirectUri: 'http://127.0.0.1:2285/auth/login' });
|
.send({ redirectUri: 'http://127.0.0.1:2285/auth/login' });
|
||||||
expect(status).toBe(500);
|
expect(status).toBe(500);
|
||||||
expect(body).toMatchObject({ statusCode: 500 });
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ describe('/users', () => {
|
|||||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||||
|
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
expect(body).toMatchObject(errorDto.badRequest('Email already in use by another account'));
|
expect(body).toMatchObject(errorDto.badRequest('Email is not available'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update my email', async () => {
|
it('should update my email', async () => {
|
||||||
|
|||||||
@@ -32,8 +32,12 @@ export function generateThumbhash(rng: SeededRandom): string {
|
|||||||
return Array.from({ length: 10 }, () => rng.nextInt(0, 256).toString(16).padStart(2, '0')).join('');
|
return Array.from({ length: 10 }, () => rng.nextInt(0, 256).toString(16).padStart(2, '0')).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateDuration(rng: SeededRandom): string {
|
export function generateDuration(rng: SeededRandom): number {
|
||||||
return `${rng.nextInt(GENERATION_CONSTANTS.MIN_VIDEO_DURATION_SECONDS, GENERATION_CONSTANTS.MAX_VIDEO_DURATION_SECONDS)}.${rng.nextInt(0, 1000).toString().padStart(3, '0')}`;
|
return (
|
||||||
|
rng.nextInt(GENERATION_CONSTANTS.MIN_VIDEO_DURATION_SECONDS, GENERATION_CONSTANTS.MAX_VIDEO_DURATION_SECONDS) *
|
||||||
|
1000 +
|
||||||
|
rng.nextInt(0, 1000)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateUUID(): string {
|
export function generateUUID(): string {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
AlbumUserRole,
|
||||||
AssetTypeEnum,
|
AssetTypeEnum,
|
||||||
AssetVisibility,
|
AssetVisibility,
|
||||||
UserAvatarColor,
|
UserAvatarColor,
|
||||||
@@ -420,9 +421,7 @@ export function getAlbum(
|
|||||||
albumThumbnailAssetId: album.thumbnailAssetId,
|
albumThumbnailAssetId: album.thumbnailAssetId,
|
||||||
createdAt: album.createdAt,
|
createdAt: album.createdAt,
|
||||||
updatedAt: album.updatedAt,
|
updatedAt: album.updatedAt,
|
||||||
ownerId: albumOwner.id,
|
albumUsers: [{ user: albumOwner, role: AlbumUserRole.Owner }],
|
||||||
owner: albumOwner,
|
|
||||||
albumUsers: [], // Empty array for non-shared album
|
|
||||||
shared: false,
|
shared: false,
|
||||||
hasSharedLink: false,
|
hasSharedLink: false,
|
||||||
isActivityEnabled: true,
|
isActivityEnabled: true,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export type MockTimelineAsset = {
|
|||||||
isTrashed: boolean;
|
isTrashed: boolean;
|
||||||
isVideo: boolean;
|
isVideo: boolean;
|
||||||
isImage: boolean;
|
isImage: boolean;
|
||||||
duration: string | null;
|
duration: number | null;
|
||||||
projectionType: string | null;
|
projectionType: string | null;
|
||||||
livePhotoVideoId: string | null;
|
livePhotoVideoId: string | null;
|
||||||
city: string | null;
|
city: string | null;
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI
|
|||||||
'.jp2',
|
'.jp2',
|
||||||
'.jpe',
|
'.jpe',
|
||||||
'.jxl',
|
'.jxl',
|
||||||
|
'.mpo',
|
||||||
'.svg',
|
'.svg',
|
||||||
'.tif',
|
'.tif',
|
||||||
'.tiff',
|
'.tiff',
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ test.describe('Timeline', () => {
|
|||||||
await page.keyboard.down('Shift');
|
await page.keyboard.down('Shift');
|
||||||
await thumbnailUtils.withAssetId(page, assets[2].id).hover();
|
await thumbnailUtils.withAssetId(page, assets[2].id).hover();
|
||||||
await expect(
|
await expect(
|
||||||
thumbnailUtils.locator(page).locator('.absolute.top-0.h-full.w-full.bg-immich-primary.opacity-40'),
|
thumbnailUtils.locator(page).locator('.absolute.top-0.size-full.bg-immich-primary.opacity-40'),
|
||||||
).toHaveCount(3);
|
).toHaveCount(3);
|
||||||
await thumbnailUtils.selectButton(page, assets[2].id).click();
|
await thumbnailUtils.selectButton(page, assets[2].id).click();
|
||||||
await page.keyboard.up('Shift');
|
await page.keyboard.up('Shift');
|
||||||
@@ -349,7 +349,7 @@ test.describe('Timeline', () => {
|
|||||||
expect(visibleMockAssetsYearMonths).toContain(month);
|
expect(visibleMockAssetsYearMonths).toContain(month);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
test('Deep link to last photo, scroll up', async ({ page }) => {
|
test.skip('Deep link to last photo, scroll up', async ({ page }) => {
|
||||||
const lastAsset = assets.at(-1)!;
|
const lastAsset = assets.at(-1)!;
|
||||||
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
|
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
|
||||||
|
|
||||||
@@ -361,7 +361,7 @@ test.describe('Timeline', () => {
|
|||||||
|
|
||||||
await thumbnailUtils.expectInViewport(page, '14e5901f-fd7f-40c0-b186-4d7e7fc67968');
|
await thumbnailUtils.expectInViewport(page, '14e5901f-fd7f-40c0-b186-4d7e7fc67968');
|
||||||
});
|
});
|
||||||
test('Deep link to first bucket, scroll down', async ({ page }) => {
|
test.skip('Deep link to first bucket, scroll down', async ({ page }) => {
|
||||||
const lastAsset = assets.at(0)!;
|
const lastAsset = assets.at(0)!;
|
||||||
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
|
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
|
||||||
await timelineUtils.locator(page).hover();
|
await timelineUtils.locator(page).hover();
|
||||||
@@ -440,7 +440,7 @@ test.describe('Timeline', () => {
|
|||||||
await thumbnailUtils.expectInViewport(page, asset.id);
|
await thumbnailUtils.expectInViewport(page, asset.id);
|
||||||
await thumbnailUtils.expectSelectedDisabled(page, asset.id);
|
await thumbnailUtils.expectSelectedDisabled(page, asset.id);
|
||||||
});
|
});
|
||||||
test('Add photos to album', async ({ page }) => {
|
test.skip('Add photos to album', async ({ page }) => {
|
||||||
const album = timelineRestData.album;
|
const album = timelineRestData.album;
|
||||||
await pageUtils.openAlbumPage(page, album.id);
|
await pageUtils.openAlbumPage(page, album.id);
|
||||||
await page.locator('nav button[aria-label="Add photos"]').click();
|
await page.locator('nav button[aria-label="Add photos"]').click();
|
||||||
@@ -752,7 +752,7 @@ test.describe('Timeline', () => {
|
|||||||
await page.getByText('Photos', { exact: true }).click();
|
await page.getByText('Photos', { exact: true }).click();
|
||||||
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
|
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
|
||||||
});
|
});
|
||||||
test('open /favorites, archive photo, unarchive photo', async ({ page }) => {
|
test.skip('open /favorites, archive photo, unarchive photo', async ({ page }) => {
|
||||||
await pageUtils.openFavorites(page);
|
await pageUtils.openFavorites(page);
|
||||||
const assetToArchive = getAsset(timelineRestData, 'ad31e29f-2069-4574-b9a9-ad86523c92cb')!;
|
const assetToArchive = getAsset(timelineRestData, 'ad31e29f-2069-4574-b9a9-ad86523c92cb')!;
|
||||||
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
|
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
|
||||||
|
|||||||
+1
-1
Submodule e2e/test-assets updated: 0eac5a3738...6742055402
@@ -1761,6 +1761,7 @@
|
|||||||
"play_original_video": "Play original video",
|
"play_original_video": "Play original video",
|
||||||
"play_original_video_setting_description": "Prefer playback of original videos rather than transcoded videos. If original asset is not compatible it may not playback correctly.",
|
"play_original_video_setting_description": "Prefer playback of original videos rather than transcoded videos. If original asset is not compatible it may not playback correctly.",
|
||||||
"play_transcoded_video": "Play transcoded video",
|
"play_transcoded_video": "Play transcoded video",
|
||||||
|
"playback_speed": "Playback speed",
|
||||||
"please_auth_to_access": "Please authenticate to access",
|
"please_auth_to_access": "Please authenticate to access",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||||
@@ -2436,6 +2437,7 @@
|
|||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"workflows_help_text": "Workflows automate actions on your assets based on triggers and filters",
|
"workflows_help_text": "Workflows automate actions on your assets based on triggers and filters",
|
||||||
"wrong_pin_code": "Wrong PIN code",
|
"wrong_pin_code": "Wrong PIN code",
|
||||||
|
"x_of_total": "{x}/{total}",
|
||||||
"year": "Year",
|
"year": "Year",
|
||||||
"years_ago": "{years, plural, one {# year} other {# years}} ago",
|
"years_ago": "{years, plural, one {# year} other {# years}} ago",
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
|
|||||||
@@ -48,14 +48,14 @@ FROM python:3.13-slim-trixie@sha256:d168b8d9eb761f4d3fe305ebd04aeb7e7f2de0297cec
|
|||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install --no-install-recommends -yqq ocl-icd-libopencl1 wget && \
|
apt-get install --no-install-recommends -yqq ocl-icd-libopencl1 wget && \
|
||||||
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/v2.28.4/intel-igc-core-2_2.28.4+20760_amd64.deb && \
|
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/v2.32.7/intel-igc-core-2_2.32.7+21184_amd64.deb && \
|
||||||
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/v2.28.4/intel-igc-opencl-2_2.28.4+20760_amd64.deb && \
|
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/v2.32.7/intel-igc-opencl-2_2.32.7+21184_amd64.deb && \
|
||||||
wget -nv https://github.com/intel/compute-runtime/releases/download/26.05.37020.3/intel-opencl-icd_26.05.37020.3-0_amd64.deb && \
|
wget -nv https://github.com/intel/compute-runtime/releases/download/26.14.37833.4/intel-opencl-icd_26.14.37833.4-0_amd64.deb && \
|
||||||
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-core_1.0.17537.24_amd64.deb && \
|
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-core_1.0.17537.24_amd64.deb && \
|
||||||
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-opencl_1.0.17537.24_amd64.deb && \
|
wget -nv https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-opencl_1.0.17537.24_amd64.deb && \
|
||||||
wget -nv https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-opencl-icd-legacy1_24.35.30872.36_amd64.deb && \
|
wget -nv https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-opencl-icd-legacy1_24.35.30872.36_amd64.deb && \
|
||||||
# TODO: Figure out how to get renovate to manage this differently versioned libigdgmm file
|
# TODO: Figure out how to get renovate to manage this differently versioned libigdgmm file
|
||||||
wget -nv https://github.com/intel/compute-runtime/releases/download/26.05.37020.3/libigdgmm12_22.9.0_amd64.deb && \
|
wget -nv https://github.com/intel/compute-runtime/releases/download/26.14.37833.4/libigdgmm12_22.9.0_amd64.deb && \
|
||||||
dpkg -i *.deb && \
|
dpkg -i *.deb && \
|
||||||
rm *.deb && \
|
rm *.deb && \
|
||||||
apt-get remove wget -yqq && \
|
apt-get remove wget -yqq && \
|
||||||
@@ -68,7 +68,7 @@ ENV LD_PRELOAD=/usr/lib/libmimalloc.so.2 \
|
|||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
# Pascal support was dropped in 9.11
|
# Pascal support was dropped in 9.11
|
||||||
apt-get install --no-install-recommends -yqq libcudnn9-cuda-12=9.10.2.21-1 && \
|
apt-get install --no-install-recommends -yqq libcudnn9-cuda-12=9.10.2.21-1 tzdata && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,10 @@ async def predict(
|
|||||||
text: str | None = Form(default=None),
|
text: str | None = Form(default=None),
|
||||||
) -> Any:
|
) -> Any:
|
||||||
if image is not None:
|
if image is not None:
|
||||||
inputs: Image | str = await run(lambda: decode_pil(image))
|
decoded = await run(lambda: decode_pil(image))
|
||||||
|
if decoded.width == 0 or decoded.height == 0:
|
||||||
|
raise HTTPException(400, "Image has zero width or height")
|
||||||
|
inputs: Image | str = decoded
|
||||||
elif text is not None:
|
elif text is not None:
|
||||||
inputs = text
|
inputs = text
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ dependencies = [
|
|||||||
"aiocache>=0.12.1,<1.0",
|
"aiocache>=0.12.1,<1.0",
|
||||||
"fastapi>=0.95.2,<1.0",
|
"fastapi>=0.95.2,<1.0",
|
||||||
"gunicorn>=21.1.0",
|
"gunicorn>=21.1.0",
|
||||||
"huggingface-hub>=0.20.1,<1.0",
|
"huggingface-hub>=1.0,<2.0",
|
||||||
"insightface>=0.7.3,<1.0",
|
"insightface>=0.7.3,<1.0",
|
||||||
"numpy<2.4.0",
|
"numpy<2.4.0",
|
||||||
"opencv-python-headless>=4.7.0.72,<5.0",
|
"opencv-python-headless>=4.7.0.72,<5.0",
|
||||||
"orjson>=3.9.5",
|
"orjson>=3.9.5",
|
||||||
"pillow>=12.2,<12.3",
|
"pillow>=12.2,<13",
|
||||||
"pydantic>=2.0.0,<3",
|
"pydantic>=2.0.0,<3",
|
||||||
"pydantic-settings>=2.5.2,<3",
|
"pydantic-settings>=2.5.2,<3",
|
||||||
"python-multipart>=0.0.6,<1.0",
|
"python-multipart>=0.0.6,<1.0",
|
||||||
|
|||||||
@@ -1198,6 +1198,19 @@ class TestLoad:
|
|||||||
mock_model.model_format = ModelFormat.ONNX
|
mock_model.model_format = ModelFormat.ONNX
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("size", [(0, 100), (100, 0), (0, 0)])
|
||||||
|
def test_predict_rejects_empty_image(size: tuple[int, int], deployed_app: TestClient) -> None:
|
||||||
|
with mock.patch("immich_ml.main.decode_pil", return_value=Image.new("RGB", size)):
|
||||||
|
response = deployed_app.post(
|
||||||
|
"http://localhost:3003/predict",
|
||||||
|
data={"entries": json.dumps({"clip": {"visual": {"modelName": "ViT-B-32__openai"}}})},
|
||||||
|
files={"image": b"fake image bytes"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert "zero" in response.json()["detail"].lower()
|
||||||
|
|
||||||
|
|
||||||
def test_root_endpoint(deployed_app: TestClient) -> None:
|
def test_root_endpoint(deployed_app: TestClient) -> None:
|
||||||
response = deployed_app.get("http://localhost:3003")
|
response = deployed_app.get("http://localhost:3003")
|
||||||
|
|
||||||
|
|||||||
@@ -14,18 +14,27 @@ config_roots = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[tools]
|
[tools]
|
||||||
node = "24.14.1"
|
node = "24.15.0"
|
||||||
flutter = "3.41.6"
|
flutter = "3.41.7"
|
||||||
pnpm = "10.33.0"
|
pnpm = "10.33.1"
|
||||||
terragrunt = "1.0.0"
|
terragrunt = "1.0.2"
|
||||||
opentofu = "1.11.5"
|
opentofu = "1.11.6"
|
||||||
java = "21.0.2"
|
java = "21.0.2"
|
||||||
|
|
||||||
[tools."github:CQLabs/homebrew-dcm"]
|
[tools."github:CQLabs/homebrew-dcm"]
|
||||||
version = "1.35.1"
|
version = "1.37.0"
|
||||||
bin = "dcm"
|
bin = "dcm"
|
||||||
postinstall = "chmod +x $MISE_TOOL_INSTALL_PATH/dcm"
|
postinstall = "chmod +x $MISE_TOOL_INSTALL_PATH/dcm"
|
||||||
|
|
||||||
|
[tools."github:jellyfin/jellyfin-ffmpeg"]
|
||||||
|
version = "7.1.3-6"
|
||||||
|
|
||||||
|
[tools."github:jellyfin/jellyfin-ffmpeg".platforms]
|
||||||
|
linux-x64 = { asset_pattern = "jellyfin-ffmpeg_*_portable_linux64-gpl.tar.xz" }
|
||||||
|
linux-arm64 = { asset_pattern = "jellyfin-ffmpeg_*_portable_linuxarm64-gpl.tar.xz" }
|
||||||
|
macos-x64 = { asset_pattern = "jellyfin-ffmpeg_*_portable_mac64-gpl.tar.xz" }
|
||||||
|
macos-arm64 = { asset_pattern = "jellyfin-ffmpeg_*_portable_macarm64-gpl.tar.xz" }
|
||||||
|
|
||||||
[settings]
|
[settings]
|
||||||
experimental = true
|
experimental = true
|
||||||
pin = true
|
pin = true
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"dart.flutterSdkPath": ".fvm/versions/3.41.7",
|
"dart.flutterSdkPath": ".fvm/versions/3.41.9",
|
||||||
"dart.lineLength": 120,
|
"dart.lineLength": 120,
|
||||||
"[dart]": {
|
"[dart]": {
|
||||||
"editor.rulers": [
|
"editor.rulers": [
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ data class PlatformAsset (
|
|||||||
val updatedAt: Long? = null,
|
val updatedAt: Long? = null,
|
||||||
val width: Long? = null,
|
val width: Long? = null,
|
||||||
val height: Long? = null,
|
val height: Long? = null,
|
||||||
val durationInSeconds: Long,
|
val durationMs: Long,
|
||||||
val orientation: Long,
|
val orientation: Long,
|
||||||
val isFavorite: Boolean,
|
val isFavorite: Boolean,
|
||||||
val adjustmentTime: Long? = null,
|
val adjustmentTime: Long? = null,
|
||||||
@@ -234,14 +234,14 @@ data class PlatformAsset (
|
|||||||
val updatedAt = pigeonVar_list[4] as Long?
|
val updatedAt = pigeonVar_list[4] as Long?
|
||||||
val width = pigeonVar_list[5] as Long?
|
val width = pigeonVar_list[5] as Long?
|
||||||
val height = pigeonVar_list[6] as Long?
|
val height = pigeonVar_list[6] as Long?
|
||||||
val durationInSeconds = pigeonVar_list[7] as Long
|
val durationMs = pigeonVar_list[7] as Long
|
||||||
val orientation = pigeonVar_list[8] as Long
|
val orientation = pigeonVar_list[8] as Long
|
||||||
val isFavorite = pigeonVar_list[9] as Boolean
|
val isFavorite = pigeonVar_list[9] as Boolean
|
||||||
val adjustmentTime = pigeonVar_list[10] as Long?
|
val adjustmentTime = pigeonVar_list[10] as Long?
|
||||||
val latitude = pigeonVar_list[11] as Double?
|
val latitude = pigeonVar_list[11] as Double?
|
||||||
val longitude = pigeonVar_list[12] as Double?
|
val longitude = pigeonVar_list[12] as Double?
|
||||||
val playbackStyle = pigeonVar_list[13] as PlatformAssetPlaybackStyle
|
val playbackStyle = pigeonVar_list[13] as PlatformAssetPlaybackStyle
|
||||||
return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite, adjustmentTime, latitude, longitude, playbackStyle)
|
return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationMs, orientation, isFavorite, adjustmentTime, latitude, longitude, playbackStyle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun toList(): List<Any?> {
|
fun toList(): List<Any?> {
|
||||||
@@ -253,7 +253,7 @@ data class PlatformAsset (
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
orientation,
|
orientation,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
adjustmentTime,
|
adjustmentTime,
|
||||||
@@ -270,7 +270,7 @@ data class PlatformAsset (
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val other = other as PlatformAsset
|
val other = other as PlatformAsset
|
||||||
return MessagesPigeonUtils.deepEquals(this.id, other.id) && MessagesPigeonUtils.deepEquals(this.name, other.name) && MessagesPigeonUtils.deepEquals(this.type, other.type) && MessagesPigeonUtils.deepEquals(this.createdAt, other.createdAt) && MessagesPigeonUtils.deepEquals(this.updatedAt, other.updatedAt) && MessagesPigeonUtils.deepEquals(this.width, other.width) && MessagesPigeonUtils.deepEquals(this.height, other.height) && MessagesPigeonUtils.deepEquals(this.durationInSeconds, other.durationInSeconds) && MessagesPigeonUtils.deepEquals(this.orientation, other.orientation) && MessagesPigeonUtils.deepEquals(this.isFavorite, other.isFavorite) && MessagesPigeonUtils.deepEquals(this.adjustmentTime, other.adjustmentTime) && MessagesPigeonUtils.deepEquals(this.latitude, other.latitude) && MessagesPigeonUtils.deepEquals(this.longitude, other.longitude) && MessagesPigeonUtils.deepEquals(this.playbackStyle, other.playbackStyle)
|
return MessagesPigeonUtils.deepEquals(this.id, other.id) && MessagesPigeonUtils.deepEquals(this.name, other.name) && MessagesPigeonUtils.deepEquals(this.type, other.type) && MessagesPigeonUtils.deepEquals(this.createdAt, other.createdAt) && MessagesPigeonUtils.deepEquals(this.updatedAt, other.updatedAt) && MessagesPigeonUtils.deepEquals(this.width, other.width) && MessagesPigeonUtils.deepEquals(this.height, other.height) && MessagesPigeonUtils.deepEquals(this.durationMs, other.durationMs) && MessagesPigeonUtils.deepEquals(this.orientation, other.orientation) && MessagesPigeonUtils.deepEquals(this.isFavorite, other.isFavorite) && MessagesPigeonUtils.deepEquals(this.adjustmentTime, other.adjustmentTime) && MessagesPigeonUtils.deepEquals(this.latitude, other.latitude) && MessagesPigeonUtils.deepEquals(this.longitude, other.longitude) && MessagesPigeonUtils.deepEquals(this.playbackStyle, other.playbackStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
@@ -282,7 +282,7 @@ data class PlatformAsset (
|
|||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.updatedAt)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.updatedAt)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.width)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.width)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.height)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.height)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.durationInSeconds)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.durationMs)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.orientation)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.orientation)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.isFavorite)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.isFavorite)
|
||||||
result = 31 * result + MessagesPigeonUtils.deepHash(this.adjustmentTime)
|
result = 31 * result + MessagesPigeonUtils.deepHash(this.adjustmentTime)
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ open class NativeSyncApiImplBase(context: Context) : ImmichPlugin() {
|
|||||||
val height = c.getInt(heightColumn).toLong()
|
val height = c.getInt(heightColumn).toLong()
|
||||||
// Duration is milliseconds
|
// Duration is milliseconds
|
||||||
val duration = if (rawMediaType == MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE) 0L
|
val duration = if (rawMediaType == MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE) 0L
|
||||||
else c.getLong(durationColumn) / 1000
|
else c.getLong(durationColumn)
|
||||||
val orientation = c.getInt(orientationColumn)
|
val orientation = c.getInt(orientationColumn)
|
||||||
val isFavorite = if (favoriteColumn == -1) false else c.getInt(favoriteColumn) != 0
|
val isFavorite = if (favoriteColumn == -1) false else c.getInt(favoriteColumn) != 0
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
version: '>=1.29.0 <=1.36.0'
|
version: '>=1.29.0 <=1.37.0'
|
||||||
|
|||||||
+3351
File diff suppressed because it is too large
Load Diff
+3301
File diff suppressed because it is too large
Load Diff
+3358
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 77;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
@@ -751,7 +751,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
@@ -760,7 +760,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.121.0;
|
MARKETING_VERSION = 1.121.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.profile;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.profile;
|
||||||
PRODUCT_NAME = "Immich-Profile";
|
PRODUCT_NAME = "Immich-Profile";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -895,7 +895,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
@@ -904,7 +904,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.121.0;
|
MARKETING_VERSION = 1.121.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.vdebug;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.debug;
|
||||||
PRODUCT_NAME = "Immich-Debug";
|
PRODUCT_NAME = "Immich-Debug";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -925,7 +925,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
@@ -958,7 +958,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -975,7 +975,7 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.vdebug.Widget;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.debug.Widget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
@@ -1001,7 +1001,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1041,7 +1041,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1057,7 +1057,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.profile.Widget;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.profile.Widget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -1081,7 +1081,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1098,7 +1098,7 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.vdebug.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.debug.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -1125,7 +1125,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1166,7 +1166,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -1182,7 +1182,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.alextran.immich.profile.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = app.futo.immich.profile.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|||||||
Generated
+6
-6
@@ -192,7 +192,7 @@ struct PlatformAsset: Hashable {
|
|||||||
var updatedAt: Int64? = nil
|
var updatedAt: Int64? = nil
|
||||||
var width: Int64? = nil
|
var width: Int64? = nil
|
||||||
var height: Int64? = nil
|
var height: Int64? = nil
|
||||||
var durationInSeconds: Int64
|
var durationMs: Int64
|
||||||
var orientation: Int64
|
var orientation: Int64
|
||||||
var isFavorite: Bool
|
var isFavorite: Bool
|
||||||
var adjustmentTime: Int64? = nil
|
var adjustmentTime: Int64? = nil
|
||||||
@@ -210,7 +210,7 @@ struct PlatformAsset: Hashable {
|
|||||||
let updatedAt: Int64? = nilOrValue(pigeonVar_list[4])
|
let updatedAt: Int64? = nilOrValue(pigeonVar_list[4])
|
||||||
let width: Int64? = nilOrValue(pigeonVar_list[5])
|
let width: Int64? = nilOrValue(pigeonVar_list[5])
|
||||||
let height: Int64? = nilOrValue(pigeonVar_list[6])
|
let height: Int64? = nilOrValue(pigeonVar_list[6])
|
||||||
let durationInSeconds = pigeonVar_list[7] as! Int64
|
let durationMs = pigeonVar_list[7] as! Int64
|
||||||
let orientation = pigeonVar_list[8] as! Int64
|
let orientation = pigeonVar_list[8] as! Int64
|
||||||
let isFavorite = pigeonVar_list[9] as! Bool
|
let isFavorite = pigeonVar_list[9] as! Bool
|
||||||
let adjustmentTime: Int64? = nilOrValue(pigeonVar_list[10])
|
let adjustmentTime: Int64? = nilOrValue(pigeonVar_list[10])
|
||||||
@@ -226,7 +226,7 @@ struct PlatformAsset: Hashable {
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
adjustmentTime: adjustmentTime,
|
adjustmentTime: adjustmentTime,
|
||||||
@@ -244,7 +244,7 @@ struct PlatformAsset: Hashable {
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
orientation,
|
orientation,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
adjustmentTime,
|
adjustmentTime,
|
||||||
@@ -257,7 +257,7 @@ struct PlatformAsset: Hashable {
|
|||||||
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return deepEqualsMessages(lhs.id, rhs.id) && deepEqualsMessages(lhs.name, rhs.name) && deepEqualsMessages(lhs.type, rhs.type) && deepEqualsMessages(lhs.createdAt, rhs.createdAt) && deepEqualsMessages(lhs.updatedAt, rhs.updatedAt) && deepEqualsMessages(lhs.width, rhs.width) && deepEqualsMessages(lhs.height, rhs.height) && deepEqualsMessages(lhs.durationInSeconds, rhs.durationInSeconds) && deepEqualsMessages(lhs.orientation, rhs.orientation) && deepEqualsMessages(lhs.isFavorite, rhs.isFavorite) && deepEqualsMessages(lhs.adjustmentTime, rhs.adjustmentTime) && deepEqualsMessages(lhs.latitude, rhs.latitude) && deepEqualsMessages(lhs.longitude, rhs.longitude) && deepEqualsMessages(lhs.playbackStyle, rhs.playbackStyle)
|
return deepEqualsMessages(lhs.id, rhs.id) && deepEqualsMessages(lhs.name, rhs.name) && deepEqualsMessages(lhs.type, rhs.type) && deepEqualsMessages(lhs.createdAt, rhs.createdAt) && deepEqualsMessages(lhs.updatedAt, rhs.updatedAt) && deepEqualsMessages(lhs.width, rhs.width) && deepEqualsMessages(lhs.height, rhs.height) && deepEqualsMessages(lhs.durationMs, rhs.durationMs) && deepEqualsMessages(lhs.orientation, rhs.orientation) && deepEqualsMessages(lhs.isFavorite, rhs.isFavorite) && deepEqualsMessages(lhs.adjustmentTime, rhs.adjustmentTime) && deepEqualsMessages(lhs.latitude, rhs.latitude) && deepEqualsMessages(lhs.longitude, rhs.longitude) && deepEqualsMessages(lhs.playbackStyle, rhs.playbackStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
@@ -269,7 +269,7 @@ struct PlatformAsset: Hashable {
|
|||||||
deepHashMessages(value: updatedAt, hasher: &hasher)
|
deepHashMessages(value: updatedAt, hasher: &hasher)
|
||||||
deepHashMessages(value: width, hasher: &hasher)
|
deepHashMessages(value: width, hasher: &hasher)
|
||||||
deepHashMessages(value: height, hasher: &hasher)
|
deepHashMessages(value: height, hasher: &hasher)
|
||||||
deepHashMessages(value: durationInSeconds, hasher: &hasher)
|
deepHashMessages(value: durationMs, hasher: &hasher)
|
||||||
deepHashMessages(value: orientation, hasher: &hasher)
|
deepHashMessages(value: orientation, hasher: &hasher)
|
||||||
deepHashMessages(value: isFavorite, hasher: &hasher)
|
deepHashMessages(value: isFavorite, hasher: &hasher)
|
||||||
deepHashMessages(value: adjustmentTime, hasher: &hasher)
|
deepHashMessages(value: adjustmentTime, hasher: &hasher)
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ class NativeSyncApiImpl: ImmichPlugin, NativeSyncApi, FlutterPlugin {
|
|||||||
id: asset.localIdentifier,
|
id: asset.localIdentifier,
|
||||||
name: "",
|
name: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
durationInSeconds: 0,
|
durationMs: 0,
|
||||||
orientation: 0,
|
orientation: 0,
|
||||||
isFavorite: false,
|
isFavorite: false,
|
||||||
playbackStyle: .unknown
|
playbackStyle: .unknown
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ extension PHAsset {
|
|||||||
updatedAt: modificationDate.map { Int64($0.timeIntervalSince1970) },
|
updatedAt: modificationDate.map { Int64($0.timeIntervalSince1970) },
|
||||||
width: Int64(pixelWidth),
|
width: Int64(pixelWidth),
|
||||||
height: Int64(pixelHeight),
|
height: Int64(pixelHeight),
|
||||||
durationInSeconds: Int64(duration),
|
durationMs: Int64(duration * 1000),
|
||||||
orientation: 0,
|
orientation: 0,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
adjustmentTime: adjustmentTimestamp,
|
adjustmentTime: adjustmentTimestamp,
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>AppGroupId</key>
|
<key>AppGroupId</key>
|
||||||
<string>$(CUSTOM_GROUP_ID)</string>
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionAttributes</key>
|
<key>NSExtensionAttributes</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>IntentsSupported</key>
|
<key>IntentsSupported</key>
|
||||||
<array>
|
<array>
|
||||||
<string>INSendMessageIntent</string>
|
<string>INSendMessageIntent</string>
|
||||||
</array>
|
</array>
|
||||||
<key>NSExtensionActivationRule</key>
|
<key>NSExtensionActivationRule</key>
|
||||||
<string>SUBQUERY ( extensionItems, $extensionItem, SUBQUERY ( $extensionItem.attachments,
|
<string>SUBQUERY ( extensionItems, $extensionItem, SUBQUERY ( $extensionItem.attachments,
|
||||||
$attachment, ( ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
|
$attachment, ( ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
|
||||||
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" || ANY
|
|| ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" || ANY
|
||||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" || ANY
|
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" || ANY
|
||||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.movie" || ANY
|
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.movie" || ANY
|
||||||
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ) ).@count > 0
|
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ) ).@count > 0
|
||||||
).@count > 0 </string>
|
).@count > 0 </string>
|
||||||
<key>PHSupportedMediaTypes</key>
|
<key>PHSupportedMediaTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>Video</string>
|
<string>Video</string>
|
||||||
<string>Image</string>
|
<string>Image</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
<key>NSExtensionMainStoryboard</key>
|
<key>NSExtensionMainStoryboard</key>
|
||||||
<string>MainInterface</string>
|
<string>MainInterface</string>
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
<string>com.apple.share-services</string>
|
<string>com.apple.share-services</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>group.app.immich.share</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>group.app.immich.share</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
app_identifier "app.alextran.immich" # The bundle identifier of your app
|
app_identifier "app.alextran.immich" # The bundle identifier of your app
|
||||||
apple_id "alex.tran1502@gmail.com" # Your Apple email address
|
apple_id "altran@futo.org" # Your Apple email address
|
||||||
|
|
||||||
|
|
||||||
# For more information about the Appfile, see:
|
# For more information about the Appfile, see:
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ default_platform(:ios)
|
|||||||
|
|
||||||
platform :ios do
|
platform :ios do
|
||||||
# Constants
|
# Constants
|
||||||
TEAM_ID = "2F67MQ8R79"
|
TEAM_ID = "2W7AC6T8T5"
|
||||||
CODE_SIGN_IDENTITY = "Apple Distribution: Hau Tran (#{TEAM_ID})"
|
CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})"
|
||||||
BASE_BUNDLE_ID = "app.alextran.immich"
|
BASE_BUNDLE_ID = "app.alextran.immich"
|
||||||
|
DEV_BUNDLE_ID = "tech.futo.immich.testflight"
|
||||||
|
|
||||||
# Helper method to get App Store Connect API key
|
# Helper method to get App Store Connect API key
|
||||||
def get_api_key
|
def get_api_key
|
||||||
app_store_connect_api_key(
|
app_store_connect_api_key(
|
||||||
@@ -44,47 +45,45 @@ def get_version_from_pubspec
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Helper method to configure code signing for all targets
|
# Helper method to configure code signing for all targets
|
||||||
def configure_code_signing(bundle_id_suffix: "", profile_name_main:, profile_name_share:, profile_name_widget:)
|
def configure_code_signing(base_bundle_id:, profile_name_main:, profile_name_share:, profile_name_widget:)
|
||||||
bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
|
|
||||||
|
|
||||||
# Runner (main app)
|
# Runner (main app)
|
||||||
update_code_signing_settings(
|
update_code_signing_settings(
|
||||||
use_automatic_signing: false,
|
use_automatic_signing: false,
|
||||||
path: "./Runner.xcodeproj",
|
path: "./Runner.xcodeproj",
|
||||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}",
|
bundle_identifier: base_bundle_id,
|
||||||
profile_name: profile_name_main,
|
profile_name: profile_name_main,
|
||||||
targets: ["Runner"]
|
targets: ["Runner"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# ShareExtension
|
# ShareExtension
|
||||||
update_code_signing_settings(
|
update_code_signing_settings(
|
||||||
use_automatic_signing: false,
|
use_automatic_signing: false,
|
||||||
path: "./Runner.xcodeproj",
|
path: "./Runner.xcodeproj",
|
||||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.ShareExtension",
|
bundle_identifier: "#{base_bundle_id}.ShareExtension",
|
||||||
profile_name: profile_name_share,
|
profile_name: profile_name_share,
|
||||||
targets: ["ShareExtension"]
|
targets: ["ShareExtension"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# WidgetExtension
|
# WidgetExtension
|
||||||
update_code_signing_settings(
|
update_code_signing_settings(
|
||||||
use_automatic_signing: false,
|
use_automatic_signing: false,
|
||||||
path: "./Runner.xcodeproj",
|
path: "./Runner.xcodeproj",
|
||||||
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
|
||||||
code_sign_identity: CODE_SIGN_IDENTITY,
|
code_sign_identity: CODE_SIGN_IDENTITY,
|
||||||
bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.Widget",
|
bundle_identifier: "#{base_bundle_id}.Widget",
|
||||||
profile_name: profile_name_widget,
|
profile_name: profile_name_widget,
|
||||||
targets: ["WidgetExtension"]
|
targets: ["WidgetExtension"]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper method to build and upload to TestFlight
|
# Helper method to build and upload to TestFlight
|
||||||
def build_and_upload(
|
def build_and_upload(
|
||||||
api_key:,
|
api_key:,
|
||||||
bundle_id_suffix: "",
|
base_bundle_id:,
|
||||||
configuration: "Release",
|
configuration: "Release",
|
||||||
distribute_external: true,
|
distribute_external: true,
|
||||||
version_number: nil,
|
version_number: nil,
|
||||||
@@ -92,9 +91,8 @@ end
|
|||||||
profile_name_share:,
|
profile_name_share:,
|
||||||
profile_name_widget:
|
profile_name_widget:
|
||||||
)
|
)
|
||||||
bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
|
app_identifier = base_bundle_id
|
||||||
app_identifier = "#{BASE_BUNDLE_ID}#{bundle_suffix}"
|
|
||||||
|
|
||||||
# Set version number if provided
|
# Set version number if provided
|
||||||
if version_number
|
if version_number
|
||||||
increment_version_number(version_number: version_number)
|
increment_version_number(version_number: version_number)
|
||||||
@@ -138,31 +136,31 @@ end
|
|||||||
desc "iOS Development Build to TestFlight (requires separate bundle ID)"
|
desc "iOS Development Build to TestFlight (requires separate bundle ID)"
|
||||||
lane :gha_testflight_dev do
|
lane :gha_testflight_dev do
|
||||||
api_key = get_api_key
|
api_key = get_api_key
|
||||||
|
|
||||||
# Download and install provisioning profiles from App Store Connect
|
# Download and install provisioning profiles from App Store Connect
|
||||||
# Certificate is imported by GHA workflow into build.keychain
|
# Certificate is imported by GHA workflow into build.keychain
|
||||||
# Capture profile names after each sigh call
|
# Capture profile names after each sigh call
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
|
sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
|
||||||
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
|
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
|
||||||
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
|
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
|
||||||
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
# Configure code signing for dev bundle IDs using the downloaded profile names
|
# Configure code signing for dev bundle IDs using the downloaded profile names
|
||||||
configure_code_signing(
|
configure_code_signing(
|
||||||
bundle_id_suffix: "development",
|
base_bundle_id: DEV_BUNDLE_ID,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
profile_name_share: share_profile_name,
|
profile_name_share: share_profile_name,
|
||||||
profile_name_widget: widget_profile_name
|
profile_name_widget: widget_profile_name
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build and upload
|
# Build and upload
|
||||||
build_and_upload(
|
build_and_upload(
|
||||||
api_key: api_key,
|
api_key: api_key,
|
||||||
bundle_id_suffix: "development",
|
base_bundle_id: DEV_BUNDLE_ID,
|
||||||
configuration: "Profile",
|
configuration: "Profile",
|
||||||
distribute_external: false,
|
distribute_external: false,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
@@ -189,6 +187,7 @@ end
|
|||||||
|
|
||||||
# Configure code signing for production bundle IDs
|
# Configure code signing for production bundle IDs
|
||||||
configure_code_signing(
|
configure_code_signing(
|
||||||
|
base_bundle_id: BASE_BUNDLE_ID,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
profile_name_share: share_profile_name,
|
profile_name_share: share_profile_name,
|
||||||
profile_name_widget: widget_profile_name
|
profile_name_widget: widget_profile_name
|
||||||
@@ -197,6 +196,7 @@ end
|
|||||||
# Build and upload with version number
|
# Build and upload with version number
|
||||||
build_and_upload(
|
build_and_upload(
|
||||||
api_key: api_key,
|
api_key: api_key,
|
||||||
|
base_bundle_id: BASE_BUNDLE_ID,
|
||||||
version_number: get_version_from_pubspec,
|
version_number: get_version_from_pubspec,
|
||||||
distribute_external: false,
|
distribute_external: false,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
@@ -243,30 +243,30 @@ end
|
|||||||
|
|
||||||
desc "iOS Build Only (no TestFlight upload)"
|
desc "iOS Build Only (no TestFlight upload)"
|
||||||
lane :gha_build_only do
|
lane :gha_build_only do
|
||||||
# Use the same build process as production, just skip the upload
|
# Use the same build process as the dev TestFlight lane, just skip the upload
|
||||||
# This ensures PR builds validate the same way as production builds
|
# This ensures PR builds validate the same way as dev TestFlight builds
|
||||||
|
|
||||||
api_key = get_api_key
|
api_key = get_api_key
|
||||||
|
|
||||||
# Download and install provisioning profiles from App Store Connect
|
# Download and install provisioning profiles from App Store Connect
|
||||||
# Certificate is imported by GHA workflow into build.keychain
|
# Certificate is imported by GHA workflow into build.keychain
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
|
sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
|
||||||
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
main_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
|
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
|
||||||
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
share_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
|
sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
|
||||||
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
widget_profile_name = lane_context[SharedValues::SIGH_NAME]
|
||||||
|
|
||||||
# Configure code signing for dev bundle IDs
|
# Configure code signing for dev bundle IDs
|
||||||
configure_code_signing(
|
configure_code_signing(
|
||||||
bundle_id_suffix: "development",
|
base_bundle_id: DEV_BUNDLE_ID,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
profile_name_share: share_profile_name,
|
profile_name_share: share_profile_name,
|
||||||
profile_name_widget: widget_profile_name
|
profile_name_widget: widget_profile_name
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build the app (same as gha_testflight_dev but without upload)
|
# Build the app (same as gha_testflight_dev but without upload)
|
||||||
build_app(
|
build_app(
|
||||||
scheme: "Runner",
|
scheme: "Runner",
|
||||||
@@ -277,9 +277,9 @@ end
|
|||||||
xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
|
xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
|
||||||
export_options: {
|
export_options: {
|
||||||
provisioningProfiles: {
|
provisioningProfiles: {
|
||||||
"#{BASE_BUNDLE_ID}.development" => main_profile_name,
|
DEV_BUNDLE_ID => main_profile_name,
|
||||||
"#{BASE_BUNDLE_ID}.development.ShareExtension" => share_profile_name,
|
"#{DEV_BUNDLE_ID}.ShareExtension" => share_profile_name,
|
||||||
"#{BASE_BUNDLE_ID}.development.Widget" => widget_profile_name
|
"#{DEV_BUNDLE_ID}.Widget" => widget_profile_name
|
||||||
},
|
},
|
||||||
signingStyle: "manual",
|
signingStyle: "manual",
|
||||||
signingCertificate: CODE_SIGN_IDENTITY
|
signingCertificate: CODE_SIGN_IDENTITY
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
enum ImmichColorPreset { indigo, deepPurple, pink, red, orange, yellow, lime, green, cyan, slateGray }
|
enum ImmichColorPreset { indigo, deepPurple, pink, red, orange, yellow, lime, green, cyan, slateGray }
|
||||||
|
|
||||||
const ImmichColorPreset defaultColorPreset = ImmichColorPreset.indigo;
|
|
||||||
const String defaultColorPresetName = "indigo";
|
|
||||||
|
|
||||||
const Color immichBrandColorLight = Color(0xFF4150AF);
|
const Color immichBrandColorLight = Color(0xFF4150AF);
|
||||||
const Color immichBrandColorDark = Color(0xFFACCBFA);
|
const Color immichBrandColorDark = Color(0xFFACCBFA);
|
||||||
const Color whiteOpacity75 = Color.fromRGBO(255, 255, 255, 0.75);
|
const Color whiteOpacity75 = Color.fromRGBO(255, 255, 255, 0.75);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ enum AlbumUserRole {
|
|||||||
// do not change this order!
|
// do not change this order!
|
||||||
editor,
|
editor,
|
||||||
viewer,
|
viewer,
|
||||||
|
owner,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model for an album stored in the server
|
// Model for an album stored in the server
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ sealed class BaseAsset {
|
|||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? width;
|
final int? width;
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? durationInSeconds;
|
final int? durationMs;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
final String? livePhotoVideoId;
|
final String? livePhotoVideoId;
|
||||||
final bool isEdited;
|
final bool isEdited;
|
||||||
@@ -38,7 +38,7 @@ sealed class BaseAsset {
|
|||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.durationInSeconds,
|
this.durationMs,
|
||||||
this.isFavorite = false,
|
this.isFavorite = false,
|
||||||
this.livePhotoVideoId,
|
this.livePhotoVideoId,
|
||||||
required this.isEdited,
|
required this.isEdited,
|
||||||
@@ -53,15 +53,17 @@ sealed class BaseAsset {
|
|||||||
AssetPlaybackStyle get playbackStyle {
|
AssetPlaybackStyle get playbackStyle {
|
||||||
if (isVideo) return AssetPlaybackStyle.video;
|
if (isVideo) return AssetPlaybackStyle.video;
|
||||||
if (isMotionPhoto) return AssetPlaybackStyle.livePhoto;
|
if (isMotionPhoto) return AssetPlaybackStyle.livePhoto;
|
||||||
if (isImage && durationInSeconds != null && durationInSeconds! > 0) return AssetPlaybackStyle.imageAnimated;
|
if (isImage && durationMs != null && durationMs! > 0) {
|
||||||
|
return AssetPlaybackStyle.imageAnimated;
|
||||||
|
}
|
||||||
if (isImage) return AssetPlaybackStyle.image;
|
if (isImage) return AssetPlaybackStyle.image;
|
||||||
return AssetPlaybackStyle.unknown;
|
return AssetPlaybackStyle.unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration get duration {
|
Duration get duration {
|
||||||
final durationInSeconds = this.durationInSeconds;
|
final durationMs = this.durationMs;
|
||||||
if (durationInSeconds != null) {
|
if (durationMs != null) {
|
||||||
return Duration(seconds: durationInSeconds);
|
return Duration(milliseconds: durationMs);
|
||||||
}
|
}
|
||||||
return const Duration();
|
return const Duration();
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,7 @@ sealed class BaseAsset {
|
|||||||
updatedAt: $updatedAt,
|
updatedAt: $updatedAt,
|
||||||
width: ${width ?? "<NA>"},
|
width: ${width ?? "<NA>"},
|
||||||
height: ${height ?? "<NA>"},
|
height: ${height ?? "<NA>"},
|
||||||
durationInSeconds: ${durationInSeconds ?? "<NA>"},
|
durationMs: ${durationMs ?? "<NA>"},
|
||||||
isFavorite: $isFavorite,
|
isFavorite: $isFavorite,
|
||||||
isEdited: $isEdited,
|
isEdited: $isEdited,
|
||||||
}''';
|
}''';
|
||||||
@@ -104,7 +106,7 @@ sealed class BaseAsset {
|
|||||||
updatedAt == other.updatedAt &&
|
updatedAt == other.updatedAt &&
|
||||||
width == other.width &&
|
width == other.width &&
|
||||||
height == other.height &&
|
height == other.height &&
|
||||||
durationInSeconds == other.durationInSeconds &&
|
durationMs == other.durationMs &&
|
||||||
isFavorite == other.isFavorite &&
|
isFavorite == other.isFavorite &&
|
||||||
isEdited == other.isEdited;
|
isEdited == other.isEdited;
|
||||||
}
|
}
|
||||||
@@ -119,7 +121,7 @@ sealed class BaseAsset {
|
|||||||
updatedAt.hashCode ^
|
updatedAt.hashCode ^
|
||||||
width.hashCode ^
|
width.hashCode ^
|
||||||
height.hashCode ^
|
height.hashCode ^
|
||||||
durationInSeconds.hashCode ^
|
durationMs.hashCode ^
|
||||||
isFavorite.hashCode ^
|
isFavorite.hashCode ^
|
||||||
isEdited.hashCode;
|
isEdited.hashCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
required super.updatedAt,
|
required super.updatedAt,
|
||||||
super.width,
|
super.width,
|
||||||
super.height,
|
super.height,
|
||||||
super.durationInSeconds,
|
super.durationMs,
|
||||||
super.isFavorite = false,
|
super.isFavorite = false,
|
||||||
super.livePhotoVideoId,
|
super.livePhotoVideoId,
|
||||||
this.orientation = 0,
|
this.orientation = 0,
|
||||||
@@ -58,7 +58,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
updatedAt: $updatedAt,
|
updatedAt: $updatedAt,
|
||||||
width: ${width ?? "<NA>"},
|
width: ${width ?? "<NA>"},
|
||||||
height: ${height ?? "<NA>"},
|
height: ${height ?? "<NA>"},
|
||||||
durationInSeconds: ${durationInSeconds ?? "<NA>"},
|
durationMs: ${durationMs ?? "<NA>"},
|
||||||
playbackStyle: $playbackStyle,
|
playbackStyle: $playbackStyle,
|
||||||
remoteId: ${remoteId ?? "<NA>"},
|
remoteId: ${remoteId ?? "<NA>"},
|
||||||
cloudId: ${cloudId ?? "<NA>"},
|
cloudId: ${cloudId ?? "<NA>"},
|
||||||
@@ -108,7 +108,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
int? width,
|
int? width,
|
||||||
int? height,
|
int? height,
|
||||||
int? durationInSeconds,
|
int? durationMs,
|
||||||
bool? isFavorite,
|
bool? isFavorite,
|
||||||
int? orientation,
|
int? orientation,
|
||||||
AssetPlaybackStyle? playbackStyle,
|
AssetPlaybackStyle? playbackStyle,
|
||||||
@@ -128,7 +128,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
orientation: orientation ?? this.orientation,
|
orientation: orientation ?? this.orientation,
|
||||||
playbackStyle: playbackStyle ?? this.playbackStyle,
|
playbackStyle: playbackStyle ?? this.playbackStyle,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
required super.updatedAt,
|
required super.updatedAt,
|
||||||
super.width,
|
super.width,
|
||||||
super.height,
|
super.height,
|
||||||
super.durationInSeconds,
|
super.durationMs,
|
||||||
super.isFavorite = false,
|
super.isFavorite = false,
|
||||||
this.thumbHash,
|
this.thumbHash,
|
||||||
this.visibility = AssetVisibility.timeline,
|
this.visibility = AssetVisibility.timeline,
|
||||||
@@ -57,7 +57,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
updatedAt: $updatedAt,
|
updatedAt: $updatedAt,
|
||||||
width: ${width ?? "<NA>"},
|
width: ${width ?? "<NA>"},
|
||||||
height: ${height ?? "<NA>"},
|
height: ${height ?? "<NA>"},
|
||||||
durationInSeconds: ${durationInSeconds ?? "<NA>"},
|
durationMs: ${durationMs ?? "<NA>"},
|
||||||
localId: ${localId ?? "<NA>"},
|
localId: ${localId ?? "<NA>"},
|
||||||
isFavorite: $isFavorite,
|
isFavorite: $isFavorite,
|
||||||
thumbHash: ${thumbHash ?? "<NA>"},
|
thumbHash: ${thumbHash ?? "<NA>"},
|
||||||
@@ -102,7 +102,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
int? width,
|
int? width,
|
||||||
int? height,
|
int? height,
|
||||||
int? durationInSeconds,
|
int? durationMs,
|
||||||
bool? isFavorite,
|
bool? isFavorite,
|
||||||
String? thumbHash,
|
String? thumbHash,
|
||||||
AssetVisibility? visibility,
|
AssetVisibility? visibility,
|
||||||
@@ -121,7 +121,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
thumbHash: thumbHash ?? this.thumbHash,
|
thumbHash: thumbHash ?? this.thumbHash,
|
||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
@@ -146,7 +146,7 @@ class RemoteAssetExif extends RemoteAsset {
|
|||||||
required super.updatedAt,
|
required super.updatedAt,
|
||||||
super.width,
|
super.width,
|
||||||
super.height,
|
super.height,
|
||||||
super.durationInSeconds,
|
super.durationMs,
|
||||||
super.isFavorite = false,
|
super.isFavorite = false,
|
||||||
super.thumbHash,
|
super.thumbHash,
|
||||||
super.visibility = AssetVisibility.timeline,
|
super.visibility = AssetVisibility.timeline,
|
||||||
@@ -178,7 +178,7 @@ class RemoteAssetExif extends RemoteAsset {
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
int? width,
|
int? width,
|
||||||
int? height,
|
int? height,
|
||||||
int? durationInSeconds,
|
int? durationMs,
|
||||||
bool? isFavorite,
|
bool? isFavorite,
|
||||||
String? thumbHash,
|
String? thumbHash,
|
||||||
AssetVisibility? visibility,
|
AssetVisibility? visibility,
|
||||||
@@ -198,7 +198,7 @@ class RemoteAssetExif extends RemoteAsset {
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
thumbHash: thumbHash ?? this.thumbHash,
|
thumbHash: thumbHash ?? this.thumbHash,
|
||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
||||||
|
|
||||||
|
class AlbumConfig {
|
||||||
|
final AlbumSortMode sortMode;
|
||||||
|
final bool isReverse;
|
||||||
|
final bool isGrid;
|
||||||
|
|
||||||
|
const AlbumConfig({this.sortMode = AlbumSortMode.mostRecent, this.isReverse = true, this.isGrid = false});
|
||||||
|
|
||||||
|
AlbumConfig copyWith({AlbumSortMode? sortMode, bool? isReverse, bool? isGrid}) =>
|
||||||
|
AlbumConfig(sortMode: sortMode ?? this.sortMode, isReverse: isReverse ?? this.isReverse, isGrid: isGrid ?? this.isGrid);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is AlbumConfig && other.sortMode == sortMode && other.isReverse == isReverse && other.isGrid == isGrid);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(sortMode, isReverse, isGrid);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'AlbumConfig(sortMode: $sortMode, isReverse: $isReverse, isGrid: $isGrid)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import 'package:immich_mobile/domain/models/config/album_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/cleanup_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/image_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/map_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/theme_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/timeline_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/viewer_config.dart';
|
||||||
|
|
||||||
|
class AppConfig {
|
||||||
|
final ThemeConfig theme;
|
||||||
|
final CleanupConfig cleanup;
|
||||||
|
final MapConfig map;
|
||||||
|
final TimelineConfig timeline;
|
||||||
|
final ImageConfig image;
|
||||||
|
final ViewerConfig viewer;
|
||||||
|
final AlbumConfig album;
|
||||||
|
|
||||||
|
const AppConfig({
|
||||||
|
this.theme = const .new(),
|
||||||
|
this.cleanup = const .new(),
|
||||||
|
this.map = const .new(),
|
||||||
|
this.timeline = const .new(),
|
||||||
|
this.image = const .new(),
|
||||||
|
this.viewer = const .new(),
|
||||||
|
this.album = const .new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
AppConfig copyWith({
|
||||||
|
ThemeConfig? theme,
|
||||||
|
CleanupConfig? cleanup,
|
||||||
|
MapConfig? map,
|
||||||
|
TimelineConfig? timeline,
|
||||||
|
ImageConfig? image,
|
||||||
|
ViewerConfig? viewer,
|
||||||
|
AlbumConfig? album,
|
||||||
|
}) => .new(
|
||||||
|
theme: theme ?? this.theme,
|
||||||
|
cleanup: cleanup ?? this.cleanup,
|
||||||
|
map: map ?? this.map,
|
||||||
|
timeline: timeline ?? this.timeline,
|
||||||
|
image: image ?? this.image,
|
||||||
|
viewer: viewer ?? this.viewer,
|
||||||
|
album: album ?? this.album,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is AppConfig &&
|
||||||
|
other.theme == theme &&
|
||||||
|
other.cleanup == cleanup &&
|
||||||
|
other.map == map &&
|
||||||
|
other.timeline == timeline &&
|
||||||
|
other.image == image &&
|
||||||
|
other.viewer == viewer &&
|
||||||
|
other.album == album);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(theme, cleanup, map, timeline, image, viewer, album);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer, album: $album)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
|
|
||||||
|
class CleanupConfig {
|
||||||
|
final bool keepFavorites;
|
||||||
|
final AssetKeepType keepMediaType;
|
||||||
|
final List<String> keepAlbumIds;
|
||||||
|
final int cutoffDaysAgo;
|
||||||
|
final bool defaultsInitialized;
|
||||||
|
|
||||||
|
const CleanupConfig({
|
||||||
|
this.keepFavorites = true,
|
||||||
|
this.keepMediaType = AssetKeepType.none,
|
||||||
|
this.keepAlbumIds = const [],
|
||||||
|
this.cutoffDaysAgo = -1,
|
||||||
|
this.defaultsInitialized = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
CleanupConfig copyWith({
|
||||||
|
bool? keepFavorites,
|
||||||
|
AssetKeepType? keepMediaType,
|
||||||
|
List<String>? keepAlbumIds,
|
||||||
|
int? cutoffDaysAgo,
|
||||||
|
bool? defaultsInitialized,
|
||||||
|
}) => .new(
|
||||||
|
keepFavorites: keepFavorites ?? this.keepFavorites,
|
||||||
|
keepMediaType: keepMediaType ?? this.keepMediaType,
|
||||||
|
keepAlbumIds: keepAlbumIds ?? this.keepAlbumIds,
|
||||||
|
cutoffDaysAgo: cutoffDaysAgo ?? this.cutoffDaysAgo,
|
||||||
|
defaultsInitialized: defaultsInitialized ?? this.defaultsInitialized,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is CleanupConfig &&
|
||||||
|
other.keepFavorites == keepFavorites &&
|
||||||
|
other.keepMediaType == keepMediaType &&
|
||||||
|
other.keepAlbumIds == keepAlbumIds &&
|
||||||
|
other.cutoffDaysAgo == cutoffDaysAgo &&
|
||||||
|
other.defaultsInitialized == defaultsInitialized);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(keepFavorites, keepMediaType, keepAlbumIds, cutoffDaysAgo, defaultsInitialized);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'CleanupConfig(keepFavorites: $keepFavorites, keepMediaType: $keepMediaType, keepAlbumIds: $keepAlbumIds, cutoffDaysAgo: $cutoffDaysAgo, defaultsInitialized: $defaultsInitialized)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
class ImageConfig {
|
||||||
|
final bool preferRemote;
|
||||||
|
final bool loadOriginal;
|
||||||
|
|
||||||
|
const ImageConfig({this.preferRemote = false, this.loadOriginal = false});
|
||||||
|
|
||||||
|
ImageConfig copyWith({bool? preferRemote, bool? loadOriginal}) =>
|
||||||
|
ImageConfig(preferRemote: preferRemote ?? this.preferRemote, loadOriginal: loadOriginal ?? this.loadOriginal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is ImageConfig && other.preferRemote == preferRemote && other.loadOriginal == loadOriginal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(preferRemote, loadOriginal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ImageConfig(preferRemoteImage: $preferRemote, loadOriginal: $loadOriginal)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MapConfig {
|
||||||
|
final int relativeDays;
|
||||||
|
final bool favoritesOnly;
|
||||||
|
final bool includeArchived;
|
||||||
|
final ThemeMode themeMode;
|
||||||
|
final bool withPartners;
|
||||||
|
|
||||||
|
const MapConfig({
|
||||||
|
this.relativeDays = 0,
|
||||||
|
this.favoritesOnly = false,
|
||||||
|
this.includeArchived = false,
|
||||||
|
this.themeMode = ThemeMode.system,
|
||||||
|
this.withPartners = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
MapConfig copyWith({
|
||||||
|
int? relativeDays,
|
||||||
|
bool? favoritesOnly,
|
||||||
|
bool? includeArchived,
|
||||||
|
ThemeMode? themeMode,
|
||||||
|
bool? withPartners,
|
||||||
|
}) => MapConfig(
|
||||||
|
relativeDays: relativeDays ?? this.relativeDays,
|
||||||
|
favoritesOnly: favoritesOnly ?? this.favoritesOnly,
|
||||||
|
includeArchived: includeArchived ?? this.includeArchived,
|
||||||
|
themeMode: themeMode ?? this.themeMode,
|
||||||
|
withPartners: withPartners ?? this.withPartners,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is MapConfig &&
|
||||||
|
other.relativeDays == relativeDays &&
|
||||||
|
other.favoritesOnly == favoritesOnly &&
|
||||||
|
other.includeArchived == includeArchived &&
|
||||||
|
other.themeMode == themeMode &&
|
||||||
|
other.withPartners == withPartners);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(relativeDays, favoritesOnly, includeArchived, themeMode, withPartners);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'MapConfig(relativeDays: $relativeDays, favoritesOnly: $favoritesOnly, includeArchived: $includeArchived, themeMode: $themeMode, withPartners: $withPartners)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
class NetworkConfig {
|
||||||
|
final bool autoEndpointSwitching;
|
||||||
|
final String? preferredWifiName;
|
||||||
|
final String? localEndpoint;
|
||||||
|
final List<String> externalEndpointList;
|
||||||
|
final Map<String, String> customHeaders;
|
||||||
|
|
||||||
|
const NetworkConfig({
|
||||||
|
this.autoEndpointSwitching = false,
|
||||||
|
this.preferredWifiName,
|
||||||
|
this.localEndpoint,
|
||||||
|
this.externalEndpointList = const [],
|
||||||
|
this.customHeaders = const {},
|
||||||
|
});
|
||||||
|
|
||||||
|
NetworkConfig copyWith({
|
||||||
|
bool? autoEndpointSwitching,
|
||||||
|
String? preferredWifiName,
|
||||||
|
String? localEndpoint,
|
||||||
|
List<String>? externalEndpointList,
|
||||||
|
Map<String, String>? customHeaders,
|
||||||
|
}) => NetworkConfig(
|
||||||
|
autoEndpointSwitching: autoEndpointSwitching ?? this.autoEndpointSwitching,
|
||||||
|
preferredWifiName: preferredWifiName ?? this.preferredWifiName,
|
||||||
|
localEndpoint: localEndpoint ?? this.localEndpoint,
|
||||||
|
externalEndpointList: externalEndpointList ?? this.externalEndpointList,
|
||||||
|
customHeaders: customHeaders ?? this.customHeaders,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is NetworkConfig &&
|
||||||
|
other.autoEndpointSwitching == autoEndpointSwitching &&
|
||||||
|
other.preferredWifiName == preferredWifiName &&
|
||||||
|
other.localEndpoint == localEndpoint &&
|
||||||
|
listEquals(other.externalEndpointList, externalEndpointList) &&
|
||||||
|
mapEquals(other.customHeaders, customHeaders));
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
autoEndpointSwitching,
|
||||||
|
preferredWifiName,
|
||||||
|
localEndpoint,
|
||||||
|
Object.hashAll(externalEndpointList),
|
||||||
|
Object.hashAllUnordered(customHeaders.entries.map((e) => Object.hash(e.key, e.value))),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'NetworkConfig(autoEndpointSwitching: $autoEndpointSwitching, preferredWifiName: $preferredWifiName, localEndpoint: $localEndpoint, externalEndpointList: $externalEndpointList, customHeaders: $customHeaders)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:immich_mobile/domain/models/config/network_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
|
|
||||||
|
class SystemConfig {
|
||||||
|
final LogLevel logLevel;
|
||||||
|
final NetworkConfig network;
|
||||||
|
|
||||||
|
const SystemConfig({this.logLevel = .info, this.network = const .new()});
|
||||||
|
|
||||||
|
SystemConfig copyWith({LogLevel? logLevel, NetworkConfig? network}) =>
|
||||||
|
SystemConfig(logLevel: logLevel ?? this.logLevel, network: network ?? this.network);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is SystemConfig && other.logLevel == logLevel && other.network == network);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(logLevel, network);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'SystemConfig(logLevel: $logLevel, network: $network)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:immich_mobile/constants/colors.dart';
|
||||||
|
|
||||||
|
class ThemeConfig {
|
||||||
|
final ThemeMode mode;
|
||||||
|
final ImmichColorPreset primaryColor;
|
||||||
|
final bool dynamicTheme;
|
||||||
|
final bool colorfulInterface;
|
||||||
|
|
||||||
|
const ThemeConfig({
|
||||||
|
this.mode = .system,
|
||||||
|
this.primaryColor = .indigo,
|
||||||
|
this.dynamicTheme = false,
|
||||||
|
this.colorfulInterface = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
ThemeConfig copyWith({
|
||||||
|
ThemeMode? mode,
|
||||||
|
ImmichColorPreset? primaryColor,
|
||||||
|
bool? dynamicTheme,
|
||||||
|
bool? colorfulInterface,
|
||||||
|
}) => .new(
|
||||||
|
mode: mode ?? this.mode,
|
||||||
|
primaryColor: primaryColor ?? this.primaryColor,
|
||||||
|
dynamicTheme: dynamicTheme ?? this.dynamicTheme,
|
||||||
|
colorfulInterface: colorfulInterface ?? this.colorfulInterface,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is ThemeConfig &&
|
||||||
|
other.mode == mode &&
|
||||||
|
other.primaryColor == primaryColor &&
|
||||||
|
other.dynamicTheme == dynamicTheme &&
|
||||||
|
other.colorfulInterface == colorfulInterface);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(mode, primaryColor, dynamicTheme, colorfulInterface);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'ThemeConfig(mode: $mode, primaryColor: $primaryColor, dynamicTheme: $dynamicTheme, colorfulInterface: $colorfulInterface)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
|
|
||||||
|
class TimelineConfig {
|
||||||
|
final int tilesPerRow;
|
||||||
|
final GroupAssetsBy groupAssetsBy;
|
||||||
|
final bool storageIndicator;
|
||||||
|
|
||||||
|
const TimelineConfig({this.tilesPerRow = 4, this.groupAssetsBy = GroupAssetsBy.day, this.storageIndicator = true});
|
||||||
|
|
||||||
|
TimelineConfig copyWith({int? tilesPerRow, GroupAssetsBy? groupAssetsBy, bool? storageIndicator}) => TimelineConfig(
|
||||||
|
tilesPerRow: tilesPerRow ?? this.tilesPerRow,
|
||||||
|
groupAssetsBy: groupAssetsBy ?? this.groupAssetsBy,
|
||||||
|
storageIndicator: storageIndicator ?? this.storageIndicator,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is TimelineConfig &&
|
||||||
|
other.tilesPerRow == tilesPerRow &&
|
||||||
|
other.groupAssetsBy == groupAssetsBy &&
|
||||||
|
other.storageIndicator == storageIndicator);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(tilesPerRow, groupAssetsBy, storageIndicator);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'TimelineConfig(tilesPerRow: $tilesPerRow, groupAssetsBy: $groupAssetsBy, storageIndicator: $storageIndicator)';
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
class ViewerConfig {
|
||||||
|
final bool loopVideo;
|
||||||
|
final bool loadOriginalVideo;
|
||||||
|
final bool autoPlayVideo;
|
||||||
|
final bool tapToNavigate;
|
||||||
|
|
||||||
|
const ViewerConfig({
|
||||||
|
this.loopVideo = true,
|
||||||
|
this.loadOriginalVideo = false,
|
||||||
|
this.autoPlayVideo = true,
|
||||||
|
this.tapToNavigate = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
ViewerConfig copyWith({bool? loopVideo, bool? loadOriginalVideo, bool? autoPlayVideo, bool? tapToNavigate}) =>
|
||||||
|
ViewerConfig(
|
||||||
|
loopVideo: loopVideo ?? this.loopVideo,
|
||||||
|
loadOriginalVideo: loadOriginalVideo ?? this.loadOriginalVideo,
|
||||||
|
autoPlayVideo: autoPlayVideo ?? this.autoPlayVideo,
|
||||||
|
tapToNavigate: tapToNavigate ?? this.tapToNavigate,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is ViewerConfig &&
|
||||||
|
other.loopVideo == loopVideo &&
|
||||||
|
other.loadOriginalVideo == loadOriginalVideo &&
|
||||||
|
other.autoPlayVideo == autoPlayVideo &&
|
||||||
|
other.tapToNavigate == tapToNavigate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(loopVideo, loadOriginalVideo, autoPlayVideo, tapToNavigate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'ViewerConfig(loopVideo: $loopVideo, loadOriginalVideo: $loadOriginalVideo, autoPlayVideo: $autoPlayVideo, tapToNavigate: $tapToNavigate)';
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ class ExifInfo {
|
|||||||
bool get hasCoordinates => latitude != null && longitude != null && latitude != 0 && longitude != 0;
|
bool get hasCoordinates => latitude != null && longitude != null && latitude != 0 && longitude != 0;
|
||||||
|
|
||||||
String get exposureTime {
|
String get exposureTime {
|
||||||
if (exposureSeconds == null) {
|
if (exposureSeconds == null || exposureSeconds! <= 0 || exposureSeconds!.isNaN) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (exposureSeconds! < 1) {
|
if (exposureSeconds! < 1) {
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:immich_mobile/constants/colors.dart';
|
||||||
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/system_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
|
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
||||||
|
|
||||||
|
enum MetadataDomain<T extends Object> {
|
||||||
|
appConfig<AppConfig>('config.app'),
|
||||||
|
systemConfig<SystemConfig>('config.system');
|
||||||
|
|
||||||
|
final String prefix;
|
||||||
|
const MetadataDomain(this.prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MetadataKey<T extends Object> {
|
||||||
|
// Theme
|
||||||
|
themePrimaryColor<ImmichColorPreset>(.appConfig, 'theme.primaryColor', .indigo, _EnumCodec(ImmichColorPreset.values)),
|
||||||
|
themeMode<ThemeMode>(.appConfig, 'theme.mode', .system, _EnumCodec(ThemeMode.values)),
|
||||||
|
themeDynamic<bool>(.appConfig, 'theme.dynamic', false),
|
||||||
|
themeColorfulInterface<bool>(.appConfig, 'theme.colorfulInterface', true),
|
||||||
|
|
||||||
|
// Image
|
||||||
|
imagePreferRemote<bool>(.appConfig, 'image.preferRemote', false),
|
||||||
|
imageLoadOriginal<bool>(.appConfig, 'image.loadOriginal', false),
|
||||||
|
|
||||||
|
// Viewer
|
||||||
|
viewerLoopVideo<bool>(.appConfig, 'viewer.loopVideo', true),
|
||||||
|
viewerLoadOriginalVideo<bool>(.appConfig, 'viewer.loadOriginalVideo', false),
|
||||||
|
viewerAutoPlayVideo<bool>(.appConfig, 'viewer.autoPlayVideo', true),
|
||||||
|
viewerTapToNavigate<bool>(.appConfig, 'viewer.tapToNavigate', false),
|
||||||
|
|
||||||
|
// Network
|
||||||
|
networkAutoEndpointSwitching<bool>(.systemConfig, 'network.autoEndpointSwitching', false),
|
||||||
|
networkPreferredWifiName<String>(.systemConfig, 'network.preferredWifiName', ''),
|
||||||
|
networkLocalEndpoint<String>(.systemConfig, 'network.localEndpoint', ''),
|
||||||
|
networkExternalEndpointList<List<String>>(
|
||||||
|
.systemConfig,
|
||||||
|
'network.externalEndpointList',
|
||||||
|
[],
|
||||||
|
_ListCodec(_PrimitiveCodec.string),
|
||||||
|
),
|
||||||
|
networkCustomHeaders<Map<String, String>>(
|
||||||
|
.systemConfig,
|
||||||
|
'network.customHeaders',
|
||||||
|
{},
|
||||||
|
_MapCodec(_PrimitiveCodec.string, _PrimitiveCodec.string),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Album
|
||||||
|
albumSortMode<AlbumSortMode>(
|
||||||
|
.appConfig,
|
||||||
|
'album.sortMode',
|
||||||
|
AlbumSortMode.mostRecent,
|
||||||
|
_EnumCodec(AlbumSortMode.values),
|
||||||
|
),
|
||||||
|
albumIsReverse<bool>(.appConfig, 'album.isReverse', true),
|
||||||
|
albumIsGrid<bool>(.appConfig, 'album.isGrid', false),
|
||||||
|
|
||||||
|
// Timeline
|
||||||
|
timelineTilesPerRow<int>(.appConfig, 'timeline.tilesPerRow', 4),
|
||||||
|
timelineGroupAssetsBy<GroupAssetsBy>(
|
||||||
|
.appConfig,
|
||||||
|
'timeline.groupAssetsBy',
|
||||||
|
GroupAssetsBy.day,
|
||||||
|
_EnumCodec(GroupAssetsBy.values),
|
||||||
|
),
|
||||||
|
timelineStorageIndicator<bool>(.appConfig, 'timeline.storageIndicator', true),
|
||||||
|
|
||||||
|
// Log
|
||||||
|
logLevel<LogLevel>(.systemConfig, 'log.level', .info, _EnumCodec(LogLevel.values)),
|
||||||
|
|
||||||
|
// Map
|
||||||
|
mapShowFavoriteOnly<bool>(.appConfig, 'map.showFavoriteOnly', false),
|
||||||
|
mapRelativeDate<int>(.appConfig, 'map.relativeDate', 0),
|
||||||
|
mapIncludeArchived<bool>(.appConfig, 'map.includeArchived', false),
|
||||||
|
mapThemeMode<ThemeMode>(.appConfig, 'map.themeMode', .system, _EnumCodec(ThemeMode.values)),
|
||||||
|
mapWithPartners<bool>(.appConfig, 'map.withPartners', false),
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
cleanupKeepFavorites<bool>(.appConfig, 'cleanup.keepFavorites', true),
|
||||||
|
cleanupKeepMediaType<AssetKeepType>(
|
||||||
|
.appConfig,
|
||||||
|
'cleanup.keepMediaType',
|
||||||
|
AssetKeepType.none,
|
||||||
|
_EnumCodec(AssetKeepType.values),
|
||||||
|
),
|
||||||
|
cleanupKeepAlbumIds<List<String>>(.appConfig, 'cleanup.keepAlbumIds', [], _ListCodec(_PrimitiveCodec.string)),
|
||||||
|
cleanupCutoffDaysAgo<int>(.appConfig, 'cleanup.cutoffDaysAgo', -1),
|
||||||
|
cleanupDefaultsInitialized<bool>(.appConfig, 'cleanup.defaultsInitialized', false);
|
||||||
|
|
||||||
|
final MetadataDomain domain;
|
||||||
|
final String name;
|
||||||
|
final T defaultValue;
|
||||||
|
final _MetadataCodec<T>? _codecOverride;
|
||||||
|
|
||||||
|
const MetadataKey(this.domain, this.name, this.defaultValue, [this._codecOverride]);
|
||||||
|
|
||||||
|
String get key => '${domain.prefix}.$name';
|
||||||
|
|
||||||
|
_MetadataCodec<T> get _codec => _codecOverride ?? _MetadataCodec.forPrimitive(defaultValue);
|
||||||
|
|
||||||
|
String encode(T value) => _codec.encode(value);
|
||||||
|
|
||||||
|
T decode(String raw) => _codec.decode(raw) ?? defaultValue;
|
||||||
|
|
||||||
|
static Map<String, MetadataKey<Object>> asKeyMap() => {for (var value in MetadataKey.values) value.key: value};
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class _MetadataCodec<T extends Object> {
|
||||||
|
const _MetadataCodec();
|
||||||
|
|
||||||
|
String encode(T value);
|
||||||
|
T? decode(String raw);
|
||||||
|
|
||||||
|
static const Map<Type, _MetadataCodec<Object>> _primitives = {
|
||||||
|
int: _PrimitiveCodec.integer,
|
||||||
|
double: _PrimitiveCodec.real,
|
||||||
|
bool: _PrimitiveCodec.boolean,
|
||||||
|
String: _PrimitiveCodec.string,
|
||||||
|
DateTime: _DateTimeCodec(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static _MetadataCodec<T> forPrimitive<T extends Object>(T sample) {
|
||||||
|
final codec = _primitives[sample.runtimeType];
|
||||||
|
if (codec == null) {
|
||||||
|
throw StateError(
|
||||||
|
'No primitive codec for ${sample.runtimeType}. Provide an explicit codec when defining the MetadataKey.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return codec as _MetadataCodec<T>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class _EnumCodec<T extends Enum> extends _MetadataCodec<T> {
|
||||||
|
final List<T> values;
|
||||||
|
|
||||||
|
const _EnumCodec(this.values);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String encode(T value) => value.name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
T? decode(String raw) => values.firstWhereOrNull((v) => v.name == raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
final class _DateTimeCodec extends _MetadataCodec<DateTime> {
|
||||||
|
const _DateTimeCodec();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String encode(DateTime value) => value.toIso8601String();
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime? decode(String raw) => DateTime.tryParse(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
final class _MapCodec<K extends Object, V extends Object> extends _MetadataCodec<Map<K, V>> {
|
||||||
|
final _MetadataCodec<K> _keyCodec;
|
||||||
|
final _MetadataCodec<V> _valueCodec;
|
||||||
|
|
||||||
|
const _MapCodec(this._keyCodec, this._valueCodec);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String encode(Map<K, V> value) {
|
||||||
|
final entries = <String, String>{};
|
||||||
|
value.forEach((k, v) => entries[_keyCodec.encode(k)] = _valueCodec.encode(v));
|
||||||
|
return jsonEncode(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<K, V>? decode(String raw) {
|
||||||
|
try {
|
||||||
|
final decoded = jsonDecode(raw);
|
||||||
|
if (decoded is! Map) return null;
|
||||||
|
final result = <K, V>{};
|
||||||
|
for (final entry in decoded.entries) {
|
||||||
|
final rawKey = entry.key;
|
||||||
|
final rawValue = entry.value;
|
||||||
|
if (rawKey is! String || rawValue is! String) return null;
|
||||||
|
final k = _keyCodec.decode(rawKey);
|
||||||
|
final v = _valueCodec.decode(rawValue);
|
||||||
|
if (k == null || v == null) return null;
|
||||||
|
result[k] = v;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} on FormatException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class _ListCodec<T extends Object> extends _MetadataCodec<List<T>> {
|
||||||
|
final _MetadataCodec<T> _elementCodec;
|
||||||
|
|
||||||
|
const _ListCodec(this._elementCodec);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String encode(List<T> value) => jsonEncode(value.map(_elementCodec.encode).toList());
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<T>? decode(String raw) {
|
||||||
|
try {
|
||||||
|
final decoded = jsonDecode(raw);
|
||||||
|
if (decoded is! List) return null;
|
||||||
|
final result = <T>[];
|
||||||
|
for (final item in decoded) {
|
||||||
|
if (item is! String) return null;
|
||||||
|
final element = _elementCodec.decode(item);
|
||||||
|
if (element == null) return null;
|
||||||
|
result.add(element);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} on FormatException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class _PrimitiveCodec<T extends Object> extends _MetadataCodec<T> {
|
||||||
|
final T? Function(String) _parse;
|
||||||
|
|
||||||
|
const _PrimitiveCodec._(this._parse);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String encode(T value) => value.toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
T? decode(String raw) => _parse(raw);
|
||||||
|
|
||||||
|
static const integer = _PrimitiveCodec<int>._(int.tryParse);
|
||||||
|
static const real = _PrimitiveCodec<double>._(double.tryParse);
|
||||||
|
static const boolean = _PrimitiveCodec<bool>._(bool.tryParse);
|
||||||
|
static const string = _PrimitiveCodec<String>._(_identity);
|
||||||
|
|
||||||
|
static String? _identity(String s) => s;
|
||||||
|
}
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
|
|
||||||
enum Setting<T> {
|
enum Setting<T> {
|
||||||
tilesPerRow<int>(StoreKey.tilesPerRow, 4),
|
|
||||||
groupAssetsBy<int>(StoreKey.groupAssetsBy, 0),
|
|
||||||
showStorageIndicator<bool>(StoreKey.storageIndicator, true),
|
|
||||||
loadOriginal<bool>(StoreKey.loadOriginal, false),
|
|
||||||
loadOriginalVideo<bool>(StoreKey.loadOriginalVideo, false),
|
|
||||||
autoPlayVideo<bool>(StoreKey.autoPlayVideo, true),
|
|
||||||
preferRemoteImage<bool>(StoreKey.preferRemoteImage, false),
|
|
||||||
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, false),
|
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, false),
|
||||||
enableBackup<bool>(StoreKey.enableBackup, false);
|
enableBackup<bool>(StoreKey.enableBackup, false);
|
||||||
|
|
||||||
|
|||||||
@@ -4,97 +4,60 @@ import 'package:immich_mobile/domain/models/user.model.dart';
|
|||||||
/// Defines the data type for each value
|
/// Defines the data type for each value
|
||||||
enum StoreKey<T> {
|
enum StoreKey<T> {
|
||||||
version<int>._(0),
|
version<int>._(0),
|
||||||
assetETag<String>._(1),
|
|
||||||
currentUser<UserDto>._(2),
|
currentUser<UserDto>._(2),
|
||||||
deviceIdHash<int>._(3),
|
|
||||||
deviceId<String>._(4),
|
deviceId<String>._(4),
|
||||||
backupFailedSince<DateTime>._(5),
|
|
||||||
backupRequireWifi<bool>._(6),
|
|
||||||
backupRequireCharging<bool>._(7),
|
backupRequireCharging<bool>._(7),
|
||||||
backupTriggerDelay<int>._(8),
|
backupTriggerDelay<int>._(8),
|
||||||
serverUrl<String>._(10),
|
serverUrl<String>._(10),
|
||||||
accessToken<String>._(11),
|
accessToken<String>._(11),
|
||||||
serverEndpoint<String>._(12),
|
serverEndpoint<String>._(12),
|
||||||
autoBackup<bool>._(13),
|
|
||||||
backgroundBackup<bool>._(14),
|
|
||||||
sslClientCertData<String>._(15),
|
|
||||||
sslClientPasswd<String>._(16),
|
|
||||||
// user settings from [AppSettingsEnum] below:
|
|
||||||
loadPreview<bool>._(100),
|
|
||||||
loadOriginal<bool>._(101),
|
|
||||||
themeMode<String>._(102),
|
|
||||||
tilesPerRow<int>._(103),
|
|
||||||
dynamicLayout<bool>._(104),
|
|
||||||
groupAssetsBy<int>._(105),
|
|
||||||
uploadErrorNotificationGracePeriod<int>._(106),
|
|
||||||
backgroundBackupTotalProgress<bool>._(107),
|
|
||||||
backgroundBackupSingleProgress<bool>._(108),
|
|
||||||
storageIndicator<bool>._(109),
|
|
||||||
thumbnailCacheSize<int>._(110),
|
|
||||||
imageCacheSize<int>._(111),
|
|
||||||
albumThumbnailCacheSize<int>._(112),
|
|
||||||
selectedAlbumSortOrder<int>._(113),
|
|
||||||
advancedTroubleshooting<bool>._(114),
|
advancedTroubleshooting<bool>._(114),
|
||||||
logLevel<int>._(115),
|
|
||||||
preferRemoteImage<bool>._(116),
|
|
||||||
loopVideo<bool>._(117),
|
|
||||||
// map related settings
|
|
||||||
mapShowFavoriteOnly<bool>._(118),
|
|
||||||
mapRelativeDate<int>._(119),
|
|
||||||
selfSignedCert<bool>._(120),
|
|
||||||
mapIncludeArchived<bool>._(121),
|
|
||||||
ignoreIcloudAssets<bool>._(122),
|
|
||||||
selectedAlbumSortReverse<bool>._(123),
|
|
||||||
mapThemeMode<int>._(124),
|
|
||||||
mapwithPartners<bool>._(125),
|
|
||||||
enableHapticFeedback<bool>._(126),
|
enableHapticFeedback<bool>._(126),
|
||||||
customHeaders<String>._(127),
|
|
||||||
|
|
||||||
// theme settings
|
|
||||||
primaryColor<String>._(128),
|
|
||||||
dynamicTheme<bool>._(129),
|
|
||||||
colorfulInterface<bool>._(130),
|
|
||||||
|
|
||||||
syncAlbums<bool>._(131),
|
syncAlbums<bool>._(131),
|
||||||
|
|
||||||
// Auto endpoint switching
|
|
||||||
autoEndpointSwitching<bool>._(132),
|
|
||||||
preferredWifiName<String>._(133),
|
|
||||||
localEndpoint<String>._(134),
|
|
||||||
externalEndpointList<String>._(135),
|
|
||||||
|
|
||||||
// Video settings
|
|
||||||
loadOriginalVideo<bool>._(136),
|
|
||||||
manageLocalMediaAndroid<bool>._(137),
|
manageLocalMediaAndroid<bool>._(137),
|
||||||
|
|
||||||
// Read-only Mode settings
|
// Read-only Mode settings
|
||||||
readonlyModeEnabled<bool>._(138),
|
readonlyModeEnabled<bool>._(138),
|
||||||
|
|
||||||
autoPlayVideo<bool>._(139),
|
|
||||||
albumGridView<bool>._(140),
|
|
||||||
|
|
||||||
// Image viewer navigation settings
|
|
||||||
tapToNavigate<bool>._(141),
|
|
||||||
|
|
||||||
// Experimental stuff
|
// Experimental stuff
|
||||||
photoManagerCustomFilter<bool>._(1000),
|
|
||||||
betaPromptShown<bool>._(1001),
|
|
||||||
betaTimeline<bool>._(1002),
|
|
||||||
enableBackup<bool>._(1003),
|
enableBackup<bool>._(1003),
|
||||||
useWifiForUploadVideos<bool>._(1004),
|
useWifiForUploadVideos<bool>._(1004),
|
||||||
useWifiForUploadPhotos<bool>._(1005),
|
useWifiForUploadPhotos<bool>._(1005),
|
||||||
needBetaMigration<bool>._(1006),
|
syncMigrationStatus<String>._(1013),
|
||||||
// TODO: Remove this after patching open-api
|
|
||||||
shouldResetSync<bool>._(1007),
|
|
||||||
|
|
||||||
// Free up space
|
// Legacy keys that have been migrated to the new metadata store
|
||||||
cleanupKeepFavorites<bool>._(1008),
|
legacySelectedAlbumSortOrder<int>._(113),
|
||||||
cleanupKeepMediaType<int>._(1009),
|
legacySelectedAlbumSortReverse<bool>._(123),
|
||||||
cleanupKeepAlbumIds<String>._(1010),
|
legacyAlbumGridView<bool>._(140),
|
||||||
cleanupCutoffDaysAgo<int>._(1011),
|
legacyAutoEndpointSwitching<bool>._(132),
|
||||||
cleanupDefaultsInitialized<bool>._(1012),
|
legacyPreferredWifiName<String>._(133),
|
||||||
|
legacyLocalEndpoint<String>._(134),
|
||||||
syncMigrationStatus<String>._(1013);
|
legacyExternalEndpointList<String>._(135),
|
||||||
|
legacyCustomHeaders<String>._(127),
|
||||||
|
legacyLoopVideo<bool>._(117),
|
||||||
|
legacyLoadOriginalVideo<bool>._(136),
|
||||||
|
legacyAutoPlayVideo<bool>._(139),
|
||||||
|
legacyTapToNavigate<bool>._(141),
|
||||||
|
legacyPreferRemoteImage<bool>._(116),
|
||||||
|
legacyLoadOriginal<bool>._(101),
|
||||||
|
legacyPrimaryColor<String>._(128),
|
||||||
|
legacyDynamicTheme<bool>._(129),
|
||||||
|
legacyColorfulInterface<bool>._(130),
|
||||||
|
legacyThemeMode<String>._(102),
|
||||||
|
legacyCleanupKeepFavorites<bool>._(1008),
|
||||||
|
legacyCleanupKeepMediaType<int>._(1009),
|
||||||
|
legacyCleanupKeepAlbumIds<String>._(1010),
|
||||||
|
legacyCleanupCutoffDaysAgo<int>._(1011),
|
||||||
|
legacyCleanupDefaultsInitialized<bool>._(1012),
|
||||||
|
legacyTilesPerRow<int>._(103),
|
||||||
|
legacyGroupAssetsBy<int>._(105),
|
||||||
|
legacyStorageIndicator<bool>._(109),
|
||||||
|
legacyMapRelativeDate<int>._(119),
|
||||||
|
legacyMapShowFavoriteOnly<bool>._(118),
|
||||||
|
legacyMapIncludeArchived<bool>._(121),
|
||||||
|
legacyMapThemeMode<int>._(124),
|
||||||
|
legacyMapwithPartners<bool>._(125),
|
||||||
|
legacyLogLevel<int>._(115);
|
||||||
|
|
||||||
const StoreKey._(this.id);
|
const StoreKey._(this.id);
|
||||||
final int id;
|
final int id;
|
||||||
|
|||||||
@@ -93,8 +93,7 @@ class LocalSyncService {
|
|||||||
|
|
||||||
if (CurrentPlatform.isIOS) {
|
if (CurrentPlatform.isIOS) {
|
||||||
// On iOS, we need to full sync albums that are marked as cloud as the delta sync
|
// On iOS, we need to full sync albums that are marked as cloud as the delta sync
|
||||||
// does not include changes for cloud albums. If ignoreIcloudAssets is enabled,
|
// does not include changes for cloud albums.
|
||||||
// remove the albums from the local database from the previous sync
|
|
||||||
final cloudAlbums = deviceAlbums.where((a) => a.isCloud).toLocalAlbums();
|
final cloudAlbums = deviceAlbums.where((a) => a.isCloud).toLocalAlbums();
|
||||||
for (final album in cloudAlbums) {
|
for (final album in cloudAlbums) {
|
||||||
final dbAlbum = dbAlbums.firstWhereOrNull((a) => a.id == album.id);
|
final dbAlbum = dbAlbums.firstWhereOrNull((a) => a.id == album.id);
|
||||||
@@ -337,7 +336,7 @@ class LocalSyncService {
|
|||||||
a.createdAt.isAtSameMomentAs(b.createdAt) &&
|
a.createdAt.isAtSameMomentAs(b.createdAt) &&
|
||||||
a.width == b.width &&
|
a.width == b.width &&
|
||||||
a.height == b.height &&
|
a.height == b.height &&
|
||||||
a.durationInSeconds == b.durationInSeconds;
|
a.durationMs == b.durationMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
final firstAdjustment = a.adjustmentTime?.millisecondsSinceEpoch ?? 0;
|
final firstAdjustment = a.adjustmentTime?.millisecondsSinceEpoch ?? 0;
|
||||||
@@ -346,7 +345,7 @@ class LocalSyncService {
|
|||||||
a.createdAt.isAtSameMomentAs(b.createdAt) &&
|
a.createdAt.isAtSameMomentAs(b.createdAt) &&
|
||||||
a.width == b.width &&
|
a.width == b.width &&
|
||||||
a.height == b.height &&
|
a.height == b.height &&
|
||||||
a.durationInSeconds == b.durationInSeconds &&
|
a.durationMs == b.durationMs &&
|
||||||
a.latitude == b.latitude &&
|
a.latitude == b.latitude &&
|
||||||
a.longitude == b.longitude;
|
a.longitude == b.longitude;
|
||||||
}
|
}
|
||||||
@@ -432,7 +431,7 @@ extension PlatformToLocalAsset on PlatformAsset {
|
|||||||
updatedAt: tryFromSecondsSinceEpoch(updatedAt, isUtc: true) ?? DateTime.timestamp(),
|
updatedAt: tryFromSecondsSinceEpoch(updatedAt, isUtc: true) ?? DateTime.timestamp(),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
playbackStyle: _toPlaybackStyle(playbackStyle),
|
playbackStyle: _toPlaybackStyle(playbackStyle),
|
||||||
|
|||||||
@@ -2,20 +2,20 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/metadata_key.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
|
||||||
import 'package:immich_mobile/utils/debug_print.dart';
|
import 'package:immich_mobile/utils/debug_print.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
/// Service responsible for handling application logging.
|
/// Service responsible for handling application logging.
|
||||||
///
|
///
|
||||||
/// It listens to Dart's [Logger.root], buffers logs in memory (optionally),
|
/// It listens to Dart's [Logger.root], buffers logs in memory (optionally),
|
||||||
/// writes them to a persistent [ILogRepository], and manages log levels
|
/// writes them to a persistent [LogRepository], and manages log levels via
|
||||||
/// via [IStoreRepository]
|
/// [MetadataRepository].
|
||||||
class LogService {
|
class LogService {
|
||||||
final LogRepository _logRepository;
|
final LogRepository _logRepository;
|
||||||
final DriftStoreRepository _storeRepository;
|
final MetadataRepository _metadataRepository;
|
||||||
|
|
||||||
final List<LogMessage> _msgBuffer = [];
|
final List<LogMessage> _msgBuffer = [];
|
||||||
|
|
||||||
@@ -38,12 +38,12 @@ class LogService {
|
|||||||
|
|
||||||
static Future<LogService> init({
|
static Future<LogService> init({
|
||||||
required LogRepository logRepository,
|
required LogRepository logRepository,
|
||||||
required DriftStoreRepository storeRepository,
|
required MetadataRepository metadataRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
_instance ??= await create(
|
_instance ??= await create(
|
||||||
logRepository: logRepository,
|
logRepository: logRepository,
|
||||||
storeRepository: storeRepository,
|
metadataRepository: metadataRepository,
|
||||||
shouldBuffer: shouldBuffer,
|
shouldBuffer: shouldBuffer,
|
||||||
);
|
);
|
||||||
return _instance!;
|
return _instance!;
|
||||||
@@ -51,17 +51,17 @@ class LogService {
|
|||||||
|
|
||||||
static Future<LogService> create({
|
static Future<LogService> create({
|
||||||
required LogRepository logRepository,
|
required LogRepository logRepository,
|
||||||
required DriftStoreRepository storeRepository,
|
required MetadataRepository metadataRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
final instance = LogService._(logRepository, storeRepository, shouldBuffer);
|
final instance = LogService._(logRepository, metadataRepository, shouldBuffer);
|
||||||
await logRepository.truncate(limit: kLogTruncateLimit);
|
await logRepository.truncate(limit: kLogTruncateLimit);
|
||||||
final level = await instance._storeRepository.tryGet(StoreKey.logLevel) ?? LogLevel.info.index;
|
final level = instance._metadataRepository.systemConfig.logLevel;
|
||||||
Logger.root.level = Level.LEVELS.elementAtOrNull(level) ?? Level.INFO;
|
Logger.root.level = Level.LEVELS.elementAtOrNull(level.index) ?? Level.INFO;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogService._(this._logRepository, this._storeRepository, this._shouldBuffer) {
|
LogService._(this._logRepository, this._metadataRepository, this._shouldBuffer) {
|
||||||
_logSubscription = Logger.root.onRecord.listen(_handleLogRecord);
|
_logSubscription = Logger.root.onRecord.listen(_handleLogRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setLogLevel(LogLevel level) async {
|
Future<void> setLogLevel(LogLevel level) async {
|
||||||
await _storeRepository.upsert(StoreKey.logLevel, level.index);
|
await _metadataRepository.write(MetadataKey.logLevel, level);
|
||||||
Logger.root.level = level.toLevel();
|
Logger.root.level = level.toLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||||
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
||||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
|
||||||
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
||||||
|
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||||
|
|
||||||
class RemoteAlbumService {
|
class RemoteAlbumService {
|
||||||
final DriftRemoteAlbumRepository _repository;
|
final DriftRemoteAlbumRepository _repository;
|
||||||
@@ -28,10 +28,6 @@ class RemoteAlbumService {
|
|||||||
return _repository.get(albumId);
|
return _repository.get(albumId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<RemoteAlbum?> getByName(String albumName, String ownerId) {
|
|
||||||
return _repository.getByName(albumName, ownerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<RemoteAlbum>> sortAlbums(
|
Future<List<RemoteAlbum>> sortAlbums(
|
||||||
List<RemoteAlbum> albums,
|
List<RemoteAlbum> albums,
|
||||||
AlbumSortMode sortMode, {
|
AlbumSortMode sortMode, {
|
||||||
@@ -86,8 +82,18 @@ class RemoteAlbumService {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<RemoteAlbum> createAlbum({required String title, required List<String> assetIds, String? description}) async {
|
Future<RemoteAlbum> createAlbum({
|
||||||
final album = await _albumApiRepository.createDriftAlbum(title, description: description, assetIds: assetIds);
|
required String title,
|
||||||
|
required UserDto owner,
|
||||||
|
required List<String> assetIds,
|
||||||
|
String? description,
|
||||||
|
}) async {
|
||||||
|
final album = await _albumApiRepository.createDriftAlbum(
|
||||||
|
title,
|
||||||
|
owner,
|
||||||
|
description: description,
|
||||||
|
assetIds: assetIds,
|
||||||
|
);
|
||||||
await _repository.create(album, assetIds);
|
await _repository.create(album, assetIds);
|
||||||
|
|
||||||
return album;
|
return album;
|
||||||
@@ -101,8 +107,10 @@ class RemoteAlbumService {
|
|||||||
bool? isActivityEnabled,
|
bool? isActivityEnabled,
|
||||||
AlbumAssetOrder? order,
|
AlbumAssetOrder? order,
|
||||||
}) async {
|
}) async {
|
||||||
|
final owner = await _repository.getOwner(albumId);
|
||||||
final updatedAlbum = await _albumApiRepository.updateAlbum(
|
final updatedAlbum = await _albumApiRepository.updateAlbum(
|
||||||
albumId,
|
albumId,
|
||||||
|
owner,
|
||||||
name: name,
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
thumbnailAssetId: thumbnailAssetId,
|
thumbnailAssetId: thumbnailAssetId,
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
|
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
import 'package:immich_mobile/repositories/drift_album_api_repository.dart';
|
||||||
import 'package:immich_mobile/utils/debug_print.dart';
|
import 'package:immich_mobile/utils/debug_print.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
@@ -12,6 +15,7 @@ final syncLinkedAlbumServiceProvider = Provider(
|
|||||||
ref.watch(localAlbumRepository),
|
ref.watch(localAlbumRepository),
|
||||||
ref.watch(remoteAlbumRepository),
|
ref.watch(remoteAlbumRepository),
|
||||||
ref.watch(driftAlbumApiRepositoryProvider),
|
ref.watch(driftAlbumApiRepositoryProvider),
|
||||||
|
ref.watch(storeServiceProvider),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -19,8 +23,14 @@ class SyncLinkedAlbumService {
|
|||||||
final DriftLocalAlbumRepository _localAlbumRepository;
|
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||||
final DriftRemoteAlbumRepository _remoteAlbumRepository;
|
final DriftRemoteAlbumRepository _remoteAlbumRepository;
|
||||||
final DriftAlbumApiRepository _albumApiRepository;
|
final DriftAlbumApiRepository _albumApiRepository;
|
||||||
|
final StoreService _storeService;
|
||||||
|
|
||||||
SyncLinkedAlbumService(this._localAlbumRepository, this._remoteAlbumRepository, this._albumApiRepository);
|
SyncLinkedAlbumService(
|
||||||
|
this._localAlbumRepository,
|
||||||
|
this._remoteAlbumRepository,
|
||||||
|
this._albumApiRepository,
|
||||||
|
this._storeService,
|
||||||
|
);
|
||||||
|
|
||||||
final _log = Logger("SyncLinkedAlbumService");
|
final _log = Logger("SyncLinkedAlbumService");
|
||||||
|
|
||||||
@@ -103,7 +113,11 @@ class SyncLinkedAlbumService {
|
|||||||
/// Creates a new remote album and links it to the local album
|
/// Creates a new remote album and links it to the local album
|
||||||
Future<void> _createAndLinkNewRemoteAlbum(LocalAlbum localAlbum) async {
|
Future<void> _createAndLinkNewRemoteAlbum(LocalAlbum localAlbum) async {
|
||||||
dPrint(() => "Creating new remote album for local album: ${localAlbum.name}");
|
dPrint(() => "Creating new remote album for local album: ${localAlbum.name}");
|
||||||
final newRemoteAlbum = await _albumApiRepository.createDriftAlbum(localAlbum.name, assetIds: []);
|
final newRemoteAlbum = await _albumApiRepository.createDriftAlbum(
|
||||||
|
localAlbum.name,
|
||||||
|
_storeService.get(StoreKey.currentUser),
|
||||||
|
assetIds: [],
|
||||||
|
);
|
||||||
await _remoteAlbumRepository.create(newRemoteAlbum, []);
|
await _remoteAlbumRepository.create(newRemoteAlbum, []);
|
||||||
return _localAlbumRepository.linkRemoteAlbum(localAlbum.id, newRemoteAlbum.id);
|
return _localAlbumRepository.linkRemoteAlbum(localAlbum.id, newRemoteAlbum.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
@@ -192,17 +193,22 @@ class SyncStreamService {
|
|||||||
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
||||||
await _syncStreamRepository.updateAssetsV1(remoteSyncAssets);
|
await _syncStreamRepository.updateAssetsV1(remoteSyncAssets);
|
||||||
if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) {
|
if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) {
|
||||||
final hasPermission = await _localFilesManager.hasManageMediaPermission();
|
await _syncAssetTrashStatus(remoteSyncAssets.where((e) => e.deletedAt != null).map((e) => e.id).toList());
|
||||||
if (hasPermission) {
|
}
|
||||||
await _handleRemoteTrashed(remoteSyncAssets.where((e) => e.deletedAt != null).map((e) => e.checksum));
|
return;
|
||||||
await _applyRemoteRestoreToLocal();
|
case SyncEntityType.assetV2:
|
||||||
} else {
|
final remoteSyncAssets = data.cast<SyncAssetV2>();
|
||||||
_logger.warning("sync Trashed Assets cannot proceed because MANAGE_MEDIA permission is missing");
|
await _syncStreamRepository.updateAssetsV2(remoteSyncAssets);
|
||||||
}
|
if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) {
|
||||||
|
await _syncAssetTrashStatus(remoteSyncAssets.where((e) => e.deletedAt != null).map((e) => e.id).toList());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case SyncEntityType.assetDeleteV1:
|
case SyncEntityType.assetDeleteV1:
|
||||||
return _syncStreamRepository.deleteAssetsV1(data.cast());
|
final remoteSyncAssets = data.cast<SyncAssetDeleteV1>();
|
||||||
|
if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) {
|
||||||
|
await _syncAssetDeletion(remoteSyncAssets.map((e) => e.assetId).toList());
|
||||||
|
}
|
||||||
|
return _syncStreamRepository.deleteAssetsV1(remoteSyncAssets);
|
||||||
case SyncEntityType.assetExifV1:
|
case SyncEntityType.assetExifV1:
|
||||||
return _syncStreamRepository.updateAssetsExifV1(data.cast());
|
return _syncStreamRepository.updateAssetsExifV1(data.cast());
|
||||||
case SyncEntityType.assetEditV1:
|
case SyncEntityType.assetEditV1:
|
||||||
@@ -215,8 +221,12 @@ class SyncStreamService {
|
|||||||
return _syncStreamRepository.deleteAssetsMetadataV1(data.cast());
|
return _syncStreamRepository.deleteAssetsMetadataV1(data.cast());
|
||||||
case SyncEntityType.partnerAssetV1:
|
case SyncEntityType.partnerAssetV1:
|
||||||
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'partner');
|
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'partner');
|
||||||
|
case SyncEntityType.partnerAssetV2:
|
||||||
|
return _syncStreamRepository.updateAssetsV2(data.cast(), debugLabel: 'partner');
|
||||||
case SyncEntityType.partnerAssetBackfillV1:
|
case SyncEntityType.partnerAssetBackfillV1:
|
||||||
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'partner backfill');
|
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'partner backfill');
|
||||||
|
case SyncEntityType.partnerAssetBackfillV2:
|
||||||
|
return _syncStreamRepository.updateAssetsV2(data.cast(), debugLabel: 'partner backfill');
|
||||||
case SyncEntityType.partnerAssetDeleteV1:
|
case SyncEntityType.partnerAssetDeleteV1:
|
||||||
return _syncStreamRepository.deleteAssetsV1(data.cast(), debugLabel: "partner");
|
return _syncStreamRepository.deleteAssetsV1(data.cast(), debugLabel: "partner");
|
||||||
case SyncEntityType.partnerAssetExifV1:
|
case SyncEntityType.partnerAssetExifV1:
|
||||||
@@ -225,6 +235,8 @@ class SyncStreamService {
|
|||||||
return _syncStreamRepository.updateAssetsExifV1(data.cast(), debugLabel: 'partner backfill');
|
return _syncStreamRepository.updateAssetsExifV1(data.cast(), debugLabel: 'partner backfill');
|
||||||
case SyncEntityType.albumV1:
|
case SyncEntityType.albumV1:
|
||||||
return _syncStreamRepository.updateAlbumsV1(data.cast());
|
return _syncStreamRepository.updateAlbumsV1(data.cast());
|
||||||
|
case SyncEntityType.albumV2:
|
||||||
|
return _syncStreamRepository.updateAlbumsV2(data.cast());
|
||||||
case SyncEntityType.albumDeleteV1:
|
case SyncEntityType.albumDeleteV1:
|
||||||
return _syncStreamRepository.deleteAlbumsV1(data.cast());
|
return _syncStreamRepository.deleteAlbumsV1(data.cast());
|
||||||
case SyncEntityType.albumUserV1:
|
case SyncEntityType.albumUserV1:
|
||||||
@@ -235,10 +247,16 @@ class SyncStreamService {
|
|||||||
return _syncStreamRepository.deleteAlbumUsersV1(data.cast());
|
return _syncStreamRepository.deleteAlbumUsersV1(data.cast());
|
||||||
case SyncEntityType.albumAssetCreateV1:
|
case SyncEntityType.albumAssetCreateV1:
|
||||||
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset create');
|
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset create');
|
||||||
|
case SyncEntityType.albumAssetCreateV2:
|
||||||
|
return _syncStreamRepository.updateAssetsV2(data.cast(), debugLabel: 'album asset create');
|
||||||
case SyncEntityType.albumAssetUpdateV1:
|
case SyncEntityType.albumAssetUpdateV1:
|
||||||
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset update');
|
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset update');
|
||||||
|
case SyncEntityType.albumAssetUpdateV2:
|
||||||
|
return _syncStreamRepository.updateAssetsV2(data.cast(), debugLabel: 'album asset update');
|
||||||
case SyncEntityType.albumAssetBackfillV1:
|
case SyncEntityType.albumAssetBackfillV1:
|
||||||
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset backfill');
|
return _syncStreamRepository.updateAssetsV1(data.cast(), debugLabel: 'album asset backfill');
|
||||||
|
case SyncEntityType.albumAssetBackfillV2:
|
||||||
|
return _syncStreamRepository.updateAssetsV2(data.cast(), debugLabel: 'album asset backfill');
|
||||||
case SyncEntityType.albumAssetExifCreateV1:
|
case SyncEntityType.albumAssetExifCreateV1:
|
||||||
return _syncStreamRepository.updateAssetsExifV1(data.cast(), debugLabel: 'album asset exif create');
|
return _syncStreamRepository.updateAssetsExifV1(data.cast(), debugLabel: 'album asset exif create');
|
||||||
case SyncEntityType.albumAssetExifUpdateV1:
|
case SyncEntityType.albumAssetExifUpdateV1:
|
||||||
@@ -340,6 +358,47 @@ class SyncStreamService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> handleWsAssetUploadReadyV2Batch(List<dynamic> batchData) async {
|
||||||
|
if (batchData.isEmpty) return;
|
||||||
|
|
||||||
|
_logger.info('Processing batch of ${batchData.length} AssetUploadReadyV2 events');
|
||||||
|
|
||||||
|
final List<SyncAssetV2> assets = [];
|
||||||
|
final List<SyncAssetExifV1> exifs = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (final data in batchData) {
|
||||||
|
if (data is! Map<String, dynamic>) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final payload = data;
|
||||||
|
final assetData = payload['asset'];
|
||||||
|
final exifData = payload['exif'];
|
||||||
|
|
||||||
|
if (assetData == null || exifData == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final asset = SyncAssetV2.fromJson(assetData);
|
||||||
|
final exif = SyncAssetExifV1.fromJson(exifData);
|
||||||
|
|
||||||
|
if (asset != null && exif != null) {
|
||||||
|
assets.add(asset);
|
||||||
|
exifs.add(exif);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assets.isNotEmpty && exifs.isNotEmpty) {
|
||||||
|
await _syncStreamRepository.updateAssetsV2(assets, debugLabel: 'websocket-batch');
|
||||||
|
await _syncStreamRepository.updateAssetsExifV1(exifs, debugLabel: 'websocket-batch');
|
||||||
|
_logger.info('Successfully processed ${assets.length} assets in batch');
|
||||||
|
}
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
_logger.severe("Error processing AssetUploadReadyV2 websocket batch events", error, stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> handleWsAssetEditReadyV1(dynamic data) async {
|
Future<void> handleWsAssetEditReadyV1(dynamic data) async {
|
||||||
_logger.info('Processing AssetEditReadyV1 event');
|
_logger.info('Processing AssetEditReadyV1 event');
|
||||||
|
|
||||||
@@ -380,28 +439,67 @@ class SyncStreamService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleRemoteTrashed(Iterable<String> checksums) async {
|
Future<void> handleWsAssetEditReadyV2(dynamic data) async {
|
||||||
if (checksums.isEmpty) {
|
_logger.info('Processing AssetEditReadyV2 event');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (data is! Map<String, dynamic>) {
|
||||||
|
throw ArgumentError("Invalid data format for AssetEditReadyV2 event");
|
||||||
|
}
|
||||||
|
|
||||||
|
final payload = data;
|
||||||
|
|
||||||
|
if (payload['asset'] == null) {
|
||||||
|
throw ArgumentError("Missing 'asset' field in AssetEditReadyV2 event data");
|
||||||
|
}
|
||||||
|
|
||||||
|
final asset = SyncAssetV2.fromJson(payload['asset']);
|
||||||
|
if (asset == null) {
|
||||||
|
throw ArgumentError("Failed to parse 'asset' field in AssetEditReadyV2 event data");
|
||||||
|
}
|
||||||
|
|
||||||
|
final assetEdits = (payload['edit'] as List<dynamic>)
|
||||||
|
.map((e) => SyncAssetEditV1.fromJson(e))
|
||||||
|
.whereType<SyncAssetEditV1>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
await _syncStreamRepository.updateAssetsV2([asset], debugLabel: 'websocket-edit');
|
||||||
|
await _syncStreamRepository.replaceAssetEditsV1(asset.id, assetEdits, debugLabel: 'websocket-edit');
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
'Successfully processed AssetEditReadyV2 event for asset ${asset.id} with ${assetEdits.length} edits',
|
||||||
|
);
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
_logger.severe("Error processing AssetEditReadyV2 websocket event", error, stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleRemoteDeleted(Iterable<String> remoteIds) async {
|
||||||
|
if (remoteIds.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
} else {
|
} else {
|
||||||
final localAssetsToTrash = await _localAssetRepository.getAssetsFromBackupAlbums(checksums);
|
final localAssetsToTrash = await _localAssetRepository.getAssetsFromBackupAlbums(remoteIds);
|
||||||
if (localAssetsToTrash.isNotEmpty) {
|
if (localAssetsToTrash.isNotEmpty) {
|
||||||
final mediaUrls = await Future.wait(
|
await _trashLocalAssets(localAssetsToTrash);
|
||||||
localAssetsToTrash.values
|
|
||||||
.expand((e) => e)
|
|
||||||
.map((localAsset) => _storageRepository.getAssetEntityForAsset(localAsset).then((e) => e?.getMediaUrl())),
|
|
||||||
);
|
|
||||||
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
|
||||||
final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
|
||||||
if (result) {
|
|
||||||
await _trashedLocalAssetRepository.trashLocalAsset(localAssetsToTrash);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_logger.info("No assets found in backup-enabled albums for assets: $checksums");
|
_logger.info("No assets found in backup-enabled albums for remote assets: $remoteIds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _trashLocalAssets(Map<String, List<LocalAsset>> localAssetsToTrash) async {
|
||||||
|
final mediaUrls = await Future.wait(
|
||||||
|
localAssetsToTrash.values
|
||||||
|
.expand((e) => e)
|
||||||
|
.map((localAsset) => _storageRepository.getAssetEntityForAsset(localAsset).then((e) => e?.getMediaUrl())),
|
||||||
|
);
|
||||||
|
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
||||||
|
final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
||||||
|
if (result) {
|
||||||
|
await _trashedLocalAssetRepository.trashLocalAsset(localAssetsToTrash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _applyRemoteRestoreToLocal() async {
|
Future<void> _applyRemoteRestoreToLocal() async {
|
||||||
final assetsToRestore = await _trashedLocalAssetRepository.getToRestore();
|
final assetsToRestore = await _trashedLocalAssetRepository.getToRestore();
|
||||||
if (assetsToRestore.isNotEmpty) {
|
if (assetsToRestore.isNotEmpty) {
|
||||||
@@ -411,4 +509,23 @@ class SyncStreamService {
|
|||||||
_logger.info("No remote assets found for restoration");
|
_logger.info("No remote assets found for restoration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _syncAssetTrashStatus(List<String> remoteIds) async {
|
||||||
|
if (!(await _localFilesManager.hasManageMediaPermission())) {
|
||||||
|
_logger.warning("Syncing asset trash status cannot proceed because MANAGE_MEDIA permission is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _handleRemoteDeleted(remoteIds);
|
||||||
|
await _applyRemoteRestoreToLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _syncAssetDeletion(List<String> remoteIds) async {
|
||||||
|
if (!(await _localFilesManager.hasManageMediaPermission())) {
|
||||||
|
_logger.warning("Syncing asset deletion cannot proceed because MANAGE_MEDIA permission is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _handleRemoteDeleted(remoteIds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/events.model.dart';
|
import 'package:immich_mobile/domain/models/events.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/setting.model.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/setting.service.dart';
|
|
||||||
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||||
import 'package:immich_mobile/utils/async_mutex.dart';
|
import 'package:immich_mobile/utils/async_mutex.dart';
|
||||||
|
|
||||||
@@ -39,14 +38,16 @@ enum TimelineOrigin {
|
|||||||
|
|
||||||
class TimelineFactory {
|
class TimelineFactory {
|
||||||
final DriftTimelineRepository _timelineRepository;
|
final DriftTimelineRepository _timelineRepository;
|
||||||
final SettingsService _settingsService;
|
final MetadataRepository _metadataRepository;
|
||||||
|
|
||||||
const TimelineFactory({required DriftTimelineRepository timelineRepository, required SettingsService settingsService})
|
const TimelineFactory({
|
||||||
: _timelineRepository = timelineRepository,
|
required DriftTimelineRepository timelineRepository,
|
||||||
_settingsService = settingsService;
|
required MetadataRepository metadataRepository,
|
||||||
|
}) : _timelineRepository = timelineRepository,
|
||||||
|
_metadataRepository = metadataRepository;
|
||||||
|
|
||||||
GroupAssetsBy get groupBy {
|
GroupAssetsBy get groupBy {
|
||||||
final group = GroupAssetsBy.values[_settingsService.get(Setting.groupAssetsBy)];
|
final group = _metadataRepository.appConfig.timeline.groupAssetsBy;
|
||||||
// We do not support auto grouping in the new timeline yet, fallback to day grouping
|
// We do not support auto grouping in the new timeline yet, fallback to day grouping
|
||||||
return group == GroupAssetsBy.auto ? GroupAssetsBy.day : group;
|
return group == GroupAssetsBy.auto ? GroupAssetsBy.day : group;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ class BackgroundSyncManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> syncWebsocketBatch(List<dynamic> batchData) {
|
Future<void> syncWebsocketBatchV1(List<dynamic> batchData) {
|
||||||
if (_syncWebsocketTask != null) {
|
if (_syncWebsocketTask != null) {
|
||||||
return _syncWebsocketTask!.future;
|
return _syncWebsocketTask!.future;
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,17 @@ class BackgroundSyncManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> syncWebsocketEdit(dynamic data) {
|
Future<void> syncWebsocketBatchV2(List<dynamic> batchData) {
|
||||||
|
if (_syncWebsocketTask != null) {
|
||||||
|
return _syncWebsocketTask!.future;
|
||||||
|
}
|
||||||
|
_syncWebsocketTask = _handleWsAssetUploadReadyV2Batch(batchData);
|
||||||
|
return _syncWebsocketTask!.whenComplete(() {
|
||||||
|
_syncWebsocketTask = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> syncWebsocketEditV1(dynamic data) {
|
||||||
if (_syncWebsocketTask != null) {
|
if (_syncWebsocketTask != null) {
|
||||||
return _syncWebsocketTask!.future;
|
return _syncWebsocketTask!.future;
|
||||||
}
|
}
|
||||||
@@ -206,6 +216,16 @@ class BackgroundSyncManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> syncWebsocketEditV2(dynamic data) {
|
||||||
|
if (_syncWebsocketTask != null) {
|
||||||
|
return _syncWebsocketTask!.future;
|
||||||
|
}
|
||||||
|
_syncWebsocketTask = _handleWsAssetEditReadyV2(data);
|
||||||
|
return _syncWebsocketTask!.whenComplete(() {
|
||||||
|
_syncWebsocketTask = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> syncLinkedAlbum() {
|
Future<void> syncLinkedAlbum() {
|
||||||
if (_linkedAlbumSyncTask != null) {
|
if (_linkedAlbumSyncTask != null) {
|
||||||
return _linkedAlbumSyncTask!.future;
|
return _linkedAlbumSyncTask!.future;
|
||||||
@@ -242,7 +262,17 @@ Cancelable<void> _handleWsAssetUploadReadyV1Batch(List<dynamic> batchData) => ru
|
|||||||
debugLabel: 'websocket-batch',
|
debugLabel: 'websocket-batch',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Cancelable<void> _handleWsAssetUploadReadyV2Batch(List<dynamic> batchData) => runInIsolateGentle(
|
||||||
|
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetUploadReadyV2Batch(batchData),
|
||||||
|
debugLabel: 'websocket-batch',
|
||||||
|
);
|
||||||
|
|
||||||
Cancelable<void> _handleWsAssetEditReadyV1(dynamic data) => runInIsolateGentle(
|
Cancelable<void> _handleWsAssetEditReadyV1(dynamic data) => runInIsolateGentle(
|
||||||
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetEditReadyV1(data),
|
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetEditReadyV1(data),
|
||||||
debugLabel: 'websocket-edit',
|
debugLabel: 'websocket-edit',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Cancelable<void> _handleWsAssetEditReadyV2(dynamic data) => runInIsolateGentle(
|
||||||
|
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetEditReadyV2(data),
|
||||||
|
debugLabel: 'websocket-edit',
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
import 'package:immich_mobile/domain/models/exif.model.dart';
|
||||||
import 'package:immich_mobile/extensions/string_extensions.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
|
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
|
||||||
import 'package:openapi/api.dart' as api;
|
import 'package:openapi/api.dart' as api;
|
||||||
|
|
||||||
@@ -14,7 +13,7 @@ extension DTOToAsset on api.AssetResponseDto {
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
ownerId: ownerId,
|
ownerId: ownerId,
|
||||||
visibility: visibility.toAssetVisibility(),
|
visibility: visibility.toAssetVisibility(),
|
||||||
durationInSeconds: duration?.toDuration()?.inSeconds ?? 0,
|
durationMs: duration,
|
||||||
height: height?.toInt(),
|
height: height?.toInt(),
|
||||||
width: width?.toInt(),
|
width: width?.toInt(),
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
@@ -36,7 +35,7 @@ extension DTOToAsset on api.AssetResponseDto {
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
ownerId: ownerId,
|
ownerId: ownerId,
|
||||||
visibility: visibility.toAssetVisibility(),
|
visibility: visibility.toAssetVisibility(),
|
||||||
durationInSeconds: duration?.toDuration()?.inSeconds ?? 0,
|
durationMs: duration,
|
||||||
height: height?.toInt(),
|
height: height?.toInt(),
|
||||||
width: width?.toInt(),
|
width: width?.toInt(),
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
|
|||||||
@@ -4,14 +4,21 @@ extension StringExtension on String {
|
|||||||
String capitalize() {
|
String capitalize() {
|
||||||
return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" ");
|
return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? get nullIfEmpty => isEmpty ? null : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DurationExtension on String {
|
extension DurationExtension on String {
|
||||||
/// Parses and returns the string of format HH:MM:SS as a duration object else null
|
/// Parses and returns the string of format HH:MM:SS.ffffff as a duration object else null
|
||||||
Duration? toDuration() {
|
Duration? toDuration() {
|
||||||
try {
|
try {
|
||||||
final parts = split(':').map((e) => double.parse(e).toInt()).toList(growable: false);
|
final parts = split(':');
|
||||||
return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]);
|
final hours = double.parse(parts[0]).toInt();
|
||||||
|
final minutes = double.parse(parts[1]).toInt();
|
||||||
|
final secondsParts = parts[2].split('.');
|
||||||
|
final seconds = int.parse(secondsParts[0]);
|
||||||
|
final milliseconds = secondsParts.length > 1 ? (double.parse('0.${secondsParts[1]}') * 1000).round() : 0;
|
||||||
|
return Duration(hours: hours, minutes: minutes, seconds: seconds, milliseconds: milliseconds);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData {
|
|||||||
type: type,
|
type: type,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
height: height,
|
height: height,
|
||||||
width: width,
|
width: width,
|
||||||
|
|||||||
+52
-57
@@ -16,7 +16,7 @@ typedef $$LocalAssetEntityTableCreateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
required String id,
|
required String id,
|
||||||
i0.Value<String?> checksum,
|
i0.Value<String?> checksum,
|
||||||
i0.Value<bool> isFavorite,
|
i0.Value<bool> isFavorite,
|
||||||
@@ -35,7 +35,7 @@ typedef $$LocalAssetEntityTableUpdateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
i0.Value<String> id,
|
i0.Value<String> id,
|
||||||
i0.Value<String?> checksum,
|
i0.Value<String?> checksum,
|
||||||
i0.Value<bool> isFavorite,
|
i0.Value<bool> isFavorite,
|
||||||
@@ -87,8 +87,8 @@ class $$LocalAssetEntityTableFilterComposer
|
|||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnFilters<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnFilters<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -182,8 +182,8 @@ class $$LocalAssetEntityTableOrderingComposer
|
|||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnOrderings<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnOrderings<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -260,8 +260,8 @@ class $$LocalAssetEntityTableAnnotationComposer
|
|||||||
i0.GeneratedColumn<int> get height =>
|
i0.GeneratedColumn<int> get height =>
|
||||||
$composableBuilder(column: $table.height, builder: (column) => column);
|
$composableBuilder(column: $table.height, builder: (column) => column);
|
||||||
|
|
||||||
i0.GeneratedColumn<int> get durationInSeconds => $composableBuilder(
|
i0.GeneratedColumn<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ class $$LocalAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
i0.Value<String> id = const i0.Value.absent(),
|
i0.Value<String> id = const i0.Value.absent(),
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
||||||
@@ -366,7 +366,7 @@ class $$LocalAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
@@ -385,7 +385,7 @@ class $$LocalAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
||||||
@@ -403,7 +403,7 @@ class $$LocalAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
@@ -522,17 +522,17 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
|
|||||||
type: i0.DriftSqlType.int,
|
type: i0.DriftSqlType.int,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
static const i0.VerificationMeta _durationInSecondsMeta =
|
static const i0.VerificationMeta _durationMsMeta = const i0.VerificationMeta(
|
||||||
const i0.VerificationMeta('durationInSeconds');
|
'durationMs',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<int> durationInSeconds =
|
late final i0.GeneratedColumn<int> durationMs = i0.GeneratedColumn<int>(
|
||||||
i0.GeneratedColumn<int>(
|
'duration_ms',
|
||||||
'duration_in_seconds',
|
aliasedName,
|
||||||
aliasedName,
|
true,
|
||||||
true,
|
type: i0.DriftSqlType.int,
|
||||||
type: i0.DriftSqlType.int,
|
requiredDuringInsert: false,
|
||||||
requiredDuringInsert: false,
|
);
|
||||||
);
|
|
||||||
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
||||||
@@ -645,7 +645,7 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
checksum,
|
checksum,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
@@ -700,13 +700,10 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
|
|||||||
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('duration_in_seconds')) {
|
if (data.containsKey('duration_ms')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_durationInSecondsMeta,
|
_durationMsMeta,
|
||||||
durationInSeconds.isAcceptableOrUnknown(
|
durationMs.isAcceptableOrUnknown(data['duration_ms']!, _durationMsMeta),
|
||||||
data['duration_in_seconds']!,
|
|
||||||
_durationInSecondsMeta,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('id')) {
|
if (data.containsKey('id')) {
|
||||||
@@ -800,9 +797,9 @@ class $LocalAssetEntityTable extends i3.LocalAssetEntity
|
|||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}height'],
|
data['${effectivePrefix}height'],
|
||||||
),
|
),
|
||||||
durationInSeconds: attachedDatabase.typeMapping.read(
|
durationMs: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}duration_in_seconds'],
|
data['${effectivePrefix}duration_ms'],
|
||||||
),
|
),
|
||||||
id: attachedDatabase.typeMapping.read(
|
id: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
@@ -870,7 +867,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? width;
|
final int? width;
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? durationInSeconds;
|
final int? durationMs;
|
||||||
final String id;
|
final String id;
|
||||||
final String? checksum;
|
final String? checksum;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
@@ -887,7 +884,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.durationInSeconds,
|
this.durationMs,
|
||||||
required this.id,
|
required this.id,
|
||||||
this.checksum,
|
this.checksum,
|
||||||
required this.isFavorite,
|
required this.isFavorite,
|
||||||
@@ -915,8 +912,8 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
if (!nullToAbsent || height != null) {
|
if (!nullToAbsent || height != null) {
|
||||||
map['height'] = i0.Variable<int>(height);
|
map['height'] = i0.Variable<int>(height);
|
||||||
}
|
}
|
||||||
if (!nullToAbsent || durationInSeconds != null) {
|
if (!nullToAbsent || durationMs != null) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds);
|
map['duration_ms'] = i0.Variable<int>(durationMs);
|
||||||
}
|
}
|
||||||
map['id'] = i0.Variable<String>(id);
|
map['id'] = i0.Variable<String>(id);
|
||||||
if (!nullToAbsent || checksum != null) {
|
if (!nullToAbsent || checksum != null) {
|
||||||
@@ -958,7 +955,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
width: serializer.fromJson<int?>(json['width']),
|
width: serializer.fromJson<int?>(json['width']),
|
||||||
height: serializer.fromJson<int?>(json['height']),
|
height: serializer.fromJson<int?>(json['height']),
|
||||||
durationInSeconds: serializer.fromJson<int?>(json['durationInSeconds']),
|
durationMs: serializer.fromJson<int?>(json['durationMs']),
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
checksum: serializer.fromJson<String?>(json['checksum']),
|
checksum: serializer.fromJson<String?>(json['checksum']),
|
||||||
isFavorite: serializer.fromJson<bool>(json['isFavorite']),
|
isFavorite: serializer.fromJson<bool>(json['isFavorite']),
|
||||||
@@ -984,7 +981,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
'width': serializer.toJson<int?>(width),
|
'width': serializer.toJson<int?>(width),
|
||||||
'height': serializer.toJson<int?>(height),
|
'height': serializer.toJson<int?>(height),
|
||||||
'durationInSeconds': serializer.toJson<int?>(durationInSeconds),
|
'durationMs': serializer.toJson<int?>(durationMs),
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'checksum': serializer.toJson<String?>(checksum),
|
'checksum': serializer.toJson<String?>(checksum),
|
||||||
'isFavorite': serializer.toJson<bool>(isFavorite),
|
'isFavorite': serializer.toJson<bool>(isFavorite),
|
||||||
@@ -1006,7 +1003,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
String? id,
|
String? id,
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
bool? isFavorite,
|
bool? isFavorite,
|
||||||
@@ -1023,9 +1020,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width.present ? width.value : this.width,
|
width: width.present ? width.value : this.width,
|
||||||
height: height.present ? height.value : this.height,
|
height: height.present ? height.value : this.height,
|
||||||
durationInSeconds: durationInSeconds.present
|
durationMs: durationMs.present ? durationMs.value : this.durationMs,
|
||||||
? durationInSeconds.value
|
|
||||||
: this.durationInSeconds,
|
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
checksum: checksum.present ? checksum.value : this.checksum,
|
checksum: checksum.present ? checksum.value : this.checksum,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
@@ -1046,9 +1041,9 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
width: data.width.present ? data.width.value : this.width,
|
width: data.width.present ? data.width.value : this.width,
|
||||||
height: data.height.present ? data.height.value : this.height,
|
height: data.height.present ? data.height.value : this.height,
|
||||||
durationInSeconds: data.durationInSeconds.present
|
durationMs: data.durationMs.present
|
||||||
? data.durationInSeconds.value
|
? data.durationMs.value
|
||||||
: this.durationInSeconds,
|
: this.durationMs,
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
||||||
isFavorite: data.isFavorite.present
|
isFavorite: data.isFavorite.present
|
||||||
@@ -1078,7 +1073,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
..write('isFavorite: $isFavorite, ')
|
..write('isFavorite: $isFavorite, ')
|
||||||
@@ -1100,7 +1095,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
checksum,
|
checksum,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
@@ -1121,7 +1116,7 @@ class LocalAssetEntityData extends i0.DataClass
|
|||||||
other.updatedAt == this.updatedAt &&
|
other.updatedAt == this.updatedAt &&
|
||||||
other.width == this.width &&
|
other.width == this.width &&
|
||||||
other.height == this.height &&
|
other.height == this.height &&
|
||||||
other.durationInSeconds == this.durationInSeconds &&
|
other.durationMs == this.durationMs &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.checksum == this.checksum &&
|
other.checksum == this.checksum &&
|
||||||
other.isFavorite == this.isFavorite &&
|
other.isFavorite == this.isFavorite &&
|
||||||
@@ -1141,7 +1136,7 @@ class LocalAssetEntityCompanion
|
|||||||
final i0.Value<DateTime> updatedAt;
|
final i0.Value<DateTime> updatedAt;
|
||||||
final i0.Value<int?> width;
|
final i0.Value<int?> width;
|
||||||
final i0.Value<int?> height;
|
final i0.Value<int?> height;
|
||||||
final i0.Value<int?> durationInSeconds;
|
final i0.Value<int?> durationMs;
|
||||||
final i0.Value<String> id;
|
final i0.Value<String> id;
|
||||||
final i0.Value<String?> checksum;
|
final i0.Value<String?> checksum;
|
||||||
final i0.Value<bool> isFavorite;
|
final i0.Value<bool> isFavorite;
|
||||||
@@ -1158,7 +1153,7 @@ class LocalAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
this.id = const i0.Value.absent(),
|
this.id = const i0.Value.absent(),
|
||||||
this.checksum = const i0.Value.absent(),
|
this.checksum = const i0.Value.absent(),
|
||||||
this.isFavorite = const i0.Value.absent(),
|
this.isFavorite = const i0.Value.absent(),
|
||||||
@@ -1176,7 +1171,7 @@ class LocalAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
this.checksum = const i0.Value.absent(),
|
this.checksum = const i0.Value.absent(),
|
||||||
this.isFavorite = const i0.Value.absent(),
|
this.isFavorite = const i0.Value.absent(),
|
||||||
@@ -1196,7 +1191,7 @@ class LocalAssetEntityCompanion
|
|||||||
i0.Expression<DateTime>? updatedAt,
|
i0.Expression<DateTime>? updatedAt,
|
||||||
i0.Expression<int>? width,
|
i0.Expression<int>? width,
|
||||||
i0.Expression<int>? height,
|
i0.Expression<int>? height,
|
||||||
i0.Expression<int>? durationInSeconds,
|
i0.Expression<int>? durationMs,
|
||||||
i0.Expression<String>? id,
|
i0.Expression<String>? id,
|
||||||
i0.Expression<String>? checksum,
|
i0.Expression<String>? checksum,
|
||||||
i0.Expression<bool>? isFavorite,
|
i0.Expression<bool>? isFavorite,
|
||||||
@@ -1214,7 +1209,7 @@ class LocalAssetEntityCompanion
|
|||||||
if (updatedAt != null) 'updated_at': updatedAt,
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
if (width != null) 'width': width,
|
if (width != null) 'width': width,
|
||||||
if (height != null) 'height': height,
|
if (height != null) 'height': height,
|
||||||
if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds,
|
if (durationMs != null) 'duration_ms': durationMs,
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (checksum != null) 'checksum': checksum,
|
if (checksum != null) 'checksum': checksum,
|
||||||
if (isFavorite != null) 'is_favorite': isFavorite,
|
if (isFavorite != null) 'is_favorite': isFavorite,
|
||||||
@@ -1234,7 +1229,7 @@ class LocalAssetEntityCompanion
|
|||||||
i0.Value<DateTime>? updatedAt,
|
i0.Value<DateTime>? updatedAt,
|
||||||
i0.Value<int?>? width,
|
i0.Value<int?>? width,
|
||||||
i0.Value<int?>? height,
|
i0.Value<int?>? height,
|
||||||
i0.Value<int?>? durationInSeconds,
|
i0.Value<int?>? durationMs,
|
||||||
i0.Value<String>? id,
|
i0.Value<String>? id,
|
||||||
i0.Value<String?>? checksum,
|
i0.Value<String?>? checksum,
|
||||||
i0.Value<bool>? isFavorite,
|
i0.Value<bool>? isFavorite,
|
||||||
@@ -1252,7 +1247,7 @@ class LocalAssetEntityCompanion
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
checksum: checksum ?? this.checksum,
|
checksum: checksum ?? this.checksum,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
@@ -1288,8 +1283,8 @@ class LocalAssetEntityCompanion
|
|||||||
if (height.present) {
|
if (height.present) {
|
||||||
map['height'] = i0.Variable<int>(height.value);
|
map['height'] = i0.Variable<int>(height.value);
|
||||||
}
|
}
|
||||||
if (durationInSeconds.present) {
|
if (durationMs.present) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds.value);
|
map['duration_ms'] = i0.Variable<int>(durationMs.value);
|
||||||
}
|
}
|
||||||
if (id.present) {
|
if (id.present) {
|
||||||
map['id'] = i0.Variable<String>(id.value);
|
map['id'] = i0.Variable<String>(id.value);
|
||||||
@@ -1334,7 +1329,7 @@ class LocalAssetEntityCompanion
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
..write('isFavorite: $isFavorite, ')
|
..write('isFavorite: $isFavorite, ')
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SELECT
|
|||||||
rae.updated_at,
|
rae.updated_at,
|
||||||
rae.width,
|
rae.width,
|
||||||
rae.height,
|
rae.height,
|
||||||
rae.duration_in_seconds,
|
rae.duration_ms,
|
||||||
rae.is_favorite,
|
rae.is_favorite,
|
||||||
rae.thumb_hash,
|
rae.thumb_hash,
|
||||||
rae.checksum,
|
rae.checksum,
|
||||||
@@ -52,7 +52,7 @@ SELECT
|
|||||||
lae.updated_at,
|
lae.updated_at,
|
||||||
lae.width,
|
lae.width,
|
||||||
lae.height,
|
lae.height,
|
||||||
lae.duration_in_seconds,
|
lae.duration_ms,
|
||||||
lae.is_favorite,
|
lae.is_favorite,
|
||||||
NULL as thumb_hash,
|
NULL as thumb_hash,
|
||||||
lae.checksum,
|
lae.checksum,
|
||||||
|
|||||||
+4
-4
@@ -29,7 +29,7 @@ class MergedAssetDrift extends i1.ModularAccessor {
|
|||||||
);
|
);
|
||||||
$arrayStartIndex += generatedlimit.amountOfVariables;
|
$arrayStartIndex += generatedlimit.amountOfVariables;
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_in_seconds, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime, rae.is_edited, 0 AS playback_style FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_in_seconds, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time, 0 AS is_edited, lae.playback_style FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
|
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_ms, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime, rae.is_edited, 0 AS playback_style FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_ms, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time, 0 AS is_edited, lae.playback_style FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
|
||||||
variables: [
|
variables: [
|
||||||
for (var $ in userIds) i0.Variable<String>($),
|
for (var $ in userIds) i0.Variable<String>($),
|
||||||
...generatedlimit.introducedVariables,
|
...generatedlimit.introducedVariables,
|
||||||
@@ -54,7 +54,7 @@ class MergedAssetDrift extends i1.ModularAccessor {
|
|||||||
updatedAt: row.read<DateTime>('updated_at'),
|
updatedAt: row.read<DateTime>('updated_at'),
|
||||||
width: row.readNullable<int>('width'),
|
width: row.readNullable<int>('width'),
|
||||||
height: row.readNullable<int>('height'),
|
height: row.readNullable<int>('height'),
|
||||||
durationInSeconds: row.readNullable<int>('duration_in_seconds'),
|
durationMs: row.readNullable<int>('duration_ms'),
|
||||||
isFavorite: row.read<bool>('is_favorite'),
|
isFavorite: row.read<bool>('is_favorite'),
|
||||||
thumbHash: row.readNullable<String>('thumb_hash'),
|
thumbHash: row.readNullable<String>('thumb_hash'),
|
||||||
checksum: row.readNullable<String>('checksum'),
|
checksum: row.readNullable<String>('checksum'),
|
||||||
@@ -127,7 +127,7 @@ class MergedAssetResult {
|
|||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? width;
|
final int? width;
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? durationInSeconds;
|
final int? durationMs;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
final String? thumbHash;
|
final String? thumbHash;
|
||||||
final String? checksum;
|
final String? checksum;
|
||||||
@@ -150,7 +150,7 @@ class MergedAssetResult {
|
|||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.durationInSeconds,
|
this.durationMs,
|
||||||
required this.isFavorite,
|
required this.isFavorite,
|
||||||
this.thumbHash,
|
this.thumbHash,
|
||||||
this.checksum,
|
this.checksum,
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
|
class MetadataEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const MetadataEntity();
|
||||||
|
|
||||||
|
TextColumn get key => text()();
|
||||||
|
|
||||||
|
TextColumn get value => text()();
|
||||||
|
|
||||||
|
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {key};
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tableName => "metadata";
|
||||||
|
}
|
||||||
@@ -0,0 +1,429 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart' as i0;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'
|
||||||
|
as i1;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.dart'
|
||||||
|
as i2;
|
||||||
|
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3;
|
||||||
|
|
||||||
|
typedef $$MetadataEntityTableCreateCompanionBuilder =
|
||||||
|
i1.MetadataEntityCompanion Function({
|
||||||
|
required String key,
|
||||||
|
required String value,
|
||||||
|
i0.Value<DateTime> updatedAt,
|
||||||
|
});
|
||||||
|
typedef $$MetadataEntityTableUpdateCompanionBuilder =
|
||||||
|
i1.MetadataEntityCompanion Function({
|
||||||
|
i0.Value<String> key,
|
||||||
|
i0.Value<String> value,
|
||||||
|
i0.Value<DateTime> updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
class $$MetadataEntityTableFilterComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$MetadataEntityTable> {
|
||||||
|
$$MetadataEntityTableFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnFilters<String> get key => $composableBuilder(
|
||||||
|
column: $table.key,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<String> get value => $composableBuilder(
|
||||||
|
column: $table.value,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<DateTime> get updatedAt => $composableBuilder(
|
||||||
|
column: $table.updatedAt,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$MetadataEntityTableOrderingComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$MetadataEntityTable> {
|
||||||
|
$$MetadataEntityTableOrderingComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnOrderings<String> get key => $composableBuilder(
|
||||||
|
column: $table.key,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<String> get value => $composableBuilder(
|
||||||
|
column: $table.value,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<DateTime> get updatedAt => $composableBuilder(
|
||||||
|
column: $table.updatedAt,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$MetadataEntityTableAnnotationComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$MetadataEntityTable> {
|
||||||
|
$$MetadataEntityTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.GeneratedColumn<String> get key =>
|
||||||
|
$composableBuilder(column: $table.key, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<String> get value =>
|
||||||
|
$composableBuilder(column: $table.value, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<DateTime> get updatedAt =>
|
||||||
|
$composableBuilder(column: $table.updatedAt, builder: (column) => column);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$MetadataEntityTableTableManager
|
||||||
|
extends
|
||||||
|
i0.RootTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$MetadataEntityTable,
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i1.$$MetadataEntityTableFilterComposer,
|
||||||
|
i1.$$MetadataEntityTableOrderingComposer,
|
||||||
|
i1.$$MetadataEntityTableAnnotationComposer,
|
||||||
|
$$MetadataEntityTableCreateCompanionBuilder,
|
||||||
|
$$MetadataEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i0.BaseReferences<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$MetadataEntityTable,
|
||||||
|
i1.MetadataEntityData
|
||||||
|
>,
|
||||||
|
),
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i0.PrefetchHooks Function()
|
||||||
|
> {
|
||||||
|
$$MetadataEntityTableTableManager(
|
||||||
|
i0.GeneratedDatabase db,
|
||||||
|
i1.$MetadataEntityTable table,
|
||||||
|
) : super(
|
||||||
|
i0.TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
createFilteringComposer: () =>
|
||||||
|
i1.$$MetadataEntityTableFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
i1.$$MetadataEntityTableOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () => i1
|
||||||
|
.$$MetadataEntityTableAnnotationComposer($db: db, $table: table),
|
||||||
|
updateCompanionCallback:
|
||||||
|
({
|
||||||
|
i0.Value<String> key = const i0.Value.absent(),
|
||||||
|
i0.Value<String> value = const i0.Value.absent(),
|
||||||
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
|
}) => i1.MetadataEntityCompanion(
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
),
|
||||||
|
createCompanionCallback:
|
||||||
|
({
|
||||||
|
required String key,
|
||||||
|
required String value,
|
||||||
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
|
}) => i1.MetadataEntityCompanion.insert(
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
),
|
||||||
|
withReferenceMapper: (p0) => p0
|
||||||
|
.map((e) => (e.readTable(table), i0.BaseReferences(db, table, e)))
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$MetadataEntityTableProcessedTableManager =
|
||||||
|
i0.ProcessedTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$MetadataEntityTable,
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i1.$$MetadataEntityTableFilterComposer,
|
||||||
|
i1.$$MetadataEntityTableOrderingComposer,
|
||||||
|
i1.$$MetadataEntityTableAnnotationComposer,
|
||||||
|
$$MetadataEntityTableCreateCompanionBuilder,
|
||||||
|
$$MetadataEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i0.BaseReferences<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$MetadataEntityTable,
|
||||||
|
i1.MetadataEntityData
|
||||||
|
>,
|
||||||
|
),
|
||||||
|
i1.MetadataEntityData,
|
||||||
|
i0.PrefetchHooks Function()
|
||||||
|
>;
|
||||||
|
|
||||||
|
class $MetadataEntityTable extends i2.MetadataEntity
|
||||||
|
with i0.TableInfo<$MetadataEntityTable, i1.MetadataEntityData> {
|
||||||
|
@override
|
||||||
|
final i0.GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$MetadataEntityTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const i0.VerificationMeta _keyMeta = const i0.VerificationMeta('key');
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> key = i0.GeneratedColumn<String>(
|
||||||
|
'key',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _valueMeta = const i0.VerificationMeta(
|
||||||
|
'value',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> value = i0.GeneratedColumn<String>(
|
||||||
|
'value',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _updatedAtMeta = const i0.VerificationMeta(
|
||||||
|
'updatedAt',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<DateTime> updatedAt =
|
||||||
|
i0.GeneratedColumn<DateTime>(
|
||||||
|
'updated_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: i3.currentDateAndTime,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<i0.GeneratedColumn> get $columns => [key, value, updatedAt];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'metadata';
|
||||||
|
@override
|
||||||
|
i0.VerificationContext validateIntegrity(
|
||||||
|
i0.Insertable<i1.MetadataEntityData> instance, {
|
||||||
|
bool isInserting = false,
|
||||||
|
}) {
|
||||||
|
final context = i0.VerificationContext();
|
||||||
|
final data = instance.toColumns(true);
|
||||||
|
if (data.containsKey('key')) {
|
||||||
|
context.handle(
|
||||||
|
_keyMeta,
|
||||||
|
key.isAcceptableOrUnknown(data['key']!, _keyMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_keyMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('value')) {
|
||||||
|
context.handle(
|
||||||
|
_valueMeta,
|
||||||
|
value.isAcceptableOrUnknown(data['value']!, _valueMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_valueMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('updated_at')) {
|
||||||
|
context.handle(
|
||||||
|
_updatedAtMeta,
|
||||||
|
updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<i0.GeneratedColumn> get $primaryKey => {key};
|
||||||
|
@override
|
||||||
|
i1.MetadataEntityData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return i1.MetadataEntityData(
|
||||||
|
key: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}key'],
|
||||||
|
)!,
|
||||||
|
value: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}value'],
|
||||||
|
)!,
|
||||||
|
updatedAt: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}updated_at'],
|
||||||
|
)!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$MetadataEntityTable createAlias(String alias) {
|
||||||
|
return $MetadataEntityTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get withoutRowId => true;
|
||||||
|
@override
|
||||||
|
bool get isStrict => true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MetadataEntityData extends i0.DataClass
|
||||||
|
implements i0.Insertable<i1.MetadataEntityData> {
|
||||||
|
final String key;
|
||||||
|
final String value;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
const MetadataEntityData({
|
||||||
|
required this.key,
|
||||||
|
required this.value,
|
||||||
|
required this.updatedAt,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
map['key'] = i0.Variable<String>(key);
|
||||||
|
map['value'] = i0.Variable<String>(value);
|
||||||
|
map['updated_at'] = i0.Variable<DateTime>(updatedAt);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory MetadataEntityData.fromJson(
|
||||||
|
Map<String, dynamic> json, {
|
||||||
|
i0.ValueSerializer? serializer,
|
||||||
|
}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return MetadataEntityData(
|
||||||
|
key: serializer.fromJson<String>(json['key']),
|
||||||
|
value: serializer.fromJson<String>(json['value']),
|
||||||
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'key': serializer.toJson<String>(key),
|
||||||
|
'value': serializer.toJson<String>(value),
|
||||||
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.MetadataEntityData copyWith({
|
||||||
|
String? key,
|
||||||
|
String? value,
|
||||||
|
DateTime? updatedAt,
|
||||||
|
}) => i1.MetadataEntityData(
|
||||||
|
key: key ?? this.key,
|
||||||
|
value: value ?? this.value,
|
||||||
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
);
|
||||||
|
MetadataEntityData copyWithCompanion(i1.MetadataEntityCompanion data) {
|
||||||
|
return MetadataEntityData(
|
||||||
|
key: data.key.present ? data.key.value : this.key,
|
||||||
|
value: data.value.present ? data.value.value : this.value,
|
||||||
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('MetadataEntityData(')
|
||||||
|
..write('key: $key, ')
|
||||||
|
..write('value: $value, ')
|
||||||
|
..write('updatedAt: $updatedAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(key, value, updatedAt);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is i1.MetadataEntityData &&
|
||||||
|
other.key == this.key &&
|
||||||
|
other.value == this.value &&
|
||||||
|
other.updatedAt == this.updatedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MetadataEntityCompanion
|
||||||
|
extends i0.UpdateCompanion<i1.MetadataEntityData> {
|
||||||
|
final i0.Value<String> key;
|
||||||
|
final i0.Value<String> value;
|
||||||
|
final i0.Value<DateTime> updatedAt;
|
||||||
|
const MetadataEntityCompanion({
|
||||||
|
this.key = const i0.Value.absent(),
|
||||||
|
this.value = const i0.Value.absent(),
|
||||||
|
this.updatedAt = const i0.Value.absent(),
|
||||||
|
});
|
||||||
|
MetadataEntityCompanion.insert({
|
||||||
|
required String key,
|
||||||
|
required String value,
|
||||||
|
this.updatedAt = const i0.Value.absent(),
|
||||||
|
}) : key = i0.Value(key),
|
||||||
|
value = i0.Value(value);
|
||||||
|
static i0.Insertable<i1.MetadataEntityData> custom({
|
||||||
|
i0.Expression<String>? key,
|
||||||
|
i0.Expression<String>? value,
|
||||||
|
i0.Expression<DateTime>? updatedAt,
|
||||||
|
}) {
|
||||||
|
return i0.RawValuesInsertable({
|
||||||
|
if (key != null) 'key': key,
|
||||||
|
if (value != null) 'value': value,
|
||||||
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.MetadataEntityCompanion copyWith({
|
||||||
|
i0.Value<String>? key,
|
||||||
|
i0.Value<String>? value,
|
||||||
|
i0.Value<DateTime>? updatedAt,
|
||||||
|
}) {
|
||||||
|
return i1.MetadataEntityCompanion(
|
||||||
|
key: key ?? this.key,
|
||||||
|
value: value ?? this.value,
|
||||||
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
if (key.present) {
|
||||||
|
map['key'] = i0.Variable<String>(key.value);
|
||||||
|
}
|
||||||
|
if (value.present) {
|
||||||
|
map['value'] = i0.Variable<String>(value.value);
|
||||||
|
}
|
||||||
|
if (updatedAt.present) {
|
||||||
|
map['updated_at'] = i0.Variable<DateTime>(updatedAt.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('MetadataEntityCompanion(')
|
||||||
|
..write('key: $key, ')
|
||||||
|
..write('value: $value, ')
|
||||||
|
..write('updatedAt: $updatedAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_remote_album_owner_id ON remote_album_entity (owner_id)')
|
|
||||||
class RemoteAlbumEntity extends Table with DriftDefaultsMixin {
|
class RemoteAlbumEntity extends Table with DriftDefaultsMixin {
|
||||||
const RemoteAlbumEntity();
|
const RemoteAlbumEntity();
|
||||||
|
|
||||||
@@ -18,8 +16,6 @@ class RemoteAlbumEntity extends Table with DriftDefaultsMixin {
|
|||||||
|
|
||||||
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
TextColumn get ownerId => text().references(UserEntity, #id, onDelete: KeyAction.cascade)();
|
|
||||||
|
|
||||||
TextColumn get thumbnailAssetId =>
|
TextColumn get thumbnailAssetId =>
|
||||||
text().references(RemoteAssetEntity, #id, onDelete: KeyAction.setNull).nullable()();
|
text().references(RemoteAssetEntity, #id, onDelete: KeyAction.setNull).nullable()();
|
||||||
|
|
||||||
|
|||||||
+25
-215
@@ -7,11 +7,9 @@ import 'package:immich_mobile/domain/models/album/album.model.dart' as i2;
|
|||||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart'
|
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart'
|
||||||
as i3;
|
as i3;
|
||||||
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i4;
|
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i4;
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart'
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'
|
||||||
as i5;
|
as i5;
|
||||||
import 'package:drift/internal/modular.dart' as i6;
|
import 'package:drift/internal/modular.dart' as i6;
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'
|
|
||||||
as i7;
|
|
||||||
|
|
||||||
typedef $$RemoteAlbumEntityTableCreateCompanionBuilder =
|
typedef $$RemoteAlbumEntityTableCreateCompanionBuilder =
|
||||||
i1.RemoteAlbumEntityCompanion Function({
|
i1.RemoteAlbumEntityCompanion Function({
|
||||||
@@ -20,7 +18,6 @@ typedef $$RemoteAlbumEntityTableCreateCompanionBuilder =
|
|||||||
i0.Value<String> description,
|
i0.Value<String> description,
|
||||||
i0.Value<DateTime> createdAt,
|
i0.Value<DateTime> createdAt,
|
||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
required String ownerId,
|
|
||||||
i0.Value<String?> thumbnailAssetId,
|
i0.Value<String?> thumbnailAssetId,
|
||||||
i0.Value<bool> isActivityEnabled,
|
i0.Value<bool> isActivityEnabled,
|
||||||
required i2.AlbumAssetOrder order,
|
required i2.AlbumAssetOrder order,
|
||||||
@@ -32,7 +29,6 @@ typedef $$RemoteAlbumEntityTableUpdateCompanionBuilder =
|
|||||||
i0.Value<String> description,
|
i0.Value<String> description,
|
||||||
i0.Value<DateTime> createdAt,
|
i0.Value<DateTime> createdAt,
|
||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<String> ownerId,
|
|
||||||
i0.Value<String?> thumbnailAssetId,
|
i0.Value<String?> thumbnailAssetId,
|
||||||
i0.Value<bool> isActivityEnabled,
|
i0.Value<bool> isActivityEnabled,
|
||||||
i0.Value<i2.AlbumAssetOrder> order,
|
i0.Value<i2.AlbumAssetOrder> order,
|
||||||
@@ -51,42 +47,10 @@ final class $$RemoteAlbumEntityTableReferences
|
|||||||
super.$_typedResult,
|
super.$_typedResult,
|
||||||
);
|
);
|
||||||
|
|
||||||
static i5.$UserEntityTable _ownerIdTable(i0.GeneratedDatabase db) =>
|
static i5.$RemoteAssetEntityTable _thumbnailAssetIdTable(
|
||||||
i6.ReadDatabaseContainer(db)
|
|
||||||
.resultSet<i5.$UserEntityTable>('user_entity')
|
|
||||||
.createAlias(
|
|
||||||
i0.$_aliasNameGenerator(
|
|
||||||
i6.ReadDatabaseContainer(db)
|
|
||||||
.resultSet<i1.$RemoteAlbumEntityTable>('remote_album_entity')
|
|
||||||
.ownerId,
|
|
||||||
i6.ReadDatabaseContainer(
|
|
||||||
db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity').id,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
i5.$$UserEntityTableProcessedTableManager get ownerId {
|
|
||||||
final $_column = $_itemColumn<String>('owner_id')!;
|
|
||||||
|
|
||||||
final manager = i5
|
|
||||||
.$$UserEntityTableTableManager(
|
|
||||||
$_db,
|
|
||||||
i6.ReadDatabaseContainer(
|
|
||||||
$_db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
)
|
|
||||||
.filter((f) => f.id.sqlEquals($_column));
|
|
||||||
final item = $_typedResult.readTableOrNull(_ownerIdTable($_db));
|
|
||||||
if (item == null) return manager;
|
|
||||||
return i0.ProcessedTableManager(
|
|
||||||
manager.$state.copyWith(prefetchedData: [item]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static i7.$RemoteAssetEntityTable _thumbnailAssetIdTable(
|
|
||||||
i0.GeneratedDatabase db,
|
i0.GeneratedDatabase db,
|
||||||
) => i6.ReadDatabaseContainer(db)
|
) => i6.ReadDatabaseContainer(db)
|
||||||
.resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity')
|
.resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity')
|
||||||
.createAlias(
|
.createAlias(
|
||||||
i0.$_aliasNameGenerator(
|
i0.$_aliasNameGenerator(
|
||||||
i6.ReadDatabaseContainer(db)
|
i6.ReadDatabaseContainer(db)
|
||||||
@@ -94,19 +58,19 @@ final class $$RemoteAlbumEntityTableReferences
|
|||||||
.thumbnailAssetId,
|
.thumbnailAssetId,
|
||||||
i6.ReadDatabaseContainer(
|
i6.ReadDatabaseContainer(
|
||||||
db,
|
db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity').id,
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity').id,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
i7.$$RemoteAssetEntityTableProcessedTableManager? get thumbnailAssetId {
|
i5.$$RemoteAssetEntityTableProcessedTableManager? get thumbnailAssetId {
|
||||||
final $_column = $_itemColumn<String>('thumbnail_asset_id');
|
final $_column = $_itemColumn<String>('thumbnail_asset_id');
|
||||||
if ($_column == null) return null;
|
if ($_column == null) return null;
|
||||||
final manager = i7
|
final manager = i5
|
||||||
.$$RemoteAssetEntityTableTableManager(
|
.$$RemoteAssetEntityTableTableManager(
|
||||||
$_db,
|
$_db,
|
||||||
i6.ReadDatabaseContainer(
|
i6.ReadDatabaseContainer(
|
||||||
$_db,
|
$_db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
)
|
)
|
||||||
.filter((f) => f.id.sqlEquals($_column));
|
.filter((f) => f.id.sqlEquals($_column));
|
||||||
final item = $_typedResult.readTableOrNull(_thumbnailAssetIdTable($_db));
|
final item = $_typedResult.readTableOrNull(_thumbnailAssetIdTable($_db));
|
||||||
@@ -162,51 +126,24 @@ class $$RemoteAlbumEntityTableFilterComposer
|
|||||||
builder: (column) => i0.ColumnWithTypeConverterFilters(column),
|
builder: (column) => i0.ColumnWithTypeConverterFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i5.$$UserEntityTableFilterComposer get ownerId {
|
i5.$$RemoteAssetEntityTableFilterComposer get thumbnailAssetId {
|
||||||
final i5.$$UserEntityTableFilterComposer composer = $composerBuilder(
|
final i5.$$RemoteAssetEntityTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
|
||||||
getCurrentColumn: (t) => t.ownerId,
|
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
getReferencedColumn: (t) => t.id,
|
|
||||||
builder:
|
|
||||||
(
|
|
||||||
joinBuilder, {
|
|
||||||
$addJoinBuilderToRootComposer,
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
}) => i5.$$UserEntityTableFilterComposer(
|
|
||||||
$db: $db,
|
|
||||||
$table: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
|
||||||
joinBuilder: joinBuilder,
|
|
||||||
$removeJoinBuilderFromRootComposer:
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return composer;
|
|
||||||
}
|
|
||||||
|
|
||||||
i7.$$RemoteAssetEntityTableFilterComposer get thumbnailAssetId {
|
|
||||||
final i7.$$RemoteAssetEntityTableFilterComposer composer = $composerBuilder(
|
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.thumbnailAssetId,
|
getCurrentColumn: (t) => t.thumbnailAssetId,
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
referencedTable: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
getReferencedColumn: (t) => t.id,
|
getReferencedColumn: (t) => t.id,
|
||||||
builder:
|
builder:
|
||||||
(
|
(
|
||||||
joinBuilder, {
|
joinBuilder, {
|
||||||
$addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer,
|
||||||
$removeJoinBuilderFromRootComposer,
|
$removeJoinBuilderFromRootComposer,
|
||||||
}) => i7.$$RemoteAssetEntityTableFilterComposer(
|
}) => i5.$$RemoteAssetEntityTableFilterComposer(
|
||||||
$db: $db,
|
$db: $db,
|
||||||
$table: i6.ReadDatabaseContainer(
|
$table: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
joinBuilder: joinBuilder,
|
joinBuilder: joinBuilder,
|
||||||
$removeJoinBuilderFromRootComposer:
|
$removeJoinBuilderFromRootComposer:
|
||||||
@@ -261,52 +198,25 @@ class $$RemoteAlbumEntityTableOrderingComposer
|
|||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i5.$$UserEntityTableOrderingComposer get ownerId {
|
i5.$$RemoteAssetEntityTableOrderingComposer get thumbnailAssetId {
|
||||||
final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder(
|
final i5.$$RemoteAssetEntityTableOrderingComposer composer =
|
||||||
composer: this,
|
|
||||||
getCurrentColumn: (t) => t.ownerId,
|
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
getReferencedColumn: (t) => t.id,
|
|
||||||
builder:
|
|
||||||
(
|
|
||||||
joinBuilder, {
|
|
||||||
$addJoinBuilderToRootComposer,
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
}) => i5.$$UserEntityTableOrderingComposer(
|
|
||||||
$db: $db,
|
|
||||||
$table: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
|
||||||
joinBuilder: joinBuilder,
|
|
||||||
$removeJoinBuilderFromRootComposer:
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return composer;
|
|
||||||
}
|
|
||||||
|
|
||||||
i7.$$RemoteAssetEntityTableOrderingComposer get thumbnailAssetId {
|
|
||||||
final i7.$$RemoteAssetEntityTableOrderingComposer composer =
|
|
||||||
$composerBuilder(
|
$composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.thumbnailAssetId,
|
getCurrentColumn: (t) => t.thumbnailAssetId,
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
referencedTable: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
getReferencedColumn: (t) => t.id,
|
getReferencedColumn: (t) => t.id,
|
||||||
builder:
|
builder:
|
||||||
(
|
(
|
||||||
joinBuilder, {
|
joinBuilder, {
|
||||||
$addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer,
|
||||||
$removeJoinBuilderFromRootComposer,
|
$removeJoinBuilderFromRootComposer,
|
||||||
}) => i7.$$RemoteAssetEntityTableOrderingComposer(
|
}) => i5.$$RemoteAssetEntityTableOrderingComposer(
|
||||||
$db: $db,
|
$db: $db,
|
||||||
$table: i6.ReadDatabaseContainer(
|
$table: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
joinBuilder: joinBuilder,
|
joinBuilder: joinBuilder,
|
||||||
$removeJoinBuilderFromRootComposer:
|
$removeJoinBuilderFromRootComposer:
|
||||||
@@ -351,52 +261,25 @@ class $$RemoteAlbumEntityTableAnnotationComposer
|
|||||||
i0.GeneratedColumnWithTypeConverter<i2.AlbumAssetOrder, int> get order =>
|
i0.GeneratedColumnWithTypeConverter<i2.AlbumAssetOrder, int> get order =>
|
||||||
$composableBuilder(column: $table.order, builder: (column) => column);
|
$composableBuilder(column: $table.order, builder: (column) => column);
|
||||||
|
|
||||||
i5.$$UserEntityTableAnnotationComposer get ownerId {
|
i5.$$RemoteAssetEntityTableAnnotationComposer get thumbnailAssetId {
|
||||||
final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder(
|
final i5.$$RemoteAssetEntityTableAnnotationComposer composer =
|
||||||
composer: this,
|
|
||||||
getCurrentColumn: (t) => t.ownerId,
|
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
getReferencedColumn: (t) => t.id,
|
|
||||||
builder:
|
|
||||||
(
|
|
||||||
joinBuilder, {
|
|
||||||
$addJoinBuilderToRootComposer,
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
}) => i5.$$UserEntityTableAnnotationComposer(
|
|
||||||
$db: $db,
|
|
||||||
$table: i6.ReadDatabaseContainer(
|
|
||||||
$db,
|
|
||||||
).resultSet<i5.$UserEntityTable>('user_entity'),
|
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
|
||||||
joinBuilder: joinBuilder,
|
|
||||||
$removeJoinBuilderFromRootComposer:
|
|
||||||
$removeJoinBuilderFromRootComposer,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return composer;
|
|
||||||
}
|
|
||||||
|
|
||||||
i7.$$RemoteAssetEntityTableAnnotationComposer get thumbnailAssetId {
|
|
||||||
final i7.$$RemoteAssetEntityTableAnnotationComposer composer =
|
|
||||||
$composerBuilder(
|
$composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.thumbnailAssetId,
|
getCurrentColumn: (t) => t.thumbnailAssetId,
|
||||||
referencedTable: i6.ReadDatabaseContainer(
|
referencedTable: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
getReferencedColumn: (t) => t.id,
|
getReferencedColumn: (t) => t.id,
|
||||||
builder:
|
builder:
|
||||||
(
|
(
|
||||||
joinBuilder, {
|
joinBuilder, {
|
||||||
$addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer,
|
||||||
$removeJoinBuilderFromRootComposer,
|
$removeJoinBuilderFromRootComposer,
|
||||||
}) => i7.$$RemoteAssetEntityTableAnnotationComposer(
|
}) => i5.$$RemoteAssetEntityTableAnnotationComposer(
|
||||||
$db: $db,
|
$db: $db,
|
||||||
$table: i6.ReadDatabaseContainer(
|
$table: i6.ReadDatabaseContainer(
|
||||||
$db,
|
$db,
|
||||||
).resultSet<i7.$RemoteAssetEntityTable>('remote_asset_entity'),
|
).resultSet<i5.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
joinBuilder: joinBuilder,
|
joinBuilder: joinBuilder,
|
||||||
$removeJoinBuilderFromRootComposer:
|
$removeJoinBuilderFromRootComposer:
|
||||||
@@ -420,7 +303,7 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
$$RemoteAlbumEntityTableUpdateCompanionBuilder,
|
$$RemoteAlbumEntityTableUpdateCompanionBuilder,
|
||||||
(i1.RemoteAlbumEntityData, i1.$$RemoteAlbumEntityTableReferences),
|
(i1.RemoteAlbumEntityData, i1.$$RemoteAlbumEntityTableReferences),
|
||||||
i1.RemoteAlbumEntityData,
|
i1.RemoteAlbumEntityData,
|
||||||
i0.PrefetchHooks Function({bool ownerId, bool thumbnailAssetId})
|
i0.PrefetchHooks Function({bool thumbnailAssetId})
|
||||||
> {
|
> {
|
||||||
$$RemoteAlbumEntityTableTableManager(
|
$$RemoteAlbumEntityTableTableManager(
|
||||||
i0.GeneratedDatabase db,
|
i0.GeneratedDatabase db,
|
||||||
@@ -445,7 +328,6 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
i0.Value<String> description = const i0.Value.absent(),
|
i0.Value<String> description = const i0.Value.absent(),
|
||||||
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<String> ownerId = const i0.Value.absent(),
|
|
||||||
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
||||||
i0.Value<bool> isActivityEnabled = const i0.Value.absent(),
|
i0.Value<bool> isActivityEnabled = const i0.Value.absent(),
|
||||||
i0.Value<i2.AlbumAssetOrder> order = const i0.Value.absent(),
|
i0.Value<i2.AlbumAssetOrder> order = const i0.Value.absent(),
|
||||||
@@ -455,7 +337,6 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
description: description,
|
description: description,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
ownerId: ownerId,
|
|
||||||
thumbnailAssetId: thumbnailAssetId,
|
thumbnailAssetId: thumbnailAssetId,
|
||||||
isActivityEnabled: isActivityEnabled,
|
isActivityEnabled: isActivityEnabled,
|
||||||
order: order,
|
order: order,
|
||||||
@@ -467,7 +348,6 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
i0.Value<String> description = const i0.Value.absent(),
|
i0.Value<String> description = const i0.Value.absent(),
|
||||||
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
required String ownerId,
|
|
||||||
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
||||||
i0.Value<bool> isActivityEnabled = const i0.Value.absent(),
|
i0.Value<bool> isActivityEnabled = const i0.Value.absent(),
|
||||||
required i2.AlbumAssetOrder order,
|
required i2.AlbumAssetOrder order,
|
||||||
@@ -477,7 +357,6 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
description: description,
|
description: description,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
ownerId: ownerId,
|
|
||||||
thumbnailAssetId: thumbnailAssetId,
|
thumbnailAssetId: thumbnailAssetId,
|
||||||
isActivityEnabled: isActivityEnabled,
|
isActivityEnabled: isActivityEnabled,
|
||||||
order: order,
|
order: order,
|
||||||
@@ -490,7 +369,7 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
prefetchHooksCallback: ({ownerId = false, thumbnailAssetId = false}) {
|
prefetchHooksCallback: ({thumbnailAssetId = false}) {
|
||||||
return i0.PrefetchHooks(
|
return i0.PrefetchHooks(
|
||||||
db: db,
|
db: db,
|
||||||
explicitlyWatchedTables: [],
|
explicitlyWatchedTables: [],
|
||||||
@@ -510,21 +389,6 @@ class $$RemoteAlbumEntityTableTableManager
|
|||||||
dynamic
|
dynamic
|
||||||
>
|
>
|
||||||
>(state) {
|
>(state) {
|
||||||
if (ownerId) {
|
|
||||||
state =
|
|
||||||
state.withJoin(
|
|
||||||
currentTable: table,
|
|
||||||
currentColumn: table.ownerId,
|
|
||||||
referencedTable: i1
|
|
||||||
.$$RemoteAlbumEntityTableReferences
|
|
||||||
._ownerIdTable(db),
|
|
||||||
referencedColumn: i1
|
|
||||||
.$$RemoteAlbumEntityTableReferences
|
|
||||||
._ownerIdTable(db)
|
|
||||||
.id,
|
|
||||||
)
|
|
||||||
as T;
|
|
||||||
}
|
|
||||||
if (thumbnailAssetId) {
|
if (thumbnailAssetId) {
|
||||||
state =
|
state =
|
||||||
state.withJoin(
|
state.withJoin(
|
||||||
@@ -564,12 +428,8 @@ typedef $$RemoteAlbumEntityTableProcessedTableManager =
|
|||||||
$$RemoteAlbumEntityTableUpdateCompanionBuilder,
|
$$RemoteAlbumEntityTableUpdateCompanionBuilder,
|
||||||
(i1.RemoteAlbumEntityData, i1.$$RemoteAlbumEntityTableReferences),
|
(i1.RemoteAlbumEntityData, i1.$$RemoteAlbumEntityTableReferences),
|
||||||
i1.RemoteAlbumEntityData,
|
i1.RemoteAlbumEntityData,
|
||||||
i0.PrefetchHooks Function({bool ownerId, bool thumbnailAssetId})
|
i0.PrefetchHooks Function({bool thumbnailAssetId})
|
||||||
>;
|
>;
|
||||||
i0.Index get idxRemoteAlbumOwnerId => i0.Index(
|
|
||||||
'idx_remote_album_owner_id',
|
|
||||||
'CREATE INDEX IF NOT EXISTS idx_remote_album_owner_id ON remote_album_entity (owner_id)',
|
|
||||||
);
|
|
||||||
|
|
||||||
class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
||||||
with i0.TableInfo<$RemoteAlbumEntityTable, i1.RemoteAlbumEntityData> {
|
with i0.TableInfo<$RemoteAlbumEntityTable, i1.RemoteAlbumEntityData> {
|
||||||
@@ -636,20 +496,6 @@ class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
|||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultValue: i4.currentDateAndTime,
|
defaultValue: i4.currentDateAndTime,
|
||||||
);
|
);
|
||||||
static const i0.VerificationMeta _ownerIdMeta = const i0.VerificationMeta(
|
|
||||||
'ownerId',
|
|
||||||
);
|
|
||||||
@override
|
|
||||||
late final i0.GeneratedColumn<String> ownerId = i0.GeneratedColumn<String>(
|
|
||||||
'owner_id',
|
|
||||||
aliasedName,
|
|
||||||
false,
|
|
||||||
type: i0.DriftSqlType.string,
|
|
||||||
requiredDuringInsert: true,
|
|
||||||
defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
|
|
||||||
'REFERENCES user_entity (id) ON DELETE CASCADE',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
static const i0.VerificationMeta _thumbnailAssetIdMeta =
|
static const i0.VerificationMeta _thumbnailAssetIdMeta =
|
||||||
const i0.VerificationMeta('thumbnailAssetId');
|
const i0.VerificationMeta('thumbnailAssetId');
|
||||||
@override
|
@override
|
||||||
@@ -698,7 +544,6 @@ class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
|||||||
description,
|
description,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
ownerId,
|
|
||||||
thumbnailAssetId,
|
thumbnailAssetId,
|
||||||
isActivityEnabled,
|
isActivityEnabled,
|
||||||
order,
|
order,
|
||||||
@@ -749,14 +594,6 @@ class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
|||||||
updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta),
|
updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('owner_id')) {
|
|
||||||
context.handle(
|
|
||||||
_ownerIdMeta,
|
|
||||||
ownerId.isAcceptableOrUnknown(data['owner_id']!, _ownerIdMeta),
|
|
||||||
);
|
|
||||||
} else if (isInserting) {
|
|
||||||
context.missing(_ownerIdMeta);
|
|
||||||
}
|
|
||||||
if (data.containsKey('thumbnail_asset_id')) {
|
if (data.containsKey('thumbnail_asset_id')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_thumbnailAssetIdMeta,
|
_thumbnailAssetIdMeta,
|
||||||
@@ -807,10 +644,6 @@ class $RemoteAlbumEntityTable extends i3.RemoteAlbumEntity
|
|||||||
i0.DriftSqlType.dateTime,
|
i0.DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}updated_at'],
|
data['${effectivePrefix}updated_at'],
|
||||||
)!,
|
)!,
|
||||||
ownerId: attachedDatabase.typeMapping.read(
|
|
||||||
i0.DriftSqlType.string,
|
|
||||||
data['${effectivePrefix}owner_id'],
|
|
||||||
)!,
|
|
||||||
thumbnailAssetId: attachedDatabase.typeMapping.read(
|
thumbnailAssetId: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
data['${effectivePrefix}thumbnail_asset_id'],
|
data['${effectivePrefix}thumbnail_asset_id'],
|
||||||
@@ -850,7 +683,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
final String description;
|
final String description;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final String ownerId;
|
|
||||||
final String? thumbnailAssetId;
|
final String? thumbnailAssetId;
|
||||||
final bool isActivityEnabled;
|
final bool isActivityEnabled;
|
||||||
final i2.AlbumAssetOrder order;
|
final i2.AlbumAssetOrder order;
|
||||||
@@ -860,7 +692,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
required this.description,
|
required this.description,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.ownerId,
|
|
||||||
this.thumbnailAssetId,
|
this.thumbnailAssetId,
|
||||||
required this.isActivityEnabled,
|
required this.isActivityEnabled,
|
||||||
required this.order,
|
required this.order,
|
||||||
@@ -873,7 +704,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
map['description'] = i0.Variable<String>(description);
|
map['description'] = i0.Variable<String>(description);
|
||||||
map['created_at'] = i0.Variable<DateTime>(createdAt);
|
map['created_at'] = i0.Variable<DateTime>(createdAt);
|
||||||
map['updated_at'] = i0.Variable<DateTime>(updatedAt);
|
map['updated_at'] = i0.Variable<DateTime>(updatedAt);
|
||||||
map['owner_id'] = i0.Variable<String>(ownerId);
|
|
||||||
if (!nullToAbsent || thumbnailAssetId != null) {
|
if (!nullToAbsent || thumbnailAssetId != null) {
|
||||||
map['thumbnail_asset_id'] = i0.Variable<String>(thumbnailAssetId);
|
map['thumbnail_asset_id'] = i0.Variable<String>(thumbnailAssetId);
|
||||||
}
|
}
|
||||||
@@ -897,7 +727,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
description: serializer.fromJson<String>(json['description']),
|
description: serializer.fromJson<String>(json['description']),
|
||||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
ownerId: serializer.fromJson<String>(json['ownerId']),
|
|
||||||
thumbnailAssetId: serializer.fromJson<String?>(json['thumbnailAssetId']),
|
thumbnailAssetId: serializer.fromJson<String?>(json['thumbnailAssetId']),
|
||||||
isActivityEnabled: serializer.fromJson<bool>(json['isActivityEnabled']),
|
isActivityEnabled: serializer.fromJson<bool>(json['isActivityEnabled']),
|
||||||
order: i1.$RemoteAlbumEntityTable.$converterorder.fromJson(
|
order: i1.$RemoteAlbumEntityTable.$converterorder.fromJson(
|
||||||
@@ -914,7 +743,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
'description': serializer.toJson<String>(description),
|
'description': serializer.toJson<String>(description),
|
||||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
'ownerId': serializer.toJson<String>(ownerId),
|
|
||||||
'thumbnailAssetId': serializer.toJson<String?>(thumbnailAssetId),
|
'thumbnailAssetId': serializer.toJson<String?>(thumbnailAssetId),
|
||||||
'isActivityEnabled': serializer.toJson<bool>(isActivityEnabled),
|
'isActivityEnabled': serializer.toJson<bool>(isActivityEnabled),
|
||||||
'order': serializer.toJson<int>(
|
'order': serializer.toJson<int>(
|
||||||
@@ -929,7 +757,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
String? description,
|
String? description,
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
String? ownerId,
|
|
||||||
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
i0.Value<String?> thumbnailAssetId = const i0.Value.absent(),
|
||||||
bool? isActivityEnabled,
|
bool? isActivityEnabled,
|
||||||
i2.AlbumAssetOrder? order,
|
i2.AlbumAssetOrder? order,
|
||||||
@@ -939,7 +766,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
description: description ?? this.description,
|
description: description ?? this.description,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
ownerId: ownerId ?? this.ownerId,
|
|
||||||
thumbnailAssetId: thumbnailAssetId.present
|
thumbnailAssetId: thumbnailAssetId.present
|
||||||
? thumbnailAssetId.value
|
? thumbnailAssetId.value
|
||||||
: this.thumbnailAssetId,
|
: this.thumbnailAssetId,
|
||||||
@@ -955,7 +781,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
: this.description,
|
: this.description,
|
||||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId,
|
|
||||||
thumbnailAssetId: data.thumbnailAssetId.present
|
thumbnailAssetId: data.thumbnailAssetId.present
|
||||||
? data.thumbnailAssetId.value
|
? data.thumbnailAssetId.value
|
||||||
: this.thumbnailAssetId,
|
: this.thumbnailAssetId,
|
||||||
@@ -974,7 +799,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
..write('description: $description, ')
|
..write('description: $description, ')
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('ownerId: $ownerId, ')
|
|
||||||
..write('thumbnailAssetId: $thumbnailAssetId, ')
|
..write('thumbnailAssetId: $thumbnailAssetId, ')
|
||||||
..write('isActivityEnabled: $isActivityEnabled, ')
|
..write('isActivityEnabled: $isActivityEnabled, ')
|
||||||
..write('order: $order')
|
..write('order: $order')
|
||||||
@@ -989,7 +813,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
description,
|
description,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
ownerId,
|
|
||||||
thumbnailAssetId,
|
thumbnailAssetId,
|
||||||
isActivityEnabled,
|
isActivityEnabled,
|
||||||
order,
|
order,
|
||||||
@@ -1003,7 +826,6 @@ class RemoteAlbumEntityData extends i0.DataClass
|
|||||||
other.description == this.description &&
|
other.description == this.description &&
|
||||||
other.createdAt == this.createdAt &&
|
other.createdAt == this.createdAt &&
|
||||||
other.updatedAt == this.updatedAt &&
|
other.updatedAt == this.updatedAt &&
|
||||||
other.ownerId == this.ownerId &&
|
|
||||||
other.thumbnailAssetId == this.thumbnailAssetId &&
|
other.thumbnailAssetId == this.thumbnailAssetId &&
|
||||||
other.isActivityEnabled == this.isActivityEnabled &&
|
other.isActivityEnabled == this.isActivityEnabled &&
|
||||||
other.order == this.order);
|
other.order == this.order);
|
||||||
@@ -1016,7 +838,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
final i0.Value<String> description;
|
final i0.Value<String> description;
|
||||||
final i0.Value<DateTime> createdAt;
|
final i0.Value<DateTime> createdAt;
|
||||||
final i0.Value<DateTime> updatedAt;
|
final i0.Value<DateTime> updatedAt;
|
||||||
final i0.Value<String> ownerId;
|
|
||||||
final i0.Value<String?> thumbnailAssetId;
|
final i0.Value<String?> thumbnailAssetId;
|
||||||
final i0.Value<bool> isActivityEnabled;
|
final i0.Value<bool> isActivityEnabled;
|
||||||
final i0.Value<i2.AlbumAssetOrder> order;
|
final i0.Value<i2.AlbumAssetOrder> order;
|
||||||
@@ -1026,7 +847,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
this.description = const i0.Value.absent(),
|
this.description = const i0.Value.absent(),
|
||||||
this.createdAt = const i0.Value.absent(),
|
this.createdAt = const i0.Value.absent(),
|
||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.ownerId = const i0.Value.absent(),
|
|
||||||
this.thumbnailAssetId = const i0.Value.absent(),
|
this.thumbnailAssetId = const i0.Value.absent(),
|
||||||
this.isActivityEnabled = const i0.Value.absent(),
|
this.isActivityEnabled = const i0.Value.absent(),
|
||||||
this.order = const i0.Value.absent(),
|
this.order = const i0.Value.absent(),
|
||||||
@@ -1037,13 +857,11 @@ class RemoteAlbumEntityCompanion
|
|||||||
this.description = const i0.Value.absent(),
|
this.description = const i0.Value.absent(),
|
||||||
this.createdAt = const i0.Value.absent(),
|
this.createdAt = const i0.Value.absent(),
|
||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
required String ownerId,
|
|
||||||
this.thumbnailAssetId = const i0.Value.absent(),
|
this.thumbnailAssetId = const i0.Value.absent(),
|
||||||
this.isActivityEnabled = const i0.Value.absent(),
|
this.isActivityEnabled = const i0.Value.absent(),
|
||||||
required i2.AlbumAssetOrder order,
|
required i2.AlbumAssetOrder order,
|
||||||
}) : id = i0.Value(id),
|
}) : id = i0.Value(id),
|
||||||
name = i0.Value(name),
|
name = i0.Value(name),
|
||||||
ownerId = i0.Value(ownerId),
|
|
||||||
order = i0.Value(order);
|
order = i0.Value(order);
|
||||||
static i0.Insertable<i1.RemoteAlbumEntityData> custom({
|
static i0.Insertable<i1.RemoteAlbumEntityData> custom({
|
||||||
i0.Expression<String>? id,
|
i0.Expression<String>? id,
|
||||||
@@ -1051,7 +869,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
i0.Expression<String>? description,
|
i0.Expression<String>? description,
|
||||||
i0.Expression<DateTime>? createdAt,
|
i0.Expression<DateTime>? createdAt,
|
||||||
i0.Expression<DateTime>? updatedAt,
|
i0.Expression<DateTime>? updatedAt,
|
||||||
i0.Expression<String>? ownerId,
|
|
||||||
i0.Expression<String>? thumbnailAssetId,
|
i0.Expression<String>? thumbnailAssetId,
|
||||||
i0.Expression<bool>? isActivityEnabled,
|
i0.Expression<bool>? isActivityEnabled,
|
||||||
i0.Expression<int>? order,
|
i0.Expression<int>? order,
|
||||||
@@ -1062,7 +879,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
if (description != null) 'description': description,
|
if (description != null) 'description': description,
|
||||||
if (createdAt != null) 'created_at': createdAt,
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (updatedAt != null) 'updated_at': updatedAt,
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
if (ownerId != null) 'owner_id': ownerId,
|
|
||||||
if (thumbnailAssetId != null) 'thumbnail_asset_id': thumbnailAssetId,
|
if (thumbnailAssetId != null) 'thumbnail_asset_id': thumbnailAssetId,
|
||||||
if (isActivityEnabled != null) 'is_activity_enabled': isActivityEnabled,
|
if (isActivityEnabled != null) 'is_activity_enabled': isActivityEnabled,
|
||||||
if (order != null) 'order': order,
|
if (order != null) 'order': order,
|
||||||
@@ -1075,7 +891,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
i0.Value<String>? description,
|
i0.Value<String>? description,
|
||||||
i0.Value<DateTime>? createdAt,
|
i0.Value<DateTime>? createdAt,
|
||||||
i0.Value<DateTime>? updatedAt,
|
i0.Value<DateTime>? updatedAt,
|
||||||
i0.Value<String>? ownerId,
|
|
||||||
i0.Value<String?>? thumbnailAssetId,
|
i0.Value<String?>? thumbnailAssetId,
|
||||||
i0.Value<bool>? isActivityEnabled,
|
i0.Value<bool>? isActivityEnabled,
|
||||||
i0.Value<i2.AlbumAssetOrder>? order,
|
i0.Value<i2.AlbumAssetOrder>? order,
|
||||||
@@ -1086,7 +901,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
description: description ?? this.description,
|
description: description ?? this.description,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
ownerId: ownerId ?? this.ownerId,
|
|
||||||
thumbnailAssetId: thumbnailAssetId ?? this.thumbnailAssetId,
|
thumbnailAssetId: thumbnailAssetId ?? this.thumbnailAssetId,
|
||||||
isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled,
|
isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled,
|
||||||
order: order ?? this.order,
|
order: order ?? this.order,
|
||||||
@@ -1111,9 +925,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
if (updatedAt.present) {
|
if (updatedAt.present) {
|
||||||
map['updated_at'] = i0.Variable<DateTime>(updatedAt.value);
|
map['updated_at'] = i0.Variable<DateTime>(updatedAt.value);
|
||||||
}
|
}
|
||||||
if (ownerId.present) {
|
|
||||||
map['owner_id'] = i0.Variable<String>(ownerId.value);
|
|
||||||
}
|
|
||||||
if (thumbnailAssetId.present) {
|
if (thumbnailAssetId.present) {
|
||||||
map['thumbnail_asset_id'] = i0.Variable<String>(thumbnailAssetId.value);
|
map['thumbnail_asset_id'] = i0.Variable<String>(thumbnailAssetId.value);
|
||||||
}
|
}
|
||||||
@@ -1136,7 +947,6 @@ class RemoteAlbumEntityCompanion
|
|||||||
..write('description: $description, ')
|
..write('description: $description, ')
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('ownerId: $ownerId, ')
|
|
||||||
..write('thumbnailAssetId: $thumbnailAssetId, ')
|
..write('thumbnailAssetId: $thumbnailAssetId, ')
|
||||||
..write('isActivityEnabled: $isActivityEnabled, ')
|
..write('isActivityEnabled: $isActivityEnabled, ')
|
||||||
..write('order: $order')
|
..write('order: $order')
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData {
|
|||||||
type: type,
|
type: type,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
height: height,
|
height: height,
|
||||||
width: width,
|
width: width,
|
||||||
|
|||||||
+52
-57
@@ -19,7 +19,7 @@ typedef $$RemoteAssetEntityTableCreateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
required String id,
|
required String id,
|
||||||
required String checksum,
|
required String checksum,
|
||||||
i0.Value<bool> isFavorite,
|
i0.Value<bool> isFavorite,
|
||||||
@@ -41,7 +41,7 @@ typedef $$RemoteAssetEntityTableUpdateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
i0.Value<String> id,
|
i0.Value<String> id,
|
||||||
i0.Value<String> checksum,
|
i0.Value<String> checksum,
|
||||||
i0.Value<bool> isFavorite,
|
i0.Value<bool> isFavorite,
|
||||||
@@ -142,8 +142,8 @@ class $$RemoteAssetEntityTableFilterComposer
|
|||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnFilters<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnFilters<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -270,8 +270,8 @@ class $$RemoteAssetEntityTableOrderingComposer
|
|||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnOrderings<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnOrderings<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -385,8 +385,8 @@ class $$RemoteAssetEntityTableAnnotationComposer
|
|||||||
i0.GeneratedColumn<int> get height =>
|
i0.GeneratedColumn<int> get height =>
|
||||||
$composableBuilder(column: $table.height, builder: (column) => column);
|
$composableBuilder(column: $table.height, builder: (column) => column);
|
||||||
|
|
||||||
i0.GeneratedColumn<int> get durationInSeconds => $composableBuilder(
|
i0.GeneratedColumn<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -499,7 +499,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
i0.Value<String> id = const i0.Value.absent(),
|
i0.Value<String> id = const i0.Value.absent(),
|
||||||
i0.Value<String> checksum = const i0.Value.absent(),
|
i0.Value<String> checksum = const i0.Value.absent(),
|
||||||
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
||||||
@@ -520,7 +520,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
@@ -542,7 +542,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
required String checksum,
|
required String checksum,
|
||||||
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
i0.Value<bool> isFavorite = const i0.Value.absent(),
|
||||||
@@ -562,7 +562,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
@@ -724,17 +724,17 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
type: i0.DriftSqlType.int,
|
type: i0.DriftSqlType.int,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
static const i0.VerificationMeta _durationInSecondsMeta =
|
static const i0.VerificationMeta _durationMsMeta = const i0.VerificationMeta(
|
||||||
const i0.VerificationMeta('durationInSeconds');
|
'durationMs',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<int> durationInSeconds =
|
late final i0.GeneratedColumn<int> durationMs = i0.GeneratedColumn<int>(
|
||||||
i0.GeneratedColumn<int>(
|
'duration_ms',
|
||||||
'duration_in_seconds',
|
aliasedName,
|
||||||
aliasedName,
|
true,
|
||||||
true,
|
type: i0.DriftSqlType.int,
|
||||||
type: i0.DriftSqlType.int,
|
requiredDuringInsert: false,
|
||||||
requiredDuringInsert: false,
|
);
|
||||||
);
|
|
||||||
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
||||||
@@ -886,7 +886,7 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
checksum,
|
checksum,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
@@ -944,13 +944,10 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('duration_in_seconds')) {
|
if (data.containsKey('duration_ms')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_durationInSecondsMeta,
|
_durationMsMeta,
|
||||||
durationInSeconds.isAcceptableOrUnknown(
|
durationMs.isAcceptableOrUnknown(data['duration_ms']!, _durationMsMeta),
|
||||||
data['duration_in_seconds']!,
|
|
||||||
_durationInSecondsMeta,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('id')) {
|
if (data.containsKey('id')) {
|
||||||
@@ -1066,9 +1063,9 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}height'],
|
data['${effectivePrefix}height'],
|
||||||
),
|
),
|
||||||
durationInSeconds: attachedDatabase.typeMapping.read(
|
durationMs: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}duration_in_seconds'],
|
data['${effectivePrefix}duration_ms'],
|
||||||
),
|
),
|
||||||
id: attachedDatabase.typeMapping.read(
|
id: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
@@ -1148,7 +1145,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? width;
|
final int? width;
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? durationInSeconds;
|
final int? durationMs;
|
||||||
final String id;
|
final String id;
|
||||||
final String checksum;
|
final String checksum;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
@@ -1168,7 +1165,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.durationInSeconds,
|
this.durationMs,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.checksum,
|
required this.checksum,
|
||||||
required this.isFavorite,
|
required this.isFavorite,
|
||||||
@@ -1199,8 +1196,8 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
if (!nullToAbsent || height != null) {
|
if (!nullToAbsent || height != null) {
|
||||||
map['height'] = i0.Variable<int>(height);
|
map['height'] = i0.Variable<int>(height);
|
||||||
}
|
}
|
||||||
if (!nullToAbsent || durationInSeconds != null) {
|
if (!nullToAbsent || durationMs != null) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds);
|
map['duration_ms'] = i0.Variable<int>(durationMs);
|
||||||
}
|
}
|
||||||
map['id'] = i0.Variable<String>(id);
|
map['id'] = i0.Variable<String>(id);
|
||||||
map['checksum'] = i0.Variable<String>(checksum);
|
map['checksum'] = i0.Variable<String>(checksum);
|
||||||
@@ -1247,7 +1244,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
width: serializer.fromJson<int?>(json['width']),
|
width: serializer.fromJson<int?>(json['width']),
|
||||||
height: serializer.fromJson<int?>(json['height']),
|
height: serializer.fromJson<int?>(json['height']),
|
||||||
durationInSeconds: serializer.fromJson<int?>(json['durationInSeconds']),
|
durationMs: serializer.fromJson<int?>(json['durationMs']),
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
checksum: serializer.fromJson<String>(json['checksum']),
|
checksum: serializer.fromJson<String>(json['checksum']),
|
||||||
isFavorite: serializer.fromJson<bool>(json['isFavorite']),
|
isFavorite: serializer.fromJson<bool>(json['isFavorite']),
|
||||||
@@ -1276,7 +1273,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
'width': serializer.toJson<int?>(width),
|
'width': serializer.toJson<int?>(width),
|
||||||
'height': serializer.toJson<int?>(height),
|
'height': serializer.toJson<int?>(height),
|
||||||
'durationInSeconds': serializer.toJson<int?>(durationInSeconds),
|
'durationMs': serializer.toJson<int?>(durationMs),
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'checksum': serializer.toJson<String>(checksum),
|
'checksum': serializer.toJson<String>(checksum),
|
||||||
'isFavorite': serializer.toJson<bool>(isFavorite),
|
'isFavorite': serializer.toJson<bool>(isFavorite),
|
||||||
@@ -1301,7 +1298,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
String? id,
|
String? id,
|
||||||
String? checksum,
|
String? checksum,
|
||||||
bool? isFavorite,
|
bool? isFavorite,
|
||||||
@@ -1321,9 +1318,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width.present ? width.value : this.width,
|
width: width.present ? width.value : this.width,
|
||||||
height: height.present ? height.value : this.height,
|
height: height.present ? height.value : this.height,
|
||||||
durationInSeconds: durationInSeconds.present
|
durationMs: durationMs.present ? durationMs.value : this.durationMs,
|
||||||
? durationInSeconds.value
|
|
||||||
: this.durationInSeconds,
|
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
checksum: checksum ?? this.checksum,
|
checksum: checksum ?? this.checksum,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
@@ -1349,9 +1344,9 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
width: data.width.present ? data.width.value : this.width,
|
width: data.width.present ? data.width.value : this.width,
|
||||||
height: data.height.present ? data.height.value : this.height,
|
height: data.height.present ? data.height.value : this.height,
|
||||||
durationInSeconds: data.durationInSeconds.present
|
durationMs: data.durationMs.present
|
||||||
? data.durationInSeconds.value
|
? data.durationMs.value
|
||||||
: this.durationInSeconds,
|
: this.durationMs,
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
||||||
isFavorite: data.isFavorite.present
|
isFavorite: data.isFavorite.present
|
||||||
@@ -1384,7 +1379,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
..write('isFavorite: $isFavorite, ')
|
..write('isFavorite: $isFavorite, ')
|
||||||
@@ -1409,7 +1404,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
checksum,
|
checksum,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
@@ -1433,7 +1428,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
other.updatedAt == this.updatedAt &&
|
other.updatedAt == this.updatedAt &&
|
||||||
other.width == this.width &&
|
other.width == this.width &&
|
||||||
other.height == this.height &&
|
other.height == this.height &&
|
||||||
other.durationInSeconds == this.durationInSeconds &&
|
other.durationMs == this.durationMs &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.checksum == this.checksum &&
|
other.checksum == this.checksum &&
|
||||||
other.isFavorite == this.isFavorite &&
|
other.isFavorite == this.isFavorite &&
|
||||||
@@ -1456,7 +1451,7 @@ class RemoteAssetEntityCompanion
|
|||||||
final i0.Value<DateTime> updatedAt;
|
final i0.Value<DateTime> updatedAt;
|
||||||
final i0.Value<int?> width;
|
final i0.Value<int?> width;
|
||||||
final i0.Value<int?> height;
|
final i0.Value<int?> height;
|
||||||
final i0.Value<int?> durationInSeconds;
|
final i0.Value<int?> durationMs;
|
||||||
final i0.Value<String> id;
|
final i0.Value<String> id;
|
||||||
final i0.Value<String> checksum;
|
final i0.Value<String> checksum;
|
||||||
final i0.Value<bool> isFavorite;
|
final i0.Value<bool> isFavorite;
|
||||||
@@ -1476,7 +1471,7 @@ class RemoteAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
this.id = const i0.Value.absent(),
|
this.id = const i0.Value.absent(),
|
||||||
this.checksum = const i0.Value.absent(),
|
this.checksum = const i0.Value.absent(),
|
||||||
this.isFavorite = const i0.Value.absent(),
|
this.isFavorite = const i0.Value.absent(),
|
||||||
@@ -1497,7 +1492,7 @@ class RemoteAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
required String checksum,
|
required String checksum,
|
||||||
this.isFavorite = const i0.Value.absent(),
|
this.isFavorite = const i0.Value.absent(),
|
||||||
@@ -1523,7 +1518,7 @@ class RemoteAssetEntityCompanion
|
|||||||
i0.Expression<DateTime>? updatedAt,
|
i0.Expression<DateTime>? updatedAt,
|
||||||
i0.Expression<int>? width,
|
i0.Expression<int>? width,
|
||||||
i0.Expression<int>? height,
|
i0.Expression<int>? height,
|
||||||
i0.Expression<int>? durationInSeconds,
|
i0.Expression<int>? durationMs,
|
||||||
i0.Expression<String>? id,
|
i0.Expression<String>? id,
|
||||||
i0.Expression<String>? checksum,
|
i0.Expression<String>? checksum,
|
||||||
i0.Expression<bool>? isFavorite,
|
i0.Expression<bool>? isFavorite,
|
||||||
@@ -1544,7 +1539,7 @@ class RemoteAssetEntityCompanion
|
|||||||
if (updatedAt != null) 'updated_at': updatedAt,
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
if (width != null) 'width': width,
|
if (width != null) 'width': width,
|
||||||
if (height != null) 'height': height,
|
if (height != null) 'height': height,
|
||||||
if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds,
|
if (durationMs != null) 'duration_ms': durationMs,
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (checksum != null) 'checksum': checksum,
|
if (checksum != null) 'checksum': checksum,
|
||||||
if (isFavorite != null) 'is_favorite': isFavorite,
|
if (isFavorite != null) 'is_favorite': isFavorite,
|
||||||
@@ -1567,7 +1562,7 @@ class RemoteAssetEntityCompanion
|
|||||||
i0.Value<DateTime>? updatedAt,
|
i0.Value<DateTime>? updatedAt,
|
||||||
i0.Value<int?>? width,
|
i0.Value<int?>? width,
|
||||||
i0.Value<int?>? height,
|
i0.Value<int?>? height,
|
||||||
i0.Value<int?>? durationInSeconds,
|
i0.Value<int?>? durationMs,
|
||||||
i0.Value<String>? id,
|
i0.Value<String>? id,
|
||||||
i0.Value<String>? checksum,
|
i0.Value<String>? checksum,
|
||||||
i0.Value<bool>? isFavorite,
|
i0.Value<bool>? isFavorite,
|
||||||
@@ -1588,7 +1583,7 @@ class RemoteAssetEntityCompanion
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
checksum: checksum ?? this.checksum,
|
checksum: checksum ?? this.checksum,
|
||||||
isFavorite: isFavorite ?? this.isFavorite,
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
@@ -1627,8 +1622,8 @@ class RemoteAssetEntityCompanion
|
|||||||
if (height.present) {
|
if (height.present) {
|
||||||
map['height'] = i0.Variable<int>(height.value);
|
map['height'] = i0.Variable<int>(height.value);
|
||||||
}
|
}
|
||||||
if (durationInSeconds.present) {
|
if (durationMs.present) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds.value);
|
map['duration_ms'] = i0.Variable<int>(durationMs.value);
|
||||||
}
|
}
|
||||||
if (id.present) {
|
if (id.present) {
|
||||||
map['id'] = i0.Variable<String>(id.value);
|
map['id'] = i0.Variable<String>(id.value);
|
||||||
@@ -1680,7 +1675,7 @@ class RemoteAssetEntityCompanion
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
..write('isFavorite: $isFavorite, ')
|
..write('isFavorite: $isFavorite, ')
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ extension TrashedLocalAssetEntityDataDomainExtension on TrashedLocalAssetEntityD
|
|||||||
type: type,
|
type: type,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
height: height,
|
height: height,
|
||||||
width: width,
|
width: width,
|
||||||
|
|||||||
+52
-57
@@ -16,7 +16,7 @@ typedef $$TrashedLocalAssetEntityTableCreateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
required String id,
|
required String id,
|
||||||
required String albumId,
|
required String albumId,
|
||||||
i0.Value<String?> checksum,
|
i0.Value<String?> checksum,
|
||||||
@@ -33,7 +33,7 @@ typedef $$TrashedLocalAssetEntityTableUpdateCompanionBuilder =
|
|||||||
i0.Value<DateTime> updatedAt,
|
i0.Value<DateTime> updatedAt,
|
||||||
i0.Value<int?> width,
|
i0.Value<int?> width,
|
||||||
i0.Value<int?> height,
|
i0.Value<int?> height,
|
||||||
i0.Value<int?> durationInSeconds,
|
i0.Value<int?> durationMs,
|
||||||
i0.Value<String> id,
|
i0.Value<String> id,
|
||||||
i0.Value<String> albumId,
|
i0.Value<String> albumId,
|
||||||
i0.Value<String?> checksum,
|
i0.Value<String?> checksum,
|
||||||
@@ -84,8 +84,8 @@ class $$TrashedLocalAssetEntityTableFilterComposer
|
|||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnFilters<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnFilters<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -171,8 +171,8 @@ class $$TrashedLocalAssetEntityTableOrderingComposer
|
|||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
i0.ColumnOrderings<int> get durationInSeconds => $composableBuilder(
|
i0.ColumnOrderings<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -240,8 +240,8 @@ class $$TrashedLocalAssetEntityTableAnnotationComposer
|
|||||||
i0.GeneratedColumn<int> get height =>
|
i0.GeneratedColumn<int> get height =>
|
||||||
$composableBuilder(column: $table.height, builder: (column) => column);
|
$composableBuilder(column: $table.height, builder: (column) => column);
|
||||||
|
|
||||||
i0.GeneratedColumn<int> get durationInSeconds => $composableBuilder(
|
i0.GeneratedColumn<int> get durationMs => $composableBuilder(
|
||||||
column: $table.durationInSeconds,
|
column: $table.durationMs,
|
||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ class $$TrashedLocalAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
i0.Value<String> id = const i0.Value.absent(),
|
i0.Value<String> id = const i0.Value.absent(),
|
||||||
i0.Value<String> albumId = const i0.Value.absent(),
|
i0.Value<String> albumId = const i0.Value.absent(),
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
@@ -342,7 +342,7 @@ class $$TrashedLocalAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
@@ -359,7 +359,7 @@ class $$TrashedLocalAssetEntityTableTableManager
|
|||||||
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
i0.Value<DateTime> updatedAt = const i0.Value.absent(),
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
required String albumId,
|
required String albumId,
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
@@ -375,7 +375,7 @@ class $$TrashedLocalAssetEntityTableTableManager
|
|||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
durationInSeconds: durationInSeconds,
|
durationMs: durationMs,
|
||||||
id: id,
|
id: id,
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
@@ -498,17 +498,17 @@ class $TrashedLocalAssetEntityTable extends i3.TrashedLocalAssetEntity
|
|||||||
type: i0.DriftSqlType.int,
|
type: i0.DriftSqlType.int,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
static const i0.VerificationMeta _durationInSecondsMeta =
|
static const i0.VerificationMeta _durationMsMeta = const i0.VerificationMeta(
|
||||||
const i0.VerificationMeta('durationInSeconds');
|
'durationMs',
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<int> durationInSeconds =
|
late final i0.GeneratedColumn<int> durationMs = i0.GeneratedColumn<int>(
|
||||||
i0.GeneratedColumn<int>(
|
'duration_ms',
|
||||||
'duration_in_seconds',
|
aliasedName,
|
||||||
aliasedName,
|
true,
|
||||||
true,
|
type: i0.DriftSqlType.int,
|
||||||
type: i0.DriftSqlType.int,
|
requiredDuringInsert: false,
|
||||||
requiredDuringInsert: false,
|
);
|
||||||
);
|
|
||||||
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
||||||
@override
|
@override
|
||||||
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
||||||
@@ -599,7 +599,7 @@ class $TrashedLocalAssetEntityTable extends i3.TrashedLocalAssetEntity
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
albumId,
|
albumId,
|
||||||
checksum,
|
checksum,
|
||||||
@@ -652,13 +652,10 @@ class $TrashedLocalAssetEntityTable extends i3.TrashedLocalAssetEntity
|
|||||||
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
height.isAcceptableOrUnknown(data['height']!, _heightMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('duration_in_seconds')) {
|
if (data.containsKey('duration_ms')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_durationInSecondsMeta,
|
_durationMsMeta,
|
||||||
durationInSeconds.isAcceptableOrUnknown(
|
durationMs.isAcceptableOrUnknown(data['duration_ms']!, _durationMsMeta),
|
||||||
data['duration_in_seconds']!,
|
|
||||||
_durationInSecondsMeta,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (data.containsKey('id')) {
|
if (data.containsKey('id')) {
|
||||||
@@ -733,9 +730,9 @@ class $TrashedLocalAssetEntityTable extends i3.TrashedLocalAssetEntity
|
|||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}height'],
|
data['${effectivePrefix}height'],
|
||||||
),
|
),
|
||||||
durationInSeconds: attachedDatabase.typeMapping.read(
|
durationMs: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.int,
|
i0.DriftSqlType.int,
|
||||||
data['${effectivePrefix}duration_in_seconds'],
|
data['${effectivePrefix}duration_ms'],
|
||||||
),
|
),
|
||||||
id: attachedDatabase.typeMapping.read(
|
id: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
@@ -800,7 +797,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? width;
|
final int? width;
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? durationInSeconds;
|
final int? durationMs;
|
||||||
final String id;
|
final String id;
|
||||||
final String albumId;
|
final String albumId;
|
||||||
final String? checksum;
|
final String? checksum;
|
||||||
@@ -815,7 +812,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.durationInSeconds,
|
this.durationMs,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.albumId,
|
required this.albumId,
|
||||||
this.checksum,
|
this.checksum,
|
||||||
@@ -841,8 +838,8 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
if (!nullToAbsent || height != null) {
|
if (!nullToAbsent || height != null) {
|
||||||
map['height'] = i0.Variable<int>(height);
|
map['height'] = i0.Variable<int>(height);
|
||||||
}
|
}
|
||||||
if (!nullToAbsent || durationInSeconds != null) {
|
if (!nullToAbsent || durationMs != null) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds);
|
map['duration_ms'] = i0.Variable<int>(durationMs);
|
||||||
}
|
}
|
||||||
map['id'] = i0.Variable<String>(id);
|
map['id'] = i0.Variable<String>(id);
|
||||||
map['album_id'] = i0.Variable<String>(albumId);
|
map['album_id'] = i0.Variable<String>(albumId);
|
||||||
@@ -880,7 +877,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
width: serializer.fromJson<int?>(json['width']),
|
width: serializer.fromJson<int?>(json['width']),
|
||||||
height: serializer.fromJson<int?>(json['height']),
|
height: serializer.fromJson<int?>(json['height']),
|
||||||
durationInSeconds: serializer.fromJson<int?>(json['durationInSeconds']),
|
durationMs: serializer.fromJson<int?>(json['durationMs']),
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
albumId: serializer.fromJson<String>(json['albumId']),
|
albumId: serializer.fromJson<String>(json['albumId']),
|
||||||
checksum: serializer.fromJson<String?>(json['checksum']),
|
checksum: serializer.fromJson<String?>(json['checksum']),
|
||||||
@@ -905,7 +902,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
'width': serializer.toJson<int?>(width),
|
'width': serializer.toJson<int?>(width),
|
||||||
'height': serializer.toJson<int?>(height),
|
'height': serializer.toJson<int?>(height),
|
||||||
'durationInSeconds': serializer.toJson<int?>(durationInSeconds),
|
'durationMs': serializer.toJson<int?>(durationMs),
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'albumId': serializer.toJson<String>(albumId),
|
'albumId': serializer.toJson<String>(albumId),
|
||||||
'checksum': serializer.toJson<String?>(checksum),
|
'checksum': serializer.toJson<String?>(checksum),
|
||||||
@@ -929,7 +926,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
i0.Value<int?> width = const i0.Value.absent(),
|
i0.Value<int?> width = const i0.Value.absent(),
|
||||||
i0.Value<int?> height = const i0.Value.absent(),
|
i0.Value<int?> height = const i0.Value.absent(),
|
||||||
i0.Value<int?> durationInSeconds = const i0.Value.absent(),
|
i0.Value<int?> durationMs = const i0.Value.absent(),
|
||||||
String? id,
|
String? id,
|
||||||
String? albumId,
|
String? albumId,
|
||||||
i0.Value<String?> checksum = const i0.Value.absent(),
|
i0.Value<String?> checksum = const i0.Value.absent(),
|
||||||
@@ -944,9 +941,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width.present ? width.value : this.width,
|
width: width.present ? width.value : this.width,
|
||||||
height: height.present ? height.value : this.height,
|
height: height.present ? height.value : this.height,
|
||||||
durationInSeconds: durationInSeconds.present
|
durationMs: durationMs.present ? durationMs.value : this.durationMs,
|
||||||
? durationInSeconds.value
|
|
||||||
: this.durationInSeconds,
|
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
albumId: albumId ?? this.albumId,
|
albumId: albumId ?? this.albumId,
|
||||||
checksum: checksum.present ? checksum.value : this.checksum,
|
checksum: checksum.present ? checksum.value : this.checksum,
|
||||||
@@ -965,9 +960,9 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
width: data.width.present ? data.width.value : this.width,
|
width: data.width.present ? data.width.value : this.width,
|
||||||
height: data.height.present ? data.height.value : this.height,
|
height: data.height.present ? data.height.value : this.height,
|
||||||
durationInSeconds: data.durationInSeconds.present
|
durationMs: data.durationMs.present
|
||||||
? data.durationInSeconds.value
|
? data.durationMs.value
|
||||||
: this.durationInSeconds,
|
: this.durationMs,
|
||||||
id: data.id.present ? data.id.value : this.id,
|
id: data.id.present ? data.id.value : this.id,
|
||||||
albumId: data.albumId.present ? data.albumId.value : this.albumId,
|
albumId: data.albumId.present ? data.albumId.value : this.albumId,
|
||||||
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
||||||
@@ -993,7 +988,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('albumId: $albumId, ')
|
..write('albumId: $albumId, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
@@ -1013,7 +1008,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
durationInSeconds,
|
durationMs,
|
||||||
id,
|
id,
|
||||||
albumId,
|
albumId,
|
||||||
checksum,
|
checksum,
|
||||||
@@ -1032,7 +1027,7 @@ class TrashedLocalAssetEntityData extends i0.DataClass
|
|||||||
other.updatedAt == this.updatedAt &&
|
other.updatedAt == this.updatedAt &&
|
||||||
other.width == this.width &&
|
other.width == this.width &&
|
||||||
other.height == this.height &&
|
other.height == this.height &&
|
||||||
other.durationInSeconds == this.durationInSeconds &&
|
other.durationMs == this.durationMs &&
|
||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.albumId == this.albumId &&
|
other.albumId == this.albumId &&
|
||||||
other.checksum == this.checksum &&
|
other.checksum == this.checksum &&
|
||||||
@@ -1050,7 +1045,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
final i0.Value<DateTime> updatedAt;
|
final i0.Value<DateTime> updatedAt;
|
||||||
final i0.Value<int?> width;
|
final i0.Value<int?> width;
|
||||||
final i0.Value<int?> height;
|
final i0.Value<int?> height;
|
||||||
final i0.Value<int?> durationInSeconds;
|
final i0.Value<int?> durationMs;
|
||||||
final i0.Value<String> id;
|
final i0.Value<String> id;
|
||||||
final i0.Value<String> albumId;
|
final i0.Value<String> albumId;
|
||||||
final i0.Value<String?> checksum;
|
final i0.Value<String?> checksum;
|
||||||
@@ -1065,7 +1060,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
this.id = const i0.Value.absent(),
|
this.id = const i0.Value.absent(),
|
||||||
this.albumId = const i0.Value.absent(),
|
this.albumId = const i0.Value.absent(),
|
||||||
this.checksum = const i0.Value.absent(),
|
this.checksum = const i0.Value.absent(),
|
||||||
@@ -1081,7 +1076,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
this.updatedAt = const i0.Value.absent(),
|
this.updatedAt = const i0.Value.absent(),
|
||||||
this.width = const i0.Value.absent(),
|
this.width = const i0.Value.absent(),
|
||||||
this.height = const i0.Value.absent(),
|
this.height = const i0.Value.absent(),
|
||||||
this.durationInSeconds = const i0.Value.absent(),
|
this.durationMs = const i0.Value.absent(),
|
||||||
required String id,
|
required String id,
|
||||||
required String albumId,
|
required String albumId,
|
||||||
this.checksum = const i0.Value.absent(),
|
this.checksum = const i0.Value.absent(),
|
||||||
@@ -1101,7 +1096,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
i0.Expression<DateTime>? updatedAt,
|
i0.Expression<DateTime>? updatedAt,
|
||||||
i0.Expression<int>? width,
|
i0.Expression<int>? width,
|
||||||
i0.Expression<int>? height,
|
i0.Expression<int>? height,
|
||||||
i0.Expression<int>? durationInSeconds,
|
i0.Expression<int>? durationMs,
|
||||||
i0.Expression<String>? id,
|
i0.Expression<String>? id,
|
||||||
i0.Expression<String>? albumId,
|
i0.Expression<String>? albumId,
|
||||||
i0.Expression<String>? checksum,
|
i0.Expression<String>? checksum,
|
||||||
@@ -1117,7 +1112,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
if (updatedAt != null) 'updated_at': updatedAt,
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
if (width != null) 'width': width,
|
if (width != null) 'width': width,
|
||||||
if (height != null) 'height': height,
|
if (height != null) 'height': height,
|
||||||
if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds,
|
if (durationMs != null) 'duration_ms': durationMs,
|
||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (albumId != null) 'album_id': albumId,
|
if (albumId != null) 'album_id': albumId,
|
||||||
if (checksum != null) 'checksum': checksum,
|
if (checksum != null) 'checksum': checksum,
|
||||||
@@ -1135,7 +1130,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
i0.Value<DateTime>? updatedAt,
|
i0.Value<DateTime>? updatedAt,
|
||||||
i0.Value<int?>? width,
|
i0.Value<int?>? width,
|
||||||
i0.Value<int?>? height,
|
i0.Value<int?>? height,
|
||||||
i0.Value<int?>? durationInSeconds,
|
i0.Value<int?>? durationMs,
|
||||||
i0.Value<String>? id,
|
i0.Value<String>? id,
|
||||||
i0.Value<String>? albumId,
|
i0.Value<String>? albumId,
|
||||||
i0.Value<String?>? checksum,
|
i0.Value<String?>? checksum,
|
||||||
@@ -1151,7 +1146,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
width: width ?? this.width,
|
width: width ?? this.width,
|
||||||
height: height ?? this.height,
|
height: height ?? this.height,
|
||||||
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
durationMs: durationMs ?? this.durationMs,
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
albumId: albumId ?? this.albumId,
|
albumId: albumId ?? this.albumId,
|
||||||
checksum: checksum ?? this.checksum,
|
checksum: checksum ?? this.checksum,
|
||||||
@@ -1185,8 +1180,8 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
if (height.present) {
|
if (height.present) {
|
||||||
map['height'] = i0.Variable<int>(height.value);
|
map['height'] = i0.Variable<int>(height.value);
|
||||||
}
|
}
|
||||||
if (durationInSeconds.present) {
|
if (durationMs.present) {
|
||||||
map['duration_in_seconds'] = i0.Variable<int>(durationInSeconds.value);
|
map['duration_ms'] = i0.Variable<int>(durationMs.value);
|
||||||
}
|
}
|
||||||
if (id.present) {
|
if (id.present) {
|
||||||
map['id'] = i0.Variable<String>(id.value);
|
map['id'] = i0.Variable<String>(id.value);
|
||||||
@@ -1227,7 +1222,7 @@ class TrashedLocalAssetEntityCompanion
|
|||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('width: $width, ')
|
..write('width: $width, ')
|
||||||
..write('height: $height, ')
|
..write('height: $height, ')
|
||||||
..write('durationInSeconds: $durationInSeconds, ')
|
..write('durationMs: $durationMs, ')
|
||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('albumId: $albumId, ')
|
..write('albumId: $albumId, ')
|
||||||
..write('checksum: $checksum, ')
|
..write('checksum: $checksum, ')
|
||||||
|
|||||||
@@ -10,18 +10,22 @@ import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
|||||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/memory.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/memory.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/person.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/person.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_asset_cloud_id.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_asset_cloud_id.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/stack.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/stack.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.drift.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.drift.dart';
|
||||||
@@ -50,6 +54,7 @@ import 'package:immich_mobile/infrastructure/repositories/db.repository.steps.da
|
|||||||
StoreEntity,
|
StoreEntity,
|
||||||
TrashedLocalAssetEntity,
|
TrashedLocalAssetEntity,
|
||||||
AssetEditEntity,
|
AssetEditEntity,
|
||||||
|
MetadataEntity,
|
||||||
],
|
],
|
||||||
include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'},
|
include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'},
|
||||||
)
|
)
|
||||||
@@ -81,7 +86,7 @@ class Drift extends $Drift {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 22;
|
int get schemaVersion => 25;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
@@ -222,6 +227,34 @@ class Drift extends $Drift {
|
|||||||
await m.createTable(v22.assetEditEntity);
|
await m.createTable(v22.assetEditEntity);
|
||||||
await m.createIndex(v22.idxAssetEditAssetId);
|
await m.createIndex(v22.idxAssetEditAssetId);
|
||||||
},
|
},
|
||||||
|
from22To23: (m, v23) async {
|
||||||
|
await m.renameColumn(v23.localAssetEntity, 'duration_in_seconds', v23.localAssetEntity.durationMs);
|
||||||
|
await m.renameColumn(v23.remoteAssetEntity, 'duration_in_seconds', v23.remoteAssetEntity.durationMs);
|
||||||
|
await m.renameColumn(
|
||||||
|
v23.trashedLocalAssetEntity,
|
||||||
|
'duration_in_seconds',
|
||||||
|
v23.trashedLocalAssetEntity.durationMs,
|
||||||
|
);
|
||||||
|
|
||||||
|
await localAssetEntity.update().write(
|
||||||
|
LocalAssetEntityCompanion.custom(durationMs: v23.localAssetEntity.durationMs * const Constant(1000)),
|
||||||
|
);
|
||||||
|
await remoteAssetEntity.update().write(
|
||||||
|
RemoteAssetEntityCompanion.custom(durationMs: v23.remoteAssetEntity.durationMs * const Constant(1000)),
|
||||||
|
);
|
||||||
|
await trashedLocalAssetEntity.update().write(
|
||||||
|
TrashedLocalAssetEntityCompanion.custom(
|
||||||
|
durationMs: v23.trashedLocalAssetEntity.durationMs * const Constant(1000),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
from23To24: (m, v24) async {
|
||||||
|
await customStatement('DROP INDEX IF EXISTS idx_remote_album_owner_id');
|
||||||
|
await m.alterTable(TableMigration(v24.remoteAlbumEntity));
|
||||||
|
},
|
||||||
|
from24To25: (m, v25) async {
|
||||||
|
await m.createTable(v25.metadata);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+12
-14
@@ -43,9 +43,11 @@ import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity
|
|||||||
as i20;
|
as i20;
|
||||||
import 'package:immich_mobile/infrastructure/entities/asset_edit.entity.drift.dart'
|
import 'package:immich_mobile/infrastructure/entities/asset_edit.entity.drift.dart'
|
||||||
as i21;
|
as i21;
|
||||||
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'
|
||||||
as i22;
|
as i22;
|
||||||
import 'package:drift/internal/modular.dart' as i23;
|
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
||||||
|
as i23;
|
||||||
|
import 'package:drift/internal/modular.dart' as i24;
|
||||||
|
|
||||||
abstract class $Drift extends i0.GeneratedDatabase {
|
abstract class $Drift extends i0.GeneratedDatabase {
|
||||||
$Drift(i0.QueryExecutor e) : super(e);
|
$Drift(i0.QueryExecutor e) : super(e);
|
||||||
@@ -89,9 +91,12 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
|||||||
.$TrashedLocalAssetEntityTable(this);
|
.$TrashedLocalAssetEntityTable(this);
|
||||||
late final i21.$AssetEditEntityTable assetEditEntity = i21
|
late final i21.$AssetEditEntityTable assetEditEntity = i21
|
||||||
.$AssetEditEntityTable(this);
|
.$AssetEditEntityTable(this);
|
||||||
i22.MergedAssetDrift get mergedAssetDrift => i23.ReadDatabaseContainer(
|
late final i22.$MetadataEntityTable metadataEntity = i22.$MetadataEntityTable(
|
||||||
this,
|
this,
|
||||||
).accessor<i22.MergedAssetDrift>(i22.MergedAssetDrift.new);
|
);
|
||||||
|
i23.MergedAssetDrift get mergedAssetDrift => i24.ReadDatabaseContainer(
|
||||||
|
this,
|
||||||
|
).accessor<i23.MergedAssetDrift>(i23.MergedAssetDrift.new);
|
||||||
@override
|
@override
|
||||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||||
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||||
@@ -105,7 +110,6 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
|||||||
localAlbumEntity,
|
localAlbumEntity,
|
||||||
localAlbumAssetEntity,
|
localAlbumAssetEntity,
|
||||||
i7.idxLocalAlbumAssetAlbumAsset,
|
i7.idxLocalAlbumAssetAlbumAsset,
|
||||||
i5.idxRemoteAlbumOwnerId,
|
|
||||||
i4.idxLocalAssetChecksum,
|
i4.idxLocalAssetChecksum,
|
||||||
i4.idxLocalAssetCloudId,
|
i4.idxLocalAssetCloudId,
|
||||||
i3.idxStackPrimaryAssetId,
|
i3.idxStackPrimaryAssetId,
|
||||||
@@ -130,6 +134,7 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
|||||||
storeEntity,
|
storeEntity,
|
||||||
trashedLocalAssetEntity,
|
trashedLocalAssetEntity,
|
||||||
assetEditEntity,
|
assetEditEntity,
|
||||||
|
metadataEntity,
|
||||||
i10.idxPartnerSharedWithId,
|
i10.idxPartnerSharedWithId,
|
||||||
i11.idxLatLng,
|
i11.idxLatLng,
|
||||||
i12.idxRemoteAlbumAssetAlbumAsset,
|
i12.idxRemoteAlbumAssetAlbumAsset,
|
||||||
@@ -160,15 +165,6 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
|||||||
),
|
),
|
||||||
result: [i0.TableUpdate('stack_entity', kind: i0.UpdateKind.delete)],
|
result: [i0.TableUpdate('stack_entity', kind: i0.UpdateKind.delete)],
|
||||||
),
|
),
|
||||||
i0.WritePropagation(
|
|
||||||
on: i0.TableUpdateQuery.onTableName(
|
|
||||||
'user_entity',
|
|
||||||
limitUpdateKind: i0.UpdateKind.delete,
|
|
||||||
),
|
|
||||||
result: [
|
|
||||||
i0.TableUpdate('remote_album_entity', kind: i0.UpdateKind.delete),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
i0.WritePropagation(
|
i0.WritePropagation(
|
||||||
on: i0.TableUpdateQuery.onTableName(
|
on: i0.TableUpdateQuery.onTableName(
|
||||||
'remote_asset_entity',
|
'remote_asset_entity',
|
||||||
@@ -399,4 +395,6 @@ class $DriftManager {
|
|||||||
);
|
);
|
||||||
i21.$$AssetEditEntityTableTableManager get assetEditEntity =>
|
i21.$$AssetEditEntityTableTableManager get assetEditEntity =>
|
||||||
i21.$$AssetEditEntityTableTableManager(_db, _db.assetEditEntity);
|
i21.$$AssetEditEntityTableTableManager(_db, _db.assetEditEntity);
|
||||||
|
i22.$$MetadataEntityTableTableManager get metadataEntity =>
|
||||||
|
i22.$$MetadataEntityTableTableManager(_db, _db.metadataEntity);
|
||||||
}
|
}
|
||||||
|
|||||||
+2921
-2
File diff suppressed because it is too large
Load Diff
@@ -297,7 +297,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
|
|||||||
updatedAt: Value(asset.updatedAt),
|
updatedAt: Value(asset.updatedAt),
|
||||||
width: Value(asset.width),
|
width: Value(asset.width),
|
||||||
height: Value(asset.height),
|
height: Value(asset.height),
|
||||||
durationInSeconds: Value(asset.durationInSeconds),
|
durationMs: Value(asset.durationMs),
|
||||||
id: asset.id,
|
id: asset.id,
|
||||||
orientation: Value(asset.orientation),
|
orientation: Value(asset.orientation),
|
||||||
isFavorite: Value(asset.isFavorite),
|
isFavorite: Value(asset.isFavorite),
|
||||||
@@ -329,7 +329,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository {
|
|||||||
updatedAt: Value(asset.updatedAt),
|
updatedAt: Value(asset.updatedAt),
|
||||||
width: Value(asset.width),
|
width: Value(asset.width),
|
||||||
height: Value(asset.height),
|
height: Value(asset.height),
|
||||||
durationInSeconds: Value(asset.durationInSeconds),
|
durationMs: Value(asset.durationMs),
|
||||||
id: asset.id,
|
id: asset.id,
|
||||||
checksum: const Value(null),
|
checksum: const Value(null),
|
||||||
orientation: Value(asset.orientation),
|
orientation: Value(asset.orientation),
|
||||||
|
|||||||
@@ -109,31 +109,40 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
|||||||
return query.map((localAlbum) => localAlbum.toDto()).get();
|
return query.map((localAlbum) => localAlbum.toDto()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, List<LocalAsset>>> getAssetsFromBackupAlbums(Iterable<String> checksums) async {
|
Future<Map<String, List<LocalAsset>>> getAssetsFromBackupAlbums(Iterable<String> remoteIds) async {
|
||||||
if (checksums.isEmpty) {
|
if (remoteIds.isEmpty) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = <String, List<LocalAsset>>{};
|
final result = <String, List<LocalAsset>>{};
|
||||||
|
|
||||||
for (final slice in checksums.toSet().slices(kDriftMaxChunk)) {
|
for (final slice in remoteIds.toSet().slices(kDriftMaxChunk)) {
|
||||||
final rows =
|
final rows =
|
||||||
await (_db.select(_db.localAlbumAssetEntity).join([
|
await (_db.select(_db.localAlbumAssetEntity).join([
|
||||||
innerJoin(_db.localAlbumEntity, _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id)),
|
innerJoin(
|
||||||
|
_db.localAlbumEntity,
|
||||||
|
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
|
||||||
|
useColumns: false,
|
||||||
|
),
|
||||||
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
|
innerJoin(_db.localAssetEntity, _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id)),
|
||||||
|
innerJoin(
|
||||||
|
_db.remoteAssetEntity,
|
||||||
|
_db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum),
|
||||||
|
useColumns: false,
|
||||||
|
),
|
||||||
])..where(
|
])..where(
|
||||||
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) &
|
_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) &
|
||||||
_db.localAssetEntity.checksum.isIn(slice),
|
_db.remoteAssetEntity.id.isIn(slice),
|
||||||
))
|
))
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
for (final row in rows) {
|
for (final row in rows) {
|
||||||
final albumId = row.readTable(_db.localAlbumAssetEntity).albumId;
|
final albumId = row.readTable(_db.localAlbumAssetEntity).albumId;
|
||||||
final assetData = row.readTable(_db.localAssetEntity);
|
final asset = row.readTable(_db.localAssetEntity).toDto();
|
||||||
final asset = assetData.toDto();
|
|
||||||
(result[albumId] ??= <LocalAsset>[]).add(asset);
|
(result[albumId] ??= <LocalAsset>[]).add(asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/config/system_config.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/metadata_key.dart';
|
||||||
|
import 'package:immich_mobile/extensions/string_extensions.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
|
class MetadataRepository extends DriftDatabaseRepository {
|
||||||
|
final Drift _db;
|
||||||
|
final Map<MetadataKey, Object> _cache = {};
|
||||||
|
|
||||||
|
MetadataRepository._(this._db) : super(_db);
|
||||||
|
|
||||||
|
static MetadataRepository? _instance;
|
||||||
|
|
||||||
|
static MetadataRepository get instance {
|
||||||
|
final instance = _instance;
|
||||||
|
if (instance == null) {
|
||||||
|
throw StateError('MetadataRepository not initialized. Call ensureInitialized() first');
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppConfig _appConfig = const .new();
|
||||||
|
AppConfig get appConfig => _appConfig;
|
||||||
|
|
||||||
|
SystemConfig _systemConfig = const .new();
|
||||||
|
SystemConfig get systemConfig => _systemConfig;
|
||||||
|
|
||||||
|
static Future<MetadataRepository> ensureInitialized(Drift db) async {
|
||||||
|
if (_instance == null) {
|
||||||
|
final instance = MetadataRepository._(db);
|
||||||
|
await instance._hydrate();
|
||||||
|
_instance = instance;
|
||||||
|
}
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> refresh() async {
|
||||||
|
instance._cache.clear();
|
||||||
|
instance._appConfig = const .new();
|
||||||
|
instance._systemConfig = const .new();
|
||||||
|
await instance._hydrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _hydrate() async => _hydrateCache(await _db.select(_db.metadataEntity).get());
|
||||||
|
|
||||||
|
T _read<T extends Object>(MetadataKey<T> key) => (_cache[key] as T?) ?? key.defaultValue;
|
||||||
|
|
||||||
|
Future<void> write<T extends Object, U extends T>(MetadataKey<T> key, U value) async {
|
||||||
|
if (_read(key) == value) return;
|
||||||
|
|
||||||
|
await _db
|
||||||
|
.into(_db.metadataEntity)
|
||||||
|
.insertOnConflictUpdate(
|
||||||
|
MetadataEntityCompanion.insert(key: key.key, value: key.encode(value), updatedAt: Value(DateTime.now())),
|
||||||
|
);
|
||||||
|
_updateCache(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> delete<T extends Object>(MetadataKey<T> key) async {
|
||||||
|
await (_db.delete(_db.metadataEntity)..where((t) => t.key.equals(key.key))).go();
|
||||||
|
_updateCache(key, key.defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<AppConfig> watchAppConfig() => _watchDomain(MetadataDomain.appConfig).distinct();
|
||||||
|
|
||||||
|
Stream<SystemConfig> watchSystemConfig() => _watchDomain(MetadataDomain.systemConfig).distinct();
|
||||||
|
|
||||||
|
Stream<T> _watchDomain<T extends Object>(MetadataDomain<T> domain) {
|
||||||
|
final query = _db.select(_db.metadataEntity)..where((t) => t.key.like('${domain.prefix}.%'));
|
||||||
|
return query.watch().map((rows) {
|
||||||
|
_hydrateCache(rows);
|
||||||
|
return domain.config(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _hydrateCache(List<MetadataEntityData> rows) {
|
||||||
|
final keyMap = MetadataKey.asKeyMap();
|
||||||
|
for (final row in rows) {
|
||||||
|
final key = keyMap[row.key];
|
||||||
|
if (key == null) continue;
|
||||||
|
_updateCache(key, key.decode(row.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateCache<T extends Object>(MetadataKey<T> key, T value) {
|
||||||
|
if (_cache[key] == value) return;
|
||||||
|
_cache[key] = value;
|
||||||
|
key.domain.rebuild(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension<T extends Object> on MetadataDomain<T> {
|
||||||
|
T config(MetadataRepository repo) => switch (this) {
|
||||||
|
.appConfig => repo._appConfig as T,
|
||||||
|
.systemConfig => repo._systemConfig as T,
|
||||||
|
};
|
||||||
|
|
||||||
|
void rebuild(MetadataRepository repo) {
|
||||||
|
switch (this) {
|
||||||
|
case .appConfig:
|
||||||
|
repo._appConfig = .new(
|
||||||
|
theme: .new(
|
||||||
|
mode: repo._read(.themeMode),
|
||||||
|
primaryColor: repo._read(.themePrimaryColor),
|
||||||
|
dynamicTheme: repo._read(.themeDynamic),
|
||||||
|
colorfulInterface: repo._read(.themeColorfulInterface),
|
||||||
|
),
|
||||||
|
cleanup: .new(
|
||||||
|
keepFavorites: repo._read(.cleanupKeepFavorites),
|
||||||
|
keepMediaType: repo._read(.cleanupKeepMediaType),
|
||||||
|
keepAlbumIds: repo._read(.cleanupKeepAlbumIds),
|
||||||
|
cutoffDaysAgo: repo._read(.cleanupCutoffDaysAgo),
|
||||||
|
defaultsInitialized: repo._read(.cleanupDefaultsInitialized),
|
||||||
|
),
|
||||||
|
map: .new(
|
||||||
|
relativeDays: repo._read(.mapRelativeDate),
|
||||||
|
favoritesOnly: repo._read(.mapShowFavoriteOnly),
|
||||||
|
includeArchived: repo._read(.mapIncludeArchived),
|
||||||
|
themeMode: repo._read(.mapThemeMode),
|
||||||
|
withPartners: repo._read(.mapWithPartners),
|
||||||
|
),
|
||||||
|
timeline: .new(
|
||||||
|
tilesPerRow: repo._read(.timelineTilesPerRow),
|
||||||
|
groupAssetsBy: repo._read(.timelineGroupAssetsBy),
|
||||||
|
storageIndicator: repo._read(.timelineStorageIndicator),
|
||||||
|
),
|
||||||
|
image: .new(preferRemote: repo._read(.imagePreferRemote), loadOriginal: repo._read(.imageLoadOriginal)),
|
||||||
|
viewer: .new(
|
||||||
|
loopVideo: repo._read(.viewerLoopVideo),
|
||||||
|
loadOriginalVideo: repo._read(.viewerLoadOriginalVideo),
|
||||||
|
autoPlayVideo: repo._read(.viewerAutoPlayVideo),
|
||||||
|
tapToNavigate: repo._read(.viewerTapToNavigate),
|
||||||
|
),
|
||||||
|
album: .new(
|
||||||
|
sortMode: repo._read(.albumSortMode),
|
||||||
|
isReverse: repo._read(.albumIsReverse),
|
||||||
|
isGrid: repo._read(.albumIsGrid),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case .systemConfig:
|
||||||
|
repo._systemConfig = .new(
|
||||||
|
logLevel: repo._read(.logLevel),
|
||||||
|
network: .new(
|
||||||
|
autoEndpointSwitching: repo._read(.networkAutoEndpointSwitching),
|
||||||
|
preferredWifiName: repo._read(.networkPreferredWifiName).nullIfEmpty,
|
||||||
|
localEndpoint: repo._read(.networkLocalEndpoint).nullIfEmpty,
|
||||||
|
externalEndpointList: repo._read(.networkExternalEndpointList),
|
||||||
|
customHeaders: repo._read(.networkCustomHeaders),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user