Fix issue #14 and bump react to v18

This commit is contained in:
2022-10-14 13:44:19 +02:00
parent 8ee9710fe2
commit de32fbd5ce
11 changed files with 1454 additions and 624 deletions

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from "react"
import { useEffect, useMemo, useState } from "react"
import { ThemeProvider } from "@emotion/react";
import {
Box,
@@ -36,7 +36,9 @@ import ArchivedDownloads from "./Archived";
const drawerWidth: number = 240;
const socket = io(`http://${localStorage.getItem('server-addr') || window.location.hostname}:${localStorage.getItem('server-port') || window.location.port}`)
const socket = io(
`http://${localStorage.getItem('server-addr') || window.location.hostname}:${localStorage.getItem('server-port') || window.location.port}`
)
interface AppBarProps extends MuiAppBarProps {
open?: boolean;

View File

@@ -18,12 +18,14 @@ import {
Typography
} from "@mui/material";
import { Buffer } from 'buffer';
import React, { Fragment, useEffect, useState } from "react";
import { Fragment, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Socket } from "socket.io-client";
import { CliArguments } from "./classes";
import { StackableResult } from "./components/StackableResult";
import { serverStates } from "./events";
import { connected, downloading, finished } from "./features/status/statusSlice";
import { I18nBuilder } from "./i18n";
import { IDLMetadata, IDLMetadataAndPID, IMessage } from "./interfaces";
import { RootState } from "./stores/store";
import { isValidURL, toFormatArgs, updateInStateMap } from "./utils";
@@ -55,6 +57,10 @@ export default function Home({ socket }: Props) {
const [showBackdrop, setShowBackdrop] = useState(false);
const [showToast, setShowToast] = useState(true);
// memos
const i18n = useMemo(() => new I18nBuilder(settings.language), [settings.language])
const cliArgs = useMemo(() => new CliArguments().fromString(settings.cliArgs), [settings.cliArgs])
/* -------------------- Effects -------------------- */
/* WebSocket connect event handler*/
useEffect(() => {
@@ -134,7 +140,7 @@ export default function Home({ socket }: Props) {
socket.emit('send-url', {
url: immediate || url || workingUrl,
path: availableDownloadPaths[downloadPath],
params: settings.cliArgs.toString() + toFormatArgs(codes),
params: cliArgs.toString() + toFormatArgs(codes),
})
setUrl('')
setWorkingUrl('')
@@ -231,7 +237,7 @@ export default function Home({ socket }: Props) {
<TextField
fullWidth
id="urlInput"
label={settings.i18n.t('urlInput')}
label={i18n.t('urlInput')}
variant="outlined"
onChange={handleUrlChange}
disabled={!status.connected || (settings.formatSelection && downloadFormats != null)}
@@ -253,8 +259,8 @@ export default function Home({ socket }: Props) {
<FormControl fullWidth>
<Select
defaultValue={0}
value={availableDownloadPaths[downloadPath]}
onChange={(e) => setDownloadPath(e.target.value)}
value={downloadPath}
onChange={(e) => setDownloadPath(Number(e.target.value))}
>
{availableDownloadPaths.map((val: string, idx: number) => (
@@ -271,7 +277,7 @@ export default function Home({ socket }: Props) {
disabled={url === ''}
onClick={() => settings.formatSelection ? sendUrlFormatSelection() : sendUrl()}
>
{settings.i18n.t('startButton')}
{i18n.t('startButton')}
</Button>
</Grid>
<Grid item>
@@ -279,7 +285,7 @@ export default function Home({ socket }: Props) {
variant="contained"
onClick={() => abort()}
>
{settings.i18n.t('abortAllButton')}
{i18n.t('abortAllButton')}
</Button>
</Grid>
</Grid>

View File

@@ -17,12 +17,23 @@ import {
TextField,
Typography
} from "@mui/material";
import React, { useState } from "react";
import { useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { debounceTime, distinctUntilChanged, map, of, takeWhile } from "rxjs";
import { Socket } from "socket.io-client";
import { LanguageUnion, setCliArgs, setFormatSelection, setLanguage, setServerAddr, setServerPort, setTheme, ThemeUnion } from "./features/settings/settingsSlice";
import { CliArguments } from "./classes";
import {
LanguageUnion,
setCliArgs,
setFormatSelection,
setLanguage,
setServerAddr,
setServerPort,
setTheme,
ThemeUnion
} from "./features/settings/settingsSlice";
import { alreadyUpdated, updated } from "./features/status/statusSlice";
import { I18nBuilder } from "./i18n";
import { RootState } from "./stores/store";
import { validateDomain, validateIP } from "./utils";
@@ -37,6 +48,8 @@ export default function Settings({ socket }: Props) {
const [invalidIP, setInvalidIP] = useState(false);
const i18n = useMemo(() => new I18nBuilder(settings.language), [settings.language])
const cliArgs = useMemo(() => new CliArguments().fromString(settings.cliArgs), [settings.cliArgs])
/**
* Update the server ip address state and localstorage whenever the input value changes.
* Validate the ip-addr then set.s
@@ -114,14 +127,14 @@ export default function Settings({ socket }: Props) {
}}
>
<Typography pb={2} variant="h6" color="primary">
{settings.i18n.t('settingsAnchor')}
{i18n.t('settingsAnchor')}
</Typography>
<FormGroup>
<Grid container spacing={2}>
<Grid item xs={12} md={11}>
<TextField
fullWidth
label={settings.i18n.t('serverAddressTitle')}
label={i18n.t('serverAddressTitle')}
defaultValue={settings.serverAddr}
error={invalidIP}
onChange={handleAddrChange}
@@ -134,7 +147,7 @@ export default function Settings({ socket }: Props) {
<Grid item xs={12} md={1}>
<TextField
fullWidth
label={settings.i18n.t('serverPortTitle')}
label={i18n.t('serverPortTitle')}
defaultValue={settings.serverPort}
onChange={handlePortChange}
error={isNaN(Number(settings.serverPort)) || Number(settings.serverPort) > 65535}
@@ -173,35 +186,48 @@ export default function Settings({ socket }: Props) {
</Select>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<TextField
fullWidth
label={'Max download speed' || i18n.t('serverPortTitle')}
defaultValue={settings.serverPort}
onChange={handlePortChange}
error={isNaN(Number(settings.serverPort)) || Number(settings.serverPort) > 65535}
sx={{ mb: 2 }}
/>
</Grid>
</Grid>
<FormControlLabel
control={
<Switch
defaultChecked={settings.cliArgs.noMTime}
onChange={() => dispatch(setCliArgs(settings.cliArgs.toggleNoMTime()))}
defaultChecked={cliArgs.noMTime}
onChange={() => dispatch(setCliArgs(cliArgs.toggleNoMTime().toString()))}
/>
}
label={settings.i18n.t('noMTimeCheckbox')}
label={i18n.t('noMTimeCheckbox')}
sx={{ mt: 3 }}
/>
<FormControlLabel
control={
<Switch
defaultChecked={settings.cliArgs.extractAudio}
onChange={() => dispatch(setCliArgs(settings.cliArgs.toggleExtractAudio()))}
defaultChecked={cliArgs.extractAudio}
onChange={() => dispatch(setCliArgs(cliArgs.toggleExtractAudio().toString()))}
disabled={settings.formatSelection}
/>
}
label={settings.i18n.t('extractAudioCheckbox')}
label={i18n.t('extractAudioCheckbox')}
/>
<FormControlLabel
control={
<Switch
defaultChecked={settings.formatSelection}
onChange={() => dispatch(setFormatSelection(!settings.formatSelection))}
onChange={() => {
dispatch(setCliArgs(cliArgs.disableExtractAudio().toString()))
dispatch(setFormatSelection(!settings.formatSelection))
}}
/>
}
label={settings.i18n.t('formatSelectionEnabler')}
label={i18n.t('formatSelectionEnabler')}
/>
<Grid>
<Stack direction="row">
@@ -210,7 +236,7 @@ export default function Settings({ socket }: Props) {
variant="contained"
onClick={() => dispatch(updated())}
>
{settings.i18n.t('updateBinButton')}
{i18n.t('updateBinButton')}
</Button>
{/* <Button sx={{ mr: 1, mt: 1 }} variant="outlined">Primary</Button> */}
</Stack>
@@ -222,7 +248,7 @@ export default function Settings({ socket }: Props) {
<Snackbar
open={status.updated}
autoHideDuration={1500}
message={settings.i18n.t('toastUpdated')}
message={i18n.t('toastUpdated')}
onClose={updateBinary}
/>
</Container>

View File

@@ -10,9 +10,9 @@ export interface SettingsState {
serverPort: string,
language: LanguageUnion,
theme: ThemeUnion,
cliArgs: CliArguments,
i18n: I18nBuilder,
formatSelection: boolean
cliArgs: string,
formatSelection: boolean,
ratelimit: string,
}
const initialState: SettingsState = {
@@ -20,9 +20,9 @@ const initialState: SettingsState = {
serverPort: localStorage.getItem("server-port") || window.location.port,
language: (localStorage.getItem("language") || "english") as LanguageUnion,
theme: (localStorage.getItem("theme") || "light") as ThemeUnion,
cliArgs: localStorage.getItem("cli-args") ? new CliArguments().fromString(localStorage.getItem("cli-args") ?? "") : new CliArguments(false, true),
i18n: new I18nBuilder((localStorage.getItem("language") || "english")),
cliArgs: localStorage.getItem("cli-args") ?? "",
formatSelection: localStorage.getItem("format-selection") === "true",
ratelimit: localStorage.getItem("rate-limit") ?? "",
}
export const settingsSlice = createSlice({
@@ -39,12 +39,11 @@ export const settingsSlice = createSlice({
},
setLanguage: (state, action: PayloadAction<LanguageUnion>) => {
state.language = action.payload
state.i18n.setLanguage(action.payload)
localStorage.setItem("language", action.payload)
},
setCliArgs: (state, action: PayloadAction<CliArguments>) => {
setCliArgs: (state, action: PayloadAction<string>) => {
state.cliArgs = action.payload
localStorage.setItem("cli-args", action.payload.toString())
localStorage.setItem("cli-args", action.payload)
},
setTheme: (state, action: PayloadAction<ThemeUnion>) => {
state.theme = action.payload
@@ -54,9 +53,13 @@ export const settingsSlice = createSlice({
state.formatSelection = action.payload
localStorage.setItem("format-selection", action.payload.toString())
},
setRateLimit: (state, action: PayloadAction<string>) => {
state.ratelimit = action.payload
localStorage.setItem("rate-limit", action.payload)
},
}
})
export const { setLanguage, setCliArgs, setTheme, setServerAddr, setServerPort, setFormatSelection } = settingsSlice.actions
export const { setLanguage, setCliArgs, setTheme, setServerAddr, setServerPort, setFormatSelection, setRateLimit } = settingsSlice.actions
export default settingsSlice.reducer