- {settingTabs.map((t) => (
+ {settings.map((t) => (
))}
-
@@ -87,7 +95,7 @@ const Close = () => {
}
const Content = () => {
- const key = useSettingTab() || "index"
+ const key = useSettingTab()
const Component = pages[key]
if (!Component) return null
@@ -100,7 +108,7 @@ const LoadRemixAsyncComponent: FC<{
}> = ({ loader }) => {
const [loading, setLoading] = useState(true)
- const [Component, setComponent] = useState({
+ const [Component, setComponent] = useState<{ c: () => ReactNode }>({
c: () => null,
})
@@ -111,8 +119,15 @@ const LoadRemixAsyncComponent: FC<{
if (!module.Component) {
return
}
+
+ const { loader } = module
setComponent({
- c: module.Component,
+ c: () => (
+ <>
+
+
+ >
+ ),
})
})
.finally(() => {
diff --git a/src/renderer/src/modules/settings/section.tsx b/src/renderer/src/modules/settings/section.tsx
new file mode 100644
index 000000000..d0ee514c1
--- /dev/null
+++ b/src/renderer/src/modules/settings/section.tsx
@@ -0,0 +1,6 @@
+import type { FC } from "react"
+
+export const SettingSectionTitle: FC<{
+ title: string
+}> = ({ title }) =>
+
{title}
diff --git a/src/renderer/src/modules/settings/tabs/apperance.tsx b/src/renderer/src/modules/settings/tabs/apperance.tsx
new file mode 100644
index 000000000..61dc899a9
--- /dev/null
+++ b/src/renderer/src/modules/settings/tabs/apperance.tsx
@@ -0,0 +1,124 @@
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@renderer/components/ui/select"
+import { useDark } from "@renderer/hooks"
+import { tipcClient } from "@renderer/lib/client"
+import { getOS } from "@renderer/lib/utils"
+import { uiActions, useUIStore } from "@renderer/store"
+import { useQuery } from "@tanstack/react-query"
+import { useCallback } from "react"
+
+import { SettingSwitch } from "../control"
+import { SettingSectionTitle } from "../section"
+import { SettingsTitle } from "../title"
+
+export const SettingAppearance = () => {
+ const { isDark, toggleDark } = useDark()
+ const saveDarkSetting = useCallback(() => {
+ toggleDark()
+ }, [])
+
+ const state = useUIStore()
+
+ return (
+
+
+
+
+ {window.electron && getOS() === "macOS" && (
+ {
+ uiActions.set("opaqueSidebar", checked)
+ }}
+ />
+ )}
+
+
+ {window.electron && }
+
+
+ )
+}
+
+const Fonts = () => {
+ const { data } = useQuery({
+ queryFn: () => tipcClient?.getSystemFonts(),
+ queryKey: ["systemFonts"],
+ })
+ const readerFontFamily = useUIStore(
+ (state) => state.readerFontFamily || "SN Pro",
+ )
+ return (
+
+ Font Family
+
+
+ )
+}
+
+const textSizeMap = {
+ tiny: 12,
+ smaller: 14,
+ default: 16,
+ medium: 18,
+ large: 20,
+}
+
+const TextSize = () => {
+ const uiTextSize = useUIStore((state) => state.uiTextSize)
+
+ return (
+
+ Text Size
+
+
+ )
+}
diff --git a/src/renderer/src/modules/settings/title.tsx b/src/renderer/src/modules/settings/title.tsx
index c78a5ffbd..8f826c4a5 100644
--- a/src/renderer/src/modules/settings/title.tsx
+++ b/src/renderer/src/modules/settings/title.tsx
@@ -1,16 +1,17 @@
-import { settingTabs } from "@renderer/lib/constants"
import { cn } from "@renderer/lib/utils"
+import { useLoaderData } from "react-router-dom"
-export const SettingsTitle = ({
+import { settings } from "./constants"
+import type { SettingPageConfig } from "./utils"
+
+export const SettingsSidebarTitle = ({
path,
className,
- sticky,
}: {
path: string
className?: string
- sticky?: boolean
}) => {
- const tab = settingTabs.find((t) => t.path === path)
+ const tab = settings.find((t) => t.path === path)
if (!tab) {
return null
@@ -19,13 +20,40 @@ export const SettingsTitle = ({
return (
-
+
{tab.name}
)
}
+
+export const SettingsTitle = ({
+ className,
+ loader,
+}: {
+ className?: string
+ loader?: () => SettingPageConfig
+}) => {
+ const { iconName, name: title } = (useLoaderData() ||
+ loader?.() ||
+ {}) as SettingPageConfig
+
+ if (!title) {
+ return null
+ }
+ return (
+
+
+ {title}
+
+ )
+}
diff --git a/src/renderer/src/modules/settings/utils.ts b/src/renderer/src/modules/settings/utils.ts
new file mode 100644
index 000000000..a347c6332
--- /dev/null
+++ b/src/renderer/src/modules/settings/utils.ts
@@ -0,0 +1,9 @@
+export interface SettingPageConfig {
+ iconName: string
+ name: string
+ priority: number
+
+}
+export const defineSettingPage = (config: SettingPageConfig) => () => ({
+ ...config,
+})
diff --git a/src/renderer/src/pages/(main)/(layer)/feeds/[feedId]/layout.tsx b/src/renderer/src/pages/(main)/(layer)/feeds/[feedId]/layout.tsx
index 762b5d617..2332520d6 100644
--- a/src/renderer/src/pages/(main)/(layer)/feeds/[feedId]/layout.tsx
+++ b/src/renderer/src/pages/(main)/(layer)/feeds/[feedId]/layout.tsx
@@ -23,7 +23,7 @@ export function Component() {
initial: entryColWidth,
containerRef,
onResizeEnd({ position }) {
- uiActions.setEntryColWidth(position)
+ uiActions.set("entryColWidth", position)
},
})
diff --git a/src/renderer/src/pages/settings/actions.tsx b/src/renderer/src/pages/settings/actions.tsx
index 6069adbcb..f490ce18d 100644
--- a/src/renderer/src/pages/settings/actions.tsx
+++ b/src/renderer/src/pages/settings/actions.tsx
@@ -4,11 +4,22 @@ import { apiClient } from "@renderer/lib/api-fetch"
import type { ActionsResponse } from "@renderer/models"
import { ActionCard } from "@renderer/modules/settings/action-card"
import { SettingsTitle } from "@renderer/modules/settings/title"
+import { defineSettingPage } from "@renderer/modules/settings/utils"
import { Queries } from "@renderer/queries"
import { useMutation } from "@tanstack/react-query"
import { useEffect, useState } from "react"
import { toast } from "sonner"
+const iconName = "i-mgc-magic-2-cute-re"
+const name = "Actions"
+const priority = 1020
+
+export const loader = defineSettingPage({
+ iconName,
+ name,
+ priority,
+})
+
type Operation =
| "contains"
| "not_contains"
@@ -79,7 +90,7 @@ export function Component() {
return (
<>
-
+
{actionsData.map((action, actionIdx) => (
+}
diff --git a/src/renderer/src/pages/settings/general.tsx b/src/renderer/src/pages/settings/general.tsx
new file mode 100644
index 000000000..4bb5d7d75
--- /dev/null
+++ b/src/renderer/src/pages/settings/general.tsx
@@ -0,0 +1,46 @@
+import { tipcClient } from "@renderer/lib/client"
+import { SettingSwitch } from "@renderer/modules/settings/control"
+import {
+ SettingsTitle,
+} from "@renderer/modules/settings/title"
+import { defineSettingPage } from "@renderer/modules/settings/utils"
+import { useCallback, useEffect, useState } from "react"
+
+const iconName = "i-mgc-settings-7-cute-re"
+const name = "General"
+const priority = 1000
+
+export const loader = defineSettingPage({
+ iconName,
+ name,
+ priority,
+})
+
+export function Component() {
+ const [loginSetting, setLoginSetting] = useState(false)
+ useEffect(() => {
+ tipcClient?.getLoginItemSettings().then((settings) => {
+ setLoginSetting(settings.openAtLogin)
+ })
+ }, [])
+
+ const saveLoginSetting = useCallback((checked: boolean) => {
+ tipcClient?.setLoginItemSettings(checked)
+ setLoginSetting(checked)
+ }, [])
+
+ return (
+ <>
+
+
+ {window.electron && (
+
+ )}
+
+ >
+ )
+}
diff --git a/src/renderer/src/pages/settings/index.tsx b/src/renderer/src/pages/settings/index.tsx
index 9c8cd087e..be13cf66b 100644
--- a/src/renderer/src/pages/settings/index.tsx
+++ b/src/renderer/src/pages/settings/index.tsx
@@ -1,52 +1,8 @@
-import { Checkbox } from "@renderer/components/ui/checkbox"
-import { Label } from "@renderer/components/ui/label"
-import { useDark } from "@renderer/hooks"
-import { tipcClient } from "@renderer/lib/client"
-import { SettingsTitle } from "@renderer/modules/settings/title"
-import { useCallback, useEffect, useState } from "react"
+import { redirect } from "react-router-dom"
-export function Component() {
- const { isDark, toggleDark } = useDark()
+export const Component = () => null
- const [loginSetting, setLoginSetting] = useState(false)
- useEffect(() => {
- tipcClient?.getLoginItemSettings().then((settings) => {
- setLoginSetting(settings.openAtLogin)
- })
- }, [])
-
- const saveLoginSetting = useCallback((checked: boolean) => {
- tipcClient?.setLoginItemSettings(checked)
- setLoginSetting(checked)
- }, [])
-
- const saveDarkSetting = useCallback(() => {
- toggleDark()
- }, [])
-
- return (
- <>
-
-
- {window.electron && (
-
-
-
-
- )}
-
-
-
-
-
- >
- )
+export const loader = () => {
+ redirect("/settings/general")
+ return null
}
diff --git a/src/renderer/src/pages/settings/layout.tsx b/src/renderer/src/pages/settings/layout.tsx
index 0c75625ea..e8c3dcb24 100644
--- a/src/renderer/src/pages/settings/layout.tsx
+++ b/src/renderer/src/pages/settings/layout.tsx
@@ -1,8 +1,11 @@
import { Logo } from "@renderer/components/icons/logo"
import { Vibrancy } from "@renderer/components/ui/background"
-import { APP_NAME, settingTabs } from "@renderer/lib/constants"
+import { APP_NAME } from "@renderer/lib/constants"
import { preventDefault } from "@renderer/lib/dom"
-import { SettingsTitle } from "@renderer/modules/settings/title"
+import { settings } from "@renderer/modules/settings/constants"
+import {
+ SettingsSidebarTitle,
+} from "@renderer/modules/settings/title"
import { Link, Outlet, useLocation } from "react-router-dom"
// TODO Web UI
@@ -15,32 +18,27 @@ export function Component() {
- {settingTabs.map((t) => (
+ {settings.map((t) => (
-
+
))}
-
- {APP_NAME}
-
+ {APP_NAME}
-
diff --git a/src/renderer/src/pages/settings/profile.tsx b/src/renderer/src/pages/settings/profile.tsx
index 17947151e..e9b4fa603 100644
--- a/src/renderer/src/pages/settings/profile.tsx
+++ b/src/renderer/src/pages/settings/profile.tsx
@@ -13,6 +13,7 @@ import {
import { Input } from "@renderer/components/ui/input"
import { apiClient } from "@renderer/lib/api-fetch"
import { SettingsTitle } from "@renderer/modules/settings/title"
+import { defineSettingPage } from "@renderer/modules/settings/utils"
import { useMutation } from "@tanstack/react-query"
import { useForm } from "react-hook-form"
import { toast } from "sonner"
@@ -24,6 +25,15 @@ const formSchema = z.object({
avatar: z.string().url(),
})
+const iconName = "i-mgc-user-setting-cute-re"
+const name = "Profile"
+const priority = 1030
+export const loader = defineSettingPage({
+ iconName,
+ name,
+ priority,
+})
+
export function Component() {
const user = useUser()
@@ -54,7 +64,7 @@ export function Component() {
return (
<>
-
+