From 60261b9d06c64f77b10c4055af2582212c2899e5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 18:44:42 +0530 Subject: [PATCH 01/15] Log the entire state --- web/apps/photos/src/pages/gallery.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 868e8e3a0b..459d542886 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -323,9 +323,7 @@ export default function Gallery() { const activePersonID = state.activePersonID; const isInSearchMode = state.isInSearchMode; - 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(); From 104029e720f63baffb3eee54f494e9d006d09a7d Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 19:05:59 +0530 Subject: [PATCH 02/15] Move --- web/apps/photos/src/pages/gallery.tsx | 72 +-------------- .../new/photos/components/gallery/reducer.ts | 87 +++++++++++++++++++ 2 files changed, 89 insertions(+), 70 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 459d542886..046572e25d 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -20,6 +20,7 @@ import { SearchResultsHeader, } from "@/new/photos/components/gallery"; import { + deriveFilteredFilesAlbumishFocus, uniqueFilesByID, useGalleryReducer, type GalleryBarMode, @@ -28,9 +29,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 +40,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, @@ -310,7 +308,6 @@ export default function Gallery() { 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; @@ -564,72 +561,7 @@ export default function Gallery() { ...files.filter((file) => tempDeletedFileIDs?.has(file.id)), ]); } 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 = deriveFilteredFilesAlbumishFocus(state); } dispatch({ diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index d5a3da0624..b13089da95 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -944,3 +944,90 @@ const findAllSectionVisibleFiles = ( !archivedCollectionIDs.has(file.collectionID), ), ); + +/** + * Helper function to compute the sorted list of files to show when we're + * showing either "albums" or "hidden-albums". + */ +export const deriveFilteredFilesAlbumishFocus = (state: GalleryState) => { + const { + barMode, + collections, + hiddenCollections, + files, + hiddenFiles, + archivedCollectionIDs, + defaultHiddenCollectionIDs, + hiddenFileIDs, + tempDeletedFileIDs, + tempHiddenFileIDs, + activeCollectionID, + } = state; + + const baseFiles = barMode == "hidden-albums" ? hiddenFiles : files; + + const activeCollection = ( + barMode == "albums" ? collections : hiddenCollections + ).find((collection) => collection.id === activeCollectionID); + + const 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; + } + }), + ); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; + return sortAsc ? sortFiles(filteredFiles, true) : filteredFiles; +}; From fa2689d14b50a67772e484cebf957650613302ff Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 19:22:52 +0530 Subject: [PATCH 03/15] Split --- .../new/photos/components/gallery/reducer.ts | 102 ++++++++++++++---- 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index b13089da95..7315708cd6 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -950,33 +950,39 @@ const findAllSectionVisibleFiles = ( * showing either "albums" or "hidden-albums". */ export const deriveFilteredFilesAlbumishFocus = (state: GalleryState) => { + if (state.barMode == "albums") { + return deriveFilteredFilesAlbumFocus(state); + } else { + return deriveFilteredFilesHiddenAlbumsFocus(state); + } +}; + +/** + * Helper function to compute the sorted list of files to show when we're + * in the "albums" focus. + */ +export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { const { - barMode, collections, - hiddenCollections, files, - hiddenFiles, archivedCollectionIDs, - defaultHiddenCollectionIDs, hiddenFileIDs, tempDeletedFileIDs, tempHiddenFileIDs, activeCollectionID, } = state; - const baseFiles = barMode == "hidden-albums" ? hiddenFiles : files; - - const activeCollection = ( - barMode == "albums" ? collections : hiddenCollections - ).find((collection) => collection.id === activeCollectionID); + const activeCollection = collections.find( + (collection) => collection.id === activeCollectionID, + ); const filteredFiles = uniqueFilesByID( - baseFiles.filter((item) => { + files.filter((item) => { if (tempDeletedFileIDs.has(item.id)) { return false; } - if (barMode != "hidden-albums" && tempHiddenFileIDs.has(item.id)) { + if (tempHiddenFileIDs.has(item.id)) { return false; } @@ -989,14 +995,6 @@ export const deriveFilteredFilesAlbumishFocus = (state: GalleryState) => { } } - // 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 ( @@ -1031,3 +1029,69 @@ export const deriveFilteredFilesAlbumishFocus = (state: GalleryState) => { const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; return sortAsc ? sortFiles(filteredFiles, true) : filteredFiles; }; + +/** + * Helper function to compute the sorted list of files to show when we're + * in the "hidden-albums" focus. + */ +export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { + const { + hiddenCollections, + hiddenFiles, + archivedCollectionIDs, + defaultHiddenCollectionIDs, + tempDeletedFileIDs, + activeCollectionID, + } = state; + + const activeCollection = hiddenCollections.find( + (collection) => collection.id === activeCollectionID, + ); + + const filteredFiles = uniqueFilesByID( + hiddenFiles.filter((item) => { + if (tempDeletedFileIDs.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; + } + } + + // COLLECTION SECTION - show files in the active collection + if (activeCollectionID === item.collectionID) { + return true; + } else { + return false; + } + }), + ); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; + return sortAsc ? sortFiles(filteredFiles, true) : filteredFiles; +}; From 8f481e547182472fb020c7944460671f145dc340 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 19:48:53 +0530 Subject: [PATCH 04/15] dedup --- .../new/photos/components/gallery/reducer.ts | 178 ++++++++++-------- 1 file changed, 95 insertions(+), 83 deletions(-) diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 7315708cd6..22cd033f81 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -976,58 +976,54 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { (collection) => collection.id === activeCollectionID, ); - const filteredFiles = uniqueFilesByID( - files.filter((item) => { - if (tempDeletedFileIDs.has(item.id)) { - return false; - } + const filteredFiles = files.filter((item) => { + if (tempDeletedFileIDs.has(item.id)) { + return false; + } - if (tempHiddenFileIDs.has(item.id)) { - return false; - } + if (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; - } - } - - // 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 + // 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; } - }), - ); - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; - return sortAsc ? sortFiles(filteredFiles, true) : filteredFiles; + } + + // 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; + } + }); + return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); }; /** @@ -1048,50 +1044,66 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { (collection) => collection.id === activeCollectionID, ); - const filteredFiles = uniqueFilesByID( - hiddenFiles.filter((item) => { - if (tempDeletedFileIDs.has(item.id)) { - return false; - } + const filteredFiles = hiddenFiles.filter((item) => { + if (tempDeletedFileIDs.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; - } - } - - // COLLECTION SECTION - show files in the active collection + // 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; + } + } + + // COLLECTION SECTION - show files in the active collection + if (activeCollectionID === item.collectionID) { + return true; + } else { + return false; + } + }); + + return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); +}; + +/** + * Prepare the list of files for being shown in the gallery. + * + * This functions uniques the given collection files so that there is only one + * entry per file ID. Then it sorts them if needed if the active collection + * prefers them to be sorted oldest first (by default, lists of collection files + * are sorted newest first, and we assume that {@link files} are already sorted + * that way). + */ +const sortAndUniqueFilteredFiles = ( + files: EnteFile[], + activeCollection: Collection | undefined, +) => { + const uniqueFiles = uniqueFilesByID(files); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; - return sortAsc ? sortFiles(filteredFiles, true) : filteredFiles; + return sortAsc ? sortFiles(uniqueFiles, true) : uniqueFiles; }; From ff06c4d1cf5ea810a2e162e74c3de967204b1e63 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:00:22 +0530 Subject: [PATCH 05/15] Prune --- .../new/photos/components/gallery/reducer.ts | 68 ++++++------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 22cd033f81..98fc6d5329 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -976,18 +976,13 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { (collection) => collection.id === activeCollectionID, ); - const filteredFiles = files.filter((item) => { - if (tempDeletedFileIDs.has(item.id)) { - return false; - } - - if (tempHiddenFileIDs.has(item.id)) { - return false; - } + const filteredFiles = files.filter((file) => { + if (tempDeletedFileIDs.has(file.id)) return false; + if (tempHiddenFileIDs.has(file.id)) return false; // archived collections files can only be seen in their respective collection - if (archivedCollectionIDs.has(item.collectionID)) { - if (activeCollectionID === item.collectionID) { + if (archivedCollectionIDs.has(file.collectionID)) { + if (activeCollectionID === file.collectionID) { return true; } else { return false; @@ -995,10 +990,10 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { } // Archived files can only be seen in archive section or their respective collection - if (isArchivedFile(item)) { + if (isArchivedFile(file)) { if ( activeCollectionID === ARCHIVE_SECTION || - activeCollectionID === item.collectionID + activeCollectionID === file.collectionID ) { return true; } else { @@ -1009,19 +1004,15 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { // ALL SECTION - show all files if (activeCollectionID === ALL_SECTION) { // show all files except the ones in hidden collections - if (hiddenFileIDs.has(item.id)) { + if (hiddenFileIDs.has(file.id)) { return false; } else { return true; } } - // COLLECTION SECTION - show files in the active collection - if (activeCollectionID === item.collectionID) { - return true; - } else { - return false; - } + // Show files in the active collection + return activeCollectionID === file.collectionID; }); return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); }; @@ -1044,14 +1035,12 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { (collection) => collection.id === activeCollectionID, ); - const filteredFiles = hiddenFiles.filter((item) => { - if (tempDeletedFileIDs.has(item.id)) { - return false; - } + const filteredFiles = hiddenFiles.filter((file) => { + if (tempDeletedFileIDs.has(file.id)) return false; // archived collections files can only be seen in their respective collection - if (archivedCollectionIDs.has(item.collectionID)) { - if (activeCollectionID === item.collectionID) { + if (archivedCollectionIDs.has(file.collectionID)) { + if (activeCollectionID === file.collectionID) { return true; } else { return false; @@ -1061,29 +1050,13 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { // HIDDEN ITEMS SECTION - show all individual hidden files if ( activeCollectionID === HIDDEN_ITEMS_SECTION && - defaultHiddenCollectionIDs.has(item.collectionID) + defaultHiddenCollectionIDs.has(file.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; - } - } - - // COLLECTION SECTION - show files in the active collection - if (activeCollectionID === item.collectionID) { - return true; - } else { - return false; - } + // Show files in the active collection + return activeCollectionID === file.collectionID; }); return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); @@ -1093,10 +1066,9 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { * Prepare the list of files for being shown in the gallery. * * This functions uniques the given collection files so that there is only one - * entry per file ID. Then it sorts them if needed if the active collection - * prefers them to be sorted oldest first (by default, lists of collection files - * are sorted newest first, and we assume that {@link files} are already sorted - * that way). + * entry per file ID. Then it sorts them if the active collection prefers them + * to be sorted oldest first (by default, lists of collection files are sorted + * newest first, and we assume that {@link files} are already sorted that way). */ const sortAndUniqueFilteredFiles = ( files: EnteFile[], From 76ba2fde0108296e8afb0eefddf5dfdc3cd586a5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:03:28 +0530 Subject: [PATCH 06/15] Unlink archive / hidden --- .../new/photos/components/gallery/reducer.ts | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 98fc6d5329..882b89e981 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -1025,7 +1025,6 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { const { hiddenCollections, hiddenFiles, - archivedCollectionIDs, defaultHiddenCollectionIDs, tempDeletedFileIDs, activeCollectionID, @@ -1038,25 +1037,16 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { const filteredFiles = hiddenFiles.filter((file) => { if (tempDeletedFileIDs.has(file.id)) return false; - // archived collections files can only be seen in their respective collection - if (archivedCollectionIDs.has(file.collectionID)) { - if (activeCollectionID === file.collectionID) { - return true; - } else { - return false; - } - } - - // HIDDEN ITEMS SECTION - show all individual hidden files + // Hidden items sections shows all standalone hidden files. if ( activeCollectionID === HIDDEN_ITEMS_SECTION && defaultHiddenCollectionIDs.has(file.collectionID) ) { return true; + } else { + // Show files in the active collection. + return activeCollectionID === file.collectionID; } - - // Show files in the active collection - return activeCollectionID === file.collectionID; }); return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); From 7c168fd9db11f9770f872b008cd955fb772fc358 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:12:20 +0530 Subject: [PATCH 07/15] Prune --- .../new/photos/components/gallery/reducer.ts | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 882b89e981..c40ce487f7 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -978,42 +978,33 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { const filteredFiles = files.filter((file) => { if (tempDeletedFileIDs.has(file.id)) return false; + if (hiddenFileIDs.has(file.id)) return false; if (tempHiddenFileIDs.has(file.id)) return false; - // archived collections files can only be seen in their respective collection + // Files in archived collections can only be seen in their respective + // collection. if (archivedCollectionIDs.has(file.collectionID)) { - if (activeCollectionID === file.collectionID) { - return true; - } else { - return false; - } + return activeCollectionID === file.collectionID; } - // Archived files can only be seen in archive section or their respective collection + // Archived files can only be seen in the archive section, or in their + // respective collection. if (isArchivedFile(file)) { - if ( + return ( activeCollectionID === ARCHIVE_SECTION || activeCollectionID === file.collectionID - ) { - return true; - } else { - return false; - } + ); } - // ALL SECTION - show all files + // Show all remaining (non-hidden, non-archived) files in "All". if (activeCollectionID === ALL_SECTION) { - // show all files except the ones in hidden collections - if (hiddenFileIDs.has(file.id)) { - return false; - } else { - return true; - } + return true; } - // Show files in the active collection + // Show files that belong to the active collection. return activeCollectionID === file.collectionID; }); + return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); }; @@ -1037,16 +1028,16 @@ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { const filteredFiles = hiddenFiles.filter((file) => { if (tempDeletedFileIDs.has(file.id)) return false; - // Hidden items sections shows all standalone hidden files. + // "Hidden" shows all standalone hidden files. if ( activeCollectionID === HIDDEN_ITEMS_SECTION && defaultHiddenCollectionIDs.has(file.collectionID) ) { return true; - } else { - // Show files in the active collection. - return activeCollectionID === file.collectionID; } + + // Show files that belong to the active collection. + return activeCollectionID === file.collectionID; }); return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); From 4a7d849d94e6670181352953823f956ef01656b1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:19:32 +0530 Subject: [PATCH 08/15] T --- web/apps/photos/src/pages/gallery.tsx | 6 ++---- .../new/photos/components/gallery/reducer.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 046572e25d..2c7a8611fc 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -21,6 +21,7 @@ import { } from "@/new/photos/components/gallery"; import { deriveFilteredFilesAlbumishFocus, + deriveFilteredFilesTrash, uniqueFilesByID, useGalleryReducer, type GalleryBarMode, @@ -556,10 +557,7 @@ export default function Gallery() { people: filteredVisiblePeople, }; } else if (activeCollectionID === TRASH_SECTION) { - filteredFiles = uniqueFilesByID([ - ...trashedFiles, - ...files.filter((file) => tempDeletedFileIDs?.has(file.id)), - ]); + filteredFiles = deriveFilteredFilesTrash(state); } else { filteredFiles = deriveFilteredFilesAlbumishFocus(state); } diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index c40ce487f7..9de93e353a 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -1008,6 +1008,20 @@ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { return sortAndUniqueFilteredFiles(filteredFiles, activeCollection); }; +/** + * Helper function to compute the sorted list of files to show when we're + * showing the "Trash". + */ +export const deriveFilteredFilesTrash = ({ + files, + trashedFiles, + tempDeletedFileIDs, +}: GalleryState) => + uniqueFilesByID([ + ...trashedFiles, + ...files.filter((file) => tempDeletedFileIDs.has(file.id)), + ]); + /** * Helper function to compute the sorted list of files to show when we're * in the "hidden-albums" focus. From e3ebc1b11a88d61644cb5172c064f5a0c82004ec Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:36:36 +0530 Subject: [PATCH 09/15] Move --- web/apps/photos/src/pages/gallery.tsx | 53 ++-------------- .../new/photos/components/gallery/reducer.ts | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 2c7a8611fc..fb12ee79aa 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -21,6 +21,7 @@ import { } from "@/new/photos/components/gallery"; import { deriveFilteredFilesAlbumishFocus, + deriveFilteredFilesPeopleFocus, deriveFilteredFilesTrash, uniqueFilesByID, useGalleryReducer, @@ -500,7 +501,7 @@ export default function Gallery() { return; } - let filteredFiles: EnteFile[] = []; + let filteredFiles: EnteFile[]; let galleryPeopleState: | { activePerson: Person | undefined; people: Person[] } | undefined; @@ -509,53 +510,9 @@ export default function Gallery() { 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, - }; + const z = deriveFilteredFilesPeopleFocus(state); + filteredFiles = z.filteredFiles; + galleryPeopleState = z.galleryPeopleState; } else if (activeCollectionID === TRASH_SECTION) { filteredFiles = deriveFilteredFilesTrash(state); } else { diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 9de93e353a..1bdd054a4e 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -1074,3 +1074,63 @@ const sortAndUniqueFilteredFiles = ( const sortAsc = activeCollection?.pubMagicMetadata?.data?.asc ?? false; return sortAsc ? sortFiles(uniqueFiles, true) : uniqueFiles; }; + +/** + * Helper function to compute the sorted list of files to show when we're + * in the "people" focus. + */ +export const deriveFilteredFilesPeopleFocus = ({ + files, + tempDeletedFileIDs, + tempHiddenFileIDs, + peopleState, + activePersonID, +}: GalleryState) => { + let filteredPeople = peopleState?.people ?? []; + let filteredVisiblePeople = peopleState?.visiblePeople ?? []; + if (tempDeletedFileIDs.size + tempHiddenFileIDs.size > 0) { + // 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 ?? []); + const filteredFiles = uniqueFilesByID( + files.filter(({ id }) => { + if (!pfSet.has(id)) return false; + return true; + }), + ); + const galleryPeopleState = { + activePerson, + people: filteredVisiblePeople, + }; + return { filteredFiles, galleryPeopleState }; +}; From 997cf72eaed515023e855213bf24a54c7f3f9aa5 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 20:51:55 +0530 Subject: [PATCH 10/15] Move --- web/apps/photos/src/pages/gallery.tsx | 12 +------- .../new/photos/components/gallery/reducer.ts | 28 ++++++++++++------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index fb12ee79aa..e9e2483e18 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -110,7 +110,6 @@ import { useCallback, useContext, useEffect, - useMemo, useRef, useState, } from "react"; @@ -305,7 +304,6 @@ 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; @@ -319,6 +317,7 @@ export default function Gallery() { const tempHiddenFileIDs = state.tempHiddenFileIDs; const barMode = state.barMode ?? "albums"; const activeCollectionID = state.activeCollectionID; + const activeCollection = state.activeCollection; const activePersonID = state.activePersonID; const isInSearchMode = state.isInSearchMode; @@ -475,15 +474,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 ( diff --git a/web/packages/new/photos/components/gallery/reducer.ts b/web/packages/new/photos/components/gallery/reducer.ts index 1bdd054a4e..1c33b39883 100644 --- a/web/packages/new/photos/components/gallery/reducer.ts +++ b/web/packages/new/photos/components/gallery/reducer.ts @@ -214,6 +214,16 @@ export interface GalleryState { */ focus: GalleryFocus | undefined; activeCollectionID: number | undefined; + /** + * If the active collection ID is for a collection and not a + * pseudo-collection, this property will be set to the corresponding + * {@link Collection}. + * + * It is guaranteed that this will be one of the {@link collections} (when + * we are in the "albums" focus) or {@link hiddenCollections} (when we are + * in "hidden-albums" focus). + */ + activeCollection: Collection | undefined; /** * The currently selected person, if any. * @@ -329,6 +339,7 @@ const initialGalleryState: GalleryState = { barMode: undefined, focus: undefined, activeCollectionID: undefined, + activeCollection: undefined, activePersonID: undefined, filteredData: [], activePerson: undefined, @@ -586,6 +597,7 @@ const galleryReducer: React.Reducer = ( ...state, barMode: "albums", activeCollectionID: ALL_SECTION, + activeCollection: undefined, isInSearchMode: false, searchResults: undefined, }; @@ -594,6 +606,7 @@ const galleryReducer: React.Reducer = ( ...state, barMode: "hidden-albums", activeCollectionID: HIDDEN_ITEMS_SECTION, + activeCollection: undefined, isInSearchMode: false, searchResults: undefined, }; @@ -608,6 +621,9 @@ const galleryReducer: React.Reducer = ( ? "hidden-albums" : "albums", activeCollectionID: action.collectionSummaryID ?? ALL_SECTION, + activeCollection: state.collections + .concat(state.hiddenCollections) + .find(({ id }) => id === action.collectionSummaryID), isInSearchMode: false, searchResults: undefined, }; @@ -963,19 +979,15 @@ export const deriveFilteredFilesAlbumishFocus = (state: GalleryState) => { */ export const deriveFilteredFilesAlbumFocus = (state: GalleryState) => { const { - collections, files, archivedCollectionIDs, hiddenFileIDs, tempDeletedFileIDs, tempHiddenFileIDs, activeCollectionID, + activeCollection, } = state; - const activeCollection = collections.find( - (collection) => collection.id === activeCollectionID, - ); - const filteredFiles = files.filter((file) => { if (tempDeletedFileIDs.has(file.id)) return false; if (hiddenFileIDs.has(file.id)) return false; @@ -1028,17 +1040,13 @@ export const deriveFilteredFilesTrash = ({ */ export const deriveFilteredFilesHiddenAlbumsFocus = (state: GalleryState) => { const { - hiddenCollections, hiddenFiles, defaultHiddenCollectionIDs, tempDeletedFileIDs, activeCollectionID, + activeCollection, } = state; - const activeCollection = hiddenCollections.find( - (collection) => collection.id === activeCollectionID, - ); - const filteredFiles = hiddenFiles.filter((file) => { if (tempDeletedFileIDs.has(file.id)) return false; From 1979da383f2e55461a6638d174445bbdd02ba05b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 22 Oct 2024 21:17:03 +0530 Subject: [PATCH 11/15] focus wip --- web/apps/photos/src/pages/gallery.tsx | 52 +++++----- .../new/photos/components/gallery/reducer.ts | 97 +++++++++---------- 2 files changed, 75 insertions(+), 74 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index e9e2483e18..742ce403bb 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -315,11 +315,18 @@ 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 activeCollection = state.activeCollection; - const activePersonID = state.activePersonID; + const barMode = state.focus.type ?? "albums"; + const activeCollectionID = + state.focus.type == "people" + ? undefined + : state.focus.activeCollectionSummaryID; + const activeCollection = + state.focus.type == "people" ? undefined : state.focus.activeCollection; + const activePerson = + state.focus.type == "people" ? state.focus.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", { state }); @@ -484,8 +491,8 @@ export default function Gallery() { !archivedCollectionIDs ) { dispatch({ - type: "set", - filteredData: [], + type: "setFilteredFiles", + filteredFiles: [], galleryPeopleState: undefined, }); return; @@ -510,8 +517,8 @@ export default function Gallery() { } dispatch({ - type: "set", - filteredData: filteredFiles, + type: "setFilteredFiles", + filteredFiles, galleryPeopleState, }); }, [ @@ -529,8 +536,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 ( @@ -550,7 +555,7 @@ export default function Gallery() { exportModalView || authenticateUserModalView || isPhotoSwipeOpen || - !filteredData?.length || + !filteredFiles?.length || !user ) { return; @@ -561,10 +566,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", @@ -572,7 +577,7 @@ export default function Gallery() { }, }; - filteredData.forEach((item) => { + filteredFiles.forEach((item) => { if (item.ownerID === user.id) { selected.ownCount++; } @@ -746,7 +751,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 @@ -782,7 +787,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 @@ -925,7 +930,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
; } @@ -1050,8 +1055,11 @@ export default function Gallery() { setActiveCollectionID: handleSetActiveCollectionID, hiddenCollectionSummaries, showPeopleSectionButton, - people: galleryPeopleState?.people ?? [], - activePerson: galleryPeopleState?.activePerson, + people: + (state.focus.type == "people" + ? state.focus.people + : undefined) ?? [], + activePerson, onSelectPerson: handleSelectPerson, setCollectionNamerAttributes, setPhotoListHeader, @@ -1109,14 +1117,14 @@ export default function Gallery() { ) : !isInSearchMode && !isFirstLoad && barMode == "people" && - !galleryPeopleState?.activePerson ? ( + !activePerson ? ( ) : ( ; - /** * Variant of {@link tempDeletedFileIDs} for files that have just been * hidden. */ tempHiddenFileIDs: Set; - /*--< Transient UI state >--*/ + /*--< State that underlies transient UI state >--*/ - /** - * If visible, what should the (sticky) gallery bar show. - */ - barMode: GalleryBarMode | undefined; - /** - * The section / area, and the item within it, that the gallery is currently - * showing. - */ - focus: GalleryFocus | undefined; - activeCollectionID: number | undefined; - /** - * If the active collection ID is for a collection and not a - * pseudo-collection, this property will be set to the corresponding - * {@link Collection}. - * - * It is guaranteed that this will be one of the {@link collections} (when - * we are in the "albums" focus) or {@link hiddenCollections} (when we are - * in "hidden-albums" focus). - */ - activeCollection: Collection | undefined; /** * The currently selected person, if any. * * When present, it is used to derive the {@link activePerson} property of - * the {@link focus}. + * the {@link focus}. UI code should use the focus, this is meant as the + * underlying primitive state. */ - activePersonID: string | undefined; - - filteredData: EnteFile[]; - /** - * The currently selected person, if any. - * - * Whenever this is present, it is guaranteed to be one of the items from - * within {@link people}. - */ - activePerson: Person | undefined; - /** - * The list of people to show. - */ - people: Person[] | undefined; - /** - * `true` if we are in "search mode". - * - * We will always be in search mode if we are showing search results, but we - * also may be in search mode earlier on smaller screens, where the search - * input is only shown on entering search mode. See: [Note: "Search mode"]. - * - * That is, {@link isInSearchMode} may be true even when - * {@link searchResults} is undefined. - */ - isInSearchMode: boolean; + selectedPersonID: string | undefined; /** * List of files that match the selected search option. * @@ -266,6 +234,31 @@ export interface GalleryState { * set this value to the result. */ searchResults: EnteFile[] | undefined; + + /*--< Transient UI state >--*/ + + /** + * The section, and the item within it, that the gallery is currently + * showing. + * + * This can be temporarily overridden when we display search results. + */ + focus: GalleryFocus | undefined; + /** + * The files to show, uniqued and sorted appropriately. + */ + filteredFiles: EnteFile[] | undefined; + /** + * `true` if we are in "search mode". + * + * We will always be in search mode if we are showing search results, but we + * also may be in search mode earlier on smaller screens, where the search + * input is only shown on entering search mode. See: [Note: "Search mode"]. + * + * That is, {@link isInSearchMode} may be true even when + * {@link searchResults} is undefined. + */ + isInSearchMode: boolean; } export type GalleryAction = @@ -279,8 +272,8 @@ export type GalleryAction = trashedFiles: EnteFile[]; } | { - type: "set"; - filteredData: EnteFile[]; + type: "setFilteredFiles"; + filteredFiles: EnteFile[]; galleryPeopleState: | { activePerson: Person | undefined; people: Person[] } | undefined; From 9438247828e8dbf758545e4e95ad11bb240e9050 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 23 Oct 2024 08:26:39 +0530 Subject: [PATCH 12/15] wip checkpoint --- web/apps/photos/src/pages/gallery.tsx | 4 +- .../new/photos/components/gallery/reducer.ts | 250 ++++++++++-------- 2 files changed, 142 insertions(+), 112 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 742ce403bb..3b9ba24c25 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -901,7 +901,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, @@ -1027,7 +1027,7 @@ export default function Gallery() { > {barMode == "hidden-albums" ? ( dispatch({ type: "showAll" })} + onBack={() => dispatch({ type: "showAlbums" })} /> ) : (