add dark mode with toggle and system preference
This commit is contained in:
parent
fcc04982b1
commit
48f1b745fe
|
@ -1,9 +1,11 @@
|
||||||
import { doesExist } from '@apextoaster/js-utils';
|
import { doesExist, mustExist } from '@apextoaster/js-utils';
|
||||||
import { TabContext, TabList, TabPanel } from '@mui/lab';
|
import { TabContext, TabList, TabPanel } from '@mui/lab';
|
||||||
import { Box, Container, Divider, Tab } from '@mui/material';
|
import { Box, Container, Divider, PaletteMode, Tab, useMediaQuery, CssBaseline } from '@mui/material';
|
||||||
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useHash } from 'react-use/lib/useHash';
|
import { useHash } from 'react-use/lib/useHash';
|
||||||
|
|
||||||
|
import { useStore } from 'zustand';
|
||||||
import { ModelControl } from './control/ModelControl.js';
|
import { ModelControl } from './control/ModelControl.js';
|
||||||
import { ImageHistory } from './ImageHistory.js';
|
import { ImageHistory } from './ImageHistory.js';
|
||||||
import { Logo } from './Logo.js';
|
import { Logo } from './Logo.js';
|
||||||
|
@ -14,11 +16,45 @@ import { Settings } from './tab/Settings.js';
|
||||||
import { Txt2Img } from './tab/Txt2Img.js';
|
import { Txt2Img } from './tab/Txt2Img.js';
|
||||||
import { Upscale } from './tab/Upscale.js';
|
import { Upscale } from './tab/Upscale.js';
|
||||||
import { getTab, TAB_LABELS } from './utils.js';
|
import { getTab, TAB_LABELS } from './utils.js';
|
||||||
|
import { StateContext } from '../state.js';
|
||||||
|
|
||||||
export function OnnxWeb() {
|
export function OnnxWeb() {
|
||||||
|
/* checks for system light/dark mode preference */
|
||||||
|
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
|
||||||
|
const state = useStore(mustExist(React.useContext(StateContext)));
|
||||||
|
|
||||||
|
const theme = React.useMemo(
|
||||||
|
() => {
|
||||||
|
if (state.theme === '') {
|
||||||
|
if (prefersDarkMode) {
|
||||||
|
return createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'dark'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'light'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: state.theme as PaletteMode
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[prefersDarkMode, state.theme],
|
||||||
|
);
|
||||||
|
|
||||||
const [hash, setHash] = useHash();
|
const [hash, setHash] = useHash();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<CssBaseline />
|
||||||
<Container>
|
<Container>
|
||||||
<Box sx={{ my: 4 }}>
|
<Box sx={{ my: 4 }}>
|
||||||
<Logo />
|
<Logo />
|
||||||
|
@ -34,29 +70,15 @@ export function OnnxWeb() {
|
||||||
{TAB_LABELS.map((name) => <Tab key={name} label={name} value={name} />)}
|
{TAB_LABELS.map((name) => <Tab key={name} label={name} value={name} />)}
|
||||||
</TabList>
|
</TabList>
|
||||||
</Box>
|
</Box>
|
||||||
<TabPanel value='txt2img'>
|
<Box sx={{ mx: 4, my: 4 }}>
|
||||||
<Txt2Img />
|
<ModelControl />
|
||||||
</TabPanel>
|
</Box>
|
||||||
<TabPanel value='img2img'>
|
|
||||||
<Img2Img />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value='inpaint'>
|
|
||||||
<Inpaint />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value='upscale'>
|
|
||||||
<Upscale />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value='blend'>
|
|
||||||
<Blend />
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value='settings'>
|
|
||||||
<Settings />
|
|
||||||
</TabPanel>
|
|
||||||
</TabContext>
|
</TabContext>
|
||||||
<Divider variant='middle' />
|
<Divider variant='middle' />
|
||||||
<Box sx={{ mx: 4, my: 4 }}>
|
<Box sx={{ mx: 4, my: 4 }}>
|
||||||
<ImageHistory />
|
<ImageHistory />
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import { doesExist, mustExist } from '@apextoaster/js-utils';
|
import { doesExist, mustExist } from '@apextoaster/js-utils';
|
||||||
import { Refresh } from '@mui/icons-material';
|
import { Refresh, Brightness4, Brightness7 } from '@mui/icons-material';
|
||||||
import { Alert, Button, Stack, TextField } from '@mui/material';
|
import { Alert, Button, Stack, Switch, TextField } from '@mui/material';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useContext, useState } from 'react';
|
import { useContext, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
@ -80,6 +80,13 @@ export function Settings() {
|
||||||
{t('setting.loadState')}
|
{t('setting.loadState')}
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<Switch onClick={() => {
|
||||||
|
if (state.theme === 'light') {
|
||||||
|
state.setTheme('dark');
|
||||||
|
} else {
|
||||||
|
state.setTheme('light');
|
||||||
|
}
|
||||||
|
}} />
|
||||||
<Stack direction='row' spacing={2}>
|
<Stack direction='row' spacing={2}>
|
||||||
<Button onClick={() => state.resetTxt2Img()} color='warning'>{t('setting.reset.txt2img')}</Button>
|
<Button onClick={() => state.resetTxt2Img()} color='warning'>{t('setting.reset.txt2img')}</Button>
|
||||||
<Button onClick={() => state.resetImg2Img()} color='warning'>{t('setting.reset.img2img')}</Button>
|
<Button onClick={() => state.resetImg2Img()} color='warning'>{t('setting.reset.img2img')}</Button>
|
||||||
|
|
|
@ -43,8 +43,10 @@ interface BrushSlice {
|
||||||
|
|
||||||
interface DefaultSlice {
|
interface DefaultSlice {
|
||||||
defaults: TabState<BaseImgParams>;
|
defaults: TabState<BaseImgParams>;
|
||||||
|
theme: string;
|
||||||
|
|
||||||
setDefaults(param: Partial<BaseImgParams>): void;
|
setDefaults(param: Partial<BaseImgParams>): void;
|
||||||
|
setTheme(theme: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HistorySlice {
|
interface HistorySlice {
|
||||||
|
@ -488,6 +490,7 @@ export function createStateSlices(server: ServerParams) {
|
||||||
defaults: {
|
defaults: {
|
||||||
...base,
|
...base,
|
||||||
},
|
},
|
||||||
|
theme: '',
|
||||||
setDefaults(params) {
|
setDefaults(params) {
|
||||||
set((prev) => ({
|
set((prev) => ({
|
||||||
defaults: {
|
defaults: {
|
||||||
|
@ -496,6 +499,11 @@ export function createStateSlices(server: ServerParams) {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
setTheme(theme) {
|
||||||
|
set((prev) => ({
|
||||||
|
theme,
|
||||||
|
}));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const createModelSlice: Slice<ModelSlice> = (set) => ({
|
const createModelSlice: Slice<ModelSlice> = (set) => ({
|
||||||
|
|
Loading…
Reference in New Issue