improve: Immich cloud filter and optimize

This commit is contained in:
2026-10-11 20:18:04 +07:00
parent 87c68ea7bb
commit 6039f2aa4e
16 changed files with 4699 additions and 87 deletions
+34 -7
View File
@@ -428,6 +428,26 @@ export function immichRoutes(
});
}
if (album) {
// First try GET /albums/:id (supported across many Immich versions)
const albRes = await call(server, { path: `/albums/${album}` });
if (albRes.ok) {
const albData = await jsonOf<{ assets?: RawAsset[] }>(albRes);
if (Array.isArray(albData?.assets) && albData.assets.length > 0) {
const allAssets = albData.assets.filter((a) => a.type === 'IMAGE' || a.type === undefined);
const start = (page - 1) * size;
return reply.send({
ok: true,
page,
size,
total: allAssets.length,
hasMore: start + size < allAssets.length,
items: allAssets.slice(start, start + size).map(assetRow),
});
}
}
}
// One query, one answer. Immich reads every field it is handed as one more
// thing an asset must be — `originalFileName` with `tagIds` is a file called
// this *and* tagged that — so the box is read as a tag when it names one, and
@@ -448,17 +468,24 @@ export function immichRoutes(
},
});
if (!res.ok) return reply.status(502).send(refusal(res));
const found = await jsonOf<{ assets?: { items?: RawAsset[]; total?: number } }>(res);
const items = found?.assets?.items ?? [];
const found = await jsonOf<any>(res);
// Robust parsing across all Immich versions:
// Immich v1: found.assets.items
// Immich v2+: found.items
// Raw array: Array.isArray(found)
const rawItems: RawAsset[] = found?.assets?.items ?? found?.items ?? (Array.isArray(found) ? found : []);
const total: number | null = found?.assets?.total ?? found?.total ?? found?.count ?? null;
const hasMore: boolean =
rawItems.length === size ||
(typeof found?.nextCursor === 'string' && !!found.nextCursor) ||
(total !== null && page * size < total);
return reply.send({
ok: true,
page,
size,
total: found?.assets?.total ?? null,
// The next page is only asked for while a full one came back: that is the
// one shape every Immich version agrees on (no `nextPage`, no `nextCursor`).
hasMore: items.length === size,
items: items.map(assetRow),
total,
hasMore,
items: rawItems.map(assetRow),
});
});