feat: make some changes in response to community suggestions

- allow to change the size of the tables (xs, sm, md, lg)
- move switch endpoint button to config page
- move proxy group preview options into select component
This commit is contained in:
kunish 2023-09-05 20:53:00 +08:00
parent 6575e73439
commit 90ecb86603
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
10 changed files with 147 additions and 91 deletions

View File

@ -78,7 +78,7 @@ services:
image: ghcr.io/metacubex/metacubexd image: ghcr.io/metacubex/metacubexd
restart: always restart: always
ports: ports:
- 80:80 - '80:80'
# optional # optional
meta: meta:

View File

@ -6,7 +6,7 @@ services:
image: ghcr.io/metacubex/metacubexd image: ghcr.io/metacubex/metacubexd
restart: always restart: always
ports: ports:
- 80:80 - '80:80'
# optional # optional
meta: meta:

View File

@ -1,7 +1,6 @@
import { useI18n } from '@solid-primitives/i18n' import { useI18n } from '@solid-primitives/i18n'
import { A, useLocation, useNavigate } from '@solidjs/router' import { A, useLocation } from '@solidjs/router'
import { import {
IconArrowsExchange,
IconFileStack, IconFileStack,
IconGlobe, IconGlobe,
IconGlobeFilled, IconGlobeFilled,
@ -17,12 +16,7 @@ import { For, ParentComponent, Show, createMemo, createSignal } from 'solid-js'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { Button } from '~/components' import { Button } from '~/components'
import { LANG, ROUTES, themes } from '~/constants' import { LANG, ROUTES, themes } from '~/constants'
import { import { renderProxiesInSamePage, setCurTheme, useProxies } from '~/signals'
renderProxiesInSamePage,
setCurTheme,
setSelectedEndpoint,
useProxies,
} from '~/signals'
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({ const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
href, href,
@ -118,15 +112,9 @@ export const Header = () => {
}) })
const location = useLocation() const location = useLocation()
const navigate = useNavigate()
const [openedDrawer, setOpenedDrawer] = createSignal(false) const [openedDrawer, setOpenedDrawer] = createSignal(false)
const onSwitchEndpointClick = () => {
setSelectedEndpoint('')
navigate(ROUTES.Setup)
}
return ( return (
<ul class="navbar rounded-box sticky inset-x-0 top-2 z-50 mx-2 mt-2 flex w-auto items-center justify-center bg-base-300 px-4"> <ul class="navbar rounded-box sticky inset-x-0 top-2 z-50 mx-2 mt-2 flex w-auto items-center justify-center bg-base-300 px-4">
<div class="navbar-start gap-4"> <div class="navbar-start gap-4">
@ -200,13 +188,6 @@ export const Header = () => {
</Button> </Button>
<ThemeSwitcher /> <ThemeSwitcher />
<Button
class="btn-circle btn-secondary btn-sm"
onClick={onSwitchEndpointClick}
>
<IconArrowsExchange />
</Button>
</div> </div>
</div> </div>
</ul> </ul>

View File

@ -135,3 +135,10 @@ export const CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY = {
), ),
[CONNECTIONS_TABLE_ACCESSOR_KEY.ID]: false, [CONNECTIONS_TABLE_ACCESSOR_KEY.ID]: false,
} }
export enum TAILWINDCSS_SIZE {
XS = 'xs',
SM = 'sm',
MD = 'md',
LG = 'lg',
}

View File

@ -59,4 +59,10 @@ 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',
tableSize: 'Table size',
xs: 'Extra small size',
sm: 'Small size',
md: 'Normal size',
lg: 'Large size',
switchEndpoint: 'Switch Endpoint',
} }

View File

@ -59,4 +59,10 @@ export default {
ms: '毫秒', ms: '毫秒',
updated: '更新于', updated: '更新于',
renderProxiesInSamePage: '将代理和代理提供者显示在同一页', renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
tableSize: '表格大小',
xs: '超小尺寸',
sm: '小尺寸',
md: '正常尺寸',
lg: '超大尺寸',
switchEndpoint: '切换后端',
} }

View File

