feat: update packages, experimental light mode

This commit is contained in:
Ash Keel 2023-10-28 13:24:26 +02:00
parent b27e5cde71
commit 7941e0699d
No known key found for this signature in database
GPG Key ID: 53A9E9A6035DD109
20 changed files with 3912 additions and 2322 deletions

View File

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>strimertül control panel</title>
</head>
<body class="dark-theme">
<body>
<div id="main"></div>
<script src="./src/index.tsx" type="module"></script>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -3,43 +3,42 @@
"version": "1.0.0",
"type": "module",
"dependencies": {
"@fontsource/space-mono": "^4.5.12",
"@monaco-editor/react": "^4.5.0",
"@radix-ui/colors": "^0.1.8",
"@radix-ui/react-alert-dialog": "^1.0.3",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.3",
"@radix-ui/react-hover-card": "^1.0.5",
"@fontsource/space-mono": "^5.0.17",
"@monaco-editor/react": "^4.6.0",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.1",
"@radix-ui/react-radio-group": "^1.1.2",
"@radix-ui/react-scroll-area": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.3",
"@radix-ui/react-toggle": "^1.0.2",
"@radix-ui/react-toggle-group": "^1.0.3",
"@radix-ui/react-toolbar": "^1.0.3",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-toolbar": "^1.0.4",
"@redux-devtools/extension": "^3.2.5",
"@reduxjs/toolkit": "^1.9.5",
"@reduxjs/toolkit": "^1.9.7",
"@stitches/react": "^1.2.8",
"@strimertul/kilovolt-client": "^8.0.0",
"@types/node": "^18.16.3",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@vitejs/plugin-react": "^4.0.0",
"i18next": "^22.4.15",
"@types/node": "^20.8.9",
"@types/react": "^18.2.33",
"@types/react-dom": "^18.2.14",
"@vitejs/plugin-react": "^4.1.0",
"i18next": "^23.6.0",
"inter-ui": "^3.19.3",
"normalize.css": "^8.0.1",
"postcss-import": "^15.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^12.2.2",
"react-redux": "^8.0.5",
"react-router-dom": "^6.11.0",
"react-i18next": "^13.3.1",
"react-redux": "^8.1.3",
"react-router-dom": "^6.17.0",
"redux-thunk": "^2.4.2",
"sass": "^1.62.1",
"typescript": "^5.0.4",
"vite": "^4.3.4",
"vite-tsconfig-paths": "^4.2.0"
"typescript": "^5.2.2",
"vite": "^4.5.0",
"vite-tsconfig-paths": "^4.2.1"
},
"scripts": {
"start": "vite",
@ -50,16 +49,16 @@
"last 2 Chrome version"
],
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"eslint": "^8.39.0",
"@typescript-eslint/eslint-plugin": "^6.9.0",
"@typescript-eslint/parser": "^6.9.0",
"eslint": "^8.52.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react-refresh": "^0.4.1",
"prettier": "^2.8.8",
"rimraf": "^5.0.0"
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-react-refresh": "^0.4.3",
"prettier": "^3.0.3",
"rimraf": "^5.0.5"
}
}

View File

@ -1 +1 @@
b9df5eb6f4841737d2fcd1301b0eb45f
fc1fa70c3a8ac4cc66b38592b8aaab6b

View File

