eslint fixes

This commit is contained in:
AnimeDL 2024-04-06 09:10:48 -07:00
parent 036440b0e5
commit 23f185c877
13 changed files with 542 additions and 597 deletions

View file

@ -1,5 +0,0 @@
lib
/videos/*.ts
build
dev.js
tsc.ts

View file

@ -1,56 +0,0 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"overrides": [
{
"files": ["gui/react/**/*"],
"rules": {
"no-console": 0
}
}
],
"rules": {
"no-console": 2,
"react/prop-types": 0,
"react-hooks/exhaustive-deps": 0,
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-declaration-merging": "warn",
"@typescript-eslint/no-unused-vars" : "warn",
"indent": [
"error",
2
],
"linebreak-style": [
"warn",
"windows"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

View file

@ -7,15 +7,6 @@ import react from 'eslint-plugin-react';
export default tseslint.config( export default tseslint.config(
eslint.configs.recommended, eslint.configs.recommended,
...tseslint.configs.recommended, ...tseslint.configs.recommended,
{
ignores: [
'lib',
'/videos/*.ts',
'build',
'dev.js',
'tsc.ts'
]
},
{ {
rules: { rules: {
'no-console': 2, 'no-console': 2,
@ -54,5 +45,20 @@ export default tseslint.config(
}, },
parser: tseslint.parser parser: tseslint.parser
} }
},
{
ignores: [
'**/lib',
'**/videos/*.ts',
'**/build',
'dev.js',
'tsc.ts'
]
},
{
files: ['gui/react/**/*'],
rules: {
'no-console': 0
}
} }
); );

View file

@ -23,11 +23,11 @@ const Layout: React.FC = () => {
maxWidth: '93rem', maxWidth: '93rem',
maxHeight: '3rem' maxHeight: '3rem'
//backgroundColor: '#ffffff', //backgroundColor: '#ffffff',
}}> }}>
<LogoutButton /> <LogoutButton />
<AuthButton /> <AuthButton />
<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')} sx={{ height: '37px' }}>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() } sx={{ height: '37px' }}>Clear Queue</Button>
<AddToQueue /> <AddToQueue />
<StartQueueButton /> <StartQueueButton />
</Box> </Box>

View file

@ -11,8 +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')}>
<Box sx={{ }}/> <Box sx={{ }}/>
{children} {children}
</ThemeProvider>; </ThemeProvider>;
}; };

View file

