light theme, if you want to kill your eyes.

This commit is contained in:
dicedtomatoreal
2020-11-02 15:24:12 -08:00
parent 9f6e7717df
commit 43657a8cb0
15 changed files with 135 additions and 48 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "zipline-next",
"version": "2.1.2",
"version": "2.2.0",
"private": true,
"dependencies": {
"@dicedtomato/colors": "^1.0.3",

View File

@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import AppBar from '@material-ui/core/AppBar';
import Box from '@material-ui/core/Box';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import Drawer from '@material-ui/core/Drawer';
@@ -31,11 +32,13 @@ import FileCopyIcon from '@material-ui/icons/FileCopy';
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
import PublishIcon from '@material-ui/icons/Publish';
import RotateLeftIcon from '@material-ui/icons/RotateLeft';
import Divider from '@material-ui/core/Divider';
import copy from 'copy-to-clipboard';
import { LOGOUT, UPDATE_USER } from '../reducer';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { makeStyles, useTheme, withStyles } from '@material-ui/core/styles';
import { useRouter } from 'next/router';
import { useDispatch } from 'react-redux';
import { store } from '../store';
const drawerWidth = 240;
@@ -53,13 +56,13 @@ const useStyles = makeStyles(theme => ({
},
appBar: {
display: 'flex',
backgroundColor: '#000',
color: '#fff',
backgroundColor: theme.palette.type === 'dark' ? '#000' : '#fff',
color: theme.palette.type !== 'dark' ? '#000' : '#fff',
[theme.breakpoints.up('sm')]: {
width: 'calc(100%)',
marginLeft: drawerWidth
},
borderBottom: '1px solid #1f1f1f'
borderBottom: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0'
},
menuButton: {
marginRight: theme.spacing(2),
@@ -84,9 +87,18 @@ const useStyles = makeStyles(theme => ({
}
}));
const NoFocusMenuItem = withStyles(theme => ({
root: {
'&:hover': {
backgroundColor: theme.palette.type === 'dark' ? '#000' : '#f7f7f7'
}
}
}))(MenuItem);
export default function UI({ children }) {
const classes = useStyles();
const theme = useTheme();
const state = store.getState();
const router = useRouter();
const dispatch = useDispatch();
const [mobileOpen, setMobileOpen] = useState(false);
@@ -161,16 +173,19 @@ export default function UI({ children }) {
<MenuIcon />
</IconButton>
<Typography variant='h6'>Zipline</Typography>
<IconButton
aria-label='account of current user'
aria-controls='menu-appbar'
aria-haspopup='true'
onClick={event => setAnchorEl(event.currentTarget)}
color='inherit'
className={classes.rightButton}
>
<AccountCircleIcon className={classes.rightButton} />
</IconButton>
<Box className={classes.rightButton}>
<IconButton
aria-label='account of current user'
aria-controls='menu-appbar'
aria-haspopup='true'
onClick={event => setAnchorEl(event.currentTarget)}
color='inherit'
className={classes.rightButton}
>
<AccountCircleIcon className={classes.rightButton} />
</IconButton>
</Box>
<Menu
id='menu-appbar'
anchorEl={anchorEl}
@@ -186,6 +201,12 @@ export default function UI({ children }) {
open={open}
onClose={() => setAnchorEl(null)}
>
<NoFocusMenuItem>
<Typography variant='h6'>
{state.user.username}
</Typography>
</NoFocusMenuItem>
<Divider />
<Link href='/user/manage'>
<MenuItem onClick={() => setAnchorEl(null)}>
<AccountCircleIcon className={classes.menuIcon} />

View File

@@ -0,0 +1,15 @@
import React from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import dark from '../lib/themes/dark';
import light from '../lib/themes/light';
export default function ZiplineTheming({ Component, pageProps, theme }) {
console.log(theme);
return (
<ThemeProvider theme={theme == 'light' ? light : dark}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
);
}

View File

@@ -42,6 +42,11 @@ export class RootController {
return first;
}
@GET('/theme')
async getTheme() {
return { theme: config.core.theme || 'dark' };
}
@GET('/users')
async allUsers(req: FastifyRequest, reply: FastifyReply) {
if (!req.cookies.zipline) throw new Error('Not logged in.');

View File

@@ -46,6 +46,7 @@ export interface ConfigCore {
secure?: boolean;
blacklisted_ips?: string[];
ratelimiter?: ConfigCoreRateLimiter;
theme?: 'dark' | 'light';
}
export interface ConfigWebhooks {

38
src/lib/themes/light.ts Normal file
View File

@@ -0,0 +1,38 @@
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
const lightTheme = createMuiTheme({
palette: {
type: 'light',
primary: {
main: '#000000'
},
secondary: {
main: '#4a5bb0'
},
background: {
default: '#fff',
paper: '#f7f7f7'
}
},
overrides: {
MuiListItem: {
root: {
'&$selected': {
backgroundColor: '#e0e0e0'
}
}
},
MuiCard: {
root: {
backgroundColor: '#fff'
}
},
MuiButton: {
root: {
margin: '132'
}
}
}
});
export default lightTheme;

View File

@@ -1,21 +1,26 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from '../store';
import theme from '../lib/themes/dark';
import ZiplineTheming from '../components/ZiplineTheming';
function MyApp({ Component, pageProps }) {
const [theme, setTheme] = useState<'dark' | 'light'>('dark');
useEffect(() => {
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) jssStyles.parentElement.removeChild(jssStyles);
}, []);
(async () => {
const d = await (await fetch('/api/theme')).json();
if (!d.error) setTheme(d.theme);
})();
}, []);
return (
<ThemeProvider theme={theme}>
<React.Fragment>
<Head>
<title>Zipline</title>
<meta
@@ -25,12 +30,11 @@ function MyApp({ Component, pageProps }) {
</Head>
<Provider store={store}>
<PersistGate loading={<div>loading</div>} persistor={persistor}>
<CssBaseline />
<Component {...pageProps} />
<PersistGate loading={<div>Loading...</div>} persistor={persistor}>
<ZiplineTheming Component={Component} pageProps={pageProps} theme={theme} />
</PersistGate>
</Provider>
</ThemeProvider>
</React.Fragment>
);
}
@@ -39,4 +43,4 @@ MyApp.propTypes = {
pageProps: PropTypes.object.isRequired
};
export default MyApp;
export default MyApp;

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
@@ -33,7 +34,7 @@ export default class MyDocument extends Document<DocumentProps> {
</Head>
) : null}
<body>
<Main />
<Main/>
<NextScript />
</body>
</Html>
@@ -43,17 +44,18 @@ export default class MyDocument extends Document<DocumentProps> {
MyDocument.getInitialProps = async ctx => {
const sheets = new ServerStyleSheets();
const config = Configuration.readConfig();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheets.collect(<App {...props} />)
enhanceApp: App => props => sheets.collect(<App {...props}/>)
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
config: Configuration.readConfig(),
config,
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement()

View File

@@ -19,7 +19,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
backdrop: {

View File

@@ -24,7 +24,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
backdrop: {
@@ -136,18 +136,18 @@ export default function Images({ config }) {
<Pagination count={chunks.length} onChange={changePage} />
</>
) : (
<Grid
container
spacing={0}
direction='column'
alignItems='center'
justify='center'
>
<Grid item xs={6} sm={12}>
<AddToPhotosIcon style={{ fontSize: 100 }} />
</Grid>
<Grid
container
spacing={0}
direction='column'
alignItems='center'
justify='center'
>
<Grid item xs={6} sm={12}>
<AddToPhotosIcon style={{ fontSize: 100 }} />
</Grid>
)}
</Grid>
)}
</Paper>
) : null}
<Popover

View File

@@ -20,7 +20,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
backdrop: {
@@ -28,7 +28,7 @@ const useStyles = makeStyles(theme => ({
color: '#fff'
},
tableBorder: {
borderColor: '#121212'
borderColor: theme.palette.type === 'dark' ? '#1f1f1f' : '#e0e0e0'
}
}));

View File

@@ -17,7 +17,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
backdrop: {

View File

@@ -32,7 +32,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
backdrop: {

View File

@@ -30,7 +30,7 @@ const useStyles = makeStyles(theme => ({
margin: '5px'
},
padding: {
border: '1px solid #1f1f1f',
border: theme.palette.type === 'dark' ? '1px solid #1f1f1f' : '1px solid #e0e0e0',
padding: '10px'
},
field: {
@@ -219,7 +219,7 @@ export default function Users() {
}
title={`${u.username} (${u.id})`}
subheader={`${u.administrator ? 'Administrator' : 'User'
}`}
}`}
/>
</Card>
</Grid>

View File

@@ -6,6 +6,7 @@ export const LOGOUT = 'LOGOUT';
export const UPDATE_USER = 'UPDATE_USER';
export const STOP_LOADING = 'STOP_LOADING';
export const START_LOADING = 'START_LOADING';
export const SET_THEME = 'SET_THEME';
export interface State {
loggedIn: boolean;