Merge branch 'dark-light-theme'

This commit is contained in:
Daniel Shleifman
2021-06-20 22:54:46 +03:00
18 changed files with 193 additions and 148 deletions

View File

@@ -12,7 +12,11 @@ import ListItemText from '@material-ui/core/ListItemText'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { echoHost } from 'utils/Hosts' import { echoHost } from 'utils/Hosts'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App' import { themeColors } from 'style/colors'
import { lightTheme } from '../style/materialUISetup'
const { primary } = themeColors
export default function AboutDialog() { export default function AboutDialog() {
const { t } = useTranslation() const { t } = useTranslation()
@@ -38,7 +42,7 @@ export default function AboutDialog() {
<DialogContent> <DialogContent>
<center> <center>
<h2>TorrServer {torrServerVersion}</h2> <h2>TorrServer {torrServerVersion}</h2>
<a style={{ color: '#00a572' }} href='https://github.com/YouROK/TorrServer'> <a style={{ color: primary }} href='https://github.com/YouROK/TorrServer'>
https://github.com/YouROK/TorrServer https://github.com/YouROK/TorrServer
</a> </a>
</center> </center>
@@ -49,22 +53,22 @@ export default function AboutDialog() {
<br /> <br />
<h2>{t('SpecialThanks')}</h2> <h2>{t('SpecialThanks')}</h2>
<b>anacrolix Matt Joiner</b>&nbsp; <b>anacrolix Matt Joiner</b>&nbsp;
<a style={{ color: '#00a572' }} href='https://github.com/anacrolix/'> <a style={{ color: primary }} href='https://github.com/anacrolix/'>
github.com/anacrolix github.com/anacrolix
</a> </a>
<br /> <br />
<b>nikk</b>&nbsp; <b>nikk</b>&nbsp;
<a style={{ color: '#00a572' }} href='https://github.com/tsynik'> <a style={{ color: primary }} href='https://github.com/tsynik'>
github.com/tsynik github.com/tsynik
</a> </a>
<br /> <br />
<b>dancheskus</b>&nbsp; <b>dancheskus</b>&nbsp;
<a style={{ color: '#00a572' }} href='https://github.com/dancheskus'> <a style={{ color: primary }} href='https://github.com/dancheskus'>
github.com/dancheskus github.com/dancheskus
</a> </a>
<br /> <br />
<b>tw1cker Руслан Пахнев</b>&nbsp; <b>tw1cker Руслан Пахнев</b>&nbsp;
<a style={{ color: '#00a572' }} href='https://github.com/Nemiroff'> <a style={{ color: primary }} href='https://github.com/Nemiroff'>
github.com/Nemiroff github.com/Nemiroff
</a> </a>
<br /> <br />

View File

@@ -13,7 +13,7 @@ import { useQuery } from 'react-query'
import { getTorrents } from 'utils/Utils' import { getTorrents } from 'utils/Utils'
import parseTorrent from 'parse-torrent' import parseTorrent from 'parse-torrent'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App' import { lightTheme } from 'style/materialUISetup'
import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers' import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers'
import { ButtonWrapper, Content, Header } from './style' import { ButtonWrapper, Content, Header } from './style'

View File

@@ -2,14 +2,16 @@ import { Button } from '@material-ui/core'
import styled, { css } from 'styled-components' import styled, { css } from 'styled-components'
export const Header = styled.div` export const Header = styled.div`
background: #00a572; ${({ theme: { primary } }) => css`
color: rgba(0, 0, 0, 0.87); background: ${primary};
font-size: 20px; color: rgba(0, 0, 0, 0.87);
color: #fff; font-size: 20px;
font-weight: 600; color: #fff;
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%); font-weight: 600;
padding: 15px 24px; 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%);
position: relative; padding: 15px 24px;
position: relative;
`}
` `
export const Content = styled.div` export const Content = styled.div`

View File

@@ -1,7 +1,5 @@
import useMediaQuery from '@material-ui/core/useMediaQuery'
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core'
import CssBaseline from '@material-ui/core/CssBaseline' import CssBaseline from '@material-ui/core/CssBaseline'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useState } from 'react'
import Typography from '@material-ui/core/Typography' import Typography from '@material-ui/core/Typography'
import IconButton from '@material-ui/core/IconButton' 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 } from '@material-ui/icons'
@@ -12,50 +10,24 @@ import TorrentList from 'components/TorrentList'
import DonateSnackbar from 'components/Donate' import DonateSnackbar from 'components/Donate'
import DonateDialog from 'components/Donate/DonateDialog' import DonateDialog from 'components/Donate/DonateDialog'
import useChangeLanguage from 'utils/useChangeLanguage' import useChangeLanguage from 'utils/useChangeLanguage'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles'
import { ThemeProvider as StyledComponentsThemeProvider } from 'styled-components'
import { useQuery } from 'react-query' import { useQuery } from 'react-query'
import { getTorrents } from 'utils/Utils' import { getTorrents } from 'utils/Utils'
import GlobalStyle from 'style/GlobalStyle'
import { AppWrapper, AppHeader, LanguageSwitch } from './style' import { AppWrapper, AppHeader, LanguageSwitch } from './style'
import Sidebar from './Sidebar' import Sidebar from './Sidebar'
import { darkTheme, lightTheme, useMaterialUITheme } from '../../style/materialUISetup'
// https://material-ui.com/ru/customization/default-theme/ import getStyledComponentsTheme from '../../style/getStyledComponentsTheme'
export const darkTheme = createMuiTheme({
palette: {
type: 'dark',
primary: { main: '#00a572' },
background: { paper: '#575757' },
},
typography: { fontFamily: 'Open Sans, sans-serif' },
})
export const lightTheme = createMuiTheme({
palette: {
type: 'light',
primary: { main: '#00a572' },
background: { paper: '#f1f1f1' },
},
typography: { fontFamily: 'Open Sans, sans-serif' },
})
export default function App() { export default function App() {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)')
const [isDrawerOpen, setIsDrawerOpen] = useState(false) const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [isDonationDialogOpen, setIsDonationDialogOpen] = useState(false) const [isDonationDialogOpen, setIsDonationDialogOpen] = useState(false)
const [torrServerVersion, setTorrServerVersion] = useState('') const [torrServerVersion, setTorrServerVersion] = useState('')
// https://material-ui.com/ru/customization/palette/ // https://material-ui.com/ru/customization/palette/
const baseTheme = useMemo( const [isDarkMode, muiTheme] = useMaterialUITheme()
() =>
createMuiTheme({
palette: {
type: prefersDarkMode ? 'dark' : 'light',
primary: { main: '#00a572' },
secondary: { main: '#ffa724' },
tonalOffset: 0.2,
},
typography: { fontFamily: 'Open Sans, sans-serif' },
}),
[prefersDarkMode],
)
const [currentLang, changeLang] = useChangeLanguage() const [currentLang, changeLang] = useChangeLanguage()
const [isOffline, setIsOffline] = useState(false) const [isOffline, setIsOffline] = useState(false)
const { data: torrents, isLoading } = useQuery('torrents', getTorrents, { const { data: torrents, isLoading } = useQuery('torrents', getTorrents, {
@@ -70,51 +42,57 @@ export default function App() {
}, []) }, [])
return ( return (
<MuiThemeProvider theme={baseTheme}> <>
<CssBaseline /> <GlobalStyle />
{/* Div100vh - iOS WebKit fix */} <MuiThemeProvider theme={muiTheme}>
<Div100vh> <StyledComponentsThemeProvider theme={getStyledComponentsTheme(isDarkMode ? 'dark' : 'light')}>
<AppWrapper> <CssBaseline />
<AppHeader>
<IconButton
style={{ marginRight: '20px' }}
color='inherit'
onClick={() => setIsDrawerOpen(!isDrawerOpen)}
edge='start'
>
{isDrawerOpen ? <CloseIcon /> : <MenuIcon />}
</IconButton>
<Typography variant='h6' noWrap> {/* Div100vh - iOS WebKit fix */}
TorrServer {torrServerVersion} <Div100vh>
</Typography> <AppWrapper>
<AppHeader>
<IconButton
style={{ marginRight: '20px' }}
color='inherit'
onClick={() => setIsDrawerOpen(!isDrawerOpen)}
edge='start'
>
{isDrawerOpen ? <CloseIcon /> : <MenuIcon />}
</IconButton>
<div style={{ justifySelf: 'end' }}> <Typography variant='h6' noWrap>
<LanguageSwitch onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}> TorrServer {torrServerVersion}
{currentLang === 'en' ? 'RU' : 'EN'} </Typography>
</LanguageSwitch>
</div>
</AppHeader>
<ThemeProvider theme={darkTheme}> <div style={{ justifySelf: 'end' }}>
<Sidebar <LanguageSwitch onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}>
isOffline={isOffline} {currentLang === 'en' ? 'RU' : 'EN'}
isLoading={isLoading} </LanguageSwitch>
isDrawerOpen={isDrawerOpen} </div>
setIsDonationDialogOpen={setIsDonationDialogOpen} </AppHeader>
/>
</ThemeProvider>
<TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} /> <MuiThemeProvider theme={darkTheme}>
<Sidebar
isOffline={isOffline}
isLoading={isLoading}
isDrawerOpen={isDrawerOpen}
setIsDonationDialogOpen={setIsDonationDialogOpen}
/>
</MuiThemeProvider>
<ThemeProvider theme={lightTheme}> <TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} />
{isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />}
</ThemeProvider>
{!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />} <MuiThemeProvider theme={lightTheme}>
</AppWrapper> {isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />}
</Div100vh> </MuiThemeProvider>
</MuiThemeProvider>
{!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />}
</AppWrapper>
</Div100vh>
</StyledComponentsThemeProvider>
</MuiThemeProvider>
</>
) )
} }

View File

@@ -18,16 +18,18 @@ export const CenteredGrid = styled.div`
` `
export const AppHeader = styled.div` export const AppHeader = styled.div`
background: #00a572; ${({ theme: { primary } }) => css`
color: #fff; background: ${primary};
grid-area: head; color: #fff;
display: grid; grid-area: head;
grid-auto-flow: column; display: grid;
align-items: center; grid-auto-flow: column;
grid-template-columns: repeat(2, max-content) 1fr; align-items: center;
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%); grid-template-columns: repeat(2, max-content) 1fr;
padding: 0 16px; 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%);
z-index: 3; padding: 0 16px;
z-index: 3;
`}
` `
export const AppSidebarStyle = styled.div` export const AppSidebarStyle = styled.div`
${({ isDrawerOpen }) => css` ${({ isDrawerOpen }) => css`

View File

@@ -4,7 +4,8 @@ import { PowerSettingsNew as PowerSettingsNewIcon } from '@material-ui/icons'
import { shutdownHost } from 'utils/Hosts' import { shutdownHost } from 'utils/Hosts'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App'
import { lightTheme } from '../style/materialUISetup'
export default function CloseServer({ isOffline, isLoading }) { export default function CloseServer({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()

View File

@@ -1,10 +1,12 @@
import { themeColors } from 'style/colors'
export const snakeSettings = { export const snakeSettings = {
default: { default: {
borderWidth: 1, borderWidth: 1,
pieceSize: 14, pieceSize: 14,
gapBetweenPieces: 3, gapBetweenPieces: 3,
borderColor: '#dbf2e8', borderColor: '#dbf2e8',
completeColor: '#00a572', completeColor: themeColors.primary,
backgroundColor: '#fff', backgroundColor: '#fff',
progressColor: '#b3dfc9', progressColor: '#b3dfc9',
readerColor: '#000', readerColor: '#000',

View File

@@ -7,7 +7,8 @@ import { useState } from 'react'
import { torrentsHost } from 'utils/Hosts' import { torrentsHost } from 'utils/Hosts'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App'
import { lightTheme } from '../style/materialUISetup'
const fnRemoveAll = () => { const fnRemoveAll = () => {
fetch(torrentsHost(), { fetch(torrentsHost(), {

View File

@@ -14,7 +14,8 @@ import { FormControlLabel, InputLabel, Select, Switch } from '@material-ui/core'
import { settingsHost, setTorrServerHost, getTorrServerHost } from 'utils/Hosts' import { settingsHost, setTorrServerHost, getTorrServerHost } from 'utils/Hosts'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App'
import { lightTheme } from '../style/materialUISetup'
export default function SettingsDialog() { export default function SettingsDialog() {
const { t } = useTranslation() const { t } = useTranslation()

View File

@@ -1,29 +1,31 @@
import styled, { css } from 'styled-components' import styled, { css } from 'styled-components'
export const TorrentCard = styled.div` export const TorrentCard = styled.div`
border-radius: 5px; ${({ theme: { primary } }) => css`
display: grid; border-radius: 5px;
grid-template-columns: 120px 260px 1fr; display: grid;
grid-template-rows: 180px; grid-template-columns: 120px 260px 1fr;
grid-template-areas: 'poster description buttons'; grid-template-rows: 180px;
gap: 10px; grid-template-areas: 'poster description buttons';
padding: 10px; gap: 10px;
background: #00a572; padding: 10px;
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%); background: ${primary};
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) { @media (max-width: 1260px), (max-height: 500px) {
grid-template-areas: grid-template-areas:
'poster description' 'poster description'
'buttons buttons'; 'buttons buttons';
grid-template-columns: 70px 1fr; grid-template-columns: 70px 1fr;
grid-template-rows: 110px max-content; grid-template-rows: 110px max-content;
} }
@media (max-width: 770px) { @media (max-width: 770px) {
grid-template-columns: 60px 1fr; grid-template-columns: 60px 1fr;
grid-template-rows: 90px max-content; grid-template-rows: 90px max-content;
} }
`}
` `
export const TorrentCardPoster = styled.div` export const TorrentCardPoster = styled.div`

View File

@@ -1,5 +1,6 @@
import { useState } from 'react' import { useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { themeColors } from 'style/colors'
import AddDialog from '../Add/AddDialog' import AddDialog from '../Add/AddDialog'
import IconWrapper from './style' import IconWrapper from './style'
@@ -16,7 +17,7 @@ export default function AddFirstTorrent() {
<lord-icon <lord-icon
src='https://cdn.lordicon.com/bbnkwdur.json' src='https://cdn.lordicon.com/bbnkwdur.json'
trigger='loop' trigger='loop'
colors='primary:#121331,secondary:#00A572' colors={`primary:#121331,secondary:${themeColors.primary}`}
stroke='26' stroke='26'
scale='60' scale='60'
/> />