@ -86,240 +86,240 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
margin: '5px', 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='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)
return;
dispatch({
type: 'downloadOptions',
payload: { ...store.downloadOptions, q: parsed }
});
}} 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={store.service == 'hidive' ? '' :
<Typography>
Simulcast is only supported on Hidive
</Typography>}
arrow placement='top'
>
<Box>
<Button sx={{ textTransform: 'none'}} disabled={store.service != 'hidive'} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, simul: !store.downloadOptions.simul } })} variant={store.downloadOptions.simul ? 'contained' : 'outlined'}>Download Simulcast ver.</Button>
</Box>
</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={{ <Box sx={{
width: '50rem',
height: '21rem',
margin: '10px',
display: 'flex', display: 'flex',
flexDirection: 'column', justifyContent: 'space-between',
gap: '1px' //backgroundColor: '#ffffff30',
}}> }}>
<Box sx={{ <Box sx={{
borderColor: '#595959',
borderStyle: 'solid',
borderWidth: '1px',
borderRadius: '5px',
//backgroundColor: '#ff4567',
width: '15rem',
height: '3.5rem',
display: 'flex', display: 'flex',
'&:hover' : { flexDirection: 'column',
borderColor: '#ffffff', alignItems: 'center',
}, gap: '0.7rem',
//backgroundColor: '#ff000030'
}}> }}>
<InputBase sx={{ <Typography sx={{fontSize: '1.4rem'}}>
ml: 2, General Options
flex: 1, </Typography>
}} <TextField value={store.downloadOptions.id} required onChange={e => {
disabled={store.downloadOptions.all} value={store.downloadOptions.e} required onChange={e => {
dispatch({ dispatch({
type: 'downloadOptions', type: 'downloadOptions',
payload: { ...store.downloadOptions, e: e.target.value } payload: { ...store.downloadOptions, id: e.target.value }
}); });
}} placeholder='Episode Select'/> }} label='Show ID'/>
<Divider orientation='vertical'/> <TextField type='number' value={store.downloadOptions.q} required onChange={e => {
<LoadingButton loading={loading} disableElevation disableFocusRipple disableRipple disableTouchRipple onClick={listEpisodes} variant='text' sx={{ textTransform: 'none'}}><Typography>List<br/>Episodes</Typography></LoadingButton> const parsed = parseInt(e.target.value);
if (isNaN(parsed) || parsed < 0 || parsed > 10)
return;
dispatch({
type: 'downloadOptions',
payload: { ...store.downloadOptions, q: parsed }
});
}} 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={store.service == 'hidive' ? '' :
<Typography>
Simulcast is only supported on Hidive
</Typography>}
arrow placement='top'
>
<Box>
<Button sx={{ textTransform: 'none'}} disabled={store.service != 'hidive'} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, simul: !store.downloadOptions.simul } })} variant={store.downloadOptions.simul ? 'contained' : 'outlined'}>Download Simulcast ver.</Button>
</Box>
</Tooltip>
</Box> </Box>
</Box> <Box sx={{
<Button sx={{ textTransform: 'none'}} onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, all: !store.downloadOptions.all } })} variant={store.downloadOptions.all ? 'contained' : 'outlined'}>Download All</Button> display: 'flex',
<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> flexDirection: 'column',
</Box> alignItems: 'center',
<Box sx={{ gap: '0.7rem',
display: 'flex', //backgroundColor: '#00000020'
flexDirection: 'column', }}>
alignItems: 'center', <Typography sx={{fontSize: '1.4rem'}}>
gap: '0.7rem', 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' //backgroundColor: '#00ff0020'
}}> }}>
<Typography sx={{fontSize: '1.4rem'}}> <Typography sx={{fontSize: '1.4rem'}}>
Language Options Language Options
</Typography> </Typography>
<MultiSelect <MultiSelect
title='Dub Languages' title='Dub Languages'
values={availableDubs} values={availableDubs}
selected={store.downloadOptions.dubLang} selected={store.downloadOptions.dubLang}
onChange={(e) => { onChange={(e) => {
dispatch({ dispatch({
type: 'downloadOptions', type: 'downloadOptions',
payload: { ...store.downloadOptions, dubLang: e } payload: { ...store.downloadOptions, dubLang: e }
}); });
}} }}
allOption allOption
/> />
<MultiSelect <MultiSelect
title='Sub Languages' title='Sub Languages'
values={availableSubs} values={availableSubs}
selected={store.downloadOptions.dlsubs} selected={store.downloadOptions.dlsubs}
onChange={(e) => { onChange={(e) => {
dispatch({ dispatch({
type: 'downloadOptions', type: 'downloadOptions',
payload: { ...store.downloadOptions, dlsubs: e } payload: { ...store.downloadOptions, dlsubs: e }
}); });
}} }}
/> />
<Tooltip title={store.service == 'crunchy' ? '' : <Tooltip title={store.service == 'crunchy' ? '' :
<Typography> <Typography>
Hardsubs are only supported on Crunchyroll Hardsubs are only supported on Crunchyroll
</Typography> </Typography>
} }
arrow placement='top'> arrow placement='top'>
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
width: '100%', width: '100%',
gap: '1rem' gap: '1rem'
}}> }}>
<Box sx={{ <Box sx={{
borderRadius: '5px', borderRadius: '5px',
//backgroundColor: '#ff4567', //backgroundColor: '#ff4567',
width: '15rem', width: '15rem',
height: '3.5rem', height: '3.5rem',
display: 'flex', display: 'flex',
}}> }}>
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel id='hsLabel'>Hardsub Language</InputLabel> <InputLabel id='hsLabel'>Hardsub Language</InputLabel>
<Select <Select
MenuProps={{ MenuProps={{
PaperProps: { PaperProps: {
style: { style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250 width: 250
} }
} }
}} }}
labelId='hsLabel' labelId='hsLabel'
label='Hardsub Language' label='Hardsub Language'
disabled={store.service != 'crunchy'} disabled={store.service != 'crunchy'}
value={store.downloadOptions.hslang} value={store.downloadOptions.hslang}
onChange={(e) => { onChange={(e) => {
dispatch({ dispatch({
type: 'downloadOptions', type: 'downloadOptions',
payload: { ...store.downloadOptions, hslang: (e.target.value as string) === '' ? undefined : e.target.value as string } payload: { ...store.downloadOptions, hslang: (e.target.value as string) === '' ? undefined : e.target.value as string }
}); });
}} }}
> >
<MenuItem value=''>No Hardsub</MenuItem> <MenuItem value=''>No Hardsub</MenuItem>
{availableSubs.map((lang) => { {availableSubs.map((lang) => {
if(lang === 'all' || lang === 'none') if(lang === 'all' || lang === 'none')
return undefined return undefined;
return <MenuItem value={lang}>{lang}</MenuItem> return <MenuItem value={lang}>{lang}</MenuItem>;
})} })}
</Select> </Select>
</FormControl> </FormControl>
</Box> </Box>
<Tooltip title={ <Tooltip title={
<Typography> <Typography>
Downloads the hardsub version of the selected subtitle.<br/>Subtitles are displayed <b>PERMANENTLY!</b><br/>You can choose only <b>1</b> subtitle per video! Downloads the hardsub version of the selected subtitle.<br/>Subtitles are displayed <b>PERMANENTLY!</b><br/>You can choose only <b>1</b> subtitle per video!
</Typography> </Typography>
} arrow placement='top'> } arrow placement='top'>
<InfoOutlinedIcon sx={{ <InfoOutlinedIcon sx={{
transition: '100ms', transition: '100ms',
ml: '0.35rem', ml: '0.35rem',
mr: '0.65rem', mr: '0.65rem',
'&:hover' : { '&:hover' : {
color: '#ffffff30', color: '#ffffff30',
} }
}} /> }} />
</Tooltip> </Tooltip>
</Box>
</Tooltip>
</Box> </Box>
</Tooltip>
</Box> </Box>
</Box> <Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginBottom: '20px'}}/>
<Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginBottom: '20px'}}/> <Box sx={{
<Box sx={{ display: 'flex',
display: 'flex', alignItems: 'center',
alignItems: 'center', justifyContent: 'center',
justifyContent: 'center', width: '100%',
width: '100%', gap: '15px'
gap: '15px' }}>
}}> <TextField value={store.downloadOptions.fileName} onChange={e => {
<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: '87%' }} label='Filename Overwrite' />
}} sx={{ width: '87%' }} label='Filename Overwrite' /> <Tooltip title={
<Tooltip title={ <Typography>
<Typography>
Click here to see the documentation Click here to see the documentation
</Typography> </Typography>
} arrow placement='top'> } arrow placement='top'>
<Link href='https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md#filename-template' rel="noopener noreferrer" target="_blank"> <Link href='https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md#filename-template' rel="noopener noreferrer" target="_blank">
<InfoOutlinedIcon sx={{ <InfoOutlinedIcon sx={{
transition: '100ms', transition: '100ms',
'&:hover' : { '&:hover' : {
color: '#ffffff30', color: '#ffffff30',
} }
}} /> }} />
</Link> </Link>
</Tooltip> </Tooltip>
</Box> </Box>
</Box> </Box>
<Box sx={{width: '95%', height: '0.3rem', backgroundColor: '#ffffff50', borderRadius: '10px', marginTop: '10px'}}/> <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> <LoadingButton sx={{ margin: '15px', textTransform: 'none' }} loading={loading} onClick={addToQueue} variant='contained'>Add to Queue</LoadingButton>
</Box>; </Box>;
}; };

