diff --git a/src/renderer/src/atoms/settings/helper.ts b/src/renderer/src/atoms/settings/helper.ts index 9c2ccd0507..aa446ab33d 100644 --- a/src/renderer/src/atoms/settings/helper.ts +++ b/src/renderer/src/atoms/settings/helper.ts @@ -1,7 +1,10 @@ import { useRefValue } from "@renderer/hooks/common" import { createAtomHooks } from "@renderer/lib/jotai" import { getStorageNS } from "@renderer/lib/ns" -import { createSettingBuilder } from "@renderer/modules/settings/setting-builder" +import type { SettingItem } from "@renderer/modules/settings/setting-builder" +import { + createSettingBuilder, +} from "@renderer/modules/settings/setting-builder" import { useAtomValue } from "jotai" import { atomWithStorage, selectAtom } from "jotai/utils" import { useMemo } from "react" @@ -87,9 +90,10 @@ export const createDefineSettingItem = label: string description?: string onChange?: (value: T[K]) => void + hide?: boolean }, - ) => { - const { label, description, onChange } = options + ): any => { + const { label, description, onChange, hide } = options return { key, label, @@ -98,7 +102,8 @@ export const createDefineSettingItem = if (onChange) return onChange(value as any) setSetting(key, value as any) }, - } as any + disabled: hide, + } as SettingItem } export const createSetting = ( diff --git a/src/renderer/src/atoms/settings/ui.ts b/src/renderer/src/atoms/settings/ui.ts index c7167c1858..74fead6e02 100644 --- a/src/renderer/src/atoms/settings/ui.ts +++ b/src/renderer/src/atoms/settings/ui.ts @@ -26,6 +26,7 @@ const createDefaultSettings = (): UISettings => ({ // Content readerRenderInlineStyle: false, codeHighlightTheme: "github-dark", + guessCodeLanguage: true, // View pictureViewMasonry: true, diff --git a/src/renderer/src/components/ui/code-highlighter/shiki/Shiki.tsx b/src/renderer/src/components/ui/code-highlighter/shiki/Shiki.tsx index 95b6936f7a..66c4914d4a 100644 --- a/src/renderer/src/components/ui/code-highlighter/shiki/Shiki.tsx +++ b/src/renderer/src/components/ui/code-highlighter/shiki/Shiki.tsx @@ -1,4 +1,8 @@ -import { useUISettingSelector } from "@renderer/atoms/settings/ui" +import { + useUISettingKey, + useUISettingSelector, +} from "@renderer/atoms/settings/ui" +import { isElectronBuild } from "@renderer/constants" import { tipcClient } from "@renderer/lib/client" import { cn } from "@renderer/lib/utils" import type { FC } from "react" @@ -53,8 +57,10 @@ export const ShikiHighLighter: FC = (props) => { language || "plaintext", ) + const guessCodeLanguage = useUISettingKey("guessCodeLanguage") useInsertionEffect(() => { - if (language || !ELECTRON) return + if (!guessCodeLanguage) return + if (language || !isElectronBuild) return if (!bundledLanguagesKeysSet) { import("shiki/langs") @@ -79,7 +85,7 @@ export const ShikiHighLighter: FC = (props) => { } }) } - }, []) + }, [guessCodeLanguage]) const loadThemesRef = useRef([] as string[]) const loadLanguagesRef = useRef([] as string[]) diff --git a/src/renderer/src/lib/parse-html.ts b/src/renderer/src/lib/parse-html.ts index b510b0f252..ebf4bd4307 100644 --- a/src/renderer/src/lib/parse-html.ts +++ b/src/renderer/src/lib/parse-html.ts @@ -189,5 +189,5 @@ function extractCodeFromHtml(htmlString: string) { return code } - return code + return tempDiv.textContent } diff --git a/src/renderer/src/modules/settings/modal/content.tsx b/src/renderer/src/modules/settings/modal/content.tsx index 621eeb0474..c9737a50b3 100644 --- a/src/renderer/src/modules/settings/modal/content.tsx +++ b/src/renderer/src/modules/settings/modal/content.tsx @@ -4,7 +4,7 @@ import { useCurrentModal } from "@renderer/components/ui/modal" import { ScrollArea } from "@renderer/components/ui/scroll-area" import { SettingsTitle } from "@renderer/modules/settings/title" import type { FC } from "react" -import { Suspense, useDeferredValue } from "react" +import { Suspense, useDeferredValue, useLayoutEffect, useState } from "react" import { settings } from "../constants" import { SettingTabProvider, useSettingTab } from "./context" @@ -53,6 +53,14 @@ const Content = () => { const key = useDeferredValue(useSettingTab() || "general") const { Component, loader } = pages[key] + const [scroller, setScroller] = useState(null) + + useLayoutEffect(() => { + if (scroller) { + scroller.scrollTop = 0 + } + }, [key]) + if (!Component) return null return ( @@ -61,6 +69,7 @@ const Content = () => { diff --git a/src/renderer/src/modules/settings/tabs/apperance.tsx b/src/renderer/src/modules/settings/tabs/apperance.tsx index 5df95719b8..eb2fb1a588 100644 --- a/src/renderer/src/modules/settings/tabs/apperance.tsx +++ b/src/renderer/src/modules/settings/tabs/apperance.tsx @@ -1,3 +1,4 @@ +import { createDefineSettingItem } from "@renderer/atoms/settings/helper" import { setUISetting, useUISettingKey, @@ -11,6 +12,7 @@ import { SelectTrigger, SelectValue, } from "@renderer/components/ui/select" +import { isElectronBuild } from "@renderer/constants" import { useDark, useSetDarkInWebApp } from "@renderer/hooks/common" import { tipcClient } from "@renderer/lib/client" import { getOS } from "@renderer/lib/utils" @@ -22,6 +24,7 @@ import { createSettingBuilder } from "../setting-builder" import { SettingsTitle } from "../title" const SettingBuilder = createSettingBuilder(useUISettingValue) +const defineItem = createDefineSettingItem(useUISettingValue, setUISetting) export const SettingAppearance = () => { const isDark = useDark() @@ -50,31 +53,26 @@ export const SettingAppearance = () => { } }} />, - { + + defineItem("opaqueSidebar", { label: "Opaque sidebars", - key: "opaqueSidebar", - disabled: - !window.electron || !["macOS", "Linux"].includes(getOS()), - onChange: (value) => setUISetting("opaqueSidebar", value), - }, + hide: !window.electron || !["macOS", "Linux"].includes(getOS()), + }), { type: "title", value: "Unread count", }, - { - disabled: - !window.electron || !["macOS", "Linux"].includes(getOS()), + + defineItem("showDockBadge", { label: "Show as Dock badge", - key: "showDockBadge", - onChange: (value) => setUISetting("showDockBadge", value), - }, - { + hide: !window.electron || !["macOS", "Linux"].includes(getOS()), + }), + + defineItem("sidebarShowUnreadCount", { label: "Show in sidebar", - key: "sidebarShowUnreadCount", - onChange: (value) => - setUISetting("sidebarShowUnreadCount", value), - }, + }), + { type: "title", value: "Fonts", @@ -87,27 +85,33 @@ export const SettingAppearance = () => { value: "Content", }, ShikiTheme, - { + + defineItem("guessCodeLanguage", { + label: "Guess code language", + hide: !isElectronBuild, + description: + "Major programming languages that use models to infer unlabeled code blocks", + }), + + defineItem("readerRenderInlineStyle", { label: "Render inline style", - key: "readerRenderInlineStyle", - onChange: (value) => - setUISetting("readerRenderInlineStyle", value), - }, + description: + "Allows rendering of the inline style of the original HTML.", + }), { type: "title", value: "Misc", }, - { + + defineItem("modalOverlay", { label: "Show modal overlay", - key: "modalOverlay", - onChange: (value) => setUISetting("modalOverlay", value), - }, - { + description: "Show modal overlay", + }), + defineItem("reduceMotion", { label: "Reduce motion", - key: "reduceMotion", - onChange: (value) => setUISetting("reduceMotion", value), - description: `Reducing the motion of elements to improve performance and reduce energy consumption.`, - }, + description: + "Reducing the motion of elements to improve performance and reduce energy consumption", + }), ]} /> diff --git a/src/shared/src/interface/settings.ts b/src/shared/src/interface/settings.ts index e2eb8c29d8..273f78ed25 100644 --- a/src/shared/src/interface/settings.ts +++ b/src/shared/src/interface/settings.ts @@ -24,6 +24,7 @@ export interface UISettings { readerFontFamily: string readerRenderInlineStyle: boolean codeHighlightTheme: string + guessCodeLanguage: boolean // view pictureViewMasonry: boolean