refactor!: remove asset faces from AssetResponseDto (#27779)

* refactor!: remove faces from `people` in AssetResposnseDto

* chore: tests

* chore: e2e generator

* chore: code review readonly

* chore: code review changes

* chore: cleanup

* fix: openapi

* chore: format

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
Brandon Wees
2026-05-11 16:05:40 -05:00
committed by GitHub
parent a278c10c75
commit 38438c8d9a
21 changed files with 134 additions and 942 deletions
+74
View File
@@ -0,0 +1,74 @@
import type { AssetFaceResponseDto, PersonResponseDto } from '@immich/sdk';
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
import { assetCacheManager } from '$lib/managers/AssetCacheManager.svelte';
import type { Faces } from '$lib/managers/asset-viewer-manager.svelte';
import { CancellableTask } from '$lib/utils/cancellable-task';
class FaceManager {
#data = $state<AssetFaceResponseDto[]>([]);
#faceLoader = new CancellableTask();
#cleared = false;
readonly faceNames = $derived.by(() => {
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const map = new Map<Faces, string>();
for (const face of this.data) {
if (!face.person) {
continue;
}
map.set(face, face.person.name);
}
return map;
});
readonly people = $derived.by(() => {
const people = new SvelteSet<PersonResponseDto>();
for (const face of this.data) {
if (face.person) {
people.add(face.person);
}
}
return people;
});
readonly facesByPersonId = $derived.by(() => {
const map = new SvelteMap<string, AssetFaceResponseDto[]>();
for (const face of faceManager.data) {
if (!face.person) {
continue;
}
const existing = map.get(face.person.id);
if (existing) {
existing.push(face);
} else {
map.set(face.person.id, [face]);
}
}
return map;
});
get data() {
return this.#data;
}
async getAssetFaces(id: string) {
if (this.#cleared) {
await this.#faceLoader.reset();
this.#cleared = false;
}
await this.#faceLoader.execute(async () => {
this.#data = await assetCacheManager.getAssetFaces(id);
}, false);
}
clear() {
this.#cleared = true;
this.#data = [];
}
}
export const faceManager = new FaceManager();
+1
View File
@@ -7,6 +7,7 @@ import { ocrManager, type OcrBoundingBox } from '$lib/stores/ocr.svelte';
vi.mock('@immich/sdk', () => ({
getAssetInfo: vi.fn(),
getAssetOcr: vi.fn(),
getFaces: vi.fn(),
}));
const createMockOcrData = (overrides?: Partial<OcrBoundingBox>): OcrBoundingBox[] => [