mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-09 11:52:08 +08:00
@@ -0,0 +1,38 @@
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
|
||||
import type { SearchState } from '@/components/base'
|
||||
import { compileStringMatcher } from '@/utils/search-matcher'
|
||||
|
||||
const initialSearch: SearchState = {
|
||||
text: '',
|
||||
matchCase: false,
|
||||
matchWholeWord: false,
|
||||
useRegularExpression: false,
|
||||
}
|
||||
|
||||
const searches: Record<'connections' | 'rules' | 'logs', SearchState> = {
|
||||
connections: initialSearch,
|
||||
rules: initialSearch,
|
||||
logs: initialSearch,
|
||||
}
|
||||
|
||||
const saveSearch = (page: keyof typeof searches, state: SearchState) => {
|
||||
searches[page] = state
|
||||
}
|
||||
|
||||
export const usePageSearch = (page: keyof typeof searches) => {
|
||||
const [searchState, setSearchState] = useState(() => searches[page])
|
||||
const match = useMemo(
|
||||
() => compileStringMatcher(searchState.text, searchState).matcher,
|
||||
[searchState],
|
||||
)
|
||||
const onSearch = useCallback(
|
||||
(_match: (content: string) => boolean, state: SearchState) => {
|
||||
saveSearch(page, state)
|
||||
setSearchState(state)
|
||||
},
|
||||
[page],
|
||||
)
|
||||
|
||||
return { searchState, match, onSearch }
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
BasePage,
|
||||
BaseSearchBox,
|
||||
BaseStyledSelect,
|
||||
type SearchState,
|
||||
VirtualList,
|
||||
} from '@/components/base'
|
||||
import {
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
import { ConnectionTable } from '@/components/connection/connection-table'
|
||||
import { useConnectionData } from '@/hooks/use-connection-data'
|
||||
import { useConnectionSetting } from '@/hooks/use-connection-setting'
|
||||
import { usePageSearch } from '@/hooks/use-page-search'
|
||||
import { useTrafficData } from '@/hooks/use-traffic-data'
|
||||
import { useVisibility } from '@/hooks/use-visibility'
|
||||
import { mutate } from '@/services/mutate'
|
||||
@@ -83,10 +83,8 @@ const EMPTY_CONNECTIONS: IConnectionsItem[] = []
|
||||
const ConnectionsPage = () => {
|
||||
const { t } = useTranslation()
|
||||
const pageVisible = useVisibility()
|
||||
const [match, setMatch] = useState<(input: string) => boolean>(
|
||||
() => () => true,
|
||||
)
|
||||
const [hasSearch, setHasSearch] = useState(false)
|
||||
const { searchState, match, onSearch } = usePageSearch('connections')
|
||||
const hasSearch = searchState.text.length > 0
|
||||
const [curOrderOpt, setCurOrderOpt] = useState<OrderKey>('default')
|
||||
const [connectionsType, setConnectionsType] = useState<'active' | 'closed'>(
|
||||
'active',
|
||||
@@ -160,13 +158,6 @@ const ConnectionsPage = () => {
|
||||
}),
|
||||
)
|
||||
|
||||
const handleSearch = useCallback(
|
||||
(match: (content: string) => boolean, state: SearchState) => {
|
||||
setMatch(() => match)
|
||||
setHasSearch(state.text.length > 0)
|
||||
},
|
||||
[],
|
||||
)
|
||||
const hasTableData = filterConn.length > 0
|
||||
|
||||
return (
|
||||
@@ -274,7 +265,11 @@ const ConnectionsPage = () => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<BaseSearchBox onSearch={handleSearch} />
|
||||
<BaseSearchBox
|
||||
defaultValue={searchState.text}
|
||||
{...searchState}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</Box>
|
||||
{isTableLayout && hasTableData && (
|
||||
<Tooltip title={t('connections.components.columnManager.title')}>
|
||||
|
||||
+6
-8
@@ -4,7 +4,7 @@ import {
|
||||
SwapVertRounded,
|
||||
} from '@mui/icons-material'
|
||||
import { Box, Button, IconButton, MenuItem } from '@mui/material'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import {
|
||||
@@ -12,13 +12,13 @@ import {
|
||||
BasePage,
|
||||
BaseSearchBox,
|
||||
BaseStyledSelect,
|
||||
type SearchState,
|
||||
VirtualList,
|
||||
type VirtualListHandle,
|
||||
} from '@/components/base'
|
||||
import LogItem from '@/components/log/log-item'
|
||||
import { useClashLog } from '@/hooks/use-clash-log'
|
||||
import { useLogData } from '@/hooks/use-log-data'
|
||||
import { usePageSearch } from '@/hooks/use-page-search'
|
||||
|
||||
const LogPage = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -28,8 +28,7 @@ const LogPage = () => {
|
||||
const logOrder = clashLog.logOrder ?? 'asc'
|
||||
const isDescending = logOrder === 'desc'
|
||||
|
||||
const [match, setMatch] = useState(() => (_: string) => true)
|
||||
const [searchState, setSearchState] = useState<SearchState>()
|
||||
const { searchState, match, onSearch } = usePageSearch('logs')
|
||||
const {
|
||||
response: { data: logData },
|
||||
refreshGetClashLog,
|
||||
@@ -174,10 +173,9 @@ const LogPage = () => {
|
||||
<MenuItem value="err">{t('shared.filters.logLevels.error')}</MenuItem>
|
||||
</BaseStyledSelect>
|
||||
<BaseSearchBox
|
||||
onSearch={(matcher, state) => {
|
||||
setMatch(() => matcher)
|
||||
setSearchState(state)
|
||||
}}
|
||||
defaultValue={searchState.text}
|
||||
{...searchState}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
+7
-2
@@ -12,6 +12,7 @@ import {
|
||||
import { ScrollTopButton } from '@/components/layout/scroll-top-button'
|
||||
import { ProviderButton } from '@/components/rule/provider-button'
|
||||
import RuleItem from '@/components/rule/rule-item'
|
||||
import { usePageSearch } from '@/hooks/use-page-search'
|
||||
import { useVisibility } from '@/hooks/use-visibility'
|
||||
import { useAppRefreshers, useRulesData } from '@/providers/app-data-context'
|
||||
|
||||
@@ -19,7 +20,7 @@ const RulesPage = () => {
|
||||
const { t } = useTranslation()
|
||||
const { rules = [] } = useRulesData()
|
||||
const { refreshRules, refreshRuleProviders } = useAppRefreshers()
|
||||
const [match, setMatch] = useState(() => (_: string) => true)
|
||||
const { searchState, match, onSearch } = usePageSearch('rules')
|
||||
const virtuosoRef = useRef<VirtualListHandle>(null)
|
||||
const [showScrollTop, setShowScrollTop] = useState(false)
|
||||
const pageVisible = useVisibility()
|
||||
@@ -76,7 +77,11 @@ const RulesPage = () => {
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<BaseSearchBox onSearch={(match) => setMatch(() => match)} />
|
||||
<BaseSearchBox
|
||||
defaultValue={searchState.text}
|
||||
{...searchState}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{filteredRules && filteredRules.length > 0 ? (
|
||||
|
||||
Reference in New Issue
Block a user