Inline and spruce
This commit is contained in:
parent
8fbff7e3a3
commit
afec29d6e7
9 changed files with 368 additions and 379 deletions
|
@ -24,7 +24,7 @@ import {
|
|||
import { getAccountsURL } from "@ente/shared/network/api";
|
||||
import { THEME_COLOR } from "@ente/shared/themes/constants";
|
||||
import { EnteMenuItem } from "components/Menu/EnteMenuItem";
|
||||
import WatchFolder from "components/WatchFolder";
|
||||
import { WatchFolder } from "components/WatchFolder";
|
||||
import isElectron from "is-electron";
|
||||
import { getAccountsToken } from "services/userService";
|
||||
import { getDownloadAppMessage } from "utils/ui";
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
savePublicCollectionUploaderName,
|
||||
} from "services/publicCollectionService";
|
||||
import uploadManager from "services/upload/uploadManager";
|
||||
import watchFolderService from "services/watchFolder/watchFolderService";
|
||||
import watchFolderService from "services/watch";
|
||||
import { NotificationAttributes } from "types/Notification";
|
||||
import { Collection } from "types/collection";
|
||||
import {
|
||||
|
|
363
web/apps/photos/src/components/WatchFolder.tsx
Normal file
363
web/apps/photos/src/components/WatchFolder.tsx
Normal file
|
@ -0,0 +1,363 @@
|
|||
import {
|
||||
FlexWrapper,
|
||||
HorizontalFlex,
|
||||
SpaceBetweenFlex,
|
||||
VerticallyCentered,
|
||||
} from "@ente/shared/components/Container";
|
||||
import DialogTitleWithCloseButton from "@ente/shared/components/DialogBox/TitleWithCloseButton";
|
||||
import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
|
||||
import { OverflowMenuOption } from "@ente/shared/components/OverflowMenu/option";
|
||||
import CheckIcon from "@mui/icons-material/Check";
|
||||
import DoNotDisturbOutlinedIcon from "@mui/icons-material/DoNotDisturbOutlined";
|
||||
import FolderCopyOutlinedIcon from "@mui/icons-material/FolderCopyOutlined";
|
||||
import FolderOpenIcon from "@mui/icons-material/FolderOpen";
|
||||
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
Stack,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} 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 { t } from "i18next";
|
||||
import { AppContext } from "pages/_app";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import watchFolderService from "services/watch";
|
||||
import { WatchMapping } from "types/watchFolder";
|
||||
import { getImportSuggestion } from "utils/upload";
|
||||
|
||||
interface WatchFolderProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const WatchFolder: React.FC<WatchFolderProps> = ({ open, onClose }) => {
|
||||
const [mappings, setMappings] = useState<WatchMapping[]>([]);
|
||||
const [inputFolderPath, setInputFolderPath] = useState("");
|
||||
const [choiceModalOpen, setChoiceModalOpen] = useState(false);
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const electron = globalThis.electron;
|
||||
|
||||
useEffect(() => {
|
||||
if (!electron) return;
|
||||
watchFolderService.getWatchMappings().then((m) => setMappings(m));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
appContext.watchFolderFiles &&
|
||||
appContext.watchFolderFiles.length > 0
|
||||
) {
|
||||
handleFolderDrop(appContext.watchFolderFiles);
|
||||
appContext.setWatchFolderFiles(null);
|
||||
}
|
||||
}, [appContext.watchFolderFiles]);
|
||||
|
||||
const handleFolderDrop = async (folders: FileList) => {
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
const folder: any = folders[i];
|
||||
const path = (folder.path as string).replace(/\\/g, "/");
|
||||
if (await watchFolderService.isFolder(path)) {
|
||||
await addFolderForWatching(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const addFolderForWatching = async (path: string) => {
|
||||
if (!electron) return;
|
||||
|
||||
setInputFolderPath(path);
|
||||
const files = await electron.getDirFiles(path);
|
||||
const analysisResult = getImportSuggestion(
|
||||
PICKED_UPLOAD_TYPE.FOLDERS,
|
||||
files,
|
||||
);
|
||||
if (analysisResult.hasNestedFolders) {
|
||||
setChoiceModalOpen(true);
|
||||
} else {
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.SINGLE_COLLECTION, path);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddFolderClick = async () => {
|
||||
await handleFolderSelection();
|
||||
};
|
||||
|
||||
const handleFolderSelection = async () => {
|
||||
const folderPath = await watchFolderService.selectFolder();
|
||||
if (folderPath) {
|
||||
await addFolderForWatching(folderPath);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddWatchMapping = async (
|
||||
uploadStrategy: UPLOAD_STRATEGY,
|
||||
folderPath?: string,
|
||||
) => {
|
||||
folderPath = folderPath || inputFolderPath;
|
||||
await watchFolderService.addWatchMapping(
|
||||
folderPath.substring(folderPath.lastIndexOf("/") + 1),
|
||||
folderPath,
|
||||
uploadStrategy,
|
||||
);
|
||||
setInputFolderPath("");
|
||||
setMappings(await watchFolderService.getWatchMappings());
|
||||
};
|
||||
|
||||
const handleRemoveWatchMapping = async (mapping: WatchMapping) => {
|
||||
await watchFolderService.removeWatchMapping(mapping.folderPath);
|
||||
setMappings(await watchFolderService.getWatchMappings());
|
||||
};
|
||||
|
||||
const closeChoiceModal = () => setChoiceModalOpen(false);
|
||||
|
||||
const uploadToSingleCollection = () => {
|
||||
closeChoiceModal();
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.SINGLE_COLLECTION);
|
||||
};
|
||||
|
||||
const uploadToMultipleCollection = () => {
|
||||
closeChoiceModal();
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.COLLECTION_PER_FOLDER);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
PaperProps={{ sx: { height: "448px", maxWidth: "414px" } }}
|
||||
>
|
||||
<DialogTitleWithCloseButton
|
||||
onClose={onClose}
|
||||
sx={{ "&&&": { padding: "32px 16px 16px 24px" } }}
|
||||
>
|
||||
{t("WATCHED_FOLDERS")}
|
||||
</DialogTitleWithCloseButton>
|
||||
<DialogContent sx={{ flex: 1 }}>
|
||||
<Stack spacing={1} p={1.5} height={"100%"}>
|
||||
<MappingList
|
||||
mappings={mappings}
|
||||
handleRemoveWatchMapping={handleRemoveWatchMapping}
|
||||
/>
|
||||
<Button
|
||||
fullWidth
|
||||
color="accent"
|
||||
onClick={handleAddFolderClick}
|
||||
>
|
||||
<span>+</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: "8px",
|
||||
}}
|
||||
></span>
|
||||
{t("ADD_FOLDER")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<UploadStrategyChoiceModal
|
||||
open={choiceModalOpen}
|
||||
onClose={closeChoiceModal}
|
||||
uploadToSingleCollection={uploadToSingleCollection}
|
||||
uploadToMultipleCollection={uploadToMultipleCollection}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const MappingsContainer = styled(Box)(() => ({
|
||||
height: "278px",
|
||||
overflow: "auto",
|
||||
"&::-webkit-scrollbar": {
|
||||
width: "4px",
|
||||
},
|
||||
}));
|
||||
|
||||
const NoMappingsContainer = styled(VerticallyCentered)({
|
||||
textAlign: "left",
|
||||
alignItems: "flex-start",
|
||||
marginBottom: "32px",
|
||||
});
|
||||
|
||||
const EntryContainer = styled(Box)({
|
||||
marginLeft: "12px",
|
||||
marginRight: "6px",
|
||||
marginBottom: "12px",
|
||||
});
|
||||
|
||||
interface MappingListProps {
|
||||
mappings: WatchMapping[];
|
||||
handleRemoveWatchMapping: (value: WatchMapping) => void;
|
||||
}
|
||||
|
||||
const MappingList: React.FC<MappingListProps> = ({
|
||||
mappings,
|
||||
handleRemoveWatchMapping,
|
||||
}) => {
|
||||
return mappings.length === 0 ? (
|
||||
<NoMappingsContent />
|
||||
) : (
|
||||
<MappingsContainer>
|
||||
{mappings.map((mapping) => {
|
||||
return (
|
||||
<MappingEntry
|
||||
key={mapping.rootFolderName}
|
||||
mapping={mapping}
|
||||
handleRemoveMapping={handleRemoveWatchMapping}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</MappingsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const NoMappingsContent: React.FC = () => {
|
||||
return (
|
||||
<NoMappingsContainer>
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="large" fontWeight={"bold"}>
|
||||
{t("NO_FOLDERS_ADDED")}
|
||||
</Typography>
|
||||
<Typography py={0.5} variant={"small"} color="text.muted">
|
||||
{t("FOLDERS_AUTOMATICALLY_MONITORED")}
|
||||
</Typography>
|
||||
<Typography variant={"small"} color="text.muted">
|
||||
<FlexWrapper gap={1}>
|
||||
<CheckmarkIcon />
|
||||
{t("UPLOAD_NEW_FILES_TO_ENTE")}
|
||||
</FlexWrapper>
|
||||
</Typography>
|
||||
<Typography variant={"small"} color="text.muted">
|
||||
<FlexWrapper gap={1}>
|
||||
<CheckmarkIcon />
|
||||
{t("REMOVE_DELETED_FILES_FROM_ENTE")}
|
||||
</FlexWrapper>
|
||||
</Typography>
|
||||
</Stack>
|
||||
</NoMappingsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const CheckmarkIcon: React.FC = () => {
|
||||
return (
|
||||
<CheckIcon
|
||||
fontSize="small"
|
||||
sx={{
|
||||
display: "inline",
|
||||
fontSize: "15px",
|
||||
|
||||
color: (theme) => theme.palette.secondary.main,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface MappingEntryProps {
|
||||
mapping: WatchMapping;
|
||||
handleRemoveMapping: (mapping: WatchMapping) => void;
|
||||
}
|
||||
|
||||
const MappingEntry: React.FC<MappingEntryProps> = ({
|
||||
mapping,
|
||||
handleRemoveMapping,
|
||||
}) => {
|
||||
const appContext = React.useContext(AppContext);
|
||||
|
||||
const stopWatching = () => {
|
||||
handleRemoveMapping(mapping);
|
||||
};
|
||||
|
||||
const confirmStopWatching = () => {
|
||||
appContext.setDialogMessage({
|
||||
title: t("STOP_WATCHING_FOLDER"),
|
||||
content: t("STOP_WATCHING_DIALOG_MESSAGE"),
|
||||
close: {
|
||||
text: t("CANCEL"),
|
||||
variant: "secondary",
|
||||
},
|
||||
proceed: {
|
||||
action: stopWatching,
|
||||
text: t("YES_STOP"),
|
||||
variant: "critical",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<SpaceBetweenFlex>
|
||||
<HorizontalFlex>
|
||||
{mapping &&
|
||||
mapping.uploadStrategy === UPLOAD_STRATEGY.SINGLE_COLLECTION ? (
|
||||
<Tooltip title={t("UPLOADED_TO_SINGLE_COLLECTION")}>
|
||||
<FolderOpenIcon />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={t("UPLOADED_TO_SEPARATE_COLLECTIONS")}>
|
||||
<FolderCopyOutlinedIcon />
|
||||
</Tooltip>
|
||||
)}
|
||||
<EntryContainer>
|
||||
<EntryHeading mapping={mapping} />
|
||||
<Typography color="text.muted" variant="small">
|
||||
{mapping.folderPath}
|
||||
</Typography>
|
||||
</EntryContainer>
|
||||
</HorizontalFlex>
|
||||
<MappingEntryOptions confirmStopWatching={confirmStopWatching} />
|
||||
</SpaceBetweenFlex>
|
||||
);
|
||||
};
|
||||
|
||||
interface EntryHeadingProps {
|
||||
mapping: WatchMapping;
|
||||
}
|
||||
|
||||
const EntryHeading: React.FC<EntryHeadingProps> = ({ mapping }) => {
|
||||
const appContext = useContext(AppContext);
|
||||
return (
|
||||
<FlexWrapper gap={1}>
|
||||
<Typography>{mapping.rootFolderName}</Typography>
|
||||
{appContext.isFolderSyncRunning &&
|
||||
watchFolderService.isMappingSyncInProgress(mapping) && (
|
||||
<CircularProgress size={12} />
|
||||
)}
|
||||
</FlexWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
interface MappingEntryOptionsProps {
|
||||
confirmStopWatching: () => void;
|
||||
}
|
||||
|
||||
const MappingEntryOptions: React.FC<MappingEntryOptionsProps> = ({
|
||||
confirmStopWatching,
|
||||
}) => {
|
||||
return (
|
||||
<OverflowMenu
|
||||
menuPaperProps={{
|
||||
sx: {
|
||||
backgroundColor: (theme) =>
|
||||
theme.colors.background.elevated2,
|
||||
},
|
||||
}}
|
||||
ariaControls={"watch-mapping-option"}
|
||||
triggerButtonIcon={<MoreHorizIcon />}
|
||||
>
|
||||
<OverflowMenuOption
|
||||
color="critical"
|
||||
onClick={confirmStopWatching}
|
||||
startIcon={<DoNotDisturbOutlinedIcon />}
|
||||
>
|
||||
{t("STOP_WATCHING")}
|
||||
</OverflowMenuOption>
|
||||
</OverflowMenu>
|
||||
);
|
||||
};
|
|
@ -1,152 +0,0 @@
|
|||
import DialogTitleWithCloseButton from "@ente/shared/components/DialogBox/TitleWithCloseButton";
|
||||
import { Button, Dialog, DialogContent, Stack } from "@mui/material";
|
||||
import UploadStrategyChoiceModal from "components/Upload/UploadStrategyChoiceModal";
|
||||
import { PICKED_UPLOAD_TYPE, UPLOAD_STRATEGY } from "constants/upload";
|
||||
import { t } from "i18next";
|
||||
import { AppContext } from "pages/_app";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import watchFolderService from "services/watchFolder/watchFolderService";
|
||||
import { WatchMapping } from "types/watchFolder";
|
||||
import { getImportSuggestion } from "utils/upload";
|
||||
import { MappingList } from "./mappingList";
|
||||
|
||||
interface Iprops {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function WatchFolder({ open, onClose }: Iprops) {
|
||||
const [mappings, setMappings] = useState<WatchMapping[]>([]);
|
||||
const [inputFolderPath, setInputFolderPath] = useState("");
|
||||
const [choiceModalOpen, setChoiceModalOpen] = useState(false);
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const electron = globalThis.electron;
|
||||
|
||||
useEffect(() => {
|
||||
if (!electron) return;
|
||||
watchFolderService.getWatchMappings().then((m) => setMappings(m));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
appContext.watchFolderFiles &&
|
||||
appContext.watchFolderFiles.length > 0
|
||||
) {
|
||||
handleFolderDrop(appContext.watchFolderFiles);
|
||||
appContext.setWatchFolderFiles(null);
|
||||
}
|
||||
}, [appContext.watchFolderFiles]);
|
||||
|
||||
const handleFolderDrop = async (folders: FileList) => {
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
const folder: any = folders[i];
|
||||
const path = (folder.path as string).replace(/\\/g, "/");
|
||||
if (await watchFolderService.isFolder(path)) {
|
||||
await addFolderForWatching(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const addFolderForWatching = async (path: string) => {
|
||||
if (!electron) return;
|
||||
|
||||
setInputFolderPath(path);
|
||||
const files = await electron.getDirFiles(path);
|
||||
const analysisResult = getImportSuggestion(
|
||||
PICKED_UPLOAD_TYPE.FOLDERS,
|
||||
files,
|
||||
);
|
||||
if (analysisResult.hasNestedFolders) {
|
||||
setChoiceModalOpen(true);
|
||||
} else {
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.SINGLE_COLLECTION, path);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddFolderClick = async () => {
|
||||
await handleFolderSelection();
|
||||
};
|
||||
|
||||
const handleFolderSelection = async () => {
|
||||
const folderPath = await watchFolderService.selectFolder();
|
||||
if (folderPath) {
|
||||
await addFolderForWatching(folderPath);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddWatchMapping = async (
|
||||
uploadStrategy: UPLOAD_STRATEGY,
|
||||
folderPath?: string,
|
||||
) => {
|
||||
folderPath = folderPath || inputFolderPath;
|
||||
await watchFolderService.addWatchMapping(
|
||||
folderPath.substring(folderPath.lastIndexOf("/") + 1),
|
||||
folderPath,
|
||||
uploadStrategy,
|
||||
);
|
||||
setInputFolderPath("");
|
||||
setMappings(await watchFolderService.getWatchMappings());
|
||||
};
|
||||
|
||||
const handleRemoveWatchMapping = async (mapping: WatchMapping) => {
|
||||
await watchFolderService.removeWatchMapping(mapping.folderPath);
|
||||
setMappings(await watchFolderService.getWatchMappings());
|
||||
};
|
||||
|
||||
const closeChoiceModal = () => setChoiceModalOpen(false);
|
||||
|
||||
const uploadToSingleCollection = () => {
|
||||
closeChoiceModal();
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.SINGLE_COLLECTION);
|
||||
};
|
||||
|
||||
const uploadToMultipleCollection = () => {
|
||||
closeChoiceModal();
|
||||
handleAddWatchMapping(UPLOAD_STRATEGY.COLLECTION_PER_FOLDER);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
PaperProps={{ sx: { height: "448px", maxWidth: "414px" } }}
|
||||
>
|
||||
<DialogTitleWithCloseButton
|
||||
onClose={onClose}
|
||||
sx={{ "&&&": { padding: "32px 16px 16px 24px" } }}
|
||||
>
|
||||
{t("WATCHED_FOLDERS")}
|
||||
</DialogTitleWithCloseButton>
|
||||
<DialogContent sx={{ flex: 1 }}>
|
||||
<Stack spacing={1} p={1.5} height={"100%"}>
|
||||
<MappingList
|
||||
mappings={mappings}
|
||||
handleRemoveWatchMapping={handleRemoveWatchMapping}
|
||||
/>
|
||||
<Button
|
||||
fullWidth
|
||||
color="accent"
|
||||
onClick={handleAddFolderClick}
|
||||
>
|
||||
<span>+</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: "8px",
|
||||
}}
|
||||
></span>
|
||||
{t("ADD_FOLDER")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<UploadStrategyChoiceModal
|
||||
open={choiceModalOpen}
|
||||
onClose={closeChoiceModal}
|
||||
uploadToSingleCollection={uploadToSingleCollection}
|
||||
uploadToMultipleCollection={uploadToMultipleCollection}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
import {
|
||||
FlexWrapper,
|
||||
HorizontalFlex,
|
||||
SpaceBetweenFlex,
|
||||
} from "@ente/shared/components/Container";
|
||||
import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
|
||||
import { OverflowMenuOption } from "@ente/shared/components/OverflowMenu/option";
|
||||
import DoNotDisturbOutlinedIcon from "@mui/icons-material/DoNotDisturbOutlined";
|
||||
import FolderCopyOutlinedIcon from "@mui/icons-material/FolderCopyOutlined";
|
||||
import FolderOpenIcon from "@mui/icons-material/FolderOpen";
|
||||
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
|
||||
import { CircularProgress, Tooltip, Typography } from "@mui/material";
|
||||
import { UPLOAD_STRATEGY } from "constants/upload";
|
||||
import { t } from "i18next";
|
||||
import { AppContext } from "pages/_app";
|
||||
import React, { useContext } from "react";
|
||||
import watchFolderService from "services/watchFolder/watchFolderService";
|
||||
import { WatchMapping } from "types/watchFolder";
|
||||
import { EntryContainer } from "../styledComponents";
|
||||
import { EntryHeading } from "./entryHeading";
|
||||
import MappingEntryOptions from "./mappingEntryOptions";
|
||||
|
||||
interface MappingEntryProps {
|
||||
mapping: WatchMapping;
|
||||
handleRemoveMapping: (mapping: WatchMapping) => void;
|
||||
}
|
||||
|
||||
export function MappingEntry({
|
||||
mapping,
|
||||
handleRemoveMapping,
|
||||
}: MappingEntryProps) {
|
||||
const appContext = React.useContext(AppContext);
|
||||
|
||||
const stopWatching = () => {
|
||||
handleRemoveMapping(mapping);
|
||||
};
|
||||
|
||||
const confirmStopWatching = () => {
|
||||
appContext.setDialogMessage({
|
||||
title: t("STOP_WATCHING_FOLDER"),
|
||||
content: t("STOP_WATCHING_DIALOG_MESSAGE"),
|
||||
close: {
|
||||
text: t("CANCEL"),
|
||||
variant: "secondary",
|
||||
},
|
||||
proceed: {
|
||||
action: stopWatching,
|
||||
text: t("YES_STOP"),
|
||||
variant: "critical",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<SpaceBetweenFlex>
|
||||
<HorizontalFlex>
|
||||
{mapping &&
|
||||
mapping.uploadStrategy === UPLOAD_STRATEGY.SINGLE_COLLECTION ? (
|
||||
<Tooltip title={t("UPLOADED_TO_SINGLE_COLLECTION")}>
|
||||
<FolderOpenIcon />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={t("UPLOADED_TO_SEPARATE_COLLECTIONS")}>
|
||||
<FolderCopyOutlinedIcon />
|
||||
</Tooltip>
|
||||
)}
|
||||
<EntryContainer>
|
||||
<EntryHeading mapping={mapping} />
|
||||
<Typography color="text.muted" variant="small">
|
||||
{mapping.folderPath}
|
||||
</Typography>
|
||||
</EntryContainer>
|
||||
</HorizontalFlex>
|
||||
<MappingEntryOptions confirmStopWatching={confirmStopWatching} />
|
||||
</SpaceBetweenFlex>
|
||||
);
|
||||
}
|
||||
|
||||
interface EntryHeadingProps {
|
||||
mapping: WatchMapping;
|
||||
}
|
||||
|
||||
export function EntryHeading({ mapping }: EntryHeadingProps) {
|
||||
const appContext = useContext(AppContext);
|
||||
return (
|
||||
<FlexWrapper gap={1}>
|
||||
<Typography>{mapping.rootFolderName}</Typography>
|
||||
{appContext.isFolderSyncRunning &&
|
||||
watchFolderService.isMappingSyncInProgress(mapping) && (
|
||||
<CircularProgress size={12} />
|
||||
)}
|
||||
</FlexWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
interface MappingEntryOptionsProps {
|
||||
confirmStopWatching: () => void;
|
||||
}
|
||||
|
||||
export default function MappingEntryOptions({
|
||||
confirmStopWatching,
|
||||
}: MappingEntryOptionsProps) {
|
||||
return (
|
||||
<OverflowMenu
|
||||
menuPaperProps={{
|
||||
sx: {
|
||||
backgroundColor: (theme) =>
|
||||
theme.colors.background.elevated2,
|
||||
},
|
||||
}}
|
||||
ariaControls={"watch-mapping-option"}
|
||||
triggerButtonIcon={<MoreHorizIcon />}
|
||||
>
|
||||
<OverflowMenuOption
|
||||
color="critical"
|
||||
onClick={confirmStopWatching}
|
||||
startIcon={<DoNotDisturbOutlinedIcon />}
|
||||
>
|
||||
{t("STOP_WATCHING")}
|
||||
</OverflowMenuOption>
|
||||
</OverflowMenu>
|
||||
);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
import { FlexWrapper } from "@ente/shared/components/Container";
|
||||
import CheckIcon from "@mui/icons-material/Check";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { WatchMapping } from "types/watchFolder";
|
||||
import { NoMappingsContainer } from "../../styledComponents";
|
||||
import { MappingEntry } from "../mappingEntry";
|
||||
import { MappingsContainer } from "../styledComponents";
|
||||
import { NoMappingsContent } from "./noMappingsContent/noMappingsContent";
|
||||
|
||||
interface MappingListProps {
|
||||
mappings: WatchMapping[];
|
||||
handleRemoveWatchMapping: (value: WatchMapping) => void;
|
||||
}
|
||||
|
||||
export function MappingList({
|
||||
mappings,
|
||||
handleRemoveWatchMapping,
|
||||
}: MappingListProps) {
|
||||
return mappings.length === 0 ? (
|
||||
<NoMappingsContent />
|
||||
) : (
|
||||
<MappingsContainer>
|
||||
{mappings.map((mapping) => {
|
||||
return (
|
||||
<MappingEntry
|
||||
key={mapping.rootFolderName}
|
||||
mapping={mapping}
|
||||
handleRemoveMapping={handleRemoveWatchMapping}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</MappingsContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoMappingsContent() {
|
||||
return (
|
||||
<NoMappingsContainer>
|
||||
<Stack spacing={1}>
|
||||
<Typography variant="large" fontWeight={"bold"}>
|
||||
{t("NO_FOLDERS_ADDED")}
|
||||
</Typography>
|
||||
<Typography py={0.5} variant={"small"} color="text.muted">
|
||||
{t("FOLDERS_AUTOMATICALLY_MONITORED")}
|
||||
</Typography>
|
||||
<Typography variant={"small"} color="text.muted">
|
||||
<FlexWrapper gap={1}>
|
||||
<CheckmarkIcon />
|
||||
{t("UPLOAD_NEW_FILES_TO_ENTE")}
|
||||
</FlexWrapper>
|
||||
</Typography>
|
||||
<Typography variant={"small"} color="text.muted">
|
||||
<FlexWrapper gap={1}>
|
||||
<CheckmarkIcon />
|
||||
{t("REMOVE_DELETED_FILES_FROM_ENTE")}
|
||||
</FlexWrapper>
|
||||
</Typography>
|
||||
</Stack>
|
||||
</NoMappingsContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export function CheckmarkIcon() {
|
||||
return (
|
||||
<CheckIcon
|
||||
fontSize="small"
|
||||
sx={{
|
||||
display: "inline",
|
||||
fontSize: "15px",
|
||||
|
||||
color: (theme) => theme.palette.secondary.main,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
import { VerticallyCentered } from "@ente/shared/components/Container";
|
||||
import { Box } from "@mui/material";
|
||||
import { styled } from "@mui/material/styles";
|
||||
|
||||
export const MappingsContainer = styled(Box)(() => ({
|
||||
height: "278px",
|
||||
overflow: "auto",
|
||||
"&::-webkit-scrollbar": {
|
||||
width: "4px",
|
||||
},
|
||||
}));
|
||||
|
||||
export const NoMappingsContainer = styled(VerticallyCentered)({
|
||||
textAlign: "left",
|
||||
alignItems: "flex-start",
|
||||
marginBottom: "32px",
|
||||
});
|
||||
|
||||
export const EntryContainer = styled(Box)({
|
||||
marginLeft: "12px",
|
||||
marginRight: "6px",
|
||||
marginBottom: "12px",
|
||||
});
|
|
@ -14,7 +14,7 @@ import {
|
|||
getPublicCollectionUID,
|
||||
} from "services/publicCollectionService";
|
||||
import { getDisableCFUploadProxyFlag } from "services/userService";
|
||||
import watchFolderService from "services/watchFolder/watchFolderService";
|
||||
import watchFolderService from "services/watch";
|
||||
import { Collection } from "types/collection";
|
||||
import { EncryptedEnteFile, EnteFile } from "types/file";
|
||||
import { SetFiles } from "types/gallery";
|
||||
|
|
|
@ -13,8 +13,8 @@ import {
|
|||
} from "types/watchFolder";
|
||||
import { groupFilesBasedOnCollectionID } from "utils/file";
|
||||
import { isSystemFile } from "utils/upload";
|
||||
import { removeFromCollection } from "../collectionService";
|
||||
import { getLocalFiles } from "../fileService";
|
||||
import { removeFromCollection } from "./collectionService";
|
||||
import { getLocalFiles } from "./fileService";
|
||||
|
||||
class WatchFolderService {
|
||||
private eventQueue: EventQueueItem[] = [];
|
Loading…
Add table
Reference in a new issue