mirror of
https://github.com/diced/zipline.git
synced 2026-01-05 09:18:24 -08:00
light theme, if you want to kill your eyes.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zipline-next",
|
||||
"version": "2.1.2",
|
||||
"version": "2.2.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@dicedtomato/colors": "^1.0.3",
|
||||
|
||||
@@ -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} />
|
||||
|
||||
15
src/components/ZiplineTheming.tsx
Normal file
15
src/components/ZiplineTheming.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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.');
|
||||
|
||||
@@ -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
38
src/lib/themes/light.ts
Normal 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;
|
||||
@@ -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;
|
||||
@@ -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()
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user