From 4da3d68a67576cb64bc93a592c420f18c4594590 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Mon, 2 Mar 2026 23:16:13 -0500 Subject: [PATCH] refactor: use keyed each for face bounding boxes (#26648) --- web/src/lib/components/asset-viewer/photo-viewer.svelte | 3 +-- web/src/lib/stores/people.store.ts | 1 + web/src/lib/utils/people-utils.spec.ts | 8 ++++++-- web/src/lib/utils/people-utils.ts | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/web/src/lib/components/asset-viewer/photo-viewer.svelte b/web/src/lib/components/asset-viewer/photo-viewer.svelte index 70b5e77d49..69a6f0f103 100644 --- a/web/src/lib/components/asset-viewer/photo-viewer.svelte +++ b/web/src/lib/components/asset-viewer/photo-viewer.svelte @@ -248,8 +248,7 @@ : slideshowLookCssMapping[$slideshowLook]}" draggable="false" /> - - {#each getBoundingBox($boundingBoxesArray, overlayMetrics) as boundingbox} + {#each getBoundingBox($boundingBoxesArray, overlayMetrics) as boundingbox (boundingbox.id)}
= {}): Faces => ({ + id: 'face-1', imageWidth: 4000, imageHeight: 3000, boundingBoxX1: 1000, @@ -21,6 +22,7 @@ describe('getBoundingBox', () => { expect(boxes).toHaveLength(1); expect(boxes[0]).toEqual({ + id: 'face-1', top: Math.round(600 * (750 / 3000)), left: Math.round(800 * (1000 / 4000)), width: Math.round(800 * (2000 / 4000) - 800 * (1000 / 4000)), @@ -42,6 +44,7 @@ describe('getBoundingBox', () => { const boxes = getBoundingBox([face], metrics); expect(boxes[0]).toEqual({ + id: 'face-1', top: 0, left: 100, width: 600, @@ -68,6 +71,7 @@ describe('getBoundingBox', () => { const boxes = getBoundingBox([face], metrics); expect(boxes[0]).toEqual({ + id: 'face-1', top: -100, left: -200, width: 800, @@ -82,8 +86,8 @@ describe('getBoundingBox', () => { it('should handle multiple faces', () => { const faces = [ - makeFace({ boundingBoxX1: 0, boundingBoxY1: 0, boundingBoxX2: 1000, boundingBoxY2: 1000 }), - makeFace({ boundingBoxX1: 2000, boundingBoxY1: 1500, boundingBoxX2: 3000, boundingBoxY2: 2500 }), + makeFace({ id: 'face-1', boundingBoxX1: 0, boundingBoxY1: 0, boundingBoxX2: 1000, boundingBoxY2: 1000 }), + makeFace({ id: 'face-2', boundingBoxX1: 2000, boundingBoxY1: 1500, boundingBoxX2: 3000, boundingBoxY2: 2500 }), ]; const metrics: ContentMetrics = { contentWidth: 800, contentHeight: 600, offsetX: 0, offsetY: 0 }; diff --git a/web/src/lib/utils/people-utils.ts b/web/src/lib/utils/people-utils.ts index 4f5b96c6f1..b8fb8973e6 100644 --- a/web/src/lib/utils/people-utils.ts +++ b/web/src/lib/utils/people-utils.ts @@ -4,6 +4,7 @@ import type { ContentMetrics } from '$lib/utils/container-utils'; import { AssetTypeEnum, type AssetFaceResponseDto } from '@immich/sdk'; export interface BoundingBox { + id: string; top: number; left: number; width: number; @@ -25,6 +26,7 @@ export const getBoundingBox = (faces: Faces[], metrics: ContentMetrics): Boundin }; boxes.push({ + id: face.id, top: Math.round(coordinates.y1), left: Math.round(coordinates.x1), width: Math.round(coordinates.x2 - coordinates.x1),