Compare commits

..

14 Commits

Author SHA1 Message Date
Alex 5645f9982d wip 2024-12-20 13:01:18 -06:00
Alex 90f893df66 wip 2024-12-20 10:12:52 -06:00
Alex 9e99973c18 wip 2024-12-19 16:53:48 -06:00
Alex 5818197c10 feat(mobile): onboarding 2024-12-19 10:07:01 -06:00
Michel Heusschen 79a780e8d9 fix(web): downloading partner assets (#14803) 2024-12-19 14:56:16 +00:00
Slavik 556c59f12f docs: misspelled var "urls" in the "machineLearning" (#14786)
[docs] misspelled var "urls" in the "machineLearning"

Co-authored-by: slavik.fursov <slavik.fursov@oracle.com>
2024-12-18 19:57:25 -05:00
renovate[bot] 8e724c3c27 chore(deps): update base-image to v20241217 (major) (#14776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-18 18:27:08 +00:00
renovate[bot] 207bb527bb chore(deps): update dependency exiftool-vendored to v28.8.0 (#13924)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-18 18:14:30 +00:00
Alex b034cb1861 fix(mobile): keep empty album as selected target (#14778) 2024-12-18 11:10:29 -06:00
Daniel Dietzler 6a855f6331 chore: update deps (#14755) 2024-12-18 14:19:48 +00:00
renovate[bot] a03f4f5610 chore(deps): update docker/setup-buildx-action action to v3.8.0 (#14757)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-18 14:18:21 +00:00
renovate[bot] e0fc8734bf chore(deps): update dependency ruff to v0.8.3 (#14756)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-17 15:35:22 -05:00
renovate[bot] 0d060ebb32 chore(deps): update node (#14736)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-17 15:21:01 -05:00
Alex f58b2572e6 chore: post release tasks (#14749) 2024-12-17 14:02:07 -06:00
55 changed files with 5105 additions and 14323 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0 uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.7.1 uses: docker/setup-buildx-action@v3.8.0
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
+2 -2
View File
@@ -125,7 +125,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0 uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.7.1 uses: docker/setup-buildx-action@v3.8.0
- name: Login to Docker Hub - name: Login to Docker Hub
# Only push to Docker Hub when making a release # Only push to Docker Hub when making a release
@@ -216,7 +216,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0 uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.7.1 uses: docker/setup-buildx-action@v3.8.0
- name: Login to Docker Hub - name: Login to Docker Hub
# Only push to Docker Hub when making a release # Only push to Docker Hub when making a release
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:22.11.0-alpine3.20@sha256:b64ced2e7cd0a4816699fe308ce6e8a08ccba463c757c00c14cd372e3d2c763e AS core FROM node:22.12.0-alpine3.20@sha256:96cc8323e25c8cc6ddcb8b965e135cfd57846e8003ec0d7bcec16c5fd5f6d39f AS core
WORKDIR /usr/src/open-api/typescript-sdk WORKDIR /usr/src/open-api/typescript-sdk
COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./ COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./
+64 -55
View File
@@ -24,7 +24,7 @@
"@types/cli-progress": "^3.11.0", "@types/cli-progress": "^3.11.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0", "@typescript-eslint/parser": "^8.15.0",
"@vitest/coverage-v8": "^2.0.5", "@vitest/coverage-v8": "^2.0.5",
@@ -34,7 +34,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"mock-fs": "^5.2.0", "mock-fs": "^5.2.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
@@ -59,7 +59,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@@ -1397,13 +1397,13 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.9.0", "version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.8" "undici-types": "~6.20.0"
} }
}, },
"node_modules/@types/normalize-package-data": { "node_modules/@types/normalize-package-data": {
@@ -1876,9 +1876,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.23.0", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -1894,11 +1894,12 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001587", "caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.4.668", "electron-to-chromium": "^1.5.73",
"node-releases": "^2.0.14", "node-releases": "^2.0.19",
"update-browserslist-db": "^1.0.13" "update-browserslist-db": "^1.1.1"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@@ -1949,9 +1950,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001597", "version": "1.0.30001689",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz",
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -1966,7 +1967,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/chai": { "node_modules/chai": {
"version": "5.1.2", "version": "5.1.2",
@@ -2095,12 +2097,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/core-js-compat": { "node_modules/core-js-compat": {
"version": "3.37.1", "version": "3.39.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"browserslist": "^4.23.0" "browserslist": "^4.24.2"
}, },
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
@@ -2163,10 +2166,11 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.705", "version": "1.5.74",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.705.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
"integrity": "sha512-LKqhpwJCLhYId2VVwEzFXWrqQI5n5zBppz1W9ehhTlfYU8CUUW6kClbN8LHF/v7flMgRdETS772nqywJ+ckVAw==", "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
"dev": true "dev": true,
"license": "ISC"
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@@ -2230,10 +2234,11 @@
} }
}, },
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.1.2", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -2355,19 +2360,19 @@
} }
}, },
"node_modules/eslint-plugin-unicorn": { "node_modules/eslint-plugin-unicorn": {
"version": "55.0.0", "version": "56.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-55.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz",
"integrity": "sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==", "integrity": "sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-validator-identifier": "^7.24.5", "@babel/helper-validator-identifier": "^7.24.7",
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"ci-info": "^4.0.0", "ci-info": "^4.0.0",
"clean-regexp": "^1.0.0", "clean-regexp": "^1.0.0",
"core-js-compat": "^3.37.0", "core-js-compat": "^3.38.1",
"esquery": "^1.5.0", "esquery": "^1.6.0",
"globals": "^15.7.0", "globals": "^15.9.0",
"indent-string": "^4.0.0", "indent-string": "^4.0.0",
"is-builtin-module": "^3.2.1", "is-builtin-module": "^3.2.1",
"jsesc": "^3.0.2", "jsesc": "^3.0.2",
@@ -2375,7 +2380,7 @@
"read-pkg-up": "^7.0.1", "read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.27", "regexp-tree": "^0.1.27",
"regjsparser": "^0.10.0", "regjsparser": "^0.10.0",
"semver": "^7.6.1", "semver": "^7.6.3",
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0"
}, },
"engines": { "engines": {
@@ -2503,10 +2508,11 @@
} }
}, },
"node_modules/esquery": { "node_modules/esquery": {
"version": "1.5.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true, "dev": true,
"license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"estraverse": "^5.1.0" "estraverse": "^5.1.0"
}, },
@@ -3253,10 +3259,11 @@
"dev": true "dev": true
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/normalize-package-data": { "node_modules/normalize-package-data": {
"version": "2.5.0", "version": "2.5.0",
@@ -3792,10 +3799,11 @@
} }
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.6.2", "version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true, "dev": true,
"license": "ISC",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
}, },
@@ -4156,16 +4164,16 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.8", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.0.13", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -4181,9 +4189,10 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"escalade": "^3.1.1", "escalade": "^3.2.0",
"picocolors": "^1.0.0" "picocolors": "^1.1.0"
}, },
"bin": { "bin": {
"update-browserslist-db": "cli.js" "update-browserslist-db": "cli.js"
+2 -2
View File
@@ -20,7 +20,7 @@
"@types/cli-progress": "^3.11.0", "@types/cli-progress": "^3.11.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0", "@typescript-eslint/parser": "^8.15.0",
"@vitest/coverage-v8": "^2.0.5", "@vitest/coverage-v8": "^2.0.5",
@@ -30,7 +30,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"mock-fs": "^5.2.0", "mock-fs": "^5.2.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
+1 -1
View File
@@ -83,7 +83,7 @@ The default configuration looks like this:
}, },
"machineLearning": { "machineLearning": {
"enabled": true, "enabled": true,
"url": ["http://immich-machine-learning:3003"], "urls": ["http://immich-machine-learning:3003"],
"clip": { "clip": {
"enabled": true, "enabled": true,
"modelName": "ViT-B-32__openai" "modelName": "ViT-B-32__openai"
-1
View File
@@ -36,7 +36,6 @@
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "~3.5.2", "@docusaurus/module-type-aliases": "~3.5.2",
"@tsconfig/docusaurus": "^2.0.2",
"prettier": "^3.2.4", "prettier": "^3.2.4",
"typescript": "^5.1.6" "typescript": "^5.1.6"
}, },
+77 -68
View File
@@ -15,7 +15,7 @@
"@immich/sdk": "file:../open-api/typescript-sdk", "@immich/sdk": "file:../open-api/typescript-sdk",
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@types/oidc-provider": "^8.5.1", "@types/oidc-provider": "^8.5.1",
"@types/pg": "^8.11.0", "@types/pg": "^8.11.0",
"@types/pngjs": "^6.0.4", "@types/pngjs": "^6.0.4",
@@ -26,7 +26,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"exiftool-vendored": "^28.3.1", "exiftool-vendored": "^28.3.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"jose": "^5.6.3", "jose": "^5.6.3",
@@ -64,7 +64,7 @@
"@types/cli-progress": "^3.11.0", "@types/cli-progress": "^3.11.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0", "@typescript-eslint/parser": "^8.15.0",
"@vitest/coverage-v8": "^2.0.5", "@vitest/coverage-v8": "^2.0.5",
@@ -74,7 +74,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"mock-fs": "^5.2.0", "mock-fs": "^5.2.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
@@ -99,7 +99,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@@ -1658,13 +1658,13 @@
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.9.0", "version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.8" "undici-types": "~6.20.0"
} }
}, },
"node_modules/@types/normalize-package-data": { "node_modules/@types/normalize-package-data": {
@@ -2381,9 +2381,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.23.0", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -2399,11 +2399,12 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001587", "caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.4.668", "electron-to-chromium": "^1.5.73",
"node-releases": "^2.0.14", "node-releases": "^2.0.19",
"update-browserslist-db": "^1.0.13" "update-browserslist-db": "^1.1.1"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@@ -2524,9 +2525,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001591", "version": "1.0.30001689",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz",
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -2541,7 +2542,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/chai": { "node_modules/chai": {
"version": "5.1.2", "version": "5.1.2",
@@ -2757,12 +2759,13 @@
} }
}, },
"node_modules/core-js-compat": { "node_modules/core-js-compat": {
"version": "3.37.1", "version": "3.39.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"browserslist": "^4.23.0" "browserslist": "^4.24.2"
}, },
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
@@ -2943,10 +2946,11 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.687", "version": "1.5.74",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.687.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
"integrity": "sha512-Ic85cOuXSP6h7KM0AIJ2hpJ98Bo4hyTUjc4yjMbkvD+8yTxEhfK9+8exT2KKYsSjnCn2tGsKVSZwE7ZgTORQCw==", "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
"dev": true "dev": true,
"license": "ISC"
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@@ -3063,10 +3067,11 @@
} }
}, },
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.1.2", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -3194,19 +3199,19 @@
} }
}, },
"node_modules/eslint-plugin-unicorn": { "node_modules/eslint-plugin-unicorn": {
"version": "55.0.0", "version": "56.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-55.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz",
"integrity": "sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==", "integrity": "sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-validator-identifier": "^7.24.5", "@babel/helper-validator-identifier": "^7.24.7",
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"ci-info": "^4.0.0", "ci-info": "^4.0.0",
"clean-regexp": "^1.0.0", "clean-regexp": "^1.0.0",
"core-js-compat": "^3.37.0", "core-js-compat": "^3.38.1",
"esquery": "^1.5.0", "esquery": "^1.6.0",
"globals": "^15.7.0", "globals": "^15.9.0",
"indent-string": "^4.0.0", "indent-string": "^4.0.0",
"is-builtin-module": "^3.2.1", "is-builtin-module": "^3.2.1",
"jsesc": "^3.0.2", "jsesc": "^3.0.2",
@@ -3214,7 +3219,7 @@
"read-pkg-up": "^7.0.1", "read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.27", "regexp-tree": "^0.1.27",
"regjsparser": "^0.10.0", "regjsparser": "^0.10.0",
"semver": "^7.6.1", "semver": "^7.6.3",
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0"
}, },
"engines": { "engines": {
@@ -3311,10 +3316,11 @@
} }
}, },
"node_modules/esquery": { "node_modules/esquery": {
"version": "1.5.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true, "dev": true,
"license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"estraverse": "^5.1.0" "estraverse": "^5.1.0"
}, },
@@ -3377,9 +3383,9 @@
} }
}, },
"node_modules/exiftool-vendored": { "node_modules/exiftool-vendored": {
"version": "28.7.0", "version": "28.8.0",
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-28.7.0.tgz", "resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-28.8.0.tgz",
"integrity": "sha512-0zoq6kBS1yPjzJs+p0qZDinWEA72PTKoRk5ETYKfmeRcZAkhv83Y3HCpbb/LdgJJywfm8BcIJGezrBHvL7dVnQ==", "integrity": "sha512-R7tirJLr9fWuH9JS/KFFLB+O7jNGKuPXGxREc6YybYangEudGb+X8ERsYXk9AifMiAWh/2agNfbgkbcQcF+MxA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -3390,14 +3396,14 @@
"luxon": "^3.5.0" "luxon": "^3.5.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"exiftool-vendored.exe": "12.99.0", "exiftool-vendored.exe": "13.0.0",
"exiftool-vendored.pl": "12.99.0" "exiftool-vendored.pl": "13.0.1"
} }
}, },
"node_modules/exiftool-vendored.exe": { "node_modules/exiftool-vendored.exe": {
"version": "12.99.0", "version": "13.0.0",
"resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-12.99.0.tgz", "resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-13.0.0.tgz",
"integrity": "sha512-ffpJHCzC9OYJqw4JlPNtCwRy02jwhmnSJEF/QqEjpuIWDEnlRBQP/yWRh1Nw21K1R4FB4yG5PlCgEDu09VQz/w==", "integrity": "sha512-4zAMuFGgxZkOoyQIzZMHv1HlvgyJK3AkNqjAgm8A8V0UmOZO7yv3pH49cDV1OduzFJqgs6yQ6eG4OGydhKtxlg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -3406,9 +3412,9 @@
] ]
}, },
"node_modules/exiftool-vendored.pl": { "node_modules/exiftool-vendored.pl": {
"version": "12.99.0", "version": "13.0.1",
"resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-12.99.0.tgz", "resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-13.0.1.tgz",
"integrity": "sha512-qRVEPQxtoerXF+izJ0O7jGAr5o0Uyvnyu7ao5DTKzF+V7Fv3SurE0l43oCeZPFKo/Ld4V7vEylhFCm4IHVZKWA==", "integrity": "sha512-+BRRzjselpWudKR0ltAW5SUt9T82D+gzQN8DdOQUgnSVWWp7oLCeTGBRptbQz+436Ihn/mPzmo/xnf0cv/Qw1A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -4765,10 +4771,11 @@
} }
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true "dev": true,
"license": "MIT"
}, },
"node_modules/nopt": { "node_modules/nopt": {
"version": "5.0.0", "version": "5.0.0",
@@ -5819,10 +5826,11 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.6.2", "version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true, "dev": true,
"license": "ISC",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
}, },
@@ -6409,9 +6417,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.8", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -6425,9 +6433,9 @@
} }
}, },
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.0.13", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -6443,9 +6451,10 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"escalade": "^3.1.1", "escalade": "^3.2.0",
"picocolors": "^1.0.0" "picocolors": "^1.1.0"
}, },
"bin": { "bin": {
"update-browserslist-db": "cli.js" "update-browserslist-db": "cli.js"
+2 -2
View File
@@ -25,7 +25,7 @@
"@immich/sdk": "file:../open-api/typescript-sdk", "@immich/sdk": "file:../open-api/typescript-sdk",
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@types/oidc-provider": "^8.5.1", "@types/oidc-provider": "^8.5.1",
"@types/pg": "^8.11.0", "@types/pg": "^8.11.0",
"@types/pngjs": "^6.0.4", "@types/pngjs": "^6.0.4",
@@ -36,7 +36,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"exiftool-vendored": "^28.3.1", "exiftool-vendored": "^28.3.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"jose": "^5.6.3", "jose": "^5.6.3",
+19 -19
View File
@@ -3043,29 +3043,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.8.2" version = "0.8.3"
description = "An extremely fast Python linter and code formatter, written in Rust." description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"}, {file = "ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6"},
{file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"}, {file = "ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939"},
{file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"}, {file = "ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452"},
{file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"}, {file = "ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"}, {file = "ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"}, {file = "ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"}, {file = "ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060"},
{file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"}, {file = "ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea"},
{file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"}, {file = "ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964"},
{file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"}, {file = "ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9"},
{file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"}, {file = "ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936"},
{file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"}, {file = "ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3"},
] ]
[[package]] [[package]]
Binary file not shown.

After

Width:  |  Height:  |  Size: 689 KiB

+3 -3
View File
@@ -403,7 +403,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 185; CURRENT_PROJECT_VERSION = 186;
DEVELOPMENT_TEAM = 2F67MQ8R79; DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -546,7 +546,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 185; CURRENT_PROJECT_VERSION = 186;
DEVELOPMENT_TEAM = 2F67MQ8R79; DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -575,7 +575,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 185; CURRENT_PROJECT_VERSION = 186;
DEVELOPMENT_TEAM = 2F67MQ8R79; DEVELOPMENT_TEAM = 2F67MQ8R79;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
+2 -2
View File
@@ -58,11 +58,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.122.3</string> <string>1.123.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>185</string> <string>186</string>
<key>FLTEnableImpeller</key> <key>FLTEnableImpeller</key>
<true/> <true/>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
@@ -0,0 +1,383 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_svg/svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
@RoutePage()
class OnboardingPage extends HookConsumerWidget {
const OnboardingPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final pageController = usePageController(keepPage: false);
toNextPage() {
pageController.nextPage(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
return Scaffold(
appBar: AppBar(
title: SvgPicture.asset(
context.isDarkTheme
? 'assets/immich-logo-inline-dark.svg'
: 'assets/immich-logo-inline-light.svg',
height: 48,
),
centerTitle: false,
elevation: 0,
),
body: SafeArea(
child: PageView(
controller: pageController,
// physics: const NeverScrollableScrollPhysics(),
children: [
OnboardingWelcome(
onNextPage: () => toNextPage(),
),
OnboardingGalleryPermission(
onNextPage: () => toNextPage(),
),
OnboardingLocationPermission(
onNextPage: () => toNextPage(),
),
],
),
),
);
}
}
class OnboardingWelcome extends StatelessWidget {
final VoidCallback onNextPage;
const OnboardingWelcome({super.key, required this.onNextPage});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(18.0),
child: ListView(
physics: const ClampingScrollPhysics(),
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Card(
clipBehavior: Clip.antiAlias,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(32),
),
),
elevation: 3,
child: AnimatedHeroImage(
imagePath: 'assets/onboarding-1-screenshot.jpeg',
color: context.colorScheme.primary.withOpacity(0.25),
colorBlendMode: BlendMode.color,
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 32.0,
left: 8.0,
bottom: 8.0,
),
child: Text(
"WELCOME",
style: context.textTheme.labelLarge?.copyWith(
color: context.colorScheme.onSurface.withOpacity(0.6),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"Lets get you setup with some permissions that the app needs",
style: context.textTheme.headlineSmall,
),
),
const SizedBox(height: 24),
Padding(
padding: const EdgeInsets.only(right: 8.0, top: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
width: 64,
height: 64,
child: MaterialButton(
onPressed: onNextPage,
color: context.primaryColor,
textColor: Colors.white,
shape: const CircleBorder(),
child: Icon(
Icons.chevron_right_rounded,
color: context.colorScheme.onPrimary,
size: 32,
),
),
),
],
),
),
],
),
);
}
}
class AnimatedHeroImage extends StatefulWidget {
final String imagePath;
final Color color;
final BlendMode colorBlendMode;
const AnimatedHeroImage({
super.key,
required this.imagePath,
required this.color,
required this.colorBlendMode,
});
@override
AnimatedHeroImageState createState() => AnimatedHeroImageState();
}
class AnimatedHeroImageState extends State<AnimatedHeroImage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<double> _rotationAnimation;
late Animation<Offset> _parallaxAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 15),
vsync: this,
)..repeat(reverse: true);
_scaleAnimation = Tween<double>(begin: 1.0, end: 1.15).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
),
);
_rotationAnimation = Tween<double>(begin: 0.0, end: 0.025).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
),
);
_parallaxAnimation =
Tween<Offset>(begin: Offset.zero, end: const Offset(0.05, 0.05))
.animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
child: Image(
image: AssetImage(widget.imagePath),
filterQuality: FilterQuality.high,
isAntiAlias: true,
// color: widget.color,
// colorBlendMode: widget.colorBlendMode,
),
builder: (context, child) {
return Transform.scale(
scale: _scaleAnimation.value,
child: Transform.rotate(
angle: _rotationAnimation.value,
child: Transform.translate(
offset: _parallaxAnimation.value,
child: child,
),
),
);
},
);
}
}
class OnboardingGalleryPermission extends StatelessWidget {
final VoidCallback onNextPage;
const OnboardingGalleryPermission({super.key, required this.onNextPage});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: PermissionInfoTemplate(
icon: Icons.perm_media_outlined,
title: "Gallery Permission",
subtitle:
"We use the read and write permission of the media gallery for the following actions",
descriptionList: [
'Display the local videos and images',
'Read the file content to upload to your Immich instance',
'Remove media from the device on your request',
],
onConfirm: onNextPage,
),
);
}
}
class OnboardingLocationPermission extends StatelessWidget {
final VoidCallback onNextPage;
const OnboardingLocationPermission({super.key, required this.onNextPage});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: PermissionInfoTemplate(
icon: Icons.location_on_outlined,
title: "Location Permission",
subtitle:
"We use the always on, precise location access for the following actions",
descriptionList: [
'Display the local videos and images',
'Read the file content to upload to your Immich instance',
'Remove media from the device on your request',
],
onConfirm: onNextPage,
),
);
}
}
class PermissionInfoTemplate extends StatelessWidget {
final String title;
final String subtitle;
final List<String> descriptionList;
final VoidCallback onConfirm;
final IconData icon;
const PermissionInfoTemplate({
super.key,
required this.title,
required this.subtitle,
required this.descriptionList,
required this.onConfirm,
required this.icon,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(
icon,
size: 32,
color: context.primaryColor.withAlpha(250),
),
const SizedBox(width: 16),
Text(
title,
style: context.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w600,
color: context.primaryColor,
),
),
],
),
const SizedBox(height: 16),
Text(
subtitle,
style: context.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w400,
color: context.colorScheme.onSurface.withAlpha(220),
),
),
const SizedBox(height: 40),
BulletList(descriptionList),
const Spacer(),
SizedBox(
height: 48,
width: double.infinity,
child: ElevatedButton(
onPressed: onConfirm,
child: const Text(
'OK',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
),
),
],
);
}
}
class BulletList extends StatelessWidget {
final List<String> strings;
const BulletList(this.strings, {super.key});
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: strings.map((textString) {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'\u2022',
style: TextStyle(
fontSize: 20,
height: 1.25,
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
textString,
textAlign: TextAlign.left,
softWrap: true,
style: context.textTheme.headlineSmall?.copyWith(
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
),
],
),
);
}).toList(),
),
);
}
}
@@ -14,7 +14,6 @@ class AlbumMediaRepository implements IAlbumMediaRepository {
final List<AssetPathEntity> assetPathEntities = final List<AssetPathEntity> assetPathEntities =
await PhotoManager.getAssetPathList( await PhotoManager.getAssetPathList(
hasAll: true, hasAll: true,
filterOption: FilterOptionGroup(containsPathModified: true),
); );
return assetPathEntities.map(_toAlbum).toList(); return assetPathEntities.map(_toAlbum).toList();
} }
+3 -1
View File
@@ -41,6 +41,7 @@ import 'package:immich_mobile/pages/library/favorite.page.dart';
import 'package:immich_mobile/pages/library/trash.page.dart'; import 'package:immich_mobile/pages/library/trash.page.dart';
import 'package:immich_mobile/pages/login/change_password.page.dart'; import 'package:immich_mobile/pages/login/change_password.page.dart';
import 'package:immich_mobile/pages/login/login.page.dart'; import 'package:immich_mobile/pages/login/login.page.dart';
import 'package:immich_mobile/pages/onboarding/onboarding.page.dart';
import 'package:immich_mobile/pages/onboarding/permission_onboarding.page.dart'; import 'package:immich_mobile/pages/onboarding/permission_onboarding.page.dart';
import 'package:immich_mobile/pages/photos/memory.page.dart'; import 'package:immich_mobile/pages/photos/memory.page.dart';
import 'package:immich_mobile/pages/photos/photos.page.dart'; import 'package:immich_mobile/pages/photos/photos.page.dart';
@@ -90,7 +91,8 @@ class AppRouter extends RootStackRouter {
@override @override
late final List<AutoRoute> routes = [ late final List<AutoRoute> routes = [
AutoRoute(page: SplashScreenRoute.page, initial: true), AutoRoute(page: OnboardingRoute.page, initial: true),
AutoRoute(page: SplashScreenRoute.page),
AutoRoute( AutoRoute(
page: PermissionOnboardingRoute.page, page: PermissionOnboardingRoute.page,
guards: [_authGuard, _duplicateGuard], guards: [_authGuard, _duplicateGuard],
+23 -23
View File
@@ -136,15 +136,10 @@ class AlbumAssetSelectionRouteArgs {
/// generated route for /// generated route for
/// [AlbumOptionsPage] /// [AlbumOptionsPage]
class AlbumOptionsRoute extends PageRouteInfo<AlbumOptionsRouteArgs> { class AlbumOptionsRoute extends PageRouteInfo<void> {
AlbumOptionsRoute({ const AlbumOptionsRoute({List<PageRouteInfo>? children})
Key? key, : super(
List<PageRouteInfo>? children,
}) : super(
AlbumOptionsRoute.name, AlbumOptionsRoute.name,
args: AlbumOptionsRouteArgs(
key: key,
),
initialChildren: children, initialChildren: children,
); );
@@ -153,25 +148,11 @@ class AlbumOptionsRoute extends PageRouteInfo<AlbumOptionsRouteArgs> {
static PageInfo page = PageInfo( static PageInfo page = PageInfo(
name, name,
builder: (data) { builder: (data) {
final args = data.argsAs<AlbumOptionsRouteArgs>(); return const AlbumOptionsPage();
return AlbumOptionsPage(
key: args.key,
);
}, },
); );
} }
class AlbumOptionsRouteArgs {
const AlbumOptionsRouteArgs({this.key});
final Key? key;
@override
String toString() {
return 'AlbumOptionsRouteArgs{key: $key}';
}
}
/// generated route for /// generated route for
/// [AlbumPreviewPage] /// [AlbumPreviewPage]
class AlbumPreviewRoute extends PageRouteInfo<AlbumPreviewRouteArgs> { class AlbumPreviewRoute extends PageRouteInfo<AlbumPreviewRouteArgs> {
@@ -1129,6 +1110,25 @@ class NativeVideoViewerRouteArgs {
} }
} }
/// generated route for
/// [OnboardingPage]
class OnboardingRoute extends PageRouteInfo<void> {
const OnboardingRoute({List<PageRouteInfo>? children})
: super(
OnboardingRoute.name,
initialChildren: children,
);
static const String name = 'OnboardingRoute';
static PageInfo page = PageInfo(
name,
builder: (data) {
return const OnboardingPage();
},
);
}
/// generated route for /// generated route for
/// [PartnerDetailPage] /// [PartnerDetailPage]
class PartnerDetailRoute extends PageRouteInfo<PartnerDetailRouteArgs> { class PartnerDetailRoute extends PageRouteInfo<PartnerDetailRouteArgs> {
+8 -8
View File
@@ -12,7 +12,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@@ -22,13 +22,13 @@
"integrity": "sha512-8tKiYffhwTGHSHYGnZ3oneLGCjX0po/XAXQ5Ng9fqKkvIdl/xz8+Vh8i+6xjzZqvZ2pLVpUcuSfnvNI/x67L0g==" "integrity": "sha512-8tKiYffhwTGHSHYGnZ3oneLGCjX0po/XAXQ5Ng9fqKkvIdl/xz8+Vh8i+6xjzZqvZ2pLVpUcuSfnvNI/x67L0g=="
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.9.0", "version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.8" "undici-types": "~6.20.0"
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
@@ -46,9 +46,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.8", "version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
} }
+1 -1
View File
@@ -19,7 +19,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"repository": { "repository": {
+3 -3
View File
@@ -1,5 +1,5 @@
# dev build # dev build
FROM ghcr.io/immich-app/base-server-dev:20241210@sha256:35c28404b508fc0741fffb39a9de17e3a6acdff0b623bb7b6cdf4a427462a0e2 AS dev FROM ghcr.io/immich-app/base-server-dev:20241217@sha256:7e69fa317cf90a0345927bbea13438dc39efc584bac13ff77ea5735c57cd008a AS dev
RUN apt-get install --no-install-recommends -yqq tini RUN apt-get install --no-install-recommends -yqq tini
WORKDIR /usr/src/app WORKDIR /usr/src/app
@@ -25,7 +25,7 @@ COPY --from=dev /usr/src/app/node_modules/@img ./node_modules/@img
COPY --from=dev /usr/src/app/node_modules/exiftool-vendored.pl ./node_modules/exiftool-vendored.pl COPY --from=dev /usr/src/app/node_modules/exiftool-vendored.pl ./node_modules/exiftool-vendored.pl
# web build # web build
FROM node:22.11.0-alpine3.20@sha256:b64ced2e7cd0a4816699fe308ce6e8a08ccba463c757c00c14cd372e3d2c763e AS web FROM node:22.12.0-alpine3.20@sha256:96cc8323e25c8cc6ddcb8b965e135cfd57846e8003ec0d7bcec16c5fd5f6d39f AS web
WORKDIR /usr/src/open-api/typescript-sdk WORKDIR /usr/src/open-api/typescript-sdk
COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./ COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./
@@ -42,7 +42,7 @@ RUN npm run build
# prod build # prod build
FROM ghcr.io/immich-app/base-server-prod:20241210@sha256:076d002070385bc6dc7454ef9419f44341c074bcfc49be5deddbdb4108ae0060 FROM ghcr.io/immich-app/base-server-prod:20241217@sha256:040c83a6d3e45755419837747fa70fa68cf92433d483c116a971b3400bb8415d
WORKDIR /usr/src/app WORKDIR /usr/src/app
ENV NODE_ENV=production \ ENV NODE_ENV=production \
+4402 -14014
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -44,11 +44,11 @@
"@nestjs/swagger": "^7.1.8", "@nestjs/swagger": "^7.1.8",
"@nestjs/typeorm": "^10.0.0", "@nestjs/typeorm": "^10.0.0",
"@nestjs/websockets": "^10.2.2", "@nestjs/websockets": "^10.2.2",
"@opentelemetry/auto-instrumentations-node": "^0.52.0", "@opentelemetry/auto-instrumentations-node": "^0.54.0",
"@opentelemetry/context-async-hooks": "^1.24.0", "@opentelemetry/context-async-hooks": "^1.24.0",
"@opentelemetry/exporter-prometheus": "^0.54.0", "@opentelemetry/exporter-prometheus": "^0.56.0",
"@opentelemetry/sdk-node": "^0.54.0", "@opentelemetry/sdk-node": "^0.56.0",
"@react-email/components": "^0.0.28", "@react-email/components": "^0.0.31",
"@socket.io/redis-adapter": "^8.3.0", "@socket.io/redis-adapter": "^8.3.0",
"archiver": "^7.0.0", "archiver": "^7.0.0",
"async-lock": "^1.4.0", "async-lock": "^1.4.0",
@@ -76,8 +76,8 @@
"openid-client": "^5.4.3", "openid-client": "^5.4.3",
"pg": "^8.11.3", "pg": "^8.11.3",
"picomatch": "^4.0.2", "picomatch": "^4.0.2",
"react": "^18.3.1", "react": "^19.0.0",
"react-email": "^3.0.0", "react-email": "^3.0.4",
"reflect-metadata": "^0.2.0", "reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"sanitize-filename": "^1.6.3", "sanitize-filename": "^1.6.3",
@@ -108,11 +108,11 @@
"@types/lodash": "^4.14.197", "@types/lodash": "^4.14.197",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/multer": "^1.4.7", "@types/multer": "^1.4.7",
"@types/node": "^22.9.0", "@types/node": "^22.10.2",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/picomatch": "^3.0.0", "@types/picomatch": "^3.0.0",
"@types/pngjs": "^6.0.5", "@types/pngjs": "^6.0.5",
"@types/react": "^18.3.4", "@types/react": "^19.0.0",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"@types/supertest": "^6.0.0", "@types/supertest": "^6.0.0",
"@types/ua-parser-js": "^0.7.36", "@types/ua-parser-js": "^0.7.36",
@@ -122,7 +122,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"mock-fs": "^5.2.0", "mock-fs": "^5.2.0",
"pngjs": "^7.0.0", "pngjs": "^7.0.0",
+1 -1
View File
@@ -49,7 +49,7 @@ export const GetLoginDetails = createParamDecorator((data, context: ExecutionCon
const userAgent = UAParser(request.headers['user-agent']); const userAgent = UAParser(request.headers['user-agent']);
return { return {
clientIp: request.ip, clientIp: request.ip ?? '',
isSecure: request.secure, isSecure: request.secure,
deviceType: userAgent.browser.name || userAgent.device.type || (request.headers.devicemodel as string) || '', deviceType: userAgent.browser.name || userAgent.device.type || (request.headers.devicemodel as string) || '',
deviceOS: userAgent.os.name || (request.headers.devicetype as string) || '', deviceOS: userAgent.os.name || (request.headers.devicetype as string) || '',
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:22.11.0-alpine3.20@sha256:b64ced2e7cd0a4816699fe308ce6e8a08ccba463c757c00c14cd372e3d2c763e FROM node:22.12.0-alpine3.20@sha256:96cc8323e25c8cc6ddcb8b965e135cfd57846e8003ec0d7bcec16c5fd5f6d39f
RUN apk add --no-cache tini RUN apk add --no-cache tini
USER node USER node
+42 -40
View File
@@ -54,7 +54,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.45.1", "eslint-plugin-svelte": "^2.45.1",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"factory.ts": "^1.4.1", "factory.ts": "^1.4.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"postcss": "^8.4.35", "postcss": "^8.4.35",
@@ -3039,9 +3039,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.23.3", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3059,10 +3059,10 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001646", "caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.5.4", "electron-to-chromium": "^1.5.73",
"node-releases": "^2.0.18", "node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.0" "update-browserslist-db": "^1.1.1"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@@ -3135,9 +3135,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001651", "version": "1.0.30001689",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz",
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3398,12 +3398,13 @@
} }
}, },
"node_modules/core-js-compat": { "node_modules/core-js-compat": {
"version": "3.37.1", "version": "3.39.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"browserslist": "^4.23.0" "browserslist": "^4.24.2"
}, },
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
@@ -3653,9 +3654,9 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.6", "version": "1.5.74",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.6.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
"integrity": "sha512-jwXWsM5RPf6j9dPYzaorcBSUg6AiqocPEyMpkchkvntaH9HGfOOMZwxMJjDY/XEs3T5dM7uyH1VhRMkqUU9qVw==", "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@@ -3805,9 +3806,9 @@
} }
}, },
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.1.2", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -3948,19 +3949,19 @@
} }
}, },
"node_modules/eslint-plugin-unicorn": { "node_modules/eslint-plugin-unicorn": {
"version": "55.0.0", "version": "56.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-55.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz",
"integrity": "sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==", "integrity": "sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-validator-identifier": "^7.24.5", "@babel/helper-validator-identifier": "^7.24.7",
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"ci-info": "^4.0.0", "ci-info": "^4.0.0",
"clean-regexp": "^1.0.0", "clean-regexp": "^1.0.0",
"core-js-compat": "^3.37.0", "core-js-compat": "^3.38.1",
"esquery": "^1.5.0", "esquery": "^1.6.0",
"globals": "^15.7.0", "globals": "^15.9.0",
"indent-string": "^4.0.0", "indent-string": "^4.0.0",
"is-builtin-module": "^3.2.1", "is-builtin-module": "^3.2.1",
"jsesc": "^3.0.2", "jsesc": "^3.0.2",
@@ -3968,7 +3969,7 @@
"read-pkg-up": "^7.0.1", "read-pkg-up": "^7.0.1",
"regexp-tree": "^0.1.27", "regexp-tree": "^0.1.27",
"regjsparser": "^0.10.0", "regjsparser": "^0.10.0",
"semver": "^7.6.1", "semver": "^7.6.3",
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0"
}, },
"engines": { "engines": {
@@ -4227,10 +4228,11 @@
} }
}, },
"node_modules/esquery": { "node_modules/esquery": {
"version": "1.5.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true, "dev": true,
"license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"estraverse": "^5.1.0" "estraverse": "^5.1.0"
}, },
@@ -5751,9 +5753,9 @@
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.18", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -8285,9 +8287,9 @@
} }
}, },
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.0", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
"integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -8305,8 +8307,8 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"escalade": "^3.1.2", "escalade": "^3.2.0",
"picocolors": "^1.0.1" "picocolors": "^1.1.0"
}, },
"bin": { "bin": {
"update-browserslist-db": "cli.js" "update-browserslist-db": "cli.js"
+1 -1
View File
@@ -46,7 +46,7 @@
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.45.1", "eslint-plugin-svelte": "^2.45.1",
"eslint-plugin-unicorn": "^55.0.0", "eslint-plugin-unicorn": "^56.0.1",
"factory.ts": "^1.4.1", "factory.ts": "^1.4.1",
"globals": "^15.9.0", "globals": "^15.9.0",
"postcss": "^8.4.35", "postcss": "^8.4.35",
@@ -29,7 +29,7 @@
// click runs before bind // click runs before bind
const previouslyEnabled = config.oauth.mobileOverrideEnabled; const previouslyEnabled = config.oauth.mobileOverrideEnabled;
if (!previouslyEnabled && !config.oauth.mobileRedirectUri) { if (!previouslyEnabled && !config.oauth.mobileRedirectUri) {
config.oauth.mobileRedirectUri = window.location.origin + '/api/oauth/mobile-redirect'; config.oauth.mobileRedirectUri = globalThis.location.origin + '/api/oauth/mobile-redirect';
} }
}; };
@@ -57,11 +57,11 @@
handleError(error, $t('error_loading_image')); handleError(error, $t('error_loading_image'));
}); });
window.addEventListener('mousemove', handleMouseMove); globalThis.addEventListener('mousemove', handleMouseMove);
}); });
onDestroy(() => { onDestroy(() => {
window.removeEventListener('mousemove', handleMouseMove); globalThis.removeEventListener('mousemove', handleMouseMove);
resetCropStore(); resetCropStore();
resetGlobalCropStore(); resetGlobalCropStore();
}); });
@@ -58,7 +58,7 @@ export function handleMouseDown(e: MouseEvent) {
} }
document.body.style.userSelect = 'none'; document.body.style.userSelect = 'none';
window.addEventListener('mouseup', handleMouseUp); globalThis.addEventListener('mouseup', handleMouseUp);
} }
export function handleMouseMove(e: MouseEvent) { export function handleMouseMove(e: MouseEvent) {
@@ -80,7 +80,7 @@ export function handleMouseMove(e: MouseEvent) {
} }
export function handleMouseUp() { export function handleMouseUp() {
window.removeEventListener('mouseup', handleMouseUp); globalThis.removeEventListener('mouseup', handleMouseUp);
document.body.style.userSelect = ''; document.body.style.userSelect = '';
stopInteraction(); stopInteraction();
} }
@@ -107,7 +107,7 @@
}; };
const onCopyShortcut = (event: KeyboardEvent) => { const onCopyShortcut = (event: KeyboardEvent) => {
if (window.getSelection()?.type === 'Range') { if (globalThis.getSelection()?.type === 'Range') {
return; return;
} }
event.preventDefault(); event.preventDefault();
@@ -11,7 +11,6 @@
let { onSuccess }: Props = $props(); let { onSuccess }: Props = $props();
let errorMessage: string = $state(''); let errorMessage: string = $state('');
let success: string;
let password = $state(''); let password = $state('');
let passwordConfirm = $state(''); let passwordConfirm = $state('');
@@ -59,9 +58,6 @@
<p class="text-sm text-red-400">{errorMessage}</p> <p class="text-sm text-red-400">{errorMessage}</p>
{/if} {/if}
{#if success}
<p class="text-sm text-immich-primary">{success}</p>
{/if}
<div class="my-5 flex w-full"> <div class="my-5 flex w-full">
<Button type="submit" size="lg" fullwidth>{$t('to_change_password')}</Button> <Button type="submit" size="lg" fullwidth>{$t('to_change_password')}</Button>
</div> </div>
@@ -28,8 +28,6 @@
onEditSuccess, onEditSuccess,
}: Props = $props(); }: Props = $props();
let error: string;
let success: string;
let quotaSize = $state(user.quotaSizeInBytes ? convertFromBytes(user.quotaSizeInBytes, ByteUnit.GiB) : null); let quotaSize = $state(user.quotaSizeInBytes ? convertFromBytes(user.quotaSizeInBytes, ByteUnit.GiB) : null);
const previousQutoa = user.quotaSizeInBytes; const previousQutoa = user.quotaSizeInBytes;
@@ -149,14 +147,6 @@
</a> </a>
</p> </p>
</div> </div>
{#if error}
<p class="ml-4 text-sm text-red-400">{error}</p>
{/if}
{#if success}
<p class="ml-4 text-sm text-immich-primary">{success}</p>
{/if}
</form> </form>
{#snippet stickyBottom()} {#snippet stickyBottom()}
@@ -33,9 +33,9 @@
return; return;
} }
if (oauth.isCallback(window.location)) { if (oauth.isCallback(globalThis.location)) {
try { try {
await oauth.login(window.location); await oauth.login(globalThis.location);
await onSuccess(); await onSuccess();
return; return;
} catch (error) { } catch (error) {
@@ -46,9 +46,9 @@
} }
try { try {
if ($featureFlags.oauthAutoLaunch && !oauth.isAutoLaunchDisabled(window.location)) { if ($featureFlags.oauthAutoLaunch && !oauth.isAutoLaunchDisabled(globalThis.location)) {
await goto(`${AppRoute.AUTH_LOGIN}?autoLaunch=0`, { replaceState: true }); await goto(`${AppRoute.AUTH_LOGIN}?autoLaunch=0`, { replaceState: true });
await oauth.authorize(window.location); await oauth.authorize(globalThis.location);
return; return;
} }
} catch (error) { } catch (error) {
@@ -85,7 +85,7 @@
const handleOAuthLogin = async () => { const handleOAuthLogin = async () => {
oauthLoading = true; oauthLoading = true;
oauthError = ''; oauthError = '';
const success = await oauth.authorize(window.location); const success = await oauth.authorize(globalThis.location);
if (!success) { if (!success) {
oauthLoading = false; oauthLoading = false;
oauthError = $t('errors.unable_to_login_with_oauth'); oauthError = $t('errors.unable_to_login_with_oauth');
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { InterpolationValues } from '$lib/components/i18n/format-message';
import FormatMessage from '$lib/components/i18n/format-message.svelte'; import FormatMessage from '$lib/components/i18n/format-message.svelte';
import type { InterpolationValues } from '$lib/components/i18n/format-message.svelte';
import type { Translations } from 'svelte-i18n'; import type { Translations } from 'svelte-i18n';
interface Props { interface Props {
@@ -1,10 +1,5 @@
<script lang="ts" module>
import type { FormatXMLElementFn, PrimitiveType } from 'intl-messageformat';
export type InterpolationValues = Record<string, PrimitiveType | FormatXMLElementFn<unknown>>;
</script>
<script lang="ts"> <script lang="ts">
import { IntlMessageFormat } from 'intl-messageformat'; import { IntlMessageFormat, type FormatXMLElementFn } from 'intl-messageformat';
import { import {
TYPE, TYPE,
type MessageFormatElement, type MessageFormatElement,
@@ -12,6 +7,7 @@
type SelectElement, type SelectElement,
} from '@formatjs/icu-messageformat-parser'; } from '@formatjs/icu-messageformat-parser';
import { locale as i18nLocale, json, type Translations } from 'svelte-i18n'; import { locale as i18nLocale, json, type Translations } from 'svelte-i18n';
import type { InterpolationValues } from '$lib/components/i18n/format-message';
type MessagePart = { type MessagePart = {
message: string; message: string;
@@ -0,0 +1,2 @@
import type { FormatXMLElementFn, PrimitiveType } from 'intl-messageformat';
export type InterpolationValues = Record<string, PrimitiveType | FormatXMLElementFn<unknown>>;
@@ -69,6 +69,7 @@
} }
showLoadingSpinner = true; showLoadingSpinner = true;
// eslint-disable-next-line unicorn/prefer-global-this
const searchTimeout = window.setTimeout(() => { const searchTimeout = window.setTimeout(() => {
if (searchWord === '') { if (searchWord === '') {
places = []; places = [];
@@ -29,6 +29,7 @@
const contextMenuEvent = new MouseEvent('contextmenu', { const contextMenuEvent = new MouseEvent('contextmenu', {
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,
// eslint-disable-next-line unicorn/prefer-global-this
view: window, view: window,
clientX: event.x, clientX: event.x,
clientY: event.y, clientY: event.y,
@@ -5,10 +5,10 @@ import { NotificationType } from '../notification';
import NotificationCard from '../notification-card.svelte'; import NotificationCard from '../notification-card.svelte';
describe('NotificationCard component', () => { describe('NotificationCard component', () => {
let sut: RenderResult<NotificationCard>; let sut: RenderResult<typeof NotificationCard>;
it('disposes timeout if already removed from the DOM', () => { it('disposes timeout if already removed from the DOM', () => {
vi.spyOn(window, 'clearTimeout'); vi.spyOn(globalThis, 'clearTimeout');
sut = render(NotificationCard, { sut = render(NotificationCard, {
notification: { notification: {
@@ -21,7 +21,7 @@ describe('NotificationCard component', () => {
}); });
cleanup(); cleanup();
expect(window.clearTimeout).toHaveBeenCalledTimes(1); expect(globalThis.clearTimeout).toHaveBeenCalledTimes(1);
}); });
it('shows message and title', () => { it('shows message and title', () => {
@@ -20,11 +20,11 @@
let loading = $state(true); let loading = $state(true);
onMount(async () => { onMount(async () => {
if (oauth.isCallback(window.location)) { if (oauth.isCallback(globalThis.location)) {
try { try {
loading = true; loading = true;
user = await oauth.link(window.location); user = await oauth.link(globalThis.location);
notificationController.show({ notificationController.show({
message: $t('linked_oauth_account'), message: $t('linked_oauth_account'),
@@ -64,7 +64,7 @@
{#if user.oauthId} {#if user.oauthId}
<Button size="sm" onclick={() => handleUnlink()}>{$t('unlink_oauth')}</Button> <Button size="sm" onclick={() => handleUnlink()}>{$t('unlink_oauth')}</Button>
{:else} {:else}
<Button size="sm" onclick={() => oauth.authorize(window.location)}>{$t('link_to_oauth')}</Button> <Button size="sm" onclick={() => oauth.authorize(globalThis.location)}>{$t('link_to_oauth')}</Button>
{/if} {/if}
{/if} {/if}
</div> </div>
@@ -64,10 +64,7 @@
for (const candidate of sharedWith) { for (const candidate of sharedWith) {
const existIndex = partners.findIndex((p) => candidate.id === p.user.id); const existIndex = partners.findIndex((p) => candidate.id === p.user.id);
if (existIndex >= 0) { if (existIndex === -1) {
partners[existIndex].sharedWithMe = true;
partners[existIndex].inTimeline = candidate.inTimeline ?? false;
} else {
partners = [ partners = [
...partners, ...partners,
{ {
@@ -77,6 +74,9 @@
inTimeline: candidate.inTimeline ?? false, inTimeline: candidate.inTimeline ?? false,
}, },
]; ];
} else {
partners[existIndex].sharedWithMe = true;
partners[existIndex].inTimeline = candidate.inTimeline ?? false;
} }
} }
}; };
@@ -43,7 +43,7 @@
let { keys = $bindable([]), sessions = $bindable([]) }: Props = $props(); let { keys = $bindable([]), sessions = $bindable([]) }: Props = $props();
let oauthOpen = let oauthOpen =
oauth.isCallback(window.location) || oauth.isCallback(globalThis.location) ||
$page.url.searchParams.get(QueryParameter.OPEN_SETTING) === OpenSettingQueryParameterValue.OAUTH; $page.url.searchParams.get(QueryParameter.OPEN_SETTING) === OpenSettingQueryParameterValue.OAUTH;
</script> </script>
+1 -1
View File
@@ -16,7 +16,7 @@ export const handleToggleTheme = () => {
}; };
const initTheme = (): ThemeSetting => { const initTheme = (): ThemeSetting => {
if (browser && window.matchMedia && !window.matchMedia('(prefers-color-scheme: dark)').matches) { if (browser && globalThis.matchMedia && !globalThis.matchMedia('(prefers-color-scheme: dark)').matches) {
return { value: Theme.LIGHT, system: false }; return { value: Theme.LIGHT, system: false };
} }
return { value: Theme.DARK, system: false }; return { value: Theme.DARK, system: false };
+2 -2
View File
@@ -261,7 +261,7 @@ export const copyToClipboard = async (secret: string) => {
}; };
export const makeSharedLinkUrl = (externalDomain: string, key: string) => { export const makeSharedLinkUrl = (externalDomain: string, key: string) => {
return new URL(`share/${key}`, externalDomain || window.location.origin).href; return new URL(`share/${key}`, externalDomain || globalThis.location.origin).href;
}; };
export const oauth = { export const oauth = {
@@ -283,7 +283,7 @@ export const oauth = {
try { try {
const redirectUri = location.href.split('?')[0]; const redirectUri = location.href.split('?')[0];
const { url } = await startOAuth({ oAuthConfigDto: { redirectUri } }); const { url } = await startOAuth({ oAuthConfigDto: { redirectUri } });
window.location.href = url; globalThis.location.href = url;
return true; return true;
} catch (error) { } catch (error) {
handleError(error, $t('errors.unable_to_login_with_oauth')); handleError(error, $t('errors.unable_to_login_with_oauth'));
+5 -3
View File
@@ -1,5 +1,6 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import FormatBoldMessage from '$lib/components/i18n/format-bold-message.svelte'; import FormatBoldMessage from '$lib/components/i18n/format-bold-message.svelte';
import type { InterpolationValues } from '$lib/components/i18n/format-message';
import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification'; import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification';
import { AppRoute } from '$lib/constants'; import { AppRoute } from '$lib/constants';
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte'; import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
@@ -33,7 +34,7 @@ import {
type UserResponseDto, type UserResponseDto,
} from '@immich/sdk'; } from '@immich/sdk';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { t } from 'svelte-i18n'; import { t, type Translations } from 'svelte-i18n';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import { handleError } from './handle-error'; import { handleError } from './handle-error';
@@ -120,7 +121,8 @@ export const addAssetsToNewAlbum = async (albumName: string, assetIds: string[])
return; return;
} }
const $t = get(t); const $t = get(t);
notificationController.show({ // for reasons beyond me <ComponentProps<typeof FormatBoldMessage>> doesn't work, even though it's (afaik) exactly this object
notificationController.show<{ key: Translations; values: InterpolationValues }>({
type: NotificationType.Info, type: NotificationType.Info,
timeout: 5000, timeout: 5000,
component: { component: {
@@ -549,7 +551,7 @@ export const delay = async (ms: number) => {
}; };
export const canCopyImageToClipboard = (): boolean => { export const canCopyImageToClipboard = (): boolean => {
return !!(navigator.clipboard && window.ClipboardItem); return !!(navigator.clipboard && globalThis.ClipboardItem);
}; };
const imgToBlob = async (imageElement: HTMLImageElement) => { const imgToBlob = async (imageElement: HTMLImageElement) => {
+1 -1
View File
@@ -95,7 +95,7 @@ export const handleLogout = async (redirectUri: string) => {
if (redirectUri.startsWith('/')) { if (redirectUri.startsWith('/')) {
await goto(redirectUri); await goto(redirectUri);
} else { } else {
window.location.href = redirectUri; globalThis.location.href = redirectUri;
} }
} finally { } finally {
resetSavedUser(); resetSavedUser();
+2 -2
View File
@@ -16,5 +16,5 @@ function fake_cancelIdleCallback(id: number) {
return clearTimeout(id); return clearTimeout(id);
} }
export const idleCB = window.requestIdleCallback || fake_requestIdleCallback; export const idleCB = globalThis.requestIdleCallback || fake_requestIdleCallback;
export const cancelIdleCB = window.cancelIdleCallback || fake_cancelIdleCallback; export const cancelIdleCB = globalThis.cancelIdleCallback || fake_cancelIdleCallback;
+1 -1
View File
@@ -11,7 +11,7 @@ export class KeyedPriorityQueue<K, T> {
const removed = this.set.delete(key); const removed = this.set.delete(key);
if (removed) { if (removed) {
const idx = this.items.findIndex((i) => i.key === key); const idx = this.items.findIndex((i) => i.key === key);
if (idx >= 0) { if (idx !== -1) {
this.items.splice(idx, 1); this.items.splice(idx, 1);
} }
} }
+1 -1
View File
@@ -24,6 +24,6 @@ export const getActivationKey = async (licenseKey: string): Promise<string> => {
export const getLicenseLink = (license: ImmichProduct) => { export const getLicenseLink = (license: ImmichProduct) => {
const url = new URL('/', PUBLIC_IMMICH_BUY_HOST); const url = new URL('/', PUBLIC_IMMICH_BUY_HOST);
url.searchParams.append('productId', license); url.searchParams.append('productId', license);
url.searchParams.append('instanceUrl', get(serverConfig).externalDomain || window.origin); url.searchParams.append('instanceUrl', get(serverConfig).externalDomain || globalThis.origin);
return url.href; return url.href;
}; };
+1 -1
View File
@@ -9,7 +9,7 @@ export type AssetGridRouteSearchParams = {
at: string | null | undefined; at: string | null | undefined;
}; };
export const isExternalUrl = (url: string): boolean => { export const isExternalUrl = (url: string): boolean => {
return new URL(url, window.location.href).origin !== window.location.origin; return new URL(url, globalThis.location.href).origin !== globalThis.location.origin;
}; };
export const isPhotosRoute = (route?: string | null) => !!route?.startsWith('/(user)/photos/[[assetId=id]]'); export const isPhotosRoute = (route?: string | null) => !!route?.startsWith('/(user)/photos/[[assetId=id]]');
@@ -42,7 +42,7 @@
}; };
const getLink = (path: string) => { const getLink = (path: string) => {
const url = new URL(AppRoute.FOLDERS, window.location.href); const url = new URL(AppRoute.FOLDERS, globalThis.location.href);
if (path) { if (path) {
url.searchParams.set(QueryParameter.PATH, path); url.searchParams.set(QueryParameter.PATH, path);
} }
@@ -31,7 +31,10 @@
<main class="grid h-screen bg-immich-bg pt-18 dark:bg-immich-dark-bg"> <main class="grid h-screen bg-immich-bg pt-18 dark:bg-immich-dark-bg">
{#if assetInteraction.selectionActive} {#if assetInteraction.selectionActive}
<AssetSelectControlBar assets={assetInteraction.selectedAssets} clearSelect={assetInteraction.clearMultiselect}> <AssetSelectControlBar
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
<CreateSharedLink /> <CreateSharedLink />
<ButtonContextMenu icon={mdiPlus} title={$t('add')}> <ButtonContextMenu icon={mdiPlus} title={$t('add')}>
<AddToAlbum /> <AddToAlbum />
@@ -63,7 +63,7 @@
}; };
const getLink = (path: string) => { const getLink = (path: string) => {
const url = new URL(AppRoute.TAGS, window.location.href); const url = new URL(AppRoute.TAGS, globalThis.location.href);
if (path) { if (path) {
url.searchParams.set(QueryParameter.PATH, path); url.searchParams.set(QueryParameter.PATH, path);
} }
+4 -4
View File
@@ -35,7 +35,7 @@
const changeTheme = (theme: ThemeSetting) => { const changeTheme = (theme: ThemeSetting) => {
if (theme.system) { if (theme.system) {
theme.value = window.matchMedia('(prefers-color-scheme: dark)').matches ? Theme.DARK : Theme.LIGHT; theme.value = globalThis.matchMedia('(prefers-color-scheme: dark)').matches ? Theme.DARK : Theme.LIGHT;
} }
if (theme.value === Theme.LIGHT) { if (theme.value === Theme.LIGHT) {
@@ -59,7 +59,7 @@
const element = document.querySelector('#stencil'); const element = document.querySelector('#stencil');
element?.remove(); element?.remove();
// if the browser theme changes, changes the Immich theme too // if the browser theme changes, changes the Immich theme too
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', handleChangeTheme); globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', handleChangeTheme);
}); });
onDestroy(() => { onDestroy(() => {
@@ -110,7 +110,7 @@
{#if $page.data.meta.imageUrl} {#if $page.data.meta.imageUrl}
<meta <meta
property="og:image" property="og:image"
content={new URL($page.data.meta.imageUrl, $serverConfig.externalDomain || window.location.origin).href} content={new URL($page.data.meta.imageUrl, $serverConfig.externalDomain || globalThis.location.origin).href}
/> />
{/if} {/if}
@@ -121,7 +121,7 @@
{#if $page.data.meta.imageUrl} {#if $page.data.meta.imageUrl}
<meta <meta
name="twitter:image" name="twitter:image"
content={new URL($page.data.meta.imageUrl, $serverConfig.externalDomain || window.location.origin).href} content={new URL($page.data.meta.imageUrl, $serverConfig.externalDomain || globalThis.location.origin).href}
/> />
{/if} {/if}
{/if} {/if}
+1 -1
View File
@@ -32,7 +32,7 @@
run(() => { run(() => {
const stepState = $page.url.searchParams.get('step'); const stepState = $page.url.searchParams.get('step');
const temporaryIndex = onboardingSteps.findIndex((step) => step.name === stepState); const temporaryIndex = onboardingSteps.findIndex((step) => step.name === stepState);
index = temporaryIndex >= 0 ? temporaryIndex : 0; index = temporaryIndex === -1 ? 0 : temporaryIndex;
}); });
const handleDoneClicked = async () => { const handleDoneClicked = async () => {