From 9a444b4881ef3885d5487fce2dcae9f1d38f701e Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 26 Sep 2024 20:33:02 +0530 Subject: [PATCH] Rename --- .../new/photos/components/Gallery/index.tsx | 63 +++++++++++++------ web/packages/new/photos/services/ml/index.ts | 27 +++++++- .../new/photos/services/user-entity/index.ts | 12 +--- 3 files changed, 70 insertions(+), 32 deletions(-) diff --git a/web/packages/new/photos/components/Gallery/index.tsx b/web/packages/new/photos/components/Gallery/index.tsx index 7969d1ccd5..7c13a2013c 100644 --- a/web/packages/new/photos/components/Gallery/index.tsx +++ b/web/packages/new/photos/components/Gallery/index.tsx @@ -8,7 +8,7 @@ */ import { pt } from "@/base/i18n"; -import { addPerson } from "@/new/photos/services/ml/"; +import { addPerson, renamePerson } from "@/new/photos/services/ml/"; import { type Person } from "@/new/photos/services/ml/people"; import type { SearchOption } from "@/new/photos/services/search/types"; import OverflowMenu from "@ente/shared/components/OverflowMenu/menu"; @@ -91,31 +91,54 @@ export const PeopleHeader: React.FC = ({ }; interface CGroupPersonOptionsProps { - person: Person; cgroup: CGroup; appContext: NewAppContextPhotos; } const CGroupPersonOptions: React.FC = ({ - person, + cgroup, + appContext, }) => { - const rename = () => { - console.log("todo rename", person); + const { startLoading, finishLoading } = appContext; + + const [openAddNameInput, setOpenAddNameInput] = useState(false); + + const handleRenamePerson = () => setOpenAddNameInput(true); + + const renamePersonUsingName = async (name: string) => { + startLoading(); + try { + await renamePerson(name, cgroup); + } finally { + finishLoading(); + } }; return ( - } - > - } - centerAlign - onClick={rename} + <> + } > - {t("rename")} - - + } + centerAlign + onClick={handleRenamePerson} + > + {pt("rename")} + + + + setOpenAddNameInput(false)} + title={pt("Rename person")} + placeholder={t("ENTER_NAME") /* TODO-Cluster */} + initialValue={cgroup.data.name ?? ""} + submitButtonTitle={t("rename")} + onSubmit={renamePersonUsingName} + /> + ); }; @@ -130,9 +153,9 @@ const ClusterPersonOptions: React.FC = ({ }) => { const { startLoading, finishLoading } = appContext; - const [openAddNameInput, setOpenAddNameInput] = useState(false); + const [openNameInput, setOpenNameInput] = useState(false); - const handleAddPerson = () => setOpenAddNameInput(true); + const handleAddPerson = () => setOpenNameInput(true); const addPersonWithName = async (name: string) => { startLoading(); @@ -167,8 +190,8 @@ const ClusterPersonOptions: React.FC = ({ setOpenAddNameInput(false)} + open={openNameInput} + onClose={() => setOpenNameInput(false)} title={pt("Add person")} placeholder={t("ENTER_NAME") /* TODO-Cluster */} initialValue={""} diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index 8b0e0929e4..4858aded3a 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -19,7 +19,12 @@ import { isInternalUser } from "../feature-flags"; import { getRemoteFlag, updateRemoteFlag } from "../remote-store"; import { setSearchPeople } from "../search"; import type { UploadItem } from "../upload/types"; -import { addUserEntity, pullUserEntities } from "../user-entity"; +import { + addUserEntity, + pullUserEntities, + updateOrCreateUserEntities, + type CGroup, +} from "../user-entity"; import type { FaceCluster } from "./cluster"; import { regenerateFaceCrops } from "./crop"; import { clearMLDB, getFaceIndex, getIndexableAndIndexedCounts } from "./db"; @@ -633,7 +638,7 @@ const regenerateFaceCropsIfNeeded = async (enteFile: EnteFile) => { }; /** - * Convert a cluster into a named cgroup, updating both remote and local state. + * Convert a cluster into a named person, updating both remote and local state. * * @param name Name of the new cgroup user entity. * @@ -652,3 +657,21 @@ export const addPerson = async (name: string, cluster: FaceCluster) => { ); return mlSync(); }; + +/** + * Rename an existing named person. + * + * @param name The new name to use. + * + * @param cgroup The existing cgroup underlying the person. This is the (remote) + * user entity that will get updated. + */ +export const renamePerson = async (name: string, cgroup: CGroup) => { + const masterKey = await masterKeyFromSession(); + await updateOrCreateUserEntities( + "cgroup", + [{ ...cgroup, data: { ...cgroup.data, name } }], + masterKey, + ); + return mlSync(); +}; diff --git a/web/packages/new/photos/services/user-entity/index.ts b/web/packages/new/photos/services/user-entity/index.ts index 067bf82903..33788b813b 100644 --- a/web/packages/new/photos/services/user-entity/index.ts +++ b/web/packages/new/photos/services/user-entity/index.ts @@ -178,15 +178,11 @@ export const addUserEntity = async ( type: EntityType, data: unknown, masterKey: Uint8Array, -) => { - // Create it on remote. +) => await postUserEntity( type, await encryptedUserEntityData(type, data, masterKey), ); - // Perform a diff sync to update our local state. - return pullUserEntities(type, masterKey); -}; export const encryptedUserEntityData = async ( type: EntityType, @@ -213,8 +209,7 @@ export const updateOrCreateUserEntities = async ( type: EntityType, entities: LocalUserEntity[], masterKey: Uint8Array, -) => { - // PUT all of them. +) => await Promise.all( entities.map(({ id, data }) => encryptedUserEntityData(type, data, masterKey).then( @@ -222,9 +217,6 @@ export const updateOrCreateUserEntities = async ( ), ), ); - // Perform a diff sync to update our local state. - return pullUserEntities(type, masterKey); -}; /** * Return the entity key that can be used to decrypt the encrypted contents of