mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-24 09:45:35 +08:00
refactor: update project source code layout
This commit is contained in:
parent
fec64133fa
commit
461488c19f
@ -15,9 +15,11 @@
|
|||||||
"@felte/solid": "^1.2.11",
|
"@felte/solid": "^1.2.11",
|
||||||
"@felte/validator-zod": "^1.0.17",
|
"@felte/validator-zod": "^1.0.17",
|
||||||
"@fontsource/fira-sans": "^5.0.11",
|
"@fontsource/fira-sans": "^5.0.11",
|
||||||
|
"@solid-primitives/clipboard": "^1.5.7",
|
||||||
"@solid-primitives/event-listener": "^2.3.0",
|
"@solid-primitives/event-listener": "^2.3.0",
|
||||||
"@solid-primitives/i18n": "^1.4.1",
|
"@solid-primitives/i18n": "^1.4.1",
|
||||||
"@solid-primitives/keyed": "^1.2.0",
|
"@solid-primitives/keyed": "^1.2.0",
|
||||||
|
"@solid-primitives/media": "^2.2.5",
|
||||||
"@solid-primitives/storage": "^2.1.1",
|
"@solid-primitives/storage": "^2.1.1",
|
||||||
"@solid-primitives/websocket": "^1.1.0",
|
"@solid-primitives/websocket": "^1.1.0",
|
||||||
"@solidjs/router": "^0.8.3",
|
"@solidjs/router": "^0.8.3",
|
||||||
|
@ -17,6 +17,9 @@ dependencies:
|
|||||||
'@fontsource/fira-sans':
|
'@fontsource/fira-sans':
|
||||||
specifier: ^5.0.11
|
specifier: ^5.0.11
|
||||||
version: 5.0.11
|
version: 5.0.11
|
||||||
|
'@solid-primitives/clipboard':
|
||||||
|
specifier: ^1.5.7
|
||||||
|
version: 1.5.7(solid-js@1.7.11)
|
||||||
'@solid-primitives/event-listener':
|
'@solid-primitives/event-listener':
|
||||||
specifier: ^2.3.0
|
specifier: ^2.3.0
|
||||||
version: 2.3.0(solid-js@1.7.11)
|
version: 2.3.0(solid-js@1.7.11)
|
||||||
@ -26,6 +29,9 @@ dependencies:
|
|||||||
'@solid-primitives/keyed':
|
'@solid-primitives/keyed':
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.0
|
||||||
version: 1.2.0(solid-js@1.7.11)
|
version: 1.2.0(solid-js@1.7.11)
|
||||||
|
'@solid-primitives/media':
|
||||||
|
specifier: ^2.2.5
|
||||||
|
version: 2.2.5(solid-js@1.7.11)
|
||||||
'@solid-primitives/storage':
|
'@solid-primitives/storage':
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1(solid-js@1.7.11)
|
version: 2.1.1(solid-js@1.7.11)
|
||||||
@ -2420,6 +2426,18 @@ packages:
|
|||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@solid-primitives/clipboard@1.5.7(solid-js@1.7.11):
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-MGTykW9739tMm2wS3P/Pb9W7BIZvgBLnC+Vhlx3s0DGm9CcEeXJ8lHyUp736UE57HKtCsqzfcCkpmIprbidIbQ==,
|
||||||
|
}
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
dependencies:
|
||||||
|
'@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
|
||||||
|
solid-js: 1.7.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@solid-primitives/context@0.2.1(solid-js@1.7.11):
|
/@solid-primitives/context@0.2.1(solid-js@1.7.11):
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
@ -2466,6 +2484,45 @@ packages:
|
|||||||
solid-js: 1.7.11
|
solid-js: 1.7.11
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@solid-primitives/media@2.2.5(solid-js@1.7.11):
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-wTESNFteSwOZsNIBPLMIVLuOHIIzt2AIZdaCYYxfsJIr/xjDqSomlmdFlAmxfJD3ondO7fwtWfc0rcmAvjoPCA==,
|
||||||
|
}
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
dependencies:
|
||||||
|
'@solid-primitives/event-listener': 2.3.0(solid-js@1.7.11)
|
||||||
|
'@solid-primitives/rootless': 1.4.2(solid-js@1.7.11)
|
||||||
|
'@solid-primitives/static-store': 0.0.5(solid-js@1.7.11)
|
||||||
|
'@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
|
||||||
|
solid-js: 1.7.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@solid-primitives/rootless@1.4.2(solid-js@1.7.11):
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-ynI/2aEOPyc14IKCX6yDBqnsAYCoLbaP9V/jejEWMVKOT2ZdV2ZxdftaLimOpWPpvjyti5DUJIGTOfLaNb7jlg==,
|
||||||
|
}
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
dependencies:
|
||||||
|
'@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
|
||||||
|
solid-js: 1.7.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@solid-primitives/static-store@0.0.5(solid-js@1.7.11):
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-ssQ+s/wrlFAEE4Zw8GV499yBfvWx7SMm+ZVc11wvao4T5xg9VfXCL9Oa+x4h+vPMvSV/Knv5LrsLiUa+wlJUXQ==,
|
||||||
|
}
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
dependencies:
|
||||||
|
'@solid-primitives/utils': 6.2.1(solid-js@1.7.11)
|
||||||
|
solid-js: 1.7.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@solid-primitives/storage@2.1.1(solid-js@1.7.11):
|
/@solid-primitives/storage@2.1.1(solid-js@1.7.11):
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
14
src/App.tsx
14
src/App.tsx
@ -1,10 +1,14 @@
|
|||||||
import { Navigate, Route, Routes, useNavigate } from '@solidjs/router'
|
import { Navigate, Route, Routes, useNavigate } from '@solidjs/router'
|
||||||
import { Show, createEffect, lazy, onMount } from 'solid-js'
|
import { Show, createEffect, lazy, onMount } from 'solid-js'
|
||||||
import { Header } from '~/components/Header'
|
import { Header } from '~/components'
|
||||||
import { curTheme, endpoint, selectedEndpoint } from '~/signals'
|
import { ROUTE } from '~/constants'
|
||||||
import { ROUTE } from './config/enum'
|
import {
|
||||||
import { useAutoSwitchTheme } from './signals/config'
|
curTheme,
|
||||||
import { useProxies } from './signals/proxies'
|
endpoint,
|
||||||
|
selectedEndpoint,
|
||||||
|
useAutoSwitchTheme,
|
||||||
|
useProxies,
|
||||||
|
} from '~/signals'
|
||||||
|
|
||||||
const Setup = lazy(() => import('~/pages/Setup'))
|
const Setup = lazy(() => import('~/pages/Setup'))
|
||||||
const Overview = lazy(() => import('~/pages/Overview'))
|
const Overview = lazy(() => import('~/pages/Overview'))
|
||||||
|
@ -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/config'
|
import { renderInTwoColumn } from '~/signals'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: JSX.Element
|
title: JSX.Element
|
||||||
@ -9,7 +9,7 @@ type Props = {
|
|||||||
onCollapse: (collapsed: boolean) => void
|
onCollapse: (collapsed: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Collapse: ParentComponent<Props> = (props) => {
|
export const Collapse: ParentComponent<Props> = (props) => {
|
||||||
const { title, content, onCollapse } = props
|
const { title, content, onCollapse } = props
|
||||||
|
|
||||||
const getCollapseClassName = () => {
|
const getCollapseClassName = () => {
|
||||||
@ -57,5 +57,3 @@ const Collapse: ParentComponent<Props> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Collapse
|
|
||||||
|
@ -14,17 +14,13 @@ import {
|
|||||||
useDragDropContext,
|
useDragDropContext,
|
||||||
} from '@thisbeyond/solid-dnd'
|
} from '@thisbeyond/solid-dnd'
|
||||||
import { For, Show, createSignal } from 'solid-js'
|
import { For, Show, createSignal } from 'solid-js'
|
||||||
import { Button } from '~/components/Button'
|
import { Button } from '~/components'
|
||||||
import {
|
import { AccessorKey, initColumnOrder, initColumnVisibility } from '~/constants'
|
||||||
AccessorKey,
|
|
||||||
initColumnOrder,
|
|
||||||
initColumnVisibility,
|
|
||||||
} from '~/config/enum'
|
|
||||||
|
|
||||||
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
||||||
type ColumnOrder = AccessorKey[]
|
type ColumnOrder = AccessorKey[]
|
||||||
|
|
||||||
export default (props: {
|
export const ConnectionsModal = (props: {
|
||||||
order: ColumnOrder
|
order: ColumnOrder
|
||||||
visible: ColumnVisibility
|
visible: ColumnVisibility
|
||||||
onOrderChange: (value: ColumnOrder) => void
|
onOrderChange: (value: ColumnOrder) => void
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Show, createEffect, createMemo, createSignal } from 'solid-js'
|
import { Show, createEffect, createMemo, createSignal } from 'solid-js'
|
||||||
import { DELAY } from '~/config/enum'
|
import { DELAY } from '~/constants'
|
||||||
import { useProxies } from '~/signals/proxies'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
const Delay = (props: { name?: string }) => {
|
export const Delay = (props: { name?: string }) => {
|
||||||
const { delayMap } = useProxies()
|
const { delayMap } = useProxies()
|
||||||
const [textClassName, setTextClassName] = createSignal('')
|
const [textClassName, setTextClassName] = createSignal('')
|
||||||
const delay = createMemo(() => {
|
const delay = createMemo(() => {
|
||||||
@ -29,5 +29,3 @@ const Delay = (props: { name?: string }) => {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Delay
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { JSX, Show, createMemo, createSignal } from 'solid-js'
|
import { JSX, Show, createMemo, createSignal } from 'solid-js'
|
||||||
import { renderInTwoColumn } from '~/signals/config'
|
import { renderInTwoColumn } from '~/signals'
|
||||||
|
|
||||||
const [windowWidth, setWindowWidth] = createSignal(0)
|
const [windowWidth, setWindowWidth] = createSignal(0)
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ window.addEventListener('resize', () => {
|
|||||||
setWindowWidth(document.body.clientWidth)
|
setWindowWidth(document.body.clientWidth)
|
||||||
})
|
})
|
||||||
|
|
||||||
const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
export const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
||||||
const isShowTwoColumns = createMemo(
|
const isShowTwoColumns = createMemo(
|
||||||
() => windowWidth() >= 640 && renderInTwoColumn(),
|
() => windowWidth() >= 640 && renderInTwoColumn(),
|
||||||
) // 640 is sm size in daisyui
|
) // 640 is sm size in daisyui
|
||||||
@ -29,5 +29,3 @@ const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ForTwoColumns
|
|
||||||
|
@ -15,11 +15,9 @@ import {
|
|||||||
} from '@tabler/icons-solidjs'
|
} from '@tabler/icons-solidjs'
|
||||||
import { For, ParentComponent, Show, createMemo, createSignal } from 'solid-js'
|
import { For, ParentComponent, Show, createMemo, createSignal } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button } from '~/components/Button'
|
import { Button } from '~/components'
|
||||||
import { LANG, ROUTE } from '~/config/enum'
|
import { LANG, ROUTE, themes } from '~/constants'
|
||||||
import { themes } from '~/constants'
|
import { setCurTheme, setSelectedEndpoint, useProxies } from '~/signals'
|
||||||
import { setCurTheme, setSelectedEndpoint } from '~/signals'
|
|
||||||
import { useProxies } from '~/signals/proxies'
|
|
||||||
|
|
||||||
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
|
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
|
||||||
href,
|
href,
|
||||||
|
@ -2,7 +2,7 @@ import InfiniteScroll from 'solid-infinite-scroll'
|
|||||||
import { createMemo, createSignal } from 'solid-js'
|
import { createMemo, createSignal } from 'solid-js'
|
||||||
import ProxyNodeCard from './ProxyNodeCard'
|
import ProxyNodeCard from './ProxyNodeCard'
|
||||||
|
|
||||||
export default (props: {
|
export const ProxyCardGroups = (props: {
|
||||||
proxies: string[]
|
proxies: string[]
|
||||||
now?: string
|
now?: string
|
||||||
onClick?: (name: string) => void
|
onClick?: (name: string) => void
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createMemo } from 'solid-js'
|
import { createMemo } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import Delay from '~/components/Delay'
|
import { Delay } from '~/components'
|
||||||
import { useProxies } from '~/signals/proxies'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
export default (props: {
|
export default (props: {
|
||||||
proxyName: string
|
proxyName: string
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { Show, createMemo } from 'solid-js'
|
import { Show, createMemo } from 'solid-js'
|
||||||
import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
|
import { ProxyPreviewBar, ProxyPreviewDots } from '~/components'
|
||||||
import { proxiesPreviewType } from '~/signals/config'
|
import { PROXIES_PREVIEW_TYPE } from '~/constants'
|
||||||
import ProxyPreviewBar from './ProxyPreviewBar'
|
import { proxiesPreviewType } from '~/signals'
|
||||||
import ProxyPreviewDots from './ProxyPreviewDots'
|
|
||||||
|
|
||||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
export const ProxyNodePreview = (props: {
|
||||||
|
proxyNameList: string[]
|
||||||
|
now?: string
|
||||||
|
}) => {
|
||||||
const off = () => proxiesPreviewType() === PROXIES_PREVIEW_TYPE.OFF
|
const off = () => proxiesPreviewType() === PROXIES_PREVIEW_TYPE.OFF
|
||||||
|
|
||||||
const isSmallGroup = createMemo(() => props.proxyNameList.length <= 30)
|
const isSmallGroup = createMemo(() => props.proxyNameList.length <= 30)
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { createMemo } from 'solid-js'
|
import { createMemo } from 'solid-js'
|
||||||
import Delay from '~/components/Delay'
|
import { Delay } from '~/components'
|
||||||
import { DELAY } from '~/config/enum'
|
import { DELAY } from '~/constants'
|
||||||
import { useProxies } from '~/signals/proxies'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
export const ProxyPreviewBar = (props: {
|
||||||
|
proxyNameList: string[]
|
||||||
|
now?: string
|
||||||
|
}) => {
|
||||||
const { delayMap } = useProxies()
|
const { delayMap } = useProxies()
|
||||||
const delayList = createMemo(() =>
|
const delayList = createMemo(() =>
|
||||||
props.proxyNameList.map((i) => delayMap()[i]),
|
props.proxyNameList.map((i) => delayMap()[i]),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { For } from 'solid-js'
|
import { For } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { DELAY } from '~/config/enum'
|
import { DELAY } from '~/constants'
|
||||||
import { useProxies } from '~/signals/proxies'
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
const DelayDots = (p: { delay: number | undefined; selected: boolean }) => {
|
const DelayDots = (p: { delay: number | undefined; selected: boolean }) => {
|
||||||
let dotClassName = p.selected
|
let dotClassName = p.selected
|
||||||
@ -23,7 +23,10 @@ const DelayDots = (p: { delay: number | undefined; selected: boolean }) => {
|
|||||||
return <div class={twMerge('m-1 h-4 w-4 rounded-full', dotClassName)}></div>
|
return <div class={twMerge('m-1 h-4 w-4 rounded-full', dotClassName)}></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
export const ProxyPreviewDots = (props: {
|
||||||
|
proxyNameList: string[]
|
||||||
|
now?: string
|
||||||
|
}) => {
|
||||||
const { delayMap } = useProxies()
|
const { delayMap } = useProxies()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import byteSize from 'byte-size'
|
import byteSize from 'byte-size'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import type { SubscriptionInfo } from '~/types'
|
import type { SubscriptionInfo as ISubscriptionInfo } from '~/types'
|
||||||
|
|
||||||
const getSubscriptionsInfo = (subscriptionInfo: SubscriptionInfo) => {
|
const getSubscriptionsInfo = (subscriptionInfo: ISubscriptionInfo) => {
|
||||||
const total = byteSize(subscriptionInfo.Total, { units: 'iec' })
|
const total = byteSize(subscriptionInfo.Total, { units: 'iec' })
|
||||||
const used = byteSize(subscriptionInfo.Download + subscriptionInfo.Upload, {
|
const used = byteSize(subscriptionInfo.Download + subscriptionInfo.Upload, {
|
||||||
units: 'iec',
|
units: 'iec',
|
||||||
@ -28,7 +28,9 @@ const getSubscriptionsInfo = (subscriptionInfo: SubscriptionInfo) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (props: { subscriptionInfo: SubscriptionInfo }) => {
|
export const SubscriptionInfo = (props: {
|
||||||
|
subscriptionInfo: ISubscriptionInfo
|
||||||
|
}) => {
|
||||||
if (!props.subscriptionInfo) {
|
if (!props.subscriptionInfo) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
12
src/components/index.ts
Normal file
12
src/components/index.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export * from './Button'
|
||||||
|
export * from './Collpase'
|
||||||
|
export * from './ConnectionsModal'
|
||||||
|
export * from './Delay'
|
||||||
|
export * from './ForTwoColumns'
|
||||||
|
export * from './Header'
|
||||||
|
export * from './ProxyCardGroups'
|
||||||
|
export * from './ProxyNodeCard'
|
||||||
|
export * from './ProxyNodePreview'
|
||||||
|
export * from './ProxyPreviewBar'
|
||||||
|
export * from './ProxyPreviewDots'
|
||||||
|
export * from './SubscriptionInfo'
|
@ -1,49 +0,0 @@
|
|||||||
export enum ROUTE {
|
|
||||||
Overview = '/overview',
|
|
||||||
Proxies = '/proxies',
|
|
||||||
Proxyprovider = '/proxyprovider',
|
|
||||||
Rules = '/rules',
|
|
||||||
Conns = '/conns',
|
|
||||||
Log = '/logs',
|
|
||||||
Config = '/config',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AccessorKey {
|
|
||||||
Close = 'close',
|
|
||||||
ID = 'ID',
|
|
||||||
Type = 'type',
|
|
||||||
Process = 'process',
|
|
||||||
Host = 'host',
|
|
||||||
Rule = 'rules',
|
|
||||||
Chains = 'chains',
|
|
||||||
DlSpeed = 'dlSpeed',
|
|
||||||
ULSpeed = 'ulSpeed',
|
|
||||||
Download = 'dl',
|
|
||||||
Upload = 'ul',
|
|
||||||
Source = 'source',
|
|
||||||
Destination = 'destination',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DELAY {
|
|
||||||
NOT_CONNECTED = 0,
|
|
||||||
MEDIUM = 200,
|
|
||||||
HIGH = 500,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum PROXIES_PREVIEW_TYPE {
|
|
||||||
OFF = 'off',
|
|
||||||
DOTS = 'dots',
|
|
||||||
BAR = 'bar',
|
|
||||||
Auto = 'auto',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LANG {
|
|
||||||
EN = 'en-US',
|
|
||||||
ZH = 'zh-CN',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initColumnOrder = Object.values(AccessorKey)
|
|
||||||
export const initColumnVisibility = {
|
|
||||||
...Object.fromEntries(initColumnOrder.map((i) => [i, true])),
|
|
||||||
[AccessorKey.ID]: false,
|
|
||||||
}
|
|
@ -29,3 +29,61 @@ export const themes = [
|
|||||||
'coffee',
|
'coffee',
|
||||||
'winter',
|
'winter',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export enum ROUTE {
|
||||||
|
Overview = '/overview',
|
||||||
|
Proxies = '/proxies',
|
||||||
|
Proxyprovider = '/proxyprovider',
|
||||||
|
Rules = '/rules',
|
||||||
|
Conns = '/conns',
|
||||||
|
Log = '/logs',
|
||||||
|
Config = '/config',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum AccessorKey {
|
||||||
|
Close = 'close',
|
||||||
|
ID = 'ID',
|
||||||
|
Type = 'type',
|
||||||
|
Process = 'process',
|
||||||
|
Host = 'host',
|
||||||
|
Rule = 'rules',
|
||||||
|
Chains = 'chains',
|
||||||
|
DlSpeed = 'dlSpeed',
|
||||||
|
ULSpeed = 'ulSpeed',
|
||||||
|
Download = 'dl',
|
||||||
|
Upload = 'ul',
|
||||||
|
Source = 'source',
|
||||||
|
Destination = 'destination',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DELAY {
|
||||||
|
NOT_CONNECTED = 0,
|
||||||
|
MEDIUM = 200,
|
||||||
|
HIGH = 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PROXIES_PREVIEW_TYPE {
|
||||||
|
OFF = 'off',
|
||||||
|
DOTS = 'dots',
|
||||||
|
BAR = 'bar',
|
||||||
|
Auto = 'auto',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PROXIES_SORTING_TYPE {
|
||||||
|
NATURAL = 'orderNatural',
|
||||||
|
LATENCY_ASC = 'orderLatency_asc',
|
||||||
|
LATENCY_DESC = 'orderLatency_desc',
|
||||||
|
NAME_ASC = 'orderName_asc',
|
||||||
|
NAME_DESC = 'orderName_desc',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum LANG {
|
||||||
|
EN = 'en-US',
|
||||||
|
ZH = 'zh-CN',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initColumnOrder = Object.values(AccessorKey)
|
||||||
|
export const initColumnVisibility = {
|
||||||
|
...Object.fromEntries(initColumnOrder.map((i) => [i, true])),
|
||||||
|
[AccessorKey.ID]: false,
|
||||||
|
}
|
||||||
|
1
src/helpers/index.ts
Normal file
1
src/helpers/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './proxies'
|
@ -3,11 +3,11 @@ import relativeTime from 'dayjs/plugin/relativeTime'
|
|||||||
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
export function formatTimeFromNow(time: number | string) {
|
export const formatTimeFromNow = (time: number | string) => {
|
||||||
return dayjs(time).fromNow()
|
return dayjs(time).fromNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBtnElFromClickEvent(event: MouseEvent) {
|
export const getBtnElFromClickEvent = (event: MouseEvent) => {
|
||||||
let el = event.target as HTMLElement
|
let el = event.target as HTMLElement
|
||||||
|
|
||||||
while (el && !el.classList.contains('btn')) {
|
while (el && !el.classList.contains('btn')) {
|
@ -1,4 +1,4 @@
|
|||||||
import { LANG } from '~/config/enum'
|
import { LANG } from '~/constants'
|
||||||
import en from './en'
|
import en from './en'
|
||||||
import zh from './zh'
|
import zh from './zh'
|
||||||
|
|
||||||
|
@ -48,4 +48,10 @@ export default {
|
|||||||
updateGEODatabases: 'Update GEO Databases',
|
updateGEODatabases: 'Update GEO Databases',
|
||||||
restartCore: 'Restart Core',
|
restartCore: 'Restart Core',
|
||||||
upgradeCore: 'Upgrade Core',
|
upgradeCore: 'Upgrade Core',
|
||||||
|
proxiesSorting: 'Proxies Sorting',
|
||||||
|
orderNatural: 'Original order in config file',
|
||||||
|
orderLatency_asc: 'By latency from low to high',
|
||||||
|
orderLatency_desc: 'By latency from high to low',
|
||||||
|
orderName_asc: 'By name alphabetically (A-Z)',
|
||||||
|
orderName_desc: 'By name alphabetically (Z-A)',
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { I18nContext, createI18nContext, useI18n } from '@solid-primitives/i18n'
|
import { I18nContext, createI18nContext, useI18n } from '@solid-primitives/i18n'
|
||||||
import { makePersisted } from '@solid-primitives/storage'
|
import { makePersisted } from '@solid-primitives/storage'
|
||||||
import { ParentComponent, createEffect, createSignal } from 'solid-js'
|
import { ParentComponent, createEffect, createSignal } from 'solid-js'
|
||||||
import { LANG } from '~/config/enum'
|
import { LANG } from '~/constants'
|
||||||
import dict from './dict'
|
import dict from './dict'
|
||||||
|
|
||||||
const useLanguage = () => {
|
const useLanguage = () => {
|
||||||
|
@ -48,4 +48,10 @@ export default {
|
|||||||
updateGEODatabases: '更新 GEO 数据库文件',
|
updateGEODatabases: '更新 GEO 数据库文件',
|
||||||
restartCore: '重启核心',
|
restartCore: '重启核心',
|
||||||
upgradeCore: '更新核心',
|
upgradeCore: '更新核心',
|
||||||
|
proxiesSorting: '节点排序',
|
||||||
|
orderNatural: '原配置文件中的排序',
|
||||||
|
orderLatency_asc: '按延迟从低到高',
|
||||||
|
orderLatency_desc: '按延迟从高到低',
|
||||||
|
orderName_asc: '按名称字母排序 (A-Z)',
|
||||||
|
orderName_desc: '按名称字母排序 (Z-A)',
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,8 @@ import { validator } from '@felte/validator-zod'
|
|||||||
import { useI18n } from '@solid-primitives/i18n'
|
import { useI18n } from '@solid-primitives/i18n'
|
||||||
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/Button'
|
import { Button } from '~/components'
|
||||||
import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
|
import { PROXIES_PREVIEW_TYPE, PROXIES_SORTING_TYPE, themes } from '~/constants'
|
||||||
import { themes } from '~/constants'
|
|
||||||
import { useRequest } from '~/signals'
|
|
||||||
import {
|
import {
|
||||||
applyThemeByMode,
|
applyThemeByMode,
|
||||||
autoCloseConns,
|
autoCloseConns,
|
||||||
@ -14,16 +12,19 @@ import {
|
|||||||
favDayTheme,
|
favDayTheme,
|
||||||
favNightTheme,
|
favNightTheme,
|
||||||
proxiesPreviewType,
|
proxiesPreviewType,
|
||||||
|
proxiesSortingType,
|
||||||
renderInTwoColumn,
|
renderInTwoColumn,
|
||||||
setAutoCloseConns,
|
setAutoCloseConns,
|
||||||
setAutoSwitchTheme,
|
setAutoSwitchTheme,
|
||||||
setFavDayTheme,
|
setFavDayTheme,
|
||||||
setFavNightTheme,
|
setFavNightTheme,
|
||||||
setProxiesPreviewType,
|
setProxiesPreviewType,
|
||||||
|
setProxiesSortingType,
|
||||||
setRenderInTwoColumn,
|
setRenderInTwoColumn,
|
||||||
setUrlForDelayTest,
|
setUrlForDelayTest,
|
||||||
urlForDelayTest,
|
urlForDelayTest,
|
||||||
} from '~/signals/config'
|
useRequest,
|
||||||
|
} from '~/signals'
|
||||||
import type { DNSQuery, Config as IConfig } from '~/types'
|
import type { DNSQuery, Config as IConfig } from '~/types'
|
||||||
|
|
||||||
const dnsQueryFormSchema = z.object({
|
const dnsQueryFormSchema = z.object({
|
||||||
@ -261,8 +262,10 @@ const ConfigForXd = () => {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="pb-4">{t('proxiesPreviewType')}</div>
|
<div class="pb-4">{t('proxiesPreviewType')}</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
|
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
|
||||||
{(value) => (
|
{(value) => (
|
||||||
@ -282,6 +285,28 @@ const ConfigForXd = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="pb-4">{t('proxiesSorting')}</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<For each={Object.values(PROXIES_SORTING_TYPE)}>
|
||||||
|
{(value) => (
|
||||||
|
<label class="flex items-center gap-2">
|
||||||
|
<span>{t(value)}</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="radio"
|
||||||
|
aria-label={value}
|
||||||
|
type="radio"
|
||||||
|
checked={value === proxiesSortingType()}
|
||||||
|
onChange={() => setProxiesSortingType(value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="pb-4">{t('autoCloseConns')}</div>
|
<div class="pb-4">{t('autoCloseConns')}</div>
|
||||||
|
|
||||||
|
@ -20,13 +20,8 @@ import byteSize from 'byte-size'
|
|||||||
import { isIPv6 } from 'is-ip'
|
import { isIPv6 } from 'is-ip'
|
||||||
import { For, createEffect, createSignal } from 'solid-js'
|
import { For, createEffect, createSignal } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { Button } from '~/components/Button'
|
import { Button, ConnectionsModal } from '~/components'
|
||||||
import ConnectionsModal from '~/components/ConnectionsModal'
|
import { AccessorKey, initColumnOrder, initColumnVisibility } from '~/constants'
|
||||||
import {
|
|
||||||
AccessorKey,
|
|
||||||
initColumnOrder,
|
|
||||||
initColumnVisibility,
|
|
||||||
} from '~/config/enum'
|
|
||||||
import { secret, useRequest, wsEndpointURL } from '~/signals'
|
import { secret, useRequest, wsEndpointURL } from '~/signals'
|
||||||
import type { Connection } from '~/types'
|
import type { Connection } from '~/types'
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { useI18n } from '@solid-primitives/i18n'
|
import { useI18n } from '@solid-primitives/i18n'
|
||||||
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
||||||
import { Show, createSignal } from 'solid-js'
|
import { Show, createSignal } from 'solid-js'
|
||||||
import { Button } from '~/components/Button'
|
import {
|
||||||
import Collapse from '~/components/Collpase'
|
Button,
|
||||||
import ForTwoColumns from '~/components/ForTwoColumns'
|
Collapse,
|
||||||
import ProxyCardGroups from '~/components/ProxyCardGroups'
|
ForTwoColumns,
|
||||||
import ProxyNodePreview from '~/components/ProxyNodePreview'
|
ProxyCardGroups,
|
||||||
import { useProxies } from '~/signals/proxies'
|
ProxyNodePreview,
|
||||||
|
} from '~/components'
|
||||||
|
import { getBtnElFromClickEvent } from '~/helpers'
|
||||||
|
import { useProxies } from '~/signals'
|
||||||
import type { Proxy } from '~/types'
|
import type { Proxy } from '~/types'
|
||||||
import { getBtnElFromClickEvent } from '~/utils/proxies'
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { useI18n } from '@solid-primitives/i18n'
|
import { useI18n } from '@solid-primitives/i18n'
|
||||||
import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs'
|
import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs'
|
||||||
import { Show, createSignal } from 'solid-js'
|
import { Show, createSignal } from 'solid-js'
|
||||||
import { Button } from '~/components/Button'
|
import {
|
||||||
import Collapse from '~/components/Collpase'
|
Button,
|
||||||
import ForTwoColumns from '~/components/ForTwoColumns'
|
Collapse,
|
||||||
import ProxyCardGroups from '~/components/ProxyCardGroups'
|
ForTwoColumns,
|
||||||
import ProxyNodePreview from '~/components/ProxyNodePreview'
|
ProxyCardGroups,
|
||||||
import SubscriptionInfo from '~/components/SubscriptionInfo'
|
ProxyNodePreview,
|
||||||
import { useProxies } from '~/signals/proxies'
|
SubscriptionInfo,
|
||||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/utils/proxies'
|
} from '~/components'
|
||||||
|
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/helpers'
|
||||||
|
import { useProxies } from '~/signals'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
|
@ -2,9 +2,9 @@ import { useI18n } from '@solid-primitives/i18n'
|
|||||||
import { IconReload } from '@tabler/icons-solidjs'
|
import { IconReload } from '@tabler/icons-solidjs'
|
||||||
import InfiniteScroll from 'solid-infinite-scroll'
|
import InfiniteScroll from 'solid-infinite-scroll'
|
||||||
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
||||||
import { Button } from '~/components/Button'
|
import { Button } from '~/components'
|
||||||
import { useRules } from '~/signals/rules'
|
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/helpers'
|
||||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/utils/proxies'
|
import { useRules } from '~/signals'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
|
@ -7,7 +7,7 @@ import ky from 'ky'
|
|||||||
import { For, onMount } from 'solid-js'
|
import { For, onMount } from 'solid-js'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { Button } from '~/components/Button'
|
import { Button } from '~/components'
|
||||||
import { endpointList, setEndpointList, setSelectedEndpoint } from '~/signals'
|
import { endpointList, setEndpointList, setSelectedEndpoint } from '~/signals'
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { makePersisted } from '@solid-primitives/storage'
|
import { makePersisted } from '@solid-primitives/storage'
|
||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
|
import { PROXIES_PREVIEW_TYPE, PROXIES_SORTING_TYPE } from '~/constants'
|
||||||
import { setCurTheme } from '~/signals'
|
import { setCurTheme } from '~/signals'
|
||||||
|
|
||||||
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
|
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
|
||||||
createSignal(PROXIES_PREVIEW_TYPE.BAR),
|
createSignal(PROXIES_PREVIEW_TYPE.Auto),
|
||||||
{ name: 'proxiesPreviewType', storage: localStorage },
|
{ name: 'proxiesPreviewType', storage: localStorage },
|
||||||
)
|
)
|
||||||
|
export const [proxiesSortingType, setProxiesSortingType] = makePersisted(
|
||||||
|
createSignal(PROXIES_SORTING_TYPE.NATURAL),
|
||||||
|
{ name: 'proxiesSortingType', storage: localStorage },
|
||||||
|
)
|
||||||
export const [urlForDelayTest, setUrlForDelayTest] = makePersisted(
|
export const [urlForDelayTest, setUrlForDelayTest] = makePersisted(
|
||||||
createSignal('https://www.gstatic.com/generate_204'),
|
createSignal('https://www.gstatic.com/generate_204'),
|
||||||
{ name: 'urlForDelayTest', storage: localStorage },
|
{ name: 'urlForDelayTest', storage: localStorage },
|
||||||
@ -42,15 +46,13 @@ const setTheme = (isDark: boolean) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyThemeByMode() {
|
export const applyThemeByMode = () =>
|
||||||
setTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
setTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
}
|
|
||||||
|
|
||||||
export function useAutoSwitchTheme() {
|
export const useAutoSwitchTheme = () => {
|
||||||
applyThemeByMode()
|
applyThemeByMode()
|
||||||
|
|
||||||
window
|
window
|
||||||
.matchMedia('(prefers-color-scheme: dark)')
|
.matchMedia('(prefers-color-scheme: dark)')
|
||||||
.addEventListener('change', (event) => {
|
.addEventListener('change', (event) => setTheme(event.matches))
|
||||||
setTheme(event.matches)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,5 @@
|
|||||||
import { makePersisted } from '@solid-primitives/storage'
|
export * from './config'
|
||||||
import ky from 'ky'
|
export * from './proxies'
|
||||||
import { createSignal } from 'solid-js'
|
export * from './request'
|
||||||
import { themes } from '~/constants'
|
export * from './rules'
|
||||||
|
export * from './theme'
|
||||||
export const useRequest = () => {
|
|
||||||
const e = endpoint()
|
|
||||||
|
|
||||||
return ky.create({
|
|
||||||
prefixUrl: e?.url,
|
|
||||||
headers: {
|
|
||||||
Authorization: e?.secret ? `Bearer ${e.secret}` : '',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const [selectedEndpoint, setSelectedEndpoint] = makePersisted(
|
|
||||||
createSignal(''),
|
|
||||||
{
|
|
||||||
name: 'selectedEndpoint',
|
|
||||||
storage: localStorage,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
export const [endpointList, setEndpointList] = makePersisted(
|
|
||||||
createSignal<
|
|
||||||
{
|
|
||||||
id: string
|
|
||||||
url: string
|
|
||||||
secret: string
|
|
||||||
}[]
|
|
||||||
>([]),
|
|
||||||
{ name: 'endpointList', storage: localStorage },
|
|
||||||
)
|
|
||||||
|
|
||||||
export const [curTheme, setCurTheme] = makePersisted(
|
|
||||||
createSignal<(typeof themes)[number]>('halloween'),
|
|
||||||
{ name: 'theme', storage: localStorage },
|
|
||||||
)
|
|
||||||
|
|
||||||
export const endpoint = () =>
|
|
||||||
endpointList().find(({ id }) => id === selectedEndpoint())
|
|
||||||
|
|
||||||
export const secret = () => endpoint()?.secret
|
|
||||||
|
|
||||||
export const wsEndpointURL = () => endpoint()?.url.replace('http', 'ws')
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
import { useRequest } from '~/signals'
|
import { autoCloseConns, urlForDelayTest, useRequest } from '~/signals'
|
||||||
import { autoCloseConns, urlForDelayTest } from '~/signals/config'
|
|
||||||
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
||||||
|
|
||||||
type ProxyInfo = {
|
type ProxyInfo = {
|
||||||
@ -17,8 +16,9 @@ const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
|||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
export function useProxies() {
|
export const useProxies = () => {
|
||||||
const request = useRequest()
|
const request = useRequest()
|
||||||
|
|
||||||
const setProxyInfoByProixes = (proxies: Proxy[] | ProxyNode[]) => {
|
const setProxyInfoByProixes = (proxies: Proxy[] | ProxyNode[]) => {
|
||||||
proxies.forEach((proxy) => {
|
proxies.forEach((proxy) => {
|
||||||
const delay = proxy.history.at(-1)?.delay ?? 0
|
const delay = proxy.history.at(-1)?.delay ?? 0
|
||||||
@ -85,7 +85,6 @@ export function useProxies() {
|
|||||||
proxyGroup.now = proxyName
|
proxyGroup.now = proxyName
|
||||||
|
|
||||||
setProxies(proxyGroupList)
|
setProxies(proxyGroupList)
|
||||||
// queueMicrotask(updateProxy)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const delayTestByProxyGroupName = async (proxyGroupName: string) => {
|
const delayTestByProxyGroupName = async (proxyGroupName: string) => {
|
||||||
@ -122,7 +121,7 @@ export function useProxies() {
|
|||||||
|
|
||||||
const healthCheckByProviderName = async (providerName: string) => {
|
const healthCheckByProviderName = async (providerName: string) => {
|
||||||
await request.get(`providers/proxies/${providerName}/healthcheck`, {
|
await request.get(`providers/proxies/${providerName}/healthcheck`, {
|
||||||
timeout: 30 * 1000, // thie api was a little bit slow sometimes...
|
timeout: 30 * 1000, // thie api is a little bit slow sometimes...
|
||||||
})
|
})
|
||||||
await updateProxy()
|
await updateProxy()
|
||||||
}
|
}
|
||||||
|
40
src/signals/request.ts
Normal file
40
src/signals/request.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { makePersisted } from '@solid-primitives/storage'
|
||||||
|
import ky from 'ky'
|
||||||
|
import { createSignal } from 'solid-js'
|
||||||
|
|
||||||
|
export const [selectedEndpoint, setSelectedEndpoint] = makePersisted(
|
||||||
|
createSignal(''),
|
||||||
|
{
|
||||||
|
name: 'selectedEndpoint',
|
||||||
|
storage: localStorage,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export const [endpointList, setEndpointList] = makePersisted(
|
||||||
|
createSignal<
|
||||||
|
{
|
||||||
|
id: string
|
||||||
|
url: string
|
||||||
|
secret: string
|
||||||
|
}[]
|
||||||
|
>([]),
|
||||||
|
{ name: 'endpointList', storage: localStorage },
|
||||||
|
)
|
||||||
|
|
||||||
|
export const useRequest = () => {
|
||||||
|
const e = endpoint()
|
||||||
|
|
||||||
|
return ky.create({
|
||||||
|
prefixUrl: e?.url,
|
||||||
|
headers: {
|
||||||
|
Authorization: e?.secret ? `Bearer ${e.secret}` : '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const endpoint = () =>
|
||||||
|
endpointList().find(({ id }) => id === selectedEndpoint())
|
||||||
|
|
||||||
|
export const secret = () => endpoint()?.secret
|
||||||
|
|
||||||
|
export const wsEndpointURL = () => endpoint()?.url.replace('http', 'ws')
|
8
src/signals/theme.ts
Normal file
8
src/signals/theme.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { makePersisted } from '@solid-primitives/storage'
|
||||||
|
import { createSignal } from 'solid-js'
|
||||||
|
import { themes } from '~/constants'
|
||||||
|
|
||||||
|
export const [curTheme, setCurTheme] = makePersisted(
|
||||||
|
createSignal<(typeof themes)[number]>('halloween'),
|
||||||
|
{ name: 'theme', storage: localStorage },
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user