feat(wallpapers): add Immich integration with caching and rotation

This patch adds Immich integration for remote images with local
caching and pruning.
It adds image rotation to the crop flow and stores rotation
with the crop state.
It adds progress tracking and size checks during image
download to avoid oversized assets.

- Add Immich caching with size limits and automatic pruning
- Extend crop handling to support rotation and persist it
- Improve download progress and error messaging
This commit is contained in:
2026-08-21 22:01:42 +02:00
parent 789b58398a
commit e494b17117
11 changed files with 343 additions and 137 deletions
+5 -2
View File
@@ -18,6 +18,7 @@ export type GalleryImage = {
cropZoom: number;
cropPositionX: number;
cropPositionY: number;
cropRotation: number;
};
export type GalleryPage = {
@@ -70,8 +71,8 @@ const demoState: WallpaperState = {
};
const inTauri = () => "__TAURI_INTERNALS__" in window;
const demoCrops = new Map<string, Pick<GalleryImage, "cropMode" | "cropZoom" | "cropPositionX" | "cropPositionY">>();
const defaultCrop = { cropMode: "cover" as const, cropZoom: 1, cropPositionX: 0.5, cropPositionY: 0.5 };
const demoCrops = new Map<string, Pick<GalleryImage, "cropMode" | "cropZoom" | "cropPositionX" | "cropPositionY" | "cropRotation">>();
const defaultCrop = { cropMode: "cover" as const, cropZoom: 1, cropPositionX: 0.5, cropPositionY: 0.5, cropRotation: 0 };
let demoImmichConnection: ImmichConnection = { configured: false, serverUrl: "", userName: "" };
export async function getState(): Promise<WallpaperState> {
@@ -126,6 +127,7 @@ export async function setImageCrop(image: GalleryImage): Promise<GalleryImage> {
zoom: image.cropZoom,
positionX: image.cropPositionX,
positionY: image.cropPositionY,
rotation: image.cropRotation,
};
if (inTauri()) return invoke<GalleryImage>("plugin:wallpaper|set_image_crop", payload);
demoCrops.set(image.id, {
@@ -133,6 +135,7 @@ export async function setImageCrop(image: GalleryImage): Promise<GalleryImage> {
cropZoom: image.cropZoom,
cropPositionX: image.cropPositionX,
cropPositionY: image.cropPositionY,
cropRotation: image.cropRotation,
});
return { ...image };
}