diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 868e8e3a0b..59966ed4f3 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -20,6 +20,9 @@ import { SearchResultsHeader, } from "@/new/photos/components/gallery"; import { + deriveAlbumishFilteredFiles, + derivePeopleFilteredFiles, + deriveTrashFilteredFiles, uniqueFilesByID, useGalleryReducer, type GalleryBarMode, @@ -28,9 +31,7 @@ import { usePeopleStateSnapshot } from "@/new/photos/components/utils/ml"; import { shouldShowWhatsNew } from "@/new/photos/services/changelog"; import { ALL_SECTION, - ARCHIVE_SECTION, DUMMY_UNCATEGORIZED_COLLECTION, - HIDDEN_ITEMS_SECTION, TRASH_SECTION, isHiddenCollection, } from "@/new/photos/services/collection"; @@ -41,7 +42,6 @@ import { getLocalTrashedFiles, sortFiles, } from "@/new/photos/services/files"; -import { isArchivedFile } from "@/new/photos/services/magic-metadata"; import type { Person } from "@/new/photos/services/ml/people"; import { filterSearchableFiles, @@ -110,7 +110,6 @@ import { useCallback, useContext, useEffect, - useMemo, useRef, useState, } from "react"; @@ -305,12 +304,10 @@ export default function Gallery() { const user = state.user; const familyData = state.familyData; const collections = state.collections; - const hiddenCollections = state.hiddenCollections; const files = state.files; const hiddenFiles = state.hiddenFiles; const trashedFiles = state.trashedFiles; const archivedCollectionIDs = state.archivedCollectionIDs; - const defaultHiddenCollectionIDs = state.defaultHiddenCollectionIDs; const hiddenFileIDs = state.hiddenFileIDs; const collectionNameMap = state.allCollectionNameByID; const fileToCollectionsMap = state.fileCollectionIDs; @@ -318,14 +315,20 @@ export default function Gallery() { const hiddenCollectionSummaries = state.hiddenCollectionSummaries; const tempDeletedFileIDs = state.tempDeletedFileIDs; const tempHiddenFileIDs = state.tempHiddenFileIDs; - const barMode = state.barMode ?? "albums"; - const activeCollectionID = state.activeCollectionID; - const activePersonID = state.activePersonID; + const barMode = state.view?.type ?? "albums"; + const activeCollectionID = + state.view?.type == "people" + ? undefined + : state.view?.activeCollectionSummaryID; + const activeCollection = + state.view?.type == "people" ? undefined : state.view?.activeCollection; + const activePerson = + state.view?.type == "people" ? state.view.activePerson : undefined; + const activePersonID = activePerson?.id; const isInSearchMode = state.isInSearchMode; + const filteredFiles = state.filteredFiles; - if (process.env.NEXT_PUBLIC_ENTE_WIP_CL) { - console.log("render", { collections, hiddenCollections, files }); - } + if (process.env.NEXT_PUBLIC_ENTE_WIP_CL) console.log("render", { state }); const router = useRouter(); @@ -478,15 +481,6 @@ export default function Gallery() { } }, [isInSearchMode, selectedSearchOption]); - const activeCollection = useMemo(() => { - if (!collections || !hiddenCollections) { - return null; - } - return [...collections, ...hiddenCollections].find( - (collection) => collection.id === activeCollectionID, - ); - }, [collections, activeCollectionID]); - // TODO: Make this a normal useEffect. useMemoSingleThreaded(async () => { if ( @@ -497,147 +491,28 @@ export default function Gallery() { !archivedCollectionIDs ) { dispatch({ - type: "set", - filteredData: [], - galleryPeopleState: undefined, + type: "setFilteredFiles", + filteredFiles: [], }); return; } - let filteredFiles: EnteFile[] = []; - let galleryPeopleState: - | { activePerson: Person | undefined; people: Person[] } - | undefined; + let filteredFiles: EnteFile[]; if (selectedSearchOption) { filteredFiles = await filterSearchableFiles( selectedSearchOption.suggestion, ); - } else if (barMode == "people") { - let filteredPeople = peopleState?.people ?? []; - let filteredVisiblePeople = peopleState?.visiblePeople ?? []; - if (tempDeletedFileIDs?.size ?? tempHiddenFileIDs?.size) { - // 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. - 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); - let activePerson = findByID(filteredVisiblePeople); - if (!activePerson) { - // This might be one of the normally hidden small clusters. - activePerson = findByID(filteredPeople); - if (activePerson) { - // Temporarily add this person's entry to the list of people - // surfaced in the people section. - filteredVisiblePeople.push(activePerson); - } else { - // We don't have an "All" pseudo-album in people mode, so - // default to the first person in the list. - activePerson = filteredVisiblePeople[0]; - } - } - const pfSet = new Set(activePerson?.fileIDs ?? []); - filteredFiles = uniqueFilesByID( - files.filter(({ id }) => { - if (!pfSet.has(id)) return false; - return true; - }), - ); - galleryPeopleState = { - activePerson, - people: filteredVisiblePeople, - }; + } else if (state.view?.type == "people") { + filteredFiles = derivePeopleFilteredFiles(state, state.view); } else if (activeCollectionID === TRASH_SECTION) { - filteredFiles = uniqueFilesByID([ - ...trashedFiles, - ...files.filter((file) => tempDeletedFileIDs?.has(file.id)), - ]); + filteredFiles = deriveTrashFilteredFiles(state); } else { - const baseFiles = barMode == "hidden-albums" ? hiddenFiles : files; - filteredFiles = uniqueFilesByID( - baseFiles.filter((item) => { - if (tempDeletedFileIDs?.has(item.id)) { - return false; - } - - if ( - barMode != "hidden-albums" && - tempHiddenFileIDs?.has(item.id) - ) { - return false; - } - - // archived collections files can only be seen in their respective collection - if (archivedCollectionIDs.has(item.collectionID)) { - if (activeCollectionID === item.collectionID) { - return true; - } else { - return false; - } - } - - // HIDDEN ITEMS SECTION - show all individual hidden files - if ( - activeCollectionID === HIDDEN_ITEMS_SECTION && - defaultHiddenCollectionIDs.has(item.collectionID) - ) { - return true; - } - - // Archived files can only be seen in archive section or their respective collection - if (isArchivedFile(item)) { - if ( - activeCollectionID === ARCHIVE_SECTION || - activeCollectionID === item.collectionID - ) { - return true; - } else { - return false; - } - } - - // ALL SECTION - show all files - if (activeCollectionID === ALL_SECTION) { - // show all files except the ones in hidden collections - if (hiddenFileIDs.has(item.id)) { - return false; - } else { - return true; - } - } - - // COLLECTION SECTION - show files in the active collection - if (activeCollectionID === item.collectionID) { - return true; - } else { - return false; - } - }), - ); - const sortAsc = - activeCollection?.pubMagicMetadata?.data?.asc ?? false; - if (sortAsc) { - filteredFiles = sortFiles(filteredFiles, true); - } + filteredFiles = deriveAlbumishFilteredFiles(state); } dispatch({ - type: "set", - filteredData: filteredFiles, - galleryPeopleState, + type: "setFilteredFiles", + filteredFiles, }); }, [ barMode, @@ -654,8 +529,6 @@ export default function Gallery() { activePersonID, ]); - const { filteredData, ...galleryPeopleState } = state; - const selectAll = (e: KeyboardEvent) => { // ignore ctrl/cmd + a if the user is typing in a text field if ( @@ -675,7 +548,7 @@ export default function Gallery() { exportModalView || authenticateUserModalView || isPhotoSwipeOpen || - !filteredData?.length || + !filteredFiles?.length || !user ) { return; @@ -686,10 +559,10 @@ export default function Gallery() { count: 0, collectionID: activeCollectionID, context: - barMode == "people" && galleryPeopleState?.activePerson?.id + barMode == "people" && activePersonID ? { mode: "people" as const, - personID: galleryPeopleState.activePerson.id, + personID: activePersonID, } : { mode: barMode as "albums" | "hidden-albums", @@ -697,7 +570,7 @@ export default function Gallery() { }, }; - filteredData.forEach((item) => { + filteredFiles.forEach((item) => { if (item.ownerID === user.id) { selected.ownCount++; } @@ -871,7 +744,7 @@ export default function Gallery() { startLoading(); try { setOpenCollectionSelector(false); - const selectedFiles = getSelectedFiles(selected, filteredData); + const selectedFiles = getSelectedFiles(selected, filteredFiles); const toProcessFiles = ops === COLLECTION_OPS_TYPE.REMOVE ? selectedFiles @@ -907,7 +780,7 @@ export default function Gallery() { // passing files here instead of filteredData for hide ops because we want to move all files copies to hidden collection const selectedFiles = getSelectedFiles( selected, - ops === FILE_OPS_TYPE.HIDE ? files : filteredData, + ops === FILE_OPS_TYPE.HIDE ? files : filteredFiles, ); const toProcessFiles = ops === FILE_OPS_TYPE.DOWNLOAD @@ -1021,7 +894,7 @@ export default function Gallery() { const handleChangeBarMode = (mode: GalleryBarMode) => mode == "people" ? dispatch({ type: "showPeople" }) - : dispatch({ type: "showAll" }); + : dispatch({ type: "showAlbums" }); const openHiddenSection: GalleryContextType["openHiddenSection"] = ( callback, @@ -1050,7 +923,7 @@ export default function Gallery() { [], ); - if (!user || !filteredData) { + if (!user || !filteredFiles) { // Don't render until we get the logged in user and dispatch "mount". return
; } @@ -1147,7 +1020,7 @@ export default function Gallery() { > {barMode == "hidden-albums" ? ( dispatch({ type: "showAll" })} + onBack={() => dispatch({ type: "showAlbums" })} /> ) : ( ) : (