mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-23 21:35:36 +08:00
feat(config): select tunnel mode
This commit is contained in:
parent
9f227c9c2c
commit
34ea1f1c56
@ -36,7 +36,6 @@ export const themes = [
|
|||||||
export enum ROUTES {
|
export enum ROUTES {
|
||||||
Overview = '/overview',
|
Overview = '/overview',
|
||||||
Proxies = '/proxies',
|
Proxies = '/proxies',
|
||||||
ProxyProvider = '/proxyprovider',
|
|
||||||
Rules = '/rules',
|
Rules = '/rules',
|
||||||
Conns = '/conns',
|
Conns = '/conns',
|
||||||
Log = '/logs',
|
Log = '/logs',
|
||||||
@ -148,3 +147,9 @@ export enum TAILWINDCSS_SIZE {
|
|||||||
MD = 'md',
|
MD = 'md',
|
||||||
LG = 'lg',
|
LG = 'lg',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum MODE_OPTIONS {
|
||||||
|
Global = 'global',
|
||||||
|
Rule = 'rule',
|
||||||
|
Direct = 'direct',
|
||||||
|
}
|
||||||
|
@ -75,4 +75,7 @@ export default {
|
|||||||
details: 'Details',
|
details: 'Details',
|
||||||
endpointURL: 'Endpoint URL',
|
endpointURL: 'Endpoint URL',
|
||||||
secret: 'Secret',
|
secret: 'Secret',
|
||||||
|
global: 'Global',
|
||||||
|
rule: 'Rule',
|
||||||
|
direct: 'Direct',
|
||||||
}
|
}
|
||||||
|
@ -75,4 +75,7 @@ export default {
|
|||||||
details: '详情',
|
details: '详情',
|
||||||
endpointURL: '后端地址',
|
endpointURL: '后端地址',
|
||||||
secret: '密钥',
|
secret: '密钥',
|
||||||
|
global: '全局',
|
||||||
|
rule: '规则',
|
||||||
|
direct: '直连',
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import { z } from 'zod'
|
|||||||
import { Button } from '~/components'
|
import { Button } from '~/components'
|
||||||
import {
|
import {
|
||||||
LANG,
|
LANG,
|
||||||
|
MODE_OPTIONS,
|
||||||
PROXIES_ORDERING_TYPE,
|
PROXIES_ORDERING_TYPE,
|
||||||
PROXIES_PREVIEW_TYPE,
|
PROXIES_PREVIEW_TYPE,
|
||||||
ROUTES,
|
ROUTES,
|
||||||
@ -24,14 +25,17 @@ import {
|
|||||||
applyThemeByMode,
|
applyThemeByMode,
|
||||||
autoCloseConns,
|
autoCloseConns,
|
||||||
autoSwitchTheme,
|
autoSwitchTheme,
|
||||||
|
backendConfig,
|
||||||
favDayTheme,
|
favDayTheme,
|
||||||
favNightTheme,
|
favNightTheme,
|
||||||
|
fetchBackendConfig,
|
||||||
latencyTestTimeoutDuration,
|
latencyTestTimeoutDuration,
|
||||||
proxiesOrderingType,
|
proxiesOrderingType,
|
||||||
proxiesPreviewType,
|
proxiesPreviewType,
|
||||||
renderInTwoColumns,
|
renderInTwoColumns,
|
||||||
setAutoCloseConns,
|
setAutoCloseConns,
|
||||||
setAutoSwitchTheme,
|
setAutoSwitchTheme,
|
||||||
|
setBackendConfig,
|
||||||
setFavDayTheme,
|
setFavDayTheme,
|
||||||
setFavNightTheme,
|
setFavNightTheme,
|
||||||
setLatencyTestTimeoutDuration,
|
setLatencyTestTimeoutDuration,
|
||||||
@ -43,11 +47,12 @@ import {
|
|||||||
setTwemoji,
|
setTwemoji,
|
||||||
setUrlForLatencyTest,
|
setUrlForLatencyTest,
|
||||||
tableSize,
|
tableSize,
|
||||||
|
updateBackendConfig,
|
||||||
urlForLatencyTest,
|
urlForLatencyTest,
|
||||||
useRequest,
|
useRequest,
|
||||||
useTwemoji,
|
useTwemoji,
|
||||||
} from '~/signals'
|
} from '~/signals'
|
||||||
import type { BackendVersion, DNSQuery, Config as IConfig } from '~/types'
|
import type { BackendVersion, DNSQuery } from '~/types'
|
||||||
|
|
||||||
const dnsQueryFormSchema = z.object({
|
const dnsQueryFormSchema = z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
@ -155,8 +160,8 @@ const ConfigForm = () => {
|
|||||||
>({ extend: validator({ schema: configFormSchema }) })
|
>({ extend: validator({ schema: configFormSchema }) })
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const configs = await request.get('configs').json<IConfig>()
|
const configs = await fetchBackendConfig()
|
||||||
|
setBackendConfig(configs)
|
||||||
setInitialValues(configs)
|
setInitialValues(configs)
|
||||||
reset()
|
reset()
|
||||||
})
|
})
|
||||||
@ -191,6 +196,16 @@ const ConfigForm = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
|
<select
|
||||||
|
class="select select-bordered"
|
||||||
|
value={backendConfig()?.mode}
|
||||||
|
onChange={(e) => updateBackendConfig('mode', e.target.value)}
|
||||||
|
>
|
||||||
|
<option value={MODE_OPTIONS.Global}>{t('global')}</option>
|
||||||
|
<option value={MODE_OPTIONS.Rule}>{t('rule')}</option>
|
||||||
|
<option value={MODE_OPTIONS.Direct}>{t('direct')}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
<form class="contents" use:form={form}>
|
<form class="contents" use:form={form}>
|
||||||
<For each={portsList}>
|
<For each={portsList}>
|
||||||
{(item) => (
|
{(item) => (
|
||||||
|
@ -334,20 +334,20 @@ export default () => {
|
|||||||
<div class="join flex w-full items-center md:flex-1">
|
<div class="join flex w-full items-center md:flex-1">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
class="input join-item input-primary flex-1 sm:input-md"
|
class="input join-item input-primary input-sm min-w-0 flex-1 sm:input-md"
|
||||||
placeholder={t('search')}
|
placeholder={t('search')}
|
||||||
onInput={(e) => setGlobalFilter(e.target.value)}
|
onInput={(e) => setGlobalFilter(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class="join-item sm:btn-md"
|
class="join-item btn-sm sm:btn-md"
|
||||||
onClick={() => setPaused((paused) => !paused)}
|
onClick={() => setPaused((paused) => !paused)}
|
||||||
>
|
>
|
||||||
{paused() ? <IconPlayerPlay /> : <IconPlayerPause />}
|
{paused() ? <IconPlayerPlay /> : <IconPlayerPause />}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class="join-item sm:btn-md"
|
class="join-item btn-sm sm:btn-md"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (table.getState().globalFilter) {
|
if (table.getState().globalFilter) {
|
||||||
table
|
table
|
||||||
@ -362,7 +362,7 @@ export default () => {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
class="btn join-item sm:btn-md"
|
class="btn join-item btn-sm sm:btn-md"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const modal = document.querySelector(
|
const modal = document.querySelector(
|
||||||
'#connections-table-ordering-modal',
|
'#connections-table-ordering-modal',
|
||||||
|
@ -82,7 +82,7 @@ export default () => {
|
|||||||
<div class="flex h-full flex-col gap-4 p-1">
|
<div class="flex h-full flex-col gap-4 p-1">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
class="input input-primary flex-shrink-0"
|
class="input input-primary input-sm flex-shrink-0 sm:input-md"
|
||||||
placeholder={t('search')}
|
placeholder={t('search')}
|
||||||
onInput={(e) => setSearch(e.target.value)}
|
onInput={(e) => setSearch(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
@ -99,7 +99,7 @@ export default () => {
|
|||||||
<button
|
<button
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
activeTab() === tab.type && 'tab-active',
|
activeTab() === tab.type && 'tab-active',
|
||||||
'tab gap-2 px-2',
|
'tab tab-sm gap-2 px-2 sm:tab-md',
|
||||||
)}
|
)}
|
||||||
onClick={() => setActiveTab(tab.type)}
|
onClick={() => setActiveTab(tab.type)}
|
||||||
>
|
>
|
||||||
|
@ -63,13 +63,13 @@ export default () => {
|
|||||||
<div class="flex h-full flex-col gap-2">
|
<div class="flex h-full flex-col gap-2">
|
||||||
<Show when={ruleProviders().length > 0}>
|
<Show when={ruleProviders().length > 0}>
|
||||||
<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
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
activeTab() === tab.type && 'tab-active',
|
activeTab() === tab.type && 'tab-active',
|
||||||
'tab gap-2 px-2',
|
'tab tab-sm gap-2 px-2 md:tab-md',
|
||||||
)}
|
)}
|
||||||
onClick={() => setActiveTab(tab.type)}
|
onClick={() => setActiveTab(tab.type)}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { makePersisted } from '@solid-primitives/storage'
|
import { makePersisted } from '@solid-primitives/storage'
|
||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
|
import { toast } from 'solid-toast'
|
||||||
import {
|
import {
|
||||||
LATENCY_QUALITY_MAP_HTTP,
|
LATENCY_QUALITY_MAP_HTTP,
|
||||||
LATENCY_QUALITY_MAP_HTTPS,
|
LATENCY_QUALITY_MAP_HTTPS,
|
||||||
@ -7,7 +8,8 @@ import {
|
|||||||
PROXIES_PREVIEW_TYPE,
|
PROXIES_PREVIEW_TYPE,
|
||||||
TAILWINDCSS_SIZE,
|
TAILWINDCSS_SIZE,
|
||||||
} from '~/constants'
|
} from '~/constants'
|
||||||
import { setCurTheme } from '~/signals'
|
import { setCurTheme, useRequest } from '~/signals'
|
||||||
|
import { Config } from '~/types'
|
||||||
|
|
||||||
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
|
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
|
||||||
createSignal(PROXIES_PREVIEW_TYPE.Auto),
|
createSignal(PROXIES_PREVIEW_TYPE.Auto),
|
||||||
@ -103,3 +105,34 @@ export const useAutoSwitchTheme = () => {
|
|||||||
.matchMedia('(prefers-color-scheme: dark)')
|
.matchMedia('(prefers-color-scheme: dark)')
|
||||||
.addEventListener('change', (event) => setTheme(event.matches))
|
.addEventListener('change', (event) => setTheme(event.matches))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const [backendConfig, setBackendConfig] = createSignal<Config>()
|
||||||
|
|
||||||
|
export const fetchBackendConfig = () => {
|
||||||
|
const request = useRequest()
|
||||||
|
|
||||||
|
return request.get('configs').json<Config>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateBackendConfig = async (
|
||||||
|
key: keyof Config,
|
||||||
|
value: Config[keyof Config],
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const request = useRequest()
|
||||||
|
|
||||||
|
await request
|
||||||
|
.patch('configs', {
|
||||||
|
body: JSON.stringify({
|
||||||
|
[key]: value,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.json<Config>()
|
||||||
|
|
||||||
|
const updatedConfig = await fetchBackendConfig()
|
||||||
|
|
||||||
|
setBackendConfig(updatedConfig)
|
||||||
|
} catch (err) {
|
||||||
|
toast.error((err as Error).message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
@ -111,6 +111,7 @@ export type Log = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
|
mode: 'global' | 'rule' | 'direct'
|
||||||
port: number
|
port: number
|
||||||
'socks-port': number
|
'socks-port': number
|
||||||
'redir-port': number
|
'redir-port': number
|
||||||
@ -137,7 +138,6 @@ export type Config = {
|
|||||||
'allow-lan': boolean
|
'allow-lan': boolean
|
||||||
'bind-address': string
|
'bind-address': string
|
||||||
'inbound-tfo': boolean
|
'inbound-tfo': boolean
|
||||||
mode: 'rule' | 'global'
|
|
||||||
UnifiedDelay: boolean
|
UnifiedDelay: boolean
|
||||||
'log-level': string
|
'log-level': string
|
||||||
ipv6: boolean
|
ipv6: boolean
|
||||||
|
Loading…
Reference in New Issue
Block a user