From dbfc1db5d28abd3b7f97ab9c2358ae705de13714 Mon Sep 17 00:00:00 2001 From: Daniel Shleifman Date: Fri, 2 Jul 2021 17:56:32 +0300 Subject: [PATCH] refactor --- web/src/components/App/Sidebar.jsx | 2 +- .../components/Settings/SettingsDialog.jsx | 825 ++++++++---------- web/src/components/Settings/index.jsx | 4 +- web/src/components/Settings/style.js | 161 ++++ 4 files changed, 533 insertions(+), 459 deletions(-) create mode 100644 web/src/components/Settings/style.js diff --git a/web/src/components/App/Sidebar.jsx b/web/src/components/App/Sidebar.jsx index 344bcaf..9158381 100644 --- a/web/src/components/App/Sidebar.jsx +++ b/web/src/components/App/Sidebar.jsx @@ -28,7 +28,7 @@ const Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading } - + diff --git a/web/src/components/Settings/SettingsDialog.jsx b/web/src/components/Settings/SettingsDialog.jsx index 457d7d1..c235341 100644 --- a/web/src/components/Settings/SettingsDialog.jsx +++ b/web/src/components/Settings/SettingsDialog.jsx @@ -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 }) => ( ) -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,305 +190,316 @@ export default function SettingsDialog({ handleClose }) {
{t('Settings')}
- <> - - + + + + + + + + + - + + + + Настройки кеша - - - - - - - - - Настройки кеша - - - - -
- {100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} МБ) -
-
От кеша будет оставаться позади воспроизводимого блока
-
- - -
- {cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} МБ) -
-
От кеша будет спереди от воспроизводимого блока
-
- - - - - Размер кеша - - - - - - - {isProMode && ( - - - - )} - - - - - Кеш предзагрузки - - - - setCachePercentage(newValue)} - /> - - - {isProMode && ( - - 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', - }} - /> - - )} - - - - - } - label={t('PreloadBuffer')} + - -
- {isRamSelected ? ( - - - Место хранения кеша - + +
+ {100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} МБ) +
+
От кеша будет оставаться позади воспроизводимого блока
+
- - - - -
Оперативная память
-
+ +
+ {cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} МБ) +
+
От кеша будет спереди от воспроизводимого блока
+
- - setIsRamSelected(false)}> - - -
Диск
-
-
- ) : ( - - Место хранения кеша + - - + + Размер кеша - - + + + setCacheSize(newValue)} + step={8} + /> + + + {isProMode && ( + + + + )} + + + + + Кеш предзагрузки + + + + setCachePercentage(newValue)} + /> + + + {isProMode && ( + + 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' }} + /> + + )} + + + } - label={t('RemoveCacheOnDrop')} + label={t('PreloadBuffer')} /> - {t('RemoveCacheOnDropDesc')} - - - )} -
-
+ - - - Дополнительные настройки + {UseDisk ? ( + + Место хранения кеша - } - label={t('EnableIPv6')} - /> -
- } - label={t('TCP')} - /> -
- } - label={t('UTP')} - /> -
- } - label={t('PEX')} - /> -
- } - label={t('ForceEncrypt')} - /> -
- -
- -
- } - label={t('DHT')} - /> -
- -
- -
- } - label={t('Upload')} - /> -
- -
- -
- } - label={t('UPNP')} - /> -
- {t('RetrackersMode')} - -
-
-
-
- +
+ updateSettings({ UseDisk: false })}> + + + + +
Оперативная память
+
+ + + + + + +
Диск
+
+
+ + + } + label={t('RemoveCacheOnDrop')} + /> + {t('RemoveCacheOnDropDesc')} + + + + ) : ( + + + Место хранения кеша + + + + + + + +
Оперативная память
+
+ + updateSettings({ UseDisk: true })}> + + + + +
Диск
+
+
+ )} + + + + + + Дополнительные настройки + + } + label={t('EnableIPv6')} + /> +
+ } + label={t('TCP')} + /> +
+ } + label={t('UTP')} + /> +
+ } + label={t('PEX')} + /> +
+ } + label={t('ForceEncrypt')} + /> +
+ +
+ +
+ } + label={t('DHT')} + /> +
+ +
+ +
+ } + label={t('Upload')} + /> +
+ +
+ +
+ } + label={t('UPNP')} + /> +
+ {t('RetrackersMode')} + +
+
+
+ + + ) : ( + 'loading...' + )} {/* {t('Settings')} + + diff --git a/web/src/components/Settings/index.jsx b/web/src/components/Settings/index.jsx index be19058..6c38026 100644 --- a/web/src/components/Settings/index.jsx +++ b/web/src/components/Settings/index.jsx @@ -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 (
- + diff --git a/web/src/components/Settings/style.js b/web/src/components/Settings/style.js new file mode 100644 index 0000000..24177da --- /dev/null +++ b/web/src/components/Settings/style.js @@ -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; + } + `} + `} +`