mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
added dark theme
This commit is contained in:
@@ -11,13 +11,10 @@ import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { echoHost } from 'utils/Hosts'
|
||||
import { ThemeProvider } from '@material-ui/core/styles'
|
||||
import { mainColors } from 'style/colors'
|
||||
import { ThemeProvider, useTheme } from '@material-ui/core/styles'
|
||||
|
||||
import { lightTheme } from '../style/materialUISetup'
|
||||
|
||||
const { primary } = mainColors
|
||||
|
||||
export default function AboutDialog() {
|
||||
const { t } = useTranslation()
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -26,6 +23,8 @@ export default function AboutDialog() {
|
||||
axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data))
|
||||
}, [])
|
||||
|
||||
const primary = useTheme().palette.primary.main
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ListItem button key='Settings' onClick={() => setOpen(true)}>
|
||||
|
||||
@@ -12,8 +12,6 @@ import usePreviousState from 'utils/usePreviousState'
|
||||
import { useQuery } from 'react-query'
|
||||
import { getTorrents } from 'utils/Utils'
|
||||
import parseTorrent from 'parse-torrent'
|
||||
import { ThemeProvider } from '@material-ui/core/styles'
|
||||
import { lightTheme } from 'style/materialUISetup'
|
||||
|
||||
import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers'
|
||||
import { ButtonWrapper, Content, Header } from './style'
|
||||
@@ -221,71 +219,69 @@ export default function AddDialog({
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<Dialog
|
||||
open
|
||||
onClose={handleClose}
|
||||
aria-labelledby='form-dialog-title'
|
||||
fullScreen={fullScreen}
|
||||
fullWidth
|
||||
maxWidth='md'
|
||||
>
|
||||
<Header>{t(isEditMode ? 'EditTorrent' : 'AddNewTorrent')}</Header>
|
||||
<Dialog
|
||||
open
|
||||
onClose={handleClose}
|
||||
aria-labelledby='form-dialog-title'
|
||||
fullScreen={fullScreen}
|
||||
fullWidth
|
||||
maxWidth='md'
|
||||
>
|
||||
<Header>{t(isEditMode ? 'EditTorrent' : 'AddNewTorrent')}</Header>
|
||||
|
||||
<Content isEditMode={isEditMode}>
|
||||
{!isEditMode && (
|
||||
<LeftSideComponent
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setSelectedFile={setSelectedFile}
|
||||
torrentSource={torrentSource}
|
||||
setTorrentSource={setTorrentSource}
|
||||
selectedFile={selectedFile}
|
||||
/>
|
||||
)}
|
||||
|
||||
<RightSideComponent
|
||||
originalTorrentTitle={originalTorrentTitle}
|
||||
setTitle={setTitle}
|
||||
setPosterUrl={setPosterUrl}
|
||||
setIsPosterUrlCorrect={setIsPosterUrlCorrect}
|
||||
<Content isEditMode={isEditMode}>
|
||||
{!isEditMode && (
|
||||
<LeftSideComponent
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setPosterList={setPosterList}
|
||||
isTorrentSourceCorrect={isTorrentSourceCorrect}
|
||||
isHashAlreadyExists={isHashAlreadyExists}
|
||||
title={title}
|
||||
parsedTitle={parsedTitle}
|
||||
posterUrl={posterUrl}
|
||||
isPosterUrlCorrect={isPosterUrlCorrect}
|
||||
posterList={posterList}
|
||||
currentLang={currentLang}
|
||||
posterSearchLanguage={posterSearchLanguage}
|
||||
setPosterSearchLanguage={setPosterSearchLanguage}
|
||||
posterSearch={posterSearch}
|
||||
removePoster={removePoster}
|
||||
updateTitleFromSource={updateTitleFromSource}
|
||||
setSelectedFile={setSelectedFile}
|
||||
torrentSource={torrentSource}
|
||||
isCustomTitleEnabled={isCustomTitleEnabled}
|
||||
setIsCustomTitleEnabled={setIsCustomTitleEnabled}
|
||||
isEditMode={isEditMode}
|
||||
setTorrentSource={setTorrentSource}
|
||||
selectedFile={selectedFile}
|
||||
/>
|
||||
</Content>
|
||||
)}
|
||||
|
||||
<ButtonWrapper>
|
||||
<Button onClick={handleClose} color='primary' variant='outlined'>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<RightSideComponent
|
||||
originalTorrentTitle={originalTorrentTitle}
|
||||
setTitle={setTitle}
|
||||
setPosterUrl={setPosterUrl}
|
||||
setIsPosterUrlCorrect={setIsPosterUrlCorrect}
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setPosterList={setPosterList}
|
||||
isTorrentSourceCorrect={isTorrentSourceCorrect}
|
||||
isHashAlreadyExists={isHashAlreadyExists}
|
||||
title={title}
|
||||
parsedTitle={parsedTitle}
|
||||
posterUrl={posterUrl}
|
||||
isPosterUrlCorrect={isPosterUrlCorrect}
|
||||
posterList={posterList}
|
||||
currentLang={currentLang}
|
||||
posterSearchLanguage={posterSearchLanguage}
|
||||
setPosterSearchLanguage={setPosterSearchLanguage}
|
||||
posterSearch={posterSearch}
|
||||
removePoster={removePoster}
|
||||
updateTitleFromSource={updateTitleFromSource}
|
||||
torrentSource={torrentSource}
|
||||
isCustomTitleEnabled={isCustomTitleEnabled}
|
||||
setIsCustomTitleEnabled={setIsCustomTitleEnabled}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Button
|
||||
variant='contained'
|
||||
style={{ minWidth: '110px' }}
|
||||
disabled={!torrentSource || (isHashAlreadyExists && !isEditMode) || !isTorrentSourceCorrect}
|
||||
onClick={handleSave}
|
||||
color='primary'
|
||||
>
|
||||
{isSaving ? <CircularProgress style={{ color: 'white' }} size={20} /> : t(isEditMode ? 'Save' : 'Add')}
|
||||
</Button>
|
||||
</ButtonWrapper>
|
||||
</Dialog>
|
||||
</ThemeProvider>
|
||||
<ButtonWrapper>
|
||||
<Button onClick={handleClose} color='primary' variant='outlined'>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant='contained'
|
||||
style={{ minWidth: '110px' }}
|
||||
disabled={!torrentSource || (isHashAlreadyExists && !isEditMode) || !isTorrentSourceCorrect}
|
||||
onClick={handleSave}
|
||||
color='primary'
|
||||
>
|
||||
{isSaving ? <CircularProgress style={{ color: 'white' }} size={20} /> : t(isEditMode ? 'Save' : 'Add')}
|
||||
</Button>
|
||||
</ButtonWrapper>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NoImageIcon } from 'icons'
|
||||
import { IconButton, InputAdornment, TextField } from '@material-ui/core'
|
||||
import { IconButton, InputAdornment, TextField, useTheme } from '@material-ui/core'
|
||||
import { CheckBox as CheckBoxIcon } from '@material-ui/icons'
|
||||
|
||||
import {
|
||||
@@ -41,6 +41,7 @@ export default function RightSideComponent({
|
||||
isEditMode,
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const primary = useTheme().palette.primary.main
|
||||
|
||||
const handleTitleChange = ({ target: { value } }) => setTitle(value)
|
||||
const handlePosterUrlChange = ({ target: { value } }) => {
|
||||
@@ -91,7 +92,7 @@ export default function RightSideComponent({
|
||||
setIsUserInteractedWithPoster(false)
|
||||
}}
|
||||
>
|
||||
<CheckBoxIcon style={{ color: isCustomTitleEnabled ? 'green' : 'gray' }} />
|
||||
<CheckBoxIcon style={{ color: isCustomTitleEnabled ? primary : 'gray' }} />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
|
||||
@@ -15,14 +15,20 @@ export const Header = styled.div`
|
||||
`
|
||||
|
||||
export const Content = styled.div`
|
||||
${({ isEditMode }) => css`
|
||||
${({
|
||||
isEditMode,
|
||||
theme: {
|
||||
addDialog: { gradientStartColor, gradientEndColor, fontColor },
|
||||
},
|
||||
}) => css`
|
||||
height: 550px;
|
||||
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||
background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(${isEditMode ? '1' : '2'}, 1fr);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
overflow: auto;
|
||||
color: ${fontColor};
|
||||
|
||||
@media (max-width: 540px) {
|
||||
${'' /* Just for bug fixing on small screens */}
|
||||
@@ -44,7 +50,14 @@ export const RightSide = styled.div`
|
||||
`
|
||||
|
||||
export const RightSideContainer = styled.div`
|
||||
${({ isHidden, notificationMessage, isError }) => css`
|
||||
${({
|
||||
isHidden,
|
||||
notificationMessage,
|
||||
isError,
|
||||
theme: {
|
||||
addDialog: { notificationErrorBGColor, notificationSuccessBGColor },
|
||||
},
|
||||
}) => css`
|
||||
height: 530px;
|
||||
|
||||
${notificationMessage &&
|
||||
@@ -58,7 +71,7 @@ export const RightSideContainer = styled.div`
|
||||
content: '${notificationMessage}';
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: ${isError ? '#cda184' : '#88cdaa'};
|
||||
background: ${isError ? notificationErrorBGColor : notificationSuccessBGColor};
|
||||
padding: 10px 15px;
|
||||
position: absolute;
|
||||
top: 52%;
|
||||
@@ -172,11 +185,18 @@ export const IconWrapper = styled.div`
|
||||
`
|
||||
|
||||
export const LeftSideTopSection = styled.div`
|
||||
background: #e4f6ed;
|
||||
padding: 0 20px 20px 20px;
|
||||
transition: all 0.3s;
|
||||
${({
|
||||
active,
|
||||
theme: {
|
||||
addDialog: { gradientStartColor },
|
||||
},
|
||||
}) => css`
|
||||
background: ${gradientStartColor};
|
||||
padding: 0 20px 20px 20px;
|
||||
transition: all 0.3s;
|
||||
|
||||
${({ active }) => active && 'box-shadow: 0 8px 10px -9px rgba(0, 0, 0, 0.5)'};
|
||||
${active && 'box-shadow: 0 8px 10px -9px rgba(0, 0, 0, 0.5)'};
|
||||
`}
|
||||
`
|
||||
|
||||
export const PosterWrapper = styled.div`
|
||||
@@ -254,7 +274,12 @@ export const PosterSuggestionsItem = styled.div`
|
||||
`
|
||||
|
||||
export const Poster = styled.div`
|
||||
${({ poster }) => css`
|
||||
${({
|
||||
poster,
|
||||
theme: {
|
||||
addDialog: { posterBGColor },
|
||||
},
|
||||
}) => css`
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
width: 200px;
|
||||
@@ -272,7 +297,7 @@ export const Poster = styled.div`
|
||||
: css`
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: #74c39c;
|
||||
background: ${posterBGColor};
|
||||
|
||||
svg {
|
||||
transform: scale(1.5) translateY(-3px);
|
||||
@@ -294,28 +319,35 @@ export const ClearPosterButton = styled(Button)`
|
||||
`
|
||||
|
||||
export const PosterLanguageSwitch = styled.div`
|
||||
grid-area: poster;
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #74c39c;
|
||||
border-radius: 50%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #e4f6ed;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
${({
|
||||
showbutton,
|
||||
theme: {
|
||||
addDialog: { languageSwitchBGColor, languageSwitchFontColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: poster;
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: ${languageSwitchBGColor};
|
||||
border-radius: 50%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: ${languageSwitchFontColor};
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
${({ showbutton }) => !showbutton && 'display: none'};
|
||||
${!showbutton && 'display: none'};
|
||||
|
||||
:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const ButtonWrapper = styled.div`
|
||||
|
||||
@@ -21,18 +21,24 @@ const Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading }
|
||||
<AppSidebarStyle isDrawerOpen={isDrawerOpen}>
|
||||
<List>
|
||||
<AddDialogButton isOffline={isOffline} isLoading={isLoading} />
|
||||
|
||||
<RemoveAll isOffline={isOffline} isLoading={isLoading} />
|
||||
</List>
|
||||
|
||||
<Divider />
|
||||
|
||||
<List>
|
||||
<SettingsDialog />
|
||||
|
||||
<AboutDialog />
|
||||
|
||||
<ListItem button onClick={() => setIsDonationDialogOpen(true)}>
|
||||
<ListItemIcon>
|
||||
<CreditCardIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t('Donate')} />
|
||||
</ListItem>
|
||||
|
||||
<CloseServer isOffline={isOffline} isLoading={isLoading} />
|
||||
</List>
|
||||
</AppSidebarStyle>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { createContext, useEffect, useState } from 'react'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import { Menu as MenuIcon, Close as CloseIcon } from '@material-ui/icons'
|
||||
import {
|
||||
Menu as MenuIcon,
|
||||
Close as CloseIcon,
|
||||
Brightness4 as Brightness4Icon,
|
||||
Brightness5 as Brightness5Icon,
|
||||
BrightnessAuto as BrightnessAutoIcon,
|
||||
} from '@material-ui/icons'
|
||||
import { echoHost } from 'utils/Hosts'
|
||||
import Div100vh from 'react-div-100vh'
|
||||
import axios from 'axios'
|
||||
@@ -16,18 +22,20 @@ import { useQuery } from 'react-query'
|
||||
import { getTorrents } from 'utils/Utils'
|
||||
import GlobalStyle from 'style/GlobalStyle'
|
||||
|
||||
import { AppWrapper, AppHeader, LanguageSwitch } from './style'
|
||||
import { AppWrapper, AppHeader, HeaderToggle } from './style'
|
||||
import Sidebar from './Sidebar'
|
||||
import { darkTheme, lightTheme, useMaterialUITheme } from '../../style/materialUISetup'
|
||||
import { lightTheme, THEME_MODES, useMaterialUITheme } from '../../style/materialUISetup'
|
||||
import getStyledComponentsTheme from '../../style/getStyledComponentsTheme'
|
||||
|
||||
export const DarkModeContext = createContext()
|
||||
|
||||
export default function App() {
|
||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
|
||||
const [isDonationDialogOpen, setIsDonationDialogOpen] = useState(false)
|
||||
const [torrServerVersion, setTorrServerVersion] = useState('')
|
||||
|
||||
// https://material-ui.com/ru/customization/palette/
|
||||
const [isDarkMode, muiTheme] = useMaterialUITheme()
|
||||
const [isDarkMode, currentThemeMode, setCurrentThemeMode, muiTheme] = useMaterialUITheme()
|
||||
const [currentLang, changeLang] = useChangeLanguage()
|
||||
const [isOffline, setIsOffline] = useState(false)
|
||||
const { data: torrents, isLoading } = useQuery('torrents', getTorrents, {
|
||||
@@ -45,54 +53,74 @@ export default function App() {
|
||||
<>
|
||||
<GlobalStyle />
|
||||
|
||||
<MuiThemeProvider theme={muiTheme}>
|
||||
<StyledComponentsThemeProvider theme={getStyledComponentsTheme(isDarkMode ? 'dark' : 'light')}>
|
||||
<CssBaseline />
|
||||
<DarkModeContext.Provider value={{ isDarkMode }}>
|
||||
<MuiThemeProvider theme={muiTheme}>
|
||||
<StyledComponentsThemeProvider
|
||||
theme={getStyledComponentsTheme(isDarkMode ? THEME_MODES.DARK : THEME_MODES.LIGHT)}
|
||||
>
|
||||
<CssBaseline />
|
||||
|
||||
{/* Div100vh - iOS WebKit fix */}
|
||||
<Div100vh>
|
||||
<AppWrapper>
|
||||
<AppHeader>
|
||||
<IconButton
|
||||
style={{ marginRight: '20px' }}
|
||||
color='inherit'
|
||||
onClick={() => setIsDrawerOpen(!isDrawerOpen)}
|
||||
edge='start'
|
||||
>
|
||||
{isDrawerOpen ? <CloseIcon /> : <MenuIcon />}
|
||||
</IconButton>
|
||||
{/* Div100vh - iOS WebKit fix */}
|
||||
<Div100vh>
|
||||
<AppWrapper>
|
||||
<AppHeader>
|
||||
<IconButton
|
||||
style={{ marginRight: '20px' }}
|
||||
color='inherit'
|
||||
onClick={() => setIsDrawerOpen(!isDrawerOpen)}
|
||||
edge='start'
|
||||
>
|
||||
{isDrawerOpen ? <CloseIcon /> : <MenuIcon />}
|
||||
</IconButton>
|
||||
|
||||
<Typography variant='h6' noWrap>
|
||||
TorrServer {torrServerVersion}
|
||||
</Typography>
|
||||
<Typography variant='h6' noWrap>
|
||||
TorrServer {torrServerVersion}
|
||||
</Typography>
|
||||
|
||||
<div style={{ justifySelf: 'end' }}>
|
||||
<LanguageSwitch onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}>
|
||||
{currentLang === 'en' ? 'RU' : 'EN'}
|
||||
</LanguageSwitch>
|
||||
</div>
|
||||
</AppHeader>
|
||||
<div
|
||||
style={{ justifySelf: 'end', display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px' }}
|
||||
>
|
||||
<HeaderToggle
|
||||
onClick={() => {
|
||||
currentThemeMode === THEME_MODES.LIGHT && setCurrentThemeMode(THEME_MODES.DARK)
|
||||
currentThemeMode === THEME_MODES.DARK && setCurrentThemeMode(THEME_MODES.AUTO)
|
||||
currentThemeMode === THEME_MODES.AUTO && setCurrentThemeMode(THEME_MODES.LIGHT)
|
||||
}}
|
||||
>
|
||||
{currentThemeMode === THEME_MODES.LIGHT ? (
|
||||
<Brightness5Icon />
|
||||
) : currentThemeMode === THEME_MODES.DARK ? (
|
||||
<Brightness4Icon />
|
||||
) : (
|
||||
<BrightnessAutoIcon />
|
||||
)}
|
||||
</HeaderToggle>
|
||||
|
||||
<HeaderToggle onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}>
|
||||
{currentLang === 'en' ? 'RU' : 'EN'}
|
||||
</HeaderToggle>
|
||||
</div>
|
||||
</AppHeader>
|
||||
|
||||
<MuiThemeProvider theme={darkTheme}>
|
||||
<Sidebar
|
||||
isOffline={isOffline}
|
||||
isLoading={isLoading}
|
||||
isDrawerOpen={isDrawerOpen}
|
||||
setIsDonationDialogOpen={setIsDonationDialogOpen}
|
||||
/>
|
||||
</MuiThemeProvider>
|
||||
|
||||
<TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} />
|
||||
<TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} />
|
||||
|
||||
<MuiThemeProvider theme={lightTheme}>
|
||||
{isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />}
|
||||
</MuiThemeProvider>
|
||||
<MuiThemeProvider theme={lightTheme}>
|
||||
{isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />}
|
||||
</MuiThemeProvider>
|
||||
|
||||
{!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />}
|
||||
</AppWrapper>
|
||||
</Div100vh>
|
||||
</StyledComponentsThemeProvider>
|
||||
</MuiThemeProvider>
|
||||
{!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />}
|
||||
</AppWrapper>
|
||||
</Div100vh>
|
||||
</StyledComponentsThemeProvider>
|
||||
</MuiThemeProvider>
|
||||
</DarkModeContext.Provider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import { rgba } from 'polished'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const AppWrapper = styled.div`
|
||||
height: 100%;
|
||||
background: #cbe8d9;
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr;
|
||||
grid-template-rows: 60px 1fr;
|
||||
grid-template-areas:
|
||||
'head head'
|
||||
'side content';
|
||||
${({
|
||||
theme: {
|
||||
app: { appSecondaryColor },
|
||||
},
|
||||
}) => css`
|
||||
height: 100%;
|
||||
background: ${rgba(appSecondaryColor, 0.8)};
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr;
|
||||
grid-template-rows: 60px 1fr;
|
||||
grid-template-areas:
|
||||
'head head'
|
||||
'side content';
|
||||
`}
|
||||
`
|
||||
|
||||
export const CenteredGrid = styled.div`
|
||||
@@ -32,16 +39,25 @@ export const AppHeader = styled.div`
|
||||
`}
|
||||
`
|
||||
export const AppSidebarStyle = styled.div`
|
||||
${({ isDrawerOpen }) => css`
|
||||
${({
|
||||
isDrawerOpen,
|
||||
theme: {
|
||||
app: { appSecondaryColor, sidebarBGColor, sidebarFillColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: side;
|
||||
width: ${isDrawerOpen ? '400%' : '100%'};
|
||||
z-index: 2;
|
||||
overflow-x: hidden;
|
||||
transition: width 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.12);
|
||||
background: #575757;
|
||||
color: #eee;
|
||||
border-right: 1px solid ${rgba(appSecondaryColor, 0.12)};
|
||||
background: ${sidebarBGColor};
|
||||
color: ${sidebarFillColor};
|
||||
white-space: nowrap;
|
||||
|
||||
svg {
|
||||
fill: ${sidebarFillColor};
|
||||
}
|
||||
`}
|
||||
`
|
||||
export const TorrentListWrapper = styled.div`
|
||||
@@ -69,25 +85,31 @@ export const TorrentListWrapper = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
export const LanguageSwitch = styled.div`
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
background: #56b887;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
transition: all 0.2s;
|
||||
font-weight: 600;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
export const HeaderToggle = styled.div`
|
||||
${({
|
||||
theme: {
|
||||
app: { headerToggleColor },
|
||||
},
|
||||
}) => css`
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
background: ${headerToggleColor};
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
transition: all 0.2s;
|
||||
font-weight: 600;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
|
||||
:hover {
|
||||
background: #4db380;
|
||||
}
|
||||
:hover {
|
||||
background: ${rgba(headerToggleColor, 0.9)};
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
@@ -1,19 +1,33 @@
|
||||
import styled from 'styled-components'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const DetailedViewWidgetSection = styled.section`
|
||||
padding: 40px;
|
||||
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||
${({
|
||||
theme: {
|
||||
detailedView: { gradientStartColor, gradientEndColor },
|
||||
},
|
||||
}) => css`
|
||||
padding: 40px;
|
||||
background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const DetailedViewCacheSection = styled.section`
|
||||
padding: 40px;
|
||||
box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);
|
||||
${({
|
||||
theme: {
|
||||
detailedView: { cacheSectionBGColor },
|
||||
},
|
||||
}) => css`
|
||||
padding: 40px;
|
||||
box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);
|
||||
background: ${cacheSectionBGColor};
|
||||
flex: 1;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
@@ -1,77 +1,89 @@
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
const bigTableDividerColor = '#ddd'
|
||||
const bigTableViewedColor = '#f3f3f3'
|
||||
const defaultPrimaryColor = '#009879'
|
||||
const defaultSecondaryColor = '#00a383'
|
||||
const defaultTertiaryColor = '#03aa89'
|
||||
const viewedPrimaryColor = '#bdbdbd'
|
||||
const viewedSecondaryColor = '#c4c4c4'
|
||||
const viewedTertiaryColor = '#c9c9c9'
|
||||
const bigTableDividerColor = '#ddd'
|
||||
const bigTableDefaultRowColor = '#fff'
|
||||
const bigTableViewedRowColor = '#f3f3f3'
|
||||
|
||||
const viewedIndicator = css`
|
||||
:before {
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: ${defaultPrimaryColor};
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
${({
|
||||
theme: {
|
||||
table: { defaultPrimaryColor },
|
||||
},
|
||||
}) => css`
|
||||
:before {
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: ${defaultPrimaryColor};
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
`}
|
||||
`
|
||||
export const TableStyle = styled.table`
|
||||
border-collapse: collapse;
|
||||
margin: 25px 0;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
border-radius: 5px 5px 0 0;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
${({
|
||||
theme: {
|
||||
table: { defaultPrimaryColor },
|
||||
},
|
||||
}) => css`
|
||||
border-collapse: collapse;
|
||||
margin: 25px 0;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
border-radius: 5px 5px 0 0;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
color: #000;
|
||||
|
||||
thead tr {
|
||||
background: ${defaultPrimaryColor};
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 12px 15px;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
border-bottom: 1px solid ${bigTableDividerColor};
|
||||
|
||||
:last-of-type {
|
||||
border-bottom: 2px solid ${defaultPrimaryColor};
|
||||
thead tr {
|
||||
background: ${defaultPrimaryColor};
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
&.viewed-file-row {
|
||||
background: ${bigTableViewedColor};
|
||||
th,
|
||||
td {
|
||||
padding: 12px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
&.viewed-file-indicator {
|
||||
position: relative;
|
||||
tbody tr {
|
||||
border-bottom: 1px solid ${bigTableDividerColor};
|
||||
background: ${bigTableDefaultRowColor};
|
||||
|
||||
${viewedIndicator}
|
||||
:last-of-type {
|
||||
border-bottom: 2px solid ${defaultPrimaryColor};
|
||||
}
|
||||
|
||||
&.viewed-file-row {
|
||||
background: ${bigTableViewedRowColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-cell {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
td {
|
||||
&.viewed-file-indicator {
|
||||
position: relative;
|
||||
|
||||
@media (max-width: 970px) {
|
||||
display: none;
|
||||
}
|
||||
${viewedIndicator}
|
||||
}
|
||||
}
|
||||
|
||||
.button-cell {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 970px) {
|
||||
display: none;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const ShortTableWrapper = styled.div`
|
||||
@@ -91,7 +103,12 @@ export const ShortTableWrapper = styled.div`
|
||||
`
|
||||
|
||||
export const ShortTable = styled.div`
|
||||
${({ isViewed }) => css`
|
||||
${({
|
||||
isViewed,
|
||||
theme: {
|
||||
table: { defaultPrimaryColor, defaultSecondaryColor, defaultTertiaryColor },
|
||||
},
|
||||
}) => css`
|
||||
width: 100%;
|
||||
grid-template-rows: repeat(3, max-content);
|
||||
border-radius: 5px;
|
||||
@@ -170,6 +187,7 @@ export const ShortTable = styled.div`
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
background: #fff;
|
||||
|
||||
@media (max-width: 410px) {
|
||||
gap: 10px;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import Measure from 'react-measure'
|
||||
import { useState, memo, useRef, useEffect } from 'react'
|
||||
import { useState, memo, useRef, useEffect, useContext } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import { DarkModeContext } from 'components/App'
|
||||
|
||||
import { useCreateCacheMap } from '../customHooks'
|
||||
import getShortCacheMap from './getShortCacheMap'
|
||||
@@ -16,6 +17,9 @@ const TorrentCache = ({ cache, isMini }) => {
|
||||
const ctxRef = useRef(null)
|
||||
const cacheMap = useCreateCacheMap(cache)
|
||||
const settingsTarget = isMini ? 'mini' : 'default'
|
||||
const { isDarkMode } = useContext(DarkModeContext)
|
||||
const theme = isDarkMode ? 'dark' : 'light'
|
||||
|
||||
const {
|
||||
readerColor,
|
||||
rangeColor,
|
||||
@@ -26,7 +30,7 @@ const TorrentCache = ({ cache, isMini }) => {
|
||||
borderColor,
|
||||
cacheMaxHeight,
|
||||
completeColor,
|
||||
} = snakeSettings[settingsTarget]
|
||||
} = snakeSettings[theme][settingsTarget]
|
||||
|
||||
const canvasWidth = isMini ? width * 0.93 : width
|
||||
|
||||
@@ -69,7 +73,7 @@ const TorrentCache = ({ cache, isMini }) => {
|
||||
|
||||
ctx.lineWidth = borderWidth
|
||||
ctx.fillStyle = inProgress
|
||||
? createGradient(ctx, percentage, settingsTarget)
|
||||
? createGradient(ctx, percentage, theme, settingsTarget)
|
||||
: isCompleted
|
||||
? completeColor
|
||||
: backgroundColor
|
||||
@@ -102,13 +106,14 @@ const TorrentCache = ({ cache, isMini }) => {
|
||||
completeColor,
|
||||
readerColor,
|
||||
rangeColor,
|
||||
theme,
|
||||
])
|
||||
|
||||
return (
|
||||
<Measure bounds onResize={({ bounds }) => setDimensions(bounds)}>
|
||||
{({ measureRef }) => (
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }} ref={measureRef}>
|
||||
<SnakeWrapper isMini={isMini}>
|
||||
<SnakeWrapper themeType={theme} isMini={isMini}>
|
||||
<canvas ref={canvasRef} />
|
||||
</SnakeWrapper>
|
||||
|
||||
|
||||
@@ -1,33 +1,60 @@
|
||||
import { mainColors } from 'style/colors'
|
||||
|
||||
export const snakeSettings = {
|
||||
default: {
|
||||
borderWidth: 1,
|
||||
pieceSize: 14,
|
||||
gapBetweenPieces: 3,
|
||||
borderColor: '#dbf2e8',
|
||||
completeColor: mainColors.primary,
|
||||
backgroundColor: '#fff',
|
||||
progressColor: '#b3dfc9',
|
||||
readerColor: '#000',
|
||||
rangeColor: '#afa6e3',
|
||||
dark: {
|
||||
default: {
|
||||
borderWidth: 1,
|
||||
pieceSize: 14,
|
||||
gapBetweenPieces: 3,
|
||||
borderColor: mainColors.dark.primary,
|
||||
completeColor: mainColors.dark.primary,
|
||||
backgroundColor: '#fff',
|
||||
progressColor: '#545a5e',
|
||||
readerColor: '#fff',
|
||||
rangeColor: '#cda184',
|
||||
},
|
||||
mini: {
|
||||
cacheMaxHeight: 340,
|
||||
borderWidth: 2,
|
||||
pieceSize: 23,
|
||||
gapBetweenPieces: 6,
|
||||
borderColor: '#545a5e',
|
||||
completeColor: '#545a5e',
|
||||
backgroundColor: '#dee3e5',
|
||||
progressColor: '#dee3e5',
|
||||
readerColor: '#000',
|
||||
rangeColor: '#cda184',
|
||||
},
|
||||
},
|
||||
mini: {
|
||||
cacheMaxHeight: 340,
|
||||
borderWidth: 2,
|
||||
pieceSize: 23,
|
||||
gapBetweenPieces: 6,
|
||||
borderColor: '#4db380',
|
||||
completeColor: '#4db380',
|
||||
backgroundColor: '#dbf2e8',
|
||||
progressColor: '#dbf2e8',
|
||||
readerColor: '#2d714f',
|
||||
rangeColor: '#afa6e3',
|
||||
light: {
|
||||
default: {
|
||||
borderWidth: 1,
|
||||
pieceSize: 14,
|
||||
gapBetweenPieces: 3,
|
||||
borderColor: '#dbf2e8',
|
||||
completeColor: mainColors.light.primary,
|
||||
backgroundColor: '#fff',
|
||||
progressColor: '#b3dfc9',
|
||||
readerColor: '#000',
|
||||
rangeColor: '#afa6e3',
|
||||
},
|
||||
mini: {
|
||||
cacheMaxHeight: 340,
|
||||
borderWidth: 2,
|
||||
pieceSize: 23,
|
||||
gapBetweenPieces: 6,
|
||||
borderColor: '#4db380',
|
||||
completeColor: '#4db380',
|
||||
backgroundColor: '#dbf2e8',
|
||||
progressColor: '#dbf2e8',
|
||||
readerColor: '#2d714f',
|
||||
rangeColor: '#afa6e3',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const createGradient = (ctx, percentage, snakeType) => {
|
||||
const { pieceSize, completeColor, progressColor } = snakeSettings[snakeType]
|
||||
export const createGradient = (ctx, percentage, theme, snakeType) => {
|
||||
const { pieceSize, completeColor, progressColor } = snakeSettings[theme][snakeType]
|
||||
|
||||
const gradient = ctx.createLinearGradient(0, pieceSize, 0, 0)
|
||||
gradient.addColorStop(0, completeColor)
|
||||
|
||||
@@ -10,12 +10,12 @@ export const ScrollNotification = styled.div`
|
||||
`
|
||||
|
||||
export const SnakeWrapper = styled.div`
|
||||
${({ isMini }) => css`
|
||||
${({ isMini, themeType }) => css`
|
||||
${isMini &&
|
||||
css`
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
max-height: ${snakeSettings.mini.cacheMaxHeight}px;
|
||||
max-height: ${snakeSettings[themeType].mini.cacheMaxHeight}px;
|
||||
overflow: auto;
|
||||
`}
|
||||
|
||||
|
||||
@@ -19,11 +19,17 @@ export const MainSectionButtonGroup = styled.div`
|
||||
`
|
||||
|
||||
export const SmallLabel = styled.div`
|
||||
${({ mb }) => css`
|
||||
${({
|
||||
mb,
|
||||
theme: {
|
||||
torrentFunctions: { fontColor },
|
||||
},
|
||||
}) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
color: ${fontColor};
|
||||
|
||||
@media (max-width: 800px) {
|
||||
font-size: 18px;
|
||||
|
||||
@@ -133,7 +133,13 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
||||
{...(isDetailedCacheView && { onBack: () => setIsDetailedCacheView(false) })}
|
||||
/>
|
||||
|
||||
<div style={{ minHeight: '80vh', overflow: 'auto' }}>
|
||||
<div
|
||||
style={{
|
||||
minHeight: '80vh',
|
||||
overflow: 'auto',
|
||||
...(isDetailedCacheView && { display: 'flex', flexDirection: 'column' }),
|
||||
}}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : isDetailedCacheView ? (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { rgba } from 'polished'
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const DialogContentGrid = styled.div`
|
||||
@@ -18,7 +19,12 @@ export const DialogContentGrid = styled.div`
|
||||
}
|
||||
`
|
||||
export const Poster = styled.div`
|
||||
${({ poster }) => css`
|
||||
${({
|
||||
poster,
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { posterBGColor },
|
||||
},
|
||||
}) => css`
|
||||
height: 400px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
@@ -35,7 +41,7 @@ export const Poster = styled.div`
|
||||
width: 300px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: #74c39c;
|
||||
background: ${posterBGColor};
|
||||
|
||||
svg {
|
||||
transform: scale(2.5) translateY(-3px);
|
||||
@@ -58,72 +64,104 @@ export const Poster = styled.div`
|
||||
`}
|
||||
`
|
||||
export const MainSection = styled.section`
|
||||
grid-area: main;
|
||||
padding: 40px;
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr;
|
||||
gap: 30px;
|
||||
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { gradientStartColor, gradientEndColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: main;
|
||||
padding: 40px;
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr;
|
||||
gap: 30px;
|
||||
background: linear-gradient(145deg, ${gradientStartColor}, ${gradientEndColor});
|
||||
|
||||
@media (max-width: 840px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`
|
||||
|
||||
export const CacheSection = styled.section`
|
||||
grid-area: cache;
|
||||
padding: 40px;
|
||||
display: grid;
|
||||
align-content: start;
|
||||
grid-template-rows: min-content 1fr min-content;
|
||||
background: #88cdaa;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`
|
||||
|
||||
export const TorrentFilesSection = styled.section`
|
||||
grid-area: file-list;
|
||||
padding: 40px;
|
||||
box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`
|
||||
|
||||
export const SectionSubName = styled.div`
|
||||
${({ mb }) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
color: #7c7b7c;
|
||||
@media (max-width: 840px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
${mb && `margin-bottom: ${mb / 2}px`};
|
||||
font-size: 11px;
|
||||
padding: 20px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const SectionTitle = styled.div`
|
||||
${({ mb }) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
font-size: 35px;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
word-break: break-word;
|
||||
export const CacheSection = styled.section`
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { chacheSectionBGColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: cache;
|
||||
padding: 40px;
|
||||
display: grid;
|
||||
align-content: start;
|
||||
grid-template-rows: min-content 1fr min-content;
|
||||
background: ${chacheSectionBGColor};
|
||||
|
||||
@media (max-width: 800px) {
|
||||
font-size: 25px;
|
||||
${mb && `margin-bottom: ${mb / 2}px`};
|
||||
padding: 20px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const TorrentFilesSection = styled.section`
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { torrentFilesSectionBGColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: file-list;
|
||||
padding: 40px;
|
||||
box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5);
|
||||
background: ${torrentFilesSectionBGColor};
|
||||
|
||||
@media (max-width: 800px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const SectionSubName = styled.div`
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { subNameFontColor },
|
||||
},
|
||||
}) => css`
|
||||
${({ mb }) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
color: ${subNameFontColor};
|
||||
|
||||
@media (max-width: 800px) {
|
||||
${mb && `margin-bottom: ${mb / 2}px`};
|
||||
font-size: 11px;
|
||||
}
|
||||
`}
|
||||
`}
|
||||
`
|
||||
|
||||
export const SectionTitle = styled.div`
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { fontColor },
|
||||
},
|
||||
}) => css`
|
||||
${({ mb }) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
font-size: 35px;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
word-break: break-word;
|
||||
color: ${fontColor};
|
||||
|
||||
@media (max-width: 800px) {
|
||||
font-size: 25px;
|
||||
${mb && `margin-bottom: ${mb / 2}px`};
|
||||
}
|
||||
`}
|
||||
`}
|
||||
`
|
||||
|
||||
export const SectionHeader = styled.div`
|
||||
margin-bottom: 20px;
|
||||
`
|
||||
@@ -182,18 +220,25 @@ export const WidgetFieldWrapper = styled.div`
|
||||
}
|
||||
`
|
||||
export const WidgetFieldTitle = styled.div`
|
||||
grid-area: title;
|
||||
justify-self: start;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 600;
|
||||
${({
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { fontColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: title;
|
||||
justify-self: start;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 600;
|
||||
color: ${fontColor};
|
||||
`}
|
||||
`
|
||||
|
||||
export const WidgetFieldIcon = styled.div`
|
||||
${({ bgColor }) => css`
|
||||
grid-area: icon;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
color: ${rgba('#fff', 0.8)};
|
||||
background: ${bgColor};
|
||||
border-radius: 5px 0 0 5px;
|
||||
|
||||
@@ -220,20 +265,29 @@ export const WidgetFieldValue = styled.div`
|
||||
`}
|
||||
`
|
||||
|
||||
export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => {
|
||||
const percentage = Math.min(100, (value * 100) / fullAmount)
|
||||
|
||||
return {
|
||||
// this block is here according to styled-components recomendation about fast changable components
|
||||
style: {
|
||||
background: `linear-gradient(to right, #b5dec9 0%, #b5dec9 ${percentage}%, #fff ${percentage}%, #fff 100%)`,
|
||||
export const LoadingProgress = styled.div.attrs(
|
||||
({
|
||||
value,
|
||||
fullAmount,
|
||||
theme: {
|
||||
dialogTorrentDetailsContent: { gradientEndColor },
|
||||
},
|
||||
}
|
||||
})`
|
||||
}) => {
|
||||
const percentage = Math.min(100, (value * 100) / fullAmount)
|
||||
|
||||
return {
|
||||
// this block is here according to styled-components recomendation about fast changable components
|
||||
style: {
|
||||
background: `linear-gradient(to right, ${gradientEndColor} 0%, ${gradientEndColor} ${percentage}%, #fff ${percentage}%, #fff 100%)`,
|
||||
},
|
||||
}
|
||||
},
|
||||
)`
|
||||
${({ label }) => css`
|
||||
border: 1px solid;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
color: #000;
|
||||
|
||||
:before {
|
||||
content: '${label}';
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import styled, { css } from 'styled-components'
|
||||
|
||||
export const TorrentCard = styled.div`
|
||||
${({ theme: { primary } }) => css`
|
||||
${({
|
||||
theme: {
|
||||
torrentCard: { cardPrimaryColor },
|
||||
},
|
||||
}) => css`
|
||||
border-radius: 5px;
|
||||
display: grid;
|
||||
grid-template-columns: 120px 260px 1fr;
|
||||
@@ -9,7 +13,7 @@ export const TorrentCard = styled.div`
|
||||
grid-template-areas: 'poster description buttons';
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
background: ${primary};
|
||||
background: ${cardPrimaryColor};
|
||||
box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
@@ -34,7 +38,12 @@ export const TorrentCardPoster = styled.div`
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
|
||||
${({ isPoster }) =>
|
||||
${({
|
||||
isPoster,
|
||||
theme: {
|
||||
torrentCard: { cardSecondaryColor, accentCardColor },
|
||||
},
|
||||
}) =>
|
||||
isPoster
|
||||
? css`
|
||||
img {
|
||||
@@ -47,8 +56,8 @@ export const TorrentCardPoster = styled.div`
|
||||
: css`
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: #74c39c;
|
||||
border: 1px solid #337a57;
|
||||
background: ${cardSecondaryColor};
|
||||
border: 1px solid ${accentCardColor};
|
||||
|
||||
svg {
|
||||
transform: translateY(-3px);
|
||||
@@ -76,128 +85,140 @@ export const TorrentCardButtons = styled.div`
|
||||
}
|
||||
`
|
||||
export const TorrentCardDescription = styled.div`
|
||||
grid-area: description;
|
||||
background: #74c39c;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
display: grid;
|
||||
grid-template-rows: 55% 1fr;
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: 770px) {
|
||||
grid-template-rows: 60% 1fr;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.description-title-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.description-section-name {
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.4px;
|
||||
color: #337a57;
|
||||
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.description-torrent-title {
|
||||
overflow: auto;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.description-statistics-wrapper {
|
||||
${({
|
||||
theme: {
|
||||
torrentCard: { cardSecondaryColor, accentCardColor },
|
||||
},
|
||||
}) => css`
|
||||
grid-area: description;
|
||||
background: ${cardSecondaryColor};
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
display: grid;
|
||||
grid-template-columns: 80px 80px 1fr;
|
||||
align-self: end;
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
grid-template-columns: 70px 70px 1fr;
|
||||
}
|
||||
grid-template-rows: 55% 1fr;
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: 770px) {
|
||||
grid-template-columns: 65px 65px 1fr;
|
||||
grid-template-rows: 60% 1fr;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.description-statistics-element-wrapper {
|
||||
}
|
||||
|
||||
.description-statistics-element-value {
|
||||
margin-left: 5px;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
font-size: 0.7rem;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.description-torrent-title,
|
||||
.description-statistics-element-value {
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.6rem;
|
||||
.description-title-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (max-width: 410px) {
|
||||
.description-section-name {
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.4px;
|
||||
color: ${accentCardColor};
|
||||
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.description-torrent-title {
|
||||
overflow: auto;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.description-statistics-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 80px 80px 1fr;
|
||||
align-self: end;
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
grid-template-columns: 70px 70px 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 770px) {
|
||||
grid-template-columns: 65px 65px 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.description-statistics-element-wrapper {
|
||||
}
|
||||
|
||||
.description-statistics-element-value {
|
||||
margin-left: 5px;
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
font-size: 0.7rem;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.description-torrent-title,
|
||||
.description-statistics-element-value {
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
|
||||
@media (max-width: 410px) {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
export const StyledButton = styled.button`
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
background: #268757;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.009em;
|
||||
padding: 0 12px;
|
||||
svg {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
:hover {
|
||||
background: #337a57;
|
||||
}
|
||||
|
||||
> :first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
padding: 7px 10px;
|
||||
justify-content: center;
|
||||
font-size: 0.8rem;
|
||||
|
||||
${({
|
||||
theme: {
|
||||
torrentCard: { buttonBGColor, accentCardColor },
|
||||
},
|
||||
}) => css`
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-transform: uppercase;
|
||||
background: ${buttonBGColor};
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.009em;
|
||||
padding: 0 12px;
|
||||
svg {
|
||||
display: none;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
:hover {
|
||||
background: ${accentCardColor};
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
font-size: 0.6rem;
|
||||
padding: 7px 5px;
|
||||
}
|
||||
> :first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 1260px), (max-height: 500px) {
|
||||
padding: 7px 10px;
|
||||
justify-content: center;
|
||||
font-size: 0.8rem;
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 770px) {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
font-size: 0.6rem;
|
||||
padding: 7px 5px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useTheme } from '@material-ui/core'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { mainColors } from 'style/colors'
|
||||
|
||||
import AddDialog from '../Add/AddDialog'
|
||||
import IconWrapper from './style'
|
||||
@@ -10,6 +10,7 @@ export default function AddFirstTorrent() {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||
const handleClickOpen = () => setIsDialogOpen(true)
|
||||
const handleClose = () => setIsDialogOpen(false)
|
||||
const primary = useTheme().palette.primary.main
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -17,7 +18,7 @@ export default function AddFirstTorrent() {
|
||||
<lord-icon
|
||||
src='https://cdn.lordicon.com/bbnkwdur.json'
|
||||
trigger='loop'
|
||||
colors={`primary:#121331,secondary:${mainColors.primary}`}
|
||||
colors={`primary:#121331,secondary:${primary}`}
|
||||
stroke='26'
|
||||
scale='60'
|
||||
/>
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { useTheme } from '@material-ui/core'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { mainColors } from 'style/colors'
|
||||
|
||||
import IconWrapper from './style'
|
||||
|
||||
export default function NoServerConnection() {
|
||||
const { t } = useTranslation()
|
||||
const primary = useTheme().palette.primary.main
|
||||
|
||||
return (
|
||||
<IconWrapper>
|
||||
<lord-icon
|
||||
src='https://cdn.lordicon.com/wrprwmwt.json'
|
||||
trigger='loop'
|
||||
colors={`primary:#121331,secondary:${mainColors.primary}`}
|
||||
colors={`primary:#121331,secondary:${primary}`}
|
||||
stroke='26'
|
||||
scale='60'
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user