mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-27 10:44:02 +08:00
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:
parent
6575e73439
commit
90ecb86603
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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>
|
||||||
|
@ -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',
|
||||||
|
}
|
||||||
|
@ -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',
|
||||||
}
|
}
|
||||||
|
@ -59,4 +59,10 @@ export default {
|
|||||||
ms: '毫秒',
|
ms: '毫秒',
|
||||||
updated: '更新于',
|
updated: '更新于',
|
||||||
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
||||||
|
tableSize: '表格大小',
|
||||||
|
xs: '超小尺寸',
|
||||||
|
sm: '小尺寸',
|
||||||
|
md: '正常尺寸',
|
||||||
|
lg: '超大尺寸',
|
||||||
|
switchEndpoint: '切换后端',
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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) => (
|
||||||
|
@ -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) => (
|
||||||
|
@ -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')
|
||||||
|
Loading…
Reference in New Issue
Block a user