feat: drop ForTwoColumns renderer

This commit is contained in:
kunish 2023-09-16 01:00:30 +08:00
parent 6c5662a7a9
commit 353b5ebff3
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
8 changed files with 144 additions and 263 deletions

View File

@ -1,6 +1,5 @@
import { JSX, ParentComponent, Show, createMemo } from 'solid-js' import { JSX, ParentComponent, Show } from 'solid-js'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { proxiesRenderInTwoColumns } from '~/signals'
type Props = { type Props = {
title: JSX.Element title: JSX.Element
@ -26,19 +25,11 @@ export const Collapse: ParentComponent<Props> = (props) => {
return props.isOpen ? openedClassName : closedClassName return props.isOpen ? openedClassName : closedClassName
} }
const mediaQueryClassName = createMemo(() => {
if (proxiesRenderInTwoColumns()) {
return 'lg:grid-cols-3 xl:grid-cols-4'
} else {
return 'sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7'
}
})
return ( return (
<div <div
class={twMerge( class={twMerge(
getCollapseClassName(), getCollapseClassName(),
'collapse collapse-arrow mb-2 select-none border-secondary bg-base-200', 'collapse collapse-arrow select-none border-secondary bg-base-200',
)} )}
> >
<div <div
@ -50,7 +41,6 @@ export const Collapse: ParentComponent<Props> = (props) => {
<div <div
class={twMerge( class={twMerge(
getCollapseContentClassName(), getCollapseContentClassName(),
mediaQueryClassName(),
'collapse-content grid grid-cols-2 gap-2 transition-opacity duration-1000', 'collapse-content grid grid-cols-2 gap-2 transition-opacity duration-1000',
)} )}
> >

View File

@ -1,25 +0,0 @@
import { createWindowSize } from '@solid-primitives/resize-observer'
import { JSX, Show, createMemo } from 'solid-js'
import { proxiesRenderInTwoColumns } from '~/signals'
export const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
const windowSize = createWindowSize()
const isShowTwoColumns = createMemo(
() => windowSize.width >= 640 && proxiesRenderInTwoColumns(),
) // 640 is sm size in daisyui
const leftColumns = createMemo(() =>
props.subChild.filter((_, index) => index % 2 === 0 || !isShowTwoColumns()),
)
const rightColumns = createMemo(() =>
props.subChild.filter((_, index) => index % 2 === 1),
)
return (
<div class="flex">
<div class="flex flex-1 flex-col">{leftColumns()}</div>
<Show when={isShowTwoColumns()}>
<div class="ml-2 flex flex-1 flex-col">{rightColumns()}</div>
</Show>
</div>
)
}

View File

@ -8,13 +8,11 @@ import {
latencyTestTimeoutDuration, latencyTestTimeoutDuration,
proxiesOrderingType, proxiesOrderingType,
proxiesPreviewType, proxiesPreviewType,
proxiesRenderInTwoColumns,
setAutoCloseConns, setAutoCloseConns,
setHideUnAvailableProxies, setHideUnAvailableProxies,
setLatencyTestTimeoutDuration, setLatencyTestTimeoutDuration,
setProxiesOrderingType, setProxiesOrderingType,
setProxiesPreviewType, setProxiesPreviewType,
setProxiesRenderInTwoColumns,
setUrlForLatencyTest, setUrlForLatencyTest,
urlForLatencyTest, urlForLatencyTest,
} from '~/signals' } from '~/signals'
@ -114,19 +112,6 @@ export const ProxiesSettingsModal = () => {
</For> </For>
</select> </select>
</div> </div>
<div>
<ConfigTitle withDivider>{t('renderInTwoColumns')}</ConfigTitle>
<div class="flex w-full justify-center">
<input
type="checkbox"
class="toggle"
checked={proxiesRenderInTwoColumns()}
onChange={(e) => setProxiesRenderInTwoColumns(e.target.checked)}
/>
</div>
</div>
</div> </div>
<form method="dialog" class="modal-backdrop"> <form method="dialog" class="modal-backdrop">

View File

@ -1,34 +0,0 @@
import { useI18n } from '@solid-primitives/i18n'
import { ConfigTitle } from '~/components'
import { MODAL } from '~/constants'
import { rulesRenderInTwoColumns, setRulesRenderInTwoColumns } from '~/signals'
export const RulesSettingsModal = () => {
const [t] = useI18n()
return (
<dialog
id={MODAL.RULES_SETTINGS}
class="modal modal-bottom sm:modal-middle"
>
<div class="modal-box flex flex-col gap-4">
<div>
<ConfigTitle withDivider>{t('renderInTwoColumns')}</ConfigTitle>
<div class="flex w-full justify-center">
<input
type="checkbox"
class="toggle"
checked={rulesRenderInTwoColumns()}
onChange={(e) => setRulesRenderInTwoColumns(e.target.checked)}
/>
</div>
</div>
</div>
<form method="dialog" class="modal-backdrop">
<button />
</form>
</dialog>
)
}

View File

@ -3,7 +3,6 @@ export * from './Collapse'
export * from './ConfigTitle' export * from './ConfigTitle'
export * from './ConnectionsSettingsModal' export * from './ConnectionsSettingsModal'
export * from './ConnectionsTableDetailsModal' export * from './ConnectionsTableDetailsModal'
export * from './ForTwoColumns'
export * from './Header' export * from './Header'
export * from './Latency' export * from './Latency'
export * from './LogoText' export * from './LogoText'
@ -14,5 +13,4 @@ export * from './ProxyNodeCard'
export * from './ProxyNodePreview' export * from './ProxyNodePreview'
export * from './ProxyPreviewBar' export * from './ProxyPreviewBar'
export * from './ProxyPreviewDots' export * from './ProxyPreviewDots'
export * from './RulesSettingsModal'
export * from './SubscriptionInfo' export * from './SubscriptionInfo'

View File

@ -9,7 +9,6 @@ import { twMerge } from 'tailwind-merge'
import { import {
Button, Button,
Collapse, Collapse,
ForTwoColumns,
ProxiesSettingsModal, ProxiesSettingsModal,
ProxyCardGroups, ProxyCardGroups,
ProxyNodePreview, ProxyNodePreview,
@ -152,154 +151,160 @@ export default () => {
<div class="flex-1 overflow-y-auto"> <div class="flex-1 overflow-y-auto">
<Show when={activeTab() === ActiveTab.proxies}> <Show when={activeTab() === ActiveTab.proxies}>
<ForTwoColumns <div class="grid grid-cols-1 place-items-start gap-2 sm:grid-cols-2">
subChild={proxies().map((proxy) => { <For each={proxies()}>
const sortedProxyNames = filterProxiesByAvailability( {(proxy) => {
sortProxiesByOrderingType( const sortedProxyNames = filterProxiesByAvailability(
proxy.all ?? [], sortProxiesByOrderingType(
proxy.all ?? [],
latencyMap(),
proxiesOrderingType(),
),
latencyMap(), latencyMap(),
proxiesOrderingType(), hideUnAvailableProxies(),
), )
latencyMap(),
hideUnAvailableProxies(),
)
const title = ( const title = (
<> <>
<div class="mr-8 flex items-center justify-between"> <div class="mr-8 flex items-center justify-between">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span>{proxy.name}</span> <span>{proxy.name}</span>
<div class="badge badge-sm">{proxy.all?.length}</div> <div class="badge badge-sm">{proxy.all?.length}</div>
</div>
<Button
class="btn-circle btn-sm"
disabled={latencyTestingMap()[proxy.name]}
onClick={(e) => onLatencyTestClick(e, proxy.name)}
>
<IconBrandSpeedtest
class={twMerge(
latencyTestingMap()[proxy.name] &&
'animate-pulse text-success',
)}
/>
</Button>
</div>
<div class="text-sm text-slate-500">
{proxy.type} {proxy.now?.length > 0 && ` :: ${proxy.now}`}
</div>
<Show when={!collapsedMap()[proxy.name]}>
<ProxyNodePreview
proxyNameList={sortedProxyNames}
now={proxy.now}
/>
</Show>
</>
)
return (
<Collapse
isOpen={collapsedMap()[proxy.name]}
title={title}
content={
<ProxyCardGroups
proxyNames={sortedProxyNames}
now={proxy.now}
onClick={(name) => {
void onProxyNodeClick(proxy, name)
}}
/>
}
onCollapse={(val) => setCollapsedMap(proxy.name, val)}
/>
)
})}
/>
</Show>
<Show when={activeTab() === ActiveTab.proxyProviders}>
<ForTwoColumns
subChild={proxyProviders().map((proxyProvider) => {
const sortedProxyNames = filterProxiesByAvailability(
sortProxiesByOrderingType(
proxyProvider.proxies.map((i) => i.name) ?? [],
latencyMap(),
proxiesOrderingType(),
),
latencyMap(),
hideUnAvailableProxies(),
)
const title = (
<>
<div class="mr-8 flex items-center justify-between">
<div class="flex items-center gap-2">
<span>{proxyProvider.name}</span>
<div class="badge badge-sm">
{proxyProvider.proxies.length}
</div> </div>
</div>
<div>
<Button
class="btn btn-circle btn-sm mr-2"
disabled={updatingMap()[proxyProvider.name]}
onClick={(e) =>
onUpdateProviderClick(e, proxyProvider.name)
}
>
<IconReload
class={twMerge(
updatingMap()[proxyProvider.name] &&
'animate-spin text-success',
)}
/>
</Button>
<Button <Button
class="btn btn-circle btn-sm" class="btn-circle btn-sm"
disabled={healthCheckingMap()[proxyProvider.name]} disabled={latencyTestingMap()[proxy.name]}
onClick={(e) => onClick={(e) => onLatencyTestClick(e, proxy.name)}
onHealthCheckClick(e, proxyProvider.name)
}
> >
<IconBrandSpeedtest <IconBrandSpeedtest
class={twMerge( class={twMerge(
healthCheckingMap()[proxyProvider.name] && latencyTestingMap()[proxy.name] &&
'animate-pulse text-success', 'animate-pulse text-success',
)} )}
/> />
</Button> </Button>
</div> </div>
</div>
<SubscriptionInfo <div class="text-sm text-slate-500">
subscriptionInfo={proxyProvider.subscriptionInfo} {proxy.type} {proxy.now?.length > 0 && ` :: ${proxy.now}`}
</div>
<Show when={!collapsedMap()[proxy.name]}>
<ProxyNodePreview
proxyNameList={sortedProxyNames}
now={proxy.now}
/>
</Show>
</>
)
return (
<Collapse
isOpen={collapsedMap()[proxy.name]}
title={title}
content={
<ProxyCardGroups
proxyNames={sortedProxyNames}
now={proxy.now}
onClick={(name) => {
void onProxyNodeClick(proxy, name)
}}
/>
}
onCollapse={(val) => setCollapsedMap(proxy.name, val)}
/> />
)
}}
</For>
</div>
</Show>
<div class="text-sm text-slate-500"> <Show when={activeTab() === ActiveTab.proxyProviders}>
{proxyProvider.vehicleType} :: {t('updated')}{' '} <div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
{formatTimeFromNow(proxyProvider.updatedAt)} <For each={proxyProviders()}>
</div> {(proxyProvider) => {
const sortedProxyNames = filterProxiesByAvailability(
sortProxiesByOrderingType(
proxyProvider.proxies.map((i) => i.name) ?? [],
latencyMap(),
proxiesOrderingType(),
),
latencyMap(),
hideUnAvailableProxies(),
)
<Show when={!collapsedMap()[proxyProvider.name]}> const title = (
<ProxyNodePreview proxyNameList={sortedProxyNames} /> <>
</Show> <div class="mr-8 flex items-center justify-between">
</> <div class="flex items-center gap-2">
) <span>{proxyProvider.name}</span>
<div class="badge badge-sm">
{proxyProvider.proxies.length}
</div>
</div>
return ( <div>
<Collapse <Button
isOpen={collapsedMap()[proxyProvider.name]} class="btn btn-circle btn-sm mr-2"
title={title} disabled={updatingMap()[proxyProvider.name]}
content={<ProxyCardGroups proxyNames={sortedProxyNames} />} onClick={(e) =>
onCollapse={(val) => setCollapsedMap(proxyProvider.name, val)} onUpdateProviderClick(e, proxyProvider.name)
/> }
) >
})} <IconReload
/> class={twMerge(
updatingMap()[proxyProvider.name] &&
'animate-spin text-success',
)}
/>
</Button>
<Button
class="btn btn-circle btn-sm"
disabled={healthCheckingMap()[proxyProvider.name]}
onClick={(e) =>
onHealthCheckClick(e, proxyProvider.name)
}
>
<IconBrandSpeedtest
class={twMerge(
healthCheckingMap()[proxyProvider.name] &&
'animate-pulse text-success',
)}
/>
</Button>
</div>
</div>
<SubscriptionInfo
subscriptionInfo={proxyProvider.subscriptionInfo}
/>
<div class="text-sm text-slate-500">
{proxyProvider.vehicleType} :: {t('updated')}{' '}
{formatTimeFromNow(proxyProvider.updatedAt)}
</div>
<Show when={!collapsedMap()[proxyProvider.name]}>
<ProxyNodePreview proxyNameList={sortedProxyNames} />
</Show>
</>
)
return (
<Collapse
isOpen={collapsedMap()[proxyProvider.name]}
title={title}
content={<ProxyCardGroups proxyNames={sortedProxyNames} />}
onCollapse={(val) =>
setCollapsedMap(proxyProvider.name, val)
}
/>
)
}}
</For>
</div>
</Show> </Show>
</div> </div>

View File

@ -1,11 +1,10 @@
import { useI18n } from '@solid-primitives/i18n' import { useI18n } from '@solid-primitives/i18n'
import { IconReload, IconSettings } from '@tabler/icons-solidjs' import { IconReload } from '@tabler/icons-solidjs'
import { For, Show, createSignal, onMount } from 'solid-js' import { For, Show, createSignal, onMount } from 'solid-js'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { Button, RulesSettingsModal } from '~/components' import { Button } from '~/components'
import { MODAL } from '~/constants'
import { formatTimeFromNow, useStringBooleanMap } from '~/helpers' import { formatTimeFromNow, useStringBooleanMap } from '~/helpers'
import { rulesRenderInTwoColumns, useRules } from '~/signals' import { useRules } from '~/signals'
enum ActiveTab { enum ActiveTab {
ruleProviders = 'ruleProviders', ruleProviders = 'ruleProviders',
@ -60,7 +59,7 @@ export default () => {
return ( return (
<div class="flex h-full flex-col gap-2"> <div class="flex h-full flex-col gap-2">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<div class="tabs-boxed tabs gap-2"> <div class="tabs tabs-boxed gap-2">
<For each={tabs()}> <For each={tabs()}>
{(tab) => ( {(tab) => (
<button <button
@ -90,31 +89,11 @@ export default () => {
/> />
</Button> </Button>
</Show> </Show>
<div class="ml-auto">
<Button
class="btn-circle btn-sm sm:btn-md"
onClick={() => {
const modal = document.querySelector(
`#${MODAL.RULES_SETTINGS}`,
) as HTMLDialogElement | null
modal?.showModal()
}}
>
<IconSettings />
</Button>
</div>
</div> </div>
<div class="flex-1 overflow-y-auto"> <div class="flex-1 overflow-y-auto">
<Show when={activeTab() === ActiveTab.rules}> <Show when={activeTab() === ActiveTab.rules}>
<div <div class="grid gap-2">
class="grid gap-2"
classList={{
'grid-cols-2': rulesRenderInTwoColumns(),
}}
>
<For each={rules()}> <For each={rules()}>
{(rule) => ( {(rule) => (
<div class="card card-bordered card-compact bg-base-200 p-4"> <div class="card card-bordered card-compact bg-base-200 p-4">
@ -136,12 +115,7 @@ export default () => {
</Show> </Show>
<Show when={activeTab() === ActiveTab.ruleProviders}> <Show when={activeTab() === ActiveTab.ruleProviders}>
<div <div class="grid gap-2">
class="grid gap-2"
classList={{
'grid-cols-2': rulesRenderInTwoColumns(),
}}
>
<For each={ruleProviders()}> <For each={ruleProviders()}>
{(ruleProvider) => ( {(ruleProvider) => (
<div class="card card-bordered card-compact bg-base-200 p-4"> <div class="card card-bordered card-compact bg-base-200 p-4">
@ -173,8 +147,6 @@ export default () => {
</div> </div>
</Show> </Show>
</div> </div>
<RulesSettingsModal />
</div> </div>
) )
} }

View File

@ -51,16 +51,6 @@ export const [favNightTheme, setFavNightTheme] = makePersisted(
createSignal('night'), createSignal('night'),
{ name: 'favNightTheme', storage: localStorage }, { name: 'favNightTheme', storage: localStorage },
) )
export const [proxiesRenderInTwoColumns, setProxiesRenderInTwoColumns] =
makePersisted(createSignal(true), {
name: 'proxiesRenderInTwoColumns',
storage: localStorage,
})
export const [rulesRenderInTwoColumns, setRulesRenderInTwoColumns] =
makePersisted(createSignal(true), {
name: 'rulesRenderInTwoColumns',
storage: localStorage,
})
export const [connectionsTableSize, setConnectionsTableSize] = makePersisted( export const [connectionsTableSize, setConnectionsTableSize] = makePersisted(
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS), createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
{ name: 'connectionsTableSize', storage: localStorage }, { name: 'connectionsTableSize', storage: localStorage },