This commit is contained in:
Boris Proshin 2024-06-13 09:02:33 +03:00 committed by GitHub
commit 675c5b0196
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 66 additions and 26 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

@ -14,8 +14,11 @@ import { DeleteChatModal } from "./DeleteChatModal";
import { EditChatModal } from "./EditChatModal";
import { MainLink } from "./MainLink";
import { notifications } from "@mantine/notifications";
import { usePrimaryColor } from "../hooks/usePrimaryColor";
export function ChatItem({ chat, isActive }: { chat: Chat, isActive: boolean }) {
const [primaryColor] = usePrimaryColor();
const toggleChatPin = async (chatId: string, event: React.UIEvent) => {
try {
event.preventDefault();
@ -55,7 +58,7 @@ export function ChatItem({ chat, isActive }: { chat: Chat, isActive: boolean })
<Link to={`/chats/${chat.id}`} style={{ flex: 1 }}>
<MainLink
icon={chat.pinned ? <IconPinned size="1rem" /> : <IconMessages size="1rem" />}
color="teal"
color={primaryColor}
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

@ -1,23 +1,15 @@
import { useLiveQuery } from 'dexie-react-hooks'
import { cloneElement, ReactElement, useEffect, useState } from 'react'
import {
Alert,
Anchor,
Button,
Flex,
List,
Modal,
PasswordInput,
TextInput,
Select,
Stack,
Text,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { useLiveQuery } from "dexie-react-hooks";
import { cloneElement, ReactElement, useEffect, useState } from "react";
import { db } from "../db";
import { config } from "../utils/config";
import { checkOpenAIKey } from "../utils/openai";
Alert, Anchor, Button, CheckIcon, ColorSwatch, Flex, Group, List, Modal, PasswordInput, rem,
Select, Stack, Text, TextInput, useMantineTheme
} from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import { db } from '../db'
import { usePrimaryColor } from '../hooks/usePrimaryColor'
import { config } from '../utils/config'
import { checkOpenAIKey } from '../utils/openai'
export function SettingsModal({ children }: { children: ReactElement }) {
const [opened, { open, close }] = useDisclosure(false);
@ -29,6 +21,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 +330,21 @@ export function SettingsModal({ children }: { children: ReactElement }) {
</Button>
</Flex>
</form>
<Stack spacing="xs">
<Text children="Theme color" />
<Group spacing="xs">
{["dark", "gray", "red", "pink", "grape", "violet", "indigo", "blue", "cyan", "teal", "green", "lime", "yellow", "orange"].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]
}