View file

@ -75,21 +75,21 @@ const EpisodeListing: React.FC = () => {
</ListItem> </ListItem>
{store.episodeListing.filter((a) => season === 'all' ? true : a.season === season).map((item, index, { length }) => { {store.episodeListing.filter((a) => season === 'all' ? true : a.season === season).map((item, index, { length }) => {
const e = isNaN(parseInt(item.e)) ? item.e : parseInt(item.e); const e = isNaN(parseInt(item.e)) ? item.e : parseInt(item.e);
const idStr = `S${item.season}E${e}` const idStr = `S${item.season}E${e}`;
const isSelected = selected.includes(e.toString()); const isSelected = selected.includes(e.toString());
const imageRef = React.createRef<HTMLImageElement>(); const imageRef = React.createRef<HTMLImageElement>();
const summaryRef = React.createRef<HTMLParagraphElement>(); const summaryRef = React.createRef<HTMLParagraphElement>();
return <Box {...{ mouseData: isSelected }} key={`Episode_List_Item_${index}`}> return <Box {...{ mouseData: isSelected }} key={`Episode_List_Item_${index}`}>
<ListItem sx={{backdropFilter: isSelected ? 'brightness(1.5)' : '', '&:hover': {backdropFilter: 'brightness(1.5)'}, display: 'grid', gridTemplateColumns: '25px 50px 1fr 5fr' }} <ListItem sx={{backdropFilter: isSelected ? 'brightness(1.5)' : '', '&:hover': {backdropFilter: 'brightness(1.5)'}, display: 'grid', gridTemplateColumns: '25px 50px 1fr 5fr' }}
onClick={() => { onClick={() => {
let arr: string[] = []; let arr: string[] = [];
if (isSelected) { if (isSelected) {
arr = [...selected.filter(a => a !== e.toString())]; arr = [...selected.filter(a => a !== e.toString())];
} else { } else {
arr = [...selected, e.toString()]; arr = [...selected, e.toString()];
} }
setSelected(arr.filter(a => a.length > 0)); setSelected(arr.filter(a => a.length > 0));
}}> }}>
{ isSelected ? <CheckBox /> : <CheckBoxOutlineBlank /> } { isSelected ? <CheckBox /> : <CheckBoxOutlineBlank /> }
<Typography color='text.primary' sx={{ textAlign: 'center' }}> <Typography color='text.primary' sx={{ textAlign: 'center' }}>
{idStr} {idStr}
@ -133,9 +133,9 @@ const EpisodeListing: React.FC = () => {
await navigator.clipboard.writeText(item.description!); await navigator.clipboard.writeText(item.description!);
enqueueSnackbar('Copied summary to clipboard', { enqueueSnackbar('Copied summary to clipboard', {
variant: 'info' variant: 'info'
}) });
}, },
text: "Copy summary to clipboard" text: 'Copy summary to clipboard'
} }
]} popupItem={summaryRef} /> ]} popupItem={summaryRef} />
{index < length - 1 && <Divider />} {index < length - 1 && <Divider />}

