multi-downloader-nx_mirror/gui.diff
2024-02-16 17:57:24 +01:00

979 lines
81 KiB
Diff

diff --git a/@types/messageHandler.d.ts b/@types/messageHandler.d.ts
index 3929178..7e63da4 100644
--- a/@types/messageHandler.d.ts
+++ b/@types/messageHandler.d.ts
@@ -40,7 +40,7 @@ export type QueueItem = {
q: number,
dlVideoOnce: boolean,
dubLang: string[],
- image: string
+ image: string,
} & 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,
ffmpegOptions: string[], mkvmergeOptions: string[], defaultAudio: LanguageItem, defaultSub: LanguageItem, 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 FuniSearchReponse = ResponseBase<FunimationSearch>;
diff --git a/gui/react/public/index.html b/gui/react/public/index.html
index 92cc7d8..e0f99bb 100644
--- a/gui/react/public/index.html
+++ b/gui/react/public/index.html
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<html>
<head>
+ <title>Multi Downloader</title>
+ <link rel="icon" type="image/webp" href="favicon.webp">
<meta charset="UTF-8">
<meta
http-equiv="Content-Security-Policy"
diff --git a/gui/react/src/Layout.tsx b/gui/react/src/Layout.tsx
index 450f00f..30cb33d 100644
--- a/gui/react/src/Layout.tsx
+++ b/gui/react/src/Layout.tsx
@@ -13,15 +13,20 @@ const Layout: React.FC = () => {
const messageHandler = React.useContext(messageChannelContext);
- return <Box sx={{ display: 'flex', flexDirection: 'column' }}>
+ return <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center'}}>
<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 />
<AuthButton />
- <Box sx={{ display: 'flex', gap: 1, height: 36 }}>
- <Button variant="contained" startIcon={<Folder />} onClick={() => messageHandler?.openFolder('content')}>Open Output Directory</Button>
- <Button variant="contained" startIcon={<ClearAll />} onClick={() => messageHandler?.clearQueue() }>Clear Queue</Button>
- </Box>
+ <Button variant="contained" startIcon={<Folder />} onClick={() => messageHandler?.openFolder('content')} sx={{ height: '37px' }}>Open Output Directory</Button>
+ <Button variant="contained" startIcon={<ClearAll />} onClick={() => messageHandler?.clearQueue() } sx={{ height: '37px' }}>Clear Queue</Button>
<AddToQueue />
<StartQueueButton />
</Box>
diff --git a/gui/react/src/Style.tsx b/gui/react/src/Style.tsx
index 4f44a07..4f4306f 100644
--- a/gui/react/src/Style.tsx
+++ b/gui/react/src/Style.tsx
@@ -11,10 +11,8 @@ const makeTheme = (mode: 'dark'|'light') : Partial<Theme> => {
const Style: FCWithChildren = ({children}) => {
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 }}/>
{children}
- </Container>
</ThemeProvider>;
};
diff --git a/gui/react/src/components/AddToQueue/AddToQueue.tsx b/gui/react/src/components/AddToQueue/AddToQueue.tsx
index 98333aa..8bbd414 100644
--- a/gui/react/src/components/AddToQueue/AddToQueue.tsx
+++ b/gui/react/src/components/AddToQueue/AddToQueue.tsx
@@ -1,5 +1,5 @@
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 DownloadSelector from './DownloadSelector/DownloadSelector';
import EpisodeListing from './DownloadSelector/Listing/EpisodeListing';
@@ -10,14 +10,14 @@ const AddToQueue: React.FC = () => {
return <Box>
<EpisodeListing />
- <Dialog open={isOpen} onClose={() => setOpen(false)} maxWidth='md'>
- <Box sx={{ border: '2px solid white', p: 2 }}>
+ <Dialog open={isOpen} onClose={() => setOpen(false)} maxWidth='md' PaperProps={{ elevation:4 }}>
+ <Box>
<SearchBox />
- <Divider variant='middle' className="divider-width" light sx={{ color: 'text.primary', fontSize: '1.2rem' }}>Options</Divider>
+ <Divider variant='middle'/>
<DownloadSelector onFinish={() => setOpen(false)} />
</Box>
</Dialog>
- <Button variant='contained' onClick={() => setOpen(true)}>
+ <Button variant='contained' onClick={() => setOpen(true)}>
<Add />
Add to Queue
</Button>
diff --git a/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx b/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx
index 489b8f1..d1d5ed4 100644
--- a/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx
+++ b/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx
@@ -1,10 +1,11 @@
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 MultiSelect from '../../reusable/MultiSelect';
import { messageChannelContext } from '../../../provider/MessageChannel';
import LoadingButton from '@mui/lab/LoadingButton';
import { useSnackbar } from 'notistack';
+import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
type DownloadSelectorProps = {
onFinish?: () => unknown
@@ -78,14 +79,36 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
setLoading(false);
};
- return <Box sx={{ display: 'flex', flexDirection: 'column' }}>
- <Box sx={{ m: 2, gap: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', flexWrap: 'wrap' }}>
+ return <Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
+ <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 => {
dispatch({
type: 'downloadOptions',
payload: { ...store.downloadOptions, id: e.target.value }
});
- }} label='Item ID' />
+ }} label='Show ID'/>
<TextField type='number' value={store.downloadOptions.q} required onChange={e => {
const parsed = parseInt(e.target.value);
if (isNaN(parsed) || parsed < 0 || parsed > 10)
@@ -94,13 +117,77 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
type: 'downloadOptions',
payload: { ...store.downloadOptions, q: parsed }
});
- }} label='Quality Level (0 for max)' />
- <TextField disabled={store.downloadOptions.all} value={store.downloadOptions.e} required onChange={e => {
- dispatch({
- type: 'downloadOptions',
- payload: { ...store.downloadOptions, e: e.target.value }
- });
- }} label='Episode Select' />
+ }} label='Quality Level (0 for max)'/>
+ <Box sx={{ display: 'flex', gap: '5px' }}>
+ <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
+ <Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
+ </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>
+ <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
title='Dub Languages'
values={availableDubs}
@@ -113,6 +200,7 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
}}
allOption
/>
+
<MultiSelect
title='Sub Languages'
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({
type: 'downloadOptions',
payload: { ...store.downloadOptions, fileName: e.target.value }
});
- }} sx={{ width: '50%' }} label='Filename' />
- <Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, all: !store.downloadOptions.all } })} variant={store.downloadOptions.all ? 'contained' : 'outlined'}>Download all</Button>
- <Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, but: !store.downloadOptions.but } })} variant={store.downloadOptions.but ? 'contained' : 'outlined'}>Download all but</Button>
- <Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
- <Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
- <Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, dlVideoOnce: !store.downloadOptions.dlVideoOnce } })} variant={store.downloadOptions.dlVideoOnce ? 'contained' : 'outlined'}>Skip unnecessary Downloads</Button>
- </Box>
- <Box sx={{ gap: 2, flex: 0, m: 1, mb: 3, display: 'flex', justifyContent: 'center' }}>
- <LoadingButton loading={loading} onClick={listEpisodes} variant='contained'>List episodes</LoadingButton>
- <LoadingButton loading={loading} onClick={addToQueue} variant='contained'>Add to Queue</LoadingButton>
+ }} sx={{ width: '87%' }} label='Filename Overwrite' />
+ <Tooltip title={
+ <Typography>
+ Click here to see the documentation
+ </Typography>
+ } arrow placement='top'>
+ <Link href='https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md#filename-template' rel="noopener noreferrer" target="_blank">
+ <InfoOutlinedIcon sx={{
+ transition: '100ms',
+ '&:hover' : {
+ color: '#ffffff30',
+ }
+ }} />
+ </Link>
+ </Tooltip>
+ </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>;
};
diff --git a/gui/react/src/components/MainFrame/MainFrame.css b/gui/react/src/components/MainFrame/MainFrame.css
deleted file mode 100644
index 2bbc1ad..0000000
--- a/gui/react/src/components/MainFrame/MainFrame.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.divider-width::before, .divider-width::after {
- border-top: 3px solid white !important;
- transform: translateY(40%) !important;
-}
\ No newline at end of file
diff --git a/gui/react/src/components/MainFrame/MainFrame.tsx b/gui/react/src/components/MainFrame/MainFrame.tsx
index de4db33..425b321 100644
--- a/gui/react/src/components/MainFrame/MainFrame.tsx
+++ b/gui/react/src/components/MainFrame/MainFrame.tsx
@@ -1,10 +1,9 @@
import { Box } from '@mui/material';
import React from 'react';
-import './MainFrame.css';
import Queue from './Queue/Queue';
const MainFrame: React.FC = () => {
- return <Box sx={{ marginLeft: 1 }}>
+ return <Box sx={{ }}>
<Queue />
</Box>;
};
diff --git a/gui/react/src/components/MainFrame/Queue/Queue.tsx b/gui/react/src/components/MainFrame/Queue/Queue.tsx
index 5a79c9e..e263784 100644
--- a/gui/react/src/components/MainFrame/Queue/Queue.tsx
+++ b/gui/react/src/components/MainFrame/Queue/Queue.tsx
@@ -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 { messageChannelContext } from '../../../provider/MessageChannel';
import { queueContext } from '../../../provider/QueueProvider';
+import DeleteIcon from '@mui/icons-material/Delete';
import useDownloadManager from '../DownloadManager/DownloadManager';
@@ -16,102 +17,384 @@ const Queue: React.FC = () => {
return data || queue.length > 0 ? <>
{data && <>
- <Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
- <img src={data.downloadInfo.image} height='auto' width='100%' alt="Thumbnail" />
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
- <Box sx={{ display: 'flex', flexDirection: 'column' }}>
- <Box sx={{ display: 'grid', gridTemplateColumns: '1fr max-content' }}>
- <Typography variant='h5' color='text.primary'>
- {data.downloadInfo.title}
- </Typography>
- <Typography variant='h5' color='text.primary'>
- Language: {data.downloadInfo.language.name}
- </Typography>
- </Box>
- <Typography variant='h6' color='text.primary'>
+ <Box sx={{
+ display: 'flex',
+ width: '100%',
+ flexDirection: 'column',
+ alignItems: 'center',
+ }}>
+ <Box sx={{
+ marginTop: '2rem',
+ marginBottom: '1rem',
+ height: '11rem',
+ width: '95rem',
+ backgroundColor: '#282828',
+ 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}
</Typography>
+ <Typography color='text.primary' sx={{
+ fontSize: '1.2rem',
+ }}>
+ {data.downloadInfo.title}
+ </Typography>
</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>
- <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)
</Typography>
</Box>
</Box>
+ </Box>
+ </Box>
</Box>
</>
}
{
current && !data && <>
- <Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
- <img src={current.image} height='auto' width='100%' alt="Thumbnail" />
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
- <Box sx={{ display: 'flex', flexDirection: 'column' }}>
- <Box sx={{ display: 'grid', gridTemplateColumns: '1fr max-content' }}>
- <Typography variant='h5' color='text.primary'>
- {current.title}
- </Typography>
- <Typography variant='h5' color='text.primary'>
- Language: <CircularProgress variant="indeterminate" />
- </Typography>
- </Box>
- <Typography variant='h6' color='text.primary'>
- {current.parent.title}
- </Typography>
- </Box>
- <LinearProgress variant='indeterminate' sx={{ height: '10px' }} />
- <Box>
- <Typography variant="body1" color='text.primary'>
- 0 / ? parts (0% | X:XX | 0 MB/s | 0MB)
- </Typography>
- </Box>
+ <Box sx={{
+ display: 'flex',
+ width: '100%',
+ flexDirection: 'column',
+ alignItems: 'center',
+ }}>
+ <Box sx={{
+ marginTop: '2rem',
+ marginBottom: '1rem',
+ height: '13rem',
+ width: '95rem',
+ backgroundColor: '#282828',
+ 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={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 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 }) => {
- return <Box key={`queue_item_${index}`}>
- <Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1, mb: 1, mt: 1 }}>
- <img src={queueItem.image} height='auto' width='100%' alt="Thumbnail" />
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
- <Box sx={{ display: 'flex', flexDirection: 'column' }}>
- <Box sx={{ display: 'grid', gridTemplateColumns: '1fr 200px' }}>
- <Typography variant='h5' color='text.primary'>
- {queueItem.title}
+ return <Box key={`queue_item_${index}`} sx={{
+ display: 'flex',
+ width: '100%',
+ height: '12rem',
+ flexDirection: 'column',
+ alignItems: 'center',
+ }}>
+ <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 variant='h5' color='text.primary'>
- Languages: {queueItem.dubLang.join(', ')}
+ <Typography color='text.primary' sx={{
+ 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>
</Box>
- <Typography variant='h6' color='text.primary'>
- {queueItem.parent.title}
- </Typography>
- </Box>
- <Typography variant='body1' color='text.primary'>
- S{queueItem.parent.season}E{queueItem.episode} <br />
- Quality: {queueItem.q}
- </Typography>
- <Button onClick={() => {
+ <Box sx={{
+ //backgroundColor: '#ffffff',
+ marginRight: '5px',
+ marginLeft: '5px',
+ }}>
+ <Tooltip title="Delete from queue" arrow placement='top'>
+ <IconButton
+ onClick={() => {
msg.removeFromQueue(index);
- }} sx={{ position: 'relative', left: '50%', transform: 'translateX(-50%)', width: '60%' }} variant="outlined" color="warning">
- Remove from Queue
- </Button>
+ }}
+ sx={{
+ backgroundColor: '#ff573a25',
+ height: '40px',
+ width: '40px',
+ margin: '4rem',
+ transition: '250ms',
+ '&:hover' : {
+ backgroundColor: '#ff573a',
+ }
+ }}>
+ <DeleteIcon />
+ </IconButton>
+ </Tooltip>
+ </Box>
+ </Box>
</Box>
</Box>
- {index < length - 1 && <Divider variant="fullWidth" />}
- </Box>;
+ ;
})}
- </> : <Box>
- <Typography color='text.primary' variant='h4'>
+ </> : <Box sx={{
+ 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
</Typography>
- <Box sx={{ height: 200, display: 'grid', gridTemplateColumns: '20% 1fr', gap: 1 }}>
- <Skeleton variant='rectangular' height={'100%'}/>
- <Box sx={{ display: 'grid', gridTemplateRows: '33% 1fr', gap: 1 }}>
- <Skeleton variant='text' height={'100%'} />
- <Skeleton variant='text' height={'100%'} />
+ <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 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>;
diff --git a/gui/react/src/components/MenuBar/MenuBar.tsx b/gui/react/src/components/MenuBar/MenuBar.tsx
index 5d74377..b1125a4 100644
--- a/gui/react/src/components/MenuBar/MenuBar.tsx
+++ b/gui/react/src/components/MenuBar/MenuBar.tsx
@@ -44,7 +44,7 @@ const MenuBar: React.FC = () => {
if (!msg)
return <></>;
- return <Box sx={{ width: '100%', display: 'flex' }}>
+ return <Box sx={{ width: '95rem', display: 'flex', marginBottom: '1rem' }}>
<Button onClick={(e) => handleClick(e, 'settings')}>
Settings
</Button>
@@ -108,7 +108,7 @@ const MenuBar: React.FC = () => {
Version: {store.version}
</MenuItem>
</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)}
</Typography>
</Box>;
diff --git a/gui/react/src/provider/ServiceProvider.tsx b/gui/react/src/provider/ServiceProvider.tsx
index 9aecfb5..ed862b1 100644
--- a/gui/react/src/provider/ServiceProvider.tsx
+++ b/gui/react/src/provider/ServiceProvider.tsx
@@ -18,13 +18,11 @@ const ServiceProvider: FCWithChildren = ({ children }) => {
};
return service === undefined ?
- <Box>
- <Typography color="text.primary" variant='h3' sx={{ textAlign: 'center', mb: 5 }}>Please choose your service</Typography>
+ <Box sx={{ justifyContent: 'center', alignItems: 'center', display: 'flex', flexDirection: 'column', height: '50rem'}}>
+ <Typography color="text.primary" variant='h3' sx={{ textAlign: 'center', mb: 5 }}>Please select your service</Typography>
<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>
- <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>
- <Divider orientation='vertical' flexItem />
<Button size='large' variant="contained" onClick={() => setService('hidive')} startIcon={<Avatar src={'https://www.hidive.com/favicon.ico'} />}>Hidive</Button>
</Box>
</Box>
diff --git a/gui/react/src/provider/Store.tsx b/gui/react/src/provider/Store.tsx
index 5054051..c82ef92 100644
--- a/gui/react/src/provider/Store.tsx
+++ b/gui/react/src/provider/Store.tsx
@@ -13,6 +13,8 @@ export type DownloadOptions = {
all: boolean,
but: boolean,
novids: boolean,
+ hslang?: string,
+ simul: boolean,
noaudio: boolean
}
@@ -48,7 +50,8 @@ const initialState: StoreState = {
all: false,
but: false,
noaudio: false,
- novids: false
+ novids: false,
+ simul: false
},
service: undefined,
episodeListing: [],
diff --git a/gui/server/services/crunchyroll.ts b/gui/server/services/crunchyroll.ts
index 9bc2777..f74fff8 100644
--- a/gui/server/services/crunchyroll.ts
+++ b/gui/server/services/crunchyroll.ts
@@ -98,7 +98,7 @@ class CrunchyHandler extends Base implements MessageHandler {
if (res.isOk) {
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',
- novids: data.novids }))) {
+ novids: data.novids, hslang: data.hslang || '' }))) {
const er = new Error(`Unable to download episode ${data.e} from ${data.id}`);
er.name = 'Download error';
this.alertError(er);
diff --git a/gui/server/services/funimation.ts b/gui/server/services/funimation.ts
index bee900e..3bfc4eb 100644
--- a/gui/server/services/funimation.ts
+++ b/gui/server/services/funimation.ts
@@ -70,7 +70,7 @@ class FunimationHandler extends Base implements MessageHandler {
},
image: a.image,
e: a.episodeID,
- episode: a.epsiodeNumber,
+ episode: a.epsiodeNumber
};
}));
return true;
diff --git a/gui/server/services/hidive.ts b/gui/server/services/hidive.ts
index f3da018..e07eea2 100644
--- a/gui/server/services/hidive.ts
+++ b/gui/server/services/hidive.ts
@@ -118,7 +118,7 @@ class HidiveHandler extends Base implements MessageHandler {
return this.alertError(new Error('Download failed upstream, check for additional logs'));
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.setDownloading(false);