@ -314,7 +314,12 @@
"title": "User interface settings",
"language": "Language",
"repeat-onboarding": "Repeat onboarding",
"partial-translation": "Partial translation"
"partial-translation": "Partial translation",
"themes": {
"dark": "Dark",
"light": "Light"
},
"theme": "Theme"
},
"extensions": {
"title": "Extensions",

View File

@ -366,8 +366,13 @@
"uiconfig": {
"language": "Lingua",
"partial-translation": "Traduzione parziale",
"repeat-onboarding": "Ripeti procedura iniziale",
"title": "Impostazioni interfaccia utente"
"repeat-onboarding": "Ripeti procudura di configurazione",
"title": "Impostazioni interfaccia utente",
"theme": "Tema",
"themes": {
"dark": "Scuro",
"light": "Chiaro"
}
},
"extensions": {
"create": "Crea nuovo",

View File

@ -416,7 +416,7 @@ export const useAuthBypass = createAsyncThunk<void, void, ThunkConfig>(
const { api } = getState();
const response = await api.client.send({ command: '_uid' });
if ('ok' in response && response.ok && 'data' in response) {
const uid = response.data;
const uid = response.data as string;
await AuthenticateKVClient(uid.toString());
dispatch(
apiReducer.actions.connectionStatusChanged(ConnectionStatus.Connected),

View File

@ -150,6 +150,7 @@ export interface UISettings {
onboardingStatus: number;
onboardingDone: boolean;
language: string;
theme: string;
}
export enum ConnectionStatus {

View File

@ -45,7 +45,7 @@ import StrimertulPage from './pages/Strimertul';
import TwitchSettingsPage from './pages/TwitchSettings';
import UISettingsPage from './pages/UISettingsPage';
import ExtensionsPage from './pages/Extensions';
import { styled } from './theme';
import { getTheme, lightMode, styled } from './theme';
import Loading from './components/Loading';
import InteractiveAuthDialog from './components/InteractiveAuthDialog';
@ -133,6 +133,8 @@ const Container = styled('div', {
flexDirection: 'row',
overflow: 'hidden',
height: '100vh',
backgroundColor: '$gray1',
color: '$gray12',
});
const PageContent = styled('main', {
@ -234,8 +236,10 @@ export default function App(): JSX.Element {
const showSidebar = location.pathname !== '/setup';
const theme = getTheme(uiConfig?.theme ?? 'dark');
return (
<Container>
<Container id="app-container" className={theme}>
<InteractiveAuthDialog />
<LogViewer />
{showSidebar ? <Sidebar sections={sections} /> : null}

View File

@ -22,7 +22,9 @@ function DialogContent({
closeButton,
}: React.PropsWithChildren<DialogProps>) {
return (
<DialogPrimitive.Portal>
<DialogPrimitive.Portal
container={document.getElementById('app-container')}
>
<DialogOverlay />
<DialogContainer>
{title && (

View File

@ -118,7 +118,7 @@ export default function InteractiveAuthDialog() {
{requests.map(({ uid, info, callbackID }) => (
<Dialog open={true} key={uid}>
<DialogContent title={t('pages.interactive-auth.title')}>
<DialogDescription css={{ color: '$teal12' }}>
<DialogDescription css={{ color: '$gray12' }}>
<TextBlock>{t('pages.interactive-auth.desc-1')}</TextBlock>
<TextBlock css={{ fontWeight: 'bold', color: '$red11' }}>
{t('pages.interactive-auth.warn-1')}

View File

@ -7,7 +7,7 @@ import { Link, useMatch, useResolvedPath } from 'react-router-dom';
import logo from '~/assets/icon-logo.svg';
import { useAppSelector } from '~/store';
import { APPNAME, APPREPO } from '../theme';
import { APPNAME, APPREPO, lightMode } from '../theme';
import BrowserLink from './BrowserLink';
import Scrollbar from './utils/Scrollbar';
@ -27,9 +27,13 @@ interface SidebarProps {
}
const Container = styled('section', {
background: '$gray1',
background: '$gray2',
maxWidth: '220px',
borderRight: '1px solid $gray6',
[`.${lightMode} &`]: {
background: '$gray2',
},
});
const Header = styled('div', {
@ -53,9 +57,9 @@ const AppLink = styled(Link, {
userSelect: 'none',
all: 'unset',
cursor: 'pointer',
color: '$teal12',
color: '$gray12',
'&:visited': {
color: '$teal12',
color: '$gray12',
},
display: 'flex',
flexDirection: 'column',
@ -121,6 +125,9 @@ const MenuLink = styled(Link, {
padding: '0.6rem 1.6rem 0.6rem 1rem',
fontSize: '0.9rem',
fontWeight: '300',
[`.${lightMode} &`]: {
fontWeight: '400',
},
variants: {
status: {
selected: {
@ -130,7 +137,7 @@ const MenuLink = styled(Link, {
clickable: {
cursor: 'pointer',
'&:hover': {
backgroundColor: '$teal4',
backgroundColor: '$gray3',
},
},
},

View File

@ -5,7 +5,7 @@ import {
Indicator,
RadioGroupProps as RootProps,
} from '@radix-ui/react-radio-group';
import { styled } from '~/ui/theme';
import { lightMode, styled } from '~/ui/theme';
export interface RadioGroupProps {
values: {
@ -37,10 +37,19 @@ const RadioItem = styled(Item, {
'&:hover': {
backgroundColor: '$teal12',
[`.${lightMode} &`]: {
backgroundColor: '$teal3',
},
},
'&:focus': {
boxShadow: '0 0 0 2px $gray2',
},
[`.${lightMode} &`]: {
backgroundColor: '$gray2',
border: '2px solid $gray12',
},
});
const RadioIndicator = styled(Indicator, {

View File

@ -32,7 +32,7 @@ import { Alert, AlertTrigger } from '../theme/alert';
const TimerList = styled('div', { marginTop: '1rem' });
const TimerItemContainer = styled('article', {
backgroundColor: '$gray2',
backgroundColor: '$gray3',
margin: '0.5rem 0',
padding: '0.5rem',
borderLeft: '5px solid $teal8',

View File

@ -66,7 +66,7 @@ const RewardHeader = styled('header', {
marginBottom: '0.4rem',
});
const RewardName = styled('span', {
color: '$teal12',
color: '$gray12',
flex: 1,
fontWeight: 'bold',
variants: {

View File

@ -178,7 +178,7 @@ const StepName = styled('div', {
variants: {
status: {
active: {
color: '$teal12',
color: '$gray12',
display: 'inherit',
},
},

View File

@ -35,7 +35,7 @@ export default function UISettingsPage(): React.ReactElement {
<PageTitle>{t('pages.uiconfig.title')}</PageTitle>
</PageHeader>
<Field size="fullWidth">
<Label htmlFor="bind">{t('pages.uiconfig.language')}</Label>
<Label>{t('pages.uiconfig.language')}</Label>
<RadioGroup
aria-label={t('pages.uiconfig.language')}
defaultValue={i18n.resolvedLanguage}
@ -60,6 +60,21 @@ export default function UISettingsPage(): React.ReactElement {
}))}
/>
</Field>
<Field size="fullWidth">
<Label>{t('pages.uiconfig.theme')}</Label>
<RadioGroup
aria-label={t('pages.uiconfig.theme')}
defaultValue="dark"
value={uiConfig?.theme ?? 'dark'}
onValueChange={(value) => {
void dispatch(setUiConfig({ ...uiConfig, theme: value }));
}}
values={['dark', 'light'].map((theme) => ({
id: theme,
label: t(`pages.uiconfig.themes.${theme}`),
}))}
/>
</Field>
<Button
type="button"
onClick={() => {

View File

@ -56,7 +56,7 @@ export const AlertContainer = styled(AlertDialogPrimitive.Content, {
export const AlertTitle = styled(AlertDialogPrimitive.Title, {
fontWeight: 'bold',
color: '$teal12',
color: '$gray12',
fontSize: '15pt',
borderBottom: '1px solid $teal6',
margin: '-1rem',
@ -75,7 +75,7 @@ export const AlertTitle = styled(AlertDialogPrimitive.Title, {
export const AlertDescription = styled(AlertDialogPrimitive.Description, {
margin: '10px 0 20px',
color: '$teal12',
color: '$gray12',
fontSize: 15,
lineHeight: 1.5,
variants: {

View File

@ -1,6 +1,6 @@
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { keyframes } from '@stitches/react';
import { styled } from './theme';
import { lightMode, styled } from './theme';
export const Dialog = DialogPrimitive.Root;
export const DialogTrigger = DialogPrimitive.Trigger;
@ -28,6 +28,10 @@ export const DialogOverlay = styled(DialogPrimitive.Overlay, {
'@media (prefers-reduced-motion: no-preference)': {
animation: `${overlayShow()} 150ms cubic-bezier(0.16, 1, 0.3, 1)`,
},
[`.${lightMode} &`]: {
backgroundColor: '$blackA8',
},
});
const dialogPadding = '50px';
@ -76,7 +80,7 @@ export const DialogContainer = styled(DialogPrimitive.Content, {
export const DialogTitle = styled(DialogPrimitive.Title, {
fontWeight: 'bold',
color: '$teal12',
color: '$gray12',
fontSize: '15pt',
borderBottom: '1px solid $teal6',
margin: '-1rem',

View File

@ -1,18 +1,24 @@
import {
grayDark,
tealDark,
yellowDark,
grassDark,
redDark,
crimsonDark,
amberDark,
blackA,
crimson,
crimsonDark,
grass,
grassDark,
gray,
grayDark,
red,
redDark,
teal,
tealDark,
yellow,
yellowDark,
} from '@radix-ui/colors';
import { globalCss, createStitches } from '@stitches/react';
import { createStitches, createTheme, globalCss } from '@stitches/react';
export const globalStyles = globalCss({
'*': { boxSizing: 'border-box' },
body: { margin: 0, padding: 0, backgroundColor: '$gray1', color: '$teal12' },
body: { margin: 0, padding: 0, backgroundColor: '$gray1', color: '$gray12' },
html: {
margin: 0,
padding: 0,
@ -56,3 +62,25 @@ export const { styled, theme } = createStitches({
wide: '(min-width: 1024px)',
},
});
export const lightMode = createTheme({
colors: {
...gray,
...teal,
...yellow,
...grass,
...red,
...crimson,
...amberDark,
...blackA,
},
});
export function getTheme(themeName: string) {
switch (themeName) {
case 'light':
return lightMode;
default:
return undefined;
}
}