Fix issue #14 and bump react to v18
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user