@@ -42,13 +42,13 @@ const ShortcutView = (props: Props) => {
onClick={handleShortcutLinkClick}
>
- {shortcut.title}
+ {shortcut.title}
{shortcut.title ? (
- (s/{shortcut.name})
+ (s/{shortcut.name})
) : (
<>
- s/
- {shortcut.name}
+ s/
+ {shortcut.name}
>
)}
diff --git a/frontend/extension/src/hooks/useColorTheme.ts b/frontend/extension/src/hooks/useColorTheme.ts
new file mode 100644
index 0000000..03b1d81
--- /dev/null
+++ b/frontend/extension/src/hooks/useColorTheme.ts
@@ -0,0 +1,43 @@
+import { useColorScheme } from "@mui/joy";
+import { useEffect } from "react";
+
+const useColorTheme = () => {
+ const { mode: colorTheme, setMode: setColorTheme } = useColorScheme();
+
+ useEffect(() => {
+ const root = document.documentElement;
+ if (colorTheme === "light") {
+ root.classList.remove("dark");
+ } else if (colorTheme === "dark") {
+ root.classList.add("dark");
+ } else {
+ const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
+ if (darkMediaQuery.matches) {
+ root.classList.add("dark");
+ } else {
+ root.classList.remove("dark");
+ }
+
+ const handleColorSchemeChange = (e: MediaQueryListEvent) => {
+ if (e.matches) {
+ root.classList.add("dark");
+ } else {
+ root.classList.remove("dark");
+ }
+ };
+ try {
+ darkMediaQuery.addEventListener("change", handleColorSchemeChange);
+ } catch (error) {
+ console.error("failed to initial color scheme listener", error);
+ }
+
+ return () => {
+ darkMediaQuery.removeEventListener("change", handleColorSchemeChange);
+ };
+ }
+ }, [colorTheme]);
+
+ return { colorTheme, setColorTheme };
+};
+
+export default useColorTheme;
diff --git a/frontend/extension/src/options.tsx b/frontend/extension/src/options.tsx
index 3ac4e55..3ed1d56 100644
--- a/frontend/extension/src/options.tsx
+++ b/frontend/extension/src/options.tsx
@@ -1,5 +1,5 @@
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service";
-import { Button, Divider, Input } from "@mui/joy";
+import { Button, CssVarsProvider, Divider, Input, Select, Option } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import { useEffect, useState } from "react";
import { Toaster, toast } from "react-hot-toast";
@@ -7,6 +7,7 @@ import Icon from "./components/Icon";
import Logo from "./components/Logo";
import PullShortcutsButton from "./components/PullShortcutsButton";
import ShortcutsContainer from "./components/ShortcutsContainer";
+import useColorTheme from "./hooks/useColorTheme";
import "./style.css";
interface SettingState {
@@ -14,7 +15,23 @@ interface SettingState {
accessToken: string;
}
+const colorThemeOptions = [
+ {
+ value: "system",
+ label: "System",
+ },
+ {
+ value: "light",
+ label: "Light",
+ },
+ {
+ value: "dark",
+ label: "Dark",
+ },
+];
+
const IndexOptions = () => {
+ const { colorTheme, setColorTheme } = useColorTheme();
const [domain, setDomain] = useStorage
("domain", (v) => (v ? v : ""));
const [accessToken, setAccessToken] = useStorage("access_token", (v) => (v ? v : ""));
const [settingState, setSettingState] = useState({
@@ -44,91 +61,119 @@ const IndexOptions = () => {
toast.success("Setting saved");
};
+ const handleSelectColorTheme = async (colorTheme: string) => {
+ setColorTheme(colorTheme as any);
+ };
+
return (
- <>
-
-
+
+
-
-
-
- Slash
- /
- Setting
-
+
+
+
+ Slash
+ /
+ Setting
+
-
-
-
-
- setPartialSettingState({ domain: e.target.value })}
- />
-
+
+
+
-
-
-
Access Token
-
- setPartialSettingState({ accessToken: e.target.value })}
- />
-
-
-
-
-
+
+ setPartialSettingState({ domain: e.target.value })}
+ />
- {isInitialized && (
- <>
-
+
+
Access Token
+
+ setPartialSettingState({ accessToken: e.target.value })}
+ />
+
+
-
- Shortcuts
- ({shortcuts.length})
-
-
-
- >
- )}
+
+
+
+
+
+
+
Preference
+
+
+
+ Color Theme
+
+
+
-
-
- >
+ {isInitialized && (
+ <>
+
+
+
+ Shortcuts
+ ({shortcuts.length})
+
+
+
+ >
+ )}
+
+
);
};
-export default IndexOptions;
+const Options = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default Options;
diff --git a/frontend/extension/src/popup.tsx b/frontend/extension/src/popup.tsx
index 85f4cf7..67e8109 100644
--- a/frontend/extension/src/popup.tsx
+++ b/frontend/extension/src/popup.tsx
@@ -1,5 +1,5 @@
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service";
-import { Button, Divider, IconButton } from "@mui/joy";
+import { Button, CssVarsProvider, Divider, IconButton } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import { Toaster } from "react-hot-toast";
import CreateShortcutsButton from "@/components/CreateShortcutsButton";
@@ -7,9 +7,11 @@ import Icon from "@/components/Icon";
import Logo from "@/components/Logo";
import PullShortcutsButton from "@/components/PullShortcutsButton";
import ShortcutsContainer from "@/components/ShortcutsContainer";
+import useColorTheme from "./hooks/useColorTheme";
import "./style.css";
const IndexPopup = () => {
+ useColorTheme();
const [domain] = useStorage
("domain", "");
const [accessToken] = useStorage("access_token", "");
const [shortcuts] = useStorage("shortcuts", []);
@@ -25,86 +27,84 @@ const IndexPopup = () => {
};
return (
- <>
-
-
-
-
-
Slash
- {isInitialized && (
- <>
-
/
-
Shortcuts
-
({shortcuts.length})
-
- >
- )}
-
-
{isInitialized && }
-
-
-
- {isInitialized ? (
+
+
+
+
+
Slash
+ {isInitialized && (
<>
- {shortcuts.length !== 0 ? (
-
- ) : (
-
- )}
-
-
-
-
+
/
+
Shortcuts
+
({shortcuts.length})
+
>
- ) : (
-
-
-
Please set your domain and access token first.
-
-
- Or
-
-
-
)}
+
{isInitialized && }
-
- >
+
+ {isInitialized ? (
+ <>
+ {shortcuts.length !== 0 ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ >
+ ) : (
+
+
+
Please set your domain and access token first.
+
+
+ Or
+
+
+
+ )}
+
+
);
};
-export default IndexPopup;
+const Popup = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default Popup;
diff --git a/frontend/extension/src/style.css b/frontend/extension/src/style.css
index 6805d7b..cdb8517 100644
--- a/frontend/extension/src/style.css
+++ b/frontend/extension/src/style.css
@@ -5,7 +5,7 @@
body,
html,
#root {
- @apply text-base;
+ @apply text-base dark:bg-zinc-900;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans", "Noto Sans CJK SC", "Microsoft YaHei UI", "Microsoft YaHei",
"WenQuanYi Micro Hei", sans-serif, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";