mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
refactor
This commit is contained in:
@@ -28,7 +28,7 @@ const Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading }
|
||||
<Divider />
|
||||
|
||||
<List>
|
||||
<SettingsDialog />
|
||||
<SettingsDialog isOffline={isOffline} isLoading={isLoading} />
|
||||
|
||||
<AboutDialog />
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from '@material-ui/core'
|
||||
import { settingsHost, setTorrServerHost, getTorrServerHost } from 'utils/Hosts'
|
||||
import { settingsHost } from 'utils/Hosts'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Header } from 'style/DialogStyles'
|
||||
@@ -26,94 +26,26 @@ import AppBar from '@material-ui/core/AppBar'
|
||||
import Tabs from '@material-ui/core/Tabs'
|
||||
import Tab from '@material-ui/core/Tab'
|
||||
import SwipeableViews from 'react-swipeable-views'
|
||||
import styled, { css } from 'styled-components'
|
||||
import { USBIcon, RAMIcon } from 'icons'
|
||||
|
||||
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;
|
||||
}
|
||||
`
|
||||
const Divider = styled.div`
|
||||
height: 1px;
|
||||
background-color: rgba(0, 0, 0, 0.12);
|
||||
margin: 30px 0;
|
||||
`
|
||||
|
||||
const PreloadCachePercentage = styled.div.attrs(
|
||||
({
|
||||
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%;
|
||||
}
|
||||
`}
|
||||
`
|
||||
import {
|
||||
FooterSection,
|
||||
Divider,
|
||||
PreloadCacheValue,
|
||||
MainSettingsContent,
|
||||
SecondarySettingsContent,
|
||||
StorageButton,
|
||||
StorageIconWrapper,
|
||||
CacheSizeSettings,
|
||||
CacheStorageSelector,
|
||||
CacheStorageSettings,
|
||||
SettingSection,
|
||||
SettingLabel,
|
||||
SettingSectionLabel,
|
||||
PreloadCachePercentage,
|
||||
cacheBeforeReaderColor,
|
||||
cacheAfterReaderColor,
|
||||
} from './style'
|
||||
|
||||
const a11yProps = index => ({
|
||||
id: `full-width-tab-${index}`,
|
||||
@@ -126,103 +58,57 @@ const TabPanel = ({ children, value, index, ...other }) => (
|
||||
</div>
|
||||
)
|
||||
|
||||
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;
|
||||
}
|
||||
`
|
||||
const SecondarySettingsContent = styled.div`
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
`
|
||||
|
||||
const StorageButton = styled.div`
|
||||
display: grid;
|
||||
place-items: center;
|
||||
gap: 10px;
|
||||
`
|
||||
|
||||
const StorageIconWrapper = styled.div`
|
||||
${({ selected }) => css`
|
||||
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;
|
||||
`
|
||||
const defaultSettings = {
|
||||
CacheSize: 96,
|
||||
ReaderReadAHead: 95,
|
||||
UseDisk: false,
|
||||
UploadRateLimit: 0,
|
||||
TorrentsSavePath: '',
|
||||
ConnectionsLimit: 23,
|
||||
DhtConnectionLimit: 500,
|
||||
DisableDHT: false,
|
||||
DisablePEX: false,
|
||||
DisableTCP: false,
|
||||
DisableUPNP: false,
|
||||
DisableUTP: true,
|
||||
DisableUpload: false,
|
||||
DownloadRateLimit: 0,
|
||||
EnableDebug: false,
|
||||
EnableIPv6: false,
|
||||
ForceEncrypt: false,
|
||||
PeersListenPort: 0,
|
||||
PreloadBuffer: false,
|
||||
RemoveCacheOnDrop: false,
|
||||
RetrackersMode: 1,
|
||||
Strategy: 0,
|
||||
TorrentDisconnectTimeout: 30,
|
||||
}
|
||||
|
||||
export default function SettingsDialog({ handleClose }) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const fullScreen = useMediaQuery('@media (max-width:930px)')
|
||||
|
||||
const [settings, setSets] = useState({})
|
||||
const [settings, setSettings] = useState()
|
||||
const [show, setShow] = useState(false)
|
||||
const [tsHost, setTSHost] = useState(getTorrServerHost())
|
||||
|
||||
useEffect(() => {
|
||||
axios
|
||||
.post(settingsHost(), { action: 'get' })
|
||||
.then(({ data }) => {
|
||||
setSets({ ...data, CacheSize: data.CacheSize / (1024 * 1024) })
|
||||
setSettings({ ...data, CacheSize: data.CacheSize / (1024 * 1024) })
|
||||
setShow(true)
|
||||
})
|
||||
.catch(() => setShow(false))
|
||||
}, [tsHost])
|
||||
}, [])
|
||||
|
||||
const handleSave = () => {
|
||||
handleClose()
|
||||
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 })
|
||||
}
|
||||
const onInputHost = ({ target: { value } }) => {
|
||||
const host = value.replace(/\/$/gi, '')
|
||||
setTorrServerHost(host)
|
||||
setTSHost(host)
|
||||
}
|
||||
|
||||
const inputForm = ({ target: { type, value, checked, id } }) => {
|
||||
const sets = JSON.parse(JSON.stringify(settings))
|
||||
@@ -242,7 +128,7 @@ export default function SettingsDialog({ handleClose }) {
|
||||
} else if (type === 'url') {
|
||||
sets[id] = value
|
||||
}
|
||||
setSets(sets)
|
||||
setSettings(sets)
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -267,7 +153,9 @@ export default function SettingsDialog({ handleClose }) {
|
||||
UseDisk,
|
||||
TorrentsSavePath,
|
||||
RemoveCacheOnDrop,
|
||||
} = settings
|
||||
} = settings || {}
|
||||
|
||||
const updateSettings = newProps => setSettings({ ...settings, ...newProps })
|
||||
|
||||
const { direction } = useTheme()
|
||||
const [selectedTab, setSelectedTab] = useState(0)
|
||||
@@ -276,14 +164,16 @@ export default function SettingsDialog({ handleClose }) {
|
||||
|
||||
const handleChangeIndex = index => setSelectedTab(index)
|
||||
|
||||
const [cacheSize, setCacheSize] = useState(96)
|
||||
const [cachePercentage, setCachePercentage] = useState(95)
|
||||
const [cacheSize, setCacheSize] = useState(32)
|
||||
const [cachePercentage, setCachePercentage] = useState(40)
|
||||
const [isProMode, setIsProMode] = useState(JSON.parse(localStorage.getItem('isProMode')) || false)
|
||||
const [isRamSelected, setIsRamSelected] = useState(true)
|
||||
|
||||
const handleSliderChange = (_, newValue) => {
|
||||
setCacheSize(newValue)
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!CacheSize || !ReaderReadAHead) return
|
||||
|
||||
setCacheSize(CacheSize)
|
||||
setCachePercentage(ReaderReadAHead)
|
||||
}, [CacheSize, ReaderReadAHead])
|
||||
|
||||
const handleBlur = ({ target: { value } }) => {
|
||||
if (value < 32) return setCacheSize(32)
|
||||
@@ -300,6 +190,7 @@ export default function SettingsDialog({ handleClose }) {
|
||||
<Dialog open onClose={handleClose} fullScreen={fullScreen} fullWidth maxWidth='md'>
|
||||
<Header>{t('Settings')}</Header>
|
||||
|
||||
{settings ? (
|
||||
<>
|
||||
<AppBar position='static' color='default'>
|
||||
<Tabs
|
||||
@@ -335,14 +226,14 @@ export default function SettingsDialog({ handleClose }) {
|
||||
isPreloadEnabled={PreloadBuffer}
|
||||
/>
|
||||
|
||||
<PreloadCacheValue color='orangered'>
|
||||
<PreloadCacheValue color={cacheBeforeReaderColor}>
|
||||
<div>
|
||||
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} МБ)
|
||||
</div>
|
||||
<div>От кеша будет оставаться позади воспроизводимого блока</div>
|
||||
</PreloadCacheValue>
|
||||
|
||||
<PreloadCacheValue color='lightblue'>
|
||||
<PreloadCacheValue color={cacheAfterReaderColor}>
|
||||
<div>
|
||||
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} МБ)
|
||||
</div>
|
||||
@@ -356,7 +247,13 @@ export default function SettingsDialog({ handleClose }) {
|
||||
|
||||
<Grid container spacing={2} alignItems='center'>
|
||||
<Grid item xs>
|
||||
<Slider min={32} max={1024} value={cacheSize} onChange={handleSliderChange} step={8} />
|
||||
<Slider
|
||||
min={32}
|
||||
max={1024}
|
||||
value={cacheSize}
|
||||
onChange={(_, newValue) => setCacheSize(newValue)}
|
||||
step={8}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{isProMode && (
|
||||
@@ -367,12 +264,7 @@ export default function SettingsDialog({ handleClose }) {
|
||||
onChange={handleInputChange}
|
||||
onBlur={handleBlur}
|
||||
style={{ width: '65px' }}
|
||||
inputProps={{
|
||||
step: 8,
|
||||
min: 32,
|
||||
max: 20000,
|
||||
type: 'number',
|
||||
}}
|
||||
inputProps={{ step: 8, min: 32, max: 20000, type: 'number' }}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
@@ -403,72 +295,56 @@ export default function SettingsDialog({ handleClose }) {
|
||||
if (value > 100) return setCachePercentage(100)
|
||||
}}
|
||||
style={{ width: '65px' }}
|
||||
inputProps={{
|
||||
min: 0,
|
||||
max: 100,
|
||||
type: 'number',
|
||||
}}
|
||||
inputProps={{ min: 0, max: 100, type: 'number' }}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</SettingSection>
|
||||
|
||||
<SettingSection>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />}
|
||||
control={
|
||||
<Switch checked={!!PreloadBuffer} onChange={inputForm} id='PreloadBuffer' color='primary' />
|
||||
}
|
||||
label={t('PreloadBuffer')}
|
||||
/>
|
||||
</SettingSection>
|
||||
</CacheSizeSettings>
|
||||
|
||||
{isRamSelected ? (
|
||||
<CacheStorageSelector>
|
||||
<SettingSectionLabel style={{ placeSelf: 'start', gridArea: 'label' }}>
|
||||
Место хранения кеша
|
||||
</SettingSectionLabel>
|
||||
|
||||
<StorageButton>
|
||||
<StorageIconWrapper selected>
|
||||
<RAMIcon />
|
||||
</StorageIconWrapper>
|
||||
<div>Оперативная память</div>
|
||||
</StorageButton>
|
||||
|
||||
<StorageButton>
|
||||
<StorageIconWrapper onClick={() => setIsRamSelected(false)}>
|
||||
<USBIcon />
|
||||
</StorageIconWrapper>
|
||||
<div>Диск</div>
|
||||
</StorageButton>
|
||||
</CacheStorageSelector>
|
||||
) : (
|
||||
{UseDisk ? (
|
||||
<CacheStorageSettings>
|
||||
<SettingSectionLabel>Место хранения кеша</SettingSectionLabel>
|
||||
|
||||
<ButtonGroup fullWidth color='primary'>
|
||||
<Button onClick={() => setIsRamSelected(true)}>
|
||||
<div>
|
||||
<RAMIcon width='50px' />
|
||||
<div>Оперативная память</div>
|
||||
</div>
|
||||
</Button>
|
||||
<div style={{ display: 'grid', gridAutoFlow: 'column' }}>
|
||||
<StorageButton small onClick={() => updateSettings({ UseDisk: false })}>
|
||||
<StorageIconWrapper small>
|
||||
<RAMIcon color='#323637' />
|
||||
</StorageIconWrapper>
|
||||
|
||||
<div>Оперативная память</div>
|
||||
</StorageButton>
|
||||
|
||||
<StorageButton small selected>
|
||||
<StorageIconWrapper small selected>
|
||||
<USBIcon color='#dee3e5' />
|
||||
</StorageIconWrapper>
|
||||
|
||||
<Button variant='contained'>
|
||||
<div>
|
||||
<USBIcon width='50px' color='white' />
|
||||
<div>Диск</div>
|
||||
</StorageButton>
|
||||
</div>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch checked={RemoveCacheOnDrop} onChange={inputForm} id='RemoveCacheOnDrop' color='primary' />
|
||||
<Switch
|
||||
checked={RemoveCacheOnDrop}
|
||||
onChange={inputForm}
|
||||
id='RemoveCacheOnDrop'
|
||||
color='primary'
|
||||
/>
|
||||
}
|
||||
label={t('RemoveCacheOnDrop')}
|
||||
/>
|
||||
<small>{t('RemoveCacheOnDropDesc')}</small>
|
||||
|
||||
<TextField
|
||||
onChange={inputForm}
|
||||
margin='dense'
|
||||
@@ -479,6 +355,28 @@ export default function SettingsDialog({ handleClose }) {
|
||||
fullWidth
|
||||
/>
|
||||
</CacheStorageSettings>
|
||||
) : (
|
||||
<CacheStorageSelector>
|
||||
<SettingSectionLabel style={{ placeSelf: 'start', gridArea: 'label' }}>
|
||||
Место хранения кеша
|
||||
</SettingSectionLabel>
|
||||
|
||||
<StorageButton selected>
|
||||
<StorageIconWrapper selected>
|
||||
<RAMIcon color='#dee3e5' />
|
||||
</StorageIconWrapper>
|
||||
|
||||
<div>Оперативная память</div>
|
||||
</StorageButton>
|
||||
|
||||
<StorageButton onClick={() => updateSettings({ UseDisk: true })}>
|
||||
<StorageIconWrapper>
|
||||
<USBIcon color='#323637' />
|
||||
</StorageIconWrapper>
|
||||
|
||||
<div>Диск</div>
|
||||
</StorageButton>
|
||||
</CacheStorageSelector>
|
||||
)}
|
||||
</MainSettingsContent>
|
||||
</TabPanel>
|
||||
@@ -599,6 +497,9 @@ export default function SettingsDialog({ handleClose }) {
|
||||
</TabPanel>
|
||||
</SwipeableViews>
|
||||
</>
|
||||
) : (
|
||||
'loading...'
|
||||
)}
|
||||
{/* <DialogTitle id='form-dialog-title'>{t('Settings')}</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
@@ -805,6 +706,18 @@ export default function SettingsDialog({ handleClose }) {
|
||||
{t('Cancel')}
|
||||
</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'>
|
||||
{t('Save')}
|
||||
</Button>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
|
||||
|
||||
import SettingsDialog from './SettingsDialog'
|
||||
|
||||
export default function SettingsDialogButton() {
|
||||
export default function SettingsDialogButton({ isOffline, isLoading }) {
|
||||
const { t } = useTranslation()
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||
|
||||
@@ -16,7 +16,7 @@ export default function SettingsDialogButton() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ListItem button onClick={handleClickOpen}>
|
||||
<ListItem disabled={isOffline || isLoading} button onClick={handleClickOpen}>
|
||||
<ListItemIcon>
|
||||
<SettingsIcon />
|
||||
</ListItemIcon>
|
||||
|
||||
161
web/src/components/Settings/style.js
Normal file
161
web/src/components/Settings/style.js
Normal 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;
|
||||
}
|
||||
`}
|
||||
`}
|
||||
`
|
||||
Reference in New Issue
Block a user