mirror of
https://github.com/anidl/multi-downloader-nx.git
synced 2026-03-11 17:45:30 +00:00
GUI update baseline
This commit is contained in:
parent
5417db41fd
commit
f0cf404c1d
18 changed files with 580 additions and 123 deletions
6
@types/messageHandler.d.ts
vendored
6
@types/messageHandler.d.ts
vendored
|
|
@ -40,7 +40,7 @@ export type QueueItem = {
|
||||||
q: number,
|
q: number,
|
||||||
dlVideoOnce: boolean,
|
dlVideoOnce: boolean,
|
||||||
dubLang: string[],
|
dubLang: string[],
|
||||||
image: string
|
image: string,
|
||||||
} & ResolveItemsData
|
} & ResolveItemsData
|
||||||
|
|
||||||
export type ResolveItemsData = {
|
export type ResolveItemsData = {
|
||||||
|
|
@ -106,7 +106,9 @@ export type FuniStreamData = { force?: 'Y'|'y'|'N'|'n'|'C'|'c', callbackMaker?:
|
||||||
forceMuxer: AvailableMuxer | undefined, simul: boolean, skipSubMux: boolean, nocleanup: boolean, override: string[], videoTitle: string,
|
forceMuxer: AvailableMuxer | undefined, simul: boolean, skipSubMux: boolean, nocleanup: boolean, override: string[], videoTitle: string,
|
||||||
ffmpegOptions: string[], mkvmergeOptions: string[], defaultAudio: LanguageItem, defaultSub: LanguageItem, ccTag: string }
|
ffmpegOptions: string[], mkvmergeOptions: string[], defaultAudio: LanguageItem, defaultSub: LanguageItem, ccTag: string }
|
||||||
export type FuniSubsData = { nosubs?: boolean, sub: boolean, dlsubs: string[], ccTag: string }
|
export type FuniSubsData = { nosubs?: boolean, sub: boolean, dlsubs: string[], ccTag: string }
|
||||||
export type DownloadData = { id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean, dlVideoOnce: boolean }
|
export type DownloadData = {
|
||||||
|
hslang?: string; id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean, dlVideoOnce: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type AuthResponse = ResponseBase<undefined>;
|
export type AuthResponse = ResponseBase<undefined>;
|
||||||
export type FuniSearchReponse = ResponseBase<FunimationSearch>;
|
export type FuniSearchReponse = ResponseBase<FunimationSearch>;
|
||||||
|
|
|
||||||
BIN
gui.diff
Normal file
BIN
gui.diff
Normal file
Binary file not shown.
BIN
gui/react/public/favicon.webp
Normal file
BIN
gui/react/public/favicon.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -1,6 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<title>Multi Downloader</title>
|
||||||
|
<link rel="icon" type="image/webp" href="favicon.webp">
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
|
|
|
||||||
BIN
gui/react/react.7z
Normal file
BIN
gui/react/react.7z
Normal file
Binary file not shown.
|
|
@ -13,15 +13,20 @@ const Layout: React.FC = () => {
|
||||||
|
|
||||||
const messageHandler = React.useContext(messageChannelContext);
|
const messageHandler = React.useContext(messageChannelContext);
|
||||||
|
|
||||||
return <Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
return <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center'}}>
|
||||||
<MenuBar />
|
<MenuBar />
|
||||||
<Box sx={{ height: 50, mb: 4, display: 'flex', gap: 1, mt: 3 }}>
|
<Box sx={{
|
||||||
|
height: 50,
|
||||||
|
width: '95rem',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
//backgroundColor: '#ffffff',
|
||||||
|
}}>
|
||||||
<LogoutButton />
|
<LogoutButton />
|
||||||
<AuthButton />
|
<AuthButton />
|
||||||
<Box sx={{ display: 'flex', gap: 1, height: 36 }}>
|
<Button variant="contained" startIcon={<Folder />} onClick={() => messageHandler?.openFolder('content')} sx={{ height: '37px' }}>Open Output Directory</Button>
|
||||||
<Button variant="contained" startIcon={<Folder />} onClick={() => messageHandler?.openFolder('content')}>Open Output Directory</Button>
|
<Button variant="contained" startIcon={<ClearAll />} onClick={() => messageHandler?.clearQueue() } sx={{ height: '37px' }}>Clear Queue</Button>
|
||||||
<Button variant="contained" startIcon={<ClearAll />} onClick={() => messageHandler?.clearQueue() }>Clear Queue</Button>
|
|
||||||
</Box>
|
|
||||||
<AddToQueue />
|
<AddToQueue />
|
||||||
<StartQueueButton />
|
<StartQueueButton />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ const makeTheme = (mode: 'dark'|'light') : Partial<Theme> => {
|
||||||
|
|
||||||
const Style: FCWithChildren = ({children}) => {
|
const Style: FCWithChildren = ({children}) => {
|
||||||
return <ThemeProvider theme={makeTheme('dark')}>
|
return <ThemeProvider theme={makeTheme('dark')}>
|
||||||
<Container maxWidth='xl'>
|
|
||||||
<Box sx={{ position: 'fixed', height: '100%', width: '100%', zIndex: -500, backgroundColor: 'rgb(0, 30, 60)', top: 0, left: 0 }}/>
|
<Box sx={{ position: 'fixed', height: '100%', width: '100%', zIndex: -500, backgroundColor: 'rgb(0, 30, 60)', top: 0, left: 0 }}/>
|
||||||
{children}
|
{children}
|
||||||
</Container>
|
|
||||||
</ThemeProvider>;
|
</ThemeProvider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Add } from '@mui/icons-material';
|
import { Add } from '@mui/icons-material';
|
||||||
import { Box, Button, Dialog, Divider } from '@mui/material';
|
import { Box, Button, Dialog, Divider, Typography } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DownloadSelector from './DownloadSelector/DownloadSelector';
|
import DownloadSelector from './DownloadSelector/DownloadSelector';
|
||||||
import EpisodeListing from './DownloadSelector/Listing/EpisodeListing';
|
import EpisodeListing from './DownloadSelector/Listing/EpisodeListing';
|
||||||
|
|
@ -10,14 +10,14 @@ const AddToQueue: React.FC = () => {
|
||||||
|
|
||||||
return <Box>
|
return <Box>
|
||||||
<EpisodeListing />
|
<EpisodeListing />
|
||||||
<Dialog open={isOpen} onClose={() => setOpen(false)} maxWidth='md'>
|
<Dialog open={isOpen} onClose={() => setOpen(false)} maxWidth='md' PaperProps={{ elevation:4 }}>
|
||||||
<Box sx={{ border: '2px solid white', p: 2 }}>
|
<Box>
|
||||||
<SearchBox />
|
<SearchBox />
|
||||||
<Divider variant='middle' className="divider-width" light sx={{ color: 'text.primary', fontSize: '1.2rem' }}>Options</Divider>
|
<Divider variant='middle'/>
|
||||||
<DownloadSelector onFinish={() => setOpen(false)} />
|
<DownloadSelector onFinish={() => setOpen(false)} />
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Button variant='contained' onClick={() => setOpen(true)}>
|
<Button variant='contained' onClick={() => setOpen(true)}>
|
||||||
<Add />
|
<Add />
|
||||||
Add to Queue
|
Add to Queue
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Button, TextField } from '@mui/material';
|
import { Box, Button, Divider, InputBase, Link, MenuItem, Select, TextField, Tooltip, Typography } from '@mui/material';
|
||||||
import useStore from '../../../hooks/useStore';
|
import useStore from '../../../hooks/useStore';
|
||||||
import MultiSelect from '../../reusable/MultiSelect';
|
import MultiSelect from '../../reusable/MultiSelect';
|
||||||
import { messageChannelContext } from '../../../provider/MessageChannel';
|
import { messageChannelContext } from '../../../provider/MessageChannel';
|
||||||
import LoadingButton from '@mui/lab/LoadingButton';
|
import LoadingButton from '@mui/lab/LoadingButton';
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
|
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
||||||
|
|
||||||
type DownloadSelectorProps = {
|
type DownloadSelectorProps = {
|
||||||
onFinish?: () => unknown
|
onFinish?: () => unknown
|
||||||
|
|
@ -78,14 +79,36 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
return <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
|
||||||
<Box sx={{ m: 2, gap: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', flexWrap: 'wrap' }}>
|
<Box sx={{display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: '5px',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
width: '50rem',
|
||||||
|
height: '21rem',
|
||||||
|
margin: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
//backgroundColor: '#ffffff30',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.7rem',
|
||||||
|
//backgroundColor: '#ff000030'
|
||||||
|
}}>
|
||||||
|
<Typography sx={{fontSize: '1.4rem'}}>
|
||||||
|
General Options
|
||||||
|
</Typography>
|
||||||
<TextField value={store.downloadOptions.id} required onChange={e => {
|
<TextField value={store.downloadOptions.id} required onChange={e => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'downloadOptions',
|
type: 'downloadOptions',
|
||||||
payload: { ...store.downloadOptions, id: e.target.value }
|
payload: { ...store.downloadOptions, id: e.target.value }
|
||||||
});
|
});
|
||||||
}} label='Item ID' />
|
}} label='Show ID'/>
|
||||||
<TextField type='number' value={store.downloadOptions.q} required onChange={e => {
|
<TextField type='number' value={store.downloadOptions.q} required onChange={e => {
|
||||||
const parsed = parseInt(e.target.value);
|
const parsed = parseInt(e.target.value);
|
||||||
if (isNaN(parsed) || parsed < 0 || parsed > 10)
|
if (isNaN(parsed) || parsed < 0 || parsed > 10)
|
||||||
|
|
@ -94,13 +117,77 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
|
||||||
type: 'downloadOptions',
|
type: 'downloadOptions',
|
||||||
payload: { ...store.downloadOptions, q: parsed }
|
payload: { ...store.downloadOptions, q: parsed }
|
||||||
});
|
});
|
||||||
}} label='Quality Level (0 for max)' />
|
}} label='Quality Level (0 for max)'/>
|
||||||
<TextField disabled={store.downloadOptions.all} value={store.downloadOptions.e} required onChange={e => {
|
<Box sx={{ display: 'flex', gap: '5px' }}>
|
||||||
dispatch({
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
|
||||||
type: 'downloadOptions',
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
|
||||||
payload: { ...store.downloadOptions, e: e.target.value }
|
</Box>
|
||||||
});
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, dlVideoOnce: !store.downloadOptions.dlVideoOnce } })} variant={store.downloadOptions.dlVideoOnce ? 'contained' : 'outlined'}>Skip Unnecessary</Button>
|
||||||
}} label='Episode Select' />
|
<Tooltip title={
|
||||||
|
<Typography>
|
||||||
|
Currently only supported on Hidive
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
arrow
|
||||||
|
placement='top'>
|
||||||
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, simul: !store.downloadOptions.simul } })} variant={store.downloadOptions.simul ? 'contained' : 'outlined'}>Download Simulcast ver.</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.7rem',
|
||||||
|
//backgroundColor: '#00000020'
|
||||||
|
}}>
|
||||||
|
<Typography sx={{fontSize: '1.4rem'}}>
|
||||||
|
Episode Options
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '1px'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
borderColor: '#595959',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '5px',
|
||||||
|
//backgroundColor: '#ff4567',
|
||||||
|
width: '15rem',
|
||||||
|
height: '3.5rem',
|
||||||
|
display: 'flex',
|
||||||
|
'&:hover' : {
|
||||||
|
borderColor: '#ffffff',
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
<InputBase sx={{
|
||||||
|
ml: 2,
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
disabled={store.downloadOptions.all} value={store.downloadOptions.e} required onChange={e => {
|
||||||
|
dispatch({
|
||||||
|
type: 'downloadOptions',
|
||||||
|
payload: { ...store.downloadOptions, e: e.target.value }
|
||||||
|
});
|
||||||
|
}} placeholder='Episode Select'/>
|
||||||
|
<Divider orientation='vertical'/>
|
||||||
|
<LoadingButton loading={loading} disableElevation disableFocusRipple disableRipple disableTouchRipple onClick={listEpisodes} variant='text' sx={{ textTransform: 'none'}}><Typography>List<br/>Episodes</Typography></LoadingButton>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, all: !store.downloadOptions.all } })} variant={store.downloadOptions.all ? 'contained' : 'outlined'}>Download All</Button>
|
||||||
|
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, but: !store.downloadOptions.but } })} variant={store.downloadOptions.but ? 'contained' : 'outlined'}>Download All but</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.7rem',
|
||||||
|
//backgroundColor: '#00ff0020'
|
||||||
|
}}>
|
||||||
|
<Typography sx={{fontSize: '1.4rem'}}>
|
||||||
|
Language Options
|
||||||
|
</Typography>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
title='Dub Languages'
|
title='Dub Languages'
|
||||||
values={availableDubs}
|
values={availableDubs}
|
||||||
|
|
@ -113,6 +200,7 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
|
||||||
}}
|
}}
|
||||||
allOption
|
allOption
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
title='Sub Languages'
|
title='Sub Languages'
|
||||||
values={availableSubs}
|
values={availableSubs}
|
||||||
|
|
@ -124,22 +212,105 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextField value={store.downloadOptions.fileName} onChange={e => {
|
<Tooltip title={
|
||||||
|
<Typography>
|
||||||
|
Comming Soon™
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
arrow placement='top'>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: '100%',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
borderColor: '#595959',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderRadius: '5px',
|
||||||
|
//backgroundColor: '#ff4567',
|
||||||
|
width: '15rem',
|
||||||
|
height: '3.5rem',
|
||||||
|
display: 'flex',
|
||||||
|
'&:hover' : {
|
||||||
|
borderColor: '#ffffff',
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
|
||||||
|
<Button sx={{ textTransform: 'none' }} variant='outlined' disabled={true}>Hardsub</Button>
|
||||||
|
<Divider orientation='vertical'/>
|
||||||
|
<Select sx={{
|
||||||
|
flex: 1
|
||||||
|
}}
|
||||||
|
title='Hardsub lang.'
|
||||||
|
placeholder='Hardsub lang.'
|
||||||
|
disabled={true}
|
||||||
|
value={store.downloadOptions.hslang}
|
||||||
|
onChange={(e) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'downloadOptions',
|
||||||
|
payload: { ...store.downloadOptions, hslang: (e.target.value as string) === '' ? undefined : e.target.value as string }
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem>Deutsch</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</Box>
|
||||||
|
<Tooltip title={
|
||||||
|
<Typography>
|
||||||
|
Burns the selected subtitle <b>PERMANENTLY</b> onto the video<br/>You can choose only <b>1</b> subtitle per video
|
||||||
|
</Typography>
|
||||||
|
} arrow placement='top'>
|
||||||
|
<InfoOutlinedIcon sx={{
|
||||||
|
transition: '100ms',
|
||||||
|
ml: '0.35rem',
|
||||||
|
mr: '0.65rem',
|
||||||
|
'&:hover' : {
|
||||||
|
color: '#ffffff30',
|
||||||
|
}
|
||||||
|
}} />
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginBottom: '20px'}}/>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: '100%',
|
||||||
|
gap: '15px'
|
||||||
|
}}>
|
||||||
|
<TextField value={store.downloadOptions.fileName} onChange={e => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'downloadOptions',
|
type: 'downloadOptions',
|
||||||
payload: { ...store.downloadOptions, fileName: e.target.value }
|
payload: { ...store.downloadOptions, fileName: e.target.value }
|
||||||
});
|
});
|
||||||
}} sx={{ width: '50%' }} label='Filename' />
|
}} sx={{ width: '87%' }} label='Filename Overwrite' />
|
||||||
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, all: !store.downloadOptions.all } })} variant={store.downloadOptions.all ? 'contained' : 'outlined'}>Download all</Button>
|
<Tooltip title={
|
||||||
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, but: !store.downloadOptions.but } })} variant={store.downloadOptions.but ? 'contained' : 'outlined'}>Download all but</Button>
|
<Typography>
|
||||||
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
|
Click here to see the documentation
|
||||||
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
|
</Typography>
|
||||||
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, dlVideoOnce: !store.downloadOptions.dlVideoOnce } })} variant={store.downloadOptions.dlVideoOnce ? 'contained' : 'outlined'}>Skip unnecessary Downloads</Button>
|
} arrow placement='top'>
|
||||||
</Box>
|
<Link href='https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md#filename-template' rel="noopener noreferrer" target="_blank">
|
||||||
<Box sx={{ gap: 2, flex: 0, m: 1, mb: 3, display: 'flex', justifyContent: 'center' }}>
|
<InfoOutlinedIcon sx={{
|
||||||
<LoadingButton loading={loading} onClick={listEpisodes} variant='contained'>List episodes</LoadingButton>
|
transition: '100ms',
|
||||||
<LoadingButton loading={loading} onClick={addToQueue} variant='contained'>Add to Queue</LoadingButton>
|
'&:hover' : {
|
||||||
|
color: '#ffffff30',
|
||||||
|
}
|
||||||
|
}} />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginTop: '10px'}}/>
|
||||||
|
|
||||||
|
<LoadingButton sx={{ margin: '15px', textTransform: 'none' }} loading={loading} onClick={addToQueue} variant='contained'>Add to Queue</LoadingButton>
|
||||||
|
|
||||||
</Box>;
|
</Box>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
.divider-width::before, .divider-width::after {
|
|
||||||
border-top: 3px solid white !important;
|
|
||||||
transform: translateY(40%) !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './MainFrame.css';
|
|
||||||
import Queue from './Queue/Queue';
|
import Queue from './Queue/Queue';
|
||||||
|
|
||||||
const MainFrame: React.FC = () => {
|
const MainFrame: React.FC = () => {
|
||||||
return <Box sx={{ marginLeft: 1 }}>
|
return <Box sx={{ }}>
|
||||||
<Queue />
|
<Queue />
|
||||||
</Box>;
|
</Box>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { Box, Button, CircularProgress, Divider, LinearProgress, Skeleton, Typography } from '@mui/material';
|
import { Badge, Box, Button, CircularProgress, Divider, IconButton, LinearProgress, Skeleton, Tooltip, Typography } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { messageChannelContext } from '../../../provider/MessageChannel';
|
import { messageChannelContext } from '../../../provider/MessageChannel';
|
||||||
import { queueContext } from '../../../provider/QueueProvider';
|
import { queueContext } from '../../../provider/QueueProvider';
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
|
||||||
import useDownloadManager from '../DownloadManager/DownloadManager';
|
import useDownloadManager from '../DownloadManager/DownloadManager';
|
||||||
|
|
||||||
|
|
@ -16,102 +17,384 @@ const Queue: React.FC = () => {
|
||||||
|
|
||||||
return data || queue.length > 0 ? <>
|
return data || queue.length > 0 ? <>
|
||||||
{data && <>
|
{data && <>
|
||||||
<Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
|
<Box sx={{
|
||||||
<img src={data.downloadInfo.image} height='auto' width='100%' alt="Thumbnail" />
|
display: 'flex',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
width: '100%',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
flexDirection: 'column',
|
||||||
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr max-content' }}>
|
alignItems: 'center',
|
||||||
<Typography variant='h5' color='text.primary'>
|
}}>
|
||||||
{data.downloadInfo.title}
|
<Box sx={{
|
||||||
</Typography>
|
marginTop: '2rem',
|
||||||
<Typography variant='h5' color='text.primary'>
|
marginBottom: '1rem',
|
||||||
Language: {data.downloadInfo.language.name}
|
height: '11rem',
|
||||||
</Typography>
|
width: '95rem',
|
||||||
</Box>
|
backgroundColor: '#282828',
|
||||||
<Typography variant='h6' color='text.primary'>
|
boxShadow: '0px 0px 50px #00000090',
|
||||||
|
borderRadius: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
transition: '250ms'
|
||||||
|
}}>
|
||||||
|
<img style={{
|
||||||
|
borderRadius: '5px',
|
||||||
|
margin: '5px',
|
||||||
|
boxShadow: '0px 0px 10px #00000090',
|
||||||
|
userSelect: 'none',
|
||||||
|
}}
|
||||||
|
src={data.downloadInfo.image} height='auto' width='auto' alt="Thumbnail" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
//backgroundColor: '#ff0000',
|
||||||
|
width: '70%',
|
||||||
|
marginLeft: '10px'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
}}>
|
||||||
{data.downloadInfo.parent.title}
|
{data.downloadInfo.parent.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.2rem',
|
||||||
|
}}>
|
||||||
|
{data.downloadInfo.title}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<LinearProgress variant='determinate' sx={{ height: '10px' }} value={(typeof data.progress.percent === 'string' ? parseInt(data.progress.percent) : data.progress.percent)} />
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
//backgroundColor: '#00ff00',
|
||||||
|
width: '30%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
}}>
|
||||||
|
Downloading: {data.downloadInfo.language.name}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
height: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
//backgroundColor: '#0000ff',
|
||||||
|
}}>
|
||||||
|
<LinearProgress variant='determinate'
|
||||||
|
sx={{
|
||||||
|
height: '20px',
|
||||||
|
width: '97.53%',
|
||||||
|
margin: '10px',
|
||||||
|
boxShadow: '0px 0px 10px #00000090',
|
||||||
|
borderRadius: '10px',
|
||||||
|
}} value={(typeof data.progress.percent === 'string' ? parseInt(data.progress.percent) : data.progress.percent)}
|
||||||
|
/>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="body1" color='text.primary'>
|
<Typography color='text.primary'
|
||||||
|
sx={{
|
||||||
|
fontSize: '1.3rem',
|
||||||
|
}}>
|
||||||
{data.progress.cur} / {(data.progress.total)} parts ({data.progress.percent}% | {formatTime(data.progress.time)} | {(data.progress.downloadSpeed / 1024 / 1024).toFixed(2)} MB/s | {(data.progress.bytes / 1024 / 1024).toFixed(2)}MB)
|
{data.progress.cur} / {(data.progress.total)} parts ({data.progress.percent}% | {formatTime(data.progress.time)} | {(data.progress.downloadSpeed / 1024 / 1024).toFixed(2)} MB/s | {(data.progress.bytes / 1024 / 1024).toFixed(2)}MB)
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
current && !data && <>
|
current && !data && <>
|
||||||
<Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
|
<Box sx={{
|
||||||
<img src={current.image} height='auto' width='100%' alt="Thumbnail" />
|
display: 'flex',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
width: '100%',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
flexDirection: 'column',
|
||||||
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr max-content' }}>
|
alignItems: 'center',
|
||||||
<Typography variant='h5' color='text.primary'>
|
}}>
|
||||||
{current.title}
|
<Box sx={{
|
||||||
</Typography>
|
marginTop: '2rem',
|
||||||
<Typography variant='h5' color='text.primary'>
|
marginBottom: '1rem',
|
||||||
Language: <CircularProgress variant="indeterminate" />
|
height: '13rem',
|
||||||
</Typography>
|
width: '93rem',
|
||||||
</Box>
|
backgroundColor: '#282828',
|
||||||
<Typography variant='h6' color='text.primary'>
|
boxShadow: '0px 0px 50px #00000090',
|
||||||
{current.parent.title}
|
borderRadius: '10px',
|
||||||
</Typography>
|
display: 'flex',
|
||||||
</Box>
|
transition: '250ms'
|
||||||
<LinearProgress variant='indeterminate' sx={{ height: '10px' }} />
|
}}>
|
||||||
<Box>
|
<img style={{
|
||||||
<Typography variant="body1" color='text.primary'>
|
borderRadius: '5px',
|
||||||
0 / ? parts (0% | X:XX | 0 MB/s | 0MB)
|
margin: '5px',
|
||||||
</Typography>
|
boxShadow: '0px 0px 10px #00000090',
|
||||||
</Box>
|
userSelect: 'none',
|
||||||
|
}}
|
||||||
|
src={current.image} height='auto' width='auto' alt="Thumbnail" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
//backgroundColor: '#ff0000',
|
||||||
|
width: '70%',
|
||||||
|
marginLeft: '10px'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
}}>
|
||||||
|
{current.parent.title}
|
||||||
|
</Typography>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.2rem',
|
||||||
|
}}>
|
||||||
|
{current.title}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
//backgroundColor: '#00ff00',
|
||||||
|
width: '30%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
}}>
|
||||||
|
Downloading:
|
||||||
|
</Typography>
|
||||||
|
<CircularProgress variant="indeterminate" sx={{
|
||||||
|
marginLeft: '2rem',
|
||||||
|
}}/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
height: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
//backgroundColor: '#0000ff',
|
||||||
|
}}>
|
||||||
|
<LinearProgress variant='indeterminate'
|
||||||
|
sx={{
|
||||||
|
height: '20px',
|
||||||
|
width: '97.53%',
|
||||||
|
margin: '10px',
|
||||||
|
boxShadow: '0px 0px 10px #00000090',
|
||||||
|
borderRadius: '10px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box>
|
||||||
|
<Typography color='text.primary'
|
||||||
|
sx={{
|
||||||
|
fontSize: '1.3rem',
|
||||||
|
}}>
|
||||||
|
0 / ? parts (0% | XX:XX | 0 MB/s | 0MB)
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
{queue.length && data && <Divider variant="fullWidth" />}
|
|
||||||
{queue.map((queueItem, index, { length }) => {
|
{queue.map((queueItem, index, { length }) => {
|
||||||
return <Box key={`queue_item_${index}`}>
|
return <Box key={`queue_item_${index}`} sx={{
|
||||||
<Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
|
display: 'flex',
|
||||||
<img src={queueItem.image} height='auto' width='100%' alt="Thumbnail" />
|
width: '100%',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
height: '12rem',
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
|
flexDirection: 'column',
|
||||||
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 200px' }}>
|
alignItems: 'center',
|
||||||
<Typography variant='h5' color='text.primary'>
|
}}>
|
||||||
{queueItem.title}
|
<Box sx={{
|
||||||
|
marginTop: '1.5rem',
|
||||||
|
marginBottom: '1.5rem',
|
||||||
|
height: '11rem',
|
||||||
|
width: '90rem',
|
||||||
|
backgroundColor: '#282828',
|
||||||
|
boxShadow: '0px 0px 10px #00000090',
|
||||||
|
borderRadius: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
}}>
|
||||||
|
<img style={{
|
||||||
|
borderRadius: '5px',
|
||||||
|
margin: '5px',
|
||||||
|
boxShadow: '0px 0px 5px #00000090',
|
||||||
|
userSelect: 'none',
|
||||||
|
}}
|
||||||
|
src={queueItem.image} height='auto' width='auto' alt="Thumbnail" />
|
||||||
|
<Box sx={{
|
||||||
|
margin: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
width: '30rem',
|
||||||
|
marginRight: '5px',
|
||||||
|
marginLeft: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
}}>
|
||||||
|
{queueItem.parent.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant='h5' color='text.primary'>
|
<Typography color='text.primary' sx={{
|
||||||
Languages: {queueItem.dubLang.join(', ')}
|
fontSize: '1.6rem',
|
||||||
|
marginTop: '-0.4rem',
|
||||||
|
marginBottom: '0.4rem',
|
||||||
|
}}>
|
||||||
|
S{queueItem.parent.season}E{queueItem.episode}
|
||||||
|
</Typography>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.2rem',
|
||||||
|
marginTop: '-0.4rem',
|
||||||
|
marginBottom: '0.4rem',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
}}>
|
||||||
|
{queueItem.title}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
width: '30rem',
|
||||||
|
marginRight: '5px',
|
||||||
|
marginLeft: '5px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
}}>
|
||||||
|
Dub(s): {queueItem.dubLang.join(', ')}
|
||||||
|
</Typography>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
}}>
|
||||||
|
Sub(s): {queueItem.dlsubs.join(', ')}
|
||||||
|
</Typography>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
|
||||||
|
}}>
|
||||||
|
Quality: {queueItem.q}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Typography variant='h6' color='text.primary'>
|
<Box sx={{
|
||||||
{queueItem.parent.title}
|
//backgroundColor: '#ffffff',
|
||||||
</Typography>
|
marginRight: '5px',
|
||||||
</Box>
|
marginLeft: '5px',
|
||||||
<Typography variant='body1' color='text.primary'>
|
}}>
|
||||||
S{queueItem.parent.season}E{queueItem.episode} <br />
|
<Tooltip title="Delete from queue" arrow placement='top'>
|
||||||
Quality: {queueItem.q}
|
<IconButton
|
||||||
</Typography>
|
onClick={() => {
|
||||||
<Button onClick={() => {
|
|
||||||
msg.removeFromQueue(index);
|
msg.removeFromQueue(index);
|
||||||
}} sx={{ position: 'relative', left: '50%', transform: 'translateX(-50%)', width: '60%' }} variant="outlined" color="warning">
|
}}
|
||||||
Remove from Queue
|
sx={{
|
||||||
</Button>
|
backgroundColor: '#ff573a25',
|
||||||
|
height: '40px',
|
||||||
|
width: '40px',
|
||||||
|
margin: '4rem',
|
||||||
|
transition: '250ms',
|
||||||
|
'&:hover' : {
|
||||||
|
backgroundColor: '#ff573a',
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{index < length - 1 && <Divider variant="fullWidth" />}
|
;
|
||||||
</Box>;
|
|
||||||
})}
|
})}
|
||||||
</> : <Box>
|
</> : <Box sx={{
|
||||||
<Typography color='text.primary' variant='h4'>
|
display: 'flex',
|
||||||
|
width: '100%',
|
||||||
|
height: '12rem',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}>
|
||||||
|
<Typography color='text.primary' sx={{
|
||||||
|
fontSize: '2rem',
|
||||||
|
margin: '10px'
|
||||||
|
}}>
|
||||||
Selected episodes will be shown here
|
Selected episodes will be shown here
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1 }}>
|
<Box sx={{
|
||||||
<Skeleton variant='rectangular' height={'100%'}/>
|
display: 'flex',
|
||||||
<Box sx={{ display: 'grid', gridTemplateRows: '33% 1fr', gap: 1 }}>
|
margin: '10px'
|
||||||
<Skeleton variant='text' height={'100%'} />
|
}}>
|
||||||
<Skeleton variant='text' height={'100%'} />
|
<Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}>
|
||||||
|
<Skeleton variant='text' height={'100%'} width={'30rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
|
<Skeleton variant='text' height={'100%'} width={'30rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
margin: '10px'
|
||||||
|
}}>
|
||||||
|
<Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}>
|
||||||
|
<Skeleton variant='text' height={'100%'} width={'30rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
|
<Skeleton variant='text' height={'100%'} width={'30rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>;
|
</Box>;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const MenuBar: React.FC = () => {
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|
||||||
return <Box sx={{ width: '100%', display: 'flex' }}>
|
return <Box sx={{ width: '95rem', display: 'flex', marginBottom: '1rem' }}>
|
||||||
<Button onClick={(e) => handleClick(e, 'settings')}>
|
<Button onClick={(e) => handleClick(e, 'settings')}>
|
||||||
Settings
|
Settings
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -108,7 +108,7 @@ const MenuBar: React.FC = () => {
|
||||||
Version: {store.version}
|
Version: {store.version}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Typography variant="h5" color="text.primary" component="div" align="center" sx={{flexGrow: 1}}>
|
<Typography variant="h5" color="text.primary" sx={{ alignSelf: 'center', textAlign: 'center', width: '100%'}}>
|
||||||
{transformService(store.service)}
|
{transformService(store.service)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>;
|
</Box>;
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,11 @@ const ServiceProvider: FCWithChildren = ({ children }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return service === undefined ?
|
return service === undefined ?
|
||||||
<Box>
|
<Box sx={{ justifyContent: 'center', alignItems: 'center', display: 'flex', flexDirection: 'column', height: '50rem'}}>
|
||||||
<Typography color="text.primary" variant='h3' sx={{ textAlign: 'center', mb: 5 }}>Please choose your service</Typography>
|
<Typography color="text.primary" variant='h3' sx={{ textAlign: 'center', mb: 5 }}>Please select your service</Typography>
|
||||||
<Box sx={{ display: 'flex', gap: 2, justifyContent: 'center' }}>
|
<Box sx={{ display: 'flex', gap: 2, justifyContent: 'center' }}>
|
||||||
<Button size='large' variant="contained" onClick={() => setService('funi')} startIcon={<Avatar src={'https://static.funimation.com/static/img/favicon.ico'} />}>Funimation</Button>
|
<Button size='large' variant="contained" onClick={() => setService('funi')} startIcon={<Avatar src={'https://static.funimation.com/static/img/favicon.ico'} />}>Funimation</Button>
|
||||||
<Divider orientation='vertical' flexItem />
|
|
||||||
<Button size='large' variant="contained" onClick={() => setService('crunchy')} startIcon={<Avatar src={'https://static.crunchyroll.com/cxweb/assets/img/favicons/favicon-32x32.png'} />}>Crunchyroll</Button>
|
<Button size='large' variant="contained" onClick={() => setService('crunchy')} startIcon={<Avatar src={'https://static.crunchyroll.com/cxweb/assets/img/favicons/favicon-32x32.png'} />}>Crunchyroll</Button>
|
||||||
<Divider orientation='vertical' flexItem />
|
|
||||||
<Button size='large' variant="contained" onClick={() => setService('hidive')} startIcon={<Avatar src={'https://www.hidive.com/favicon.ico'} />}>Hidive</Button>
|
<Button size='large' variant="contained" onClick={() => setService('hidive')} startIcon={<Avatar src={'https://www.hidive.com/favicon.ico'} />}>Hidive</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ export type DownloadOptions = {
|
||||||
all: boolean,
|
all: boolean,
|
||||||
but: boolean,
|
but: boolean,
|
||||||
novids: boolean,
|
novids: boolean,
|
||||||
|
hslang?: string,
|
||||||
|
simul: boolean,
|
||||||
noaudio: boolean
|
noaudio: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +50,8 @@ const initialState: StoreState = {
|
||||||
all: false,
|
all: false,
|
||||||
but: false,
|
but: false,
|
||||||
noaudio: false,
|
noaudio: false,
|
||||||
novids: false
|
novids: false,
|
||||||
|
simul: false
|
||||||
},
|
},
|
||||||
service: undefined,
|
service: undefined,
|
||||||
episodeListing: [],
|
episodeListing: [],
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class CrunchyHandler extends Base implements MessageHandler {
|
||||||
if (res.isOk) {
|
if (res.isOk) {
|
||||||
for (const select of res.value) {
|
for (const select of res.value) {
|
||||||
if (!(await this.crunchy.downloadEpisode(select, {..._default, skipsubs: false, callbackMaker: this.makeProgressHandler.bind(this), q: data.q, fileName: data.fileName, dlsubs: data.dlsubs, dlVideoOnce: data.dlVideoOnce, force: 'y',
|
if (!(await this.crunchy.downloadEpisode(select, {..._default, skipsubs: false, callbackMaker: this.makeProgressHandler.bind(this), q: data.q, fileName: data.fileName, dlsubs: data.dlsubs, dlVideoOnce: data.dlVideoOnce, force: 'y',
|
||||||
novids: data.novids }))) {
|
novids: data.novids, hslang: data.hslang || '' }))) {
|
||||||
const er = new Error(`Unable to download episode ${data.e} from ${data.id}`);
|
const er = new Error(`Unable to download episode ${data.e} from ${data.id}`);
|
||||||
er.name = 'Download error';
|
er.name = 'Download error';
|
||||||
this.alertError(er);
|
this.alertError(er);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ class FunimationHandler extends Base implements MessageHandler {
|
||||||
},
|
},
|
||||||
image: a.image,
|
image: a.image,
|
||||||
e: a.episodeID,
|
e: a.episodeID,
|
||||||
episode: a.epsiodeNumber,
|
episode: a.epsiodeNumber
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ class HidiveHandler extends Base implements MessageHandler {
|
||||||
return this.alertError(new Error('Download failed upstream, check for additional logs'));
|
return this.alertError(new Error('Download failed upstream, check for additional logs'));
|
||||||
|
|
||||||
for (const ep of res.value) {
|
for (const ep of res.value) {
|
||||||
await this.hidive.getEpisode(ep, {..._default, callbackMaker: this.makeProgressHandler.bind(this), dubLang: data.dubLang, dlsubs: data.dlsubs, fileName: data.fileName, q: data.q, force: 'y', noaudio: data.noaudio, novids: data.novids});
|
await this.hidive.getEpisode(ep, {..._default, callbackMaker: this.makeProgressHandler.bind(this), dubLang: data.dubLang, dlsubs: data.dlsubs, fileName: data.fileName, q: data.q, force: 'y', noaudio: data.noaudio, novids: data.novids });
|
||||||
}
|
}
|
||||||
this.sendMessage({ name: 'finish', data: undefined });
|
this.sendMessage({ name: 'finish', data: undefined });
|
||||||
this.setDownloading(false);
|
this.setDownloading(false);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue