From 18e0e91bbd6a8a236da671eec91d86eb1a7afa50 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 18 Oct 2024 12:56:39 +0530 Subject: [PATCH] Recon checkpoint --- web/apps/photos/src/pages/gallery.tsx | 26 ++++++------ web/packages/new/photos/services/ml/index.ts | 33 ++++++--------- web/packages/new/photos/services/ml/people.ts | 42 ++++++++++++------- 3 files changed, 51 insertions(+), 50 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 2d663f8d81..4ce9eff380 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -576,19 +576,19 @@ export default function Gallery() { // Prune the in-memory temp updates from the actual state to // obtain the UI state. Kept inside an preflight check to so // that the common path remains fast. - filteredPeople = filteredPeople - .map((p) => ({ - ...p, - fileIDs: p.fileIDs.filter( - (id) => - !tempDeletedFileIds?.has(id) && - !tempHiddenFileIds?.has(id), - ), - })) - .filter((p) => p.fileIDs.length > 0); - filteredVisiblePeople = filteredPeople.filter( - (p) => p.isVisible, - ); + const filterTemp = (ps: Person[]) => + ps + .map((p) => ({ + ...p, + fileIDs: p.fileIDs.filter( + (id) => + !tempDeletedFileIds?.has(id) && + !tempHiddenFileIds?.has(id), + ), + })) + .filter((p) => p.fileIDs.length > 0); + filteredPeople = filterTemp(filteredPeople); + filteredVisiblePeople = filterTemp(filteredVisiblePeople); } const findByID = (ps: Person[]) => ps.find((p) => p.id == activePersonID); diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index fdfecb5109..8dd21626a8 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -620,8 +620,7 @@ export const clipMatches = ( */ export interface AnnotatedFaceID { faceID: string; - personID: string | undefined; - clusterID: string | undefined; + personID: string; } /** @@ -633,29 +632,21 @@ export const getAnnotatedFacesForFile = async ( const index = await savedFaceIndex(file.id); if (!index) return []; - const faceIDToPersonID = new Map(); - const people = _state.peopleSnapshot ?? []; - for (const person of people) { - const faceIDs = - person.type == "cgroup" - ? person.cgroup.data.assigned.map((c) => c.faces).flat() - : person.cluster.faces; - for (const faceID of faceIDs) { - faceIDToPersonID.set(faceID, person.id); - } - } + const personByFaceID = _state.peopleSnapshot?.personByFaceID; + if (!personByFaceID) return []; - const sortableFaces: { face: AnnotatedFaceID; clusterSize: number }[] = []; + const sortableFaces: [AnnotatedFaceID, number][] = []; for (const { faceID } of index.faces) { - const personID = faceIDToPersonID.get(faceID); - if (personID) { - annotatedFaceIDs.push({ faceID, personID }); - } else { - otherFaceIDs.push(faceID); - } + const person = personByFaceID.get(faceID); + if (!person) continue; + sortableFaces.push([ + { faceID, personID: person.id }, + person.fileIDs.length, + ]); } - return { annotatedFaceIDs, otherFaceIDs }; + sortableFaces.sort(([, a], [, b]) => b - a); + return sortableFaces.map(([f]) => f); }; /** diff --git a/web/packages/new/photos/services/ml/people.ts b/web/packages/new/photos/services/ml/people.ts index 253cf38d1a..dc739dba06 100644 --- a/web/packages/new/photos/services/ml/people.ts +++ b/web/packages/new/photos/services/ml/people.ts @@ -136,15 +136,6 @@ export type Person = ( * The {@link EnteFile} which contains the display face. */ displayFaceFile: EnteFile; - /** - * `true` if this person should be normally shown in the UI. - * - * By default, people derived from small, local-only clusters are not - * surfaced in the UI (For such people, this flag will be set to false). The - * user can still see these people by clicking on one of the faces they - * contain from a photo's info view. - */ - isVisible: boolean; }; /** @@ -189,9 +180,11 @@ export interface PeopleSnapshot { /** * List of all people who should be normally shown in the UI. * - * These are just people whose {@link isVisible} property is true. This list - * is easily derivable from {@link people}, it is only maintained as a - * separate list for convenience. + * By default, people derived from small, local-only clusters are not + * surfaced in the UI. Such people will be present in the {@link people} + * list, but not in the {@link visiblePeople} list. The user can still see + * these people by clicking on one of the faces they contain from a photo's + * info view. */ visiblePeople: Person[]; /** @@ -317,9 +310,6 @@ export const reconstructPeopleSnapshot = async (): Promise => { const mostRecentFace = faces[0]; if (!mostRecentFace) return undefined; - // Ignore clusters with too few visible faces. - if (faces.length < 10) return undefined; - return { type: "cluster", cluster, @@ -336,7 +326,27 @@ export const reconstructPeopleSnapshot = async (): Promise => { .filter((c) => !!c) .sort((a, b) => b.fileIDs.length - a.fileIDs.length); - return sorted(cgroupPeople).concat(sorted(clusterPeople)); + const people = sorted(cgroupPeople).concat(sorted(clusterPeople)); + + const visiblePeople = people.filter((p) => { + // Ignore local only clusters with too few visible faces. + if (p.type == "cluster" && p.cluster.faces.length < 10) return false; + return true; + }); + + // Reverse map for easy lookup. + const personByFaceID = new Map(); + for (const person of people) { + const faceIDs = + person.type == "cgroup" + ? person.cgroup.data.assigned.map((c) => c.faces).flat() + : person.cluster.faces; + for (const faceID of faceIDs) { + personByFaceID.set(faceID, person); + } + } + + return { people, visiblePeople, personByFaceID }; }; /**