Enum to type - wip

This commit is contained in:
Manav Rathi 2024-04-17 20:32:21 +05:30
parent 739c541f5d
commit ca5b98b8d2
No known key found for this signature in database
5 changed files with 65 additions and 64 deletions

View file

@ -8,7 +8,7 @@ import {
DEFAULT_IMPORT_SUGGESTION,
PICKED_UPLOAD_TYPE,
UPLOAD_STAGES,
UPLOAD_STRATEGY,
type CollectionMapping,
} from "constants/upload";
import { t } from "i18next";
import isElectron from "is-electron";
@ -391,7 +391,7 @@ export default function Uploader(props: Props) {
};
const uploadFilesToNewCollections = async (
strategy: UPLOAD_STRATEGY,
strategy: CollectionMapping,
collectionName?: string,
) => {
try {
@ -405,7 +405,7 @@ export default function Uploader(props: Props) {
string,
(File | ElectronFile)[]
>();
if (strategy === UPLOAD_STRATEGY.SINGLE_COLLECTION) {
if (strategy == "root") {
collectionNameToFilesMap.set(
collectionName,
toUploadFiles.current,
@ -605,10 +605,7 @@ export default function Uploader(props: Props) {
}
const uploadToSingleNewCollection = (collectionName: string) => {
uploadFilesToNewCollections(
UPLOAD_STRATEGY.SINGLE_COLLECTION,
collectionName,
);
uploadFilesToNewCollections("root", collectionName);
};
const showCollectionCreateModal = (suggestedName: string) => {
@ -647,7 +644,7 @@ export default function Uploader(props: Props) {
`upload pending files to collection - ${pendingDesktopUploadCollectionName.current}`,
);
uploadFilesToNewCollections(
UPLOAD_STRATEGY.SINGLE_COLLECTION,
"root",
pendingDesktopUploadCollectionName.current,
);
pendingDesktopUploadCollectionName.current = null;
@ -655,17 +652,13 @@ export default function Uploader(props: Props) {
log.info(
`pending upload - strategy - "multiple collections" `,
);
uploadFilesToNewCollections(
UPLOAD_STRATEGY.COLLECTION_PER_FOLDER,
);
uploadFilesToNewCollections("leaf");
}
return;
}
if (isElectron() && pickedUploadType === PICKED_UPLOAD_TYPE.ZIPS) {
log.info("uploading zip files");
uploadFilesToNewCollections(
UPLOAD_STRATEGY.COLLECTION_PER_FOLDER,
);
uploadFilesToNewCollections("leaf");
return;
}
if (isFirstUpload && !importSuggestion.rootFolderName) {
@ -784,7 +777,7 @@ export default function Uploader(props: Props) {
);
return;
}
uploadFilesToNewCollections(UPLOAD_STRATEGY.COLLECTION_PER_FOLDER);
uploadFilesToNewCollections("leaf");
};
return (

View file

@ -1,5 +1,6 @@
import { ensureElectron } from "@/next/electron";
import { FolderWatch } from "@/next/types/ipc";
import type { CollectionMapping, FolderWatch } from "@/next/types/ipc";
import { ensure } from "@/utils/ensure";
import {
FlexWrapper,
HorizontalFlex,
@ -26,7 +27,7 @@ import {
} from "@mui/material";
import { styled } from "@mui/material/styles";
import UploadStrategyChoiceModal from "components/Upload/UploadStrategyChoiceModal";
import { PICKED_UPLOAD_TYPE, UPLOAD_STRATEGY } from "constants/upload";
import { PICKED_UPLOAD_TYPE } from "constants/upload";
import { t } from "i18next";
import { AppContext } from "pages/_app";
import React, { useContext, useEffect, useState } from "react";
@ -44,11 +45,17 @@ interface WatchFolderProps {
* This is the screen that controls that "watch folder" feature in the app.
*/
export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
// The folders we are watching
const [watches, setWatches] = useState<FolderWatch[] | undefined>();
const [inputFolderPath, setInputFolderPath] = useState<
// Temporarily stash the folder path while we show a choice dialog to the
// user to select the collection mapping.
const [savedFolderPath, setSavedFolderPath] = useState<
string | undefined
>();
// True when we're showing the choice dialog to ask the user to set the
// collection mapping.
const [choiceModalOpen, setChoiceModalOpen] = useState(false);
const appContext = useContext(AppContext);
useEffect(() => {
@ -70,43 +77,34 @@ export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
const folder: any = folders[i];
const path = (folder.path as string).replace(/\\/g, "/");
if (await watcher.isFolder(path)) {
await addFolderForWatching(path);
await selectCollectionMappingAndAddWatch(path);
}
}
};
const addFolderForWatching = async (path: string) => {
setInputFolderPath(path);
const selectCollectionMappingAndAddWatch = async (path: string) => {
const files = await ensureElectron().getDirFiles(path);
const analysisResult = getImportSuggestion(
PICKED_UPLOAD_TYPE.FOLDERS,
files,
);
if (analysisResult.hasNestedFolders) {
setSavedFolderPath(path);
setChoiceModalOpen(true);
} else {
addWatchWithStrategy(UPLOAD_STRATEGY.SINGLE_COLLECTION, path);
addWatch(path, "root");
}
};
const addWatchWithStrategy = async (
uploadStrategy: UPLOAD_STRATEGY,
folderPath?: string,
) => {
folderPath = folderPath || inputFolderPath;
await watcher.addWatchMapping(
folderPath.substring(folderPath.lastIndexOf("/") + 1),
folderPath,
uploadStrategy,
);
setInputFolderPath("");
const addWatch = async (folderPath: string, mapping: CollectionMapping) => {
await watcher.addWatch(folderPath, mapping);
setWatches(await watcher.getWatchMappings());
};
const addWatch = async () => {
const addNewWatch = async () => {
const folderPath = await watcher.selectFolder();
if (folderPath) {
await addFolderForWatching(folderPath);
await selectCollectionMappingAndAddWatch(folderPath);
}
};
@ -117,14 +115,10 @@ export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
const closeChoiceModal = () => setChoiceModalOpen(false);
const uploadToSingleCollection = () => {
const addWatchWithMapping = (mapping: CollectionMapping) => {
closeChoiceModal();
addWatchWithStrategy(UPLOAD_STRATEGY.SINGLE_COLLECTION);
};
const uploadToMultipleCollection = () => {
closeChoiceModal();
addWatchWithStrategy(UPLOAD_STRATEGY.COLLECTION_PER_FOLDER);
setSavedFolderPath(undefined);
addWatch(ensure(savedFolderPath), mapping);
};
return (
@ -143,7 +137,7 @@ export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
<DialogContent sx={{ flex: 1 }}>
<Stack spacing={1} p={1.5} height={"100%"}>
<WatchList {...{ watches, removeWatch }} />
<Button fullWidth color="accent" onClick={addWatch}>
<Button fullWidth color="accent" onClick={addNewWatch}>
<span>+</span>
<span
style={{
@ -158,8 +152,8 @@ export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
<UploadStrategyChoiceModal
open={choiceModalOpen}
onClose={closeChoiceModal}
uploadToSingleCollection={uploadToSingleCollection}
uploadToMultipleCollection={uploadToMultipleCollection}
uploadToSingleCollection={() => addWatchWithMapping("root")}
uploadToMultipleCollection={() => addWatchWithMapping("parent")}
/>
</>
);
@ -269,7 +263,7 @@ const WatchEntry: React.FC<WatchEntryProps> = ({ watch, removeWatch }) => {
return (
<SpaceBetweenFlex>
<HorizontalFlex>
{watch.uploadStrategy === UPLOAD_STRATEGY.SINGLE_COLLECTION ? (
{watch.uploadStrategy === "root" ? (
<Tooltip title={t("UPLOADED_TO_SINGLE_COLLECTION")}>
<FolderOpenIcon />
</Tooltip>

View file

@ -6,7 +6,7 @@
import { ensureElectron } from "@/next/electron";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
import type { FolderWatch } from "@/next/types/ipc";
import type { CollectionMapping, FolderWatch } from "@/next/types/ipc";
import { UPLOAD_RESULT, UPLOAD_STRATEGY } from "constants/upload";
import debounce from "debounce";
import uploadManager from "services/upload/uploadManager";
@ -140,21 +140,22 @@ class WatchFolderService {
);
}
async addWatchMapping(
rootFolderName: string,
folderPath: string,
uploadStrategy: UPLOAD_STRATEGY,
) {
try {
await ensureElectron().addWatchMapping(
rootFolderName,
folderPath,
uploadStrategy,
);
this.syncWithDisk();
} catch (e) {
log.error("error while adding watch mapping", e);
}
/**
* Add a new folder watch for the given root {@link folderPath}
*
* @param mapping The {@link CollectionMapping} to use to decide which
* collection do files belonging to nested directories go to.
*/
async addWatch(folderPath: string, mapping: CollectionMapping) {
const rootFolderName = folderPath.substring(
folderPath.lastIndexOf("/") + 1,
);
await ensureElectron().addWatchMapping(
rootFolderName,
folderPath,
mapping,
);
this.syncWithDisk();
}
/**

View file

@ -377,8 +377,8 @@ export interface Electron {
* A top level folder that was selected by the user for watching.
*
* The user can set up multiple such watches. Each of these can in turn be
* syncing multiple on disk folders to one or more (dependening on the
* {@link uploadStrategy}) Ente albums.
* syncing multiple on disk folders to one or more Ente collections (depending
* on the value of {@link collectionMapping}).
*
* This type is passed across the IPC boundary. It is persisted on the Node.js
* side.
@ -391,6 +391,12 @@ export interface FolderWatch {
ignoredFiles: string[];
}
export type CollectionMapping =
/** Map everything to a single collection corresponding to the root directory */
| "root"
/** Map each file to a collection named after its parent directory */
| "parent";
/**
* An on-disk file that was synced as part of a folder watch.
*/

View file

@ -0,0 +1,7 @@
/**
* Throw an exception if the given value is undefined.
*/
export const ensure = <T>(v: T | undefined): T => {
if (v === undefined) throw new Error("Required value was not found");
return v;
};