metacubexd/src/pages/Rules.tsx

123 lines
4.1 KiB
TypeScript
Raw Normal View History

2023-09-02 00:15:19 +08:00
import { useI18n } from '@solid-primitives/i18n'
2023-09-02 17:42:13 +08:00
import { IconReload } from '@tabler/icons-solidjs'
2023-09-01 11:44:11 +08:00
import InfiniteScroll from 'solid-infinite-scroll'
2023-09-02 17:42:13 +08:00
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
2023-09-05 15:38:42 +08:00
import { twMerge } from 'tailwind-merge'
import { Button } from '~/components'
2023-09-05 15:38:42 +08:00
import { formatTimeFromNow, useStringBooleanMap } from '~/helpers'
import { renderRulesAndProviderInTwoColumns, useRules } from '~/signals'
2023-08-28 22:13:48 +08:00
export default () => {
2023-09-02 00:15:19 +08:00
const [t] = useI18n()
2023-09-02 17:42:13 +08:00
const {
rules,
rulesProviders,
updateRules,
updateAllRuleProvider,
updateRuleProviderByName,
} = useRules()
2023-09-01 11:44:11 +08:00
const [maxRuleRender, setMaxRuleRender] = createSignal(100)
const renderRules = createMemo(() => rules().slice(0, maxRuleRender()))
2023-08-28 22:13:48 +08:00
onMount(updateRules)
2023-08-28 22:13:48 +08:00
2023-09-05 16:19:14 +08:00
const { map: updatingMap, setWithCallback: setUpdatingMap } =
2023-09-05 15:38:42 +08:00
useStringBooleanMap()
const [allProviderIsUpdating, setAllProviderIsUpdating] = createSignal(false)
const onUpdateProviderClick = (e: MouseEvent, name: string) => {
2023-09-05 15:38:42 +08:00
e.stopPropagation()
2023-09-05 16:19:14 +08:00
void setUpdatingMap(name, () => updateRuleProviderByName(name))
2023-09-02 17:42:13 +08:00
}
2023-08-28 22:13:48 +08:00
2023-09-05 15:38:42 +08:00
const onUpdateAllProviderClick = async (e: MouseEvent) => {
e.stopPropagation()
setAllProviderIsUpdating(true)
try {
await updateAllRuleProvider()
} catch {}
setAllProviderIsUpdating(false)
2023-09-02 17:42:13 +08:00
}
2023-08-28 22:13:48 +08:00
return (
<div
class={twMerge(
'flex w-full flex-col gap-4',
renderRulesAndProviderInTwoColumns() && 'flex-row',
)}
>
2023-09-02 17:42:13 +08:00
<div class="flex-1">
2023-09-02 00:15:19 +08:00
<h1 class="pb-4 text-lg font-semibold">{t('rules')}</h1>
2023-08-28 22:13:48 +08:00
2023-09-02 17:42:13 +08:00
<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>
2023-09-02 17:42:13 +08:00
<div class="text-xs text-slate-500">
{rule.type} :: {rule.proxy}
2023-08-28 22:13:48 +08:00
</div>
2023-09-02 17:42:13 +08:00
</div>
)}
</InfiniteScroll>
2023-08-28 22:13:48 +08:00
</div>
2023-09-02 17:42:13 +08:00
<Show when={rulesProviders().length > 0}>
<div class="flex-1">
2023-09-08 23:16:27 +08:00
<h1 class="flex items-center gap-2 pb-4 text-lg font-semibold">
2023-09-02 17:42:13 +08:00
{t('ruleProviders')}
<Button
2023-09-07 14:24:48 +08:00
class="btn-circle btn-sm"
2023-09-06 22:20:45 +08:00
disabled={allProviderIsUpdating()}
2023-09-02 17:42:13 +08:00
onClick={(e) => onUpdateAllProviderClick(e)}
>
2023-09-05 15:38:42 +08:00
<IconReload
2023-09-05 20:25:49 +08:00
class={twMerge(
allProviderIsUpdating() && 'animate-spin text-success',
)}
2023-09-05 15:38:42 +08:00
/>
</Button>
2023-09-02 17:42:13 +08:00
</h1>
2023-08-28 22:13:48 +08:00
<For each={rulesProviders()}>
{(rulesProvider) => (
2023-09-02 17:42:13 +08:00
<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>
2023-09-02 17:42:13 +08:00
</div>
<div class="text-xs text-slate-500">
{rulesProvider.vehicleType} / {rulesProvider.behavior} /
{t('updated')} {formatTimeFromNow(rulesProvider.updatedAt)}
2023-08-28 22:13:48 +08:00
</div>
2023-09-05 21:39:04 +08:00
<Button
class="btn-circle btn-sm absolute right-2 top-2 mr-2 h-4"
2023-09-06 22:20:45 +08:00
disabled={updatingMap()[rulesProvider.name]}
2023-09-05 21:39:04 +08:00
onClick={(e) => onUpdateProviderClick(e, rulesProvider.name)}
>
<IconReload
class={twMerge(
updatingMap()[rulesProvider.name] &&
'animate-spin text-success',
)}
/>
</Button>
2023-08-28 22:13:48 +08:00
</div>
)}
</For>
</div>
2023-09-02 17:42:13 +08:00
</Show>
2023-08-28 22:13:48 +08:00
</div>
)
2023-08-24 04:20:53 +08:00
}