View File

@@ -1,4 +1,5 @@
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { themeColors } from 'style/colors'
import IconWrapper from './style' import IconWrapper from './style'
@@ -10,7 +11,7 @@ export default function NoServerConnection() {
<lord-icon <lord-icon
src='https://cdn.lordicon.com/wrprwmwt.json' src='https://cdn.lordicon.com/wrprwmwt.json'
trigger='loop' trigger='loop'
colors='primary:#121331,secondary:#00A572' colors={`primary:#121331,secondary:${themeColors.primary}`}
stroke='26' stroke='26'
scale='60' scale='60'
/> />

View File

@@ -1,20 +0,0 @@
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
body {
font-family: "Open Sans", sans-serif;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
letter-spacing: -0.1px;
}
button {
font-family: "Open Sans", sans-serif;
letter-spacing: -0.1px;
}

View File

@@ -5,8 +5,6 @@ import { QueryClientProvider, QueryClient } from 'react-query'
import App from './components/App' import App from './components/App'
import 'i18n' import 'i18n'
import './index.css'
const queryClient = new QueryClient() const queryClient = new QueryClient()
ReactDOM.render( ReactDOM.render(

24
web/src/style/GlobalStyle.js Executable file
View File

@@ -0,0 +1,24 @@
import { createGlobalStyle } from 'styled-components'
export default createGlobalStyle`
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
body {
font-family: "Open Sans", sans-serif;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
letter-spacing: -0.1px;
}
button {
font-family: "Open Sans", sans-serif;
letter-spacing: -0.1px;
}
`

8
web/src/style/colors.js Normal file
View File

@@ -0,0 +1,8 @@
export const themeColors = {
light: {},
dark: {},
}
export const mainColors = {
primary: '#00a572',
}

View File

@@ -0,0 +1,3 @@
import { mainColors, themeColors } from './colors'
export default type => ({ ...themeColors[type], ...mainColors })

View File

@@ -0,0 +1,37 @@
import useMediaQuery from '@material-ui/core/useMediaQuery'
import { createMuiTheme } from '@material-ui/core'
import { useMemo } from 'react'
import { mainColors } from './colors'
// https://material-ui.com/ru/customization/default-theme/
export const darkTheme = createMuiTheme({
palette: {
type: 'dark',
background: { paper: '#575757' },
},
})
export const lightTheme = createMuiTheme({
palette: {
type: 'light',
background: { paper: '#f1f1f1' },
},
})
export const useMaterialUITheme = () => {
const isDarkMode = useMediaQuery('(prefers-color-scheme: dark)')
const muiTheme = useMemo(
() =>
createMuiTheme({
palette: {
type: isDarkMode ? 'dark' : 'light',
primary: { main: mainColors.primary },
},
typography: { fontFamily: 'Open Sans, sans-serif' },
}),
[isDarkMode],
)
return [isDarkMode, muiTheme]
}