Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3760782d7f | |||
| a8a63b24d0 | |||
| ab0ed11778 | |||
| 5ec407b57c | |||
| fdf0b16fe3 | |||
| c924f6c27c | |||
| df45ef0e35 | |||
| 81c813a882 | |||
| b014162088 | |||
| 276101ee82 | |||
| 9837d60074 | |||
| 28b7443b92 | |||
| 5acdc958b6 | |||
| e384692025 | |||
| 54b276c984 | |||
| 7eb004bd00 | |||
| c2965c4408 | |||
| b749a68349 | |||
| 30aa2c9b82 | |||
| 9ed04588b8 | |||
| 7d320217b9 | |||
| efdf8bbca9 | |||
| 34c4fbf730 | |||
| ca775ab3e9 | |||
| 2dd5514043 | |||
| f33dbdfe9a | |||
| b1587a5dee | |||
| 501485d0b1 | |||
| ed7f857975 | |||
| d346985457 | |||
| a144a1bec3 | |||
| 9f318a9338 | |||
| 11f41099c3 | |||
| 96481aae5d | |||
| 4a42a72bd3 | |||
| 66f2ac8ce3 | |||
| 6b2de807a7 | |||
| 96f8050143 | |||
| 14689462f8 | |||
| fb68da2b51 | |||
| 720b9a286e | |||
| d93ccb1669 | |||
| c34fc4f2d1 | |||
| 905a062a6e | |||
| aeed24b5b4 | |||
| 28ba22e8c1 | |||
| 5b64456f48 | |||
| 02fd6d22b3 | |||
| 10ed31d725 | |||
| 23d4314eed | |||
| ea135cc310 | |||
| 745e1b003d | |||
| 1dae622dbc | |||
| 8ca24f0ef2 | |||
| f679021f0e | |||
| 65f5118bdd | |||
| 9f4fad2a0f | |||
| 325fb4b5d1 | |||
| f040c9fb38 | |||
| 0eacdf93eb | |||
| 20262209ce | |||
| dd638ac207 | |||
| d5b23373c7 | |||
| 9765ccb5a7 | |||
| 82d934d09d | |||
| 2821e0bf95 | |||
| bb3d9b6306 | |||
| c83df2686a | |||
| 94da5942bd | |||
| 54d2c12fff | |||
| 64fcb25971 | |||
| 7f03bd8440 | |||
| 2974cdbbee | |||
| f0677735fd | |||
| bb78eb4c4b | |||
| 4ed75f2ac9 | |||
| 3f4b783889 |
+12
-24
@@ -1,41 +1,29 @@
|
|||||||
changelog:
|
changelog:
|
||||||
categories:
|
categories:
|
||||||
- title: ⚠️ Breaking Changes
|
- title: 🚨 Breaking Changes
|
||||||
labels:
|
labels:
|
||||||
- breaking-change
|
- breaking-change
|
||||||
|
|
||||||
- title: 🗄️ Server
|
- title: 🔒 Security
|
||||||
labels:
|
labels:
|
||||||
- 🗄️server
|
- security
|
||||||
|
|
||||||
- title: 📱 Mobile
|
- title: 🚀 Features
|
||||||
labels:
|
labels:
|
||||||
- 📱mobile
|
- feature
|
||||||
|
|
||||||
- title: 🖥️ Web
|
- title: 🌟 Enhancements
|
||||||
labels:
|
labels:
|
||||||
- 🖥️web
|
- enhancement
|
||||||
|
|
||||||
- title: 🧠 Machine Learning
|
- title: 🐛 Bug fixes
|
||||||
labels:
|
labels:
|
||||||
- 🧠machine-learning
|
- bugfix
|
||||||
|
|
||||||
- title: ⚡ CLI
|
- title: 📚 Documentation
|
||||||
labels:
|
|
||||||
- cli
|
|
||||||
|
|
||||||
- title: 📓 Documentation
|
|
||||||
labels:
|
labels:
|
||||||
- documentation
|
- documentation
|
||||||
|
|
||||||
- title: 🔨 Maintenance
|
- title: 🌐 Translations
|
||||||
labels:
|
labels:
|
||||||
- deployment
|
- translation
|
||||||
- dependencies
|
|
||||||
- renovate
|
|
||||||
- maintenance
|
|
||||||
- tech-debt
|
|
||||||
|
|
||||||
- title: Other changes
|
|
||||||
labels:
|
|
||||||
- "*"
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@v6.5.0
|
uses: docker/build-push-action@v6.6.1
|
||||||
with:
|
with:
|
||||||
file: cli/Dockerfile
|
file: cli/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@v6.5.0
|
uses: docker/build-push-action@v6.6.1
|
||||||
with:
|
with:
|
||||||
context: ${{ matrix.context }}
|
context: ${{ matrix.context }}
|
||||||
file: ${{ matrix.file }}
|
file: ${{ matrix.file }}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
/dist
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
project: 'tsconfig.json',
|
|
||||||
sourceType: 'module',
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
},
|
|
||||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
|
||||||
extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', 'plugin:unicorn/recommended'],
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
ignorePatterns: ['.eslintrc.js'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-floating-promises': 'error',
|
|
||||||
'unicorn/prefer-module': 'off',
|
|
||||||
'unicorn/prevent-abbreviations': 'off',
|
|
||||||
'unicorn/no-process-exit': 'off',
|
|
||||||
'unicorn/import-style': 'off',
|
|
||||||
curly: 2,
|
|
||||||
'prettier/prettier': 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM node:20.16.0-alpine3.20@sha256:eb8101caae9ac02229bd64c024919fe3d4504ff7f329da79ca60a04db08cef52 as core
|
FROM node:20.16.0-alpine3.20@sha256:eb8101caae9ac02229bd64c024919fe3d4504ff7f329da79ca60a04db08cef52 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 ./
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
|
import js from '@eslint/js';
|
||||||
|
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import globals from 'globals';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ['eslint.config.mjs', 'dist'],
|
||||||
|
},
|
||||||
|
...compat.extends(
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:unicorn/recommended',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': typescriptEslint,
|
||||||
|
},
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
},
|
||||||
|
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: 5,
|
||||||
|
sourceType: 'module',
|
||||||
|
|
||||||
|
parserOptions: {
|
||||||
|
project: 'tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-floating-promises': 'error',
|
||||||
|
'unicorn/prefer-module': 'off',
|
||||||
|
'unicorn/prevent-abbreviations': 'off',
|
||||||
|
'unicorn/no-process-exit': 'off',
|
||||||
|
'unicorn/import-style': 'off',
|
||||||
|
curly: 2,
|
||||||
|
'prettier/prettier': 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
Generated
+251
-325
@@ -17,28 +17,31 @@
|
|||||||
"immich": "dist/index.js"
|
"immich": "dist/index.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@types/byte-size": "^8.1.0",
|
"@types/byte-size": "^8.1.0",
|
||||||
"@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": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^7.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"byte-size": "^9.0.0",
|
"byte-size": "^9.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^9.0.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": "^55.0.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-organize-imports": "^4.0.0",
|
"prettier-plugin-organize-imports": "^4.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.12",
|
"vite": "^5.0.12",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^5.0.0",
|
||||||
"vitest": "^2.0.5",
|
"vitest": "^2.0.5",
|
||||||
"vitest-fetch-mock": "^0.3.0",
|
"vitest-fetch-mock": "^0.3.0",
|
||||||
"yaml": "^2.3.1"
|
"yaml": "^2.3.1"
|
||||||
@@ -56,7 +59,7 @@
|
|||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -714,24 +717,65 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/regexpp": {
|
"node_modules/@eslint-community/regexpp": {
|
||||||
"version": "4.10.0",
|
"version": "4.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
|
||||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/config-array": {
|
||||||
"version": "2.1.4",
|
"version": "0.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
|
||||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
"integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/object-schema": "^2.1.4",
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"minimatch": "^3.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/config-array/node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/config-array/node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.6.0",
|
"espree": "^10.0.1",
|
||||||
"globals": "^13.19.0",
|
"globals": "^14.0.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
@@ -739,7 +783,7 @@
|
|||||||
"strip-json-comments": "^3.1.1"
|
"strip-json-comments": "^3.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -755,6 +799,19 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
@@ -768,48 +825,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "8.57.0",
|
"version": "9.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz",
|
||||||
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
|
"integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@eslint/object-schema": {
|
||||||
"version": "0.11.14",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
|
||||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
"integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"license": "Apache-2.0",
|
||||||
"@humanwhocodes/object-schema": "^2.0.2",
|
|
||||||
"debug": "^4.3.1",
|
|
||||||
"minimatch": "^3.0.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.10.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
|
|
||||||
"version": "1.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0",
|
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/module-importer": {
|
"node_modules/@humanwhocodes/module-importer": {
|
||||||
@@ -825,11 +857,19 @@
|
|||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/object-schema": {
|
"node_modules/@humanwhocodes/retry": {
|
||||||
"version": "2.0.2",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
|
||||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
"integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@immich/sdk": {
|
"node_modules/@immich/sdk": {
|
||||||
"resolved": "../open-api/typescript-sdk",
|
"resolved": "../open-api/typescript-sdk",
|
||||||
@@ -1229,9 +1269,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.14.12",
|
"version": "20.14.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
|
||||||
"integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==",
|
"integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1245,32 +1285,32 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz",
|
||||||
"integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==",
|
"integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/type-utils": "7.17.0",
|
"@typescript-eslint/type-utils": "8.0.1",
|
||||||
"@typescript-eslint/utils": "7.17.0",
|
"@typescript-eslint/utils": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^5.3.1",
|
"ignore": "^5.3.1",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^7.0.0",
|
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
@@ -1279,27 +1319,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz",
|
||||||
"integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==",
|
"integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0",
|
"@typescript-eslint/typescript-estree": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
@@ -1308,17 +1348,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz",
|
||||||
"integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==",
|
"integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0"
|
"@typescript-eslint/visitor-keys": "8.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1326,27 +1366,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==",
|
"integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0",
|
"@typescript-eslint/typescript-estree": "8.0.1",
|
||||||
"@typescript-eslint/utils": "7.17.0",
|
"@typescript-eslint/utils": "8.0.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
|
||||||
"eslint": "^8.56.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"optional": true
|
"optional": true
|
||||||
@@ -1354,13 +1391,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz",
|
||||||
"integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==",
|
"integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1368,14 +1405,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz",
|
||||||
"integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==",
|
"integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"globby": "^11.1.0",
|
"globby": "^11.1.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
@@ -1384,7 +1421,7 @@
|
|||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1397,52 +1434,46 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==",
|
"integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0"
|
"@typescript-eslint/typescript-estree": "8.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz",
|
||||||
"integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==",
|
"integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"eslint-visitor-keys": "^3.4.3"
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ungap/structured-clone": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
|
||||||
@@ -1551,9 +1582,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.12.0",
|
"version": "8.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||||
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
|
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1568,6 +1599,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
@@ -1960,18 +1992,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/doctrine": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"esutils": "^2.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eastasianwidth": {
|
"node_modules/eastasianwidth": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||||
@@ -2060,41 +2080,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.57.0",
|
"version": "9.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz",
|
||||||
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
|
"integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.6.1",
|
"@eslint-community/regexpp": "^4.11.0",
|
||||||
"@eslint/eslintrc": "^2.1.4",
|
"@eslint/config-array": "^0.17.1",
|
||||||
"@eslint/js": "8.57.0",
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.14",
|
"@eslint/js": "9.8.0",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
|
"@humanwhocodes/retry": "^0.3.0",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
"@ungap/structured-clone": "^1.2.0",
|
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.2",
|
"cross-spawn": "^7.0.2",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"doctrine": "^3.0.0",
|
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.2.2",
|
"eslint-scope": "^8.0.2",
|
||||||
"eslint-visitor-keys": "^3.4.3",
|
"eslint-visitor-keys": "^4.0.0",
|
||||||
"espree": "^9.6.1",
|
"espree": "^10.1.0",
|
||||||
"esquery": "^1.4.2",
|
"esquery": "^1.5.0",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^6.0.1",
|
"file-entry-cache": "^8.0.0",
|
||||||
"find-up": "^5.0.0",
|
"find-up": "^5.0.0",
|
||||||
"glob-parent": "^6.0.2",
|
"glob-parent": "^6.0.2",
|
||||||
"globals": "^13.19.0",
|
|
||||||
"graphemer": "^1.4.0",
|
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"imurmurhash": "^0.1.4",
|
"imurmurhash": "^0.1.4",
|
||||||
"is-glob": "^4.0.0",
|
"is-glob": "^4.0.0",
|
||||||
"is-path-inside": "^3.0.3",
|
"is-path-inside": "^3.0.3",
|
||||||
"js-yaml": "^4.1.0",
|
|
||||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
"levn": "^0.4.1",
|
"levn": "^0.4.1",
|
||||||
"lodash.merge": "^4.6.2",
|
"lodash.merge": "^4.6.2",
|
||||||
@@ -2108,10 +2125,10 @@
|
|||||||
"eslint": "bin/eslint.js"
|
"eslint": "bin/eslint.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://eslint.org/donate"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
@@ -2191,30 +2208,18 @@
|
|||||||
"eslint": ">=8.56.0"
|
"eslint": ">=8.56.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-unicorn/node_modules/globals": {
|
|
||||||
"version": "15.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz",
|
|
||||||
"integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "7.2.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
|
||||||
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
|
"integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esrecurse": "^4.3.0",
|
"esrecurse": "^4.3.0",
|
||||||
"estraverse": "^5.2.0"
|
"estraverse": "^5.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -2237,16 +2242,31 @@
|
|||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint/node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint/node_modules/minimatch": {
|
"node_modules/eslint/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
},
|
},
|
||||||
@@ -2255,17 +2275,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/espree": {
|
||||||
"version": "9.6.1",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
|
||||||
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
"integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.9.0",
|
"acorn": "^8.12.0",
|
||||||
"acorn-jsx": "^5.3.2",
|
"acorn-jsx": "^5.3.2",
|
||||||
"eslint-visitor-keys": "^3.4.1"
|
"eslint-visitor-keys": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/espree/node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -2404,15 +2438,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||||
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
|
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flat-cache": "^3.0.4"
|
"flat-cache": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
@@ -2443,24 +2478,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "3.2.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
|
||||||
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
|
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flatted": "^3.2.9",
|
"flatted": "^3.2.9",
|
||||||
"keyv": "^4.5.3",
|
"keyv": "^4.5.4"
|
||||||
"rimraf": "^3.0.2"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
||||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/foreground-child": {
|
"node_modules/foreground-child": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
@@ -2478,12 +2514,6 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@@ -2561,15 +2591,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "13.24.0",
|
"version": "15.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
|
||||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
"integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"type-fest": "^0.20.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
@@ -2693,22 +2721,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/is-arrayish": {
|
"node_modules/is-arrayish": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
@@ -2904,7 +2916,8 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/json-parse-even-better-errors": {
|
"node_modules/json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@@ -2929,6 +2942,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"json-buffer": "3.0.1"
|
"json-buffer": "3.0.1"
|
||||||
}
|
}
|
||||||
@@ -3213,15 +3227,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/onetime": {
|
"node_modules/onetime": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||||
@@ -3338,15 +3343,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-is-absolute": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-key": {
|
"node_modules/path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
@@ -3431,9 +3427,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.39",
|
"version": "8.4.41",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
|
||||||
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
|
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -3712,63 +3708,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rimraf": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"glob": "^7.1.3"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"rimraf": "bin.js"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rimraf/node_modules/brace-expansion": {
|
|
||||||
"version": "1.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0",
|
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rimraf/node_modules/glob": {
|
|
||||||
"version": "7.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
|
||||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.1.1",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rimraf/node_modules/minimatch": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.13.0",
|
"version": "4.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
|
||||||
@@ -4197,18 +4136,6 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
|
||||||
"version": "0.20.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.5.4",
|
"version": "5.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||||
@@ -4279,14 +4206,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.3.5",
|
"version": "5.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz",
|
||||||
"integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==",
|
"integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.40",
|
||||||
"rollup": "^4.13.0"
|
"rollup": "^4.13.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4306,6 +4233,7 @@
|
|||||||
"less": "*",
|
"less": "*",
|
||||||
"lightningcss": "^1.21.0",
|
"lightningcss": "^1.21.0",
|
||||||
"sass": "*",
|
"sass": "*",
|
||||||
|
"sass-embedded": "*",
|
||||||
"stylus": "*",
|
"stylus": "*",
|
||||||
"sugarss": "*",
|
"sugarss": "*",
|
||||||
"terser": "^5.4.0"
|
"terser": "^5.4.0"
|
||||||
@@ -4323,6 +4251,9 @@
|
|||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"sass-embedded": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"stylus": {
|
"stylus": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
@@ -4357,10 +4288,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-tsconfig-paths": {
|
"node_modules/vite-tsconfig-paths": {
|
||||||
"version": "4.3.2",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.0.1.tgz",
|
||||||
"integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==",
|
"integrity": "sha512-yqwv+LstU7NwPeNqajZzLEBVpUFU6Dugtb2P84FXuvaoYA+/70l9MHE+GYfYAycVyPSDYZ7mjOFuYBRqlEpTig==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"globrex": "^0.1.2",
|
"globrex": "^0.1.2",
|
||||||
@@ -4598,12 +4530,6 @@
|
|||||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
|
||||||
|
|||||||
+8
-5
@@ -13,28 +13,31 @@
|
|||||||
"cli"
|
"cli"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@types/byte-size": "^8.1.0",
|
"@types/byte-size": "^8.1.0",
|
||||||
"@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": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^7.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"byte-size": "^9.0.0",
|
"byte-size": "^9.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^9.0.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": "^55.0.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-organize-imports": "^4.0.0",
|
"prettier-plugin-organize-imports": "^4.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.12",
|
"vite": "^5.0.12",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^5.0.0",
|
||||||
"vitest": "^2.0.5",
|
"vitest": "^2.0.5",
|
||||||
"vitest-fetch-mock": "^0.3.0",
|
"vitest-fetch-mock": "^0.3.0",
|
||||||
"yaml": "^2.3.1"
|
"yaml": "^2.3.1"
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
- database
|
- database
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
immich-web:
|
immich-web:
|
||||||
container_name: immich_web
|
container_name: immich_web
|
||||||
@@ -91,6 +93,8 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- database
|
- database
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ services:
|
|||||||
- redis
|
- redis
|
||||||
- database
|
- database
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
@@ -40,6 +42,8 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
@@ -67,7 +71,7 @@ services:
|
|||||||
interval: 5m
|
interval: 5m
|
||||||
start_interval: 30s
|
start_interval: 30s
|
||||||
start_period: 5m
|
start_period: 5m
|
||||||
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
command: ["postgres", "-c", "shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
# set IMMICH_METRICS=true in .env to enable metrics
|
# set IMMICH_METRICS=true in .env to enable metrics
|
||||||
@@ -75,7 +79,7 @@ services:
|
|||||||
container_name: immich_prometheus
|
container_name: immich_prometheus
|
||||||
ports:
|
ports:
|
||||||
- 9090:9090
|
- 9090:9090
|
||||||
image: prom/prometheus@sha256:f20d3127bf2876f4a1df76246fca576b41ddf1125ed1c546fbd8b16ea55117e6
|
image: prom/prometheus@sha256:cafe963e591c872d38f3ea41ff8eb22cee97917b7c97b5c0ccd43a419f11f613
|
||||||
volumes:
|
volumes:
|
||||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- prometheus-data:/prometheus
|
- prometheus-data:/prometheus
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ services:
|
|||||||
- redis
|
- redis
|
||||||
- database
|
- database
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
@@ -41,6 +43,8 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
@@ -65,7 +69,7 @@ services:
|
|||||||
interval: 5m
|
interval: 5m
|
||||||
start_interval: 30s
|
start_interval: 30s
|
||||||
start_period: 5m
|
start_period: 5m
|
||||||
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
command: ["postgres", "-c", "shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ DB_DATA_LOCATION=./postgres
|
|||||||
IMMICH_VERSION=release
|
IMMICH_VERSION=release
|
||||||
|
|
||||||
# Connection secret for postgres. You should change it to a random password
|
# Connection secret for postgres. You should change it to a random password
|
||||||
|
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
|
||||||
DB_PASSWORD=postgres
|
DB_PASSWORD=postgres
|
||||||
|
|
||||||
# The values below this line do not need to be changed
|
# The values below this line do not need to be changed
|
||||||
|
|||||||
@@ -294,6 +294,12 @@ You need to enable WebSockets on your reverse proxy.
|
|||||||
|
|
||||||
Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md).
|
Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md).
|
||||||
|
|
||||||
|
### How can I reduce the log verbosity of Redis?
|
||||||
|
|
||||||
|
To decrease Redis logs, you can add the following line to the `redis:` section of the `docker-compose.yml`:
|
||||||
|
|
||||||
|
` command: redis-server --loglevel warning`
|
||||||
|
|
||||||
### How can I run Immich as a non-root user?
|
### How can I run Immich as a non-root user?
|
||||||
|
|
||||||
You can change the user in the container by setting the `user` argument in `docker-compose.yml` for each service.
|
You can change the user in the container by setting the `user` argument in `docker-compose.yml` for each service.
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
### Unit tests
|
### Unit tests
|
||||||
|
|
||||||
Unit are run by calling `npm run test` from the `server` directory.
|
Unit are run by calling `npm run test` from the `server/` directory.
|
||||||
|
You need to run `npm install` (in `server/`) before _once_.
|
||||||
|
|
||||||
### End to end tests
|
### End to end tests
|
||||||
|
|
||||||
@@ -14,6 +15,11 @@ The e2e tests can be run by first starting up a test production environment via:
|
|||||||
make e2e
|
make e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Before you can run the tests, you need to run the following commands _once_:
|
||||||
|
|
||||||
|
- `npm install` (in `e2e/`)
|
||||||
|
- `make open-api` (in the project root `/`)
|
||||||
|
|
||||||
Once the test environment is running, the e2e tests can be run via:
|
Once the test environment is running, the e2e tests can be run via:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -1,8 +1,22 @@
|
|||||||
# Create Custom Map Styles for Immich Using Maptiler
|
# Custom Map Styles
|
||||||
|
|
||||||
You may decide that you'd like to modify the style document which is used to draw the maps in Immich. This can be done easily using Maptiler, if you do not want to write an entire JSON document by hand.
|
You may decide that you'd like to modify the style document which is used to
|
||||||
|
draw the maps in Immich. In addition to visual customization, this also allows
|
||||||
|
you to pick your own map tile provider instead of the default one. The default
|
||||||
|
`style.json` for [light theme](https://github.com/immich-app/immich/tree/main/server/resources/style-light.json)
|
||||||
|
and [dark theme](https://github.com/immich-app/immich/blob/main/server/resources/style-dark.json)
|
||||||
|
can be used as a basis for creating your own style.
|
||||||
|
|
||||||
## Steps
|
There are several sources for already-made `style.json` map themes, as well as
|
||||||
|
online generators you can use.
|
||||||
|
|
||||||
|
1. In **Immich**, navigate to **Administration --> Settings --> Map & GPS Settings** and expand the **Map Settings** subsection.
|
||||||
|
2. Paste the link to your JSON style in either the **Light Style** or **Dark Style**. (You can add different styles which will help make the map style more appropriate depending on whether you set **Immich** to Light or Dark mode.)
|
||||||
|
3. Save your selections. Reload the map, and enjoy your custom map style!
|
||||||
|
|
||||||
|
## Use Maptiler to build a custom style
|
||||||
|
|
||||||
|
Customizing the map style can be done easily using Maptiler, if you do not want to write an entire JSON document by hand.
|
||||||
|
|
||||||
1. Create a free account at https://cloud.maptiler.com
|
1. Create a free account at https://cloud.maptiler.com
|
||||||
2. Once logged in, you can either create a brand new map by clicking on **New Map**, selecting a starter map, and then clicking **Customize**, OR by selecting a **Standard Map** and customizing it from there.
|
2. Once logged in, you can either create a brand new map by clicking on **New Map**, selecting a starter map, and then clicking **Customize**, OR by selecting a **Standard Map** and customizing it from there.
|
||||||
@@ -11,6 +25,3 @@ You may decide that you'd like to modify the style document which is used to dra
|
|||||||
5. Next, **Publish** your style using the **Publish** button at the top right. This will deploy it to production, which means it is able to be exposed over the Internet. Maptiler will present an interactive side-by-side map with the original and your changes prior to publication.<br/>
|
5. Next, **Publish** your style using the **Publish** button at the top right. This will deploy it to production, which means it is able to be exposed over the Internet. Maptiler will present an interactive side-by-side map with the original and your changes prior to publication.<br/>
|
||||||
6. Maptiler will warn you that changing the map will change it across all apps using the map. Since no apps are using the map yet, this is okay.
|
6. Maptiler will warn you that changing the map will change it across all apps using the map. Since no apps are using the map yet, this is okay.
|
||||||
7. Clicking on the name of your new map at the top left will bring you to the item's **details** page. From here, copy the link to the JSON style under **Use vector style**. This link will automatically contain your personal API key to Maptiler.
|
7. Clicking on the name of your new map at the top left will bring you to the item's **details** page. From here, copy the link to the JSON style under **Use vector style**. This link will automatically contain your personal API key to Maptiler.
|
||||||
8. In **Immich**, navigate to **Administration --> Settings --> Map & GPS Settings** and expand the **Map Settings** subsection.
|
|
||||||
9. Paste the link to your JSON style in either the **Light Style** or **Dark Style**. (You can add different styles which will help make the map style more appropriate depending on whether you set **Immich** to Light or Dark mode.
|
|
||||||
10. Save your selections. Reload the map, and enjoy your custom map style!
|
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ Optionally, you can enable hardware acceleration for machine learning and transc
|
|||||||
|
|
||||||
- Populate custom database information if necessary.
|
- Populate custom database information if necessary.
|
||||||
- Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
|
- Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
|
||||||
- Consider changing `DB_PASSWORD` to something randomly generated
|
- Consider changing `DB_PASSWORD` to a custom value. Postgres is not publically exposed, so this password is only used for local authentication.
|
||||||
|
To avoid issues with Docker parsing this value, it is best to use only the characters `A-Za-z0-9`.
|
||||||
|
|
||||||
### Step 3 - Start the containers
|
### Step 3 - Start the containers
|
||||||
|
|
||||||
|
|||||||
@@ -38,21 +38,23 @@ Regardless of filesystem, it is not recommended to use a network share for your
|
|||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
| Variable | Description | Default | Containers | Workers |
|
| Variable | Description | Default | Containers | Workers |
|
||||||
| :---------------------------------- | :-------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- |
|
| :---------------------------------- | :---------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- |
|
||||||
| `TZ` | Timezone | | server | microservices |
|
| `TZ` | Timezone | | server | microservices |
|
||||||
| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices |
|
| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices |
|
||||||
| `IMMICH_LOG_LEVEL` | Log Level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices |
|
| `IMMICH_LOG_LEVEL` | Log Level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices |
|
||||||
| `IMMICH_MEDIA_LOCATION` | Media Location | `./upload`<sup>\*1</sup> | server | api, microservices |
|
| `IMMICH_MEDIA_LOCATION` | Media Location inside the container ⚠️**You probably shouldn't set this**<sup>\*1</sup>⚠️ | `./upload`<sup>\*2</sup> | server | api, microservices |
|
||||||
| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices |
|
| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices |
|
||||||
| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | |
|
| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | |
|
||||||
| `CPU_CORES` | Amount of cores available to the immich server | auto-detected cpu core count | server | |
|
| `CPU_CORES` | Amount of cores available to the immich server | auto-detected cpu core count | server | |
|
||||||
| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api |
|
| `IMMICH_API_METRICS_PORT` | Port for the OTEL metrics | `8081` | server | api |
|
||||||
| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices |
|
| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices |
|
||||||
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
|
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
|
||||||
| `IMMICH_TRUSTED_PROXIES` | List of comma separated IPs set as trusted proxies | | server | api |
|
| `IMMICH_TRUSTED_PROXIES` | List of comma separated IPs set as trusted proxies | | server | api |
|
||||||
|
|
||||||
\*1: With the default `WORKDIR` of `/usr/src/app`, this path will resolve to `/usr/src/app/upload`.
|
\*1: This path is where the Immich code looks for the files, which is internal to the docker container. Setting it to a path on your host will certainly break things, you should use the `UPLOAD_LOCATION` variable instead.
|
||||||
|
|
||||||
|
\*2: With the default `WORKDIR` of `/usr/src/app`, this path will resolve to `/usr/src/app/upload`.
|
||||||
It only need to be set if the Immich deployment method is changing.
|
It only need to be set if the Immich deployment method is changing.
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
|||||||
@@ -145,28 +145,36 @@ const config = {
|
|||||||
label: 'Installation',
|
label: 'Installation',
|
||||||
to: '/docs/install/requirements',
|
to: '/docs/install/requirements',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Contributing',
|
||||||
|
to: '/docs/overview/support-the-project',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Privacy Policy',
|
||||||
|
to: '/privacy-policy',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Community',
|
title: 'Documentation',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: 'Discord',
|
label: 'Roadmap',
|
||||||
href: 'https://discord.immich.app',
|
to: '/roadmap',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Reddit',
|
label: 'API',
|
||||||
href: 'https://www.reddit.com/r/immich/',
|
to: '/docs/api',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cursed Knowledge',
|
||||||
|
to: '/cursed-knowledge',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Links',
|
title: 'Links',
|
||||||
items: [
|
items: [
|
||||||
// {
|
|
||||||
// label: "Blog",
|
|
||||||
// to: "/blog",
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
label: 'GitHub',
|
label: 'GitHub',
|
||||||
href: 'https://github.com/immich-app/immich',
|
href: 'https://github.com/immich-app/immich',
|
||||||
@@ -175,6 +183,14 @@ const config = {
|
|||||||
label: 'YouTube',
|
label: 'YouTube',
|
||||||
href: 'https://www.youtube.com/@immich-app',
|
href: 'https://www.youtube.com/@immich-app',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Discord',
|
||||||
|
href: 'https://discord.immich.app',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Reddit',
|
||||||
|
href: 'https://www.reddit.com/r/immich/',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Generated
+51
-39
@@ -4237,9 +4237,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.19",
|
"version": "10.4.20",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||||
"integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
|
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4254,12 +4254,13 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.23.0",
|
"browserslist": "^4.23.3",
|
||||||
"caniuse-lite": "^1.0.30001599",
|
"caniuse-lite": "^1.0.30001646",
|
||||||
"fraction.js": "^4.3.7",
|
"fraction.js": "^4.3.7",
|
||||||
"normalize-range": "^0.1.2",
|
"normalize-range": "^0.1.2",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.1",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4531,9 +4532,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.23.0",
|
"version": "4.23.3",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
|
||||||
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
|
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4548,11 +4549,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.30001646",
|
||||||
"electron-to-chromium": "^1.4.668",
|
"electron-to-chromium": "^1.5.4",
|
||||||
"node-releases": "^2.0.14",
|
"node-releases": "^2.0.18",
|
||||||
"update-browserslist-db": "^1.0.13"
|
"update-browserslist-db": "^1.1.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"browserslist": "cli.js"
|
"browserslist": "cli.js"
|
||||||
@@ -4699,9 +4701,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001614",
|
"version": "1.0.30001651",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||||
"integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==",
|
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4715,7 +4717,8 @@
|
|||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
"node_modules/ccount": {
|
"node_modules/ccount": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -6342,9 +6345,10 @@
|
|||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.751",
|
"version": "1.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.751.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.6.tgz",
|
||||||
"integrity": "sha512-2DEPi++qa89SMGRhufWTiLmzqyuGmNF3SK4+PQetW1JKiZdEpF4XQonJXJCzyuYSA6mauiMhbyVhqYAP45Hvfw=="
|
"integrity": "sha512-jwXWsM5RPf6j9dPYzaorcBSUg6AiqocPEyMpkchkvntaH9HGfOOMZwxMJjDY/XEs3T5dM7uyH1VhRMkqUU9qVw==",
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
"version": "9.2.2",
|
"version": "9.2.2",
|
||||||
@@ -11958,9 +11962,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.14",
|
"version": "2.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
|
||||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
|
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nopt": {
|
"node_modules/nopt": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
@@ -13747,9 +13752,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.12.1",
|
"version": "6.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
"integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.0.6"
|
"side-channel": "^1.0.6"
|
||||||
},
|
},
|
||||||
@@ -16014,9 +16020,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz",
|
||||||
"integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==",
|
"integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alloc/quick-lru": "^5.2.0",
|
"@alloc/quick-lru": "^5.2.0",
|
||||||
@@ -16607,9 +16613,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.13",
|
"version": "1.1.0",
|
||||||
"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.0.tgz",
|
||||||
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
|
"integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -16624,9 +16630,10 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.2",
|
||||||
"picocolors": "^1.0.0"
|
"picocolors": "^1.0.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"update-browserslist-db": "cli.js"
|
"update-browserslist-db": "cli.js"
|
||||||
@@ -16714,12 +16721,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/url": {
|
"node_modules/url": {
|
||||||
"version": "0.11.3",
|
"version": "0.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
|
||||||
"integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==",
|
"integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"punycode": "^1.4.1",
|
"punycode": "^1.4.1",
|
||||||
"qs": "^6.11.2"
|
"qs": "^6.12.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/url-loader": {
|
"node_modules/url-loader": {
|
||||||
@@ -16783,7 +16794,8 @@
|
|||||||
"node_modules/url/node_modules/punycode": {
|
"node_modules/url/node_modules/punycode": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/util": {
|
"node_modules/util": {
|
||||||
"version": "0.10.4",
|
"version": "0.10.4",
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ const projects: CommunityProjectProps[] = [
|
|||||||
description: 'Powershell Module for the Immich API',
|
description: 'Powershell Module for the Immich API',
|
||||||
url: 'https://github.com/hanpq/PSImmich',
|
url: 'https://github.com/hanpq/PSImmich',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Immich Distribution',
|
||||||
|
description: 'Snap package for easy install and zero-care auto updates of Immich. Self-hosted photo management.',
|
||||||
|
url: 'https://immich-distribution.nsg.cc',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function CommunityProject({ title, description, url }: CommunityProjectProps): JSX.Element {
|
function CommunityProject({ title, description, url }: CommunityProjectProps): JSX.Element {
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
import { mdiCalendarToday, mdiLeadPencil, mdiLockOutline, mdiSpeedometerSlow, mdiWeb } from '@mdi/js';
|
import {
|
||||||
|
mdiCalendarToday,
|
||||||
|
mdiCrosshairsOff,
|
||||||
|
mdiLeadPencil,
|
||||||
|
mdiLockOff,
|
||||||
|
mdiLockOutline,
|
||||||
|
mdiSpeedometerSlow,
|
||||||
|
mdiWeb,
|
||||||
|
mdiWrap,
|
||||||
|
} from '@mdi/js';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Item as TimelineItem, Timeline } from '../components/timeline';
|
import { Item as TimelineItem, Timeline } from '../components/timeline';
|
||||||
@@ -8,6 +17,41 @@ const withLanguage = (date: Date) => (language: string) => date.toLocaleDateStri
|
|||||||
type Item = Omit<TimelineItem, 'done' | 'getDateLabel'> & { date: Date };
|
type Item = Omit<TimelineItem, 'done' | 'getDateLabel'> & { date: Date };
|
||||||
|
|
||||||
const items: Item[] = [
|
const items: Item[] = [
|
||||||
|
{
|
||||||
|
icon: mdiWrap,
|
||||||
|
iconColor: 'gray',
|
||||||
|
title: 'Carriage returns in bash scripts are cursed',
|
||||||
|
description: 'Git can be configured to automatically convert LF to CRLF on checkout and CRLF breaks bash scripts.',
|
||||||
|
link: {
|
||||||
|
url: 'https://github.com/immich-app/immich/pull/11613',
|
||||||
|
text: '#11613',
|
||||||
|
},
|
||||||
|
date: new Date(2024, 7, 7),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiLockOff,
|
||||||
|
iconColor: 'red',
|
||||||
|
title: 'Fetch inside Cloudflare Workers is cursed',
|
||||||
|
description:
|
||||||
|
'Fetch requests in Cloudflare Workers use http by default, even if you explicitly specify https, which can often cause redirect loops.',
|
||||||
|
link: {
|
||||||
|
url: 'https://community.cloudflare.com/t/does-cloudflare-worker-allow-secure-https-connection-to-fetch-even-on-flexible-ssl/68051/5',
|
||||||
|
text: 'Cloudflare',
|
||||||
|
},
|
||||||
|
date: new Date(2024, 7, 7),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiCrosshairsOff,
|
||||||
|
iconColor: 'gray',
|
||||||
|
title: 'GPS sharing on mobile is cursed',
|
||||||
|
description:
|
||||||
|
'Some phones will silently strip GPS data from images when apps without location permission try to access them.',
|
||||||
|
link: {
|
||||||
|
url: 'https://github.com/immich-app/immich/discussions/11268',
|
||||||
|
text: '#11268',
|
||||||
|
},
|
||||||
|
date: new Date(2024, 6, 21),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
icon: mdiLeadPencil,
|
icon: mdiLeadPencil,
|
||||||
iconColor: 'gold',
|
iconColor: 'gold',
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
import Layout from '@theme/Layout';
|
||||||
|
import { useColorMode } from '@docusaurus/theme-common';
|
||||||
|
function HomepageHeader() {
|
||||||
|
const { isDarkTheme } = useColorMode();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header>
|
||||||
|
<section className="max-w-[900px] m-4 p-4 md:p-6 md:m-auto md:my-12 border border-red-400 rounded-2xl bg-slate-200 dark:bg-immich-dark-gray">
|
||||||
|
<section>
|
||||||
|
<h1>Privacy Policy</h1>
|
||||||
|
<p>Last updated: July 31st 2024</p>
|
||||||
|
<p>
|
||||||
|
Welcome to Immich. We are committed to respecting your privacy. This Privacy Policy sets out how we collect,
|
||||||
|
use, and share information when you use our Immich app.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 1. Scope of This Policy */}
|
||||||
|
<section>
|
||||||
|
<h2>1. Scope of This Policy</h2>
|
||||||
|
<p>
|
||||||
|
This Privacy Policy applies to the Immich app ("we", "our", or "us") and covers our collection, use, and
|
||||||
|
disclosure of your information. This Policy does not cover any third-party websites, services, or
|
||||||
|
applications that can be accessed through our app, or third-party services you may access through Immich.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. Information We Collect */}
|
||||||
|
<section>
|
||||||
|
<h2>2. Information We Collect</h2>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<strong>Locally Stored Data</strong>: Immich stores all your photos, albums, settings, and locally on your
|
||||||
|
device. We do not have access to this data, nor do we transmit or store it on any of our servers.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<strong>Purchase Information:</strong> When you make a purchase within the{' '}
|
||||||
|
<a href="https://buy.immich.app">https://buy.immich.app</a>, we collect the following information for tax
|
||||||
|
calculation purposes:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Country of origin</li>
|
||||||
|
<li>Postal code (if the user is from Canada or the United States)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. Use of Your Information */}
|
||||||
|
<section>
|
||||||
|
<h2>3. Use of Your Information</h2>
|
||||||
|
<p>
|
||||||
|
<strong>Tax Calculation:</strong> The country of origin and postal code (for users from Canada or the United
|
||||||
|
States) are collected solely for determining the applicable tax rates on your purchase.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. Sharing of Your Information */}
|
||||||
|
<section>
|
||||||
|
<h2>4. Sharing of Your Information</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Tax Authorities:</strong> The purchase information may be shared with tax authorities as required
|
||||||
|
by law.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Payment Providers:</strong> The purchase information may be shared with payment providers where
|
||||||
|
required.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. Changes to This Policy */}
|
||||||
|
<section>
|
||||||
|
<h2>5. Changes to This Policy</h2>
|
||||||
|
<p>
|
||||||
|
We may update our Privacy Policy from time to time. If we make any changes, we will notify you by revising
|
||||||
|
the "Last updated" date at the top of this policy. It's encouraged that users frequently check this page for
|
||||||
|
any changes to stay informed about how we are helping to protect the personal information we collect.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 6. Contact Us */}
|
||||||
|
<section>
|
||||||
|
<h2>6. Contact Us</h2>
|
||||||
|
<p>
|
||||||
|
If you have any questions about this Privacy Policy, please contact us at{' '}
|
||||||
|
<a href="mailto:immich@futo.org">immich@futo.org</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Home(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<Layout
|
||||||
|
title="Home"
|
||||||
|
description="immich Self-hosted photo and video backup solution directly from your mobile phone "
|
||||||
|
noFooter={true}
|
||||||
|
>
|
||||||
|
<HomepageHeader />
|
||||||
|
<div className="flex flex-col place-items-center place-content-center">
|
||||||
|
<p>This project is available under GNU AGPL v3 license.</p>
|
||||||
|
<p className="text-xs">Privacy should not be a luxury</p>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
project: 'tsconfig.json',
|
|
||||||
sourceType: 'module',
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
},
|
|
||||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
|
||||||
extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', 'plugin:unicorn/recommended'],
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
ignorePatterns: ['.eslintrc.js'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-floating-promises': 'error',
|
|
||||||
'unicorn/prefer-module': 'off',
|
|
||||||
'unicorn/import-style': 'off',
|
|
||||||
curly: 2,
|
|
||||||
'prettier/prettier': 0,
|
|
||||||
'unicorn/prevent-abbreviations': 'off',
|
|
||||||
'unicorn/filename-case': 'off',
|
|
||||||
'unicorn/no-null': 'off',
|
|
||||||
'unicorn/prefer-top-level-await': 'off',
|
|
||||||
'unicorn/prefer-event-target': 'off',
|
|
||||||
'unicorn/no-thenable': 'off',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
|
import js from '@eslint/js';
|
||||||
|
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||||
|
import tsParser from '@typescript-eslint/parser';
|
||||||
|
import globals from 'globals';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ['eslint.config.mjs'],
|
||||||
|
},
|
||||||
|
...compat.extends(
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:unicorn/recommended',
|
||||||
|
),
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': typescriptEslint,
|
||||||
|
},
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
},
|
||||||
|
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: 5,
|
||||||
|
sourceType: 'module',
|
||||||
|
|
||||||
|
parserOptions: {
|
||||||
|
project: 'tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-floating-promises': 'error',
|
||||||
|
'unicorn/prefer-module': 'off',
|
||||||
|
'unicorn/import-style': 'off',
|
||||||
|
curly: 2,
|
||||||
|
'prettier/prettier': 0,
|
||||||
|
'unicorn/prevent-abbreviations': 'off',
|
||||||
|
'unicorn/filename-case': 'off',
|
||||||
|
'unicorn/no-null': 'off',
|
||||||
|
'unicorn/prefer-top-level-await': 'off',
|
||||||
|
'unicorn/prefer-event-target': 'off',
|
||||||
|
'unicorn/no-thenable': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
Generated
+230
-208
@@ -9,23 +9,26 @@
|
|||||||
"version": "1.111.0",
|
"version": "1.111.0",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/cli": "file:../cli",
|
"@immich/cli": "file:../cli",
|
||||||
"@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": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"@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",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^7.1.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.0.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": "^55.0.0",
|
||||||
"exiftool-vendored": "^28.0.0",
|
"exiftool-vendored": "^28.0.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
"jose": "^5.6.3",
|
"jose": "^5.6.3",
|
||||||
"luxon": "^3.4.4",
|
"luxon": "^3.4.4",
|
||||||
"oidc-provider": "^8.5.1",
|
"oidc-provider": "^8.5.1",
|
||||||
@@ -54,22 +57,25 @@
|
|||||||
"immich": "dist/index.js"
|
"immich": "dist/index.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@types/byte-size": "^8.1.0",
|
"@types/byte-size": "^8.1.0",
|
||||||
"@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": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^7.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"byte-size": "^9.0.0",
|
"byte-size": "^9.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^9.0.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": "^55.0.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-organize-imports": "^4.0.0",
|
"prettier-plugin-organize-imports": "^4.0.0",
|
||||||
@@ -93,7 +99,7 @@
|
|||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -731,24 +737,41 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/regexpp": {
|
"node_modules/@eslint-community/regexpp": {
|
||||||
"version": "4.10.0",
|
"version": "4.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
|
||||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/config-array": {
|
||||||
"version": "2.1.4",
|
"version": "0.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
|
||||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
"integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/object-schema": "^2.1.4",
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"minimatch": "^3.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.6.0",
|
"espree": "^10.0.1",
|
||||||
"globals": "^13.19.0",
|
"globals": "^14.0.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
@@ -756,33 +779,43 @@
|
|||||||
"strip-json-comments": "^3.1.1"
|
"strip-json-comments": "^3.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||||
"version": "8.57.0",
|
"version": "14.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||||
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
|
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "0.11.14",
|
"version": "9.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz",
|
||||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
"integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"@humanwhocodes/object-schema": "^2.0.2",
|
|
||||||
"debug": "^4.3.1",
|
|
||||||
"minimatch": "^3.0.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.10.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/object-schema": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/module-importer": {
|
"node_modules/@humanwhocodes/module-importer": {
|
||||||
@@ -798,11 +831,19 @@
|
|||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/object-schema": {
|
"node_modules/@humanwhocodes/retry": {
|
||||||
"version": "2.0.2",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
|
||||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
"integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@immich/cli": {
|
"node_modules/@immich/cli": {
|
||||||
"resolved": "../cli",
|
"resolved": "../cli",
|
||||||
@@ -1072,13 +1113,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@playwright/test": {
|
"node_modules/@playwright/test": {
|
||||||
"version": "1.45.3",
|
"version": "1.46.0",
|
||||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.3.tgz",
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.0.tgz",
|
||||||
"integrity": "sha512-UKF4XsBfy+u3MFWEH44hva1Q8Da28G6RFtR2+5saw+jgAFQV5yYnB1fu68Mz7fO+5GJF3wgwAIs0UelU8TxFrA==",
|
"integrity": "sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright": "1.45.3"
|
"playwright": "1.46.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
@@ -1475,9 +1516,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.14.12",
|
"version": "20.14.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
|
||||||
"integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==",
|
"integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1632,32 +1673,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz",
|
||||||
"integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==",
|
"integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/type-utils": "7.17.0",
|
"@typescript-eslint/type-utils": "8.0.1",
|
||||||
"@typescript-eslint/utils": "7.17.0",
|
"@typescript-eslint/utils": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^5.3.1",
|
"ignore": "^5.3.1",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^7.0.0",
|
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
@@ -1666,27 +1707,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz",
|
||||||
"integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==",
|
"integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0",
|
"@typescript-eslint/typescript-estree": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
@@ -1695,17 +1736,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz",
|
||||||
"integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==",
|
"integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0"
|
"@typescript-eslint/visitor-keys": "8.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1713,27 +1754,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==",
|
"integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0",
|
"@typescript-eslint/typescript-estree": "8.0.1",
|
||||||
"@typescript-eslint/utils": "7.17.0",
|
"@typescript-eslint/utils": "8.0.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
|
||||||
"eslint": "^8.56.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"optional": true
|
"optional": true
|
||||||
@@ -1741,13 +1779,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz",
|
||||||
"integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==",
|
"integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1755,14 +1793,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz",
|
||||||
"integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==",
|
"integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "8.0.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"globby": "^11.1.0",
|
"globby": "^11.1.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
@@ -1771,7 +1809,7 @@
|
|||||||
"ts-api-utils": "^1.3.0"
|
"ts-api-utils": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1810,52 +1848,46 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==",
|
"integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "8.0.1",
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0"
|
"@typescript-eslint/typescript-estree": "8.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^8.56.0"
|
"eslint": "^8.57.0 || ^9.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "7.17.0",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz",
|
||||||
"integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==",
|
"integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "8.0.1",
|
||||||
"eslint-visitor-keys": "^3.4.3"
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ungap/structured-clone": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
|
||||||
@@ -1983,9 +2015,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.12.0",
|
"version": "8.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||||
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
|
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -2000,6 +2032,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
@@ -2704,18 +2737,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/doctrine": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"esutils": "^2.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eastasianwidth": {
|
"node_modules/eastasianwidth": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||||
@@ -2867,41 +2888,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.57.0",
|
"version": "9.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz",
|
||||||
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
|
"integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.6.1",
|
"@eslint-community/regexpp": "^4.11.0",
|
||||||
"@eslint/eslintrc": "^2.1.4",
|
"@eslint/config-array": "^0.17.1",
|
||||||
"@eslint/js": "8.57.0",
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.14",
|
"@eslint/js": "9.8.0",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
|
"@humanwhocodes/retry": "^0.3.0",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
"@ungap/structured-clone": "^1.2.0",
|
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.2",
|
"cross-spawn": "^7.0.2",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"doctrine": "^3.0.0",
|
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.2.2",
|
"eslint-scope": "^8.0.2",
|
||||||
"eslint-visitor-keys": "^3.4.3",
|
"eslint-visitor-keys": "^4.0.0",
|
||||||
"espree": "^9.6.1",
|
"espree": "^10.1.0",
|
||||||
"esquery": "^1.4.2",
|
"esquery": "^1.5.0",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^6.0.1",
|
"file-entry-cache": "^8.0.0",
|
||||||
"find-up": "^5.0.0",
|
"find-up": "^5.0.0",
|
||||||
"glob-parent": "^6.0.2",
|
"glob-parent": "^6.0.2",
|
||||||
"globals": "^13.19.0",
|
|
||||||
"graphemer": "^1.4.0",
|
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"imurmurhash": "^0.1.4",
|
"imurmurhash": "^0.1.4",
|
||||||
"is-glob": "^4.0.0",
|
"is-glob": "^4.0.0",
|
||||||
"is-path-inside": "^3.0.3",
|
"is-path-inside": "^3.0.3",
|
||||||
"js-yaml": "^4.1.0",
|
|
||||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
"levn": "^0.4.1",
|
"levn": "^0.4.1",
|
||||||
"lodash.merge": "^4.6.2",
|
"lodash.merge": "^4.6.2",
|
||||||
@@ -2915,10 +2933,10 @@
|
|||||||
"eslint": "bin/eslint.js"
|
"eslint": "bin/eslint.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://eslint.org/donate"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
@@ -2998,30 +3016,18 @@
|
|||||||
"eslint": ">=8.56.0"
|
"eslint": ">=8.56.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-unicorn/node_modules/globals": {
|
|
||||||
"version": "15.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz",
|
|
||||||
"integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "7.2.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
|
||||||
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
|
"integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esrecurse": "^4.3.0",
|
"esrecurse": "^4.3.0",
|
||||||
"estraverse": "^5.2.0"
|
"estraverse": "^5.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -3039,18 +3045,45 @@
|
|||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/eslint/node_modules/eslint-visitor-keys": {
|
||||||
"version": "9.6.1",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
|
||||||
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/espree": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.9.0",
|
"acorn": "^8.12.0",
|
||||||
"acorn-jsx": "^5.3.2",
|
"acorn-jsx": "^5.3.2",
|
||||||
"eslint-visitor-keys": "^3.4.1"
|
"eslint-visitor-keys": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/espree/node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
@@ -3252,15 +3285,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||||
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
|
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flat-cache": "^3.0.4"
|
"flat-cache": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
@@ -3293,24 +3327,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "3.2.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
|
||||||
"integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
|
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flatted": "^3.2.9",
|
"flatted": "^3.2.9",
|
||||||
"keyv": "^4.5.3",
|
"keyv": "^4.5.4"
|
||||||
"rimraf": "^3.0.2"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
||||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/foreground-child": {
|
"node_modules/foreground-child": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
@@ -3526,15 +3561,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "13.24.0",
|
"version": "15.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
|
||||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
"integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"type-fest": "^0.20.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
@@ -4324,10 +4357,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/luxon": {
|
"node_modules/luxon": {
|
||||||
"version": "3.4.4",
|
"version": "3.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
|
||||||
"integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
|
"integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
@@ -5144,13 +5178,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/playwright": {
|
"node_modules/playwright": {
|
||||||
"version": "1.45.3",
|
"version": "1.46.0",
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.3.tgz",
|
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.0.tgz",
|
||||||
"integrity": "sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==",
|
"integrity": "sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.45.3"
|
"playwright-core": "1.46.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
@@ -5163,9 +5197,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/playwright-core": {
|
"node_modules/playwright-core": {
|
||||||
"version": "1.45.3",
|
"version": "1.46.0",
|
||||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.3.tgz",
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.0.tgz",
|
||||||
"integrity": "sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==",
|
"integrity": "sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -6277,18 +6311,6 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
|
||||||
"version": "0.20.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "1.6.18",
|
"version": "1.6.18",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
|||||||
+7
-4
@@ -19,23 +19,26 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
|
"@eslint/js": "^9.8.0",
|
||||||
"@immich/cli": "file:../cli",
|
"@immich/cli": "file:../cli",
|
||||||
"@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": "^20.14.12",
|
"@types/node": "^20.14.14",
|
||||||
"@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",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^7.1.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.0.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": "^55.0.0",
|
||||||
"exiftool-vendored": "^28.0.0",
|
"exiftool-vendored": "^28.0.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
"jose": "^5.6.3",
|
"jose": "^5.6.3",
|
||||||
"luxon": "^3.4.4",
|
"luxon": "^3.4.4",
|
||||||
"oidc-provider": "^8.5.1",
|
"oidc-provider": "^8.5.1",
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ const makeUploadDto = (options?: { omit: string }): Record<string, any> => {
|
|||||||
const TEN_TIMES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
const TEN_TIMES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
|
||||||
const locationAssetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
|
const locationAssetFilepath = `${testAssetDir}/metadata/gps-position/thompson-springs.jpg`;
|
||||||
|
const ratingAssetFilepath = `${testAssetDir}/metadata/rating/mongolels.jpg`;
|
||||||
|
|
||||||
const readTags = async (bytes: Buffer, filename: string) => {
|
const readTags = async (bytes: Buffer, filename: string) => {
|
||||||
const filepath = join(tempDir, filename);
|
const filepath = join(tempDir, filename);
|
||||||
@@ -72,6 +73,7 @@ describe('/asset', () => {
|
|||||||
let user2Assets: AssetMediaResponseDto[];
|
let user2Assets: AssetMediaResponseDto[];
|
||||||
let stackAssets: AssetMediaResponseDto[];
|
let stackAssets: AssetMediaResponseDto[];
|
||||||
let locationAsset: AssetMediaResponseDto;
|
let locationAsset: AssetMediaResponseDto;
|
||||||
|
let ratingAsset: AssetMediaResponseDto;
|
||||||
|
|
||||||
const setupTests = async () => {
|
const setupTests = async () => {
|
||||||
await utils.resetDatabase();
|
await utils.resetDatabase();
|
||||||
@@ -99,6 +101,16 @@ describe('/asset', () => {
|
|||||||
|
|
||||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: locationAsset.id });
|
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: locationAsset.id });
|
||||||
|
|
||||||
|
// asset rating
|
||||||
|
ratingAsset = await utils.createAsset(admin.accessToken, {
|
||||||
|
assetData: {
|
||||||
|
filename: 'mongolels.jpg',
|
||||||
|
bytes: await readFile(ratingAssetFilepath),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: ratingAsset.id });
|
||||||
|
|
||||||
user1Assets = await Promise.all([
|
user1Assets = await Promise.all([
|
||||||
utils.createAsset(user1.accessToken),
|
utils.createAsset(user1.accessToken),
|
||||||
utils.createAsset(user1.accessToken),
|
utils.createAsset(user1.accessToken),
|
||||||
@@ -214,6 +226,22 @@ describe('/asset', () => {
|
|||||||
expect(body).toMatchObject({ id: user1Assets[0].id });
|
expect(body).toMatchObject({ id: user1Assets[0].id });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get the asset rating', async () => {
|
||||||
|
await utils.waitForWebsocketEvent({
|
||||||
|
event: 'assetUpload',
|
||||||
|
id: ratingAsset.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.get(`/assets/${ratingAsset.id}`)
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
id: ratingAsset.id,
|
||||||
|
exifInfo: expect.objectContaining({ rating: 3 }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should work with a shared link', async () => {
|
it('should work with a shared link', async () => {
|
||||||
const sharedLink = await utils.createSharedLink(user1.accessToken, {
|
const sharedLink = await utils.createSharedLink(user1.accessToken, {
|
||||||
type: SharedLinkType.Individual,
|
type: SharedLinkType.Individual,
|
||||||
@@ -575,6 +603,31 @@ describe('/asset', () => {
|
|||||||
expect(status).toEqual(200);
|
expect(status).toEqual(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set the rating', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.put(`/assets/${user1Assets[0].id}`)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||||
|
.send({ rating: 2 });
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
id: user1Assets[0].id,
|
||||||
|
exifInfo: expect.objectContaining({
|
||||||
|
rating: 2,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
expect(status).toEqual(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject invalid rating', async () => {
|
||||||
|
for (const test of [{ rating: 7 }, { rating: 3.5 }, { rating: null }]) {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.put(`/assets/${user1Assets[0].id}`)
|
||||||
|
.send(test)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(errorDto.badRequest());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('should return tagged people', async () => {
|
it('should return tagged people', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.put(`/assets/${user1Assets[0].id}`)
|
.put(`/assets/${user1Assets[0].id}`)
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import type { Socket } from 'socket.io-client';
|
||||||
import { utils } from 'src/utils';
|
import { utils } from 'src/utils';
|
||||||
|
|
||||||
test.describe('Detail Panel', () => {
|
test.describe('Detail Panel', () => {
|
||||||
let admin: LoginResponseDto;
|
let admin: LoginResponseDto;
|
||||||
let asset: AssetMediaResponseDto;
|
let asset: AssetMediaResponseDto;
|
||||||
|
let websocket: Socket;
|
||||||
|
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
utils.initSdk();
|
utils.initSdk();
|
||||||
await utils.resetDatabase();
|
await utils.resetDatabase();
|
||||||
admin = await utils.adminSetup();
|
admin = await utils.adminSetup();
|
||||||
asset = await utils.createAsset(admin.accessToken);
|
asset = await utils.createAsset(admin.accessToken);
|
||||||
|
websocket = await utils.connectWebsocket(admin.accessToken);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(() => {
|
||||||
|
utils.disconnectWebsocket(websocket);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can be opened for shared links', async ({ page }) => {
|
test('can be opened for shared links', async ({ page }) => {
|
||||||
@@ -57,4 +64,23 @@ test.describe('Detail Panel', () => {
|
|||||||
await expect(textarea).toBeVisible();
|
await expect(textarea).toBeVisible();
|
||||||
await expect(textarea).not.toBeDisabled();
|
await expect(textarea).not.toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('description changes are visible after reopening', async ({ context, page }) => {
|
||||||
|
await utils.setAuthCookies(context, admin.accessToken);
|
||||||
|
await page.goto(`/photos/${asset.id}`);
|
||||||
|
await page.waitForSelector('#immich-asset-viewer');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Info' }).click();
|
||||||
|
const textarea = page.getByRole('textbox', { name: 'Add a description' });
|
||||||
|
await textarea.fill('new description');
|
||||||
|
await expect(textarea).toHaveValue('new description');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Info' }).click();
|
||||||
|
await expect(textarea).not.toBeVisible();
|
||||||
|
await page.getByRole('button', { name: 'Info' }).click();
|
||||||
|
await expect(textarea).toBeVisible();
|
||||||
|
|
||||||
|
await utils.waitForWebsocketEvent({ event: 'assetUpdate', id: asset.id });
|
||||||
|
await expect(textarea).toHaveValue('new description');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ test.describe('Registration', () => {
|
|||||||
// onboarding
|
// onboarding
|
||||||
await expect(page).toHaveURL('/auth/onboarding');
|
await expect(page).toHaveURL('/auth/onboarding');
|
||||||
await page.getByRole('button', { name: 'Theme' }).click();
|
await page.getByRole('button', { name: 'Theme' }).click();
|
||||||
|
await page.getByRole('button', { name: 'Privacy' }).click();
|
||||||
await page.getByRole('button', { name: 'Storage Template' }).click();
|
await page.getByRole('button', { name: 'Storage Template' }).click();
|
||||||
await page.getByRole('button', { name: 'Done' }).click();
|
await page.getByRole('button', { name: 'Done' }).click();
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ test.describe('Photo Viewer', () => {
|
|||||||
|
|
||||||
test('initially shows a loading spinner', async ({ page }) => {
|
test('initially shows a loading spinner', async ({ page }) => {
|
||||||
await page.route(`/api/assets/${asset.id}/thumbnail**`, async (route) => {
|
await page.route(`/api/assets/${asset.id}/thumbnail**`, async (route) => {
|
||||||
// slow down the request for thumbnail, so spiner has chance to show up
|
// slow down the request for thumbnail, so spinner has chance to show up
|
||||||
await new Promise((f) => setTimeout(f, 2000));
|
await new Promise((f) => setTimeout(f, 2000));
|
||||||
await route.continue();
|
await route.continue();
|
||||||
});
|
});
|
||||||
@@ -40,7 +40,7 @@ test.describe('Photo Viewer', () => {
|
|||||||
await page.goto(`/photos/${asset.id}`);
|
await page.goto(`/photos/${asset.id}`);
|
||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||||
const box = await imageLocator(page).boundingBox();
|
const box = await imageLocator(page).boundingBox();
|
||||||
expect(box).toBeTruthy;
|
expect(box).toBeTruthy();
|
||||||
const { x, y, width, height } = box!;
|
const { x, y, width, height } = box!;
|
||||||
await page.mouse.move(x + width / 2, y + height / 2);
|
await page.mouse.move(x + width / 2, y + height / 2);
|
||||||
await page.mouse.wheel(0, -1);
|
await page.mouse.wheel(0, -1);
|
||||||
|
|||||||
+1
-1
Submodule e2e/test-assets updated: 898069e47f...39f25a96f1
+10
-10
@@ -1,12 +1,12 @@
|
|||||||
ARG DEVICE=cpu
|
ARG DEVICE=cpu
|
||||||
|
|
||||||
FROM python:3.11-bookworm@sha256:f89d36dbb4728313572f88877b8be7d11fd03bea964cdf0a6b0f61edfcde3709 as builder-cpu
|
FROM python:3.11-bookworm@sha256:d0131ce0ff4bdb5e9eae6bc86ebde891c207d5cac1f3f582b5de0f903cc68384 AS builder-cpu
|
||||||
|
|
||||||
FROM builder-cpu as builder-openvino
|
FROM builder-cpu AS builder-openvino
|
||||||
|
|
||||||
FROM builder-cpu as builder-cuda
|
FROM builder-cpu AS builder-cuda
|
||||||
|
|
||||||
FROM builder-cpu as builder-armnn
|
FROM builder-cpu AS builder-armnn
|
||||||
|
|
||||||
ENV ARMNN_PATH=/opt/armnn
|
ENV ARMNN_PATH=/opt/armnn
|
||||||
COPY ann /opt/ann
|
COPY ann /opt/ann
|
||||||
@@ -15,7 +15,7 @@ RUN mkdir /opt/armnn && \
|
|||||||
cd /opt/ann && \
|
cd /opt/ann && \
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
FROM builder-${DEVICE} as builder
|
FROM builder-${DEVICE} AS builder
|
||||||
|
|
||||||
ARG DEVICE
|
ARG DEVICE
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
@@ -34,9 +34,9 @@ RUN python3 -m venv /opt/venv
|
|||||||
COPY poetry.lock pyproject.toml ./
|
COPY poetry.lock pyproject.toml ./
|
||||||
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
|
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
|
||||||
|
|
||||||
FROM python:3.11-slim-bookworm@sha256:7f49f147e57a65a5ca731203ed350ac5c88fa54aeb942924dd7057fe34a18e79 as prod-cpu
|
FROM python:3.11-slim-bookworm@sha256:a90e299af8a9cd6b59c4aaed2b024c78561476978244a1ab89742a4a5ac8c974 AS prod-cpu
|
||||||
|
|
||||||
FROM prod-cpu as prod-openvino
|
FROM prod-cpu AS prod-openvino
|
||||||
|
|
||||||
COPY scripts/configure-apt.sh ./
|
COPY scripts/configure-apt.sh ./
|
||||||
RUN ./configure-apt.sh && \
|
RUN ./configure-apt.sh && \
|
||||||
@@ -44,13 +44,13 @@ RUN ./configure-apt.sh && \
|
|||||||
apt-get install -t unstable --no-install-recommends -yqq intel-opencl-icd && \
|
apt-get install -t unstable --no-install-recommends -yqq intel-opencl-icd && \
|
||||||
rm configure-apt.sh
|
rm configure-apt.sh
|
||||||
|
|
||||||
FROM nvidia/cuda:12.3.2-cudnn9-runtime-ubuntu22.04@sha256:fa44193567d1908f7ca1f3abf8623ce9c63bc8cba7bcfdb32702eb04d326f7a8 as prod-cuda
|
FROM nvidia/cuda:12.3.2-cudnn9-runtime-ubuntu22.04@sha256:fa44193567d1908f7ca1f3abf8623ce9c63bc8cba7bcfdb32702eb04d326f7a8 AS prod-cuda
|
||||||
|
|
||||||
COPY --from=builder-cuda /usr/local/bin/python3 /usr/local/bin/python3
|
COPY --from=builder-cuda /usr/local/bin/python3 /usr/local/bin/python3
|
||||||
COPY --from=builder-cuda /usr/local/lib/python3.11 /usr/local/lib/python3.11
|
COPY --from=builder-cuda /usr/local/lib/python3.11 /usr/local/lib/python3.11
|
||||||
COPY --from=builder-cuda /usr/local/lib/libpython3.11.so /usr/local/lib/libpython3.11.so
|
COPY --from=builder-cuda /usr/local/lib/libpython3.11.so /usr/local/lib/libpython3.11.so
|
||||||
|
|
||||||
FROM prod-cpu as prod-armnn
|
FROM prod-cpu AS prod-armnn
|
||||||
|
|
||||||
ENV LD_LIBRARY_PATH=/opt/armnn
|
ENV LD_LIBRARY_PATH=/opt/armnn
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ COPY --from=builder-armnn \
|
|||||||
/opt/ann/build.sh \
|
/opt/ann/build.sh \
|
||||||
/opt/armnn/
|
/opt/armnn/
|
||||||
|
|
||||||
FROM prod-${DEVICE} as prod
|
FROM prod-${DEVICE} AS prod
|
||||||
ARG DEVICE
|
ARG DEVICE
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
from socket import socket
|
from socket import socket
|
||||||
|
|
||||||
from gunicorn.arbiter import Arbiter
|
from gunicorn.arbiter import Arbiter
|
||||||
from pydantic import BaseModel, BaseSettings
|
from pydantic.v1 import BaseModel, BaseSettings
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.logging import RichHandler
|
from rich.logging import RichHandler
|
||||||
from uvicorn import Server
|
from uvicorn import Server
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from fastapi import Depends, FastAPI, File, Form, HTTPException
|
|||||||
from fastapi.responses import ORJSONResponse
|
from fastapi.responses import ORJSONResponse
|
||||||
from onnxruntime.capi.onnxruntime_pybind11_state import InvalidProtobuf, NoSuchFile
|
from onnxruntime.capi.onnxruntime_pybind11_state import InvalidProtobuf, NoSuchFile
|
||||||
from PIL.Image import Image
|
from PIL.Image import Image
|
||||||
from pydantic import ValidationError
|
from pydantic.v1 import ValidationError
|
||||||
from starlette.formparsers import MultiPartParser
|
from starlette.formparsers import MultiPartParser
|
||||||
|
|
||||||
from app.models import get_model_deps
|
from app.models import get_model_deps
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from typing import Any, Literal, Protocol, TypedDict, TypeGuard, TypeVar
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
from pydantic import BaseModel
|
from pydantic.v1 import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class StrEnum(str, Enum):
|
class StrEnum(str, Enum):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM mambaorg/micromamba:bookworm-slim@sha256:eb744eed8e9308edaea942ddd92ad8da8a9b904ca0796fa240b72de51ce0d353 as builder
|
FROM mambaorg/micromamba:bookworm-slim@sha256:954e438daab0ad0835430ea84acb27dd47d1ea35a7120c3c9dd9d1a5578f4b13 AS builder
|
||||||
|
|
||||||
ENV TRANSFORMERS_CACHE=/cache \
|
ENV TRANSFORMERS_CACHE=/cache \
|
||||||
PYTHONDONTWRITEBYTECODE=1 \
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
|||||||
Generated
+178
-91
@@ -40,6 +40,17 @@ develop = ["imgaug (>=0.4.0)", "pytest"]
|
|||||||
imgaug = ["imgaug (>=0.4.0)"]
|
imgaug = ["imgaug (>=0.4.0)"]
|
||||||
tests = ["pytest"]
|
tests = ["pytest"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "annotated-types"
|
||||||
|
version = "0.7.0"
|
||||||
|
description = "Reusable constraint types to use with typing.Annotated"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
||||||
|
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyio"
|
name = "anyio"
|
||||||
version = "4.2.0"
|
version = "4.2.0"
|
||||||
@@ -1530,13 +1541,13 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "locust"
|
name = "locust"
|
||||||
version = "2.29.1"
|
version = "2.31.1"
|
||||||
description = "Developer-friendly load testing framework"
|
description = "Developer-friendly load testing framework"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "locust-2.29.1-py3-none-any.whl", hash = "sha256:8b15daab44cdf50eef1860a32bb30969423e3795247115e5a37446da3240c6d6"},
|
{file = "locust-2.31.1-py3-none-any.whl", hash = "sha256:20756509939004e95c622ac3042886edab38b736f00534cc03ce2774064e7f71"},
|
||||||
{file = "locust-2.29.1.tar.gz", hash = "sha256:2e0628a59e2689a50cb4735a9a43709e30f2da7ed276c15d877c5325507f44b1"},
|
{file = "locust-2.31.1.tar.gz", hash = "sha256:d26b7333cdef80645f3978d8ff9aabab4d53e41ed82cc8490212aa68e8498fdd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -1548,14 +1559,14 @@ gevent = ">=22.10.2"
|
|||||||
geventhttpclient = ">=2.3.1"
|
geventhttpclient = ">=2.3.1"
|
||||||
msgpack = ">=1.0.0"
|
msgpack = ">=1.0.0"
|
||||||
psutil = ">=5.9.1"
|
psutil = ">=5.9.1"
|
||||||
pywin32 = {version = "*", markers = "platform_system == \"Windows\""}
|
pywin32 = {version = "*", markers = "sys_platform == \"win32\""}
|
||||||
pyzmq = ">=25.0.0"
|
pyzmq = ">=25.0.0"
|
||||||
requests = [
|
requests = [
|
||||||
{version = ">=2.32.2", markers = "python_version > \"3.11\""},
|
{version = ">=2.32.2", markers = "python_full_version > \"3.11.0\""},
|
||||||
{version = ">=2.26.0", markers = "python_version <= \"3.11\""},
|
{version = ">=2.26.0", markers = "python_full_version <= \"3.11.0\""},
|
||||||
]
|
]
|
||||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""}
|
typing_extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""}
|
||||||
Werkzeug = ">=2.0.0"
|
Werkzeug = ">=2.0.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1794,38 +1805,38 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.11.0"
|
version = "1.11.1"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"},
|
{file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"},
|
||||||
{file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"},
|
{file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"},
|
||||||
{file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"},
|
{file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"},
|
||||||
{file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"},
|
{file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"},
|
||||||
{file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"},
|
{file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"},
|
||||||
{file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"},
|
{file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"},
|
||||||
{file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"},
|
{file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"},
|
||||||
{file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"},
|
{file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"},
|
||||||
{file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"},
|
{file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"},
|
||||||
{file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"},
|
{file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"},
|
||||||
{file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"},
|
{file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"},
|
||||||
{file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"},
|
{file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"},
|
||||||
{file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"},
|
{file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"},
|
||||||
{file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"},
|
{file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"},
|
||||||
{file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"},
|
{file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"},
|
||||||
{file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"},
|
{file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"},
|
||||||
{file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"},
|
{file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"},
|
||||||
{file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"},
|
{file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"},
|
||||||
{file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"},
|
{file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"},
|
||||||
{file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"},
|
{file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"},
|
||||||
{file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"},
|
{file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"},
|
||||||
{file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"},
|
{file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"},
|
||||||
{file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"},
|
{file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"},
|
||||||
{file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"},
|
{file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"},
|
||||||
{file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"},
|
{file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"},
|
||||||
{file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"},
|
{file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"},
|
||||||
{file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"},
|
{file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2117,6 +2128,8 @@ files = [
|
|||||||
{file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"},
|
{file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"},
|
||||||
{file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"},
|
{file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"},
|
||||||
{file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"},
|
{file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"},
|
||||||
|
{file = "orjson-3.10.6-cp313-none-win32.whl", hash = "sha256:efdf2c5cde290ae6b83095f03119bdc00303d7a03b42b16c54517baa3c4ca3d0"},
|
||||||
|
{file = "orjson-3.10.6-cp313-none-win_amd64.whl", hash = "sha256:8e190fe7888e2e4392f52cafb9626113ba135ef53aacc65cd13109eb9746c43e"},
|
||||||
{file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"},
|
{file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"},
|
||||||
{file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"},
|
{file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"},
|
||||||
{file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"},
|
{file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"},
|
||||||
@@ -2367,62 +2380,126 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "1.10.17"
|
version = "2.8.2"
|
||||||
description = "Data validation and settings management using python type hints"
|
description = "Data validation using Python type hints"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"},
|
{file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"},
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"},
|
{file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"},
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"},
|
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"},
|
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"},
|
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"},
|
|
||||||
{file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"},
|
|
||||||
{file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"},
|
|
||||||
{file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"},
|
|
||||||
{file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"},
|
|
||||||
{file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"},
|
|
||||||
{file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"},
|
|
||||||
{file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"},
|
|
||||||
{file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
typing-extensions = ">=4.2.0"
|
annotated-types = ">=0.4.0"
|
||||||
|
pydantic-core = "2.20.1"
|
||||||
|
typing-extensions = [
|
||||||
|
{version = ">=4.12.2", markers = "python_version >= \"3.13\""},
|
||||||
|
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
|
||||||
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dotenv = ["python-dotenv (>=0.10.4)"]
|
email = ["email-validator (>=2.0.0)"]
|
||||||
email = ["email-validator (>=1.0.3)"]
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic-core"
|
||||||
|
version = "2.20.1"
|
||||||
|
description = "Core functionality for Pydantic validation and serialization"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"},
|
||||||
|
{file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"},
|
||||||
|
{file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"},
|
||||||
|
{file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
@@ -2991,19 +3068,18 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "68.2.2"
|
version = "70.3.0"
|
||||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
|
{file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"},
|
||||||
{file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
|
{file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "six"
|
name = "six"
|
||||||
@@ -3245,6 +3321,17 @@ files = [
|
|||||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.12.2"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||||
|
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
@@ -3601,4 +3688,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.10,<4.0"
|
python-versions = ">=3.10,<4.0"
|
||||||
content-hash = "df9afeda50e05cb62b322a047028a9b0851db197c4f379903c70adab3a98777a"
|
content-hash = "187485f19267f2d0a01e38fc0c1f8911c07a29aee11080179a96a127abb9c11b"
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ opencv-python-headless = ">=4.7.0.72,<5.0"
|
|||||||
pillow = ">=9.5.0,<11.0"
|
pillow = ">=9.5.0,<11.0"
|
||||||
fastapi-slim = ">=0.95.2,<1.0"
|
fastapi-slim = ">=0.95.2,<1.0"
|
||||||
uvicorn = {extras = ["standard"], version = ">=0.22.0,<1.0"}
|
uvicorn = {extras = ["standard"], version = ">=0.22.0,<1.0"}
|
||||||
pydantic = "^1.10.8"
|
pydantic = "^2.8.2"
|
||||||
aiocache = ">=0.12.1,<1.0"
|
aiocache = ">=0.12.1,<1.0"
|
||||||
rich = ">=13.4.2"
|
rich = ">=13.4.2"
|
||||||
ftfy = ">=6.1.1"
|
ftfy = ">=6.1.1"
|
||||||
setuptools = "^68.0.0"
|
setuptools = "^70.0.0"
|
||||||
python-multipart = ">=0.0.6,<1.0"
|
python-multipart = ">=0.0.6,<1.0"
|
||||||
orjson = ">=3.9.5"
|
orjson = ">=3.9.5"
|
||||||
gunicorn = ">=21.1.0"
|
gunicorn = ">=21.1.0"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.alextran.immich"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.alextran.immich"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
<application android:label="Immich" android:name=".ImmichApp" android:usesCleartextTraffic="true"
|
<application android:label="Immich" android:name=".ImmichApp" android:usesCleartextTraffic="true"
|
||||||
android:icon="@mipmap/ic_launcher" android:requestLegacyExternalStorage="true" android:largeHeap="true">
|
android:icon="@mipmap/ic_launcher" android:requestLegacyExternalStorage="true"
|
||||||
|
android:largeHeap="true">
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.EnableImpeller"
|
android:name="io.flutter.embedding.android.EnableImpeller"
|
||||||
@@ -55,7 +56,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_MEDIA" />
|
<uses-permission android:name="android.permission.MANAGE_MEDIA" />
|
||||||
@@ -65,6 +67,7 @@
|
|||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
@@ -76,4 +79,4 @@
|
|||||||
<data android:scheme="geo" />
|
<data android:scheme="geo" />
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -8,9 +8,11 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rootProject.buildDir = '../build'
|
rootProject.buildDir = '../build'
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ pluginManagement {
|
|||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version "7.4.2" apply false
|
id "com.android.application" version "7.4.2" apply false
|
||||||
id "org.jetbrains.kotlin.android" version "1.9.24" apply false
|
id "org.jetbrains.kotlin.android" version "1.9.0" apply false
|
||||||
id "org.jetbrains.kotlin.kapt" version "1.9.24" apply false
|
id "org.jetbrains.kotlin.kapt" version "1.9.0" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
include ":app"
|
include ":app"
|
||||||
|
|||||||
@@ -201,7 +201,7 @@
|
|||||||
"delete_shared_link_dialog_title": "Delete Shared Link",
|
"delete_shared_link_dialog_title": "Delete Shared Link",
|
||||||
"description_input_hint_text": "Add description...",
|
"description_input_hint_text": "Add description...",
|
||||||
"description_input_submit_error": "Error updating description, check the log for more details",
|
"description_input_submit_error": "Error updating description, check the log for more details",
|
||||||
"edit_date_time_dialog_date_time": "Date and Time",
|
"edit_date_time_dialog_date_time": "Edit date and time",
|
||||||
"edit_date_time_dialog_timezone": "Timezone",
|
"edit_date_time_dialog_timezone": "Timezone",
|
||||||
"edit_location_dialog_title": "Location",
|
"edit_location_dialog_title": "Location",
|
||||||
"exif_bottom_sheet_description": "Add Description...",
|
"exif_bottom_sheet_description": "Add Description...",
|
||||||
@@ -531,6 +531,11 @@
|
|||||||
"theme_setting_dark_mode_switch": "Dark mode",
|
"theme_setting_dark_mode_switch": "Dark mode",
|
||||||
"theme_setting_image_viewer_quality_subtitle": "Adjust the quality of the detail image viewer",
|
"theme_setting_image_viewer_quality_subtitle": "Adjust the quality of the detail image viewer",
|
||||||
"theme_setting_image_viewer_quality_title": "Image viewer quality",
|
"theme_setting_image_viewer_quality_title": "Image viewer quality",
|
||||||
|
"theme_setting_primary_color_title": "Primary color",
|
||||||
|
"theme_setting_primary_color_subtitle": "Pick a color for primary actions and accents.",
|
||||||
|
"theme_setting_colorful_interface_title": "Colorful interface",
|
||||||
|
"theme_setting_colorful_interface_subtitle": "Apply primary color to background surfaces.",
|
||||||
|
"theme_setting_system_primary_color_title": "Use system color",
|
||||||
"theme_setting_system_theme_switch": "Automatic (Follow system setting)",
|
"theme_setting_system_theme_switch": "Automatic (Follow system setting)",
|
||||||
"theme_setting_theme_subtitle": "Choose the app's theme setting",
|
"theme_setting_theme_subtitle": "Choose the app's theme setting",
|
||||||
"theme_setting_theme_title": "Theme",
|
"theme_setting_theme_title": "Theme",
|
||||||
@@ -562,4 +567,4 @@
|
|||||||
"viewer_remove_from_stack": "Remove from Stack",
|
"viewer_remove_from_stack": "Remove from Stack",
|
||||||
"viewer_stack_use_as_main_asset": "Use as Main Asset",
|
"viewer_stack_use_as_main_asset": "Use as Main Asset",
|
||||||
"viewer_unstack": "Un-Stack"
|
"viewer_unstack": "Un-Stack"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
||||||
+17
-22
@@ -51,9 +51,6 @@ PODS:
|
|||||||
- fluttertoast (0.0.2):
|
- fluttertoast (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Toast
|
- Toast
|
||||||
- FMDB (2.7.5):
|
|
||||||
- FMDB/standard (= 2.7.5)
|
|
||||||
- FMDB/standard (2.7.5)
|
|
||||||
- geolocator_apple (1.2.0):
|
- geolocator_apple (1.2.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- image_picker_ios (0.0.1):
|
- image_picker_ios (0.0.1):
|
||||||
@@ -73,7 +70,7 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- path_provider_ios (0.0.1):
|
- path_provider_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- permission_handler_apple (9.1.1):
|
- permission_handler_apple (9.3.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- photo_manager (2.0.0):
|
- photo_manager (2.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
@@ -90,7 +87,7 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- sqflite (0.0.3):
|
- sqflite (0.0.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FlutterMacOS
|
||||||
- SwiftyGif (5.4.5)
|
- SwiftyGif (5.4.5)
|
||||||
- Toast (4.0.0)
|
- Toast (4.0.0)
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
@@ -123,7 +120,7 @@ DEPENDENCIES:
|
|||||||
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
||||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||||
@@ -132,7 +129,6 @@ SPEC REPOS:
|
|||||||
trunk:
|
trunk:
|
||||||
- DKImagePickerController
|
- DKImagePickerController
|
||||||
- DKPhotoGallery
|
- DKPhotoGallery
|
||||||
- FMDB
|
|
||||||
- MapLibre
|
- MapLibre
|
||||||
- ReachabilitySwift
|
- ReachabilitySwift
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
@@ -184,7 +180,7 @@ EXTERNAL SOURCES:
|
|||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: ".symlinks/plugins/sqflite/ios"
|
:path: ".symlinks/plugins/sqflite/darwin"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
video_player_avfoundation:
|
video_player_avfoundation:
|
||||||
@@ -200,33 +196,32 @@ SPEC CHECKSUMS:
|
|||||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
|
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
|
||||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
|
||||||
flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04
|
flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04
|
||||||
flutter_web_auth: c25208760459cec375a3c39f6a8759165ca0fa4d
|
flutter_web_auth: c25208760459cec375a3c39f6a8759165ca0fa4d
|
||||||
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
|
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
geolocator_apple: 6cbaf322953988e009e5ecb481f07efece75c450
|
||||||
geolocator_apple: 9157311f654584b9bb72686c55fc02a97b73f461
|
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||||
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
|
|
||||||
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
||||||
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073
|
||||||
MapLibre: 620fc933c1d6029b33738c905c1490d024e5d4ef
|
MapLibre: 620fc933c1d6029b33738c905c1490d024e5d4ef
|
||||||
maplibre_gl: a2efec727dd340e4c65e26d2b03b584f14881fd9
|
maplibre_gl: a2efec727dd340e4c65e26d2b03b584f14881fd9
|
||||||
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
|
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
||||||
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||||
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||||
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
|
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
SDWebImage: 066c47b573f408f18caa467d71deace7c0f8280d
|
SDWebImage: 066c47b573f408f18caa467d71deace7c0f8280d
|
||||||
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
|
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||||
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
|
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||||
video_player_avfoundation: 02011213dab73ae3687df27ce441fbbcc82b5579
|
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
|
||||||
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
|
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
|
||||||
|
|
||||||
PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
|
PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */,
|
D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */,
|
||||||
|
C494C1A226E78FAB736DAB6C /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -267,6 +268,23 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||||
};
|
};
|
||||||
|
C494C1A226E78FAB736DAB6C /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */ = {
|
D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|||||||
@@ -1,5 +1,108 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:immich_mobile/utils/immich_app_theme.dart';
|
||||||
|
|
||||||
const Color immichBackgroundColor = Color(0xFFf6f8fe);
|
enum ImmichColorPreset {
|
||||||
const Color immichDarkBackgroundColor = Color.fromARGB(255, 0, 0, 0);
|
indigo,
|
||||||
const Color immichDarkThemePrimaryColor = Color.fromARGB(255, 173, 203, 250);
|
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 immichBrandColorDark = Color(0xFFACCBFA);
|
||||||
|
|
||||||
|
final Map<ImmichColorPreset, ImmichTheme> _themePresetsMap = {
|
||||||
|
ImmichColorPreset.indigo: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(
|
||||||
|
seedColor: immichBrandColorLight,
|
||||||
|
).copyWith(primary: immichBrandColorLight),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: immichBrandColorDark,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
).copyWith(primary: immichBrandColorDark),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.deepPurple: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFF6F43C0)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFD3BBFF),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.pink: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFFED79B5)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFED79B5),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.red: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFFC51C16)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFD3302F),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.orange: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xffff5b01),
|
||||||
|
dynamicSchemeVariant: DynamicSchemeVariant.fidelity,
|
||||||
|
),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFCC6D08),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
dynamicSchemeVariant: DynamicSchemeVariant.fidelity,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.yellow: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFFFFB400)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFFFB400),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.lime: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFFCDDC39)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFFCDDC39),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.green: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFF18C249)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFF18C249),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.cyan: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(seedColor: const Color(0xFF00BCD4)),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFF00BCD4),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImmichColorPreset.slateGray: ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xFF696969),
|
||||||
|
dynamicSchemeVariant: DynamicSchemeVariant.neutral,
|
||||||
|
),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: const Color(0xff696969),
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
dynamicSchemeVariant: DynamicSchemeVariant.neutral,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
extension ImmichColorModeExtension on ImmichColorPreset {
|
||||||
|
ImmichTheme getTheme() => _themePresetsMap[this]!;
|
||||||
|
}
|
||||||
|
|||||||
@@ -170,6 +170,30 @@ class ExifInfo {
|
|||||||
state.hashCode ^
|
state.hashCode ^
|
||||||
country.hashCode ^
|
country.hashCode ^
|
||||||
description.hashCode;
|
description.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return """
|
||||||
|
{
|
||||||
|
id: $id,
|
||||||
|
fileSize: $fileSize,
|
||||||
|
dateTimeOriginal: $dateTimeOriginal,
|
||||||
|
timeZone: $timeZone,
|
||||||
|
make: $make,
|
||||||
|
model: $model,
|
||||||
|
lens: $lens,
|
||||||
|
f: $f,
|
||||||
|
mm: $mm,
|
||||||
|
iso: $iso,
|
||||||
|
exposureSeconds: $exposureSeconds,
|
||||||
|
lat: $lat,
|
||||||
|
long: $long,
|
||||||
|
city: $city,
|
||||||
|
state: $state,
|
||||||
|
country: $country,
|
||||||
|
description: $description,
|
||||||
|
}""";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double? _exposureTimeToSeconds(String? s) {
|
double? _exposureTimeToSeconds(String? s) {
|
||||||
|
|||||||
@@ -229,6 +229,11 @@ enum StoreKey<T> {
|
|||||||
mapwithPartners<bool>(125, type: bool),
|
mapwithPartners<bool>(125, type: bool),
|
||||||
enableHapticFeedback<bool>(126, type: bool),
|
enableHapticFeedback<bool>(126, type: bool),
|
||||||
customHeaders<String>(127, type: String),
|
customHeaders<String>(127, type: String),
|
||||||
|
|
||||||
|
// theme settings
|
||||||
|
primaryColor<String>(128, type: String),
|
||||||
|
dynamicTheme<bool>(129, type: bool),
|
||||||
|
colorfulInterface<bool>(130, type: bool),
|
||||||
;
|
;
|
||||||
|
|
||||||
const StoreKey(
|
const StoreKey(
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ extension ContextHelper on BuildContext {
|
|||||||
bool get isDarkTheme => themeData.brightness == Brightness.dark;
|
bool get isDarkTheme => themeData.brightness == Brightness.dark;
|
||||||
|
|
||||||
// Returns the current Primary color of the Theme
|
// Returns the current Primary color of the Theme
|
||||||
Color get primaryColor => themeData.primaryColor;
|
Color get primaryColor => themeData.colorScheme.primary;
|
||||||
|
|
||||||
// Returns the Scaffold background color of the Theme
|
// Returns the Scaffold background color of the Theme
|
||||||
Color get scaffoldBackgroundColor => themeData.scaffoldBackgroundColor;
|
Color get scaffoldBackgroundColor => colorScheme.surface;
|
||||||
|
|
||||||
// Returns the current TextTheme
|
// Returns the current TextTheme
|
||||||
TextTheme get textTheme => themeData.textTheme;
|
TextTheme get textTheme => themeData.textTheme;
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
extension ImmichColorSchemeExtensions on ColorScheme {
|
||||||
|
bool get _isDarkMode => brightness == Brightness.dark;
|
||||||
|
Color get onSurfaceSecondary => _isDarkMode
|
||||||
|
? onSurface.darken(amount: .3)
|
||||||
|
: onSurface.lighten(amount: .3);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ColorExtensions on Color {
|
||||||
|
Color lighten({double amount = 0.1}) {
|
||||||
|
return Color.alphaBlend(
|
||||||
|
Colors.white.withOpacity(amount),
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color darken({double amount = 0.1}) {
|
||||||
|
return Color.alphaBlend(
|
||||||
|
Colors.black.withOpacity(amount),
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,6 +65,8 @@ Future<void> initApp() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await fetchSystemPalette();
|
||||||
|
|
||||||
// Initialize Immich Logger Service
|
// Initialize Immich Logger Service
|
||||||
ImmichLogger();
|
ImmichLogger();
|
||||||
|
|
||||||
@@ -187,6 +189,7 @@ class ImmichAppState extends ConsumerState<ImmichApp>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var router = ref.watch(appRouterProvider);
|
var router = ref.watch(appRouterProvider);
|
||||||
|
var immichTheme = ref.watch(immichThemeProvider);
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
@@ -196,9 +199,9 @@ class ImmichAppState extends ConsumerState<ImmichApp>
|
|||||||
home: MaterialApp.router(
|
home: MaterialApp.router(
|
||||||
title: 'Immich',
|
title: 'Immich',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
themeMode: ref.watch(immichThemeProvider),
|
themeMode: ref.watch(immichThemeModeProvider),
|
||||||
darkTheme: immichDarkTheme,
|
darkTheme: getThemeData(colorScheme: immichTheme.dark),
|
||||||
theme: immichLightTheme,
|
theme: getThemeData(colorScheme: immichTheme.light),
|
||||||
routeInformationParser: router.defaultRouteParser(),
|
routeInformationParser: router.defaultRouteParser(),
|
||||||
routerDelegate: router.delegate(
|
routerDelegate: router.delegate(
|
||||||
navigatorObservers: () => [TabNavigationObserver(ref: ref)],
|
navigatorObservers: () => [TabNavigationObserver(ref: ref)],
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import 'package:auto_route/auto_route.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart';
|
import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart';
|
||||||
import 'package:photo_manager/photo_manager.dart';
|
import 'package:photo_manager/photo_manager.dart';
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ class AlbumPreviewPage extends HookConsumerWidget {
|
|||||||
"ID ${album.id}",
|
"ID ${album.id}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: Colors.grey[600],
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||||
import 'package:immich_mobile/widgets/backup/album_info_card.dart';
|
import 'package:immich_mobile/widgets/backup/album_info_card.dart';
|
||||||
@@ -128,13 +127,12 @@ class BackupAlbumSelectionPage extends HookConsumerWidget {
|
|||||||
album.name,
|
album.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: isDarkTheme ? Colors.black : immichBackgroundColor,
|
color: context.scaffoldBackgroundColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.red[300],
|
backgroundColor: Colors.red[300],
|
||||||
deleteIconColor:
|
deleteIconColor: context.scaffoldBackgroundColor,
|
||||||
isDarkTheme ? Colors.black : immichBackgroundColor,
|
|
||||||
deleteIcon: const Icon(
|
deleteIcon: const Icon(
|
||||||
Icons.cancel_rounded,
|
Icons.cancel_rounded,
|
||||||
size: 15,
|
size: 15,
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||||
import 'package:immich_mobile/providers/album/album.provider.dart';
|
import 'package:immich_mobile/providers/album/album.provider.dart';
|
||||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||||
@@ -17,6 +20,7 @@ import 'package:immich_mobile/providers/websocket.provider.dart';
|
|||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/widgets/backup/backup_info_card.dart';
|
import 'package:immich_mobile/widgets/backup/backup_info_card.dart';
|
||||||
import 'package:immich_mobile/widgets/backup/current_backup_asset_info_box.dart';
|
import 'package:immich_mobile/widgets/backup/current_backup_asset_info_box.dart';
|
||||||
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class BackupControllerPage extends HookConsumerWidget {
|
class BackupControllerPage extends HookConsumerWidget {
|
||||||
@@ -27,6 +31,9 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
BackUpState backupState = ref.watch(backupProvider);
|
BackUpState backupState = ref.watch(backupProvider);
|
||||||
final hasAnyAlbum = backupState.selectedBackupAlbums.isNotEmpty;
|
final hasAnyAlbum = backupState.selectedBackupAlbums.isNotEmpty;
|
||||||
final didGetBackupInfo = useState(false);
|
final didGetBackupInfo = useState(false);
|
||||||
|
final isScreenDarkened = useState(false);
|
||||||
|
final darkenScreenTimer = useRef<Timer?>(null);
|
||||||
|
|
||||||
bool hasExclusiveAccess =
|
bool hasExclusiveAccess =
|
||||||
backupState.backupProgress != BackUpProgressEnum.inBackground;
|
backupState.backupProgress != BackUpProgressEnum.inBackground;
|
||||||
bool shouldBackup = backupState.allUniqueAssets.length -
|
bool shouldBackup = backupState.allUniqueAssets.length -
|
||||||
@@ -36,6 +43,25 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
? false
|
? false
|
||||||
: true;
|
: true;
|
||||||
|
|
||||||
|
void startScreenDarkenTimer() {
|
||||||
|
darkenScreenTimer.value = Timer(const Duration(seconds: 30), () {
|
||||||
|
isScreenDarkened.value = true;
|
||||||
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopScreenDarkenTimer() {
|
||||||
|
isScreenDarkened.value = false;
|
||||||
|
darkenScreenTimer.value?.cancel();
|
||||||
|
SystemChrome.setEnabledSystemUIMode(
|
||||||
|
SystemUiMode.manual,
|
||||||
|
overlays: [
|
||||||
|
SystemUiOverlay.top,
|
||||||
|
SystemUiOverlay.bottom,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
// Update the background settings information just to make sure we
|
// Update the background settings information just to make sure we
|
||||||
@@ -48,7 +74,14 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
ref
|
ref
|
||||||
.watch(websocketProvider.notifier)
|
.watch(websocketProvider.notifier)
|
||||||
.stopListenToEvent('on_upload_success');
|
.stopListenToEvent('on_upload_success');
|
||||||
return null;
|
|
||||||
|
WakelockPlus.enable();
|
||||||
|
|
||||||
|
return () {
|
||||||
|
WakelockPlus.disable();
|
||||||
|
darkenScreenTimer.value?.cancel();
|
||||||
|
isScreenDarkened.value = false;
|
||||||
|
};
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -65,6 +98,19 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
[backupState.backupProgress],
|
[backupState.backupProgress],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() {
|
||||||
|
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
|
||||||
|
startScreenDarkenTimer();
|
||||||
|
} else {
|
||||||
|
stopScreenDarkenTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
[backupState.backupProgress],
|
||||||
|
);
|
||||||
|
|
||||||
Widget buildSelectedAlbumName() {
|
Widget buildSelectedAlbumName() {
|
||||||
var text = "backup_controller_page_backup_selected".tr();
|
var text = "backup_controller_page_backup_selected".tr();
|
||||||
var albums = ref.watch(backupProvider).selectedBackupAlbums;
|
var albums = ref.watch(backupProvider).selectedBackupAlbums;
|
||||||
@@ -130,9 +176,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: context.isDarkTheme
|
color: context.colorScheme.outlineVariant,
|
||||||
? const Color.fromARGB(255, 56, 56, 56)
|
|
||||||
: Colors.black12,
|
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -151,7 +195,9 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"backup_controller_page_to_backup",
|
"backup_controller_page_to_backup",
|
||||||
style: context.textTheme.bodyMedium,
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
buildSelectedAlbumName(),
|
buildSelectedAlbumName(),
|
||||||
buildExcludedAlbumName(),
|
buildExcludedAlbumName(),
|
||||||
@@ -251,72 +297,102 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return GestureDetector(
|
||||||
appBar: AppBar(
|
onTap: () {
|
||||||
elevation: 0,
|
if (isScreenDarkened.value) {
|
||||||
title: const Text(
|
stopScreenDarkenTimer();
|
||||||
"backup_controller_page_backup",
|
}
|
||||||
).tr(),
|
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
|
||||||
leading: IconButton(
|
startScreenDarkenTimer();
|
||||||
onPressed: () {
|
}
|
||||||
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
},
|
||||||
context.maybePop(true);
|
child: AnimatedOpacity(
|
||||||
},
|
opacity: isScreenDarkened.value ? 0.1 : 1.0,
|
||||||
splashRadius: 24,
|
duration: const Duration(seconds: 1),
|
||||||
icon: const Icon(
|
child: Scaffold(
|
||||||
Icons.arrow_back_ios_rounded,
|
appBar: AppBar(
|
||||||
),
|
elevation: 0,
|
||||||
),
|
title: const Text(
|
||||||
actions: [
|
"backup_controller_page_backup",
|
||||||
Padding(
|
).tr(),
|
||||||
padding: const EdgeInsets.only(right: 8.0),
|
leading: IconButton(
|
||||||
child: IconButton(
|
onPressed: () {
|
||||||
onPressed: () => context.pushRoute(const BackupOptionsRoute()),
|
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
||||||
|
context.maybePop(true);
|
||||||
|
},
|
||||||
splashRadius: 24,
|
splashRadius: 24,
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.settings_outlined,
|
Icons.arrow_back_ios_rounded,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
actions: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () =>
|
||||||
|
context.pushRoute(const BackupOptionsRoute()),
|
||||||
|
splashRadius: 24,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.settings_outlined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.only(left: 16.0, right: 16, bottom: 32),
|
||||||
|
child: ListView(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: hasAnyAlbum
|
||||||
|
? [
|
||||||
|
buildFolderSelectionTile(),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_total".tr(),
|
||||||
|
subtitle: "backup_controller_page_total_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${backupState.allUniqueAssets.length}",
|
||||||
|
),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_backup".tr(),
|
||||||
|
subtitle: "backup_controller_page_backup_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${backupState.selectedAlbumsBackupAssetsIds.length}",
|
||||||
|
),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_remainder".tr(),
|
||||||
|
subtitle:
|
||||||
|
"backup_controller_page_remainder_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${max(0, backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length)}",
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
const CurrentUploadingAssetInfoBox(),
|
||||||
|
if (!hasExclusiveAccess) buildBackgroundBackupInfo(),
|
||||||
|
buildBackupButton(),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
buildFolderSelectionTile(),
|
||||||
|
if (!didGetBackupInfo.value) buildLoadingIndicator(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 32),
|
|
||||||
child: ListView(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: hasAnyAlbum
|
|
||||||
? [
|
|
||||||
buildFolderSelectionTile(),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_total".tr(),
|
|
||||||
subtitle: "backup_controller_page_total_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${backupState.allUniqueAssets.length}",
|
|
||||||
),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_backup".tr(),
|
|
||||||
subtitle: "backup_controller_page_backup_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${backupState.selectedAlbumsBackupAssetsIds.length}",
|
|
||||||
),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_remainder".tr(),
|
|
||||||
subtitle: "backup_controller_page_remainder_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${max(0, backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length)}",
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
const CurrentUploadingAssetInfoBox(),
|
|
||||||
if (!hasExclusiveAccess) buildBackgroundBackupInfo(),
|
|
||||||
buildBackupButton(),
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
buildFolderSelectionTile(),
|
|
||||||
if (!didGetBackupInfo.value) buildLoadingIndicator(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'package:immich_mobile/entities/album.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/user.entity.dart';
|
import 'package:immich_mobile/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
||||||
|
|
||||||
@RoutePage<List<String>?>()
|
@RoutePage()
|
||||||
class AlbumAdditionalSharedUserSelectionPage extends HookConsumerWidget {
|
class AlbumAdditionalSharedUserSelectionPage extends HookConsumerWidget {
|
||||||
final Album album;
|
final Album album;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import 'package:immich_mobile/widgets/asset_grid/immich_asset_grid.dart';
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
@RoutePage<AssetSelectionPageResult?>()
|
@RoutePage()
|
||||||
class AlbumAssetSelectionPage extends HookConsumerWidget {
|
class AlbumAssetSelectionPage extends HookConsumerWidget {
|
||||||
const AlbumAssetSelectionPage({
|
const AlbumAssetSelectionPage({
|
||||||
super.key,
|
super.key,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/album/shared_album.provider.dart';
|
import 'package:immich_mobile/providers/album/shared_album.provider.dart';
|
||||||
import 'package:immich_mobile/providers/authentication.provider.dart';
|
import 'package:immich_mobile/providers/authentication.provider.dart';
|
||||||
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
|
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
|
||||||
@@ -102,7 +103,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
backgroundColor: context.scaffoldBackgroundColor,
|
backgroundColor: context.colorScheme.surfaceContainer,
|
||||||
isScrollControlled: false,
|
isScrollControlled: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
@@ -131,7 +132,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
album.owner.value?.email ?? "",
|
album.owner.value?.email ?? "",
|
||||||
style: TextStyle(color: Colors.grey[600]),
|
style: TextStyle(color: context.colorScheme.onSurfaceSecondary),
|
||||||
),
|
),
|
||||||
trailing: Text(
|
trailing: Text(
|
||||||
"shared_album_section_people_owner_label",
|
"shared_album_section_people_owner_label",
|
||||||
@@ -160,7 +161,9 @@ class AlbumOptionsPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
user.email,
|
user.email,
|
||||||
style: TextStyle(color: Colors.grey[600]),
|
style: TextStyle(
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
trailing: userId == user.id || isOwner
|
trailing: userId == user.id || isOwner
|
||||||
? const Icon(Icons.more_horiz_rounded)
|
? const Icon(Icons.more_horiz_rounded)
|
||||||
@@ -214,7 +217,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
|
|||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
"shared_album_activity_setting_subtitle",
|
"shared_album_activity_setting_subtitle",
|
||||||
style: context.textTheme.labelLarge?.copyWith(
|
style: context.textTheme.labelLarge?.copyWith(
|
||||||
color: context.textTheme.labelLarge?.color?.withAlpha(175),
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/user.entity.dart';
|
import 'package:immich_mobile/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
||||||
|
|
||||||
@RoutePage<List<String>>()
|
@RoutePage()
|
||||||
class AlbumSharedUserSelectionPage extends HookConsumerWidget {
|
class AlbumSharedUserSelectionPage extends HookConsumerWidget {
|
||||||
const AlbumSharedUserSelectionPage({super.key, required this.assets});
|
const AlbumSharedUserSelectionPage({super.key, required this.assets});
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import 'package:immich_mobile/providers/album/current_album.provider.dart';
|
|||||||
import 'package:immich_mobile/providers/album/shared_album.provider.dart';
|
import 'package:immich_mobile/providers/album/shared_album.provider.dart';
|
||||||
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
|
import 'package:immich_mobile/utils/immich_loading_overlay.dart';
|
||||||
import 'package:immich_mobile/services/album.service.dart';
|
import 'package:immich_mobile/services/album.service.dart';
|
||||||
import 'package:immich_mobile/widgets/album/album_action_outlined_button.dart';
|
import 'package:immich_mobile/widgets/album/album_action_filled_button.dart';
|
||||||
import 'package:immich_mobile/widgets/album/album_viewer_editable_title.dart';
|
import 'package:immich_mobile/widgets/album/album_viewer_editable_title.dart';
|
||||||
import 'package:immich_mobile/providers/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/multiselect.provider.dart';
|
||||||
import 'package:immich_mobile/providers/authentication.provider.dart';
|
import 'package:immich_mobile/providers/authentication.provider.dart';
|
||||||
@@ -114,13 +114,13 @@ class AlbumViewerPage extends HookConsumerWidget {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
AlbumActionOutlinedButton(
|
AlbumActionFilledButton(
|
||||||
iconData: Icons.add_photo_alternate_outlined,
|
iconData: Icons.add_photo_alternate_outlined,
|
||||||
onPressed: () => onAddPhotosPressed(album),
|
onPressed: () => onAddPhotosPressed(album),
|
||||||
labelText: "share_add_photos".tr(),
|
labelText: "share_add_photos".tr(),
|
||||||
),
|
),
|
||||||
if (userId == album.ownerId)
|
if (userId == album.ownerId)
|
||||||
AlbumActionOutlinedButton(
|
AlbumActionFilledButton(
|
||||||
iconData: Icons.person_add_alt_rounded,
|
iconData: Icons.person_add_alt_rounded,
|
||||||
onPressed: () => onAddUsersPressed(album),
|
onPressed: () => onAddUsersPressed(album),
|
||||||
labelText: "album_viewer_page_share_add_users".tr(),
|
labelText: "album_viewer_page_share_add_users".tr(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/entities/logger_message.entity.dart';
|
import 'package:immich_mobile/entities/logger_message.entity.dart';
|
||||||
import 'package:immich_mobile/services/immich_logger.service.dart';
|
import 'package:immich_mobile/services/immich_logger.service.dart';
|
||||||
@@ -18,7 +19,6 @@ class AppLogPage extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final immichLogger = ImmichLogger();
|
final immichLogger = ImmichLogger();
|
||||||
final logMessages = useState(immichLogger.messages);
|
final logMessages = useState(immichLogger.messages);
|
||||||
final isDarkTheme = context.isDarkTheme;
|
|
||||||
|
|
||||||
Widget colorStatusIndicator(Color color) {
|
Widget colorStatusIndicator(Color color) {
|
||||||
return Column(
|
return Column(
|
||||||
@@ -55,13 +55,9 @@ class AppLogPage extends HookConsumerWidget {
|
|||||||
case LogLevel.INFO:
|
case LogLevel.INFO:
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
case LogLevel.SEVERE:
|
case LogLevel.SEVERE:
|
||||||
return isDarkTheme
|
return Colors.redAccent.withOpacity(0.25);
|
||||||
? Colors.redAccent.withOpacity(0.25)
|
|
||||||
: Colors.redAccent.withOpacity(0.075);
|
|
||||||
case LogLevel.WARNING:
|
case LogLevel.WARNING:
|
||||||
return isDarkTheme
|
return Colors.orangeAccent.withOpacity(0.25);
|
||||||
? Colors.orangeAccent.withOpacity(0.25)
|
|
||||||
: Colors.orangeAccent.withOpacity(0.075);
|
|
||||||
default:
|
default:
|
||||||
return context.primaryColor.withOpacity(0.1);
|
return context.primaryColor.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
@@ -120,10 +116,7 @@ class AppLogPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: ListView.separated(
|
body: ListView.separated(
|
||||||
separatorBuilder: (context, index) {
|
separatorBuilder: (context, index) {
|
||||||
return Divider(
|
return const Divider(height: 0);
|
||||||
height: 0,
|
|
||||||
color: isDarkTheme ? Colors.white70 : Colors.grey[600],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
itemCount: logMessages.value.length,
|
itemCount: logMessages.value.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
@@ -141,8 +134,9 @@ class AppLogPage extends HookConsumerWidget {
|
|||||||
minLeadingWidth: 10,
|
minLeadingWidth: 10,
|
||||||
title: Text(
|
title: Text(
|
||||||
truncateLogMessage(logMessage.message, 4),
|
truncateLogMessage(logMessage.message, 4),
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
fontFamily: "Inconsolata",
|
fontFamily: "Inconsolata",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -150,7 +144,7 @@ class AppLogPage extends HookConsumerWidget {
|
|||||||
"at ${DateFormat("HH:mm:ss.SSS").format(logMessage.createdAt)} in ${logMessage.context1}",
|
"at ${DateFormat("HH:mm:ss.SSS").format(logMessage.createdAt)} in ${logMessage.context1}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12.0,
|
fontSize: 12.0,
|
||||||
color: Colors.grey[600],
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
leading: buildLeadingIcon(logMessage.level),
|
leading: buildLeadingIcon(logMessage.level),
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
var isDarkTheme = context.isDarkTheme;
|
|
||||||
|
|
||||||
buildTextWithCopyButton(String header, String text) {
|
buildTextWithCopyButton(String header, String text) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@@ -61,7 +59,7 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isDarkTheme ? Colors.grey[900] : Colors.grey[200],
|
color: context.colorScheme.surfaceContainerHigh,
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
borderRadius: BorderRadius.circular(15.0),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@@ -100,7 +98,7 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isDarkTheme ? Colors.grey[900] : Colors.grey[200],
|
color: context.colorScheme.surfaceContainerHigh,
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
borderRadius: BorderRadius.circular(15.0),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'package:immich_mobile/providers/album/album.provider.dart';
|
|||||||
import 'package:immich_mobile/providers/album/album_title.provider.dart';
|
import 'package:immich_mobile/providers/album/album_title.provider.dart';
|
||||||
import 'package:immich_mobile/providers/asset.provider.dart';
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/widgets/album/album_action_outlined_button.dart';
|
import 'package:immich_mobile/widgets/album/album_action_filled_button.dart';
|
||||||
import 'package:immich_mobile/widgets/album/album_title_text_field.dart';
|
import 'package:immich_mobile/widgets/album/album_title_text_field.dart';
|
||||||
import 'package:immich_mobile/widgets/album/shared_album_thumbnail_image.dart';
|
import 'package:immich_mobile/widgets/album/shared_album_thumbnail_image.dart';
|
||||||
|
|
||||||
@@ -109,20 +109,16 @@ class CreateAlbumPage extends HookConsumerWidget {
|
|||||||
if (selectedAssets.value.isEmpty) {
|
if (selectedAssets.value.isEmpty) {
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 16, left: 18, right: 18),
|
padding: const EdgeInsets.only(top: 16, left: 16, right: 16),
|
||||||
child: OutlinedButton.icon(
|
child: FilledButton.icon(
|
||||||
style: OutlinedButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.symmetric(vertical: 22, horizontal: 16),
|
const EdgeInsets.symmetric(vertical: 24, horizontal: 16),
|
||||||
side: BorderSide(
|
|
||||||
color: context.isDarkTheme
|
|
||||||
? const Color.fromARGB(255, 63, 63, 63)
|
|
||||||
: const Color.fromARGB(255, 129, 129, 129),
|
|
||||||
),
|
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
|
backgroundColor: context.colorScheme.surfaceContainerHigh,
|
||||||
),
|
),
|
||||||
onPressed: onSelectPhotosButtonPressed,
|
onPressed: onSelectPhotosButtonPressed,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
@@ -134,6 +130,7 @@ class CreateAlbumPage extends HookConsumerWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'create_shared_album_page_share_select_photos',
|
'create_shared_album_page_share_select_photos',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
color: context.primaryColor,
|
color: context.primaryColor,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
@@ -150,11 +147,11 @@ class CreateAlbumPage extends HookConsumerWidget {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
|
padding: const EdgeInsets.only(left: 12.0, top: 16, bottom: 16),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 30,
|
height: 42,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
AlbumActionOutlinedButton(
|
AlbumActionFilledButton(
|
||||||
iconData: Icons.add_photo_alternate_outlined,
|
iconData: Icons.add_photo_alternate_outlined,
|
||||||
onPressed: onSelectPhotosButtonPressed,
|
onPressed: onSelectPhotosButtonPressed,
|
||||||
labelText: "share_add_photos".tr(),
|
labelText: "share_add_photos".tr(),
|
||||||
@@ -266,7 +263,7 @@ class CreateAlbumPage extends HookConsumerWidget {
|
|||||||
pinned: true,
|
pinned: true,
|
||||||
floating: false,
|
floating: false,
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: const Size.fromHeight(66.0),
|
preferredSize: const Size.fromHeight(96.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
buildTitleInputField(),
|
buildTitleInputField(),
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import 'package:immich_mobile/services/app_settings.service.dart';
|
|||||||
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_viewer/advanced_bottom_sheet.dart';
|
import 'package:immich_mobile/widgets/asset_viewer/advanced_bottom_sheet.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_viewer/bottom_gallery_bar.dart';
|
import 'package:immich_mobile/widgets/asset_viewer/bottom_gallery_bar.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_viewer/exif_sheet/exif_bottom_sheet.dart';
|
import 'package:immich_mobile/widgets/asset_viewer/detail_panel/detail_panel.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_viewer/gallery_app_bar.dart';
|
import 'package:immich_mobile/widgets/asset_viewer/gallery_app_bar.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_image.dart';
|
import 'package:immich_mobile/widgets/common/immich_image.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
||||||
@@ -152,7 +152,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||||||
.watch(appSettingsServiceProvider)
|
.watch(appSettingsServiceProvider)
|
||||||
.getSetting<bool>(AppSettingsEnum.advancedTroubleshooting)
|
.getSetting<bool>(AppSettingsEnum.advancedTroubleshooting)
|
||||||
? AdvancedBottomSheet(assetDetail: asset)
|
? AdvancedBottomSheet(assetDetail: asset)
|
||||||
: ExifBottomSheet(asset: asset),
|
: DetailPanel(asset: asset),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -49,10 +49,6 @@ class SettingsPage extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
bottom: const PreferredSize(
|
|
||||||
preferredSize: Size.fromHeight(1),
|
|
||||||
child: Divider(height: 1),
|
|
||||||
),
|
|
||||||
title: const Text('setting_pages_app_bar_settings').tr(),
|
title: const Text('setting_pages_app_bar_settings').tr(),
|
||||||
),
|
),
|
||||||
body: context.isMobile ? _MobileLayout() : _TabletLayout(),
|
body: context.isMobile ? _MobileLayout() : _TabletLayout(),
|
||||||
@@ -67,13 +63,18 @@ class _MobileLayout extends StatelessWidget {
|
|||||||
children: SettingSection.values
|
children: SettingSection.values
|
||||||
.map(
|
.map(
|
||||||
(s) => ListTile(
|
(s) => ListTile(
|
||||||
title: Text(
|
contentPadding:
|
||||||
s.title,
|
const EdgeInsets.symmetric(vertical: 2.0, horizontal: 16.0),
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
).tr(),
|
|
||||||
leading: Icon(s.icon),
|
leading: Icon(s.icon),
|
||||||
|
title: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Text(
|
||||||
|
s.title,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
),
|
||||||
onTap: () => context.pushRoute(SettingsSubRoute(section: s)),
|
onTap: () => context.pushRoute(SettingsSubRoute(section: s)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -102,7 +103,7 @@ class _TabletLayout extends HookWidget {
|
|||||||
leading: Icon(s.icon),
|
leading: Icon(s.icon),
|
||||||
selected: s.index == selectedSection.value.index,
|
selected: s.index == selectedSection.value.index,
|
||||||
selectedColor: context.primaryColor,
|
selectedColor: context.primaryColor,
|
||||||
selectedTileColor: context.primaryColor.withAlpha(50),
|
selectedTileColor: context.themeData.highlightColor,
|
||||||
onTap: () => selectedSection.value = s,
|
onTap: () => selectedSection.value = s,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -97,8 +97,10 @@ class EditImagePage extends ConsumerWidget {
|
|||||||
gravity: ToastGravity.CENTER,
|
gravity: ToastGravity.CENTER,
|
||||||
);
|
);
|
||||||
|
|
||||||
await PhotoManager.editor
|
await PhotoManager.editor.saveImage(
|
||||||
.saveImage(imageData, title: "_edited.jpg");
|
imageData,
|
||||||
|
title: '${asset!.fileName}_edited.jpg',
|
||||||
|
);
|
||||||
await ref.read(albumProvider.notifier).getDeviceAlbums();
|
await ref.read(albumProvider.notifier).getDeviceAlbums();
|
||||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
final trashEnabled =
|
final trashEnabled =
|
||||||
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
|
ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash));
|
||||||
final albums = ref.watch(albumProvider);
|
final albums = ref.watch(albumProvider);
|
||||||
final isDarkTheme = context.isDarkTheme;
|
|
||||||
final albumSortOption = ref.watch(albumSortByOptionsProvider);
|
final albumSortOption = ref.watch(albumSortByOptionsProvider);
|
||||||
final albumSortIsReverse = ref.watch(albumSortOrderProvider);
|
final albumSortIsReverse = ref.watch(albumSortOrderProvider);
|
||||||
|
|
||||||
@@ -116,12 +115,7 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
width: cardSize,
|
width: cardSize,
|
||||||
height: cardSize,
|
height: cardSize,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
color: context.colorScheme.surfaceContainer,
|
||||||
color: isDarkTheme
|
|
||||||
? const Color.fromARGB(255, 53, 53, 53)
|
|
||||||
: const Color.fromARGB(255, 203, 203, 203),
|
|
||||||
),
|
|
||||||
color: isDarkTheme ? Colors.grey[900] : Colors.grey[50],
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -139,7 +133,9 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'library_page_new_album',
|
'library_page_new_album',
|
||||||
style: context.textTheme.labelLarge,
|
style: context.textTheme.labelLarge?.copyWith(
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -156,26 +152,25 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
Function() onClick,
|
Function() onClick,
|
||||||
) {
|
) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: OutlinedButton.icon(
|
child: FilledButton.icon(
|
||||||
onPressed: onClick,
|
onPressed: onClick,
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
label,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: context.isDarkTheme
|
color: context.colorScheme.onSurface,
|
||||||
? Colors.white
|
|
||||||
: Colors.black.withAlpha(200),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: OutlinedButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
elevation: 0,
|
||||||
backgroundColor: isDarkTheme ? Colors.grey[900] : Colors.grey[50],
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
||||||
side: BorderSide(
|
backgroundColor: context.colorScheme.surfaceContainer,
|
||||||
color: isDarkTheme ? Colors.grey[800]! : Colors.grey[300]!,
|
|
||||||
),
|
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
icon,
|
icon,
|
||||||
@@ -247,6 +242,7 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
Text(
|
Text(
|
||||||
'library_page_albums',
|
'library_page_albums',
|
||||||
style: context.textTheme.bodyLarge?.copyWith(
|
style: context.textTheme.bodyLarge?.copyWith(
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/widgets/forms/login/login_form.dart';
|
import 'package:immich_mobile/widgets/forms/login/login_form.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
@@ -39,8 +40,8 @@ class LoginPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'v${appVersion.value}',
|
'v${appVersion.value}',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.grey,
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: "Inconsolata",
|
fontFamily: "Inconsolata",
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import 'package:immich_mobile/widgets/map/map_theme_override.dart';
|
|||||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||||
import 'package:immich_mobile/utils/map_utils.dart';
|
import 'package:immich_mobile/utils/map_utils.dart';
|
||||||
|
|
||||||
@RoutePage<LatLng?>()
|
@RoutePage()
|
||||||
class MapLocationPickerPage extends HookConsumerWidget {
|
class MapLocationPickerPage extends HookConsumerWidget {
|
||||||
final LatLng initialLatLng;
|
final LatLng initialLatLng;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/models/search/search_curated_content.model.dart';
|
import 'package:immich_mobile/models/search/search_curated_content.model.dart';
|
||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
||||||
import 'package:immich_mobile/providers/search/people.provider.dart';
|
import 'package:immich_mobile/providers/search/people.provider.dart';
|
||||||
@@ -38,7 +39,7 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
fontSize: 15.0,
|
fontSize: 15.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Color categoryIconColor = context.isDarkTheme ? Colors.white : Colors.black;
|
Color categoryIconColor = context.colorScheme.onSurface;
|
||||||
|
|
||||||
showNameEditModel(
|
showNameEditModel(
|
||||||
String personId,
|
String personId,
|
||||||
@@ -128,13 +129,9 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
child: Card(
|
child: Card(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
color: context.colorScheme.surfaceContainerHigh,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(50),
|
||||||
side: BorderSide(
|
|
||||||
color: context.isDarkTheme
|
|
||||||
? Colors.grey[800]!
|
|
||||||
: const Color.fromARGB(255, 225, 225, 225),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@@ -144,13 +141,15 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.search, color: context.primaryColor),
|
Icon(
|
||||||
|
Icons.search,
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
const SizedBox(width: 16.0),
|
const SizedBox(width: 16.0),
|
||||||
Text(
|
Text(
|
||||||
"search_bar_hint",
|
"search_bar_hint",
|
||||||
style: context.textTheme.bodyLarge?.copyWith(
|
style: context.textTheme.bodyLarge?.copyWith(
|
||||||
color:
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
context.isDarkTheme ? Colors.white70 : Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
||||||
import 'package:immich_mobile/providers/search/paginated_search.provider.dart';
|
import 'package:immich_mobile/providers/search/paginated_search.provider.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_grid/multiselect_grid.dart';
|
import 'package:immich_mobile/widgets/asset_grid/multiselect_grid.dart';
|
||||||
@@ -509,7 +510,7 @@ class SearchInputPage extends HookConsumerWidget {
|
|||||||
? 'contextual_search'.tr()
|
? 'contextual_search'.tr()
|
||||||
: 'filename_search'.tr(),
|
: 'filename_search'.tr(),
|
||||||
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
hintStyle: context.textTheme.bodyLarge?.copyWith(
|
||||||
color: context.themeData.colorScheme.onSurface.withOpacity(0.75),
|
color: context.themeData.colorScheme.onSurfaceSecondary,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
enabledBorder: const UnderlineInputBorder(
|
enabledBorder: const UnderlineInputBorder(
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
const padding = 20.0;
|
const padding = 20.0;
|
||||||
final themeData = context.themeData;
|
final themeData = context.themeData;
|
||||||
|
final colorScheme = context.colorScheme;
|
||||||
final descriptionController =
|
final descriptionController =
|
||||||
useTextEditingController(text: existingLink?.description ?? "");
|
useTextEditingController(text: existingLink?.description ?? "");
|
||||||
final descriptionFocusNode = useFocusNode();
|
final descriptionFocusNode = useFocusNode();
|
||||||
@@ -58,7 +59,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
Text(
|
Text(
|
||||||
existingLink!.title,
|
existingLink!.title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: themeData.primaryColor,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -81,7 +82,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
existingLink!.description ?? "--",
|
existingLink!.description ?? "--",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: themeData.primaryColor,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
@@ -109,7 +110,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
labelText: 'shared_link_edit_description'.tr(),
|
labelText: 'shared_link_edit_description'.tr(),
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: themeData.primaryColor,
|
color: colorScheme.primary,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
@@ -135,7 +136,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
labelText: 'shared_link_edit_password'.tr(),
|
labelText: 'shared_link_edit_password'.tr(),
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: themeData.primaryColor,
|
color: colorScheme.primary,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
@@ -157,7 +158,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
onChanged: newShareLink.value.isEmpty
|
onChanged: newShareLink.value.isEmpty
|
||||||
? (value) => showMetadata.value = value
|
? (value) => showMetadata.value = value
|
||||||
: null,
|
: null,
|
||||||
activeColor: themeData.primaryColor,
|
activeColor: colorScheme.primary,
|
||||||
dense: true,
|
dense: true,
|
||||||
title: Text(
|
title: Text(
|
||||||
"shared_link_edit_show_meta",
|
"shared_link_edit_show_meta",
|
||||||
@@ -173,7 +174,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
onChanged: newShareLink.value.isEmpty
|
onChanged: newShareLink.value.isEmpty
|
||||||
? (value) => allowDownload.value = value
|
? (value) => allowDownload.value = value
|
||||||
: null,
|
: null,
|
||||||
activeColor: themeData.primaryColor,
|
activeColor: colorScheme.primary,
|
||||||
dense: true,
|
dense: true,
|
||||||
title: Text(
|
title: Text(
|
||||||
"shared_link_edit_allow_download",
|
"shared_link_edit_allow_download",
|
||||||
@@ -189,7 +190,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
onChanged: newShareLink.value.isEmpty
|
onChanged: newShareLink.value.isEmpty
|
||||||
? (value) => allowUpload.value = value
|
? (value) => allowUpload.value = value
|
||||||
: null,
|
: null,
|
||||||
activeColor: themeData.primaryColor,
|
activeColor: colorScheme.primary,
|
||||||
dense: true,
|
dense: true,
|
||||||
title: Text(
|
title: Text(
|
||||||
"shared_link_edit_allow_upload",
|
"shared_link_edit_allow_upload",
|
||||||
@@ -205,7 +206,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
onChanged: newShareLink.value.isEmpty
|
onChanged: newShareLink.value.isEmpty
|
||||||
? (value) => editExpiry.value = value
|
? (value) => editExpiry.value = value
|
||||||
: null,
|
: null,
|
||||||
activeColor: themeData.primaryColor,
|
activeColor: colorScheme.primary,
|
||||||
dense: true,
|
dense: true,
|
||||||
title: Text(
|
title: Text(
|
||||||
"shared_link_edit_change_expiry",
|
"shared_link_edit_change_expiry",
|
||||||
@@ -221,7 +222,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
"shared_link_edit_expire_after",
|
"shared_link_edit_expire_after",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: themeData.primaryColor,
|
color: colorScheme.primary,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
enableSearch: false,
|
enableSearch: false,
|
||||||
@@ -233,14 +234,6 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
expiryAfter.value = value!;
|
expiryAfter.value = value!;
|
||||||
},
|
},
|
||||||
inputDecorationTheme: themeData.inputDecorationTheme.copyWith(
|
|
||||||
disabledBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(color: Colors.grey.withOpacity(0.5)),
|
|
||||||
),
|
|
||||||
enabledBorder: const OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(color: Colors.grey),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dropdownMenuEntries: [
|
dropdownMenuEntries: [
|
||||||
DropdownMenuEntry(
|
DropdownMenuEntry(
|
||||||
value: 0,
|
value: 0,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.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/providers/album/shared_album.provider.dart';
|
import 'package:immich_mobile/providers/album/shared_album.provider.dart';
|
||||||
import 'package:immich_mobile/widgets/album/album_thumbnail_card.dart';
|
import 'package:immich_mobile/widgets/album/album_thumbnail_card.dart';
|
||||||
@@ -83,20 +84,24 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
color: context.primaryColor,
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: isOwner
|
subtitle: isOwner
|
||||||
? Text(
|
? Text(
|
||||||
'album_thumbnail_owned'.tr(),
|
'album_thumbnail_owned'.tr(),
|
||||||
style: context.textTheme.bodyMedium,
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: album.ownerName != null
|
: album.ownerName != null
|
||||||
? Text(
|
? Text(
|
||||||
'album_thumbnail_shared_by'
|
'album_thumbnail_shared_by'
|
||||||
.tr(args: [album.ownerName!]),
|
.tr(args: [album.ownerName!]),
|
||||||
style: context.textTheme.bodyMedium,
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
onTap: () => context
|
onTap: () => context
|
||||||
@@ -166,11 +171,13 @@ class SharingPage extends HookConsumerWidget {
|
|||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Card(
|
child: Card(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: Colors.grey,
|
color: context.isDarkTheme
|
||||||
width: 0.5,
|
? const Color(0xFF383838)
|
||||||
|
: Colors.black12,
|
||||||
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ Future<List<PersonResponseDto>> getAllPeople(
|
|||||||
Future<RenderList> personAssets(PersonAssetsRef ref, String personId) async {
|
Future<RenderList> personAssets(PersonAssetsRef ref, String personId) async {
|
||||||
final PersonService personService = ref.read(personServiceProvider);
|
final PersonService personService = ref.read(personServiceProvider);
|
||||||
final assets = await personService.getPersonAssets(personId);
|
final assets = await personService.getPersonAssets(personId);
|
||||||
if (assets == null) {
|
|
||||||
return RenderList.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
final settings = ref.read(appSettingsServiceProvider);
|
final settings = ref.read(appSettingsServiceProvider);
|
||||||
final groupBy =
|
final groupBy =
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ final getAllPeopleProvider =
|
|||||||
);
|
);
|
||||||
|
|
||||||
typedef GetAllPeopleRef = AutoDisposeFutureProviderRef<List<PersonResponseDto>>;
|
typedef GetAllPeopleRef = AutoDisposeFutureProviderRef<List<PersonResponseDto>>;
|
||||||
String _$personAssetsHash() => r'1d6eff5ca3aa630b58c4dad9516193b21896984d';
|
String _$personAssetsHash() => r'3dfecb67a54d07e4208bcb9581b2625acd2e1832';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:immich_mobile/entities/album.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/logger_message.entity.dart';
|
import 'package:immich_mobile/entities/logger_message.entity.dart';
|
||||||
import 'package:immich_mobile/entities/user.entity.dart';
|
import 'package:immich_mobile/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/models/albums/asset_selection_page_result.model.dart';
|
|
||||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
||||||
import 'package:immich_mobile/models/shared_link/shared_link.model.dart';
|
import 'package:immich_mobile/models/shared_link/shared_link.model.dart';
|
||||||
@@ -69,7 +68,7 @@ import 'package:photo_manager/photo_manager.dart' hide LatLng;
|
|||||||
part 'router.gr.dart';
|
part 'router.gr.dart';
|
||||||
|
|
||||||
@AutoRouterConfig(replaceInRouteName: 'Page,Route')
|
@AutoRouterConfig(replaceInRouteName: 'Page,Route')
|
||||||
class AppRouter extends _$AppRouter {
|
class AppRouter extends RootStackRouter {
|
||||||
late final AuthGuard _authGuard;
|
late final AuthGuard _authGuard;
|
||||||
late final DuplicateGuard _duplicateGuard;
|
late final DuplicateGuard _duplicateGuard;
|
||||||
late final BackupPermissionGuard _backupPermissionGuard;
|
late final BackupPermissionGuard _backupPermissionGuard;
|
||||||
|
|||||||
+363
-436
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:immich_mobile/constants/immich_colors.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
|
|
||||||
enum AppSettingsEnum<T> {
|
enum AppSettingsEnum<T> {
|
||||||
@@ -8,6 +9,21 @@ enum AppSettingsEnum<T> {
|
|||||||
"themeMode",
|
"themeMode",
|
||||||
"system",
|
"system",
|
||||||
), // "light","dark","system"
|
), // "light","dark","system"
|
||||||
|
primaryColor<String>(
|
||||||
|
StoreKey.primaryColor,
|
||||||
|
"primaryColor",
|
||||||
|
defaultColorPresetName,
|
||||||
|
),
|
||||||
|
dynamicTheme<bool>(
|
||||||
|
StoreKey.dynamicTheme,
|
||||||
|
"dynamicTheme",
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
colorfulInterface<bool>(
|
||||||
|
StoreKey.colorfulInterface,
|
||||||
|
"colorfulInterface",
|
||||||
|
true,
|
||||||
|
),
|
||||||
tilesPerRow<int>(StoreKey.tilesPerRow, "tilesPerRow", 4),
|
tilesPerRow<int>(StoreKey.tilesPerRow, "tilesPerRow", 4),
|
||||||
dynamicLayout<bool>(StoreKey.dynamicLayout, "dynamicLayout", false),
|
dynamicLayout<bool>(StoreKey.dynamicLayout, "dynamicLayout", false),
|
||||||
groupAssetsBy<int>(StoreKey.groupAssetsBy, "groupBy", 0),
|
groupAssetsBy<int>(StoreKey.groupAssetsBy, "groupBy", 0),
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ class AssetService {
|
|||||||
final dto = await _apiService.assetsApi.getAssetInfo(a.remoteId!);
|
final dto = await _apiService.assetsApi.getAssetInfo(a.remoteId!);
|
||||||
if (dto != null && dto.exifInfo != null) {
|
if (dto != null && dto.exifInfo != null) {
|
||||||
final newExif = Asset.remote(dto).exifInfo!.copyWith(id: a.id);
|
final newExif = Asset.remote(dto).exifInfo!.copyWith(id: a.id);
|
||||||
|
a.exifInfo = newExif;
|
||||||
if (newExif != a.exifInfo) {
|
if (newExif != a.exifInfo) {
|
||||||
if (a.isInDb) {
|
if (a.isInDb) {
|
||||||
_db.writeTxn(() => a.put(_db));
|
_db.writeTxn(() => a.put(_db));
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ class AssetDescriptionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getAssetDescription(Asset asset) {
|
||||||
|
final localExifId = asset.exifInfo?.id;
|
||||||
|
|
||||||
|
// Guard [remoteAssetId] and [localExifId] null
|
||||||
|
if (localExifId == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
final exifInfo = _db.exifInfos.getSync(localExifId);
|
||||||
|
|
||||||
|
return exifInfo?.description ?? "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final assetDescriptionServiceProvider = Provider(
|
final assetDescriptionServiceProvider = Provider(
|
||||||
|
|||||||
@@ -30,15 +30,41 @@ class PersonService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Asset>?> getPersonAssets(String id) async {
|
Future<List<Asset>> getPersonAssets(String id) async {
|
||||||
|
List<Asset> result = [];
|
||||||
|
var hasNext = true;
|
||||||
|
var currentPage = 1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final assets = await _apiService.peopleApi.getPersonAssets(id);
|
while (hasNext) {
|
||||||
if (assets == null) return null;
|
final response = await _apiService.searchApi.searchMetadata(
|
||||||
return await _db.assets.getAllByRemoteId(assets.map((e) => e.id));
|
MetadataSearchDto(
|
||||||
|
personIds: [id],
|
||||||
|
page: currentPage,
|
||||||
|
size: 1000,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.assets.nextPage == null) {
|
||||||
|
hasNext = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final assets = response.assets.items;
|
||||||
|
final mapAssets =
|
||||||
|
await _db.assets.getAllByRemoteId(assets.map((e) => e.id));
|
||||||
|
result.addAll(mapAssets);
|
||||||
|
|
||||||
|
currentPage++;
|
||||||
|
}
|
||||||
} catch (error, stack) {
|
} catch (error, stack) {
|
||||||
_log.severe("Error while fetching person assets", error, stack);
|
_log.severe("Error while fetching person assets", error, stack);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PersonResponseDto?> updateName(String id, String name) async {
|
Future<PersonResponseDto?> updateName(String id, String name) async {
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
import 'package:immich_mobile/constants/immich_colors.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
|
|
||||||
final immichThemeProvider = StateProvider<ThemeMode>((ref) {
|
class ImmichTheme {
|
||||||
|
ColorScheme light;
|
||||||
|
ColorScheme dark;
|
||||||
|
|
||||||
|
ImmichTheme({required this.light, required this.dark});
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmichTheme? _immichDynamicTheme;
|
||||||
|
bool get isDynamicThemeAvailable => _immichDynamicTheme != null;
|
||||||
|
|
||||||
|
final immichThemeModeProvider = StateProvider<ThemeMode>((ref) {
|
||||||
var themeMode = ref
|
var themeMode = ref
|
||||||
.watch(appSettingsServiceProvider)
|
.watch(appSettingsServiceProvider)
|
||||||
.getSetting(AppSettingsEnum.themeMode);
|
.getSetting(AppSettingsEnum.themeMode);
|
||||||
@@ -20,266 +32,272 @@ final immichThemeProvider = StateProvider<ThemeMode>((ref) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final ThemeData base = ThemeData(
|
final immichThemePresetProvider = StateProvider<ImmichColorPreset>((ref) {
|
||||||
chipTheme: const ChipThemeData(
|
var appSettingsProvider = ref.watch(appSettingsServiceProvider);
|
||||||
side: BorderSide.none,
|
var primaryColorName =
|
||||||
),
|
appSettingsProvider.getSetting(AppSettingsEnum.primaryColor);
|
||||||
sliderTheme: const SliderThemeData(
|
|
||||||
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
|
|
||||||
trackHeight: 2.0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final ThemeData immichLightTheme = ThemeData(
|
debugPrint("Current theme preset $primaryColorName");
|
||||||
useMaterial3: true,
|
|
||||||
brightness: Brightness.light,
|
|
||||||
colorScheme: ColorScheme.fromSeed(
|
|
||||||
seedColor: Colors.indigo,
|
|
||||||
),
|
|
||||||
primarySwatch: Colors.indigo,
|
|
||||||
primaryColor: Colors.indigo,
|
|
||||||
hintColor: Colors.indigo,
|
|
||||||
focusColor: Colors.indigo,
|
|
||||||
splashColor: Colors.indigo.withOpacity(0.15),
|
|
||||||
fontFamily: 'Overpass',
|
|
||||||
scaffoldBackgroundColor: immichBackgroundColor,
|
|
||||||
snackBarTheme: const SnackBarThemeData(
|
|
||||||
contentTextStyle: TextStyle(
|
|
||||||
fontFamily: 'Overpass',
|
|
||||||
color: Colors.indigo,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
),
|
|
||||||
appBarTheme: const AppBarTheme(
|
|
||||||
titleTextStyle: TextStyle(
|
|
||||||
fontFamily: 'Overpass',
|
|
||||||
color: Colors.indigo,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
backgroundColor: immichBackgroundColor,
|
|
||||||
foregroundColor: Colors.indigo,
|
|
||||||
elevation: 0,
|
|
||||||
scrolledUnderElevation: 0,
|
|
||||||
centerTitle: true,
|
|
||||||
),
|
|
||||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
|
||||||
type: BottomNavigationBarType.fixed,
|
|
||||||
backgroundColor: immichBackgroundColor,
|
|
||||||
selectedItemColor: Colors.indigo,
|
|
||||||
),
|
|
||||||
cardTheme: const CardTheme(
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
),
|
|
||||||
drawerTheme: const DrawerThemeData(
|
|
||||||
backgroundColor: immichBackgroundColor,
|
|
||||||
),
|
|
||||||
textTheme: const TextTheme(
|
|
||||||
displayLarge: TextStyle(
|
|
||||||
fontSize: 26,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.indigo,
|
|
||||||
),
|
|
||||||
displayMedium: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.black87,
|
|
||||||
),
|
|
||||||
displaySmall: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.indigo,
|
|
||||||
),
|
|
||||||
titleSmall: TextStyle(
|
|
||||||
fontSize: 16.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
titleMedium: TextStyle(
|
|
||||||
fontSize: 18.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
titleLarge: TextStyle(
|
|
||||||
fontSize: 26.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Colors.indigo,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
chipTheme: base.chipTheme,
|
|
||||||
sliderTheme: base.sliderTheme,
|
|
||||||
popupMenuTheme: const PopupMenuThemeData(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
|
||||||
),
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
indicatorColor: Colors.indigo.withOpacity(0.15),
|
|
||||||
iconTheme: WidgetStatePropertyAll(
|
|
||||||
IconThemeData(color: Colors.grey[700]),
|
|
||||||
),
|
|
||||||
backgroundColor: immichBackgroundColor,
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
labelTextStyle: WidgetStatePropertyAll(
|
|
||||||
TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey[800],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dialogTheme: const DialogTheme(
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
),
|
|
||||||
inputDecorationTheme: const InputDecorationTheme(
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: Colors.indigo,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
labelStyle: TextStyle(
|
|
||||||
color: Colors.indigo,
|
|
||||||
),
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.0,
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
textSelectionTheme: const TextSelectionThemeData(
|
|
||||||
cursorColor: Colors.indigo,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final ThemeData immichDarkTheme = ThemeData(
|
try {
|
||||||
useMaterial3: true,
|
return ImmichColorPreset.values
|
||||||
brightness: Brightness.dark,
|
.firstWhere((e) => e.name == primaryColorName);
|
||||||
primarySwatch: Colors.indigo,
|
} catch (e) {
|
||||||
primaryColor: immichDarkThemePrimaryColor,
|
debugPrint(
|
||||||
colorScheme: ColorScheme.fromSeed(
|
"Theme preset $primaryColorName not found. Applying default preset.",
|
||||||
seedColor: immichDarkThemePrimaryColor,
|
);
|
||||||
brightness: Brightness.dark,
|
appSettingsProvider.setSetting(
|
||||||
),
|
AppSettingsEnum.primaryColor,
|
||||||
scaffoldBackgroundColor: immichDarkBackgroundColor,
|
defaultColorPresetName,
|
||||||
hintColor: Colors.grey[600],
|
);
|
||||||
fontFamily: 'Overpass',
|
return defaultColorPreset;
|
||||||
snackBarTheme: SnackBarThemeData(
|
}
|
||||||
contentTextStyle: const TextStyle(
|
});
|
||||||
fontFamily: 'Overpass',
|
|
||||||
color: immichDarkThemePrimaryColor,
|
final dynamicThemeSettingProvider = StateProvider<bool>((ref) {
|
||||||
fontWeight: FontWeight.bold,
|
return ref
|
||||||
|
.watch(appSettingsServiceProvider)
|
||||||
|
.getSetting(AppSettingsEnum.dynamicTheme);
|
||||||
|
});
|
||||||
|
|
||||||
|
final colorfulInterfaceSettingProvider = StateProvider<bool>((ref) {
|
||||||
|
return ref
|
||||||
|
.watch(appSettingsServiceProvider)
|
||||||
|
.getSetting(AppSettingsEnum.colorfulInterface);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Provider for current selected theme
|
||||||
|
final immichThemeProvider = StateProvider<ImmichTheme>((ref) {
|
||||||
|
var primaryColor = ref.read(immichThemePresetProvider);
|
||||||
|
var useSystemColor = ref.watch(dynamicThemeSettingProvider);
|
||||||
|
var useColorfulInterface = ref.watch(colorfulInterfaceSettingProvider);
|
||||||
|
|
||||||
|
var currentTheme = (useSystemColor && _immichDynamicTheme != null)
|
||||||
|
? _immichDynamicTheme!
|
||||||
|
: primaryColor.getTheme();
|
||||||
|
|
||||||
|
return useColorfulInterface
|
||||||
|
? currentTheme
|
||||||
|
: _decolorizeSurfaces(theme: currentTheme);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Method to fetch dynamic system colors
|
||||||
|
Future<void> fetchSystemPalette() async {
|
||||||
|
try {
|
||||||
|
final corePalette = await DynamicColorPlugin.getCorePalette();
|
||||||
|
if (corePalette != null) {
|
||||||
|
final primaryColor = corePalette.toColorScheme().primary;
|
||||||
|
debugPrint('dynamic_color: Core palette detected.');
|
||||||
|
|
||||||
|
// Some palettes do not generate surface container colors accurately,
|
||||||
|
// so we regenerate all colors using the primary color
|
||||||
|
_immichDynamicTheme = ImmichTheme(
|
||||||
|
light: ColorScheme.fromSeed(
|
||||||
|
seedColor: primaryColor,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
),
|
||||||
|
dark: ColorScheme.fromSeed(
|
||||||
|
seedColor: primaryColor,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('dynamic_color: Failed to obtain core palette.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method replaces all surface shades in ImmichTheme to a static ones
|
||||||
|
// as we are creating the colorscheme through seedColor the default surfaces are
|
||||||
|
// tinted with primary color
|
||||||
|
ImmichTheme _decolorizeSurfaces({
|
||||||
|
required ImmichTheme theme,
|
||||||
|
}) {
|
||||||
|
return ImmichTheme(
|
||||||
|
light: theme.light.copyWith(
|
||||||
|
surface: const Color(0xFFf9f9f9),
|
||||||
|
onSurface: const Color(0xFF1b1b1b),
|
||||||
|
surfaceContainerLowest: const Color(0xFFffffff),
|
||||||
|
surfaceContainerLow: const Color(0xFFf3f3f3),
|
||||||
|
surfaceContainer: const Color(0xFFeeeeee),
|
||||||
|
surfaceContainerHigh: const Color(0xFFe8e8e8),
|
||||||
|
surfaceContainerHighest: const Color(0xFFe2e2e2),
|
||||||
|
surfaceDim: const Color(0xFFdadada),
|
||||||
|
surfaceBright: const Color(0xFFf9f9f9),
|
||||||
|
onSurfaceVariant: const Color(0xFF4c4546),
|
||||||
|
inverseSurface: const Color(0xFF303030),
|
||||||
|
onInverseSurface: const Color(0xFFf1f1f1),
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.grey[900],
|
dark: theme.dark.copyWith(
|
||||||
),
|
surface: const Color(0xFF131313),
|
||||||
textButtonTheme: TextButtonThemeData(
|
onSurface: const Color(0xFFE2E2E2),
|
||||||
style: TextButton.styleFrom(
|
surfaceContainerLowest: const Color(0xFF0E0E0E),
|
||||||
foregroundColor: immichDarkThemePrimaryColor,
|
surfaceContainerLow: const Color(0xFF1B1B1B),
|
||||||
|
surfaceContainer: const Color(0xFF1F1F1F),
|
||||||
|
surfaceContainerHigh: const Color(0xFF242424),
|
||||||
|
surfaceContainerHighest: const Color(0xFF2E2E2E),
|
||||||
|
surfaceDim: const Color(0xFF131313),
|
||||||
|
surfaceBright: const Color(0xFF353535),
|
||||||
|
onSurfaceVariant: const Color(0xFFCfC4C5),
|
||||||
|
inverseSurface: const Color(0xFFE2E2E2),
|
||||||
|
onInverseSurface: const Color(0xFF303030),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
appBarTheme: const AppBarTheme(
|
}
|
||||||
titleTextStyle: TextStyle(
|
|
||||||
fontFamily: 'Overpass',
|
ThemeData getThemeData({required ColorScheme colorScheme}) {
|
||||||
color: immichDarkThemePrimaryColor,
|
var isDark = colorScheme.brightness == Brightness.dark;
|
||||||
fontWeight: FontWeight.bold,
|
var primaryColor = colorScheme.primary;
|
||||||
fontSize: 18,
|
|
||||||
|
return ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: isDark ? Brightness.dark : Brightness.light,
|
||||||
|
colorScheme: colorScheme,
|
||||||
|
primaryColor: primaryColor,
|
||||||
|
hintColor: colorScheme.onSurfaceSecondary,
|
||||||
|
focusColor: primaryColor,
|
||||||
|
scaffoldBackgroundColor: colorScheme.surface,
|
||||||
|
splashColor: primaryColor.withOpacity(0.1),
|
||||||
|
highlightColor: primaryColor.withOpacity(0.1),
|
||||||
|
dialogBackgroundColor: colorScheme.surfaceContainer,
|
||||||
|
bottomSheetTheme: BottomSheetThemeData(
|
||||||
|
backgroundColor: colorScheme.surfaceContainer,
|
||||||
),
|
),
|
||||||
backgroundColor: Color.fromARGB(255, 32, 33, 35),
|
fontFamily: 'Overpass',
|
||||||
foregroundColor: immichDarkThemePrimaryColor,
|
snackBarTheme: SnackBarThemeData(
|
||||||
elevation: 0,
|
contentTextStyle: TextStyle(
|
||||||
scrolledUnderElevation: 0,
|
fontFamily: 'Overpass',
|
||||||
centerTitle: true,
|
color: primaryColor,
|
||||||
),
|
fontWeight: FontWeight.bold,
|
||||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
),
|
||||||
type: BottomNavigationBarType.fixed,
|
backgroundColor: colorScheme.surfaceContainerHighest,
|
||||||
backgroundColor: Color.fromARGB(255, 35, 36, 37),
|
|
||||||
selectedItemColor: immichDarkThemePrimaryColor,
|
|
||||||
),
|
|
||||||
drawerTheme: DrawerThemeData(
|
|
||||||
backgroundColor: immichDarkBackgroundColor,
|
|
||||||
scrimColor: Colors.white.withOpacity(0.1),
|
|
||||||
),
|
|
||||||
textTheme: const TextTheme(
|
|
||||||
displayLarge: TextStyle(
|
|
||||||
fontSize: 26,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Color.fromARGB(255, 255, 255, 255),
|
|
||||||
),
|
),
|
||||||
displayMedium: TextStyle(
|
appBarTheme: AppBarTheme(
|
||||||
fontSize: 14,
|
titleTextStyle: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
color: primaryColor,
|
||||||
color: Color.fromARGB(255, 255, 255, 255),
|
fontFamily: 'Overpass',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
backgroundColor:
|
||||||
|
isDark ? colorScheme.surfaceContainer : colorScheme.surface,
|
||||||
|
foregroundColor: primaryColor,
|
||||||
|
elevation: 0,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
displaySmall: TextStyle(
|
textTheme: TextTheme(
|
||||||
fontSize: 12,
|
displayLarge: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontSize: 26,
|
||||||
color: immichDarkThemePrimaryColor,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
color: isDark ? Colors.white : primaryColor,
|
||||||
titleSmall: TextStyle(
|
),
|
||||||
fontSize: 16.0,
|
displayMedium: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontSize: 14,
|
||||||
),
|
fontWeight: FontWeight.bold,
|
||||||
titleMedium: TextStyle(
|
color: isDark ? Colors.white : Colors.black87,
|
||||||
fontSize: 18.0,
|
),
|
||||||
fontWeight: FontWeight.bold,
|
displaySmall: TextStyle(
|
||||||
),
|
fontSize: 12,
|
||||||
titleLarge: TextStyle(
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 26.0,
|
color: primaryColor,
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
),
|
titleSmall: const TextStyle(
|
||||||
),
|
fontSize: 16.0,
|
||||||
cardColor: Colors.grey[900],
|
fontWeight: FontWeight.bold,
|
||||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
titleMedium: const TextStyle(
|
||||||
foregroundColor: Colors.black87,
|
fontSize: 18.0,
|
||||||
backgroundColor: immichDarkThemePrimaryColor,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
titleLarge: const TextStyle(
|
||||||
chipTheme: base.chipTheme,
|
fontSize: 26.0,
|
||||||
sliderTheme: base.sliderTheme,
|
fontWeight: FontWeight.bold,
|
||||||
popupMenuTheme: const PopupMenuThemeData(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
|
||||||
),
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
indicatorColor: immichDarkThemePrimaryColor.withOpacity(0.4),
|
|
||||||
iconTheme: WidgetStatePropertyAll(
|
|
||||||
IconThemeData(color: Colors.grey[500]),
|
|
||||||
),
|
|
||||||
backgroundColor: Colors.grey[900],
|
|
||||||
surfaceTintColor: Colors.transparent,
|
|
||||||
labelTextStyle: WidgetStatePropertyAll(
|
|
||||||
TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
dialogTheme: const DialogTheme(
|
style: ElevatedButton.styleFrom(
|
||||||
surfaceTintColor: Colors.transparent,
|
backgroundColor: primaryColor,
|
||||||
),
|
foregroundColor: isDark ? Colors.black87 : Colors.white,
|
||||||
inputDecorationTheme: const InputDecorationTheme(
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide(
|
|
||||||
color: immichDarkThemePrimaryColor,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
labelStyle: TextStyle(
|
chipTheme: const ChipThemeData(
|
||||||
color: immichDarkThemePrimaryColor,
|
side: BorderSide.none,
|
||||||
),
|
),
|
||||||
hintStyle: TextStyle(
|
sliderTheme: const SliderThemeData(
|
||||||
fontSize: 14.0,
|
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
|
||||||
fontWeight: FontWeight.normal,
|
trackHeight: 2.0,
|
||||||
),
|
),
|
||||||
),
|
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||||
textSelectionTheme: const TextSelectionThemeData(
|
type: BottomNavigationBarType.fixed,
|
||||||
cursorColor: immichDarkThemePrimaryColor,
|
),
|
||||||
),
|
popupMenuTheme: const PopupMenuThemeData(
|
||||||
);
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
|
backgroundColor:
|
||||||
|
isDark ? colorScheme.surfaceContainer : colorScheme.surface,
|
||||||
|
labelTextStyle: const WidgetStatePropertyAll(
|
||||||
|
TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||||
|
),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
textSelectionTheme: TextSelectionThemeData(
|
||||||
|
cursorColor: primaryColor,
|
||||||
|
),
|
||||||
|
dropdownMenuTheme: DropdownMenuThemeData(
|
||||||
|
menuStyle: MenuStyle(
|
||||||
|
shape: WidgetStatePropertyAll<OutlinedBorder>(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||||
|
),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
|
dynamic upgradeDto(dynamic value, String targetType) {
|
||||||
|
switch (targetType) {
|
||||||
|
case 'UserPreferencesResponseDto':
|
||||||
|
if (value is Map) {
|
||||||
|
if (value['rating'] == null) {
|
||||||
|
value['rating'] = RatingResponse().toJson();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -118,6 +118,7 @@ Future<void> handleEditDateTime(
|
|||||||
initialTZ: timeZone,
|
initialTZ: timeZone,
|
||||||
initialTZOffset: offset,
|
initialTZOffset: offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (dateTime == null) {
|
if (dateTime == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -142,10 +143,12 @@ Future<void> handleEditLocation(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final location = await showLocationPicker(
|
final location = await showLocationPicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialLatLng: initialLatLng,
|
initialLatLng: initialLatLng,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-11
@@ -1,12 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
class AlbumActionOutlinedButton extends StatelessWidget {
|
class AlbumActionFilledButton extends StatelessWidget {
|
||||||
final VoidCallback? onPressed;
|
final VoidCallback? onPressed;
|
||||||
final String labelText;
|
final String labelText;
|
||||||
final IconData iconData;
|
final IconData iconData;
|
||||||
|
|
||||||
const AlbumActionOutlinedButton({
|
const AlbumActionFilledButton({
|
||||||
super.key,
|
super.key,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
required this.labelText,
|
required this.labelText,
|
||||||
@@ -17,18 +17,13 @@ class AlbumActionOutlinedButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(right: 16.0),
|
padding: const EdgeInsets.only(right: 16.0),
|
||||||
child: OutlinedButton.icon(
|
child: FilledButton.icon(
|
||||||
style: OutlinedButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10),
|
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 16),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(25),
|
borderRadius: BorderRadius.circular(25),
|
||||||
),
|
),
|
||||||
side: BorderSide(
|
backgroundColor: context.colorScheme.surfaceContainerHigh,
|
||||||
width: 1,
|
|
||||||
color: context.isDarkTheme
|
|
||||||
? const Color.fromARGB(255, 63, 63, 63)
|
|
||||||
: const Color.fromARGB(255, 206, 206, 206),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
iconData,
|
iconData,
|
||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
import 'package:immich_mobile/entities/album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
||||||
|
|
||||||
class AlbumThumbnailCard extends StatelessWidget {
|
class AlbumThumbnailCard extends StatelessWidget {
|
||||||
@@ -23,8 +24,6 @@ class AlbumThumbnailCard extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var isDarkTheme = context.isDarkTheme;
|
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
var cardSize = constraints.maxWidth;
|
var cardSize = constraints.maxWidth;
|
||||||
@@ -34,12 +33,13 @@ class AlbumThumbnailCard extends StatelessWidget {
|
|||||||
height: cardSize,
|
height: cardSize,
|
||||||
width: cardSize,
|
width: cardSize,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isDarkTheme ? Colors.grey[800] : Colors.grey[200],
|
color: context.colorScheme.surfaceContainerHigh,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.no_photography,
|
Icons.no_photography,
|
||||||
size: cardSize * .15,
|
size: cardSize * .15,
|
||||||
|
color: context.colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -65,6 +65,9 @@ class AlbumThumbnailCard extends StatelessWidget {
|
|||||||
return RichText(
|
return RichText(
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
|
),
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: album.assetCount == 1
|
text: album.assetCount == 1
|
||||||
@@ -72,14 +75,9 @@ class AlbumThumbnailCard extends StatelessWidget {
|
|||||||
.tr(args: ['${album.assetCount}'])
|
.tr(args: ['${album.assetCount}'])
|
||||||
: 'album_thumbnail_card_items'
|
: 'album_thumbnail_card_items'
|
||||||
.tr(args: ['${album.assetCount}']),
|
.tr(args: ['${album.assetCount}']),
|
||||||
style: context.textTheme.bodyMedium,
|
|
||||||
),
|
),
|
||||||
if (owner != null) const TextSpan(text: ' · '),
|
if (owner != null) const TextSpan(text: ' · '),
|
||||||
if (owner != null)
|
if (owner != null) TextSpan(text: owner),
|
||||||
TextSpan(
|
|
||||||
text: owner,
|
|
||||||
style: context.textTheme.bodyMedium,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -112,7 +110,7 @@ class AlbumThumbnailCard extends StatelessWidget {
|
|||||||
album.name,
|
album.name,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
color: context.primaryColor,
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ class AlbumTitleTextField extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isDarkTheme = context.isDarkTheme;
|
|
||||||
|
|
||||||
return TextField(
|
return TextField(
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
if (v.isEmpty) {
|
if (v.isEmpty) {
|
||||||
@@ -35,7 +33,7 @@ class AlbumTitleTextField extends ConsumerWidget {
|
|||||||
focusNode: albumTitleTextFieldFocusNode,
|
focusNode: albumTitleTextFieldFocusNode,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
color: context.colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
controller: albumTitleController,
|
controller: albumTitleController,
|
||||||
@@ -70,15 +68,12 @@ class AlbumTitleTextField extends ConsumerWidget {
|
|||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
hintText: 'share_add_title'.tr(),
|
hintText: 'share_add_title'.tr(),
|
||||||
hintStyle: TextStyle(
|
hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
color: isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
focusColor: Colors.grey[300],
|
focusColor: Colors.grey[300],
|
||||||
fillColor: isDarkTheme
|
fillColor: context.colorScheme.surfaceContainerHigh,
|
||||||
? const Color.fromARGB(255, 32, 33, 35)
|
|
||||||
: Colors.grey[200],
|
|
||||||
filled: isAlbumTitleTextFieldFocus.value,
|
filled: isAlbumTitleTextFieldFocus.value,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class AlbumViewerAppbar extends HookConsumerWidget
|
|||||||
'action_common_confirm',
|
'action_common_confirm',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: !context.isDarkTheme ? Colors.red : Colors.red[300],
|
color: context.colorScheme.error,
|
||||||
),
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -73,24 +73,18 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
|
|||||||
splashRadius: 10,
|
splashRadius: 10,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: const OutlineInputBorder(
|
||||||
borderSide: const BorderSide(color: Colors.transparent),
|
borderSide: BorderSide(color: Colors.transparent),
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: const OutlineInputBorder(
|
||||||
borderSide: const BorderSide(color: Colors.transparent),
|
borderSide: BorderSide(color: Colors.transparent),
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
),
|
||||||
focusColor: Colors.grey[300],
|
focusColor: Colors.grey[300],
|
||||||
fillColor: context.isDarkTheme
|
fillColor: context.scaffoldBackgroundColor,
|
||||||
? const Color.fromARGB(255, 32, 33, 35)
|
|
||||||
: Colors.grey[200],
|
|
||||||
filled: titleFocusNode.hasFocus,
|
filled: titleFocusNode.hasFocus,
|
||||||
hintText: 'share_add_title'.tr(),
|
hintText: 'share_add_title'.tr(),
|
||||||
hintStyle: TextStyle(
|
hintStyle: context.themeData.inputDecorationTheme.hintStyle?.copyWith(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
color: context.isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class ControlBottomAppBar extends HookConsumerWidget {
|
|||||||
ScrollController scrollController,
|
ScrollController scrollController,
|
||||||
) {
|
) {
|
||||||
return Card(
|
return Card(
|
||||||
color: context.isDarkTheme ? Colors.grey[900] : Colors.grey[100],
|
color: context.colorScheme.surfaceContainerLow,
|
||||||
surfaceTintColor: Colors.transparent,
|
surfaceTintColor: Colors.transparent,
|
||||||
elevation: 18.0,
|
elevation: 18.0,
|
||||||
shape: const RoundedRectangleBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
|
|||||||
@@ -22,12 +22,15 @@ class DisableMultiSelectButton extends ConsumerWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
onPressed: () => onPressed(),
|
onPressed: () => onPressed(),
|
||||||
icon: const Icon(Icons.close_rounded),
|
icon: Icon(
|
||||||
|
Icons.close_rounded,
|
||||||
|
color: context.colorScheme.onPrimary,
|
||||||
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
'$selectedItemCount',
|
'$selectedItemCount',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
height: 2.5,
|
height: 2.5,
|
||||||
color: context.isDarkTheme ? Colors.black : Colors.white,
|
color: context.colorScheme.onPrimary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
@@ -74,9 +75,9 @@ class GroupDividerTitle extends HookConsumerWidget {
|
|||||||
Icons.check_circle_rounded,
|
Icons.check_circle_rounded,
|
||||||
color: context.primaryColor,
|
color: context.primaryColor,
|
||||||
)
|
)
|
||||||
: const Icon(
|
: Icon(
|
||||||
Icons.check_circle_outline_rounded,
|
Icons.check_circle_outline_rounded,
|
||||||
color: Colors.grey,
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/collection_extensions.dart';
|
import 'package:immich_mobile/extensions/collection_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
|
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_grid/asset_drag_region.dart';
|
import 'package:immich_mobile/widgets/asset_grid/asset_drag_region.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_grid/thumbnail_image.dart';
|
import 'package:immich_mobile/widgets/asset_grid/thumbnail_image.dart';
|
||||||
@@ -266,7 +267,9 @@ class ImmichAssetGridViewState extends ConsumerState<ImmichAssetGridView> {
|
|||||||
scrollStateListener: dragScrolling,
|
scrollStateListener: dragScrolling,
|
||||||
itemPositionsListener: _itemPositionsListener,
|
itemPositionsListener: _itemPositionsListener,
|
||||||
controller: _itemScrollController,
|
controller: _itemScrollController,
|
||||||
backgroundColor: context.themeData.hintColor,
|
backgroundColor: context.isDarkTheme
|
||||||
|
? context.colorScheme.primary.darken(amount: .5)
|
||||||
|
: context.colorScheme.primary,
|
||||||
labelTextBuilder: _labelBuilder,
|
labelTextBuilder: _labelBuilder,
|
||||||
padding: appBarOffset()
|
padding: appBarOffset()
|
||||||
? const EdgeInsets.only(top: 60)
|
? const EdgeInsets.only(top: 60)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
||||||
import 'package:immich_mobile/utils/storage_indicator.dart';
|
import 'package:immich_mobile/utils/storage_indicator.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
@@ -42,8 +43,8 @@ class ThumbnailImage extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final assetContainerColor = context.isDarkTheme
|
final assetContainerColor = context.isDarkTheme
|
||||||
? Colors.blueGrey
|
? context.primaryColor.darken(amount: 0.6)
|
||||||
: context.themeData.primaryColorLight;
|
: context.primaryColor.lighten(amount: 0.8);
|
||||||
// Assets from response DTOs do not have an isar id, querying which would give us the default autoIncrement id
|
// Assets from response DTOs do not have an isar id, querying which would give us the default autoIncrement id
|
||||||
final isFromDto = asset.id == Isar.autoIncrement;
|
final isFromDto = asset.id == Isar.autoIncrement;
|
||||||
|
|
||||||
@@ -192,8 +193,8 @@ class ThumbnailImage extends ConsumerWidget {
|
|||||||
bottom: 5,
|
bottom: 5,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
storageIcon(asset),
|
storageIcon(asset),
|
||||||
color: Colors.white,
|
color: Colors.white.withOpacity(.8),
|
||||||
size: 18,
|
size: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (asset.isFavorite)
|
if (asset.isFavorite)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
|
|
||||||
class ThumbnailPlaceholder extends StatelessWidget {
|
class ThumbnailPlaceholder extends StatelessWidget {
|
||||||
final EdgeInsets margin;
|
final EdgeInsets margin;
|
||||||
@@ -13,25 +14,20 @@ class ThumbnailPlaceholder extends StatelessWidget {
|
|||||||
this.height = 250,
|
this.height = 250,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const _brightColors = [
|
|
||||||
Color(0xFFF1F3F4),
|
|
||||||
Color(0xFFB4B6B8),
|
|
||||||
];
|
|
||||||
|
|
||||||
static const _darkColors = [
|
|
||||||
Color(0xFF3B3F42),
|
|
||||||
Color(0xFF2B2F32),
|
|
||||||
];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
var gradientColors = [
|
||||||
|
context.colorScheme.surfaceContainer,
|
||||||
|
context.colorScheme.surfaceContainer.darken(amount: .1),
|
||||||
|
];
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
margin: margin,
|
margin: margin,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: context.isDarkTheme ? _darkColors : _brightColors,
|
colors: gradientColors,
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -61,58 +61,6 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||||||
navStack.length > 2 &&
|
navStack.length > 2 &&
|
||||||
navStack.elementAt(navStack.length - 2).name == TrashRoute.name;
|
navStack.elementAt(navStack.length - 2).name == TrashRoute.name;
|
||||||
final isInAlbum = ref.watch(currentAlbumProvider)?.isRemote ?? false;
|
final isInAlbum = ref.watch(currentAlbumProvider)?.isRemote ?? false;
|
||||||
// !!!! itemsList and actionlist should always be in sync
|
|
||||||
final itemsList = [
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Icon(
|
|
||||||
Platform.isAndroid ? Icons.share_rounded : Icons.ios_share_rounded,
|
|
||||||
),
|
|
||||||
label: 'control_bottom_app_bar_share'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_share'.tr(),
|
|
||||||
),
|
|
||||||
if (asset.isImage)
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.tune_outlined),
|
|
||||||
label: 'control_bottom_app_bar_edit'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_edit'.tr(),
|
|
||||||
),
|
|
||||||
if (isOwner)
|
|
||||||
asset.isArchived
|
|
||||||
? BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.unarchive_rounded),
|
|
||||||
label: 'control_bottom_app_bar_unarchive'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_unarchive'.tr(),
|
|
||||||
)
|
|
||||||
: BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.archive_outlined),
|
|
||||||
label: 'control_bottom_app_bar_archive'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_archive'.tr(),
|
|
||||||
),
|
|
||||||
if (isOwner && stack.isNotEmpty)
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.burst_mode_outlined),
|
|
||||||
label: 'control_bottom_app_bar_stack'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_stack'.tr(),
|
|
||||||
),
|
|
||||||
if (isOwner && !isInAlbum)
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.delete_outline),
|
|
||||||
label: 'control_bottom_app_bar_delete'.tr(),
|
|
||||||
tooltip: 'control_bottom_app_bar_delete'.tr(),
|
|
||||||
),
|
|
||||||
if (!isOwner)
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.download_outlined),
|
|
||||||
label: 'download'.tr(),
|
|
||||||
tooltip: 'download'.tr(),
|
|
||||||
),
|
|
||||||
if (isInAlbum)
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.remove_circle_outline),
|
|
||||||
label: 'album_viewer_appbar_share_remove'.tr(),
|
|
||||||
tooltip: 'album_viewer_appbar_share_remove'.tr(),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
void removeAssetFromStack() {
|
void removeAssetFromStack() {
|
||||||
if (stackIndex > 0 && showStack) {
|
if (stackIndex > 0 && showStack) {
|
||||||
@@ -366,16 +314,71 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Function(int)> actionslist = [
|
final List<Map<BottomNavigationBarItem, Function(int)>> albumActions = [
|
||||||
(_) => shareAsset(),
|
{
|
||||||
if (asset.isImage) (_) => handleEdit(),
|
BottomNavigationBarItem(
|
||||||
if (isOwner) (_) => handleArchive(),
|
icon: Icon(
|
||||||
if (isOwner && stack.isNotEmpty) (_) => showStackActionItems(),
|
Platform.isAndroid ? Icons.share_rounded : Icons.ios_share_rounded,
|
||||||
if (isOwner) (_) => handleDelete(),
|
),
|
||||||
if (!isOwner) (_) => handleDownload(),
|
label: 'control_bottom_app_bar_share'.tr(),
|
||||||
if (isInAlbum) (_) => handleRemoveFromAlbum(),
|
tooltip: 'control_bottom_app_bar_share'.tr(),
|
||||||
|
): (_) => shareAsset(),
|
||||||
|
},
|
||||||
|
if (asset.isImage)
|
||||||
|
{
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.tune_outlined),
|
||||||
|
label: 'control_bottom_app_bar_edit'.tr(),
|
||||||
|
tooltip: 'control_bottom_app_bar_edit'.tr(),
|
||||||
|
): (_) => handleEdit(),
|
||||||
|
},
|
||||||
|
if (isOwner)
|
||||||
|
{
|
||||||
|
asset.isArchived
|
||||||
|
? BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.unarchive_rounded),
|
||||||
|
label: 'control_bottom_app_bar_unarchive'.tr(),
|
||||||
|
tooltip: 'control_bottom_app_bar_unarchive'.tr(),
|
||||||
|
)
|
||||||
|
: BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.archive_outlined),
|
||||||
|
label: 'control_bottom_app_bar_archive'.tr(),
|
||||||
|
tooltip: 'control_bottom_app_bar_archive'.tr(),
|
||||||
|
): (_) => handleArchive(),
|
||||||
|
},
|
||||||
|
if (isOwner && stack.isNotEmpty)
|
||||||
|
{
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.burst_mode_outlined),
|
||||||
|
label: 'control_bottom_app_bar_stack'.tr(),
|
||||||
|
tooltip: 'control_bottom_app_bar_stack'.tr(),
|
||||||
|
): (_) => showStackActionItems(),
|
||||||
|
},
|
||||||
|
if (isOwner && !isInAlbum)
|
||||||
|
{
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.delete_outline),
|
||||||
|
label: 'control_bottom_app_bar_delete'.tr(),
|
||||||
|
tooltip: 'control_bottom_app_bar_delete'.tr(),
|
||||||
|
): (_) => handleDelete(),
|
||||||
|
},
|
||||||
|
if (!isOwner)
|
||||||
|
{
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.download_outlined),
|
||||||
|
label: 'download'.tr(),
|
||||||
|
tooltip: 'download'.tr(),
|
||||||
|
): (_) => handleDownload(),
|
||||||
|
},
|
||||||
|
if (isInAlbum)
|
||||||
|
{
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: const Icon(Icons.remove_circle_outline),
|
||||||
|
label: 'album_viewer_appbar_share_remove'.tr(),
|
||||||
|
tooltip: 'album_viewer_appbar_share_remove'.tr(),
|
||||||
|
): (_) => handleRemoveFromAlbum(),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return IgnorePointer(
|
return IgnorePointer(
|
||||||
ignoring: !ref.watch(showControlsProvider),
|
ignoring: !ref.watch(showControlsProvider),
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
@@ -407,11 +410,10 @@ class BottomGalleryBar extends ConsumerWidget {
|
|||||||
unselectedItemColor: Colors.white,
|
unselectedItemColor: Colors.white,
|
||||||
showSelectedLabels: true,
|
showSelectedLabels: true,
|
||||||
showUnselectedLabels: true,
|
showUnselectedLabels: true,
|
||||||
items: itemsList,
|
items:
|
||||||
|
albumActions.map((e) => e.keys.first).toList(growable: false),
|
||||||
onTap: (index) {
|
onTap: (index) {
|
||||||
if (index < actionslist.length) {
|
albumActions[index].values.first.call(index);
|
||||||
actionslist[index].call(index);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/entities/exif_info.entity.dart';
|
import 'package:immich_mobile/entities/exif_info.entity.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/services/asset_description.service.dart';
|
import 'package:immich_mobile/services/asset_description.service.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
||||||
@@ -23,23 +25,21 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final textColor = context.isDarkTheme ? Colors.white : Colors.black;
|
|
||||||
final controller = useTextEditingController();
|
final controller = useTextEditingController();
|
||||||
final focusNode = useFocusNode();
|
final focusNode = useFocusNode();
|
||||||
final isFocus = useState(false);
|
final isFocus = useState(false);
|
||||||
final isTextEmpty = useState(controller.text.isEmpty);
|
final isTextEmpty = useState(controller.text.isEmpty);
|
||||||
final descriptionProvider = ref.watch(assetDescriptionServiceProvider);
|
final descriptionProvider = ref.watch(assetDescriptionServiceProvider);
|
||||||
|
|
||||||
final owner = ref.watch(currentUserProvider);
|
final owner = ref.watch(currentUserProvider);
|
||||||
final hasError = useState(false);
|
final hasError = useState(false);
|
||||||
|
final assetWithExif = ref.watch(assetDetailProvider(asset));
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
controller.text = exifInfo?.description ?? '';
|
controller.text = descriptionProvider.getAssetDescription(asset);
|
||||||
isTextEmpty.value = exifInfo?.description?.isEmpty ?? true;
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
[exifInfo?.description],
|
[assetWithExif.value],
|
||||||
);
|
);
|
||||||
|
|
||||||
submitDescription(String description) async {
|
submitDescription(String description) async {
|
||||||
@@ -49,6 +49,7 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
asset,
|
asset,
|
||||||
description,
|
description,
|
||||||
);
|
);
|
||||||
|
controller.text = description;
|
||||||
} catch (error, stack) {
|
} catch (error, stack) {
|
||||||
hasError.value = true;
|
hasError.value = true;
|
||||||
_log.severe("Error updating description", error, stack);
|
_log.severe("Error updating description", error, stack);
|
||||||
@@ -71,7 +72,7 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.cancel_rounded,
|
Icons.cancel_rounded,
|
||||||
color: Colors.grey[500],
|
color: context.colorScheme.onSurfaceSecondary,
|
||||||
),
|
),
|
||||||
splashRadius: 10,
|
splashRadius: 10,
|
||||||
);
|
);
|
||||||
@@ -100,10 +101,12 @@ class DescriptionInput extends HookConsumerWidget {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'description_input_hint_text'.tr(),
|
hintText: 'description_input_hint_text'.tr(),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
hintStyle: context.textTheme.labelLarge?.copyWith(
|
|
||||||
color: textColor.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
suffixIcon: suffixIcon,
|
suffixIcon: suffixIcon,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
errorBorder: InputBorder.none,
|
||||||
|
focusedErrorBorder: InputBorder.none,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/extensions/asset_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/extensions/duration_extensions.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
|
import 'package:immich_mobile/utils/selection_handlers.dart';
|
||||||
|
|
||||||
|
class AssetDateTime extends ConsumerWidget {
|
||||||
|
final Asset asset;
|
||||||
|
|
||||||
|
const AssetDateTime({super.key, required this.asset});
|
||||||
|
|
||||||
|
String getDateTimeString(Asset a) {
|
||||||
|
final (deltaTime, timeZone) = a.getTZAdjustedTimeAndOffset();
|
||||||
|
final date = DateFormat.yMMMEd().format(deltaTime);
|
||||||
|
final time = DateFormat.jm().format(deltaTime);
|
||||||
|
return '$date • $time GMT${timeZone.formatAsOffset()}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final watchedAsset = ref.watch(assetDetailProvider(asset));
|
||||||
|
String formattedDateTime = getDateTimeString(asset);
|
||||||
|
|
||||||
|
void editDateTime() async {
|
||||||
|
await handleEditDateTime(ref, context, [asset]);
|
||||||
|
|
||||||
|
if (watchedAsset.value != null) {
|
||||||
|
formattedDateTime = getDateTimeString(watchedAsset.value!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
formattedDateTime,
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (asset.isRemote)
|
||||||
|
IconButton(
|
||||||
|
onPressed: editDateTime,
|
||||||
|
icon: const Icon(Icons.edit_outlined),
|
||||||
|
iconSize: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
|
import 'package:immich_mobile/widgets/asset_viewer/detail_panel/file_info.dart';
|
||||||
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/entities/exif_info.entity.dart';
|
||||||
|
import 'package:immich_mobile/widgets/asset_viewer/detail_panel/camera_info.dart';
|
||||||
|
|
||||||
|
class AssetDetails extends ConsumerWidget {
|
||||||
|
final Asset asset;
|
||||||
|
final ExifInfo? exifInfo;
|
||||||
|
|
||||||
|
const AssetDetails({
|
||||||
|
super.key,
|
||||||
|
required this.asset,
|
||||||
|
this.exifInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final assetWithExif = ref.watch(assetDetailProvider(asset));
|
||||||
|
final ExifInfo? exifInfo = (assetWithExif.value ?? asset).exifInfo;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 24.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"exif_bottom_sheet_details",
|
||||||
|
style: context.textTheme.labelMedium?.copyWith(
|
||||||
|
color: context.textTheme.labelMedium?.color?.withAlpha(200),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
FileInfo(asset: asset),
|
||||||
|
if (exifInfo?.make != null) CameraInfo(exifInfo: exifInfo!),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
import 'package:immich_mobile/providers/asset.provider.dart';
|
||||||
|
import 'package:immich_mobile/utils/selection_handlers.dart';
|
||||||
|
import 'package:immich_mobile/widgets/asset_viewer/detail_panel/exif_map.dart';
|
||||||
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/entities/exif_info.entity.dart';
|
||||||
|
|
||||||
|
class AssetLocation extends HookConsumerWidget {
|
||||||
|
final Asset asset;
|
||||||
|
|
||||||
|
const AssetLocation({
|
||||||
|
super.key,
|
||||||
|
required this.asset,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final assetWithExif = ref.watch(assetDetailProvider(asset));
|
||||||
|
final ExifInfo? exifInfo = (assetWithExif.value ?? asset).exifInfo;
|
||||||
|
final hasCoordinates = exifInfo?.hasCoordinates ?? false;
|
||||||
|
|
||||||
|
void editLocation() {
|
||||||
|
handleEditLocation(ref, context, [assetWithExif.value ?? asset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guard no lat/lng
|
||||||
|
if (!hasCoordinates) {
|
||||||
|
return asset.isRemote
|
||||||
|
? ListTile(
|
||||||
|
minLeadingWidth: 0,
|
||||||
|
contentPadding: const EdgeInsets.all(0),
|
||||||
|
leading: const Icon(Icons.location_on),
|
||||||
|
title: Text(
|
||||||
|
"exif_bottom_sheet_location_add",
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: context.primaryColor,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
onTap: editLocation,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getLocationName() {
|
||||||
|
if (exifInfo == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
final cityName = exifInfo.city;
|
||||||
|
final stateName = exifInfo.state;
|
||||||
|
|
||||||
|
bool hasLocationName = (cityName != null && stateName != null);
|
||||||
|
|
||||||
|
return hasLocationName
|
||||||
|
? Text(
|
||||||
|
"$cityName, $stateName",
|
||||||
|
style: context.textTheme.labelLarge,
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(top: asset.isRemote ? 0 : 16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"exif_bottom_sheet_location",
|
||||||
|
style: context.textTheme.labelMedium?.copyWith(
|
||||||
|
color: context.textTheme.labelMedium?.color?.withAlpha(200),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
).tr(),
|
||||||
|
if (asset.isRemote)
|
||||||
|
IconButton(
|
||||||
|
onPressed: editLocation,
|
||||||
|
icon: const Icon(Icons.edit_outlined),
|
||||||
|
iconSize: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
asset.isRemote ? const SizedBox.shrink() : const SizedBox(height: 16),
|
||||||
|
ExifMap(
|
||||||
|
exifInfo: exifInfo!,
|
||||||
|
markerId: asset.remoteId,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
getLocationName(),
|
||||||
|
Text(
|
||||||
|
"${exifInfo.latitude!.toStringAsFixed(4)}, ${exifInfo.longitude!.toStringAsFixed(4)}",
|
||||||
|
style: context.textTheme.labelMedium?.copyWith(
|
||||||
|
color: context.textTheme.labelMedium?.color?.withAlpha(150),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user