mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-26 07:24:10 +08:00
Co-authored-by: nb5p <nb5p@users.noreply.github.com> Co-authored-by: kunish <kunish.butt@gmail.com>
This commit is contained in:
parent
8fa51e5639
commit
a9aa8e540e
573
CHANGELOG.md
573
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
4868
pnpm-lock.yaml
generated
4868
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -47,7 +47,7 @@ export default {
|
||||
autoSwitchTheme: 'Automatically switch theme',
|
||||
favDayTheme: 'Favorite light theme',
|
||||
favNightTheme: 'Favorite dark theme',
|
||||
renderInTwoColumns: 'Render proxies in two columns',
|
||||
renderInTwoColumns: 'Render in two columns',
|
||||
updateGEODatabases: 'Update GEO Databases',
|
||||
restartCore: 'Restart Core',
|
||||
upgradeCore: 'Upgrade Core',
|
||||
@ -60,8 +60,6 @@ export default {
|
||||
ms: 'ms',
|
||||
updated: 'Updated',
|
||||
renderProxiesInSamePage: 'Render proxies and proxy provider in same page',
|
||||
renderRulesAndProviderInTwoColumns:
|
||||
'Render rules and rule provider in two columns',
|
||||
tableSize: 'Table size',
|
||||
xs: 'Extra small size',
|
||||
sm: 'Small size',
|
||||
|
@ -47,7 +47,7 @@ export default {
|
||||
autoSwitchTheme: '自动切换主题',
|
||||
favDayTheme: '浅色主题偏好',
|
||||
favNightTheme: '深色主题偏好',
|
||||
renderInTwoColumns: '节点双列渲染',
|
||||
renderInTwoColumns: '双列渲染',
|
||||
updateGEODatabases: '更新 GEO 数据库文件',
|
||||
restartCore: '重启核心',
|
||||
upgradeCore: '更新核心',
|
||||
@ -60,7 +60,6 @@ export default {
|
||||
ms: '毫秒',
|
||||
updated: '更新于',
|
||||
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
||||
renderRulesAndProviderInTwoColumns: '规则和规则提供者双列渲染',
|
||||
tableSize: '表格大小',
|
||||
xs: '超小尺寸',
|
||||
sm: '小尺寸',
|
||||
|
@ -30,7 +30,6 @@ import {
|
||||
proxiesOrderingType,
|
||||
proxiesPreviewType,
|
||||
renderInTwoColumns,
|
||||
renderRulesAndProviderInTwoColumns,
|
||||
setAutoCloseConns,
|
||||
setAutoSwitchTheme,
|
||||
setFavDayTheme,
|
||||
@ -39,7 +38,6 @@ import {
|
||||
setProxiesOrderingType,
|
||||
setProxiesPreviewType,
|
||||
setRenderInTwoColumns,
|
||||
setRenderRulesAndProviderInTwoColumns,
|
||||
setSelectedEndpoint,
|
||||
setTableSize,
|
||||
setTwemoji,
|
||||
@ -319,11 +317,6 @@ const ConfigForXd = () => {
|
||||
value: renderInTwoColumns,
|
||||
onChange: setRenderInTwoColumns,
|
||||
},
|
||||
{
|
||||
label: 'renderRulesAndProviderInTwoColumns',
|
||||
value: renderRulesAndProviderInTwoColumns,
|
||||
onChange: setRenderRulesAndProviderInTwoColumns,
|
||||
},
|
||||
{
|
||||
label: 'autoSwitchTheme',
|
||||
value: autoSwitchTheme,
|
||||
|
@ -3,15 +3,20 @@ import { IconReload } from '@tabler/icons-solidjs'
|
||||
import InfiniteScroll from 'solid-infinite-scroll'
|
||||
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Button } from '~/components'
|
||||
import { Button, ForTwoColumns } from '~/components'
|
||||
import { formatTimeFromNow, useStringBooleanMap } from '~/helpers'
|
||||
import { renderRulesAndProviderInTwoColumns, useRules } from '~/signals'
|
||||
import { useRules } from '~/signals'
|
||||
|
||||
enum ActiveTab {
|
||||
ruleProviders = 'ruleProviders',
|
||||
rules = 'rules',
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const [t] = useI18n()
|
||||
const {
|
||||
rules,
|
||||
rulesProviders,
|
||||
ruleProviders,
|
||||
updateRules,
|
||||
updateAllRuleProvider,
|
||||
updateRuleProviderByName,
|
||||
@ -39,43 +44,45 @@ export default () => {
|
||||
setAllProviderIsUpdating(false)
|
||||
}
|
||||
|
||||
const [activeTab, setActiveTab] = createSignal(ActiveTab.rules)
|
||||
|
||||
const tabs = () => [
|
||||
{
|
||||
type: ActiveTab.rules,
|
||||
name: t('rules'),
|
||||
count: rules().length,
|
||||
},
|
||||
{
|
||||
type: ActiveTab.ruleProviders,
|
||||
name: t('ruleProviders'),
|
||||
count: ruleProviders().length,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div
|
||||
class={twMerge(
|
||||
'flex w-full flex-col gap-4',
|
||||
renderRulesAndProviderInTwoColumns() && 'flex-row',
|
||||
)}
|
||||
>
|
||||
<div class="flex-1">
|
||||
<h1 class="pb-4 text-lg font-semibold">{t('rules')}</h1>
|
||||
<div class="flex h-full flex-col gap-2">
|
||||
<Show when={ruleProviders().length > 0}>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="tabs-boxed tabs gap-2">
|
||||
<For each={tabs()}>
|
||||
{(tab) => (
|
||||
<button
|
||||
class={twMerge(
|
||||
activeTab() === tab.type && 'tab-active',
|
||||
'tab gap-2 px-2',
|
||||
)}
|
||||
onClick={() => setActiveTab(tab.type)}
|
||||
>
|
||||
<span>{tab.name}</span>
|
||||
<div class="badge badge-sm">{tab.count}</div>
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
||||
<InfiniteScroll
|
||||
each={renderRules()}
|
||||
hasMore={renderRules().length < rules().length}
|
||||
next={() => setMaxRuleRender(maxRuleRender() + 100)}
|
||||
>
|
||||
{(rule) => (
|
||||
<div class="card card-bordered card-compact mb-2 bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="break-all">{rule.payload}</span>
|
||||
<Show when={typeof rule.size === 'number' && rule.size !== -1}>
|
||||
<div class="badge badge-sm">{rule.size}</div>
|
||||
</Show>
|
||||
</div>
|
||||
<div class="text-xs text-slate-500">
|
||||
{rule.type} :: {rule.proxy}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
|
||||
<Show when={rulesProviders().length > 0}>
|
||||
<div class="flex-1">
|
||||
<h1 class="flex items-center gap-2 pb-4 text-lg font-semibold">
|
||||
{t('ruleProviders')}
|
||||
<Show when={activeTab() === ActiveTab.ruleProviders}>
|
||||
<Button
|
||||
class="btn-circle btn-sm"
|
||||
class="btn btn-circle btn-sm"
|
||||
disabled={allProviderIsUpdating()}
|
||||
onClick={(e) => onUpdateAllProviderClick(e)}
|
||||
>
|
||||
@ -85,38 +92,66 @@ export default () => {
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</h1>
|
||||
|
||||
<For each={rulesProviders()}>
|
||||
{(rulesProvider) => (
|
||||
<div class="card card-bordered card-compact mb-2 bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2 pr-8">
|
||||
<span class="break-all">{rulesProvider.name}</span>
|
||||
<div class="badge badge-sm">{rulesProvider.ruleCount}</div>
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-slate-500">
|
||||
{rulesProvider.vehicleType} / {rulesProvider.behavior} /
|
||||
{t('updated')} {formatTimeFromNow(rulesProvider.updatedAt)}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
class="btn-circle btn-sm absolute right-2 top-2 mr-2 h-4"
|
||||
disabled={updatingMap()[rulesProvider.name]}
|
||||
onClick={(e) => onUpdateProviderClick(e, rulesProvider.name)}
|
||||
>
|
||||
<IconReload
|
||||
class={twMerge(
|
||||
updatingMap()[rulesProvider.name] &&
|
||||
'animate-spin text-success',
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<Show when={activeTab() === ActiveTab.ruleProviders}>
|
||||
<ForTwoColumns
|
||||
subChild={ruleProviders().map((ruleProvider) => {
|
||||
return (
|
||||
<div class="card card-bordered card-compact mb-2 bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2 pr-8">
|
||||
<span class="break-all">{ruleProvider.name}</span>
|
||||
<div class="badge badge-sm">{ruleProvider.ruleCount}</div>
|
||||
</div>
|
||||
<div class="text-xs text-slate-500">
|
||||
{ruleProvider.vehicleType} / {ruleProvider.behavior} /
|
||||
{t('updated')} {formatTimeFromNow(ruleProvider.updatedAt)}
|
||||
</div>
|
||||
<Button
|
||||
class="btn-circle btn-sm absolute right-2 top-2 mr-2 h-4"
|
||||
disabled={updatingMap()[ruleProvider.name]}
|
||||
onClick={(e) => onUpdateProviderClick(e, ruleProvider.name)}
|
||||
>
|
||||
<IconReload
|
||||
class={twMerge(
|
||||
updatingMap()[ruleProvider.name] &&
|
||||
'animate-spin text-success',
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Show when={activeTab() === ActiveTab.rules}>
|
||||
<InfiniteScroll
|
||||
each={renderRules()}
|
||||
hasMore={renderRules().length < rules().length}
|
||||
next={() => setMaxRuleRender(maxRuleRender() + 100)}
|
||||
>
|
||||
{(rule) => (
|
||||
<div class="card card-bordered card-compact mb-2 bg-base-200 p-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="break-all">{rule.payload}</span>
|
||||
<Show
|
||||
when={typeof rule.size === 'number' && rule.size !== -1}
|
||||
>
|
||||
<div class="badge badge-sm">{rule.size}</div>
|
||||
</Show>
|
||||
</div>
|
||||
<div class="text-xs text-slate-500">
|
||||
{rule.type} :: {rule.proxy}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</InfiniteScroll>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -45,13 +45,6 @@ export const [renderInTwoColumns, setRenderInTwoColumns] = makePersisted(
|
||||
createSignal(true),
|
||||
{ name: 'renderInTwoColumn', storage: localStorage },
|
||||
)
|
||||
export const [
|
||||
renderRulesAndProviderInTwoColumns,
|
||||
setRenderRulesAndProviderInTwoColumns,
|
||||
] = makePersisted(createSignal(true), {
|
||||
name: 'renderRulesAndProviderInTwoColumns',
|
||||
storage: localStorage,
|
||||
})
|
||||
export const [tableSize, setTableSize] = makePersisted(
|
||||
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
|
||||
{ name: 'tableSize', storage: localStorage },
|
||||
|
@ -5,7 +5,7 @@ import type { Rule, RuleProvider } from '~/types'
|
||||
export const useRules = () => {
|
||||
const request = useRequest()
|
||||
const [rules, setRules] = createSignal<Rule[]>([])
|
||||
const [rulesProviders, setRulesProviders] = createSignal<RuleProvider[]>([])
|
||||
const [ruleProviders, setRuleProviders] = createSignal<RuleProvider[]>([])
|
||||
|
||||
const updateRules = async () => {
|
||||
const [{ rules }, { providers }] = await Promise.all([
|
||||
@ -16,12 +16,12 @@ export const useRules = () => {
|
||||
])
|
||||
|
||||
setRules(Object.values(rules))
|
||||
setRulesProviders(Object.values(providers))
|
||||
setRuleProviders(Object.values(providers))
|
||||
}
|
||||
|
||||
const updateAllRuleProvider = async () => {
|
||||
await Promise.all(
|
||||
rulesProviders().map((provider) => {
|
||||
ruleProviders().map((provider) => {
|
||||
return request.put(`providers/rules/${provider.name}`)
|
||||
}),
|
||||
)
|
||||
@ -35,7 +35,7 @@ export const useRules = () => {
|
||||
|
||||
return {
|
||||
rules,
|
||||
rulesProviders,
|
||||
ruleProviders,
|
||||
updateRules,
|
||||
updateAllRuleProvider,
|
||||
updateRuleProviderByName,
|
||||
|
Loading…
x
Reference in New Issue
Block a user