@ -1,12 +1,15 @@
import { createForm } from '@felte/solid' import { createForm } from '@felte/solid'
import { validator } from '@felte/validator-zod' import { validator } from '@felte/validator-zod'
import { useI18n } from '@solid-primitives/i18n' import { useI18n } from '@solid-primitives/i18n'
import { useNavigate } from '@solidjs/router'
import { For, Show, createSignal, onMount } from 'solid-js' import { For, Show, createSignal, onMount } from 'solid-js'
import { z } from 'zod' import { z } from 'zod'
import { Button } from '~/components' import { Button } from '~/components'
import { import {
PROXIES_ORDERING_TYPE, PROXIES_ORDERING_TYPE,
PROXIES_PREVIEW_TYPE, PROXIES_PREVIEW_TYPE,
ROUTES,
TAILWINDCSS_SIZE,
themes, themes,
} from '~/constants' } from '~/constants'
import { import {
@ -27,8 +30,11 @@ import {
setProxiesPreviewType, setProxiesPreviewType,
setRenderInTwoColumn, setRenderInTwoColumn,
setRenderProxiesInSamePage, setRenderProxiesInSamePage,
setSelectedEndpoint,
setTableSize,
setTwemoji, setTwemoji,
setUrlForLatencyTest, setUrlForLatencyTest,
tableSize,
urlForLatencyTest, urlForLatencyTest,
useRequest, useRequest,
useTwemoji, useTwemoji,
@ -165,7 +171,7 @@ const ConfigForm = () => {
} }
return ( return (
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-4">
<form class="contents" use:form={form}> <form class="contents" use:form={form}>
<For each={portsList}> <For each={portsList}>
{(item) => ( {(item) => (
@ -198,12 +204,39 @@ const ConfigForm = () => {
{t('restartCore')} {t('restartCore')}
</Button> </Button>
</div> </div>
<div class="flex flex-col">
<div class="pb-4 text-lg font-semibold">{t('urlForLatencyTest')}</div>
<input
class="w-100 input input-bordered max-w-md"
value={urlForLatencyTest()}
onChange={(e) => setUrlForLatencyTest(e.target.value)}
/>
</div>
<div>
<div class="pb-4 text-lg font-semibold">{t('autoCloseConns')}</div>
<input
class="toggle"
type="checkbox"
checked={autoCloseConns()}
onChange={(e) => setAutoCloseConns(e.target.checked)}
/>
</div>
</div> </div>
) )
} }
const ConfigForXd = () => { const ConfigForXd = () => {
const [t] = useI18n() const [t] = useI18n()
const navigate = useNavigate()
const onSwitchEndpointClick = () => {
setSelectedEndpoint('')
navigate(ROUTES.Setup)
}
return ( return (
<div class="grid gap-4"> <div class="grid gap-4">
@ -283,61 +316,6 @@ const ConfigForXd = () => {
</div> </div>
</Show> </Show>
<div>
<div class="pb-4 text-lg font-semibold">{t('proxiesPreviewType')}</div>
<div class="flex items-center gap-4">
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
{(value) => (
<label class="flex items-center gap-2">
<span>{t(value)}</span>
<input
class="radio"
aria-label={value}
type="radio"
checked={value === proxiesPreviewType()}
onChange={() => setProxiesPreviewType(value)}
/>
</label>
)}
</For>
</div>
</div>
<div>
<div class="pb-4 text-lg font-semibold">{t('proxiesSorting')}</div>
<div class="flex flex-col gap-4">
<For each={Object.values(PROXIES_ORDERING_TYPE)}>
{(value) => (
<label class="flex items-center gap-2">
<span>{t(value)}</span>
<input
class="radio"
aria-label={value}
type="radio"
checked={value === proxiesOrderingType()}
onChange={() => setProxiesOrderingType(value)}
/>
</label>
)}
</For>
</div>
</div>
<div>
<div class="pb-4 text-lg font-semibold">{t('autoCloseConns')}</div>
<input
class="toggle"
type="checkbox"
checked={autoCloseConns()}
onChange={(e) => setAutoCloseConns(e.target.checked)}
/>
</div>
<div> <div>
<div class="pb-4 text-lg font-semibold">{t('useTwemoji')}</div> <div class="pb-4 text-lg font-semibold">{t('useTwemoji')}</div>
@ -349,14 +327,58 @@ const ConfigForXd = () => {
/> />
</div> </div>
<div class="flex flex-col"> <div>
<div class="pb-4 text-lg font-semibold">{t('urlForLatencyTest')}</div> <div class="pb-4 text-lg font-semibold">{t('proxiesPreviewType')}</div>
<input <select
class="w-100 input input-bordered max-w-md" class="select select-bordered w-full max-w-xs"
value={urlForLatencyTest()} value={proxiesPreviewType()}
onChange={(e) => setUrlForLatencyTest(e.target.value)} onChange={(e) =>
/> setProxiesPreviewType(e.target.value as PROXIES_PREVIEW_TYPE)
}
>
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
{(value) => <option value={value}>{t(value)}</option>}
</For>
</select>
</div>
<div>
<div class="pb-4 text-lg font-semibold">{t('proxiesSorting')}</div>
<select
class="select select-bordered w-full max-w-xs"
value={proxiesOrderingType()}
onChange={(e) =>
setProxiesOrderingType(e.target.value as PROXIES_ORDERING_TYPE)
}
>
<For each={Object.values(PROXIES_ORDERING_TYPE)}>
{(value) => (
<option class="flex items-center gap-2" value={value}>
{t(value)}
</option>
)}
</For>
</select>
</div>
<div>
<div class="pb-4 text-lg font-semibold">{t('tableSize')}</div>
<select
class="select select-bordered w-full max-w-xs"
value={tableSize()}
onChange={(e) => setTableSize(e.target.value as TAILWINDCSS_SIZE)}
>
<For each={Object.values(TAILWINDCSS_SIZE)}>
{(value) => <option value={value}>{t(value)}</option>}
</For>
</select>
</div>
<div>
<Button onClick={onSwitchEndpointClick}>{t('switchEndpoint')}</Button>
</div> </div>
</div> </div>
) )
@ -369,7 +391,7 @@ export default () => {
<ConfigForm /> <ConfigForm />
<ConfigForXd /> <ConfigForXd />
{import.meta.env.version} <kbd class="kbd">{import.meta.env.version}</kbd>
</div> </div>
) )
} }

View File

@ -28,9 +28,10 @@ import {
CONNECTIONS_TABLE_ACCESSOR_KEY, CONNECTIONS_TABLE_ACCESSOR_KEY,
CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER, CONNECTIONS_TABLE_INITIAL_COLUMN_ORDER,
CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY, CONNECTIONS_TABLE_INITIAL_COLUMN_VISIBILITY,
TAILWINDCSS_SIZE,
} from '~/constants' } from '~/constants'
import { formatTimeFromNow } from '~/helpers' import { formatTimeFromNow } from '~/helpers'
import { secret, useRequest, wsEndpointURL } from '~/signals' import { secret, tableSize, useRequest, wsEndpointURL } from '~/signals'
import type { Connection } from '~/types' import type { Connection } from '~/types'
type ConnectionWithSpeed = Connection & { type ConnectionWithSpeed = Connection & {
@ -234,6 +235,28 @@ export default () => {
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
}) })
const tableSizeClassName = () => {
const size = tableSize()
if (size === TAILWINDCSS_SIZE.XS) {
return 'table-xs'
}
if (size === TAILWINDCSS_SIZE.SM) {
return 'table-sm'
}
if (size === TAILWINDCSS_SIZE.MD) {
return 'table-md'
}
if (size === TAILWINDCSS_SIZE.LG) {
return 'table-lg'
}
return ''
}
return ( return (
<div class="flex h-full flex-col gap-4 overflow-y-auto p-1"> <div class="flex h-full flex-col gap-4 overflow-y-auto p-1">
<div class="flex w-full items-center gap-2"> <div class="flex w-full items-center gap-2">
@ -267,7 +290,12 @@ export default () => {
</div> </div>
<div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300"> <div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300">
<table class="table table-zebra table-xs relative rounded-none"> <table
class={twMerge(
tableSizeClassName(),
'table table-zebra relative rounded-none',
)}
>
<thead class="sticky top-0 z-10 h-8"> <thead class="sticky top-0 z-10 h-8">
<For each={table.getHeaderGroups()}> <For each={table.getHeaderGroups()}>
{(headerGroup) => ( {(headerGroup) => (

View File

@ -8,7 +8,8 @@ import {
getCoreRowModel, getCoreRowModel,
} from '@tanstack/solid-table' } from '@tanstack/solid-table'
import { For, createEffect, createSignal } from 'solid-js' import { For, createEffect, createSignal } from 'solid-js'
import { secret, wsEndpointURL } from '~/signals' import { twMerge } from 'tailwind-merge'
import { secret, tableSize, wsEndpointURL } from '~/signals'
import { Log } from '~/types' import { Log } from '~/types'
type LogWithSeq = Log & { seq: number } type LogWithSeq = Log & { seq: number }
@ -75,7 +76,7 @@ export default () => {
/> />
<div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300"> <div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300">
<table class="table table-xs relative rounded-none"> <table class={twMerge(tableSize(), 'table relative rounded-none')}>
<thead class="sticky top-0 z-10"> <thead class="sticky top-0 z-10">
<For each={table.getHeaderGroups()}> <For each={table.getHeaderGroups()}>
{(headerGroup) => ( {(headerGroup) => (

View File

@ -5,6 +5,7 @@ import {
LATENCY_QUALITY_MAP_HTTPS, LATENCY_QUALITY_MAP_HTTPS,
PROXIES_ORDERING_TYPE, PROXIES_ORDERING_TYPE,
PROXIES_PREVIEW_TYPE, PROXIES_PREVIEW_TYPE,
TAILWINDCSS_SIZE,
} from '~/constants' } from '~/constants'
import { setCurTheme } from '~/signals' import { setCurTheme } from '~/signals'
@ -49,6 +50,10 @@ export const [renderProxiesInSamePage, setRenderProxiesInSamePage] =
name: 'renderProxiesInSamePage', name: 'renderProxiesInSamePage',
storage: localStorage, storage: localStorage,
}) })
export const [tableSize, setTableSize] = makePersisted(
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
{ name: 'tableSize', storage: localStorage },
)
export const isLatencyTestByHttps = () => export const isLatencyTestByHttps = () =>
urlForLatencyTest().startsWith('https') urlForLatencyTest().startsWith('https')