Add theme color to the settings

This commit is contained in:
Boris Proshin 2023-07-19 18:57:51 +03:00
parent e8240a7bef
commit 745b216219
6 changed files with 58 additions and 7 deletions

View file

@ -13,6 +13,7 @@ import {
import { ChatRoute } from "../routes/ChatRoute";
import { IndexRoute } from "../routes/IndexRoute";
import { Layout } from "./Layout";
import { usePrimaryColor } from "../hooks/usePrimaryColor";
const history = createHashHistory();
const location = new ReactLocation({ history });
@ -26,6 +27,8 @@ export function App() {
getInitialValueInEffect: true,
});
const [primaryColor] = usePrimaryColor();
const toggleColorScheme = (value?: ColorScheme) =>
setColorScheme(value || (colorScheme === "dark" ? "light" : "dark"));
@ -49,7 +52,7 @@ export function App() {
withCSSVariables
theme={{
colorScheme,
primaryColor: "teal",
primaryColor,
globalStyles: (theme) => ({
body: {
backgroundColor:

View file

@ -42,7 +42,7 @@ export function Chats({ search }: { search: string }) {
<Link to={`/chats/${chat.id}`} style={{ flex: 1 }}>
<MainLink
icon={<IconMessages size="1rem" />}
color="teal"
color="primary"
chat={chat}
label={chat.description}
/>

View file

@ -41,6 +41,7 @@ import { LogoText } from "./Logo";
import { Prompts } from "./Prompts";
import { SettingsModal } from "./SettingsModal";
import { config } from "../utils/config";
import { usePrimaryThemeColor } from "../hooks/usePrimaryColor";
declare global {
interface Window {
@ -67,6 +68,8 @@ export function Layout() {
theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]
}`;
const primaryColor = usePrimaryThemeColor();
useEffect(() => {
setOpened(false);
}, [router.state.location]);
@ -95,7 +98,7 @@ export function Layout() {
<LogoText
style={{
height: 22,
color: "#27B882",
color: primaryColor[6],
display: "block",
}}
/>

View file

@ -1,3 +1,5 @@
import { usePrimaryThemeColor } from '../hooks/usePrimaryColor'
export function LogoText(props: JSX.IntrinsicElements["svg"]) {
return (
<svg
@ -15,6 +17,8 @@ export function LogoText(props: JSX.IntrinsicElements["svg"]) {
}
export function Logo(props: JSX.IntrinsicElements["svg"]) {
const primaryColor = usePrimaryThemeColor();
return (
<svg
fill="none"
@ -41,8 +45,8 @@ export function Logo(props: JSX.IntrinsicElements["svg"]) {
y2={116.46}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#41E094" />
<stop offset={1} stopColor="#27B882" />
<stop stopColor={primaryColor[5]} />
<stop offset={1} stopColor={primaryColor[6]} />
</linearGradient>
</defs>
</svg>
@ -50,6 +54,8 @@ export function Logo(props: JSX.IntrinsicElements["svg"]) {
}
export function LogoIcon(props: JSX.IntrinsicElements["svg"]) {
const primaryColor = usePrimaryThemeColor();
return (
<svg
fill="none"
@ -72,8 +78,8 @@ export function LogoIcon(props: JSX.IntrinsicElements["svg"]) {
y2={116.46}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#41E094" />
<stop offset={1} stopColor="#27B882" />
<stop stopColor={primaryColor[5]} />
<stop offset={1} stopColor={primaryColor[6]} />
</linearGradient>
</defs>
</svg>

View file

@ -10,6 +10,11 @@ import {
Select,
Stack,
Text,
useMantineTheme,
Group,
ColorSwatch,
CheckIcon,
rem,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
@ -18,6 +23,7 @@ import { cloneElement, ReactElement, useEffect, useState } from "react";
import { db } from "../db";
import { config } from "../utils/config";
import { checkOpenAIKey } from "../utils/openai";
import { usePrimaryColor } from "../hooks/usePrimaryColor";
export function SettingsModal({ children }: { children: ReactElement }) {
const [opened, { open, close }] = useDisclosure(false);
@ -29,6 +35,9 @@ export function SettingsModal({ children }: { children: ReactElement }) {
const [auth, setAuth] = useState(config.defaultAuth);
const [base, setBase] = useState("");
const [version, setVersion] = useState("");
const [primaryColor, setPrimaryColor] = usePrimaryColor();
const theme = useMantineTheme();
const settings = useLiveQuery(async () => {
return db.settings.where({ id: "general" }).first();
@ -335,6 +344,21 @@ export function SettingsModal({ children }: { children: ReactElement }) {
</Button>
</Flex>
</form>
<Stack spacing="xs">
<Text children="Theme color" />
<Group spacing="xs">
{["red", "pink", "grape", "violet", "indigo", "blue", "cyan", "green", "lime", "yellow", "orange", "teal"].map((color) => (
<ColorSwatch
component="button"
color={theme.colors[color][6]}
onClick={() => setPrimaryColor(color)}
sx={{ color: "#fff", cursor: "pointer" }}
>
{color === primaryColor && <CheckIcon width={rem(10)} />}
</ColorSwatch>
))}
</Group>
</Stack>
</Stack>
</Modal>
</>

View file

@ -0,0 +1,15 @@
import { useMantineTheme } from '@mantine/core'
import { useLocalStorage } from '@mantine/hooks'
export function usePrimaryColor() {
return useLocalStorage<string>({
key: "mantine-primary-color",
defaultValue: "teal",
})
}
export function usePrimaryThemeColor() {
const [primaryColor] = usePrimaryColor()
const theme = useMantineTheme()
return theme.colors[primaryColor]
}