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,7 +2,8 @@ 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`
background: ${primary};
color: rgba(0, 0, 0, 0.87); color: rgba(0, 0, 0, 0.87);
font-size: 20px; font-size: 20px;
color: #fff; color: #fff;
@@ -10,6 +11,7 @@ export const Header = styled.div`
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%); 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%);
padding: 15px 24px; padding: 15px 24px;
position: relative; 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,7 +42,11 @@ export default function App() {
}, []) }, [])
return ( return (
<MuiThemeProvider theme={baseTheme}> <>
<GlobalStyle />
<MuiThemeProvider theme={muiTheme}>
<StyledComponentsThemeProvider theme={getStyledComponentsTheme(isDarkMode ? 'dark' : 'light')}>
<CssBaseline /> <CssBaseline />
{/* Div100vh - iOS WebKit fix */} {/* Div100vh - iOS WebKit fix */}
@@ -97,24 +73,26 @@ export default function App() {
</div> </div>
</AppHeader> </AppHeader>
<ThemeProvider theme={darkTheme}> <MuiThemeProvider theme={darkTheme}>
<Sidebar <Sidebar
isOffline={isOffline} isOffline={isOffline}
isLoading={isLoading} isLoading={isLoading}
isDrawerOpen={isDrawerOpen} isDrawerOpen={isDrawerOpen}
setIsDonationDialogOpen={setIsDonationDialogOpen} setIsDonationDialogOpen={setIsDonationDialogOpen}
/> />
</ThemeProvider> </MuiThemeProvider>
<TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} /> <TorrentList isOffline={isOffline} torrents={torrents} isLoading={isLoading} />
<ThemeProvider theme={lightTheme}> <MuiThemeProvider theme={lightTheme}>
{isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />} {isDonationDialogOpen && <DonateDialog onClose={() => setIsDonationDialogOpen(false)} />}
</ThemeProvider> </MuiThemeProvider>
{!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />} {!JSON.parse(localStorage.getItem('snackbarIsClosed')) && <DonateSnackbar />}
</AppWrapper> </AppWrapper>
</Div100vh> </Div100vh>
</StyledComponentsThemeProvider>
</MuiThemeProvider> </MuiThemeProvider>
</>
) )
} }

View File

@@ -18,7 +18,8 @@ export const CenteredGrid = styled.div`
` `
export const AppHeader = styled.div` export const AppHeader = styled.div`
background: #00a572; ${({ theme: { primary } }) => css`
background: ${primary};
color: #fff; color: #fff;
grid-area: head; grid-area: head;
display: grid; display: grid;
@@ -28,6 +29,7 @@ export const AppHeader = styled.div`
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%); 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%);
padding: 0 16px; padding: 0 16px;
z-index: 3; 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,6 +1,7 @@
import styled, { css } from 'styled-components' import styled, { css } from 'styled-components'
export const TorrentCard = styled.div` export const TorrentCard = styled.div`
${({ theme: { primary } }) => css`
border-radius: 5px; border-radius: 5px;
display: grid; display: grid;
grid-template-columns: 120px 260px 1fr; grid-template-columns: 120px 260px 1fr;
@@ -8,7 +9,7 @@ export const TorrentCard = styled.div`
grid-template-areas: 'poster description buttons'; grid-template-areas: 'poster description buttons';
gap: 10px; gap: 10px;
padding: 10px; padding: 10px;
background: #00a572; 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%); 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) {
@@ -24,6 +25,7 @@ export const TorrentCard = styled.div`
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]
}