Skip to content

Commit

Permalink
feat(settings): allow importing videos data from a json file
Browse files Browse the repository at this point in the history
  • Loading branch information
AXeL-dev committed Sep 9, 2022
1 parent 7128969 commit 2a61b05
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ import {
import { useAppDispatch } from 'store';
import { setVideos } from 'store/reducers/videos';
import { nanoid } from '@reduxjs/toolkit';
import { Alert } from 'ui/components/shared';
import ReactDOM from 'react-dom';

interface IClearVideosDataProps {}

export const id = nanoid();
export const icon = <DeleteIcon />;
export const label = 'Clear saved videos data';
export const label = 'Clear videos data';
export const color = 'primary';

function ClearVideosData(props: IClearVideosDataProps) {
const [openInfoAlert, setOpenInfoAlert] = useState(false);
const [confirmationDialogProps, setConfirmationDialogProps] =
useState<ConfirmationDialogProps>({
open: false,
Expand All @@ -29,11 +32,12 @@ function ClearVideosData(props: IClearVideosDataProps) {
const handleClick = () => {
setConfirmationDialogProps({
open: true,
title: 'Clear saved videos data',
title: 'Clear videos data',
text: 'Are you sure that you want to clear all saved videos data?',
onClose: (confirmed) => {
if (confirmed) {
dispatch(setVideos({ list: [] }));
setOpenInfoAlert(true);
}
setConfirmationDialogProps((state) => ({
...state,
Expand All @@ -54,6 +58,18 @@ function ClearVideosData(props: IClearVideosDataProps) {
{label}
</Button>
<ConfirmationDialog {...confirmationDialogProps} />
{ReactDOM.createPortal(
<Alert
open={openInfoAlert}
severity="info"
closable
syncOpen
onClose={() => setOpenInfoAlert(false)}
>
All videos data has been cleared!
</Alert>,
document.getElementById('layout-content-portal')!,
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface IExportVideosDataProps {

export const id = nanoid();
export const icon = <FileDownloadIcon />;
export const label = 'Export saved videos data';
export const label = 'Export videos data';
export const color = 'secondary';

function ExportVideosData(props: IExportVideosDataProps) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState, useRef, ChangeEvent, MouseEvent } from 'react';
import { Button } from '@mui/material';
import FileUploadIcon from '@mui/icons-material/FileUpload';
import { Nullable } from 'types';
import { readFile } from 'helpers/file';
import { nanoid } from '@reduxjs/toolkit';
import { useAppDispatch } from 'store';
import { setVideos } from 'store/reducers/videos';
import { Alert } from 'ui/components/shared';
import ReactDOM from 'react-dom';

interface IImportVideosDataProps {}

export const id = nanoid();
export const icon = <FileUploadIcon />;
export const label = 'Import videos data';
export const color = 'secondary';

function ImportVideosData(props: IImportVideosDataProps) {
const [openSuccessAlert, setOpenSuccessAlert] = useState(false);
const fileInputRef = useRef<Nullable<HTMLInputElement>>(null);
const dispatch = useAppDispatch();

const importVideos = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) {
return;
}
try {
readFile(file).then((content) => {
const videos = JSON.parse(content as string);
dispatch(setVideos({ list: videos }));
setOpenSuccessAlert(true);
});
} catch (e) {
console.error(e);
}
};

return (
<>
<Button
variant="contained"
color={color}
startIcon={icon}
sx={{ textTransform: 'none' }}
onClick={() => {
fileInputRef.current?.click();
}}
>
{label}
</Button>
<input
type="file"
ref={fileInputRef}
style={{
display: 'none',
visibility: 'hidden',
overflow: 'hidden',
width: 0,
height: 0,
}}
accept=".json"
onClick={(event: MouseEvent<HTMLInputElement>) => {
event.currentTarget.value = '';
}}
onChange={importVideos}
/>
{ReactDOM.createPortal(
<Alert
open={openSuccessAlert}
severity="success"
closable
syncOpen
onClose={() => setOpenSuccessAlert(false)}
>
Videos imported successfully!
</Alert>,
document.getElementById('layout-content-portal')!,
)}
</>
);
}

export default ImportVideosData;
9 changes: 9 additions & 0 deletions src/ui/components/pages/Settings/SavedVideosOptions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import ClearVideosData, * as clearVideosOption from './ClearVideosData';
import ExportVideosData, * as exportVideosOption from './ExportVideosData';
import ImportVideosData, * as importVideosOption from './ImportVideosData';
import { StyledMenuList } from 'ui/components/shared/StyledMenu/StyledMenuList';
import { VideoCache } from 'types';

Expand All @@ -26,6 +27,12 @@ const options = [
label: exportVideosOption.label,
color: exportVideosOption.color,
},
{
id: importVideosOption.id,
icon: importVideosOption.icon,
label: importVideosOption.label,
color: importVideosOption.color,
},
{
id: clearVideosOption.id,
icon: clearVideosOption.icon,
Expand Down Expand Up @@ -70,6 +77,8 @@ function SavedVideosOptions(props: ISavedVideosOptionsProps) {
return <ClearVideosData />;
case exportVideosOption.id:
return <ExportVideosData videos={videos} />;
case importVideosOption.id:
return <ImportVideosData />;
default:
return null;
}
Expand Down
12 changes: 5 additions & 7 deletions src/ui/components/pages/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,11 @@ export function Settings(props: SettingsProps) {
}}
type={SettingType.Secret}
/>
{savedVideosSize > 0 ? (
<CustomField
label="Saved videos data"
description={`Estimated size: ${formatByteSize(savedVideosSize)}`}
render={() => <SavedVideosOptions videos={videos} />}
/>
) : null}
<CustomField
label="Saved videos data"
description={`Estimated size: ${formatByteSize(savedVideosSize)}`}
render={() => <SavedVideosOptions videos={videos} />}
/>
</Stack>
</Layout>
);
Expand Down
1 change: 1 addition & 0 deletions src/ui/components/shared/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function Layout(props: LayoutProps) {
<Box
sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', ...sx }}
>
<div id="layout-content-portal"></div>
{children}
</Box>
</Box>
Expand Down

0 comments on commit 2a61b05

Please sign in to comment.