refactor: knip cleanup (#7468)

* chore(frontend): expand Knip reports

* chore: remove unused Mihomo changelog sync script

* refactor: remove unused value exports

* refactor: remove unused type exports

* refactor: remove circular route dependencies

* chore(frontend): move Knip scope to config

* chore(i18n): remove stale portable update message
This commit is contained in:
Tunglies
2026-07-13 11:29:25 +08:00
committed by GitHub
parent 6f9fb97b31
commit 7ca20fc4ed
44 changed files with 266 additions and 602 deletions
@@ -13,7 +13,7 @@ import type { ReactNode } from 'react'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
export type BaseSplitChipEditorMode = 'visual' | 'advanced'
type BaseSplitChipEditorMode = 'visual' | 'advanced'
interface BaseSplitChipEditorProps {
value?: string
+1 -4
View File
@@ -6,10 +6,7 @@ export { BaseLoading } from './base-loading'
export { BaseLoadingOverlay } from './base-loading-overlay'
export { BasePage } from './base-page'
export { BaseSearchBox, type SearchState } from './base-search-box'
export {
BaseSplitChipEditor,
type BaseSplitChipEditorMode,
} from './base-split-chip-editor'
export { BaseSplitChipEditor } from './base-split-chip-editor'
export { BaseStyledSelect } from './base-styled-select'
export { BaseStyledTextField } from './base-styled-text-field'
export { MonacoEditor } from './monaco-editor'
+1 -1
View File
@@ -28,7 +28,7 @@ import getSystem from '@/utils/get-system'
const appWindow = getCurrentWebviewWindow()
export type EditorLanguage = 'yaml' | 'javascript' | 'css'
type EditorLanguage = 'yaml' | 'javascript' | 'css'
export interface EditorViewerProps {
open: boolean
-86
View File
@@ -1,6 +1,3 @@
import { useEffect, useMemo, useReducer, useRef } from 'react'
import { useVerge } from '@/hooks/use-verge'
import delayManager from '@/services/delay'
import { compileStringMatcher } from '@/utils/search-matcher'
@@ -13,89 +10,6 @@ export type ProxySearchState = {
useRegularExpression?: boolean
}
export default function useFilterSort(
proxies: IProxyItem[],
groupName: string,
filterText: string,
sortType: ProxySortType,
searchState?: ProxySearchState,
) {
const { verge } = useVerge()
const [_, bumpRefresh] = useReducer((count: number) => count + 1, 0)
const lastInputRef = useRef<{ text: string; sort: ProxySortType } | null>(
null,
)
const debounceTimerRef = useRef<number | null>(null)
useEffect(() => {
let last = 0
delayManager.setGroupListener(groupName, () => {
// 简单节流
const now = Date.now()
if (now - last > 666) {
last = now
bumpRefresh()
}
})
return () => {
delayManager.removeGroupListener(groupName)
}
}, [groupName])
const compute = useMemo(() => {
const fp = filterProxies(proxies, groupName, filterText, searchState)
const sp = sortProxies(
fp,
groupName,
sortType,
verge?.default_latency_timeout,
)
return sp
}, [
proxies,
groupName,
filterText,
sortType,
searchState,
verge?.default_latency_timeout,
])
const [result, setResult] = useReducer(
(_prev: IProxyItem[], next: IProxyItem[]) => next,
compute,
)
useEffect(() => {
if (debounceTimerRef.current !== null) {
window.clearTimeout(debounceTimerRef.current)
debounceTimerRef.current = null
}
const prev = lastInputRef.current
const stableInputs =
prev && prev.text === filterText && prev.sort === sortType
lastInputRef.current = { text: filterText, sort: sortType }
const delay = stableInputs ? 0 : 150
debounceTimerRef.current = window.setTimeout(() => {
setResult(compute)
debounceTimerRef.current = null
}, delay)
return () => {
if (debounceTimerRef.current !== null) {
window.clearTimeout(debounceTimerRef.current)
debounceTimerRef.current = null
}
}
}, [compute, filterText, sortType])
return result
}
export function filterSort(
proxies: IProxyItem[],
groupName: string,
@@ -17,7 +17,6 @@ import type { Options as ReactMarkdownOptions } from 'react-markdown'
import { BaseDialog, DialogRef } from '@/components/base'
import { useUpdate } from '@/hooks/use-update'
import { portableFlag } from '@/pages/_layout'
import { showNotice } from '@/services/notice-service'
import { useSetUpdateState, useUpdateState } from '@/services/states'
@@ -160,10 +159,6 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
}, [updateInfo])
const onUpdate = useLockFn(async () => {
if (portableFlag) {
showNotice.error('settings.modals.update.messages.portableError')
return
}
if (!updateInfo?.body) return
if (breakChangeFlag) {
showNotice.error('settings.modals.update.messages.breakChangeError')
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
import { DialogRef, TooltipIcon } from '@/components/base'
import { useVerge } from '@/hooks/use-verge'
import { navItems } from '@/pages/_routers'
import { navigationItems } from '@/pages/_navigation-meta'
import { copyClashEnv } from '@/services/cmds'
import { supportedLanguages } from '@/services/i18n'
import { showNotice } from '@/services/notice-service'
@@ -187,7 +187,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
onGuard={(e) => patchVerge({ start_page: e })}
>
<Select size="small" sx={{ width: 140, '> div': { py: '7.5px' } }}>
{navItems.map((page: { label: string; path: string }) => {
{Object.values(navigationItems).map((page) => {
return (
<MenuItem key={page.path} value={page.path}>
{t(page.label)}