format selection enabled
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
import { Backdrop, Button, CircularProgress, Container, Grid, Paper, Snackbar, TextField, } from "@mui/material";
|
||||
import { Backdrop, Button, ButtonGroup, CircularProgress, Container, Grid, Paper, Skeleton, Snackbar, TextField, Typography, } from "@mui/material";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { io, Socket } from "socket.io-client";
|
||||
import { StackableResult } from "./components/StackableResult";
|
||||
import { connected, disconnected, downloading, finished } from "./features/status/statusSlice";
|
||||
import { IDLInfo, IDLInfoBase, IDownloadInfo, IMessage } from "./interfaces";
|
||||
import { RootState } from "./stores/store";
|
||||
import { updateInStateMap, } from "./utils";
|
||||
import { toFormatArgs, updateInStateMap, } from "./utils";
|
||||
|
||||
type Props = {
|
||||
socket: Socket
|
||||
}
|
||||
let socket: Socket;
|
||||
|
||||
export default function Home({ socket }: Props) {
|
||||
export default function Home() {
|
||||
// redux state
|
||||
const settings = useSelector((state: RootState) => state.settings)
|
||||
const status = useSelector((state: RootState) => state.status)
|
||||
@@ -22,11 +20,23 @@ export default function Home({ socket }: Props) {
|
||||
const [progressMap, setProgressMap] = useState(new Map<number, number>());
|
||||
const [messageMap, setMessageMap] = useState(new Map<number, IMessage>());
|
||||
const [downloadInfoMap, setDownloadInfoMap] = useState(new Map<number, IDLInfoBase>());
|
||||
const [downloadFormats, setDownloadFormats] = useState<IDownloadInfo>();
|
||||
const [pickedVideoFormat, setPickedVideoFormat] = useState('');
|
||||
const [pickedAudioFormat, setPickedAudioFormat] = useState('');
|
||||
const [pickedBestFormat, setPickedBestFormat] = useState('');
|
||||
|
||||
const [url, setUrl] = useState('');
|
||||
const [workingUrl, setWorkingUrl] = useState('');
|
||||
const [showBackdrop, setShowBackdrop] = useState(false);
|
||||
|
||||
/* -------------------- Effects -------------------- */
|
||||
useEffect(() => {
|
||||
socket = io(`http://${localStorage.getItem('server-addr') || 'localhost'}:3022`);
|
||||
return () => {
|
||||
socket.disconnect()
|
||||
};
|
||||
}, [])
|
||||
|
||||
/* WebSocket connect event handler*/
|
||||
useEffect(() => {
|
||||
socket.on('connect', () => {
|
||||
@@ -53,6 +63,7 @@ export default function Home({ socket }: Props) {
|
||||
socket.on('available-formats', (data: IDownloadInfo) => {
|
||||
setShowBackdrop(false)
|
||||
console.log(data)
|
||||
setDownloadFormats(data);
|
||||
})
|
||||
}, [])
|
||||
|
||||
@@ -89,11 +100,37 @@ export default function Home({ socket }: Props) {
|
||||
* Retrive url from input, cli-arguments from checkboxes and emits via WebSocket
|
||||
*/
|
||||
const sendUrl = () => {
|
||||
const codes = new Array<string>();
|
||||
if (pickedVideoFormat !== '') codes.push(pickedVideoFormat);
|
||||
if (pickedAudioFormat !== '') codes.push(pickedAudioFormat);
|
||||
if (pickedBestFormat !== '') codes.push(pickedBestFormat);
|
||||
|
||||
socket.emit('send-url', {
|
||||
url: url,
|
||||
params: settings.cliArgs.toString(),
|
||||
url: url || workingUrl,
|
||||
params: settings.cliArgs.toString() + toFormatArgs(codes),
|
||||
})
|
||||
setUrl('')
|
||||
setWorkingUrl('')
|
||||
setTimeout(() => {
|
||||
const input = document.getElementById('urlInput') as HTMLInputElement;
|
||||
input.value = '';
|
||||
setShowBackdrop(true);
|
||||
setDownloadFormats(null);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive url from input and display the formats selection view
|
||||
*/
|
||||
const sendUrlFormatSelection = () => {
|
||||
socket.emit('send-url-format-selection', {
|
||||
url: url,
|
||||
})
|
||||
setWorkingUrl(url)
|
||||
setUrl('')
|
||||
setPickedAudioFormat('');
|
||||
setPickedVideoFormat('');
|
||||
setPickedBestFormat('');
|
||||
setTimeout(() => {
|
||||
const input = document.getElementById('urlInput') as HTMLInputElement;
|
||||
input.value = '';
|
||||
@@ -120,6 +157,7 @@ export default function Home({ socket }: Props) {
|
||||
socket.emit('abort', { pid: id })
|
||||
return
|
||||
}
|
||||
setDownloadFormats(null)
|
||||
socket.emit('abort-all')
|
||||
}
|
||||
|
||||
@@ -145,13 +183,14 @@ export default function Home({ socket }: Props) {
|
||||
label={settings.i18n.t('urlInput')}
|
||||
variant="outlined"
|
||||
onChange={handleUrlChange}
|
||||
disabled={settings.formatSelection && downloadFormats != null}
|
||||
/>
|
||||
<Grid container spacing={1} pt={2}>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={url === ''}
|
||||
onClick={() => sendUrl()}
|
||||
onClick={() => settings.formatSelection ? sendUrlFormatSelection() : sendUrl()}
|
||||
>
|
||||
{settings.i18n.t('startButton')}
|
||||
</Button>
|
||||
@@ -168,6 +207,110 @@ export default function Home({ socket }: Props) {
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{/* Format Selection grid */}
|
||||
{downloadFormats ? <Grid container spacing={2} mt={2}>
|
||||
<Grid item xs={12}>
|
||||
<Paper
|
||||
sx={{
|
||||
p: 2,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" component="div" pb={1}>
|
||||
{downloadFormats.title}
|
||||
</Typography>
|
||||
{/* <Skeleton variant="rectangular" height={180} /> */}
|
||||
</Grid>
|
||||
<Grid item xs={12} pb={1}>
|
||||
<img src={downloadFormats.thumbnail} height={260} width="100%" style={{ objectFit: 'cover' }} />
|
||||
</Grid>
|
||||
{/* video only */}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Best quality
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item pr={2} py={1}>
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={pickedBestFormat !== ''}
|
||||
onClick={() => {
|
||||
setPickedBestFormat(downloadFormats.best.format_id)
|
||||
setPickedVideoFormat('')
|
||||
setPickedAudioFormat('')
|
||||
}}>
|
||||
{downloadFormats.best.format_note || downloadFormats.best.format_id} - {downloadFormats.best.vcodec}+{downloadFormats.best.acodec}
|
||||
</Button>
|
||||
</Grid>
|
||||
{/* video only */}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Video data
|
||||
</Typography>
|
||||
</Grid>
|
||||
{downloadFormats.formats
|
||||
.filter(format => format.acodec === 'none' && format.vcodec !== 'none')
|
||||
.map((format, idx) => (
|
||||
<Grid item pr={2} py={1} key={idx}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
setPickedVideoFormat(format.format_id)
|
||||
setPickedBestFormat('')
|
||||
}}
|
||||
disabled={pickedVideoFormat === format.format_id}
|
||||
>
|
||||
{format.format_note} - {format.vcodec === 'none' ? format.acodec : format.vcodec}
|
||||
</Button>
|
||||
</Grid>
|
||||
))
|
||||
}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="body1" component="div">
|
||||
Audio data
|
||||
</Typography>
|
||||
</Grid>
|
||||
{downloadFormats.formats
|
||||
.filter(format => format.acodec !== 'none' && format.vcodec === 'none')
|
||||
.map((format, idx) => (
|
||||
<Grid item pr={2} py={1} key={idx}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
setPickedAudioFormat(format.format_id)
|
||||
setPickedBestFormat('')
|
||||
}}
|
||||
disabled={pickedAudioFormat === format.format_id}
|
||||
>
|
||||
{format.format_note} - {format.vcodec === 'none' ? format.acodec : format.vcodec}
|
||||
</Button>
|
||||
</Grid>
|
||||
))
|
||||
}
|
||||
<Grid item xs={12} pt={2}>
|
||||
<ButtonGroup disableElevation variant="contained">
|
||||
<Button
|
||||
onClick={() => sendUrl()}
|
||||
disabled={!pickedBestFormat && !(pickedAudioFormat || pickedVideoFormat)}
|
||||
> Download
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setPickedAudioFormat('');
|
||||
setPickedVideoFormat('');
|
||||
setPickedBestFormat('');
|
||||
}}
|
||||
> Clear
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid> : null}
|
||||
<Grid container spacing={{ xs: 2, md: 2 }} columns={{ xs: 4, sm: 8, md: 12 }} pt={2}>
|
||||
{ /*Super big brain flatMap moment*/
|
||||
Array
|
||||
|
||||
Reference in New Issue
Block a user