From dd59568f1a016b188fb9165a3091e206490f3d6f Mon Sep 17 00:00:00 2001 From: Boris Proshin Date: Thu, 20 Jul 2023 15:27:53 +0300 Subject: [PATCH 1/2] Move theme selection to the settings --- src/components/App.tsx | 6 +++--- src/components/Layout.tsx | 19 ----------------- src/components/SettingsModal.tsx | 35 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index e46d0ab..18d10ec 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -3,7 +3,7 @@ import { ColorSchemeProvider, MantineProvider, } from "@mantine/core"; -import { useHotkeys, useLocalStorage } from "@mantine/hooks"; +import { useColorScheme, useHotkeys, useLocalStorage } from "@mantine/hooks"; import { Notifications } from "@mantine/notifications"; import { createHashHistory, @@ -18,11 +18,11 @@ const history = createHashHistory(); const location = new ReactLocation({ history }); export function App() { - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + const preferredColorScheme = useColorScheme(); const [colorScheme, setColorScheme] = useLocalStorage({ key: "mantine-color-scheme", - defaultValue: prefersDark ? "dark" : "light", + defaultValue: preferredColorScheme, getInitialValueInEffect: true, }); diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 3c39330..7be0f2d 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -21,11 +21,9 @@ import { IconBrandTwitter, IconDatabase, IconMessage, - IconMoonStars, IconPlus, IconSearch, IconSettings, - IconSunHigh, IconX, } from "@tabler/icons-react"; import { Link, Outlet, useNavigate, useRouter } from "@tanstack/react-location"; @@ -187,23 +185,6 @@ export function Layout() {
- {config.allowDarkModeToggle && ( - - toggleColorScheme()} - > - {colorScheme === "dark" ? ( - - ) : ( - - )} - - - )} {config.allowSettingsModal && ( diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx index 824263c..489069d 100644 --- a/src/components/SettingsModal.tsx +++ b/src/components/SettingsModal.tsx @@ -10,6 +10,8 @@ import { Select, Stack, Text, + Tabs, + useMantineColorScheme, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; @@ -18,6 +20,11 @@ import { cloneElement, ReactElement, useEffect, useState } from "react"; import { db } from "../db"; import { config } from "../utils/config"; import { checkOpenAIKey } from "../utils/openai"; +import { + IconBrightnessHalf, + IconMoonStars, + IconSunHigh, +} from "@tabler/icons-react"; export function SettingsModal({ children }: { children: ReactElement }) { const [opened, { open, close }] = useDisclosure(false); @@ -29,6 +36,7 @@ export function SettingsModal({ children }: { children: ReactElement }) { const [auth, setAuth] = useState(config.defaultAuth); const [base, setBase] = useState(""); const [version, setVersion] = useState(""); + const { colorScheme, toggleColorScheme } = useMantineColorScheme(); const settings = useLiveQuery(async () => { return db.settings.where({ id: "general" }).first(); @@ -335,6 +343,33 @@ export function SettingsModal({ children }: { children: ReactElement }) { + {config.allowDarkModeToggle && ( + + + + + } + children="Light Mode" + onClick={() => toggleColorScheme()} + /> + } + children="Dark Mode" + onClick={() => toggleColorScheme()} + /> + } + children="System theme" + onClick={() => toggleColorScheme()} + /> + + + + )} From b22b42b84d4e6cf43002e3777a690e2d7a732a05 Mon Sep 17 00:00:00 2001 From: Boris Proshin Date: Sun, 23 Jul 2023 19:26:20 +0300 Subject: [PATCH 2/2] Setup theme logic --- src/components/SettingsModal.tsx | 67 ++++++++++++++++++++++++++++---- src/db/index.ts | 5 +++ src/static/config.json | 3 +- src/utils/config.ts | 7 +++- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx index 489069d..6e293ee 100644 --- a/src/components/SettingsModal.tsx +++ b/src/components/SettingsModal.tsx @@ -13,11 +13,11 @@ import { Tabs, useMantineColorScheme, } from "@mantine/core"; -import { useDisclosure } from "@mantine/hooks"; +import { useColorScheme, 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 { ColorTheme, db } from "../db"; import { config } from "../utils/config"; import { checkOpenAIKey } from "../utils/openai"; import { @@ -36,7 +36,22 @@ export function SettingsModal({ children }: { children: ReactElement }) { const [auth, setAuth] = useState(config.defaultAuth); const [base, setBase] = useState(""); const [version, setVersion] = useState(""); - const { colorScheme, toggleColorScheme } = useMantineColorScheme(); + const [selectedTheme, setSelectedTheme] = useState("system"); + const { toggleColorScheme } = useMantineColorScheme(); + + const preferredColorScheme = useColorScheme(); + + useEffect(() => { + if (selectedTheme === "system") { + toggleColorScheme(preferredColorScheme); + } + }, [preferredColorScheme]); + + useEffect(() => { + toggleColorScheme( + selectedTheme === "system" ? preferredColorScheme : selectedTheme + ); + }, [selectedTheme]); const settings = useLiveQuery(async () => { return db.settings.where({ id: "general" }).first(); @@ -61,8 +76,44 @@ export function SettingsModal({ children }: { children: ReactElement }) { if (settings?.openAiApiVersion) { setVersion(settings.openAiApiVersion); } + if (settings?.theme) { + setSelectedTheme(settings.theme); + } }, [settings]); + const onThemeChange = async (colorTheme: ColorTheme) => { + try { + setSubmitting(true); + await db.settings.where({ id: "general" }).modify((row) => { + row.theme = colorTheme; + console.log(row); + }); + setSelectedTheme(colorTheme); + notifications.show({ + title: "Saved", + message: "Your theme has been saved.", + }); + } catch (error: any) { + if (error.toJSON().message === "Network Error") { + notifications.show({ + title: "Error", + color: "red", + message: "No internet connection.", + }); + } + const message = error.response?.data?.error?.message; + if (message) { + notifications.show({ + title: "Error", + color: "red", + message, + }); + } + } finally { + setSubmitting(false); + } + }; + return ( <> {cloneElement(children, { onClick: open })} @@ -343,28 +394,28 @@ export function SettingsModal({ children }: { children: ReactElement }) { - {config.allowDarkModeToggle && ( + {config.allowThemeToggle && ( - + } children="Light Mode" - onClick={() => toggleColorScheme()} + onClick={() => onThemeChange("light")} /> } children="Dark Mode" - onClick={() => toggleColorScheme()} + onClick={() => onThemeChange("dark")} /> } children="System theme" - onClick={() => toggleColorScheme()} + onClick={() => onThemeChange("system")} /> diff --git a/src/db/index.ts b/src/db/index.ts index f4f1288..2088168 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -1,7 +1,10 @@ import Dexie, { Table } from "dexie"; import "dexie-export-import"; +import { ColorScheme } from "@mantine/core"; import { config } from "../utils/config"; +export type ColorTheme = ColorScheme | "system"; + export interface Chat { id: string; description: string; @@ -32,6 +35,7 @@ export interface Settings { openAiApiAuth?: 'none' | 'bearer-token' | 'api-key'; openAiApiBase?: string; openAiApiVersion?: string; + theme?: ColorTheme; } export class Database extends Dexie { @@ -58,6 +62,7 @@ export class Database extends Dexie { ...(config.defaultKey != '' && { openAiApiKey: config.defaultKey }), ...(config.defaultBase != '' && { openAiApiBase: config.defaultBase }), ...(config.defaultVersion != '' && { openAiApiVersion: config.defaultVersion }), + theme: config.defaultTheme, }); }); } diff --git a/src/static/config.json b/src/static/config.json index 4671086..024b284 100644 --- a/src/static/config.json +++ b/src/static/config.json @@ -5,6 +5,7 @@ "defaultBase": "", "defaultVersion": "", "defaultKey": "", + "defaultTheme": "system", "availableModels": [ { "value": "gpt-3.5-turbo", @@ -219,7 +220,7 @@ } ], "showDownloadLink": true, - "allowDarkModeToggle": true, + "allowThemeToggle": true, "allowSettingsModal": true, "allowDatabaseModal": true, "showTwitterLink": true, diff --git a/src/utils/config.ts b/src/utils/config.ts index e629936..955be6b 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,17 +1,20 @@ +import { ColorTheme } from '../db' + interface Config { defaultModel: AvailableModel["value"]; defaultType: 'openai' | 'custom'; defaultAuth: 'none' | 'bearer-token' | 'api-key'; defaultBase: string; defaultVersion: string; - defaultKey: string; + defaultKey: string; + defaultTheme: ColorTheme; availableModels: AvailableModel[]; writingCharacters: WritingCharacter[]; writingTones: string[]; writingStyles: string[]; writingFormats: WritingFormat[]; showDownloadLink: boolean; - allowDarkModeToggle: boolean; + allowThemeToggle: boolean; allowSettingsModal: boolean; allowDatabaseModal: boolean; showTwitterLink: boolean;