From a745b69ebe09ecf1501d9964740dc04f873c7aa0 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 15 Oct 2024 15:50:52 +0530 Subject: [PATCH] State updates --- .../components/gallery/PeopleHeader.tsx | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/web/packages/new/photos/components/gallery/PeopleHeader.tsx b/web/packages/new/photos/components/gallery/PeopleHeader.tsx index 809da0aef3..a72b131473 100644 --- a/web/packages/new/photos/components/gallery/PeopleHeader.tsx +++ b/web/packages/new/photos/components/gallery/PeopleHeader.tsx @@ -281,13 +281,11 @@ interface SuggestionsDialogState { * - saved choice for which the user has changed their mind. * - suggestion that the user has either explicitly accepted or rejected. */ - marks: Map; + marks: Map; } type SCItem = PreviewableCluster & { fixed?: boolean; accepted?: boolean }; -type SCMark = "yes" | "no" | undefined; - type SuggestionsDialogAction = | { type: "fetch"; personID: string } | { type: "fetchFailed"; personID: string } @@ -296,7 +294,7 @@ type SuggestionsDialogAction = personID: string; suggestionsAndChoices: PersonSuggestionsAndChoices; } - | { type: "mark"; item: SCItem; value: SCMark } + | { type: "mark"; item: SCItem; value: boolean | undefined } | { type: "save" } | { type: "toggleHistory" } | { type: "close" }; @@ -339,9 +337,13 @@ const suggestionsDialogReducer = ( case "mark": { const marks = new Map(state.marks); const { item, value } = action; - // If this was a new suggestion, prune off marks created as a result - // of the user toggling the item back to its original unset state. if (item.accepted === undefined && value === undefined) { + // If this was a suggestion, prune marks created as a result of + // the user toggling the item back to its original unset state. + marks.delete(item.id); + } else if (item.accepted && value === item.accepted) { + // If this is a choice, prune marks which match the choice's + // accepted state. marks.delete(item.id); } else { marks.set(item.id, value); @@ -428,7 +430,7 @@ const SuggestionsDialog: React.FC = ({ resetPersonAndClose(); }; - const handleMark = (item: SCItem, value: SCMark) => + const handleMark = (item: SCItem, value: boolean | undefined) => dispatch({ type: "mark", item, value }); const handleSave = async () => { @@ -539,12 +541,12 @@ const SuggestionsDialog: React.FC = ({ interface SuggestionOrChoiceListProps { items: SCItem[]; - marks: Map; + marks: Map; /** * Callback invoked when the user changes the value associated with the * given suggestion or choice. */ - onMarkItem: (item: SCItem, value: SCMark) => void; + onMarkItem: (item: SCItem, value: boolean | undefined) => void; } const SuggestionOrChoiceList: React.FC = ({ @@ -571,9 +573,9 @@ const SuggestionOrChoiceList: React.FC = ({ {!item.fixed && ( onMarkItem(item, toClusterMark(v))} + onChange={(_, v) => onMarkItem(item, toItemValue(v))} > @@ -588,9 +590,16 @@ const SuggestionOrChoiceList: React.FC = ({ ); -const toItemValue = (accepted?: boolean) => - accepted ? "yes" : accepted === false ? "no" : undefined; +const fromItemValue = ( + item: SCItem, + marks: Map, +) => { + // Use the in-memory state if available. + if (marks.has(item.id)) return marks.get(item.id); + // Use the original state of the choice (when applicable). + return item.accepted ? "yes" : item.accepted === false ? "no" : undefined; +}; -const toClusterMark = (v: unknown) => +const toItemValue = (v: unknown) => // This dance is needed for TypeScript to recognize the type. - v == "yes" ? "yes" : v == "no" ? "no" : undefined; + v == "yes" ? true : v == "no" ? false : undefined;