mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 10:42:09 +08:00
perf(frontend): optimize initial dependency loading
This commit is contained in:
@@ -4,10 +4,16 @@ import { open as openUrl } from '@tauri-apps/plugin-shell'
|
||||
import type { DownloadEvent } from '@tauri-apps/plugin-updater'
|
||||
import { useLockFn } from 'ahooks'
|
||||
import type { Ref } from 'react'
|
||||
import { useImperativeHandle, useMemo, useRef, useState } from 'react'
|
||||
import {
|
||||
lazy,
|
||||
Suspense,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import rehypeRaw from 'rehype-raw'
|
||||
import type { Options as ReactMarkdownOptions } from 'react-markdown'
|
||||
|
||||
import { BaseDialog, DialogRef } from '@/components/base'
|
||||
import { useUpdate } from '@/hooks/use-update'
|
||||
@@ -39,6 +45,17 @@ const GITHUB_ALERT_PATTERN =
|
||||
const GITHUB_ALERT_CLASS_PATTERN =
|
||||
/markdown-alert-(note|tip|important|warning|caution)/
|
||||
|
||||
const LazyReactMarkdown = lazy(async () => {
|
||||
const [{ default: ReactMarkdown }, { default: rehypeRaw }] =
|
||||
await Promise.all([import('react-markdown'), import('rehype-raw')])
|
||||
|
||||
return {
|
||||
default: (props: ReactMarkdownOptions) => (
|
||||
<ReactMarkdown {...props} rehypePlugins={[rehypeRaw]} />
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
const getAlertTypeFromClassName = (
|
||||
className: unknown,
|
||||
): GitHubAlertType | null => {
|
||||
@@ -367,62 +384,67 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGitHubAlerts]}
|
||||
rehypePlugins={[rehypeRaw]}
|
||||
components={{
|
||||
a: ({ ...props }) => {
|
||||
const { children } = props
|
||||
return (
|
||||
<a {...props} target="_blank" rel="noreferrer">
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
},
|
||||
blockquote: ({ className, children }) => {
|
||||
const alertType = getAlertTypeFromClassName(className)
|
||||
{open && (
|
||||
<Suspense fallback={<LinearProgress />}>
|
||||
<LazyReactMarkdown
|
||||
remarkPlugins={[remarkGitHubAlerts]}
|
||||
components={{
|
||||
a: ({ ...props }) => {
|
||||
const { children } = props
|
||||
return (
|
||||
<a {...props} target="_blank" rel="noreferrer">
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
},
|
||||
blockquote: ({ className, children }) => {
|
||||
const alertType = getAlertTypeFromClassName(className)
|
||||
|
||||
if (!alertType) {
|
||||
return <blockquote className={className}>{children}</blockquote>
|
||||
}
|
||||
if (!alertType) {
|
||||
return (
|
||||
<blockquote className={className}>{children}</blockquote>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="blockquote"
|
||||
className={className}
|
||||
sx={(theme) => {
|
||||
const color = GITHUB_ALERTS[alertType].color
|
||||
return {
|
||||
m: '12px 0 18px',
|
||||
px: 2,
|
||||
py: 1,
|
||||
borderLeft: `4px solid ${color}`,
|
||||
borderRadius: 1,
|
||||
bgcolor: alpha(
|
||||
color,
|
||||
theme.palette.mode === 'dark' ? 0.16 : 0.08,
|
||||
),
|
||||
'& p': {
|
||||
my: 0.75,
|
||||
},
|
||||
'& .markdown-alert-title': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.75,
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.4,
|
||||
},
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
},
|
||||
}}
|
||||
>
|
||||
{markdownContent}
|
||||
</ReactMarkdown>
|
||||
return (
|
||||
<Box
|
||||
component="blockquote"
|
||||
className={className}
|
||||
sx={(theme) => {
|
||||
const color = GITHUB_ALERTS[alertType].color
|
||||
return {
|
||||
m: '12px 0 18px',
|
||||
px: 2,
|
||||
py: 1,
|
||||
borderLeft: `4px solid ${color}`,
|
||||
borderRadius: 1,
|
||||
bgcolor: alpha(
|
||||
color,
|
||||
theme.palette.mode === 'dark' ? 0.16 : 0.08,
|
||||
),
|
||||
'& p': {
|
||||
my: 0.75,
|
||||
},
|
||||
'& .markdown-alert-title': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.75,
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.4,
|
||||
},
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
},
|
||||
}}
|
||||
>
|
||||
{markdownContent}
|
||||
</LazyReactMarkdown>
|
||||
</Suspense>
|
||||
)}
|
||||
</Box>
|
||||
{updateState && (
|
||||
<LinearProgress
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { ipv4, ipv6 } from 'cidr-block'
|
||||
import validator from 'validator'
|
||||
import isFQDN from 'validator/es/lib/isFQDN'
|
||||
import isIP from 'validator/es/lib/isIP'
|
||||
import isPort from 'validator/es/lib/isPort'
|
||||
import isURL from 'validator/es/lib/isURL'
|
||||
|
||||
const stripBrackets = (value: string) =>
|
||||
value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value
|
||||
|
||||
const isIpv4 = (value: string) => validator.isIP(value, 4)
|
||||
const isIpv6 = (value: string) => validator.isIP(value, 6)
|
||||
const isHostname = (value: string) =>
|
||||
validator.isFQDN(value, { require_tld: false })
|
||||
const isIpv4 = (value: string) => isIP(value, 4)
|
||||
const isIpv6 = (value: string) => isIP(value, 6)
|
||||
const isHostname = (value: string) => isFQDN(value, { require_tld: false })
|
||||
|
||||
export const isValidUrl = (value: string) =>
|
||||
validator.isURL(value.trim(), {
|
||||
isURL(value.trim(), {
|
||||
protocols: ['http', 'https'],
|
||||
require_protocol: true,
|
||||
require_valid_protocol: true,
|
||||
@@ -18,7 +20,7 @@ export const isValidUrl = (value: string) =>
|
||||
require_tld: false,
|
||||
})
|
||||
|
||||
export const isValidPort = (value: string) => validator.isPort(value.trim())
|
||||
export const isValidPort = (value: string) => isPort(value.trim())
|
||||
|
||||
export const normalizeHost = (value: string): string | null => {
|
||||
const host = value.trim()
|
||||
|
||||
Reference in New Issue
Block a user