diff --git a/web/packages/new/photos/components/Gallery/index.tsx b/web/packages/new/photos/components/Gallery/index.tsx index ecc648840d..53584d7bee 100644 --- a/web/packages/new/photos/components/Gallery/index.tsx +++ b/web/packages/new/photos/components/Gallery/index.tsx @@ -19,7 +19,7 @@ import { IconButton, Stack, Tooltip, Typography } from "@mui/material"; import { t } from "i18next"; import React, { useState } from "react"; import type { FaceCluster } from "../../services/ml/cluster"; -import type { CGroupUserEntity } from "../../services/user-entity"; +import type { CGroup } from "../../services/user-entity"; import type { NewAppContextPhotos } from "../../types/context"; import { SpaceBetweenFlex } from "../mui-custom"; import { NameInputDialog } from "../NameInputDialog"; @@ -75,7 +75,7 @@ export const PeopleHeader: React.FC = ({ {person.type == "cgroup" ? ( ) : ( @@ -91,7 +91,7 @@ export const PeopleHeader: React.FC = ({ interface CGroupPersonOptionsProps { person: Person; - cgroup: CGroupUserEntity; + cgroup: CGroup; appContext: NewAppContextPhotos; } diff --git a/web/packages/new/photos/services/ml/cluster.ts b/web/packages/new/photos/services/ml/cluster.ts index b0c489bf57..4cd7e6850f 100644 --- a/web/packages/new/photos/services/ml/cluster.ts +++ b/web/packages/new/photos/services/ml/cluster.ts @@ -3,10 +3,7 @@ import log from "@/base/log"; import { ensure } from "@/utils/ensure"; import { wait } from "@/utils/promise"; import type { EnteFile } from "../../types/file"; -import { - savedCGroupUserEntities, - updateOrCreateUserEntities, -} from "../user-entity"; +import { savedCGroups, updateOrCreateUserEntities } from "../user-entity"; import { savedFaceClusters, saveFaceClusters } from "./db"; import { faceDirection, @@ -94,7 +91,7 @@ export const clusterFaces = async ( let clusters: FaceCluster[] = []; // Get the locally available remote cluster groups. - const cgroupUserEntities = await savedCGroupUserEntities(); + const cgroups = await savedCGroups(); // Sort them so that the latest ones are first. // @@ -108,9 +105,7 @@ export const clusterFaces = async ( // slack in how they implement the sync without needing to make an blocking // API request for every user interaction. - const sortedCGroupUserEntities = cgroupUserEntities.sort( - (a, b) => b.updatedAt - a.updatedAt, - ); + const sortedCGroups = cgroups.sort((a, b) => b.updatedAt - a.updatedAt); // Extract the remote clusters. clusters = clusters.concat( @@ -118,7 +113,7 @@ export const clusterFaces = async ( // // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - sortedCGroupUserEntities.map((cg) => cg.data.assigned).flat(), + sortedCGroups.map((cg) => cg.data.assigned).flat(), ); // Add on the clusters we have available locally. @@ -345,7 +340,7 @@ export const reconcileClusters = async ( const clusterByID = new Map(clusters.map((c) => [c.id, c])); // Get the existing remote cluster groups. - const cgroupEntities = await savedCGroupUserEntities(); + const cgroupEntities = await savedCGroups(); // Find the cgroups that have changed since we started. const changedCGroupEntities = cgroupEntities diff --git a/web/packages/new/photos/services/ml/people.ts b/web/packages/new/photos/services/ml/people.ts index b4b6cb18d0..cfa34d1c53 100644 --- a/web/packages/new/photos/services/ml/people.ts +++ b/web/packages/new/photos/services/ml/people.ts @@ -2,11 +2,7 @@ import { masterKeyFromSession } from "@/base/session-store"; import { wipClusterEnable } from "."; import type { EnteFile } from "../../types/file"; import { getLocalFiles } from "../files"; -import { - addUserEntity, - savedCGroupUserEntities, - type CGroupUserEntity, -} from "../user-entity"; +import { addUserEntity, savedCGroups, type CGroup } from "../user-entity"; import type { FaceCluster } from "./cluster"; import { getFaceIndexes, savedFaceClusters } from "./db"; import { fileIDFromFaceID } from "./face"; @@ -18,7 +14,7 @@ import { fileIDFromFaceID } from "./face"; * Interactions include hiding, merging and giving a name and/or a cover photo. * * The most frequent interaction is naming a {@link FaceCluster}, which promotes - * it to a become a {@link CGroupUserEntity}. The promotion comes with the + * it to a become a {@link CGroup}. The promotion comes with the * ability to be synced with remote (as a "cgroup" user entity). * * There after, the user may attach more clusters to the same cgroup. @@ -84,8 +80,8 @@ export interface CGroupUserEntityData { } /** - * A massaged version of {@link CGroupUserEntityData} or a {@link FaceCluster} - * suitable for being shown in the UI. + * A massaged version of {@link CGroup} or a {@link FaceCluster} suitable for + * being shown in the UI. * * We transform both both remote cluster groups and local-only face clusters * into the same "person" object that can be shown in the UI. @@ -99,11 +95,11 @@ export interface CGroupUserEntityData { * * Beyond this semantic difference, there is also data massaging: a * {@link Person} has data converted into a format that the UI can directly and - * efficiently use, as compared to a {@link CGroupUserEntityData}, which is - * tailored for transmission and storage. + * efficiently use, as compared to a {@link CGroup}, which is tailored for + * transmission and storage. */ export type Person = ( - | { type: "cgroup"; cgroupUserEntity: CGroupUserEntity } + | { type: "cgroup"; cgroup: CGroup } | { type: "cluster"; cluster: FaceCluster } ) & { /** @@ -173,17 +169,18 @@ export const reconstructPeople = async (): Promise => { type Interim = (Person | undefined)[]; // Convert cgroups to people. - const cgroups = await savedCGroupUserEntities(); - const cgroupPeople: Interim = cgroups.map((cgroupUserEntity) => { - const { id, data: cgroup } = cgroupUserEntity; + const cgroups = await savedCGroups(); + const cgroupPeople: Interim = cgroups.map((cgroup) => { + const { id, data } = cgroup; + const { name, isHidden, assigned, avatarFaceID } = data; // Hidden cgroups are clusters specifically marked so as to not be shown // in the UI. - if (cgroup.isHidden) return undefined; + if (isHidden) return undefined; // Person faces from all the clusters assigned to this cgroup, sorted by // their score. - const faces = cgroup.assigned + const faces = assigned .map(({ faces }) => faces.map((id) => personFaceByID.get(id)).filter((f) => !!f), ) @@ -198,7 +195,6 @@ export const reconstructPeople = async (): Promise => { const fileIDs = [...new Set(faces.map((f) => f.file.id))]; // Avatar face ID, or the highest scoring face. - const avatarFaceID = cgroup.avatarFaceID; let avatarFile: EnteFile | undefined; if (avatarFaceID) { const avatarFileID = fileIDFromFaceID(avatarFaceID); @@ -217,9 +213,9 @@ export const reconstructPeople = async (): Promise => { return { type: "cgroup", - cgroupUserEntity, + cgroup, id, - name: cgroup.name, + name, fileIDs, displayFaceID, displayFaceFile, diff --git a/web/packages/new/photos/services/user-entity/index.ts b/web/packages/new/photos/services/user-entity/index.ts index b11b5ab4a7..067bf82903 100644 --- a/web/packages/new/photos/services/user-entity/index.ts +++ b/web/packages/new/photos/services/user-entity/index.ts @@ -50,7 +50,7 @@ export type EntityType = * Zod schema for the fields of interest in the location tag that we get from * remote. */ -const RemoteLocationTag = z.object({ +const RemoteLocationTagData = z.object({ name: z.string(), radius: z.number(), centerPoint: z.object({ @@ -62,14 +62,14 @@ const RemoteLocationTag = z.object({ /** * A view of the location tag data suitable for use by the rest of the app. */ -export type LocationTag = z.infer; +export type LocationTag = z.infer; /** * Return the list of locally available location tags. */ export const savedLocationTags = (): Promise => savedEntities("location").then((es) => - es.map((e) => RemoteLocationTag.parse(e.data)), + es.map((e) => RemoteLocationTagData.parse(e.data)), ); const RemoteFaceCluster = z.object({ @@ -82,7 +82,7 @@ const RemoteFaceCluster = z.object({ * * See also: {@link CGroupUserEntityData}. */ -const RemoteCGroup = z.object({ +const RemoteCGroupData = z.object({ name: z.string().nullish().transform(nullToUndefined), assigned: z.array(RemoteFaceCluster), // The remote cgroup also has a "rejected" property, but that is not @@ -91,7 +91,10 @@ const RemoteCGroup = z.object({ avatarFaceID: z.string().nullish().transform(nullToUndefined), }); -export type CGroupUserEntity = Omit & { +/** + * A "cgroup" user entity. + */ +export type CGroup = Omit & { // CGroupUserEntityData is meant to be a (documented) equivalent of // `z.infer`. data: CGroupUserEntityData; @@ -100,13 +103,13 @@ export type CGroupUserEntity = Omit & { /** * Return the list of locally available cgroup user entities. */ -export const savedCGroupUserEntities = (): Promise => +export const savedCGroups = (): Promise => // See: [Note: strict mode migration] // // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore savedEntities("cgroup").then((es) => - es.map((e) => ({ ...e, data: RemoteCGroup.parse(e.data) })), + es.map((e) => ({ ...e, data: RemoteCGroupData.parse(e.data) })), ); /**