mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-25 07:04:11 +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/validator-zod": "^1.0.17",
|
||||
"@fontsource/fira-sans": "^5.0.11",
|
||||
"@solid-primitives/clipboard": "^1.5.7",
|
||||
"@solid-primitives/event-listener": "^2.3.0",
|
||||
"@solid-primitives/i18n": "^1.4.1",
|
||||
"@solid-primitives/keyed": "^1.2.0",
|
||||
"@solid-primitives/media": "^2.2.5",
|
||||
"@solid-primitives/storage": "^2.1.1",
|
||||
"@solid-primitives/websocket": "^1.1.0",
|
||||
"@solidjs/router": "^0.8.3",
|
||||
|
57
pnpm-lock.yaml
generated
57
pnpm-lock.yaml
generated
@ -17,6 +17,9 @@ dependencies:
|
||||
'@fontsource/fira-sans':
|
||||
specifier: ^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':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0(solid-js@1.7.11)
|
||||
@ -26,6 +29,9 @@ dependencies:
|
||||
'@solid-primitives/keyed':
|
||||
specifier: ^1.2.0
|
||||
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':
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1(solid-js@1.7.11)
|
||||
@ -2420,6 +2426,18 @@ packages:
|
||||
rollup: 2.79.1
|
||||
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):
|
||||
resolution:
|
||||
{
|
||||
@ -2466,6 +2484,45 @@ packages:
|
||||
solid-js: 1.7.11
|
||||
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):
|
||||
resolution:
|
||||
{
|
||||
|
14
src/App.tsx
14
src/App.tsx
@ -1,10 +1,14 @@
|
||||
import { Navigate, Route, Routes, useNavigate } from '@solidjs/router'
|
||||
import { Show, createEffect, lazy, onMount } from 'solid-js'
|
||||
import { Header } from '~/components/Header'
|
||||
import { curTheme, endpoint, selectedEndpoint } from '~/signals'
|
||||
import { ROUTE } from './config/enum'
|
||||
import { useAutoSwitchTheme } from './signals/config'
|
||||
import { useProxies } from './signals/proxies'
|
||||
import { Header } from '~/components'
|
||||
import { ROUTE } from '~/constants'
|
||||
import {
|
||||
curTheme,
|
||||
endpoint,
|
||||
selectedEndpoint,
|
||||
useAutoSwitchTheme,
|
||||
useProxies,
|
||||
} from '~/signals'
|
||||
|
||||
const Setup = lazy(() => import('~/pages/Setup'))
|
||||
const Overview = lazy(() => import('~/pages/Overview'))
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { JSX, ParentComponent, Show, createMemo } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { renderInTwoColumn } from '~/signals/config'
|
||||
import { renderInTwoColumn } from '~/signals'
|
||||
|
||||
type Props = {
|
||||
title: JSX.Element
|
||||
@ -9,7 +9,7 @@ type Props = {
|
||||
onCollapse: (collapsed: boolean) => void
|
||||
}
|
||||
|
||||
const Collapse: ParentComponent<Props> = (props) => {
|
||||
export const Collapse: ParentComponent<Props> = (props) => {
|
||||
const { title, content, onCollapse } = props
|
||||
|
||||
const getCollapseClassName = () => {
|
||||
@ -57,5 +57,3 @@ const Collapse: ParentComponent<Props> = (props) => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Collapse
|
||||
|
@ -14,17 +14,13 @@ import {
|
||||
useDragDropContext,
|
||||
} from '@thisbeyond/solid-dnd'
|
||||
import { For, Show, createSignal } from 'solid-js'
|
||||
import { Button } from '~/components/Button'
|
||||
import {
|
||||
AccessorKey,
|
||||
initColumnOrder,
|
||||
initColumnVisibility,
|
||||
} from '~/config/enum'
|
||||
import { Button } from '~/components'
|
||||
import { AccessorKey, initColumnOrder, initColumnVisibility } from '~/constants'
|
||||
|
||||
type ColumnVisibility = Partial<Record<AccessorKey, boolean>>
|
||||
type ColumnOrder = AccessorKey[]
|
||||
|
||||
export default (props: {
|
||||
export const ConnectionsModal = (props: {
|
||||
order: ColumnOrder
|
||||
visible: ColumnVisibility
|
||||
onOrderChange: (value: ColumnOrder) => void
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Show, createEffect, createMemo, createSignal } from 'solid-js'
|
||||
import { DELAY } from '~/config/enum'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { DELAY } from '~/constants'
|
||||
import { useProxies } from '~/signals'
|
||||
|
||||
const Delay = (props: { name?: string }) => {
|
||||
export const Delay = (props: { name?: string }) => {
|
||||
const { delayMap } = useProxies()
|
||||
const [textClassName, setTextClassName] = createSignal('')
|
||||
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 { renderInTwoColumn } from '~/signals/config'
|
||||
import { renderInTwoColumn } from '~/signals'
|
||||
|
||||
const [windowWidth, setWindowWidth] = createSignal(0)
|
||||
|
||||
@ -9,7 +9,7 @@ window.addEventListener('resize', () => {
|
||||
setWindowWidth(document.body.clientWidth)
|
||||
})
|
||||
|
||||
const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
||||
export const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
||||
const isShowTwoColumns = createMemo(
|
||||
() => windowWidth() >= 640 && renderInTwoColumn(),
|
||||
) // 640 is sm size in daisyui
|
||||
@ -29,5 +29,3 @@ const ForTwoColumns = (props: { subChild: JSX.Element[] }) => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ForTwoColumns
|
||||
|
@ -15,11 +15,9 @@ import {
|
||||
} from '@tabler/icons-solidjs'
|
||||
import { For, ParentComponent, Show, createMemo, createSignal } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Button } from '~/components/Button'
|
||||
import { LANG, ROUTE } from '~/config/enum'
|
||||
import { themes } from '~/constants'
|
||||
import { setCurTheme, setSelectedEndpoint } from '~/signals'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { Button } from '~/components'
|
||||
import { LANG, ROUTE, themes } from '~/constants'
|
||||
import { setCurTheme, setSelectedEndpoint, useProxies } from '~/signals'
|
||||
|
||||
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
|
||||
href,
|
||||
|
@ -2,7 +2,7 @@ import InfiniteScroll from 'solid-infinite-scroll'
|
||||
import { createMemo, createSignal } from 'solid-js'
|
||||
import ProxyNodeCard from './ProxyNodeCard'
|
||||
|
||||
export default (props: {
|
||||
export const ProxyCardGroups = (props: {
|
||||
proxies: string[]
|
||||
now?: string
|
||||
onClick?: (name: string) => void
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createMemo } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import Delay from '~/components/Delay'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { Delay } from '~/components'
|
||||
import { useProxies } from '~/signals'
|
||||
|
||||
export default (props: {
|
||||
proxyName: string
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { Show, createMemo } from 'solid-js'
|
||||
import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
|
||||
import { proxiesPreviewType } from '~/signals/config'
|
||||
import ProxyPreviewBar from './ProxyPreviewBar'
|
||||
import ProxyPreviewDots from './ProxyPreviewDots'
|
||||
import { ProxyPreviewBar, ProxyPreviewDots } from '~/components'
|
||||
import { PROXIES_PREVIEW_TYPE } from '~/constants'
|
||||
import { proxiesPreviewType } from '~/signals'
|
||||
|
||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
||||
export const ProxyNodePreview = (props: {
|
||||
proxyNameList: string[]
|
||||
now?: string
|
||||
}) => {
|
||||
const off = () => proxiesPreviewType() === PROXIES_PREVIEW_TYPE.OFF
|
||||
|
||||
const isSmallGroup = createMemo(() => props.proxyNameList.length <= 30)
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { createMemo } from 'solid-js'
|
||||
import Delay from '~/components/Delay'
|
||||
import { DELAY } from '~/config/enum'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { Delay } from '~/components'
|
||||
import { DELAY } from '~/constants'
|
||||
import { useProxies } from '~/signals'
|
||||
|
||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
||||
export const ProxyPreviewBar = (props: {
|
||||
proxyNameList: string[]
|
||||
now?: string
|
||||
}) => {
|
||||
const { delayMap } = useProxies()
|
||||
const delayList = createMemo(() =>
|
||||
props.proxyNameList.map((i) => delayMap()[i]),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { For } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { DELAY } from '~/config/enum'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { DELAY } from '~/constants'
|
||||
import { useProxies } from '~/signals'
|
||||
|
||||
const DelayDots = (p: { delay: number | undefined; selected: boolean }) => {
|
||||
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>
|
||||
}
|
||||
|
||||
export default (props: { proxyNameList: string[]; now?: string }) => {
|
||||
export const ProxyPreviewDots = (props: {
|
||||
proxyNameList: string[]
|
||||
now?: string
|
||||
}) => {
|
||||
const { delayMap } = useProxies()
|
||||
|
||||
return (
|
||||
|
@ -1,8 +1,8 @@
|
||||
import byteSize from 'byte-size'
|
||||
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 used = byteSize(subscriptionInfo.Download + subscriptionInfo.Upload, {
|
||||
units: 'iec',
|
||||
@ -28,7 +28,9 @@ const getSubscriptionsInfo = (subscriptionInfo: SubscriptionInfo) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default (props: { subscriptionInfo: SubscriptionInfo }) => {
|
||||
export const SubscriptionInfo = (props: {
|
||||
subscriptionInfo: ISubscriptionInfo
|
||||
}) => {
|
||||
if (!props.subscriptionInfo) {
|
||||
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',
|
||||
'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)
|
||||
|
||||
export function formatTimeFromNow(time: number | string) {
|
||||
export const formatTimeFromNow = (time: number | string) => {
|
||||
return dayjs(time).fromNow()
|
||||
}
|
||||
|
||||
export function getBtnElFromClickEvent(event: MouseEvent) {
|
||||
export const getBtnElFromClickEvent = (event: MouseEvent) => {
|
||||
let el = event.target as HTMLElement
|
||||
|
||||
while (el && !el.classList.contains('btn')) {
|
@ -1,4 +1,4 @@
|
||||
import { LANG } from '~/config/enum'
|
||||
import { LANG } from '~/constants'
|
||||
import en from './en'
|
||||
import zh from './zh'
|
||||
|
||||
|
@ -48,4 +48,10 @@ export default {
|
||||
updateGEODatabases: 'Update GEO Databases',
|
||||
restartCore: 'Restart 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 { makePersisted } from '@solid-primitives/storage'
|
||||
import { ParentComponent, createEffect, createSignal } from 'solid-js'
|
||||
import { LANG } from '~/config/enum'
|
||||
import { LANG } from '~/constants'
|
||||
import dict from './dict'
|
||||
|
||||
const useLanguage = () => {
|
||||
|
@ -48,4 +48,10 @@ export default {
|
||||
updateGEODatabases: '更新 GEO 数据库文件',
|
||||
restartCore: '重启核心',
|
||||
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 { For, Show, createSignal, onMount } from 'solid-js'
|
||||
import { z } from 'zod'
|
||||
import { Button } from '~/components/Button'
|
||||
import { PROXIES_PREVIEW_TYPE } from '~/config/enum'
|
||||
import { themes } from '~/constants'
|
||||
import { useRequest } from '~/signals'
|
||||
import { Button } from '~/components'
|
||||
import { PROXIES_PREVIEW_TYPE, PROXIES_SORTING_TYPE, themes } from '~/constants'
|
||||
import {
|
||||
applyThemeByMode,
|
||||
autoCloseConns,
|
||||
@ -14,16 +12,19 @@ import {
|
||||
favDayTheme,
|
||||
favNightTheme,
|
||||
proxiesPreviewType,
|
||||
proxiesSortingType,
|
||||
renderInTwoColumn,
|
||||
setAutoCloseConns,
|
||||
setAutoSwitchTheme,
|
||||
setFavDayTheme,
|
||||
setFavNightTheme,
|
||||
setProxiesPreviewType,
|
||||
setProxiesSortingType,
|
||||
setRenderInTwoColumn,
|
||||
setUrlForDelayTest,
|
||||
urlForDelayTest,
|
||||
} from '~/signals/config'
|
||||
useRequest,
|
||||
} from '~/signals'
|
||||
import type { DNSQuery, Config as IConfig } from '~/types'
|
||||
|
||||
const dnsQueryFormSchema = z.object({
|
||||
@ -261,8 +262,10 @@ const ConfigForXd = () => {
|
||||
</select>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div>
|
||||
<div class="pb-4">{t('proxiesPreviewType')}</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<For each={Object.values(PROXIES_PREVIEW_TYPE)}>
|
||||
{(value) => (
|
||||
@ -282,6 +285,28 @@ const ConfigForXd = () => {
|
||||
</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 class="pb-4">{t('autoCloseConns')}</div>
|
||||
|
||||
|
@ -20,13 +20,8 @@ import byteSize from 'byte-size'
|
||||
import { isIPv6 } from 'is-ip'
|
||||
import { For, createEffect, createSignal } from 'solid-js'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Button } from '~/components/Button'
|
||||
import ConnectionsModal from '~/components/ConnectionsModal'
|
||||
import {
|
||||
AccessorKey,
|
||||
initColumnOrder,
|
||||
initColumnVisibility,
|
||||
} from '~/config/enum'
|
||||
import { Button, ConnectionsModal } from '~/components'
|
||||
import { AccessorKey, initColumnOrder, initColumnVisibility } from '~/constants'
|
||||
import { secret, useRequest, wsEndpointURL } from '~/signals'
|
||||
import type { Connection } from '~/types'
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
|
||||
import { Show, createSignal } from 'solid-js'
|
||||
import { Button } from '~/components/Button'
|
||||
import Collapse from '~/components/Collpase'
|
||||
import ForTwoColumns from '~/components/ForTwoColumns'
|
||||
import ProxyCardGroups from '~/components/ProxyCardGroups'
|
||||
import ProxyNodePreview from '~/components/ProxyNodePreview'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import {
|
||||
Button,
|
||||
Collapse,
|
||||
ForTwoColumns,
|
||||
ProxyCardGroups,
|
||||
ProxyNodePreview,
|
||||
} from '~/components'
|
||||
import { getBtnElFromClickEvent } from '~/helpers'
|
||||
import { useProxies } from '~/signals'
|
||||
import type { Proxy } from '~/types'
|
||||
import { getBtnElFromClickEvent } from '~/utils/proxies'
|
||||
|
||||
export default () => {
|
||||
const [t] = useI18n()
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { useI18n } from '@solid-primitives/i18n'
|
||||
import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs'
|
||||
import { Show, createSignal } from 'solid-js'
|
||||
import { Button } from '~/components/Button'
|
||||
import Collapse from '~/components/Collpase'
|
||||
import ForTwoColumns from '~/components/ForTwoColumns'
|
||||
import ProxyCardGroups from '~/components/ProxyCardGroups'
|
||||
import ProxyNodePreview from '~/components/ProxyNodePreview'
|
||||
import SubscriptionInfo from '~/components/SubscriptionInfo'
|
||||
import { useProxies } from '~/signals/proxies'
|
||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/utils/proxies'
|
||||
import {
|
||||
Button,
|
||||
Collapse,
|
||||
ForTwoColumns,
|
||||
ProxyCardGroups,
|
||||
ProxyNodePreview,
|
||||
SubscriptionInfo,
|
||||
} from '~/components'
|
||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/helpers'
|
||||
import { useProxies } from '~/signals'
|
||||
|
||||
export default () => {
|
||||
const [t] = useI18n()
|
||||
|
@ -2,9 +2,9 @@ import { useI18n } from '@solid-primitives/i18n'
|
||||
import { IconReload } from '@tabler/icons-solidjs'
|
||||
import InfiniteScroll from 'solid-infinite-scroll'
|
||||
import { For, Show, createMemo, createSignal, onMount } from 'solid-js'
|
||||
import { Button } from '~/components/Button'
|
||||
import { useRules } from '~/signals/rules'
|
||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/utils/proxies'
|
||||
import { Button } from '~/components'
|
||||
import { formatTimeFromNow, getBtnElFromClickEvent } from '~/helpers'
|
||||
import { useRules } from '~/signals'
|
||||
|
||||
export default () => {
|
||||
const [t] = useI18n()
|
||||
|
@ -7,7 +7,7 @@ import ky from 'ky'
|
||||
import { For, onMount } from 'solid-js'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { z } from 'zod'
|
||||
import { Button } from '~/components/Button'
|
||||
import { Button } from '~/components'
|
||||
import { endpointList, setEndpointList, setSelectedEndpoint } from '~/signals'
|
||||
|
||||
const schema = z.object({
|
||||
|
@ -1,12 +1,16 @@
|
||||
import { makePersisted } from '@solid-primitives/storage'
|
||||
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'
|
||||
|
||||
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
|
||||
createSignal(PROXIES_PREVIEW_TYPE.BAR),
|
||||
createSignal(PROXIES_PREVIEW_TYPE.Auto),
|
||||
{ name: 'proxiesPreviewType', storage: localStorage },
|
||||
)
|
||||
export const [proxiesSortingType, setProxiesSortingType] = makePersisted(
|
||||
createSignal(PROXIES_SORTING_TYPE.NATURAL),
|
||||
{ name: 'proxiesSortingType', storage: localStorage },
|
||||
)
|
||||
export const [urlForDelayTest, setUrlForDelayTest] = makePersisted(
|
||||
createSignal('https://www.gstatic.com/generate_204'),
|
||||
{ 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)
|
||||
}
|
||||
|
||||
export function useAutoSwitchTheme() {
|
||||
export const useAutoSwitchTheme = () => {
|
||||
applyThemeByMode()
|
||||
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', (event) => {
|
||||
setTheme(event.matches)
|
||||
})
|
||||
.addEventListener('change', (event) => setTheme(event.matches))
|
||||
}
|
||||
|
@ -1,46 +1,5 @@
|
||||
import { makePersisted } from '@solid-primitives/storage'
|
||||
import ky from 'ky'
|
||||
import { createSignal } from 'solid-js'
|
||||
import { themes } from '~/constants'
|
||||
|
||||
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')
|
||||
export * from './config'
|
||||
export * from './proxies'
|
||||
export * from './request'
|
||||
export * from './rules'
|
||||
export * from './theme'
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { createSignal } from 'solid-js'
|
||||
import { useRequest } from '~/signals'
|
||||
import { autoCloseConns, urlForDelayTest } from '~/signals/config'
|
||||
import { autoCloseConns, urlForDelayTest, useRequest } from '~/signals'
|
||||
import type { Proxy, ProxyNode, ProxyProvider } from '~/types'
|
||||
|
||||
type ProxyInfo = {
|
||||
@ -17,8 +16,9 @@ const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
||||
{},
|
||||
)
|
||||
|
||||
export function useProxies() {
|
||||
export const useProxies = () => {
|
||||
const request = useRequest()
|
||||
|
||||
const setProxyInfoByProixes = (proxies: Proxy[] | ProxyNode[]) => {
|
||||
proxies.forEach((proxy) => {
|
||||
const delay = proxy.history.at(-1)?.delay ?? 0
|
||||
@ -85,7 +85,6 @@ export function useProxies() {
|
||||
proxyGroup.now = proxyName
|
||||
|
||||
setProxies(proxyGroupList)
|
||||
// queueMicrotask(updateProxy)
|
||||
}
|
||||
|
||||
const delayTestByProxyGroupName = async (proxyGroupName: string) => {
|
||||
@ -122,7 +121,7 @@ export function useProxies() {
|
||||
|
||||
const healthCheckByProviderName = async (providerName: string) => {
|
||||
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()
|
||||
}
|
||||
|
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…
x
Reference in New Issue
Block a user