mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-07-31 19:25:43 +08:00
feat: add dark mode switch in sidebar
This commit is contained in:
@ -9,6 +9,7 @@ import Tooltip from "./kit/Tooltip";
|
|||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
import EngineIcon from "./EngineIcon";
|
import EngineIcon from "./EngineIcon";
|
||||||
import LocaleSwitch from "./LocaleSwitch";
|
import LocaleSwitch from "./LocaleSwitch";
|
||||||
|
import DarkModeSwitch from "./DarkModeSwitch";
|
||||||
import CreateConnectionModal from "./CreateConnectionModal";
|
import CreateConnectionModal from "./CreateConnectionModal";
|
||||||
import SettingModal from "./SettingModal";
|
import SettingModal from "./SettingModal";
|
||||||
import EditConversationTitleModal from "./EditConversationTitleModal";
|
import EditConversationTitleModal from "./EditConversationTitleModal";
|
||||||
@ -202,6 +203,7 @@ const ConnectionSidebar = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-end items-center">
|
<div className="w-full flex flex-col justify-end items-center">
|
||||||
|
<DarkModeSwitch />
|
||||||
<LocaleSwitch />
|
<LocaleSwitch />
|
||||||
<Tooltip title={t("common.setting")} side="right">
|
<Tooltip title={t("common.setting")} side="right">
|
||||||
<button
|
<button
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useConversationStore, useLayoutStore } from "@/store";
|
import { useConversationStore, useLayoutStore } from "@/store";
|
||||||
|
import useDarkMode from "@/hooks/useDarkmode";
|
||||||
import Icon from "../Icon";
|
import Icon from "../Icon";
|
||||||
import GitHubStarBadge from "../GitHubStarBadge";
|
import GitHubStarBadge from "../GitHubStarBadge";
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ const Header = (props: Props) => {
|
|||||||
const { className } = props;
|
const { className } = props;
|
||||||
const layoutStore = useLayoutStore();
|
const layoutStore = useLayoutStore();
|
||||||
const conversationStore = useConversationStore();
|
const conversationStore = useConversationStore();
|
||||||
|
const isDarkMode = useDarkMode();
|
||||||
const currentConversation = conversationStore.currentConversation;
|
const currentConversation = conversationStore.currentConversation;
|
||||||
const title = currentConversation?.title || "SQL Chat";
|
const title = currentConversation?.title || "SQL Chat";
|
||||||
|
|
||||||
@ -41,7 +43,7 @@ const Header = (props: Props) => {
|
|||||||
className="flex flex-row justify-center items-center h-10 px-3 py-1 rounded-md whitespace-nowrap hover:bg-gray-100 dark:hover:bg-zinc-700"
|
className="flex flex-row justify-center items-center h-10 px-3 py-1 rounded-md whitespace-nowrap hover:bg-gray-100 dark:hover:bg-zinc-700"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<img className="h-5 sm:h-6 w-auto" src="/craft-by-bytebase.webp" alt="" />
|
<img className="h-5 sm:h-6 w-auto" src={isDarkMode ? "/craft-by-bytebase-dark-mode.webp" : "/craft-by-bytebase.webp"} alt="" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
29
src/components/DarkModeSwitch.tsx
Normal file
29
src/components/DarkModeSwitch.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { useSettingStore } from "@/store";
|
||||||
|
import useDarkMode from "@/hooks/useDarkmode";
|
||||||
|
import Icon from "./Icon";
|
||||||
|
|
||||||
|
const DarkModeSwitch = () => {
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const isDarkMode = useDarkMode();
|
||||||
|
|
||||||
|
const switchDarkMode = () => {
|
||||||
|
if (isDarkMode) {
|
||||||
|
settingStore.setTheme("light");
|
||||||
|
} else {
|
||||||
|
settingStore.setTheme("dark");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModeIcon = isDarkMode ? Icon.IoMdMoon : Icon.IoMdSunny;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="w-10 h-10 p-1 rounded-full flex flex-row justify-center items-center hover:bg-gray-100 dark:hover:bg-zinc-700"
|
||||||
|
onClick={switchDarkMode}
|
||||||
|
>
|
||||||
|
<ModeIcon className="text-gray-600 dark:text-gray-300 w-6 h-auto" />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DarkModeSwitch;
|
@ -1,6 +1,7 @@
|
|||||||
import { useConversationStore, useConnectionStore, useMessageStore, useUserStore } from "@/store";
|
import { useConversationStore, useConnectionStore, useMessageStore, useUserStore } from "@/store";
|
||||||
import { CreatorRole } from "@/types";
|
import { CreatorRole } from "@/types";
|
||||||
import { generateUUID } from "@/utils";
|
import { generateUUID } from "@/utils";
|
||||||
|
import useDarkMode from "@/hooks/useDarkmode";
|
||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
|
|
||||||
// examples are used to show some examples to the user.
|
// examples are used to show some examples to the user.
|
||||||
@ -17,6 +18,7 @@ const EmptyView = (props: Props) => {
|
|||||||
const conversationStore = useConversationStore();
|
const conversationStore = useConversationStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const messageStore = useMessageStore();
|
const messageStore = useMessageStore();
|
||||||
|
const isDarkMode = useDarkMode();
|
||||||
|
|
||||||
const handleExampleClick = async (content: string) => {
|
const handleExampleClick = async (content: string) => {
|
||||||
let conversation = conversationStore.currentConversation;
|
let conversation = conversationStore.currentConversation;
|
||||||
@ -44,7 +46,7 @@ const EmptyView = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div className={`${className || ""} w-full h-full flex flex-col justify-start items-center`}>
|
<div className={`${className || ""} w-full h-full flex flex-col justify-start items-center`}>
|
||||||
<div className="w-96 max-w-full font-medium leading-loose mb-8">
|
<div className="w-96 max-w-full font-medium leading-loose mb-8">
|
||||||
<img src="/chat-logo-and-text.webp" alt="sql-chat-logo" />
|
<img src={isDarkMode ? "/chat-logo-and-text-dark-mode.webp" : "/chat-logo-and-text.webp"} alt="sql-chat-logo" />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full grid grid-cols-2 sm:grid-cols-3 gap-4">
|
<div className="w-full grid grid-cols-2 sm:grid-cols-3 gap-4">
|
||||||
<div className="w-full flex flex-col justify-start items-center">
|
<div className="w-full flex flex-col justify-start items-center">
|
||||||
|
17
src/hooks/useDarkmode.ts
Normal file
17
src/hooks/useDarkmode.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { useSettingStore } from "@/store";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const useDarkMode = () => {
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
||||||
|
});
|
||||||
|
}, [settingStore.setting.theme]);
|
||||||
|
|
||||||
|
return isDarkMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDarkMode;
|
Reference in New Issue
Block a user