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