import { Button, Container, FormControl, FormControlLabel, FormGroup, Grid, InputAdornment, InputLabel, MenuItem, Paper, Select, SelectChangeEvent, Snackbar, Stack, Switch, TextField, Typography } from "@mui/material"; 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 { 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"; type Props = { socket: Socket } export default function Settings({ socket }: Props) { const settings = useSelector((state: RootState) => state.settings) const status = useSelector((state: RootState) => state.status) const dispatch = useDispatch() 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 * @param event Input change event */ const handleAddrChange = (event: any) => { const $serverAddr = of(event) .pipe( map(event => event.target.value), debounceTime(500), distinctUntilChanged() ) .subscribe(addr => { if (validateIP(addr)) { setInvalidIP(false) dispatch(setServerAddr(addr)) } else if (validateDomain(addr)) { setInvalidIP(false) dispatch(setServerAddr(addr)) } else { setInvalidIP(true) } }) return $serverAddr.unsubscribe() } /** * Set server port */ const handlePortChange = (event: any) => { const $port = of(event) .pipe( map(event => event.target.value), map(val => Number(val)), takeWhile(val => isFinite(val) && val <= 65535), ) .subscribe(port => { dispatch(setServerPort(port.toString())) }) return $port.unsubscribe() } /** * Language toggler handler */ const handleLanguageChange = (event: SelectChangeEvent) => { dispatch(setLanguage(event.target.value as LanguageUnion)); } /** * Theme toggler handler */ const handleThemeChange = (event: SelectChangeEvent) => { dispatch(setTheme(event.target.value as ThemeUnion)); } /** * Send via WebSocket a message in order to update the yt-dlp binary from server */ const updateBinary = () => { socket.emit('update-bin') dispatch(alreadyUpdated()) } return ( {i18n.t('settingsAnchor')} ws://, }} sx={{ mb: 2 }} /> 65535} sx={{ mb: 2 }} /> Language Theme 65535} sx={{ mb: 2 }} /> dispatch(setCliArgs(cliArgs.toggleNoMTime().toString()))} /> } label={i18n.t('noMTimeCheckbox')} sx={{ mt: 3 }} /> dispatch(setCliArgs(cliArgs.toggleExtractAudio().toString()))} disabled={settings.formatSelection} /> } label={i18n.t('extractAudioCheckbox')} /> { dispatch(setCliArgs(cliArgs.disableExtractAudio().toString())) dispatch(setFormatSelection(!settings.formatSelection)) }} /> } label={i18n.t('formatSelectionEnabler')} /> {/* */} ); }