refactor(desktop): improve shiki highlight component (#3461)
* refactor(desktop): improve shiki highlight component * update * update
This commit is contained in:
parent
be093e1b75
commit
18de7a8de8
|
|
@ -7,7 +7,7 @@ import { AnimatedCommandButton } from "./base"
|
|||
export const CopyButton: Component<{
|
||||
value: string
|
||||
style?: React.CSSProperties
|
||||
variant?: "solid" | "outline"
|
||||
variant?: "solid" | "outline" | "ghost"
|
||||
}> = ({ value, className, style, variant = "solid" }) => {
|
||||
const copiedTimerRef = useRef<any>()
|
||||
const handleCopy = useCallback(() => {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export const AnimatedCommandButton: FC<AnimatedCommandButtonProps & HTMLMotionPr
|
|||
"center pointer-events-auto flex text-xs",
|
||||
"rounded-md p-1.5 duration-200",
|
||||
variant === "solid" || variant === "ghost"
|
||||
? "border-accent/5 bg-accent/80 border text-white backdrop-blur"
|
||||
? "border-accent/5 bg-accent/80 text-accent border backdrop-blur"
|
||||
: "text-accent bg-slate-50/50 dark:bg-slate-900/50",
|
||||
variant === "ghost" && "bg-theme-item-active hover:bg-theme-item-hover",
|
||||
className,
|
||||
|
|
|
|||
|
|
@ -15,44 +15,7 @@ const LanguageAlias = {
|
|||
jsx: "javascriptreact",
|
||||
md: "markdown",
|
||||
}
|
||||
const LanguageToColorMap = {
|
||||
"c#": "#178600",
|
||||
"c++": "#f34b7d",
|
||||
"objective-c": "#438eff",
|
||||
"objective-c++": "#6866fb",
|
||||
c: "#555555",
|
||||
cpp: "#f34b7d",
|
||||
csharp: "#178600",
|
||||
css: "#563d7c",
|
||||
dart: "#00B4AB",
|
||||
dockerfile: "#384d54",
|
||||
go: "#00add8",
|
||||
html: "#e34c26",
|
||||
java: "#b07219",
|
||||
javascript: "#f1e05a",
|
||||
javascriptreact: "#f1e05a",
|
||||
json: "#292929",
|
||||
kotlin: "#F18E33",
|
||||
lisp: "#3fb68b",
|
||||
lua: "#000080",
|
||||
markdown: "#083fa1",
|
||||
matlab: "#e16737",
|
||||
perl: "#0298c3",
|
||||
php: "#4f5d95",
|
||||
python: "#3572a5",
|
||||
r: "#198ce7",
|
||||
ruby: "#701516",
|
||||
rust: "#dea584",
|
||||
scala: "#c22d40",
|
||||
shell: "#89e051",
|
||||
sql: "#e38c00",
|
||||
swift: "#ffac45",
|
||||
typescript: "#2b7489",
|
||||
typescriptreact: "#2b7489",
|
||||
vimscript: "#199f4b",
|
||||
vue: "#2c3e50",
|
||||
yaml: "#cb171e",
|
||||
}
|
||||
|
||||
const languageToIconMap = {
|
||||
javascriptreact: <UilReact />,
|
||||
typescriptreact: <UilReact />,
|
||||
|
|
@ -62,15 +25,6 @@ const languageToIconMap = {
|
|||
css: <MdiLanguageCss3 />,
|
||||
markdown: <RiMarkdownFill />,
|
||||
}
|
||||
export const getLanguageColor = (language?: string) => {
|
||||
if (!language) return
|
||||
|
||||
const alias = LanguageAlias[language]
|
||||
if (alias) {
|
||||
return LanguageToColorMap[alias]
|
||||
}
|
||||
return LanguageToColorMap[language]
|
||||
}
|
||||
|
||||
export const getLanguageIcon = (language?: string) => {
|
||||
if (!language) return null
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { useIsDark } from "@follow/hooks"
|
||||
import { ELECTRON_BUILD } from "@follow/shared/constants"
|
||||
import { cn } from "@follow/utils/utils"
|
||||
import { useIsomorphicLayoutEffect } from "foxact/use-isomorphic-layout-effect"
|
||||
|
|
@ -11,11 +10,12 @@ import type {
|
|||
DynamicImportThemeRegistration,
|
||||
} from "shiki"
|
||||
|
||||
import { useUISettingKey, useUISettingSelector } from "~/atoms/settings/ui"
|
||||
import { useUISettingKey } from "~/atoms/settings/ui"
|
||||
import { tipcClient } from "~/lib/client"
|
||||
|
||||
import { CopyButton } from "../../button/CopyButton"
|
||||
import { getLanguageColor, getLanguageIcon } from "../constants"
|
||||
import { getLanguageIcon } from "../constants"
|
||||
import { useShikiDefaultTheme } from "./hooks"
|
||||
import { shiki, shikiTransformers } from "./shared"
|
||||
import styles from "./shiki.module.css"
|
||||
|
||||
|
|
@ -72,10 +72,7 @@ export const ShikiHighLighter: FC<ShikiProps> = (props) => {
|
|||
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
const isDark = useIsDark()
|
||||
const codeThemeLight = useUISettingSelector((s) => overrideTheme || s.codeHighlightThemeLight)
|
||||
const codeThemeDark = useUISettingSelector((s) => overrideTheme || s.codeHighlightThemeDark)
|
||||
const codeTheme = isDark ? codeThemeDark : codeThemeLight
|
||||
const codeTheme = useShikiDefaultTheme(overrideTheme)
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
let isMounted = true
|
||||
|
|
@ -188,27 +185,22 @@ const ShikiCode: FC<
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"group relative my-4",
|
||||
"my-4 border",
|
||||
styles["shiki-wrapper"],
|
||||
transparent ? styles["transparent"] : null,
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between border-b p-2">
|
||||
{language !== "plaintext" && (
|
||||
<span className="center flex gap-1 text-xs uppercase opacity-80 dark:text-white">
|
||||
<span className="center [&_svg]:size-4">{getLanguageIcon(language)}</span>
|
||||
<span>{language}</span>
|
||||
</span>
|
||||
)}
|
||||
<CopyButton variant="outline" value={code} />
|
||||
</div>
|
||||
<div dangerouslySetInnerHTML={{ __html: rendered }} data-language={language} />
|
||||
<CopyButton
|
||||
variant="outline"
|
||||
value={code}
|
||||
style={{
|
||||
color: getLanguageColor(language),
|
||||
}}
|
||||
className={"absolute right-2 top-2 opacity-0 duration-200 group-hover:opacity-100"}
|
||||
/>
|
||||
{language !== "plaintext" && (
|
||||
<span className="center absolute bottom-2 right-2 flex gap-1 text-xs uppercase opacity-80 dark:text-white">
|
||||
<span className="center [&_svg]:size-4">{getLanguageIcon(language)}</span>
|
||||
<span>{language}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import { useIsDark } from "@follow/hooks"
|
||||
|
||||
export const useShikiDefaultTheme = () => {
|
||||
const isDark = useIsDark()
|
||||
import { useUISettingSelector } from "~/atoms/settings/ui"
|
||||
|
||||
return isDark ? "github-dark" : "github-light"
|
||||
export const useShikiDefaultTheme = (overrideTheme?: string) => {
|
||||
const isDark = useIsDark()
|
||||
const codeThemeLight = useUISettingSelector((s) => overrideTheme || s.codeHighlightThemeLight)
|
||||
const codeThemeDark = useUISettingSelector((s) => overrideTheme || s.codeHighlightThemeDark)
|
||||
|
||||
return isDark ? codeThemeDark : codeThemeLight
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ export function AddModalContent({
|
|||
}
|
||||
}, [details.data])
|
||||
|
||||
const codes = [
|
||||
`FOLLOW_OWNER_USER_ID=${me?.handle || me?.id} # User id or handle of your follow account`,
|
||||
`FOLLOW_DESCRIPTION=${instance?.description || `${me?.name}'s instance`} # The description of your instance`,
|
||||
`FOLLOW_PRICE=${instance?.price || 100} # The monthly price of your instance, set to 0 means free.`,
|
||||
`FOLLOW_USER_LIMIT=${instance?.userLimit || 1000} # The user limit of your instance, set it to 0 or 1 can make your instance private, leaving it empty means no restriction`,
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="max-w-[550px] space-y-4 lg:min-w-[550px]">
|
||||
<div className="text-sm">{t("rsshub.addModal.description")}</div>
|
||||
|
|
@ -73,11 +80,8 @@ export function AddModalContent({
|
|||
<ShikiHighLighter
|
||||
transparent
|
||||
theme={shikiTheme}
|
||||
className="border-border group relative mt-3 cursor-auto select-text whitespace-pre break-words rounded-lg border bg-zinc-100 p-2 text-sm dark:bg-neutral-800 [&_pre]:whitespace-pre [&_pre]:break-words [&_pre]:!p-0"
|
||||
code={`FOLLOW_OWNER_USER_ID=${me?.handle || me?.id} # User id or handle of your follow account
|
||||
FOLLOW_DESCRIPTION=${instance?.description || `${me?.name}'s instance`} # The description of your instance
|
||||
FOLLOW_PRICE=${instance?.price || 100} # The monthly price of your instance, set to 0 means free.
|
||||
FOLLOW_USER_LIMIT=${instance?.userLimit || 1000} # The user limit of your instance, set it to 0 or 1 can make your instance private, leaving it empty means no restriction`}
|
||||
className="group mt-3 cursor-auto select-text whitespace-pre break-words rounded-lg bg-zinc-100 text-sm dark:bg-neutral-800 [&_pre]:whitespace-pre [&_pre]:break-words"
|
||||
code={codes.join("\n")}
|
||||
language="dotenv"
|
||||
/>
|
||||
{details.isLoading ? (
|
||||
|
|
|
|||
Loading…
Reference in New Issue