support custom substore backend

This commit is contained in:
pompurin404 2024-09-04 16:13:59 +08:00
parent 1773be543f
commit a1d3558581
No known key found for this signature in database
5 changed files with 70 additions and 17 deletions

View File

@ -1,14 +1,17 @@
import axios from 'axios'
import { subStorePort } from '../resolve/server'
import { getAppConfig } from '../config'
export async function subStoreSubs(): Promise<ISubStoreSub[]> {
const res = await axios.get(`http://127.0.0.1:${subStorePort}/api/subs`)
const { useCustomSubStore = false, customSubStoreUrl = '' } = await getAppConfig()
const baseUrl = useCustomSubStore ? customSubStoreUrl : `http://127.0.0.1:${subStorePort}`
const res = await axios.get(`${baseUrl}/api/subs`)
return res.data.data as ISubStoreSub[]
}
export async function subStoreCollections(): Promise<ISubStoreSub[]> {
const res = await axios.get(`http://127.0.0.1:${subStorePort}/api/collections`)
const { useCustomSubStore = false, customSubStoreUrl = '' } = await getAppConfig()
const baseUrl = useCustomSubStore ? customSubStoreUrl : `http://127.0.0.1:${subStorePort}`
const res = await axios.get(`${baseUrl}/api/collections`)
return res.data.data as ISubStoreSub[]
}

View File

