mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
refactor
This commit is contained in:
166
web/src/components/Settings/PrimarySettingsComponent.jsx
Normal file
166
web/src/components/Settings/PrimarySettingsComponent.jsx
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { USBIcon, RAMIcon } from 'icons'
|
||||||
|
import { FormControlLabel, Switch } from '@material-ui/core'
|
||||||
|
import TextField from '@material-ui/core/TextField'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Divider,
|
||||||
|
PreloadCacheValue,
|
||||||
|
MainSettingsContent,
|
||||||
|
StorageButton,
|
||||||
|
StorageIconWrapper,
|
||||||
|
CacheStorageSelector,
|
||||||
|
SettingSectionLabel,
|
||||||
|
PreloadCachePercentage,
|
||||||
|
cacheBeforeReaderColor,
|
||||||
|
cacheAfterReaderColor,
|
||||||
|
} from './style'
|
||||||
|
import SliderInput from './SliderInput'
|
||||||
|
|
||||||
|
const CacheStorageLocationLabel = ({ style }) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingSectionLabel style={style}>
|
||||||
|
{t('SettingsDialog.CacheStorageLocation')}
|
||||||
|
<small>{t('SettingsDialog.UseDiskDesc')}</small>
|
||||||
|
</SettingSectionLabel>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PrimarySettingsComponent({
|
||||||
|
settings,
|
||||||
|
inputForm,
|
||||||
|
cachePercentage,
|
||||||
|
cacheSize,
|
||||||
|
isProMode,
|
||||||
|
setCacheSize,
|
||||||
|
setCachePercentage,
|
||||||
|
updateSettings,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { PreloadBuffer, UseDisk, TorrentsSavePath, RemoveCacheOnDrop } = settings || {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MainSettingsContent>
|
||||||
|
<div>
|
||||||
|
<SettingSectionLabel>{t('SettingsDialog.CacheSettings')}</SettingSectionLabel>
|
||||||
|
|
||||||
|
<PreloadCachePercentage
|
||||||
|
value={100 - cachePercentage}
|
||||||
|
label={`${t('Cache')} ${cacheSize} MB`}
|
||||||
|
isPreloadEnabled={PreloadBuffer}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PreloadCacheValue color={cacheBeforeReaderColor}>
|
||||||
|
<div>
|
||||||
|
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} MB)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.CacheBeforeReaderDesc')}</div>
|
||||||
|
</PreloadCacheValue>
|
||||||
|
|
||||||
|
<PreloadCacheValue color={cacheAfterReaderColor}>
|
||||||
|
<div>
|
||||||
|
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} MB)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.CacheAfterReaderDesc')}</div>
|
||||||
|
</PreloadCacheValue>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<SliderInput
|
||||||
|
isProMode={isProMode}
|
||||||
|
title={t('SettingsDialog.CacheSize')}
|
||||||
|
value={cacheSize}
|
||||||
|
setValue={setCacheSize}
|
||||||
|
sliderMin={32}
|
||||||
|
sliderMax={1024}
|
||||||
|
inputMin={32}
|
||||||
|
inputMax={20000}
|
||||||
|
step={8}
|
||||||
|
onBlurCallback={value => setCacheSize(Math.round(value / 8) * 8)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SliderInput
|
||||||
|
isProMode={isProMode}
|
||||||
|
title={t('SettingsDialog.ReaderReadAHead')}
|
||||||
|
value={cachePercentage}
|
||||||
|
setValue={setCachePercentage}
|
||||||
|
sliderMin={40}
|
||||||
|
sliderMax={95}
|
||||||
|
inputMin={0}
|
||||||
|
inputMax={100}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!!PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />}
|
||||||
|
label={t('SettingsDialog.PreloadBuffer')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{UseDisk ? (
|
||||||
|
<div>
|
||||||
|
<CacheStorageLocationLabel />
|
||||||
|
|
||||||
|
<div style={{ display: 'grid', gridAutoFlow: 'column' }}>
|
||||||
|
<StorageButton small onClick={() => updateSettings({ UseDisk: false })}>
|
||||||
|
<StorageIconWrapper small>
|
||||||
|
<RAMIcon color='#323637' />
|
||||||
|
</StorageIconWrapper>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.RAM')}</div>
|
||||||
|
</StorageButton>
|
||||||
|
|
||||||
|
<StorageButton small selected>
|
||||||
|
<StorageIconWrapper small selected>
|
||||||
|
<USBIcon color='#dee3e5' />
|
||||||
|
</StorageIconWrapper>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.Disk')}</div>
|
||||||
|
</StorageButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={RemoveCacheOnDrop} onChange={inputForm} id='RemoveCacheOnDrop' color='primary' />}
|
||||||
|
label={t('SettingsDialog.RemoveCacheOnDrop')}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<small>{t('SettingsDialog.RemoveCacheOnDropDesc')}</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='TorrentsSavePath'
|
||||||
|
label={t('SettingsDialog.TorrentsSavePath')}
|
||||||
|
value={TorrentsSavePath}
|
||||||
|
type='url'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<CacheStorageSelector>
|
||||||
|
<CacheStorageLocationLabel style={{ placeSelf: 'start', gridArea: 'label' }} />
|
||||||
|
|
||||||
|
<StorageButton selected>
|
||||||
|
<StorageIconWrapper selected>
|
||||||
|
<RAMIcon color='#dee3e5' />
|
||||||
|
</StorageIconWrapper>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.RAM')}</div>
|
||||||
|
</StorageButton>
|
||||||
|
|
||||||
|
<StorageButton onClick={() => updateSettings({ UseDisk: true })}>
|
||||||
|
<StorageIconWrapper>
|
||||||
|
<USBIcon color='#323637' />
|
||||||
|
</StorageIconWrapper>
|
||||||
|
|
||||||
|
<div>{t('SettingsDialog.Disk')}</div>
|
||||||
|
</StorageButton>
|
||||||
|
</CacheStorageSelector>
|
||||||
|
)}
|
||||||
|
</MainSettingsContent>
|
||||||
|
)
|
||||||
|
}
|
||||||
142
web/src/components/Settings/SecondarySettingsComponent.jsx
Normal file
142
web/src/components/Settings/SecondarySettingsComponent.jsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import TextField from '@material-ui/core/TextField'
|
||||||
|
import { FormControlLabel, InputLabel, Select, Switch } from '@material-ui/core'
|
||||||
|
|
||||||
|
import { SecondarySettingsContent, SettingSectionLabel } from './style'
|
||||||
|
|
||||||
|
export default function SecondarySettingsComponent({ settings, inputForm }) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const {
|
||||||
|
RetrackersMode,
|
||||||
|
TorrentDisconnectTimeout,
|
||||||
|
EnableIPv6,
|
||||||
|
ForceEncrypt,
|
||||||
|
DisableTCP,
|
||||||
|
DisableUTP,
|
||||||
|
DisableUPNP,
|
||||||
|
DisableDHT,
|
||||||
|
DisablePEX,
|
||||||
|
DisableUpload,
|
||||||
|
DownloadRateLimit,
|
||||||
|
UploadRateLimit,
|
||||||
|
ConnectionsLimit,
|
||||||
|
DhtConnectionLimit,
|
||||||
|
PeersListenPort,
|
||||||
|
} = settings || {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SecondarySettingsContent>
|
||||||
|
<SettingSectionLabel>{t('SettingsDialog.AdditionalSettings')}</SettingSectionLabel>
|
||||||
|
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={EnableIPv6} onChange={inputForm} id='EnableIPv6' color='primary' />}
|
||||||
|
label='IPv6'
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisableTCP} onChange={inputForm} id='DisableTCP' color='primary' />}
|
||||||
|
label='TCP (Transmission Control Protocol)'
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisableUTP} onChange={inputForm} id='DisableUTP' color='primary' />}
|
||||||
|
label='μTP (Micro Transport Protocol)'
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisablePEX} onChange={inputForm} id='DisablePEX' color='primary' />}
|
||||||
|
label='PEX (Peer Exchange)'
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={ForceEncrypt} onChange={inputForm} id='ForceEncrypt' color='primary' />}
|
||||||
|
label={t('SettingsDialog.ForceEncrypt')}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='TorrentDisconnectTimeout'
|
||||||
|
label={t('SettingsDialog.TorrentDisconnectTimeout')}
|
||||||
|
value={TorrentDisconnectTimeout}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='ConnectionsLimit'
|
||||||
|
label={t('SettingsDialog.ConnectionsLimit')}
|
||||||
|
value={ConnectionsLimit}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisableDHT} onChange={inputForm} id='DisableDHT' color='primary' />}
|
||||||
|
label={t('SettingsDialog.DHT')}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='DhtConnectionLimit'
|
||||||
|
label={t('SettingsDialog.DhtConnectionLimit')}
|
||||||
|
value={DhtConnectionLimit}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='DownloadRateLimit'
|
||||||
|
label={t('SettingsDialog.DownloadRateLimit')}
|
||||||
|
value={DownloadRateLimit}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisableUpload} onChange={inputForm} id='DisableUpload' color='primary' />}
|
||||||
|
label={t('SettingsDialog.Upload')}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='UploadRateLimit'
|
||||||
|
label={t('SettingsDialog.UploadRateLimit')}
|
||||||
|
value={UploadRateLimit}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
onChange={inputForm}
|
||||||
|
margin='dense'
|
||||||
|
id='PeersListenPort'
|
||||||
|
label={t('SettingsDialog.PeersListenPort')}
|
||||||
|
value={PeersListenPort}
|
||||||
|
type='number'
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={!DisableUPNP} onChange={inputForm} id='DisableUPNP' color='primary' />}
|
||||||
|
label='UPnP (Universal Plug and Play)'
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<InputLabel htmlFor='RetrackersMode'>{t('SettingsDialog.RetrackersMode')}</InputLabel>
|
||||||
|
<Select onChange={inputForm} type='number' native id='RetrackersMode' value={RetrackersMode}>
|
||||||
|
<option value={0}>{t('SettingsDialog.DontAddRetrackers')}</option>
|
||||||
|
<option value={1}>{t('SettingsDialog.AddRetrackers')}</option>
|
||||||
|
<option value={2}>{t('SettingsDialog.RemoveRetrackers')}</option>
|
||||||
|
<option value={3}>{t('SettingsDialog.ReplaceRetrackers')}</option>
|
||||||
|
</Select>
|
||||||
|
<br />
|
||||||
|
</SecondarySettingsContent>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,19 +1,8 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import Dialog from '@material-ui/core/Dialog'
|
import Dialog from '@material-ui/core/Dialog'
|
||||||
import TextField from '@material-ui/core/TextField'
|
|
||||||
import Button from '@material-ui/core/Button'
|
import Button from '@material-ui/core/Button'
|
||||||
import Checkbox from '@material-ui/core/Checkbox'
|
import Checkbox from '@material-ui/core/Checkbox'
|
||||||
import {
|
import { FormControlLabel, useMediaQuery, useTheme } from '@material-ui/core'
|
||||||
FormControlLabel,
|
|
||||||
Grid,
|
|
||||||
Input,
|
|
||||||
InputLabel,
|
|
||||||
Select,
|
|
||||||
Slider,
|
|
||||||
Switch,
|
|
||||||
useMediaQuery,
|
|
||||||
useTheme,
|
|
||||||
} from '@material-ui/core'
|
|
||||||
import { settingsHost } 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'
|
||||||
@@ -22,85 +11,13 @@ 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 { USBIcon, RAMIcon } from 'icons'
|
|
||||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||||
|
|
||||||
import {
|
import { FooterSection, Content } from './style'
|
||||||
FooterSection,
|
|
||||||
Divider,
|
|
||||||
PreloadCacheValue,
|
|
||||||
MainSettingsContent,
|
|
||||||
SecondarySettingsContent,
|
|
||||||
StorageButton,
|
|
||||||
StorageIconWrapper,
|
|
||||||
CacheStorageSelector,
|
|
||||||
SettingSectionLabel,
|
|
||||||
PreloadCachePercentage,
|
|
||||||
cacheBeforeReaderColor,
|
|
||||||
cacheAfterReaderColor,
|
|
||||||
Content,
|
|
||||||
} from './style'
|
|
||||||
import defaultSettings from './defaultSettings'
|
import defaultSettings from './defaultSettings'
|
||||||
import { a11yProps, TabPanel } from './tabComponents'
|
import { a11yProps, TabPanel } from './tabComponents'
|
||||||
|
import PrimarySettingsComponent from './PrimarySettingsComponent'
|
||||||
const CacheStorageLocationLabel = ({ style }) => {
|
import SecondarySettingsComponent from './SecondarySettingsComponent'
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SettingSectionLabel style={style}>
|
|
||||||
{t('SettingsDialog.CacheStorageLocation')}
|
|
||||||
<small>{t('SettingsDialog.UseDiskDesc')}</small>
|
|
||||||
</SettingSectionLabel>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SliderInput = ({
|
|
||||||
isProMode,
|
|
||||||
title,
|
|
||||||
value,
|
|
||||||
setValue,
|
|
||||||
sliderMin,
|
|
||||||
sliderMax,
|
|
||||||
inputMin,
|
|
||||||
inputMax,
|
|
||||||
step = 1,
|
|
||||||
onBlurCallback,
|
|
||||||
}) => {
|
|
||||||
const onBlur = ({ target: { value } }) => {
|
|
||||||
if (value < inputMin) return setValue(inputMin)
|
|
||||||
if (value > inputMax) return setValue(inputMax)
|
|
||||||
|
|
||||||
onBlurCallback && onBlurCallback(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onInputChange = ({ target: { value } }) => setValue(value === '' ? '' : Number(value))
|
|
||||||
const onSliderChange = (_, newValue) => setValue(newValue)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div>{title}</div>
|
|
||||||
|
|
||||||
<Grid container spacing={2} alignItems='center'>
|
|
||||||
<Grid item xs>
|
|
||||||
<Slider min={sliderMin} max={sliderMax} value={value} onChange={onSliderChange} step={step} />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{isProMode && (
|
|
||||||
<Grid item>
|
|
||||||
<Input
|
|
||||||
value={value}
|
|
||||||
margin='dense'
|
|
||||||
onChange={onInputChange}
|
|
||||||
onBlur={onBlur}
|
|
||||||
style={{ width: '65px' }}
|
|
||||||
inputProps={{ step, min: inputMin, max: inputMax, type: 'number' }}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function SettingsDialog({ handleClose }) {
|
export default function SettingsDialog({ handleClose }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -149,29 +66,7 @@ export default function SettingsDialog({ handleClose }) {
|
|||||||
setSettings(sets)
|
setSettings(sets)
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { CacheSize, ReaderReadAHead } = settings || {}
|
||||||
CacheSize,
|
|
||||||
PreloadBuffer,
|
|
||||||
ReaderReadAHead,
|
|
||||||
RetrackersMode,
|
|
||||||
TorrentDisconnectTimeout,
|
|
||||||
EnableIPv6,
|
|
||||||
ForceEncrypt,
|
|
||||||
DisableTCP,
|
|
||||||
DisableUTP,
|
|
||||||
DisableUPNP,
|
|
||||||
DisableDHT,
|
|
||||||
DisablePEX,
|
|
||||||
DisableUpload,
|
|
||||||
DownloadRateLimit,
|
|
||||||
UploadRateLimit,
|
|
||||||
ConnectionsLimit,
|
|
||||||
DhtConnectionLimit,
|
|
||||||
PeersListenPort,
|
|
||||||
UseDisk,
|
|
||||||
TorrentsSavePath,
|
|
||||||
RemoveCacheOnDrop,
|
|
||||||
} = settings || {}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!CacheSize || !ReaderReadAHead) return
|
if (!CacheSize || !ReaderReadAHead) return
|
||||||
@@ -215,252 +110,20 @@ export default function SettingsDialog({ handleClose }) {
|
|||||||
onChangeIndex={handleChangeIndex}
|
onChangeIndex={handleChangeIndex}
|
||||||
>
|
>
|
||||||
<TabPanel value={selectedTab} index={0} dir={direction}>
|
<TabPanel value={selectedTab} index={0} dir={direction}>
|
||||||
<MainSettingsContent>
|
<PrimarySettingsComponent
|
||||||
<div>
|
settings={settings}
|
||||||
<SettingSectionLabel>{t('SettingsDialog.CacheSettings')}</SettingSectionLabel>
|
inputForm={inputForm}
|
||||||
|
cachePercentage={cachePercentage}
|
||||||
<PreloadCachePercentage
|
cacheSize={cacheSize}
|
||||||
value={100 - cachePercentage}
|
isProMode={isProMode}
|
||||||
label={`${t('Cache')} ${cacheSize} MB`}
|
setCacheSize={setCacheSize}
|
||||||
isPreloadEnabled={PreloadBuffer}
|
setCachePercentage={setCachePercentage}
|
||||||
/>
|
updateSettings={updateSettings}
|
||||||
|
/>
|
||||||
<PreloadCacheValue color={cacheBeforeReaderColor}>
|
|
||||||
<div>
|
|
||||||
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} MB)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.CacheBeforeReaderDesc')}</div>
|
|
||||||
</PreloadCacheValue>
|
|
||||||
|
|
||||||
<PreloadCacheValue color={cacheAfterReaderColor}>
|
|
||||||
<div>
|
|
||||||
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} MB)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.CacheAfterReaderDesc')}</div>
|
|
||||||
</PreloadCacheValue>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
|
|
||||||
<SliderInput
|
|
||||||
isProMode={isProMode}
|
|
||||||
title={t('SettingsDialog.CacheSize')}
|
|
||||||
value={cacheSize}
|
|
||||||
setValue={setCacheSize}
|
|
||||||
sliderMin={32}
|
|
||||||
sliderMax={1024}
|
|
||||||
inputMin={32}
|
|
||||||
inputMax={20000}
|
|
||||||
step={8}
|
|
||||||
onBlurCallback={value => setCacheSize(Math.round(value / 8) * 8)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SliderInput
|
|
||||||
isProMode={isProMode}
|
|
||||||
title={t('SettingsDialog.ReaderReadAHead')}
|
|
||||||
value={cachePercentage}
|
|
||||||
setValue={setCachePercentage}
|
|
||||||
sliderMin={40}
|
|
||||||
sliderMax={95}
|
|
||||||
inputMin={0}
|
|
||||||
inputMax={100}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch checked={!!PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />
|
|
||||||
}
|
|
||||||
label={t('SettingsDialog.PreloadBuffer')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{UseDisk ? (
|
|
||||||
<div>
|
|
||||||
<CacheStorageLocationLabel />
|
|
||||||
|
|
||||||
<div style={{ display: 'grid', gridAutoFlow: 'column' }}>
|
|
||||||
<StorageButton small onClick={() => updateSettings({ UseDisk: false })}>
|
|
||||||
<StorageIconWrapper small>
|
|
||||||
<RAMIcon color='#323637' />
|
|
||||||
</StorageIconWrapper>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.RAM')}</div>
|
|
||||||
</StorageButton>
|
|
||||||
|
|
||||||
<StorageButton small selected>
|
|
||||||
<StorageIconWrapper small selected>
|
|
||||||
<USBIcon color='#dee3e5' />
|
|
||||||
</StorageIconWrapper>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.Disk')}</div>
|
|
||||||
</StorageButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={RemoveCacheOnDrop}
|
|
||||||
onChange={inputForm}
|
|
||||||
id='RemoveCacheOnDrop'
|
|
||||||
color='primary'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={t('SettingsDialog.RemoveCacheOnDrop')}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<small>{t('SettingsDialog.RemoveCacheOnDropDesc')}</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='TorrentsSavePath'
|
|
||||||
label={t('SettingsDialog.TorrentsSavePath')}
|
|
||||||
value={TorrentsSavePath}
|
|
||||||
type='url'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<CacheStorageSelector>
|
|
||||||
<CacheStorageLocationLabel style={{ placeSelf: 'start', gridArea: 'label' }} />
|
|
||||||
|
|
||||||
<StorageButton selected>
|
|
||||||
<StorageIconWrapper selected>
|
|
||||||
<RAMIcon color='#dee3e5' />
|
|
||||||
</StorageIconWrapper>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.RAM')}</div>
|
|
||||||
</StorageButton>
|
|
||||||
|
|
||||||
<StorageButton onClick={() => updateSettings({ UseDisk: true })}>
|
|
||||||
<StorageIconWrapper>
|
|
||||||
<USBIcon color='#323637' />
|
|
||||||
</StorageIconWrapper>
|
|
||||||
|
|
||||||
<div>{t('SettingsDialog.Disk')}</div>
|
|
||||||
</StorageButton>
|
|
||||||
</CacheStorageSelector>
|
|
||||||
)}
|
|
||||||
</MainSettingsContent>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={selectedTab} index={1} dir={direction}>
|
<TabPanel value={selectedTab} index={1} dir={direction}>
|
||||||
<SecondarySettingsContent>
|
<SecondarySettingsComponent settings={settings} inputForm={inputForm} />
|
||||||
<SettingSectionLabel>{t('SettingsDialog.AdditionalSettings')}</SettingSectionLabel>
|
|
||||||
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={EnableIPv6} onChange={inputForm} id='EnableIPv6' color='primary' />}
|
|
||||||
label='IPv6'
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={!DisableTCP} onChange={inputForm} id='DisableTCP' color='primary' />}
|
|
||||||
label='TCP (Transmission Control Protocol)'
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={!DisableUTP} onChange={inputForm} id='DisableUTP' color='primary' />}
|
|
||||||
label='μTP (Micro Transport Protocol)'
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={!DisablePEX} onChange={inputForm} id='DisablePEX' color='primary' />}
|
|
||||||
label='PEX (Peer Exchange)'
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={ForceEncrypt} onChange={inputForm} id='ForceEncrypt' color='primary' />}
|
|
||||||
label={t('SettingsDialog.ForceEncrypt')}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='TorrentDisconnectTimeout'
|
|
||||||
label={t('SettingsDialog.TorrentDisconnectTimeout')}
|
|
||||||
value={TorrentDisconnectTimeout}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='ConnectionsLimit'
|
|
||||||
label={t('SettingsDialog.ConnectionsLimit')}
|
|
||||||
value={ConnectionsLimit}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={!DisableDHT} onChange={inputForm} id='DisableDHT' color='primary' />}
|
|
||||||
label={t('SettingsDialog.DHT')}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='DhtConnectionLimit'
|
|
||||||
label={t('SettingsDialog.DhtConnectionLimit')}
|
|
||||||
value={DhtConnectionLimit}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='DownloadRateLimit'
|
|
||||||
label={t('SettingsDialog.DownloadRateLimit')}
|
|
||||||
value={DownloadRateLimit}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch checked={!DisableUpload} onChange={inputForm} id='DisableUpload' color='primary' />
|
|
||||||
}
|
|
||||||
label={t('SettingsDialog.Upload')}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='UploadRateLimit'
|
|
||||||
label={t('SettingsDialog.UploadRateLimit')}
|
|
||||||
value={UploadRateLimit}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<TextField
|
|
||||||
onChange={inputForm}
|
|
||||||
margin='dense'
|
|
||||||
id='PeersListenPort'
|
|
||||||
label={t('SettingsDialog.PeersListenPort')}
|
|
||||||
value={PeersListenPort}
|
|
||||||
type='number'
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={!DisableUPNP} onChange={inputForm} id='DisableUPNP' color='primary' />}
|
|
||||||
label='UPnP (Universal Plug and Play)'
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<InputLabel htmlFor='RetrackersMode'>{t('SettingsDialog.RetrackersMode')}</InputLabel>
|
|
||||||
<Select onChange={inputForm} type='number' native id='RetrackersMode' value={RetrackersMode}>
|
|
||||||
<option value={0}>{t('SettingsDialog.DontAddRetrackers')}</option>
|
|
||||||
<option value={1}>{t('SettingsDialog.AddRetrackers')}</option>
|
|
||||||
<option value={2}>{t('SettingsDialog.RemoveRetrackers')}</option>
|
|
||||||
<option value={3}>{t('SettingsDialog.ReplaceRetrackers')}</option>
|
|
||||||
</Select>
|
|
||||||
<br />
|
|
||||||
</SecondarySettingsContent>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</SwipeableViews>
|
</SwipeableViews>
|
||||||
</>
|
</>
|
||||||
|
|||||||
49
web/src/components/Settings/SliderInput.jsx
Normal file
49
web/src/components/Settings/SliderInput.jsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { Grid, Input, Slider } from '@material-ui/core'
|
||||||
|
|
||||||
|
export default function SliderInput({
|
||||||
|
isProMode,
|
||||||
|
title,
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
sliderMin,
|
||||||
|
sliderMax,
|
||||||
|
inputMin,
|
||||||
|
inputMax,
|
||||||
|
step = 1,
|
||||||
|
onBlurCallback,
|
||||||
|
}) {
|
||||||
|
const onBlur = ({ target: { value } }) => {
|
||||||
|
if (value < inputMin) return setValue(inputMin)
|
||||||
|
if (value > inputMax) return setValue(inputMax)
|
||||||
|
|
||||||
|
onBlurCallback && onBlurCallback(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onInputChange = ({ target: { value } }) => setValue(value === '' ? '' : Number(value))
|
||||||
|
const onSliderChange = (_, newValue) => setValue(newValue)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>{title}</div>
|
||||||
|
|
||||||
|
<Grid container spacing={2} alignItems='center'>
|
||||||
|
<Grid item xs>
|
||||||
|
<Slider min={sliderMin} max={sliderMax} value={value} onChange={onSliderChange} step={step} />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{isProMode && (
|
||||||
|
<Grid item>
|
||||||
|
<Input
|
||||||
|
value={value}
|
||||||
|
margin='dense'
|
||||||
|
onChange={onInputChange}
|
||||||
|
onBlur={onBlur}
|
||||||
|
style={{ width: '65px' }}
|
||||||
|
inputProps={{ step, min: inputMin, max: inputMax, type: 'number' }}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user