This commit is contained in:
Daniel Shleifman
2021-07-02 17:56:32 +03:00
parent bc717647ea
commit dbfc1db5d2
4 changed files with 533 additions and 459 deletions

View File

@@ -28,7 +28,7 @@ const Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading }
<Divider /> <Divider />
<List> <List>
<SettingsDialog /> <SettingsDialog isOffline={isOffline} isLoading={isLoading} />
<AboutDialog /> <AboutDialog />

View File

@@ -18,7 +18,7 @@ import {
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from '@material-ui/core' } from '@material-ui/core'
import { settingsHost, setTorrServerHost, getTorrServerHost } from 'utils/Hosts' import { settingsHost } from 'utils/Hosts'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Header } from 'style/DialogStyles' import { Header } from 'style/DialogStyles'
@@ -26,94 +26,26 @@ import AppBar from '@material-ui/core/AppBar'
import Tabs from '@material-ui/core/Tabs' import Tabs from '@material-ui/core/Tabs'
import Tab from '@material-ui/core/Tab' import Tab from '@material-ui/core/Tab'
import SwipeableViews from 'react-swipeable-views' import SwipeableViews from 'react-swipeable-views'
import styled, { css } from 'styled-components'
import { USBIcon, RAMIcon } from 'icons' import { USBIcon, RAMIcon } from 'icons'
const FooterSection = styled.div` import {
padding: 20px; FooterSection,
display: flex; Divider,
align-items: center; PreloadCacheValue,
justify-content: space-between; MainSettingsContent,
background: #e8e5eb; SecondarySettingsContent,
StorageButton,
> :last-child > :not(:last-child) { StorageIconWrapper,
margin-right: 10px; CacheSizeSettings,
} CacheStorageSelector,
` CacheStorageSettings,
const Divider = styled.div` SettingSection,
height: 1px; SettingLabel,
background-color: rgba(0, 0, 0, 0.12); SettingSectionLabel,
margin: 30px 0; PreloadCachePercentage,
` cacheBeforeReaderColor,
cacheAfterReaderColor,
const PreloadCachePercentage = styled.div.attrs( } from './style'
({
value,
// theme: {
// dialogTorrentDetailsContent: { gradientEndColor },
// },
}) => {
const gradientStartColor = 'lightblue'
const gradientEndColor = 'orangered'
return {
// this block is here according to styled-components recomendation about fast changable components
style: {
background: `linear-gradient(to right, ${gradientEndColor} 0%, ${gradientEndColor} ${value}%, ${gradientStartColor} ${value}%, ${gradientStartColor} 100%)`,
},
}
},
)`
${({ label, isPreloadEnabled }) => css`
border: 1px solid;
padding: 10px 20px;
border-radius: 5px;
color: #000;
margin-bottom: 10px;
position: relative;
:before {
content: '${label}';
display: grid;
place-items: center;
font-size: 20px;
}
${isPreloadEnabled &&
css`
:after {
content: '';
width: 100%;
height: 3px;
background: green;
position: absolute;
bottom: 0;
left: 0;
}
`}
`}
`
const PreloadCacheValue = styled.div`
${({ color }) => css`
display: grid;
grid-template-columns: max-content 100px 1fr;
gap: 10px;
align-items: center;
:not(:last-child) {
margin-bottom: 5px;
}
:before {
content: '';
background: ${color};
width: 15px;
height: 15px;
border-radius: 50%;
}
`}
`
const a11yProps = index => ({ const a11yProps = index => ({
id: `full-width-tab-${index}`, id: `full-width-tab-${index}`,
@@ -126,103 +58,57 @@ const TabPanel = ({ children, value, index, ...other }) => (
</div> </div>
) )
const MainSettingsContent = styled.div` const defaultSettings = {
min-height: 500px; CacheSize: 96,
display: grid; ReaderReadAHead: 95,
grid-template-columns: repeat(2, 1fr); UseDisk: false,
gap: 40px; UploadRateLimit: 0,
padding: 20px; TorrentsSavePath: '',
ConnectionsLimit: 23,
@media (max-width: 930px) { DhtConnectionLimit: 500,
grid-template-columns: 1fr; DisableDHT: false,
} DisablePEX: false,
` DisableTCP: false,
const SecondarySettingsContent = styled.div` DisableUPNP: false,
min-height: 500px; DisableUTP: true,
padding: 20px; DisableUpload: false,
` DownloadRateLimit: 0,
EnableDebug: false,
const StorageButton = styled.div` EnableIPv6: false,
display: grid; ForceEncrypt: false,
place-items: center; PeersListenPort: 0,
gap: 10px; PreloadBuffer: false,
` RemoveCacheOnDrop: false,
RetrackersMode: 1,
const StorageIconWrapper = styled.div` Strategy: 0,
${({ selected }) => css` TorrentDisconnectTimeout: 30,
width: 150px; }
height: 150px;
border-radius: 50%;
background: ${selected ? 'blue' : 'lightgray'};
transition: 0.2s;
${!selected &&
css`
cursor: pointer;
:hover {
background: orangered;
}
`}
svg {
transform: rotate(-45deg) scale(0.75);
}
`}
`
const CacheSizeSettings = styled.div``
const CacheStorageSelector = styled.div`
display: grid;
grid-template-rows: max-content 1fr;
grid-template-columns: 1fr 1fr;
grid-template-areas: 'label label';
place-items: center;
@media (max-width: 930px) {
grid-template-columns: repeat(2, max-content);
column-gap: 30px;
}
`
const CacheStorageSettings = styled.div``
const SettingSection = styled.section``
const SettingLabel = styled.div``
const SettingSectionLabel = styled.div`
font-size: 25px;
padding-bottom: 20px;
`
export default function SettingsDialog({ handleClose }) { export default function SettingsDialog({ handleClose }) {
const { t } = useTranslation() const { t } = useTranslation()
const fullScreen = useMediaQuery('@media (max-width:930px)') const fullScreen = useMediaQuery('@media (max-width:930px)')
const [settings, setSets] = useState({}) const [settings, setSettings] = useState()
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const [tsHost, setTSHost] = useState(getTorrServerHost())
useEffect(() => { useEffect(() => {
axios axios
.post(settingsHost(), { action: 'get' }) .post(settingsHost(), { action: 'get' })
.then(({ data }) => { .then(({ data }) => {
setSets({ ...data, CacheSize: data.CacheSize / (1024 * 1024) }) setSettings({ ...data, CacheSize: data.CacheSize / (1024 * 1024) })
setShow(true) setShow(true)
}) })
.catch(() => setShow(false)) .catch(() => setShow(false))
}, [tsHost]) }, [])
const handleSave = () => { const handleSave = () => {
handleClose() handleClose()
const sets = JSON.parse(JSON.stringify(settings)) const sets = JSON.parse(JSON.stringify(settings))
sets.CacheSize *= 1024 * 1024 sets.CacheSize = cacheSize * 1024 * 1024
sets.ReaderReadAHead = cachePercentage
axios.post(settingsHost(), { action: 'set', sets }) axios.post(settingsHost(), { action: 'set', sets })
} }
const onInputHost = ({ target: { value } }) => {
const host = value.replace(/\/$/gi, '')
setTorrServerHost(host)
setTSHost(host)
}
const inputForm = ({ target: { type, value, checked, id } }) => { const inputForm = ({ target: { type, value, checked, id } }) => {
const sets = JSON.parse(JSON.stringify(settings)) const sets = JSON.parse(JSON.stringify(settings))
@@ -242,7 +128,7 @@ export default function SettingsDialog({ handleClose }) {
} else if (type === 'url') { } else if (type === 'url') {
sets[id] = value sets[id] = value
} }
setSets(sets) setSettings(sets)
} }
const { const {
@@ -267,7 +153,9 @@ export default function SettingsDialog({ handleClose }) {
UseDisk, UseDisk,
TorrentsSavePath, TorrentsSavePath,
RemoveCacheOnDrop, RemoveCacheOnDrop,
} = settings } = settings || {}
const updateSettings = newProps => setSettings({ ...settings, ...newProps })
const { direction } = useTheme() const { direction } = useTheme()
const [selectedTab, setSelectedTab] = useState(0) const [selectedTab, setSelectedTab] = useState(0)
@@ -276,14 +164,16 @@ export default function SettingsDialog({ handleClose }) {
const handleChangeIndex = index => setSelectedTab(index) const handleChangeIndex = index => setSelectedTab(index)
const [cacheSize, setCacheSize] = useState(96) const [cacheSize, setCacheSize] = useState(32)
const [cachePercentage, setCachePercentage] = useState(95) const [cachePercentage, setCachePercentage] = useState(40)
const [isProMode, setIsProMode] = useState(JSON.parse(localStorage.getItem('isProMode')) || false) const [isProMode, setIsProMode] = useState(JSON.parse(localStorage.getItem('isProMode')) || false)
const [isRamSelected, setIsRamSelected] = useState(true)
const handleSliderChange = (_, newValue) => { useEffect(() => {
setCacheSize(newValue) if (!CacheSize || !ReaderReadAHead) return
}
setCacheSize(CacheSize)
setCachePercentage(ReaderReadAHead)
}, [CacheSize, ReaderReadAHead])
const handleBlur = ({ target: { value } }) => { const handleBlur = ({ target: { value } }) => {
if (value < 32) return setCacheSize(32) if (value < 32) return setCacheSize(32)
@@ -300,305 +190,316 @@ export default function SettingsDialog({ handleClose }) {
<Dialog open onClose={handleClose} fullScreen={fullScreen} fullWidth maxWidth='md'> <Dialog open onClose={handleClose} fullScreen={fullScreen} fullWidth maxWidth='md'>
<Header>{t('Settings')}</Header> <Header>{t('Settings')}</Header>
<> {settings ? (
<AppBar position='static' color='default'> <>
<Tabs <AppBar position='static' color='default'>
value={selectedTab} <Tabs
onChange={handleChange} value={selectedTab}
indicatorColor='primary' onChange={handleChange}
textColor='primary' indicatorColor='primary'
variant='fullWidth' textColor='primary'
variant='fullWidth'
>
<Tab label='Основные' {...a11yProps(0)} />
<Tab
disabled={!isProMode}
label={isProMode ? 'Дополнительные' : 'Дополнительные (включите pro mode)'}
{...a11yProps(1)}
/>
</Tabs>
</AppBar>
<SwipeableViews
axis={direction === 'rtl' ? 'x-reverse' : 'x'}
index={selectedTab}
onChangeIndex={handleChangeIndex}
> >
<Tab label='Основные' {...a11yProps(0)} /> <TabPanel value={selectedTab} index={0} dir={direction}>
<MainSettingsContent>
<CacheSizeSettings>
<SettingSectionLabel>Настройки кеша</SettingSectionLabel>
<Tab <PreloadCachePercentage
disabled={!isProMode} value={100 - cachePercentage}
label={isProMode ? 'Дополнительные' : 'Дополнительные (включите pro mode)'} label={`Кеш ${cacheSize} МБ`}
{...a11yProps(1)} isPreloadEnabled={PreloadBuffer}
/>
</Tabs>
</AppBar>
<SwipeableViews
axis={direction === 'rtl' ? 'x-reverse' : 'x'}
index={selectedTab}
onChangeIndex={handleChangeIndex}
>
<TabPanel value={selectedTab} index={0} dir={direction}>
<MainSettingsContent>
<CacheSizeSettings>
<SettingSectionLabel>Настройки кеша</SettingSectionLabel>
<PreloadCachePercentage
value={100 - cachePercentage}
label={`Кеш ${cacheSize} МБ`}
isPreloadEnabled={PreloadBuffer}
/>
<PreloadCacheValue color='orangered'>
<div>
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} МБ)
</div>
<div>От кеша будет оставаться позади воспроизводимого блока</div>
</PreloadCacheValue>
<PreloadCacheValue color='lightblue'>
<div>
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} МБ)
</div>
<div>От кеша будет спереди от воспроизводимого блока</div>
</PreloadCacheValue>
<Divider />
<SettingSection>
<SettingLabel>Размер кеша</SettingLabel>
<Grid container spacing={2} alignItems='center'>
<Grid item xs>
<Slider min={32} max={1024} value={cacheSize} onChange={handleSliderChange} step={8} />
</Grid>
{isProMode && (
<Grid item>
<Input
value={cacheSize}
margin='dense'
onChange={handleInputChange}
onBlur={handleBlur}
style={{ width: '65px' }}
inputProps={{
step: 8,
min: 32,
max: 20000,
type: 'number',
}}
/>
</Grid>
)}
</Grid>
</SettingSection>
<SettingSection>
<SettingLabel>Кеш предзагрузки</SettingLabel>
<Grid container spacing={2} alignItems='center'>
<Grid item xs>
<Slider
min={40}
max={95}
value={cachePercentage}
onChange={(_, newValue) => setCachePercentage(newValue)}
/>
</Grid>
{isProMode && (
<Grid item>
<Input
value={cachePercentage}
margin='dense'
onChange={({ target: { value } }) => setCachePercentage(value === '' ? '' : Number(value))}
onBlur={({ target: { value } }) => {
if (value < 0) return setCachePercentage(0)
if (value > 100) return setCachePercentage(100)
}}
style={{ width: '65px' }}
inputProps={{
min: 0,
max: 100,
type: 'number',
}}
/>
</Grid>
)}
</Grid>
</SettingSection>
<SettingSection>
<FormControlLabel
control={<Switch checked={PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />}
label={t('PreloadBuffer')}
/> />
</SettingSection>
</CacheSizeSettings>
{isRamSelected ? ( <PreloadCacheValue color={cacheBeforeReaderColor}>
<CacheStorageSelector> <div>
<SettingSectionLabel style={{ placeSelf: 'start', gridArea: 'label' }}> {100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} МБ)
Место хранения кеша </div>
</SettingSectionLabel> <div>От кеша будет оставаться позади воспроизводимого блока</div>
</PreloadCacheValue>
<StorageButton> <PreloadCacheValue color={cacheAfterReaderColor}>
<StorageIconWrapper selected> <div>
<RAMIcon /> {cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} МБ)
</StorageIconWrapper> </div>
<div>Оперативная память</div> <div>От кеша будет спереди от воспроизводимого блока</div>
</StorageButton> </PreloadCacheValue>
<StorageButton> <Divider />
<StorageIconWrapper onClick={() => setIsRamSelected(false)}>
<USBIcon />
</StorageIconWrapper>
<div>Диск</div>
</StorageButton>
</CacheStorageSelector>
) : (
<CacheStorageSettings>
<SettingSectionLabel>Место хранения кеша</SettingSectionLabel>
<ButtonGroup fullWidth color='primary'> <SettingSection>
<Button onClick={() => setIsRamSelected(true)}> <SettingLabel>Размер кеша</SettingLabel>
<div>
<RAMIcon width='50px' />
<div>Оперативная память</div>
</div>
</Button>
<Button variant='contained'> <Grid container spacing={2} alignItems='center'>
<div> <Grid item xs>
<USBIcon width='50px' color='white' /> <Slider
<div>Диск</div> min={32}
</div> max={1024}
</Button> value={cacheSize}
</ButtonGroup> onChange={(_, newValue) => setCacheSize(newValue)}
step={8}
/>
</Grid>
{isProMode && (
<Grid item>
<Input
value={cacheSize}
margin='dense'
onChange={handleInputChange}
onBlur={handleBlur}
style={{ width: '65px' }}
inputProps={{ step: 8, min: 32, max: 20000, type: 'number' }}
/>
</Grid>
)}
</Grid>
</SettingSection>
<SettingSection>
<SettingLabel>Кеш предзагрузки</SettingLabel>
<Grid container spacing={2} alignItems='center'>
<Grid item xs>
<Slider
min={40}
max={95}
value={cachePercentage}
onChange={(_, newValue) => setCachePercentage(newValue)}
/>
</Grid>
{isProMode && (
<Grid item>
<Input
value={cachePercentage}
margin='dense'
onChange={({ target: { value } }) => setCachePercentage(value === '' ? '' : Number(value))}
onBlur={({ target: { value } }) => {
if (value < 0) return setCachePercentage(0)
if (value > 100) return setCachePercentage(100)
}}
style={{ width: '65px' }}
inputProps={{ min: 0, max: 100, type: 'number' }}
/>
</Grid>
)}
</Grid>
</SettingSection>
<FormControlLabel <FormControlLabel
control={ control={
<Switch checked={RemoveCacheOnDrop} onChange={inputForm} id='RemoveCacheOnDrop' color='primary' /> <Switch checked={!!PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />
} }
label={t('RemoveCacheOnDrop')} label={t('PreloadBuffer')}
/> />
<small>{t('RemoveCacheOnDropDesc')}</small> </CacheSizeSettings>
<TextField
onChange={inputForm}
margin='dense'
id='TorrentsSavePath'
label={t('TorrentsSavePath')}
value={TorrentsSavePath}
type='url'
fullWidth
/>
</CacheStorageSettings>
)}
</MainSettingsContent>
</TabPanel>
<TabPanel value={selectedTab} index={1} dir={direction}> {UseDisk ? (
<SecondarySettingsContent> <CacheStorageSettings>
<SettingSectionLabel>Дополнительные настройки</SettingSectionLabel> <SettingSectionLabel>Место хранения кеша</SettingSectionLabel>
<FormControlLabel <div style={{ display: 'grid', gridAutoFlow: 'column' }}>
control={<Switch checked={EnableIPv6} onChange={inputForm} id='EnableIPv6' color='primary' />} <StorageButton small onClick={() => updateSettings({ UseDisk: false })}>
label={t('EnableIPv6')} <StorageIconWrapper small>
/> <RAMIcon color='#323637' />
<br /> </StorageIconWrapper>
<FormControlLabel
control={<Switch checked={!DisableTCP} onChange={inputForm} id='DisableTCP' color='primary' />} <div>Оперативная память</div>
label={t('TCP')} </StorageButton>
/>
<br /> <StorageButton small selected>
<FormControlLabel <StorageIconWrapper small selected>
control={<Switch checked={!DisableUTP} onChange={inputForm} id='DisableUTP' color='primary' />} <USBIcon color='#dee3e5' />
label={t('UTP')} </StorageIconWrapper>
/>
<br /> <div>Диск</div>
<FormControlLabel </StorageButton>
control={<Switch checked={!DisablePEX} onChange={inputForm} id='DisablePEX' color='primary' />} </div>
label={t('PEX')}
/> <FormControlLabel
<br /> control={
<FormControlLabel <Switch
control={<Switch checked={ForceEncrypt} onChange={inputForm} id='ForceEncrypt' color='primary' />} checked={RemoveCacheOnDrop}
label={t('ForceEncrypt')} onChange={inputForm}
/> id='RemoveCacheOnDrop'
<br /> color='primary'
<TextField />
onChange={inputForm} }
margin='dense' label={t('RemoveCacheOnDrop')}
id='TorrentDisconnectTimeout' />
label={t('TorrentDisconnectTimeout')} <small>{t('RemoveCacheOnDropDesc')}</small>
value={TorrentDisconnectTimeout}
type='number' <TextField
fullWidth onChange={inputForm}
/> margin='dense'
<br /> id='TorrentsSavePath'
<TextField label={t('TorrentsSavePath')}
onChange={inputForm} value={TorrentsSavePath}
margin='dense' type='url'
id='ConnectionsLimit' fullWidth
label={t('ConnectionsLimit')} />
value={ConnectionsLimit} </CacheStorageSettings>
type='number' ) : (
fullWidth <CacheStorageSelector>
/> <SettingSectionLabel style={{ placeSelf: 'start', gridArea: 'label' }}>
<br /> Место хранения кеша
<FormControlLabel </SettingSectionLabel>
control={<Switch checked={!DisableDHT} onChange={inputForm} id='DisableDHT' color='primary' />}
label={t('DHT')} <StorageButton selected>
/> <StorageIconWrapper selected>
<br /> <RAMIcon color='#dee3e5' />
<TextField </StorageIconWrapper>
onChange={inputForm}
margin='dense' <div>Оперативная память</div>
id='DhtConnectionLimit' </StorageButton>
label={t('DhtConnectionLimit')}
value={DhtConnectionLimit} <StorageButton onClick={() => updateSettings({ UseDisk: true })}>
type='number' <StorageIconWrapper>
fullWidth <USBIcon color='#323637' />
/> </StorageIconWrapper>
<br />
<TextField <div>Диск</div>
onChange={inputForm} </StorageButton>
margin='dense' </CacheStorageSelector>
id='DownloadRateLimit' )}
label={t('DownloadRateLimit')} </MainSettingsContent>
value={DownloadRateLimit} </TabPanel>
type='number'
fullWidth <TabPanel value={selectedTab} index={1} dir={direction}>
/> <SecondarySettingsContent>
<br /> <SettingSectionLabel>Дополнительные настройки</SettingSectionLabel>
<FormControlLabel
control={<Switch checked={!DisableUpload} onChange={inputForm} id='DisableUpload' color='primary' />} <FormControlLabel
label={t('Upload')} control={<Switch checked={EnableIPv6} onChange={inputForm} id='EnableIPv6' color='primary' />}
/> label={t('EnableIPv6')}
<br /> />
<TextField <br />
onChange={inputForm} <FormControlLabel
margin='dense' control={<Switch checked={!DisableTCP} onChange={inputForm} id='DisableTCP' color='primary' />}
id='UploadRateLimit' label={t('TCP')}
label={t('UploadRateLimit')} />
value={UploadRateLimit} <br />
type='number' <FormControlLabel
fullWidth control={<Switch checked={!DisableUTP} onChange={inputForm} id='DisableUTP' color='primary' />}
/> label={t('UTP')}
<br /> />
<TextField <br />
onChange={inputForm} <FormControlLabel
margin='dense' control={<Switch checked={!DisablePEX} onChange={inputForm} id='DisablePEX' color='primary' />}
id='PeersListenPort' label={t('PEX')}
label={t('PeersListenPort')} />
value={PeersListenPort} <br />
type='number' <FormControlLabel
fullWidth control={<Switch checked={ForceEncrypt} onChange={inputForm} id='ForceEncrypt' color='primary' />}
/> label={t('ForceEncrypt')}
<br /> />
<FormControlLabel <br />
control={<Switch checked={!DisableUPNP} onChange={inputForm} id='DisableUPNP' color='primary' />} <TextField
label={t('UPNP')} onChange={inputForm}
/> margin='dense'
<br /> id='TorrentDisconnectTimeout'
<InputLabel htmlFor='RetrackersMode'>{t('RetrackersMode')}</InputLabel> label={t('TorrentDisconnectTimeout')}
<Select onChange={inputForm} type='number' native id='RetrackersMode' value={RetrackersMode}> value={TorrentDisconnectTimeout}
<option value={0}>{t('DontAddRetrackers')}</option> type='number'
<option value={1}>{t('AddRetrackers')}</option> fullWidth
<option value={2}>{t('RemoveRetrackers')}</option> />
<option value={3}>{t('ReplaceRetrackers')}</option> <br />
</Select> <TextField
<br /> onChange={inputForm}
</SecondarySettingsContent> margin='dense'
</TabPanel> id='ConnectionsLimit'
</SwipeableViews> label={t('ConnectionsLimit')}
</> value={ConnectionsLimit}
type='number'
fullWidth
/>
<br />
<FormControlLabel
control={<Switch checked={!DisableDHT} onChange={inputForm} id='DisableDHT' color='primary' />}
label={t('DHT')}
/>
<br />
<TextField
onChange={inputForm}
margin='dense'
id='DhtConnectionLimit'
label={t('DhtConnectionLimit')}
value={DhtConnectionLimit}
type='number'
fullWidth
/>
<br />
<TextField
onChange={inputForm}
margin='dense'
id='DownloadRateLimit'
label={t('DownloadRateLimit')}
value={DownloadRateLimit}
type='number'
fullWidth
/>
<br />
<FormControlLabel
control={<Switch checked={!DisableUpload} onChange={inputForm} id='DisableUpload' color='primary' />}
label={t('Upload')}
/>
<br />
<TextField
onChange={inputForm}
margin='dense'
id='UploadRateLimit'
label={t('UploadRateLimit')}
value={UploadRateLimit}
type='number'
fullWidth
/>
<br />
<TextField
onChange={inputForm}
margin='dense'
id='PeersListenPort'
label={t('PeersListenPort')}
value={PeersListenPort}
type='number'
fullWidth
/>
<br />
<FormControlLabel
control={<Switch checked={!DisableUPNP} onChange={inputForm} id='DisableUPNP' color='primary' />}
label={t('UPNP')}
/>
<br />
<InputLabel htmlFor='RetrackersMode'>{t('RetrackersMode')}</InputLabel>
<Select onChange={inputForm} type='number' native id='RetrackersMode' value={RetrackersMode}>
<option value={0}>{t('DontAddRetrackers')}</option>
<option value={1}>{t('AddRetrackers')}</option>
<option value={2}>{t('RemoveRetrackers')}</option>
<option value={3}>{t('ReplaceRetrackers')}</option>
</Select>
<br />
</SecondarySettingsContent>
</TabPanel>
</SwipeableViews>
</>
) : (
'loading...'
)}
{/* <DialogTitle id='form-dialog-title'>{t('Settings')}</DialogTitle> {/* <DialogTitle id='form-dialog-title'>{t('Settings')}</DialogTitle>
<DialogContent> <DialogContent>
<TextField <TextField
@@ -805,6 +706,18 @@ export default function SettingsDialog({ handleClose }) {
{t('Cancel')} {t('Cancel')}
</Button> </Button>
<Button
onClick={() => {
setCacheSize(defaultSettings.CacheSize)
setCachePercentage(defaultSettings.ReaderReadAHead)
updateSettings(defaultSettings)
}}
color='secondary'
variant='outlined'
>
Reset to default
</Button>
<Button variant='contained' onClick={handleSave} color='primary'> <Button variant='contained' onClick={handleSave} color='primary'>
{t('Save')} {t('Save')}
</Button> </Button>

View File

@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
import SettingsDialog from './SettingsDialog' import SettingsDialog from './SettingsDialog'
export default function SettingsDialogButton() { export default function SettingsDialogButton({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()
const [isDialogOpen, setIsDialogOpen] = useState(false) const [isDialogOpen, setIsDialogOpen] = useState(false)
@@ -16,7 +16,7 @@ export default function SettingsDialogButton() {
return ( return (
<div> <div>
<ListItem button onClick={handleClickOpen}> <ListItem disabled={isOffline || isLoading} button onClick={handleClickOpen}>
<ListItemIcon> <ListItemIcon>
<SettingsIcon /> <SettingsIcon />
</ListItemIcon> </ListItemIcon>

View File

@@ -0,0 +1,161 @@
import styled, { css } from 'styled-components'
import { mainColors } from 'style/colors'
export const cacheBeforeReaderColor = '#b3dfc9'
export const cacheAfterReaderColor = mainColors.light.primary
export const FooterSection = styled.div`
padding: 20px;
display: flex;
align-items: center;
justify-content: space-between;
background: #e8e5eb;
> :last-child > :not(:last-child) {
margin-right: 10px;
}
`
export const Divider = styled.div`
height: 1px;
background-color: rgba(0, 0, 0, 0.12);
margin: 30px 0;
`
export const PreloadCacheValue = styled.div`
${({ color }) => css`
display: grid;
grid-template-columns: max-content 100px 1fr;
gap: 10px;
align-items: center;
:not(:last-child) {
margin-bottom: 5px;
}
:before {
content: '';
background: ${color};
width: 15px;
height: 15px;
border-radius: 50%;
}
`}
`
export const MainSettingsContent = styled.div`
min-height: 500px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
padding: 20px;
@media (max-width: 930px) {
grid-template-columns: 1fr;
}
`
export const SecondarySettingsContent = styled.div`
min-height: 500px;
padding: 20px;
`
export const StorageButton = styled.div`
${({ small, selected }) => css`
transition: 0.2s;
cursor: default;
${!selected &&
css`
cursor: pointer;
:hover {
filter: brightness(0.8);
}
`}
${small
? css`
display: grid;
grid-template-columns: max-content 1fr;
gap: 20px;
align-items: center;
margin-bottom: 20px;
`
: css`
display: grid;
place-items: center;
gap: 10px;
`}
`}
`
export const StorageIconWrapper = styled.div`
${({ selected, small }) => css`
width: ${small ? '60px' : '150px'};
height: ${small ? '60px' : '150px'};
border-radius: 50%;
background: ${selected ? '#323637' : '#dee3e5'};
svg {
transform: rotate(-45deg) scale(0.75);
}
`}
`
export const CacheSizeSettings = styled.div``
export const CacheStorageSelector = styled.div`
display: grid;
grid-template-rows: max-content 1fr;
grid-template-columns: 1fr 1fr;
grid-template-areas: 'label label';
place-items: center;
@media (max-width: 930px) {
grid-template-columns: repeat(2, max-content);
column-gap: 30px;
}
`
export const CacheStorageSettings = styled.div``
export const SettingSection = styled.section``
export const SettingLabel = styled.div``
export const SettingSectionLabel = styled.div`
font-size: 25px;
padding-bottom: 20px;
`
export const PreloadCachePercentage = styled.div.attrs(({ value }) => ({
// this block is here according to styled-components recomendation about fast changable components
style: {
background: `linear-gradient(to right, ${cacheBeforeReaderColor} 0%, ${cacheBeforeReaderColor} ${value}%, ${cacheAfterReaderColor} ${value}%, ${cacheAfterReaderColor} 100%)`,
},
}))`
${({ label, isPreloadEnabled }) => css`
border: 1px solid #323637;
padding: 10px 20px;
border-radius: 5px;
color: #000;
margin-bottom: 10px;
position: relative;
:before {
content: '${label}';
display: grid;
place-items: center;
font-size: 20px;
}
${isPreloadEnabled &&
css`
:after {
content: '';
width: 100%;
height: 2px;
background: #323637;
position: absolute;
bottom: 0;
left: 0;
}
`}
`}
`