@ -53,8 +53,8 @@ export async function startPacServer(): Promise<void> {
}
export async function startSubStoreServer(): Promise<void> {
const { useSubStore = true } = await getAppConfig()
if (!useSubStore) return
const { useSubStore = true, useCustomSubStore = false } = await getAppConfig()
if (!useSubStore || useCustomSubStore) return
if (subStorePort) return
subStorePort = await findAvailablePort(3000)
new Worker(path.join(resourcesFilesDir(), 'sub-store.bundle.js'), {

View File

@ -1,7 +1,7 @@
import React, { Key } from 'react'
import React, { Key, useState } from 'react'
import SettingCard from '../base/base-setting-card'
import SettingItem from '../base/base-setting-item'
import { Button, Select, SelectItem, Switch, Tab, Tabs } from '@nextui-org/react'
import { Button, Input, Select, SelectItem, Switch, Tab, Tabs } from '@nextui-org/react'
import { BiCopy } from 'react-icons/bi'
import useSWR from 'swr'
import {
@ -16,6 +16,7 @@ import {
import { useAppConfig } from '@renderer/hooks/use-app-config'
import { platform } from '@renderer/utils/init'
import { useTheme } from 'next-themes'
import debounce from '@renderer/utils/debounce'
const GeneralConfig: React.FC = () => {
const { data: enable, mutate: mutateEnable } = useSWR('checkAutoRun', checkAutoRun)
@ -28,11 +29,17 @@ const GeneralConfig: React.FC = () => {
proxyInTray = true,
useWindowFrame = false,
useSubStore = true,
useCustomSubStore = false,
customSubStoreUrl,
envType = platform === 'win32' ? 'powershell' : 'bash',
autoCheckUpdate,
appTheme = 'system'
} = appConfig || {}
const [subStoreUrl, setSubStoreUrl] = useState(customSubStoreUrl)
const setSubStoreUrlDebounce = debounce((v: string) => {
patchAppConfig({ customSubStoreUrl: v })
}, 500)
const onThemeChange = (key: Key, type: 'theme' | 'color'): void => {
const [theme, color] = appTheme.split('-')
@ -170,6 +177,36 @@ const GeneralConfig: React.FC = () => {
}}
/>
</SettingItem>
{useSubStore && (
<SettingItem title="使用自建Substore后端" divider>
<Switch
size="sm"
isSelected={useCustomSubStore}
onValueChange={async (v) => {
try {
await patchAppConfig({ useCustomSubStore: v })
if (!v) await startSubStoreServer()
} catch (e) {
alert(e)
}
}}
/>
</SettingItem>
)}
{useCustomSubStore && (
<SettingItem title="自建SubStore后端地址" divider>
<Input
size="sm"
className="w-[60%]"
value={subStoreUrl}
placeholder="必须包含协议头"
onValueChange={(v: string) => {
setSubStoreUrl(v)
setSubStoreUrlDebounce(v)
}}
/>
</SettingItem>
)}
<SettingItem title="使用系统标题栏" divider>
<Switch
size="sm"

View File

@ -46,7 +46,7 @@ const Profiles: React.FC = () => {
mutateProfileConfig
} = useProfileConfig()
const { appConfig } = useAppConfig()
const { useSubStore = true } = appConfig || {}
const { useSubStore = true, useCustomSubStore = false, customSubStoreUrl = '' } = appConfig || {}
const { current, items = [] } = profileConfig || {}
const [sortedItems, setSortedItems] = useState(items)
const [useProxy, setUseProxy] = useState(false)
@ -65,12 +65,14 @@ const Profiles: React.FC = () => {
useSubStore ? subStoreCollections : (): undefined => {}
)
const subStoreMenuItems = useMemo(() => {
console.log(subs, collections)
const items: { icon?: ReactNode; key: string; name: string; divider: boolean }[] = [
{
key: 'open-substore',
name: '访问 SubStore',
icon: <SubStoreIcon />,
divider: Boolean(subs) || Boolean(collections)
divider:
(Boolean(subs) && subs.length > 0) || (Boolean(collections) && collections.length > 0)
}
]
if (subs) {
@ -79,7 +81,7 @@ const Profiles: React.FC = () => {
key: `sub-${sub.name}`,
name: sub.displayName,
icon: sub.icon ? <img src={sub.icon} className="h-[18px] w-[18px]" /> : null,
divider: index === subs.length - 1 && Boolean(collections)
divider: index === subs.length - 1 && Boolean(collections) && collections.length > 0
})
})
}
@ -263,7 +265,11 @@ const Profiles: React.FC = () => {
onAction={async (key) => {
if (key === 'open-substore') {
const port = await subStorePort()
open(`https://sub-store.vercel.app/subs?api=http://127.0.0.1:${port}`)
if (useCustomSubStore) {
open(`https://sub-store.vercel.app/subs?api=${customSubStoreUrl}`)
} else {
open(`https://sub-store.vercel.app/subs?api=http://127.0.0.1:${port}`)
}
} else if (key.toString().startsWith('sub-')) {
setSubStoreImporting(true)
try {
@ -274,7 +280,9 @@ const Profiles: React.FC = () => {
await addProfileItem({
name: sub?.displayName ?? '',
type: 'remote',
url: `http://127.0.0.1:${port}/download/${key.toString().replace('sub-', '')}?target=ClashMeta`,
url: useCustomSubStore
? `${customSubStoreUrl}/download/${key.toString().replace('sub-', '')}?target=ClashMeta`
: `http://127.0.0.1:${port}/download/${key.toString().replace('sub-', '')}?target=ClashMeta`,
useProxy
})
} catch (e) {
@ -286,13 +294,16 @@ const Profiles: React.FC = () => {
setSubStoreImporting(true)
try {
const port = await subStorePort()
const sub = collections.find(
(sub) => sub.name === key.toString().replace('sub-', '')
const collection = collections.find(
(collection) =>
collection.name === key.toString().replace('collection-', '')
)
await addProfileItem({
name: sub?.displayName ?? '',
name: collection?.displayName ?? '',
type: 'remote',
url: `http://127.0.0.1:${port}/download/collection/${key.toString().replace('collection-', '')}?target=ClashMeta`,
url: useCustomSubStore
? `${customSubStoreUrl}/download/collection/${key.toString().replace('collection-', '')}?target=ClashMeta`
: `http://127.0.0.1:${port}/download/collection/${key.toString().replace('collection-', '')}?target=ClashMeta`,
useProxy
})
} catch (e) {

View File

@ -220,6 +220,8 @@ interface IAppConfig {
connectionDirection: 'asc' | 'desc'
connectionOrderBy: 'time' | 'upload' | 'download' | 'uploadSpeed' | 'downloadSpeed'
useSubStore: boolean
useCustomSubStore?: boolean
customSubStoreUrl?: string
autoSetDNS?: boolean
originDNS?: string
useWindowFrame: boolean