ente/src/components/ExportModal.tsx

198 lines
7 KiB
TypeScript
Raw Normal View History

2021-07-07 05:31:48 +00:00
import React, { useEffect, useState } from 'react';
2021-07-07 09:20:59 +00:00
import { Button } from 'react-bootstrap';
2021-07-07 05:31:48 +00:00
import exportService from 'services/exportService';
2021-07-08 05:44:54 +00:00
import styled from 'styled-components';
2021-07-07 05:31:48 +00:00
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
2021-07-07 09:20:59 +00:00
import constants from 'utils/strings/constants';
import { Label, Row, Value } from './Container';
2021-07-06 11:23:13 +00:00
import ExportFinished from './ExportFinished';
2021-07-06 09:20:05 +00:00
import ExportInit from './ExportInit';
import ExportInProgress from './ExportInProgress';
2021-07-07 09:20:59 +00:00
import FolderIcon from './icons/FolderIcon';
import InProgressIcon from './icons/InProgressIcon';
import MessageDialog from './MessageDialog';
2021-07-06 09:20:05 +00:00
2021-07-08 05:44:54 +00:00
const FolderIconWrapper = styled.div`
width: 15%;
margin-left: 10px;
cursor: pointer;
padding: 3px;
border: 1px solid #444;
&:hover{
background-color:#444;
}
`;
2021-07-08 06:42:28 +00:00
export enum ExportStage {
2021-07-06 09:20:05 +00:00
INIT,
INPROGRESS,
2021-07-07 07:45:55 +00:00
PAUSED,
2021-07-06 09:20:05 +00:00
FINISHED
}
2021-07-07 05:31:48 +00:00
interface Props {
show: boolean
onHide: () => void
2021-07-07 07:45:55 +00:00
usage: string
}
export interface ExportStats {
current: number;
total: number;
failed: number;
2021-07-07 05:31:48 +00:00
}
export default function ExportModal(props: Props) {
2021-07-08 06:42:28 +00:00
const [exportStage, setExportStage] = useState(ExportStage.INIT);
2021-07-07 05:31:48 +00:00
const [exportFolder, setExportFolder] = useState(null);
const [exportSize, setExportSize] = useState(null);
2021-07-07 07:45:55 +00:00
const [exportStats, setExportStats] = useState<ExportStats>({ current: 0, total: 0, failed: 0 });
const [lastExportTime, setLastExportTime] = useState(0);
2021-07-07 09:20:59 +00:00
2021-07-07 05:31:48 +00:00
useEffect(() => {
const exportInfo = getData(LS_KEYS.EXPORT);
2021-07-08 06:42:28 +00:00
exportInfo?.state && setExportStage(exportInfo.state);
2021-07-07 05:31:48 +00:00
exportInfo?.folder && setExportFolder(exportInfo.folder);
2021-07-07 07:45:55 +00:00
exportInfo?.time && setLastExportTime(exportInfo.time);
2021-07-07 05:31:48 +00:00
setExportSize(props.usage);
2021-07-09 03:35:33 +00:00
exportService.ElectronAPIs.registerStopExportListener(stopExport);
exportService.ElectronAPIs.registerPauseExportListener(pauseExport);
exportService.ElectronAPIs.registerStartExportListener(startExport);
2021-07-07 05:31:48 +00:00
}, []);
2021-07-07 07:45:55 +00:00
useEffect(() => {
2021-07-07 09:20:59 +00:00
if (exportStats.total !== 0 && exportStats.current === exportStats.total) {
2021-07-08 06:42:28 +00:00
updateExportStage(ExportStage.FINISHED);
2021-07-07 07:45:55 +00:00
updateExportTime(Date.now());
}
}, [exportStats]);
2021-07-07 09:20:59 +00:00
useEffect(() => {
setExportSize(props.usage);
}, [props.usage]);
2021-07-07 05:31:48 +00:00
const updateExportFolder = (newFolder) => {
setExportFolder(newFolder);
setData(LS_KEYS.EXPORT, { ...getData(LS_KEYS.EXPORT), folder: newFolder });
};
2021-07-08 06:42:28 +00:00
const updateExportStage = (newState) => {
setExportStage(newState);
2021-07-07 07:45:55 +00:00
setData(LS_KEYS.EXPORT, { ...getData(LS_KEYS.EXPORT), state: newState });
};
const updateExportTime = (newTime) => {
setLastExportTime(newTime);
setData(LS_KEYS.EXPORT, { ...getData(LS_KEYS.EXPORT), time: newTime });
};
const startExport = async () => {
2021-07-09 03:35:33 +00:00
const exportFolder = getData(LS_KEYS.EXPORT)?.folder;
if (!exportFolder) {
const folderSelected = await selectExportDirectory();
if (!folderSelected) {
// no-op as select folder aborted
return;
}
}
2021-07-08 06:42:28 +00:00
updateExportStage(ExportStage.INPROGRESS);
2021-07-07 07:45:55 +00:00
setExportStats({ current: 0, total: 0, failed: 0 });
exportService.exportFiles(setExportStats);
2021-07-07 05:31:48 +00:00
};
2021-07-07 09:20:59 +00:00
const selectExportDirectory = async () => {
const newFolder = await exportService.selectExportDirectory();
if (newFolder) {
updateExportFolder(newFolder);
return true;
} else {
return false;
}
2021-07-07 09:20:59 +00:00
};
2021-07-09 03:35:33 +00:00
const stopExport = () => {
exportService.stopRunningExport();
const lastExportTime = getData(LS_KEYS.EXPORT)?.time;
2021-07-08 06:42:28 +00:00
if (!lastExportTime) {
updateExportStage(ExportStage.INIT);
} else {
updateExportStage(ExportStage.FINISHED);
}
};
const pauseExport = () => {
updateExportStage(ExportStage.PAUSED);
2021-07-09 03:35:33 +00:00
exportService.pauseRunningExport();
2021-07-08 06:42:28 +00:00
};
2021-07-07 09:20:59 +00:00
const ExportDynamicState = () => {
2021-07-08 06:42:28 +00:00
switch (exportStage) {
case ExportStage.INIT:
2021-07-07 09:20:59 +00:00
return (
<ExportInit {...props}
exportFolder={exportFolder}
exportSize={exportSize}
updateExportFolder={updateExportFolder}
startExport={startExport}
2021-07-07 09:20:59 +00:00
selectExportDirectory={selectExportDirectory}
/>
);
2021-07-08 06:42:28 +00:00
case ExportStage.INPROGRESS:
case ExportStage.PAUSED:
2021-07-07 09:20:59 +00:00
return (
<ExportInProgress {...props}
exportFolder={exportFolder}
exportSize={exportSize}
2021-07-08 06:42:28 +00:00
exportStage={exportStage}
2021-07-07 09:20:59 +00:00
exportStats={exportStats}
exportFiles={startExport}
2021-07-09 03:35:33 +00:00
cancelExport={stopExport}
2021-07-08 06:42:28 +00:00
pauseExport={pauseExport}
2021-07-07 09:20:59 +00:00
/>
);
2021-07-08 06:42:28 +00:00
case ExportStage.FINISHED:
2021-07-07 09:20:59 +00:00
return (
<ExportFinished
{...props}
exportFolder={exportFolder}
exportSize={exportSize}
updateExportFolder={updateExportFolder}
lastExportTime={lastExportTime}
exportStats={exportStats}
exportFiles={startExport}
/>
);
default: return (<></>);
}
};
return (
<MessageDialog
show={props.show}
onHide={props.onHide}
attributes={{
title: constants.EXPORT_DATA,
}}
>
<div style={{ borderBottom: '1px solid #444', marginBottom: '20px', padding: '0 5%' }}>
<Row>
<Label width="40%">{constants.DESTINATION}</Label>
<Value width="60%">
{!exportFolder ?
(<Button variant={'outline-success'} onClick={selectExportDirectory}>{constants.SELECT_FOLDER}</Button>) :
(<>
<span style={{ overflow: 'hidden', direction: 'rtl', height: '1.5rem', width: '90%', whiteSpace: 'nowrap' }}>
{exportFolder}
</span>
2021-07-08 05:44:54 +00:00
<FolderIconWrapper onClick={selectExportDirectory} >
2021-07-07 09:20:59 +00:00
<FolderIcon />
2021-07-08 05:44:54 +00:00
</FolderIconWrapper>
2021-07-07 09:20:59 +00:00
</>)
}
</Value>
</Row>
<Row>
<Label width="40%">{constants.TOTAL_EXPORT_SIZE} </Label><Value width="60%">{exportSize ? `${exportSize} GB` : <InProgressIcon />}</Value>
</Row>
</div>
<ExportDynamicState />
</MessageDialog >
);
2021-07-06 09:20:05 +00:00
}