mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-30 23:35:37 +08:00
feat(rules): config for render rules in two columns
This commit is contained in:
parent
79ad0acfea
commit
7e2fe6acb0
@ -1,6 +1,6 @@
|
|||||||
import { JSX, ParentComponent, Show, createMemo } from 'solid-js'
|
import { JSX, ParentComponent, Show, createMemo } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { renderInTwoColumn } from '~/signals'
|
import { renderInTwoColumns } from '~/signals'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: JSX.Element
|
title: JSX.Element
|
||||||
@ -27,7 +27,7 @@ export const Collapse: ParentComponent<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mediaQueryClassName = createMemo(() => {
|
const mediaQueryClassName = createMemo(() => {
|
||||||
if (renderInTwoColumn()) {
|
if (renderInTwoColumns()) {
|
||||||
return 'lg:grid-cols-3 xl:grid-cols-4'
|
return 'lg:grid-cols-3 xl:grid-cols-4'
|
||||||
} else {
|
} else {
|
||||||
return 'sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7'
|
return 'sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7'
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { createWindowSize } from '@solid-primitives/resize-observer'
|
import { createWindowSize } from '@solid-primitives/resize-observer'
|
||||||
import { JSX, Show, createMemo } from 'solid-js'
|
import { JSX, Show, createMemo } from 'solid-js'
|
||||||
import { renderInTwoColumn } from '~/signals'
|
import { renderInTwoColumns } from '~/signals'
|
||||||
|
|
||||||
export const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
export const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
||||||
const windowSize = createWindowSize()
|
const windowSize = createWindowSize()
|
||||||
const isShowTwoColumns = createMemo(
|
const isShowTwoColumns = createMemo(
|
||||||
() => windowSize.width >= 640 && renderInTwoColumn(),
|
() => windowSize.width >= 640 && renderInTwoColumns(),
|
||||||
) // 640 is sm size in daisyui
|
) // 640 is sm size in daisyui
|
||||||
const leftCloumns = createMemo(() =>
|
const leftCloumns = createMemo(() =>
|
||||||
props.subChild.filter((_, index) => index % 2 === 0 || !isShowTwoColumns()),
|
props.subChild.filter((_, index) => index % 2 === 0 || !isShowTwoColumns()),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { PROXIES_ORDERING_TYPE } from '~/constants'
|
import { PROXIES_ORDERING_TYPE } from '~/constants'
|
||||||
|
import { latencyQualityMap } from '~/signals'
|
||||||
|
|
||||||
export const formatTimeFromNow = (time: number | string) => {
|
export const formatTimeFromNow = (time: number | string) => {
|
||||||
return dayjs(time).fromNow()
|
return dayjs(time).fromNow()
|
||||||
@ -45,16 +46,16 @@ export const sortProxiesByOrderingType = (
|
|||||||
|
|
||||||
switch (orderingType) {
|
switch (orderingType) {
|
||||||
case PROXIES_ORDERING_TYPE.LATENCY_ASC:
|
case PROXIES_ORDERING_TYPE.LATENCY_ASC:
|
||||||
if (prevLatency === -1) return 1
|
if (prevLatency === latencyQualityMap().NOT_CONNECTED) return 1
|
||||||
|
|
||||||
if (nextLatency === -1) return -1
|
if (nextLatency === latencyQualityMap().NOT_CONNECTED) return -1
|
||||||
|
|
||||||
return prevLatency - nextLatency
|
return prevLatency - nextLatency
|
||||||
|
|
||||||
case PROXIES_ORDERING_TYPE.LATENCY_DESC:
|
case PROXIES_ORDERING_TYPE.LATENCY_DESC:
|
||||||
if (prevLatency === -1) return 1
|
if (prevLatency === latencyQualityMap().NOT_CONNECTED) return 1
|
||||||
|
|
||||||
if (nextLatency === -1) return -1
|
if (nextLatency === latencyQualityMap().NOT_CONNECTED) return -1
|
||||||
|
|
||||||
return nextLatency - prevLatency
|
return nextLatency - prevLatency
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export default {
|
|||||||
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 Proxies in two columns',
|
renderInTwoColumns: 'Render proxies in two columns',
|
||||||
updateGEODatabases: 'Update GEO Databases',
|
updateGEODatabases: 'Update GEO Databases',
|
||||||
restartCore: 'Restart Core',
|
restartCore: 'Restart Core',
|
||||||
upgradeCore: 'Upgrade Core',
|
upgradeCore: 'Upgrade Core',
|
||||||
@ -60,6 +60,8 @@ 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',
|
||||||
|
renderRulesAndProviderInTwoColumns:
|
||||||
|
'Render rules and rule provider in two columns',
|
||||||
tableSize: 'Table size',
|
tableSize: 'Table size',
|
||||||
xs: 'Extra small size',
|
xs: 'Extra small size',
|
||||||
sm: 'Small size',
|
sm: 'Small size',
|
||||||
|
@ -60,6 +60,7 @@ export default {
|
|||||||
ms: '毫秒',
|
ms: '毫秒',
|
||||||
updated: '更新于',
|
updated: '更新于',
|
||||||
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
renderProxiesInSamePage: '将代理和代理提供者显示在同一页',
|
||||||
|
renderRulesAndProviderInTwoColumns: '规则和规则提供者双列渲染',
|
||||||
tableSize: '表格大小',
|
tableSize: '表格大小',
|
||||||
xs: '超小尺寸',
|
xs: '超小尺寸',
|
||||||
sm: '小尺寸',
|
sm: '小尺寸',
|
||||||
|
@ -29,8 +29,9 @@ import {
|
|||||||
latencyTestTimeoutDuration,
|
latencyTestTimeoutDuration,
|
||||||
proxiesOrderingType,
|
proxiesOrderingType,
|
||||||
proxiesPreviewType,
|
proxiesPreviewType,
|
||||||
renderInTwoColumn,
|
renderInTwoColumns,
|
||||||
renderProxiesInSamePage,
|
renderProxiesInSamePage,
|
||||||
|
renderRulesAndProviderInTwoColumns,
|
||||||
setAutoCloseConns,
|
setAutoCloseConns,
|
||||||
setAutoSwitchTheme,
|
setAutoSwitchTheme,
|
||||||
setFavDayTheme,
|
setFavDayTheme,
|
||||||
@ -38,8 +39,9 @@ import {
|
|||||||
setLatencyTestTimeoutDuration,
|
setLatencyTestTimeoutDuration,
|
||||||
setProxiesOrderingType,
|
setProxiesOrderingType,
|
||||||
setProxiesPreviewType,
|
setProxiesPreviewType,
|
||||||
setRenderInTwoColumn,
|
setRenderInTwoColumns,
|
||||||
setRenderProxiesInSamePage,
|
setRenderProxiesInSamePage,
|
||||||
|
setRenderRulesAndProviderInTwoColumns,
|
||||||
setSelectedEndpoint,
|
setSelectedEndpoint,
|
||||||
setTableSize,
|
setTableSize,
|
||||||
setTwemoji,
|
setTwemoji,
|
||||||
@ -270,98 +272,102 @@ const ConfigForXd = () => {
|
|||||||
navigate(ROUTES.Setup)
|
navigate(ROUTES.Setup)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const autoSwitchThemeSubChild = () => (
|
||||||
<div class="grid gap-4">
|
<Show when={autoSwitchTheme()}>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<ConfigTitle>{t('renderInTwoColumns')}</ConfigTitle>
|
<ConfigTitle>{t('favDayTheme')}</ConfigTitle>
|
||||||
|
|
||||||
<input
|
<select
|
||||||
type="checkbox"
|
class="select select-bordered w-full max-w-xs"
|
||||||
class="toggle"
|
|
||||||
checked={renderInTwoColumn()}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setRenderInTwoColumn(e.target.checked)
|
setFavDayTheme(e.target.value)
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<ConfigTitle>{t('renderProxiesInSamePage')}</ConfigTitle>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
class="toggle"
|
|
||||||
checked={renderProxiesInSamePage()}
|
|
||||||
onChange={(e) => {
|
|
||||||
setRenderProxiesInSamePage(e.target.checked)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<ConfigTitle>{t('autoSwitchTheme')}</ConfigTitle>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
class="toggle"
|
|
||||||
checked={autoSwitchTheme()}
|
|
||||||
onChange={(e) => {
|
|
||||||
setAutoSwitchTheme(e.target.checked)
|
|
||||||
applyThemeByMode()
|
applyThemeByMode()
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<For each={themes}>
|
||||||
|
{(theme) => (
|
||||||
|
<option selected={favDayTheme() === theme} value={theme}>
|
||||||
|
{theme}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<ConfigTitle>{t('favNightTheme')}</ConfigTitle>
|
||||||
|
|
||||||
<Show when={autoSwitchTheme()}>
|
<select
|
||||||
<div class="flex flex-col">
|
class="select select-bordered w-full max-w-xs"
|
||||||
<ConfigTitle>{t('favDayTheme')}</ConfigTitle>
|
onChange={(e) => {
|
||||||
|
setFavNightTheme(e.target.value)
|
||||||
<select
|
applyThemeByMode()
|
||||||
class="select select-bordered w-full max-w-xs"
|
}}
|
||||||
onChange={(e) => {
|
>
|
||||||
setFavDayTheme(e.target.value)
|
<For each={themes}>
|
||||||
applyThemeByMode()
|
{(theme) => (
|
||||||
}}
|
<option selected={favNightTheme() === theme} value={theme}>
|
||||||
>
|
{theme}
|
||||||
<For each={themes}>
|
</option>
|
||||||
{(theme) => (
|
)}
|
||||||
<option selected={favDayTheme() === theme} value={theme}>
|
</For>
|
||||||
{theme}
|
</select>
|
||||||
</option>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<ConfigTitle>{t('favNightTheme')}</ConfigTitle>
|
|
||||||
|
|
||||||
<select
|
|
||||||
class="select select-bordered w-full max-w-xs"
|
|
||||||
onChange={(e) => {
|
|
||||||
setFavNightTheme(e.target.value)
|
|
||||||
applyThemeByMode()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<For each={themes}>
|
|
||||||
{(theme) => (
|
|
||||||
<option selected={favNightTheme() === theme} value={theme}>
|
|
||||||
{theme}
|
|
||||||
</option>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<ConfigTitle>{t('useTwemoji')}</ConfigTitle>
|
|
||||||
|
|
||||||
<input
|
|
||||||
class="toggle"
|
|
||||||
type="checkbox"
|
|
||||||
checked={useTwemoji()}
|
|
||||||
onChange={(e) => setTwemoji(e.target.checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
|
||||||
|
const checkboxList = [
|
||||||
|
{
|
||||||
|
label: 'renderInTwoColumns',
|
||||||
|
value: renderInTwoColumns,
|
||||||
|
onChange: setRenderInTwoColumns,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'renderRulesAndProviderInTwoColumns',
|
||||||
|
value: renderRulesAndProviderInTwoColumns,
|
||||||
|
onChange: setRenderRulesAndProviderInTwoColumns,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'renderProxiesInSamePage',
|
||||||
|
value: renderProxiesInSamePage,
|
||||||
|
onChange: setRenderProxiesInSamePage,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'autoSwitchTheme',
|
||||||
|
value: autoSwitchTheme,
|
||||||
|
onChange: (value: boolean) => {
|
||||||
|
setAutoSwitchTheme(value)
|
||||||
|
applyThemeByMode()
|
||||||
|
},
|
||||||
|
subChild: autoSwitchThemeSubChild,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'useTwemoji',
|
||||||
|
value: useTwemoji,
|
||||||
|
onChange: setTwemoji,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="grid gap-4">
|
||||||
|
<For each={checkboxList}>
|
||||||
|
{(checkbox) => (
|
||||||
|
<>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<ConfigTitle>{t(checkbox.label)}</ConfigTitle>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="toggle"
|
||||||
|
checked={checkbox.value()}
|
||||||
|
onChange={(e) => {
|
||||||
|
checkbox.onChange(e.target.checked)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{checkbox.subChild?.()}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ConfigTitle>{t('proxiesPreviewType')}</ConfigTitle>
|
<ConfigTitle>{t('proxiesPreviewType')}</ConfigTitle>
|
||||||
|
@ -5,7 +5,7 @@ import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
|||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button } from '~/components'
|
import { Button } from '~/components'
|
||||||
import { formatTimeFromNow, useStringBooleanMap } from '~/helpers'
|
import { formatTimeFromNow, useStringBooleanMap } from '~/helpers'
|
||||||
import { useRules } from '~/signals'
|
import { renderRulesAndProviderInTwoColumns, useRules } from '~/signals'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
@ -40,7 +40,12 @@ export default () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex w-full gap-4">
|
<div
|
||||||
|
class={twMerge(
|
||||||
|
'flex w-full flex-col gap-4',
|
||||||
|
renderRulesAndProviderInTwoColumns() && 'flex-row',
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<h1 class="pb-4 text-lg font-semibold">{t('rules')}</h1>
|
<h1 class="pb-4 text-lg font-semibold">{t('rules')}</h1>
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ export const [favNightTheme, setFavNightTheme] = makePersisted(
|
|||||||
createSignal('night'),
|
createSignal('night'),
|
||||||
{ name: 'favNightTheme', storage: localStorage },
|
{ name: 'favNightTheme', storage: localStorage },
|
||||||
)
|
)
|
||||||
export const [renderInTwoColumn, setRenderInTwoColumn] = makePersisted(
|
export const [renderInTwoColumns, setRenderInTwoColumns] = makePersisted(
|
||||||
createSignal(true),
|
createSignal(true),
|
||||||
{ name: 'renderInTwoColumn', storage: localStorage },
|
{ name: 'renderInTwoColumn', storage: localStorage },
|
||||||
)
|
)
|
||||||
@ -50,6 +50,13 @@ export const [renderProxiesInSamePage, setRenderProxiesInSamePage] =
|
|||||||
name: 'renderProxiesInSamePage',
|
name: 'renderProxiesInSamePage',
|
||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
})
|
})
|
||||||
|
export const [
|
||||||
|
renderRulesAndProviderInTwoColumns,
|
||||||
|
setRenderRulesAndProviderInTwoColumns,
|
||||||
|
] = makePersisted(createSignal(true), {
|
||||||
|
name: 'renderRulesAndProviderInTwoColumns',
|
||||||
|
storage: localStorage,
|
||||||
|
})
|
||||||
export const [tableSize, setTableSize] = makePersisted(
|
export const [tableSize, setTableSize] = makePersisted(
|
||||||
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
|
createSignal<TAILWINDCSS_SIZE>(TAILWINDCSS_SIZE.XS),
|
||||||
{ name: 'tableSize', storage: localStorage },
|
{ name: 'tableSize', storage: localStorage },
|
||||||
|
Loading…
Reference in New Issue
Block a user