View file

@ -100,9 +100,9 @@ const SearchBox: React.FC = () => {
await navigator.clipboard.writeText(a.desc!); await navigator.clipboard.writeText(a.desc!);
enqueueSnackbar('Copied summary to clipboard', { enqueueSnackbar('Copied summary to clipboard', {
variant: 'info' variant: 'info'
}) });
}, },
text: "Copy summary to clipboard" text: 'Copy summary to clipboard'
} }
]} popupItem={summaryRef} /> ]} popupItem={summaryRef} />
} }

View file

@ -17,113 +17,9 @@ const Queue: React.FC = () => {
return data || queue.length > 0 ? <> return data || queue.length > 0 ? <>
{data && <> {data && <>
<Box sx={{
display: 'flex',
width: '100%',
flexDirection: 'column',
alignItems: 'center',
}}>
<Box sx={{
marginTop: '2rem',
marginBottom: '1rem',
height: '12rem',
width: '93vw',
maxWidth: '93rem',
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>
</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 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={{ <Box sx={{
display: 'flex', display: 'flex',
width: '100%',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
}}> }}>
@ -137,104 +33,208 @@ const Queue: React.FC = () => {
boxShadow: '0px 0px 50px #00000090', boxShadow: '0px 0px 50px #00000090',
borderRadius: '10px', borderRadius: '10px',
display: 'flex', display: 'flex',
overflow: 'hidden',
transition: '250ms' transition: '250ms'
}}> }}>
<img style={{ <img style={{
borderRadius: '5px', borderRadius: '5px',
margin: '5px', margin: '5px',
boxShadow: '0px 0px 10px #00000090', boxShadow: '0px 0px 10px #00000090',
userSelect: 'none', userSelect: 'none',
maxWidth: '20.5rem',
}} }}
src={current.image} height='auto' width='auto' alt="Thumbnail" /> src={data.downloadInfo.image} height='auto' width='auto' alt="Thumbnail" />
<Box <Box
sx={{
display: 'flex',
flexDirection: 'column',
width: '100%',
justifyContent: 'center',
//backgroundColor: '#ffffff0f'
}}>
<Box sx={{
display: 'flex',
}}>
<Box sx={{
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',
position: 'relative',
}}>
<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={{ sx={{
fontSize: '1.3rem', display: 'flex',
flexDirection: 'column',
width: '100%',
justifyContent: 'center'
}}> }}>
0 / ? parts (0% | XX:XX | 0 MB/s | 0MB) <Box sx={{
</Typography> 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>
</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 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> </Box>
</Box>
</>
}
{
current && !data && <>
<Box sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}>
<Box sx={{
marginTop: '2rem',
marginBottom: '1rem',
height: '12rem',
width: '93vw',
maxWidth: '93rem',
backgroundColor: '#282828',
boxShadow: '0px 0px 50px #00000090',
borderRadius: '10px',
display: 'flex',
overflow: 'hidden',
transition: '250ms'
}}>
<img style={{
borderRadius: '5px',
margin: '5px',
boxShadow: '0px 0px 10px #00000090',
userSelect: 'none',
maxWidth: '20.5rem',
}}
src={current.image} height='auto' width='auto' alt="Thumbnail" />
<Box
sx={{
display: 'flex',
flexDirection: 'column',
width: '100%',
justifyContent: 'center',
//backgroundColor: '#ffffff0f'
}}>
<Box sx={{
display: 'flex',
}}>
<Box sx={{
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',
position: 'relative',
}}>
<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> </Box>
</Box>
</Box>
</> </>
} }
{queue.map((queueItem, index, { length }) => { {queue.map((queueItem, index, { length }) => {
@ -255,7 +255,7 @@ const Queue: React.FC = () => {
borderRadius: '10px', borderRadius: '10px',
display: 'flex', display: 'flex',
overflow: 'hidden', overflow: 'hidden',
}}> }}>
<img style={{ <img style={{
borderRadius: '5px', borderRadius: '5px',
margin: '5px', margin: '5px',
@ -269,102 +269,102 @@ const Queue: React.FC = () => {
display: 'flex', display: 'flex',
width: '100%', width: '100%',
justifyContent: 'space-between', justifyContent: 'space-between',
}}>
<Box sx={{
width: '30%',
marginRight: '5px',
marginLeft: '5px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}> }}>
<Box sx={{ <Typography color='text.primary' sx={{
width: '30%', fontSize: '1.8rem',
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 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: '40%',
marginRight: '5px',
marginLeft: '5px',
display: 'flex',
flexDirection: 'column',
overflow: 'hidden', overflow: 'hidden',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
justifyContent: 'space-between', textOverflow: 'ellipsis',
}}>
{queueItem.parent.title}
</Typography>
<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: '40%',
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',
}}> }}>
<Typography color='text.primary' sx={{
fontSize: '1.8rem',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
}}>
Dub(s): {queueItem.dubLang.join(', ')} Dub(s): {queueItem.dubLang.join(', ')}
</Typography> </Typography>
<Typography color='text.primary' sx={{ <Typography color='text.primary' sx={{
fontSize: '1.8rem', fontSize: '1.8rem',
overflow: 'hidden', overflow: 'hidden',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
}}>
Sub(s): {queueItem.dlsubs.join(', ')}
</Typography>
<Typography color='text.primary' sx={{
fontSize: '1.8rem',
}}>
Quality: {queueItem.q}
</Typography>
</Box>
<Box sx={{
marginRight: '5px',
marginLeft: '5px',
width: '30%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex'
}}> }}>
Sub(s): {queueItem.dlsubs.join(', ')}
</Typography>
<Typography color='text.primary' sx={{
fontSize: '1.8rem',
}}>
Quality: {queueItem.q}
</Typography>
</Box>
<Box sx={{
marginRight: '5px',
marginLeft: '5px',
width: '30%',
justifyContent: 'center',
alignItems: 'center',
display: 'flex'
}}>
<Tooltip title="Delete from queue" arrow placement='top'> <Tooltip title="Delete from queue" arrow placement='top'>
<IconButton <IconButton
onClick={() => { onClick={() => {
msg.removeFromQueue(index); msg.removeFromQueue(index);
}} }}
sx={{ sx={{
backgroundColor: '#ff573a25', backgroundColor: '#ff573a25',
height: '40px', height: '40px',
transition: '250ms', transition: '250ms',
'&:hover' : { '&:hover' : {
backgroundColor: '#ff573a', backgroundColor: '#ff573a',
} }
}}> }}>
<DeleteIcon /> <DeleteIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</Box> </Box>
</Box>
</Box> </Box>
</Box> </Box>
</Box>
; ;
})} })}
</> : <Box sx={{ </> : <Box sx={{
@ -383,12 +383,12 @@ const Queue: React.FC = () => {
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
margin: '10px' margin: '10px'
}}> }}>
<Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/> <Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
flexDirection: 'column', 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' }}/>
<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>
@ -396,12 +396,12 @@ const Queue: React.FC = () => {
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
margin: '10px' margin: '10px'
}}> }}>
<Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/> <Skeleton variant='rectangular' height={'10rem'} width={'20rem'} sx={{ margin: '5px', borderRadius: '5px' }}/>
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
flexDirection: 'column', 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' }}/>
<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>

