Compare commits

...

5 Commits

Author SHA1 Message Date
Mees Frensel 87daf9dda5 fix(web): language selector 2026-06-13 21:47:18 +02:00
Alex f1da9d2429 chore: update perm for build mobile in release gha (#29027) 2026-06-12 14:34:11 +00:00
Mees Frensel 232ca3cf3f chore(web): clarify workflow triggers (#29026) 2026-06-12 19:43:57 +05:30
Matthew Momjian 50f1121459 fix(docs): v3 bumps (#29007)
* v3 bumps

* format
2026-06-12 09:34:35 -04:00
Mees Frensel 892397807c chore(web): add switch case exhaustiveness lint (#29015) 2026-06-12 09:30:19 -04:00
16 changed files with 37 additions and 11 deletions
+1
View File
@@ -97,6 +97,7 @@ jobs:
needs: bump_version
permissions:
contents: read
pull-requests: write
secrets:
KEY_JKS: ${{ secrets.KEY_JKS }}
ALIAS: ${{ secrets.ALIAS }}
@@ -17,7 +17,7 @@ running `apt install postgresql-NN-pgvector`, where `NN` is your Postgres versio
You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
:::note Supported versions
Immich is known to work with Postgres versions `>= 14, < 19`.
Immich is known to work with Postgres versions `>= 14, < 20`.
VectorChord is known to work with pgvector versions `>= 0.7, < 0.9`.
@@ -144,7 +144,7 @@ ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE vector(512);
<details>
<summary>Migration steps</summary>
1. Ensure you have at least 0.7.0 of pgvector installed. If it is below that, please upgrade it and run the SQL command `ALTER EXTENSION vector UPDATE;` using psql or your choice of database client
1. Ensure you have at least `0.7.0` of pgvector installed. If it is below that, please upgrade it and run the SQL command `ALTER EXTENSION vector UPDATE;` using psql or your choice of database client
2. Follow the Prerequisites to install VectorChord
3. If Immich does not have superuser permissions, run the SQL command `CREATE EXTENSION vchord CASCADE;`
4. Remove the `DB_VECTOR_EXTENSION=pgvector` environmental variable as it will make Immich still use pgvector if set
+3 -1
View File
@@ -20,9 +20,11 @@ Hardware and software requirements for Immich:
- **RAM**: Minimum 6GB, recommended 8GB.
- **CPU**: Minimum 2 cores, recommended 4 cores.
- Immich runs on the `amd64` and `arm64` platforms.
Since `v2.6`, the machine learning container on `amd64` requires the `>= x86-64-v2` [microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels).
Since `v3`, the machine learning container on `amd64` requires the `>= x86-64-v2` [microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels).
Most CPUs released since ~2012 support this microarchitecture.
If you are using a virtual machine, ensure you have selected a [supported microarchitecture](https://pve.proxmox.com/pve-docs/chapter-qm.html#_qemu_cpu_types).
If you are unable to support this instruction set, the last version to support `x86-64-v1` is `v2.7.5`.
Note that this release is no longer supported, and you must run a matching `immich-server` version.
- **Storage**: Recommended Unix-compatible filesystem (EXT4, ZFS, APFS, etc.) with support for user/group ownership and permissions.
- The generation of thumbnails and transcoded video can increase the size of the photo library by 10-20% on average.
+2 -2
View File
@@ -2390,12 +2390,12 @@
"trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.",
"trigger": "Trigger",
"trigger_asset_metadata_extraction": "Asset Metadata Extraction",
"trigger_asset_metadata_extraction_description": "Triggered when the EXIF of an asset is extracted",
"trigger_asset_metadata_extraction_description": "Triggered when the EXIF metadata of an asset is extracted",
"trigger_asset_uploaded": "Asset Upload",
"trigger_asset_uploaded_description": "Triggered when a new asset is uploaded",
"trigger_description": "An event that kicks off the workflow",
"trigger_person_recognized": "Person Recognized",
"trigger_person_recognized_description": "Triggered when a person is detected",
"trigger_person_recognized_description": "Triggered when a person is recognized",
"trigger_type": "Trigger type",
"troubleshoot": "Troubleshoot",
"type": "Type",
+1
View File
@@ -129,6 +129,7 @@ export default typescriptEslint.config(
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/switch-exhaustiveness-check': ['error', { considerDefaultExhaustiveForUnions: true }],
'object-shorthand': ['error', 'always'],
'svelte/no-navigation-without-resolve': 'off',
},
@@ -351,6 +351,7 @@
closeViewer();
break;
}
// no default
}
onAction?.(action);
@@ -69,6 +69,7 @@
await goto(Route.photos());
break;
}
// no default
}
};
</script>
@@ -316,6 +316,7 @@
}
break;
}
// no default
}
};
@@ -140,6 +140,7 @@
break;
}
// no default
}
};
const handleAction = (action: Action) => {
@@ -195,6 +196,7 @@
});
break;
}
// no default
}
};
const handleUndoDelete = async (assets: TimelineAsset[]) => {
@@ -667,6 +667,7 @@ class TransformManager implements EditToolManager {
desiredWidth = Math.max(minSize, Math.max(mouseX, 0) - x);
break;
}
// no default
}
// Height
@@ -683,10 +684,14 @@ class TransformManager implements EditToolManager {
desiredHeight = Math.max(minSize, Math.max(mouseY, 0) - y);
break;
}
// no default
}
// Old
switch (this.resizeSide) {
case ResizeBoundary.None: {
break;
}
case ResizeBoundary.Left: {
const { newWidth: w, newHeight: h } = this.keepAspectRatio(desiredWidth, height);
const finalWidth = clamp(w, minSize, canvas.clientWidth);
@@ -72,12 +72,7 @@ export interface TrashAssets {
values: string[];
}
export interface UpdateStackAssets {
type: 'update_stack_assets';
values: string[];
}
export type PendingChange = AddAsset | UpdateAsset | DeleteAsset | TrashAssets | UpdateStackAssets;
export type PendingChange = AddAsset | UpdateAsset | DeleteAsset | TrashAssets;
export type ScrubberMonth = {
height: number;
@@ -105,6 +105,7 @@
}
break;
}
// no default
}
selectedRowIndex = -1;
+7
View File
@@ -98,6 +98,13 @@ function createUploadStore() {
case UploadState.DONE: {
break;
}
case UploadState.PENDING:
case UploadState.STARTED:
case undefined: {
console.error('Cannot remove uploads in progress');
break;
}
}
return stats;
@@ -171,6 +171,7 @@ export class GCastDestination implements ICastDestination {
///
private onSessionStateChanged(event: cast.framework.SessionStateEventData) {
switch (event.sessionState) {
case cast.framework.SessionState.NO_SESSION:
case cast.framework.SessionState.SESSION_ENDED: {
this.session = null;
break;
@@ -180,6 +181,11 @@ export class GCastDestination implements ICastDestination {
this.session = event.session.getSessionObj();
break;
}
case cast.framework.SessionState.SESSION_START_FAILED: {
console.error('Google Cast failed to start session:', event.errorCode);
break;
}
// no default
}
}
+1
View File
@@ -116,6 +116,7 @@ const nonIntlNames: Record<string, string> = {
kxm: 'Khmer Surin',
mfa: 'Malay (Pattani)',
swg: 'Schwäbisch',
tl: 'Tagalog',
};
const getLanguageName = (code: string) =>
@@ -104,6 +104,7 @@
break;
}
}
// no default
}
try {
@@ -115,6 +116,7 @@
toastManager.primary($t('admin.cleared_jobs', { values: { job: item.title } }));
break;
}
// no default
}
} catch (error) {
handleError(error, $t('admin.failed_job_command', { values: { command: dto.command, job: item.title } }));