mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-26 07:24:10 +08:00
feat(proxies): overhaul the look of proxies page, drop renderInTwoColumns support
This commit is contained in:
parent
2e92dd20cf
commit
698362f1c7
@ -29,7 +29,7 @@
|
|||||||
"@solid-primitives/timer": "^1.3.10",
|
"@solid-primitives/timer": "^1.3.10",
|
||||||
"@solid-primitives/websocket": "^1.2.2",
|
"@solid-primitives/websocket": "^1.2.2",
|
||||||
"@solidjs/meta": "^0.29.4",
|
"@solidjs/meta": "^0.29.4",
|
||||||
"@solidjs/router": "^0.14.7",
|
"@solidjs/router": "^0.14.8",
|
||||||
"@tabler/icons-solidjs": "^3.19.0",
|
"@tabler/icons-solidjs": "^3.19.0",
|
||||||
"@tanstack/match-sorter-utils": "^8.19.4",
|
"@tanstack/match-sorter-utils": "^8.19.4",
|
||||||
"@tanstack/solid-table": "^8.20.5",
|
"@tanstack/solid-table": "^8.20.5",
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -53,8 +53,8 @@ importers:
|
|||||||
specifier: ^0.29.4
|
specifier: ^0.29.4
|
||||||
version: 0.29.4(solid-js@1.9.2)
|
version: 0.29.4(solid-js@1.9.2)
|
||||||
'@solidjs/router':
|
'@solidjs/router':
|
||||||
specifier: ^0.14.7
|
specifier: ^0.14.8
|
||||||
version: 0.14.7(solid-js@1.9.2)
|
version: 0.14.8(solid-js@1.9.2)
|
||||||
'@tabler/icons-solidjs':
|
'@tabler/icons-solidjs':
|
||||||
specifier: ^3.19.0
|
specifier: ^3.19.0
|
||||||
version: 3.19.0(solid-js@1.9.2)
|
version: 3.19.0(solid-js@1.9.2)
|
||||||
@ -1984,10 +1984,10 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
solid-js: '>=1.8.4'
|
solid-js: '>=1.8.4'
|
||||||
|
|
||||||
'@solidjs/router@0.14.7':
|
'@solidjs/router@0.14.8':
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
integrity: sha512-agLf8AUz5XnW6+F64a4Iq+QQQobI5zGHQ/gUYd/WHSwcbnFpavbsiwRLob3YhWMXVX3sQyn4ekUN+uchMCRupw==,
|
integrity: sha512-S+rD5Twp0820cM03wEIYtb7/4KN7Cfr3BP+qPIqb7IXO/SZ72tWqHEMQsmcjDbr4yVfpA+5Sq0Y+xcq09y1gQA==,
|
||||||
}
|
}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
solid-js: ^1.8.6
|
solid-js: ^1.8.6
|
||||||
@ -7577,7 +7577,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
solid-js: 1.9.2
|
solid-js: 1.9.2
|
||||||
|
|
||||||
'@solidjs/router@0.14.7(solid-js@1.9.2)':
|
'@solidjs/router@0.14.8(solid-js@1.9.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
solid-js: 1.9.2
|
solid-js: 1.9.2
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ interface ButtonWithoutIconProps extends ButtonBaseProps {
|
|||||||
export const Button: ParentComponent<
|
export const Button: ParentComponent<
|
||||||
ButtonWithIconProps | ButtonWithoutIconProps
|
ButtonWithIconProps | ButtonWithoutIconProps
|
||||||
> = (props) => {
|
> = (props) => {
|
||||||
|
// @ts-expect-error Expression produces a union type that is too complex to represent
|
||||||
const [local, others] = splitProps(props, ['class', 'loading', 'icon'])
|
const [local, others] = splitProps(props, ['class', 'loading', 'icon'])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import type { JSX, ParentComponent } from 'solid-js'
|
import type { JSX, ParentComponent } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { renderProxiesInTwoColumns } from '~/signals'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: JSX.Element
|
title: JSX.Element
|
||||||
@ -25,14 +24,6 @@ export const Collapse: ParentComponent<Props> = (props) => {
|
|||||||
return props.isOpen ? openedClassName : closedClassName
|
return props.isOpen ? openedClassName : closedClassName
|
||||||
}
|
}
|
||||||
|
|
||||||
const gridStyle = createMemo(() => {
|
|
||||||
if (renderProxiesInTwoColumns()) {
|
|
||||||
return 'lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5'
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'sm:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 2xl:grid-cols-10'
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
@ -50,8 +41,7 @@ export const Collapse: ParentComponent<Props> = (props) => {
|
|||||||
<div
|
<div
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
getCollapseContentClassName(),
|
getCollapseContentClassName(),
|
||||||
gridStyle(),
|
'collapse-content grid grid-cols-1 gap-2 transition-opacity duration-1000 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5',
|
||||||
'collapse-content grid grid-cols-2 gap-2 transition-opacity duration-1000',
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Show when={props.isOpen}>{children(() => props.children)()}</Show>
|
<Show when={props.isOpen}>{children(() => props.children)()}</Show>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import { useProxies } from '~/signals'
|
|
||||||
|
|
||||||
export const IPv6Support = (props: { name?: string }) => {
|
|
||||||
const { getNowProxyNodeName, proxyIPv6SupportMap } = useProxies()
|
|
||||||
|
|
||||||
const support = createMemo(() => {
|
|
||||||
return proxyIPv6SupportMap()[getNowProxyNodeName(props.name || '')]
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Show when={support()}>
|
|
||||||
<span class={`text-xs`}>IPv6</span>
|
|
||||||
</Show>
|
|
||||||
)
|
|
||||||
}
|
|
@ -11,7 +11,6 @@ import {
|
|||||||
latencyTestTimeoutDuration,
|
latencyTestTimeoutDuration,
|
||||||
proxiesOrderingType,
|
proxiesOrderingType,
|
||||||
proxiesPreviewType,
|
proxiesPreviewType,
|
||||||
renderProxiesInTwoColumns,
|
|
||||||
setAutoCloseConns,
|
setAutoCloseConns,
|
||||||
setHideUnAvailableProxies,
|
setHideUnAvailableProxies,
|
||||||
setIconHeight,
|
setIconHeight,
|
||||||
@ -19,7 +18,6 @@ import {
|
|||||||
setLatencyTestTimeoutDuration,
|
setLatencyTestTimeoutDuration,
|
||||||
setProxiesOrderingType,
|
setProxiesOrderingType,
|
||||||
setProxiesPreviewType,
|
setProxiesPreviewType,
|
||||||
setRenderProxiesInTwoColumns,
|
|
||||||
setUrlForLatencyTest,
|
setUrlForLatencyTest,
|
||||||
setUrlIPv6SupportTest,
|
setUrlIPv6SupportTest,
|
||||||
urlForIPv6SupportTest,
|
urlForIPv6SupportTest,
|
||||||
@ -107,7 +105,7 @@ export const ProxiesSettingsModal: Component<{
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ConfigTitle withDivider>{t('hideUnAvailableProxies')}</ConfigTitle>
|
<ConfigTitle withDivider>{t('hideUnavailableProxies')}</ConfigTitle>
|
||||||
|
|
||||||
<div class="flex w-full justify-center">
|
<div class="flex w-full justify-center">
|
||||||
<input
|
<input
|
||||||
@ -119,19 +117,6 @@ export const ProxiesSettingsModal: Component<{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<ConfigTitle withDivider>{t('renderInTwoColumns')}</ConfigTitle>
|
|
||||||
|
|
||||||
<div class="flex w-full justify-center">
|
|
||||||
<input
|
|
||||||
class="toggle"
|
|
||||||
type="checkbox"
|
|
||||||
checked={renderProxiesInTwoColumns()}
|
|
||||||
onChange={(e) => setRenderProxiesInTwoColumns(e.target.checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ConfigTitle withDivider>{t('proxiesPreviewType')}</ConfigTitle>
|
<ConfigTitle withDivider>{t('proxiesPreviewType')}</ConfigTitle>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button, IPv6Support, Latency } from '~/components'
|
import { Button, Latency } from '~/components'
|
||||||
import { filterSpecialProxyType, formatProxyType } from '~/helpers'
|
import { filterSpecialProxyType, formatProxyType } from '~/helpers'
|
||||||
import { useProxies } from '~/signals'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
@ -9,10 +9,19 @@ export const ProxyNodeCard = (props: {
|
|||||||
isSelected?: boolean
|
isSelected?: boolean
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
}) => {
|
}) => {
|
||||||
const { proxyLatencyTest, proxyLatencyTestingMap } = useProxies()
|
|
||||||
const { proxyName, isSelected, onClick } = props
|
const { proxyName, isSelected, onClick } = props
|
||||||
const { proxyNodeMap } = useProxies()
|
const {
|
||||||
|
getNowProxyNodeName,
|
||||||
|
proxyIPv6SupportMap,
|
||||||
|
proxyNodeMap,
|
||||||
|
proxyLatencyTest,
|
||||||
|
proxyLatencyTestingMap,
|
||||||
|
} = useProxies()
|
||||||
|
const supportIPv6 = createMemo(
|
||||||
|
() => proxyIPv6SupportMap()[getNowProxyNodeName(props.proxyName || '')],
|
||||||
|
)
|
||||||
const proxyNode = createMemo(() => proxyNodeMap()[proxyName])
|
const proxyNode = createMemo(() => proxyNodeMap()[proxyName])
|
||||||
|
|
||||||
const specialType = () =>
|
const specialType = () =>
|
||||||
filterSpecialProxyType(proxyNode()?.type)
|
filterSpecialProxyType(proxyNode()?.type)
|
||||||
? proxyNode()?.xudp
|
? proxyNode()?.xudp
|
||||||
@ -25,55 +34,61 @@ export const ProxyNodeCard = (props: {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
'border-neutral-focus card card-bordered tooltip-bottom flex flex-col justify-between gap-1 bg-neutral p-2 text-neutral-content',
|
'card tooltip card-compact tooltip-accent bg-neutral text-neutral-content',
|
||||||
isSelected &&
|
isSelected &&
|
||||||
'bg-gradient-to-br from-primary to-secondary text-primary-content',
|
'bg-gradient-to-l from-primary to-secondary text-primary-content',
|
||||||
onClick && 'cursor-pointer',
|
onClick && 'cursor-pointer',
|
||||||
)}
|
)}
|
||||||
|
data-tip={proxyName}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
title={proxyName}
|
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="card-body">
|
||||||
<span class="break-all text-left text-sm">{proxyName}</span>
|
<span class="card-title truncate text-sm">{proxyName}</span>
|
||||||
|
|
||||||
<span class="flex items-center gap-1">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<IPv6Support name={props.proxyName} />
|
<div class="flex items-center gap-2">
|
||||||
<Button
|
<Show when={specialType()}>
|
||||||
class="btn-circle btn-ghost h-auto min-h-0 w-auto"
|
<div class="badge badge-primary badge-sm font-bold uppercase">
|
||||||
icon={
|
{formatProxyType(proxyNode()?.type)}
|
||||||
<IconBrandSpeedtest
|
</div>
|
||||||
size={20}
|
|
||||||
class={twMerge(
|
|
||||||
proxyLatencyTestingMap()[proxyName] &&
|
|
||||||
'animate-pulse text-success',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
|
|
||||||
void proxyLatencyTest(proxyName, proxyNode().provider)
|
<Show when={specialType()}>
|
||||||
}}
|
<div class="badge badge-secondary badge-sm">
|
||||||
/>
|
{specialType()}
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</Show>
|
||||||
|
</Show>
|
||||||
|
|
||||||
<div class="flex items-center justify-between gap-1">
|
<Show when={supportIPv6()}>
|
||||||
<div
|
<div class="badge badge-accent badge-sm">IPv6</div>
|
||||||
class={twMerge(
|
</Show>
|
||||||
'text-xs text-slate-500',
|
</div>
|
||||||
isSelected && 'text-primary-content',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{formatProxyType(proxyNode()?.type)}
|
|
||||||
|
|
||||||
<Show when={specialType()}>{` :: ${specialType()}`}</Show>
|
<div class="flex items-center gap-2">
|
||||||
|
<Latency
|
||||||
|
name={props.proxyName}
|
||||||
|
class={twMerge(isSelected && 'badge')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
class="btn-square btn-sm"
|
||||||
|
icon={
|
||||||
|
<IconBrandSpeedtest
|
||||||
|
class={twMerge(
|
||||||
|
'size-6',
|
||||||
|
proxyLatencyTestingMap()[proxyName] &&
|
||||||
|
'animate-pulse text-success',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
void proxyLatencyTest(proxyName, proxyNode().provider)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Latency
|
|
||||||
name={props.proxyName}
|
|
||||||
class={twMerge(isSelected && 'badge badge-sm px-1')}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import { createWindowSize } from '@solid-primitives/resize-observer'
|
|
||||||
import type { ParentComponent } from 'solid-js'
|
|
||||||
|
|
||||||
export const RenderInTwoColumns: ParentComponent = (props) => {
|
|
||||||
const resolvedChildren = children(() => props.children)
|
|
||||||
const windowSize = createWindowSize()
|
|
||||||
// 640 is sm size in default tailwindcss breakpoint
|
|
||||||
const showTwoColumns = createMemo(() => windowSize.width >= 640)
|
|
||||||
|
|
||||||
const leftColumns = createMemo(() =>
|
|
||||||
resolvedChildren.toArray().filter((_, index) => index % 2 === 0),
|
|
||||||
)
|
|
||||||
|
|
||||||
const rightColumns = createMemo(() =>
|
|
||||||
resolvedChildren.toArray().filter((_, index) => index % 2 === 1),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="flex flex-col gap-2 sm:flex-row">
|
|
||||||
<Show when={showTwoColumns()} fallback={props.children}>
|
|
||||||
<div class="flex flex-1 flex-col gap-2">{leftColumns()}</div>
|
|
||||||
<div class="flex flex-1 flex-col gap-2">{rightColumns()}</div>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ export * from './ConfigTitle'
|
|||||||
export * from './ConnectionsSettingsModal'
|
export * from './ConnectionsSettingsModal'
|
||||||
export * from './ConnectionsTableDetailsModal'
|
export * from './ConnectionsTableDetailsModal'
|
||||||
export * from './Header'
|
export * from './Header'
|
||||||
export * from './IPv6Support'
|
|
||||||
export * from './Latency'
|
export * from './Latency'
|
||||||
export * from './LogoText'
|
export * from './LogoText'
|
||||||
export * from './LogsSettingsModal'
|
export * from './LogsSettingsModal'
|
||||||
@ -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 './RenderInTwoColumns'
|
|
||||||
export * from './SubscriptionInfo'
|
export * from './SubscriptionInfo'
|
||||||
|
@ -47,15 +47,14 @@ export default {
|
|||||||
bar: 'Bar',
|
bar: 'Bar',
|
||||||
auto: 'Auto',
|
auto: 'Auto',
|
||||||
off: 'Off',
|
off: 'Off',
|
||||||
proxiesPreviewType: 'Proxies preview type',
|
proxiesPreviewType: 'Proxies Preview Type',
|
||||||
urlForIPv6SupportTest: 'URL for IPv6 support test',
|
urlForIPv6SupportTest: 'URL for IPv6 Support Test',
|
||||||
urlForLatencyTest: 'URL for latency test',
|
urlForLatencyTest: 'URL for Latency Test',
|
||||||
autoCloseConns: 'Automatically Close connections',
|
autoCloseConns: 'Automatically Close Connections',
|
||||||
useTwemoji: 'Use Twemoji Mozilla Font',
|
useTwemoji: 'Use Twemoji Mozilla Font',
|
||||||
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 in two columns',
|
|
||||||
updateGEODatabases: 'Update GEO Databases',
|
updateGEODatabases: 'Update GEO Databases',
|
||||||
restartCore: 'Restart Core',
|
restartCore: 'Restart Core',
|
||||||
upgradeCore: 'Upgrade Core',
|
upgradeCore: 'Upgrade Core',
|
||||||
@ -95,7 +94,7 @@ export default {
|
|||||||
active: 'Active',
|
active: 'Active',
|
||||||
closed: 'Closed',
|
closed: 'Closed',
|
||||||
sort: 'Sort',
|
sort: 'Sort',
|
||||||
hideUnAvailableProxies: 'Hide UnAvailable Proxies',
|
hideUnavailableProxies: 'Hide Unavailable Proxies',
|
||||||
reloadConfig: 'Reload Config',
|
reloadConfig: 'Reload Config',
|
||||||
flushFakeIP: 'Flush Fake-IP',
|
flushFakeIP: 'Flush Fake-IP',
|
||||||
tagClientSourceIPWithName: 'Tag Client Source IP With Name',
|
tagClientSourceIPWithName: 'Tag Client Source IP With Name',
|
||||||
|
@ -57,7 +57,6 @@ export default {
|
|||||||
autoSwitchTheme: '自动切换主题',
|
autoSwitchTheme: '自动切换主题',
|
||||||
favDayTheme: '浅色主题偏好',
|
favDayTheme: '浅色主题偏好',
|
||||||
favNightTheme: '深色主题偏好',
|
favNightTheme: '深色主题偏好',
|
||||||
renderInTwoColumns: '双列渲染',
|
|
||||||
updateGEODatabases: '更新 GEO 数据库',
|
updateGEODatabases: '更新 GEO 数据库',
|
||||||
restartCore: '重启核心',
|
restartCore: '重启核心',
|
||||||
upgradeCore: '更新核心',
|
upgradeCore: '更新核心',
|
||||||
@ -97,7 +96,7 @@ export default {
|
|||||||
active: '活动',
|
active: '活动',
|
||||||
closed: '已关闭',
|
closed: '已关闭',
|
||||||
sort: '排序',
|
sort: '排序',
|
||||||
hideUnAvailableProxies: '隐藏不可用节点',
|
hideUnavailableProxies: '隐藏不可用节点',
|
||||||
reloadConfig: '重载配置',
|
reloadConfig: '重载配置',
|
||||||
flushFakeIP: '清空 Fake-IP',
|
flushFakeIP: '清空 Fake-IP',
|
||||||
tagClientSourceIPWithName: '为客户端源 IP 地址添加名称标记',
|
tagClientSourceIPWithName: '为客户端源 IP 地址添加名称标记',
|
||||||
|
@ -27,7 +27,6 @@ import {
|
|||||||
iconHeight,
|
iconHeight,
|
||||||
iconMarginRight,
|
iconMarginRight,
|
||||||
proxiesOrderingType,
|
proxiesOrderingType,
|
||||||
renderProxiesInTwoColumns,
|
|
||||||
useConnections,
|
useConnections,
|
||||||
useProxies,
|
useProxies,
|
||||||
} from '~/signals'
|
} from '~/signals'
|
||||||
@ -174,14 +173,7 @@ 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}>
|
||||||
<div
|
<div class="flex flex-col gap-2">
|
||||||
class={twMerge(
|
|
||||||
'grid grid-cols-1 place-items-start gap-2',
|
|
||||||
renderProxiesInTwoColumns()
|
|
||||||
? 'sm:grid-cols-2'
|
|
||||||
: 'sm:grid-cols-1',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<For each={renderProxies()}>
|
<For each={renderProxies()}>
|
||||||
{(proxyGroup) => {
|
{(proxyGroup) => {
|
||||||
const sortedProxyNames = createMemo(() =>
|
const sortedProxyNames = createMemo(() =>
|
||||||
@ -195,7 +187,7 @@ export default () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const title = (
|
const title = (
|
||||||
<>
|
<div class="space-y-2">
|
||||||
<div class="flex items-center justify-between pr-8">
|
<div class="flex items-center justify-between pr-8">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<Show when={proxyGroup.icon}>
|
<Show when={proxyGroup.icon}>
|
||||||
@ -233,18 +225,21 @@ export default () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between text-sm text-slate-500">
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||||
<span>
|
<div class="badge badge-primary badge-sm">
|
||||||
{proxyGroup.type}{' '}
|
<span class="font-bold">{proxyGroup.type}</span>
|
||||||
{proxyGroup.now?.length > 0 &&
|
|
||||||
` :: ${proxyGroup.now}`}
|
<Show when={proxyGroup.now?.length > 0}>
|
||||||
</span>
|
<pre>{` :: ${proxyGroup.now}`}</pre>
|
||||||
<span>
|
</Show>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="badge badge-secondary badge-sm">
|
||||||
{byteSize(
|
{byteSize(
|
||||||
speedGroupByName()[proxyGroup.name] ?? 0,
|
speedGroupByName()[proxyGroup.name] ?? 0,
|
||||||
).toString()}
|
).toString()}
|
||||||
/s
|
/s
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={!collapsedMap()[proxyGroup.name]}>
|
<Show when={!collapsedMap()[proxyGroup.name]}>
|
||||||
@ -253,7 +248,7 @@ export default () => {
|
|||||||
now={proxyGroup.now}
|
now={proxyGroup.now}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
</>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -283,14 +278,7 @@ export default () => {
|
|||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={activeTab() === ActiveTab.proxyProviders}>
|
<Show when={activeTab() === ActiveTab.proxyProviders}>
|
||||||
<div
|
<div class="flex flex-col gap-2">
|
||||||
class={twMerge(
|
|
||||||
'grid grid-cols-1 place-items-start gap-2',
|
|
||||||
renderProxiesInTwoColumns()
|
|
||||||
? 'sm:grid-cols-2'
|
|
||||||
: 'sm:grid-cols-1',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<For each={proxyProviders()}>
|
<For each={proxyProviders()}>
|
||||||
{(proxyProvider) => {
|
{(proxyProvider) => {
|
||||||
const sortedProxyNames = createMemo(() =>
|
const sortedProxyNames = createMemo(() =>
|
||||||
@ -305,6 +293,7 @@ export default () => {
|
|||||||
<div class="flex items-center justify-between pr-8">
|
<div class="flex items-center justify-between pr-8">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span>{proxyProvider.name}</span>
|
<span>{proxyProvider.name}</span>
|
||||||
|
|
||||||
<div class="badge badge-sm">
|
<div class="badge badge-sm">
|
||||||
{proxyProvider.proxies.length}
|
{proxyProvider.proxies.length}
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,12 +31,6 @@ export const [hideUnAvailableProxies, setHideUnAvailableProxies] =
|
|||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const [renderProxiesInTwoColumns, setRenderProxiesInTwoColumns] =
|
|
||||||
makePersisted(createSignal(true), {
|
|
||||||
name: 'renderProxiesInTwoColumns',
|
|
||||||
storage: localStorage,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const [urlForLatencyTest, setUrlForLatencyTest] = makePersisted(
|
export const [urlForLatencyTest, setUrlForLatencyTest] = makePersisted(
|
||||||
createSignal('https://www.gstatic.com/generate_204'),
|
createSignal('https://www.gstatic.com/generate_204'),
|
||||||
{ name: 'urlForLatencyTest', storage: localStorage },
|
{ name: 'urlForLatencyTest', storage: localStorage },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user