View file

@ -2,7 +2,7 @@ import { Box, Button, Menu, MenuItem, Typography } from '@mui/material';
import React from 'react'; import React from 'react';
import { messageChannelContext } from '../../provider/MessageChannel'; import { messageChannelContext } from '../../provider/MessageChannel';
import useStore from '../../hooks/useStore'; import useStore from '../../hooks/useStore';
import { StoreState } from '../../provider/Store' import { StoreState } from '../../provider/Store';
const MenuBar: React.FC = () => { const MenuBar: React.FC = () => {
const [ openMenu, setMenuOpen ] = React.useState<'settings'|'help'|undefined>(); const [ openMenu, setMenuOpen ] = React.useState<'settings'|'help'|undefined>();
@ -15,20 +15,20 @@ const MenuBar: React.FC = () => {
type: 'version', type: 'version',
payload: await messageChannel?.version() payload: await messageChannel?.version()
}); });
} };
getVersion(); getVersion();
const transformService = (service: StoreState['service']) => { const transformService = (service: StoreState['service']) => {
switch(service) { switch(service) {
case 'crunchy': case 'crunchy':
return "Crunchyroll" return 'Crunchyroll';
case 'funi': case 'funi':
return "Funimation" return 'Funimation';
case "hidive": case 'hidive':
return "Hidive" return 'Hidive';
} }
} };
const msg = React.useContext(messageChannelContext); const msg = React.useContext(messageChannelContext);
@ -46,12 +46,12 @@ const MenuBar: React.FC = () => {
return <Box sx={{ display: 'flex', marginBottom: '1rem', width: '100%', alignItems: 'center' }}> return <Box sx={{ display: 'flex', marginBottom: '1rem', width: '100%', alignItems: 'center' }}>
<Box sx={{ position: 'relative', left: '0%', width: '50%'}}> <Box sx={{ position: 'relative', left: '0%', width: '50%'}}>
<Button onClick={(e) => handleClick(e, 'settings')}> <Button onClick={(e) => handleClick(e, 'settings')}>
Settings Settings
</Button> </Button>
<Button onClick={(e) => handleClick(e, 'help')}> <Button onClick={(e) => handleClick(e, 'help')}>
Help Help
</Button> </Button>
</Box> </Box>
<Menu open={openMenu === 'settings'} anchorEl={anchorEl} onClose={handleClose}> <Menu open={openMenu === 'settings'} anchorEl={anchorEl} onClose={handleClose}>
<MenuItem onClick={() => { <MenuItem onClick={() => {

View file

@ -11,7 +11,7 @@ import Store from './provider/Store';
import ErrorHandler from './provider/ErrorHandler'; import ErrorHandler from './provider/ErrorHandler';
import QueueProvider from './provider/QueueProvider'; import QueueProvider from './provider/QueueProvider';
document.body.style.backgroundColor = "rgb(0, 30, 60)"; document.body.style.backgroundColor = 'rgb(0, 30, 60)';
document.body.style.display = 'flex'; document.body.style.display = 'flex';
document.body.style.justifyContent = 'center'; document.body.style.justifyContent = 'center';

View file

@ -15,11 +15,11 @@ export class RandomEventHandler {
private handler: { private handler: {
[eventName in keyof RandomEvents]: Handler<eventName>[] [eventName in keyof RandomEvents]: Handler<eventName>[]
} = { } = {
progress: [], progress: [],
finish: [], finish: [],
queueChange: [], queueChange: [],
current: [] current: []
}; };
public on<T extends keyof RandomEvents>(name: T, listener: Handler<T>) { public on<T extends keyof RandomEvents>(name: T, listener: Handler<T>) {
if (Object.prototype.hasOwnProperty.call(this.handler, name)) { if (Object.prototype.hasOwnProperty.call(this.handler, name)) {
@ -212,7 +212,7 @@ const MessageChannelProvider: FCWithChildren = ({ children }) => {
} }
const messageHandler: FrontEndMessages = { const messageHandler: FrontEndMessages = {
name: "default", name: 'default',
auth: async (data) => (await messageAndResponse(socket, { name: 'auth', data })).data, auth: async (data) => (await messageAndResponse(socket, { name: 'auth', data })).data,
version: async () => (await messageAndResponse(socket, { name: 'version', data: undefined })).data, version: async () => (await messageAndResponse(socket, { name: 'version', data: undefined })).data,
checkToken: async () => (await messageAndResponse(socket, { name: 'checkToken', data: undefined })).data, checkToken: async () => (await messageAndResponse(socket, { name: 'checkToken', data: undefined })).data,

View file

@ -113,8 +113,8 @@
"build-macos-gui": "pnpm run prebuild-gui && cd lib && node modules/build macos-x64 true", "build-macos-gui": "pnpm run prebuild-gui && cd lib && node modules/build macos-x64 true",
"build-alpine-gui": "pnpm run prebuild-gui && cd lib && node modules/build alpine-x64 true", "build-alpine-gui": "pnpm run prebuild-gui && cd lib && node modules/build alpine-x64 true",
"build-android-gui": "pnpm run prebuild-gui && cd lib && node modules/build linuxstatic-armv7 true", "build-android-gui": "pnpm run prebuild-gui && cd lib && node modules/build linuxstatic-armv7 true",
"eslint": "npx eslint *.ts modules", "eslint": "npx eslint .",
"eslint-fix": "npx eslint *.ts modules --fix", "eslint-fix": "npx eslint . --fix",
"pretest": "pnpm run tsc", "pretest": "pnpm run tsc",
"test": "pnpm run pretest && cd lib && node modules/build windows-x64 && node modules/build linuxstatic-x64 && node modules/build macos-x64" "test": "pnpm run pretest && cd lib && node modules/build windows-x64 && node modules/build linuxstatic-x64 && node modules/build macos-x64"
} }