diff --git a/web/apps/photos/src/components/Upload/UploadStrategyChoiceModal.tsx b/web/apps/photos/src/components/Upload/CollectionMappingChoiceModal.tsx similarity index 71% rename from web/apps/photos/src/components/Upload/UploadStrategyChoiceModal.tsx rename to web/apps/photos/src/components/Upload/CollectionMappingChoiceModal.tsx index 4e773a3a82..c358a2d1d5 100644 --- a/web/apps/photos/src/components/Upload/UploadStrategyChoiceModal.tsx +++ b/web/apps/photos/src/components/Upload/CollectionMappingChoiceModal.tsx @@ -1,3 +1,4 @@ +import type { CollectionMapping } from "@/next/types/ipc"; import { CenteredFlex, SpaceBetweenFlex, @@ -8,23 +9,19 @@ import DialogTitleWithCloseButton, { import { Button, Dialog, DialogContent, Typography } from "@mui/material"; import { t } from "i18next"; -interface Props { - uploadToMultipleCollection: () => void; +interface CollectionMappingChoiceModalProps { open: boolean; onClose: () => void; - uploadToSingleCollection: () => void; + didSelect: (mapping: CollectionMapping) => void; } -function UploadStrategyChoiceModal({ - uploadToMultipleCollection, - uploadToSingleCollection, - ...props -}: Props) { - const handleClose = dialogCloseHandler({ - onClose: props.onClose, - }); + +export const CollectionMappingChoiceModal: React.FC< + CollectionMappingChoiceModalProps +> = ({ open, onClose, didSelect }) => { + const handleClose = dialogCloseHandler({ onClose }); return ( - + {t("MULTI_FOLDER_UPLOAD")} @@ -39,8 +36,8 @@ function UploadStrategyChoiceModal({ size="medium" color="accent" onClick={() => { - props.onClose(); - uploadToSingleCollection(); + onClose(); + didSelect("root"); }} > {t("UPLOAD_STRATEGY_SINGLE_COLLECTION")} @@ -52,8 +49,8 @@ function UploadStrategyChoiceModal({ size="medium" color="accent" onClick={() => { - props.onClose(); - uploadToMultipleCollection(); + onClose(); + didSelect("parent"); }} > {t("UPLOAD_STRATEGY_COLLECTION_PER_FOLDER")} @@ -62,5 +59,4 @@ function UploadStrategyChoiceModal({ ); -} -export default UploadStrategyChoiceModal; +}; diff --git a/web/apps/photos/src/components/Upload/Uploader.tsx b/web/apps/photos/src/components/Upload/Uploader.tsx index 20f6358a93..85623f183a 100644 --- a/web/apps/photos/src/components/Upload/Uploader.tsx +++ b/web/apps/photos/src/components/Upload/Uploader.tsx @@ -58,8 +58,8 @@ import { groupFilesBasedOnParentFolder, } from "utils/upload"; import { SetCollectionNamerAttributes } from "../Collections/CollectionNamer"; +import { CollectionMappingChoiceModal } from "./CollectionMappingChoiceModal"; import UploadProgress from "./UploadProgress"; -import UploadStrategyChoiceModal from "./UploadStrategyChoiceModal"; import UploadTypeSelector from "./UploadTypeSelector"; const FIRST_ALBUM_NAME = "My First Album"; @@ -780,13 +780,23 @@ export default function Uploader(props: Props) { uploadFilesToNewCollections("leaf"); }; + const didSelectCollectionMapping = (mapping: CollectionMapping) => { + switch (mapping) { + case "root": + handleUploadToSingleCollection(); + break; + case "parent": + handleUploadToMultipleCollections(); + break; + } + }; + return ( <> - = ({ open, onClose }) => { - addWatchWithMapping("root")} - uploadToMultipleCollection={() => addWatchWithMapping("parent")} + didSelect={addWatchWithMapping} /> ); @@ -263,7 +262,7 @@ const WatchEntry: React.FC = ({ watch, removeWatch }) => { return ( - {watch.uploadStrategy === "root" ? ( + {watch.collectionMapping === "root" ? ( diff --git a/web/apps/photos/src/services/watch.ts b/web/apps/photos/src/services/watch.ts index 80fd777d20..c7bd04dedf 100644 --- a/web/apps/photos/src/services/watch.ts +++ b/web/apps/photos/src/services/watch.ts @@ -7,7 +7,7 @@ import { ensureElectron } from "@/next/electron"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; import type { CollectionMapping, FolderWatch } from "@/next/types/ipc"; -import { UPLOAD_RESULT, UPLOAD_STRATEGY } from "constants/upload"; +import { UPLOAD_RESULT } from "constants/upload"; import debounce from "debounce"; import uploadManager from "services/upload/uploadManager"; import { Collection } from "types/collection"; @@ -202,7 +202,7 @@ class WatchFolderService { throw Error("no Mapping found for event"); } log.info( - `mapping for event rootFolder: ${mapping.rootFolderName} folderPath: ${mapping.folderPath} uploadStrategy: ${mapping.uploadStrategy} syncedFilesCount: ${mapping.syncedFiles.length} ignoredFilesCount ${mapping.ignoredFiles.length}`, + `mapping for event rootFolder: ${mapping.rootFolderName} folderPath: ${mapping.folderPath} colelctionMapping: ${mapping.collectionMapping} syncedFilesCount: ${mapping.syncedFiles.length} ignoredFilesCount ${mapping.ignoredFiles.length}`, ); if (event.type === "upload") { event.files = getValidFilesToUpload(event.files, mapping); @@ -740,9 +740,9 @@ const isSyncedOrIgnoredPath = (path: string, watch: FolderWatch) => watch.syncedFiles.find((f) => f.path === path); const collectionNameForPath = (filePath: string, watch: FolderWatch) => - watch.uploadStrategy === UPLOAD_STRATEGY.COLLECTION_PER_FOLDER - ? parentDirectoryName(filePath) - : watch.rootFolderName; + watch.collectionMapping == "root" + ? watch.rootFolderName + : parentDirectoryName(filePath); const parentDirectoryName = (filePath: string) => { const components = filePath.split("/"); diff --git a/web/packages/next/types/ipc.ts b/web/packages/next/types/ipc.ts index 887e8c1f27..85dcc870e0 100644 --- a/web/packages/next/types/ipc.ts +++ b/web/packages/next/types/ipc.ts @@ -385,12 +385,21 @@ export interface Electron { */ export interface FolderWatch { rootFolderName: string; - uploadStrategy: number; + /** + * Specify if nested files should all be mapped to the same single root + * collection, or if there should be a collection per directory that has + * files. @see {@link CollectionMapping}. + */ + collectionMapping: CollectionMapping; folderPath: string; syncedFiles: FolderWatchSyncedFile[]; ignoredFiles: string[]; } +/** + * The ways in which we can map nested files to collections when uploading or + * watching directories from the user's local file system. + */ export type CollectionMapping = /** Map everything to a single collection corresponding to the root directory */ | "root"