mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-15 19:22:31 +08:00
support substore cron
This commit is contained in:
parent
9f5a39f652
commit
3eabb15efb
|
@ -4,11 +4,8 @@
|
|||
|
||||
### New Features
|
||||
|
||||
- 代理组图标支持SVG格式
|
||||
- 优化覆写启用逻辑
|
||||
- 覆写支持全局启用
|
||||
- 筛选过滤忽略大小写
|
||||
- 支持设置 Sub-Store 定时同步
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- 修复 MacOS 上复制粘贴快捷键失效的问题
|
||||
- 修复全局覆写重复执行的问题
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
"@types/ws": "^8.5.12",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cron-validator": "^1.3.1",
|
||||
"driver.js": "^1.3.1",
|
||||
"electron": "^32.0.2",
|
||||
"electron-builder": "^25.0.5",
|
||||
|
|
|
@ -93,6 +93,9 @@ importers:
|
|||
autoprefixer:
|
||||
specifier: ^10.4.20
|
||||
version: 10.4.20(postcss@8.4.45)
|
||||
cron-validator:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1
|
||||
driver.js:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1
|
||||
|
@ -2661,6 +2664,9 @@ packages:
|
|||
crc@3.8.0:
|
||||
resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==}
|
||||
|
||||
cron-validator@1.3.1:
|
||||
resolution: {integrity: sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -8717,6 +8723,8 @@ snapshots:
|
|||
buffer: 5.7.1
|
||||
optional: true
|
||||
|
||||
cron-validator@1.3.1: {}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
|
|
|
@ -57,7 +57,13 @@ export async function startPacServer(): Promise<void> {
|
|||
}
|
||||
|
||||
export async function startSubStoreServer(): Promise<void> {
|
||||
const { useSubStore = true, useCustomSubStore = false } = await getAppConfig()
|
||||
const {
|
||||
useSubStore = true,
|
||||
useCustomSubStore = false,
|
||||
subStoreBackendSyncCron = '',
|
||||
subStoreBackendDownloadCron = '',
|
||||
subStoreBackendUploadCron = ''
|
||||
} = await getAppConfig()
|
||||
if (!useSubStore) return
|
||||
if (!subStoreFrontendPort) {
|
||||
subStoreFrontendPort = await findAvailablePort(4000)
|
||||
|
@ -74,7 +80,10 @@ export async function startSubStoreServer(): Promise<void> {
|
|||
SUB_STORE_BACKEND_API_PORT: subStorePort.toString(),
|
||||
SUB_STORE_DATA_BASE_PATH: subStoreDir(),
|
||||
SUB_STORE_BACKEND_CUSTOM_ICON: icon.toDataURL(),
|
||||
SUB_STORE_BACKEND_CUSTOM_NAME: 'Mihomo Party'
|
||||
SUB_STORE_BACKEND_CUSTOM_NAME: 'Mihomo Party',
|
||||
SUB_STORE_BACKEND_SYNC_CRON: subStoreBackendSyncCron,
|
||||
SUB_STORE_BACKEND_DOWNLOAD_CRON: subStoreBackendDownloadCron,
|
||||
SUB_STORE_BACKEND_UPLOAD_CRON: subStoreBackendUploadCron
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,7 +14,12 @@ const SettingCard: React.FC<Props> = (props) => {
|
|||
</Card>
|
||||
) : (
|
||||
<Accordion isCompact className={`${props.className} my-2`} variant="splitted" {...props}>
|
||||
<AccordionItem hideIndicator keepContentMounted title={props.title}>
|
||||
<AccordionItem
|
||||
className="data-[open=true]:pb-2"
|
||||
hideIndicator
|
||||
keepContentMounted
|
||||
title={props.title}
|
||||
>
|
||||
{props.children}
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Key, useState } from 'react'
|
||||
import React, { Key } from 'react'
|
||||
import SettingCard from '../base/base-setting-card'
|
||||
import SettingItem from '../base/base-setting-item'
|
||||
import { Button, Input, Select, SelectItem, Switch, Tab, Tabs, Tooltip } from '@nextui-org/react'
|
||||
|
@ -10,13 +10,11 @@ import {
|
|||
disableAutoRun,
|
||||
enableAutoRun,
|
||||
relaunchApp,
|
||||
restartCore,
|
||||
startSubStoreServer
|
||||
restartCore
|
||||
} from '@renderer/utils/ipc'
|
||||
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'
|
||||
import { IoIosHelpCircle } from 'react-icons/io'
|
||||
|
||||
const GeneralConfig: React.FC = () => {
|
||||
|
@ -29,20 +27,13 @@ const GeneralConfig: React.FC = () => {
|
|||
showTraffic = true,
|
||||
proxyInTray = true,
|
||||
useWindowFrame = false,
|
||||
useSubStore = true,
|
||||
autoQuitWithoutCore = false,
|
||||
autoQuitWithoutCoreDelay = 60,
|
||||
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('-')
|
||||
|
||||
|
@ -202,50 +193,7 @@ const GeneralConfig: React.FC = () => {
|
|||
</SettingItem>
|
||||
</>
|
||||
)}
|
||||
<SettingItem title="启用 Sub-Store" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={useSubStore}
|
||||
onValueChange={async (v) => {
|
||||
try {
|
||||
await patchAppConfig({ useSubStore: v })
|
||||
if (v) await startSubStoreServer()
|
||||
} catch (e) {
|
||||
alert(e)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
{useSubStore && (
|
||||
<SettingItem title="使用自建 Sub-Store 后端" 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="自建 Sub-Store 后端地址" divider>
|
||||
<Input
|
||||
size="sm"
|
||||
className="w-[60%]"
|
||||
value={subStoreUrl}
|
||||
placeholder="必须包含协议头"
|
||||
onValueChange={(v: string) => {
|
||||
setSubStoreUrl(v)
|
||||
setSubStoreUrlDebounce(v)
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
)}
|
||||
|
||||
<SettingItem title="使用系统标题栏" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
|
|
187
src/renderer/src/components/settings/substore-config.tsx
Normal file
187
src/renderer/src/components/settings/substore-config.tsx
Normal file
|
@ -0,0 +1,187 @@
|
|||
import React, { useState } from 'react'
|
||||
import SettingCard from '@renderer/components/base/base-setting-card'
|
||||
import SettingItem from '@renderer/components/base/base-setting-item'
|
||||
import { Button, Input, Switch } from '@nextui-org/react'
|
||||
import { startSubStoreServer } from '@renderer/utils/ipc'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import debounce from '@renderer/utils/debounce'
|
||||
import { isValidCron } from 'cron-validator'
|
||||
|
||||
const SubStoreConfig: React.FC = () => {
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const {
|
||||
useSubStore = true,
|
||||
useCustomSubStore = false,
|
||||
customSubStoreUrl,
|
||||
subStoreBackendSyncCron,
|
||||
subStoreBackendDownloadCron,
|
||||
subStoreBackendUploadCron
|
||||
} = appConfig || {}
|
||||
|
||||
const [customSubStoreUrlValue, setCustomSubStoreUrlValue] = useState(customSubStoreUrl)
|
||||
const setCustomSubStoreUrl = debounce(async (v: string) => {
|
||||
await patchAppConfig({ customSubStoreUrl: v })
|
||||
}, 500)
|
||||
const [subStoreBackendSyncCronValue, setSubStoreBackendSyncCronValue] =
|
||||
useState(subStoreBackendSyncCron)
|
||||
const [subStoreBackendDownloadCronValue, setSubStoreBackendDownloadCronValue] = useState(
|
||||
subStoreBackendDownloadCron
|
||||
)
|
||||
const [subStoreBackendUploadCronValue, setSubStoreBackendUploadCronValue] =
|
||||
useState(subStoreBackendUploadCron)
|
||||
return (
|
||||
<SettingCard title="Sub-Store 设置">
|
||||
<SettingItem title="启用 Sub-Store" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={useSubStore}
|
||||
onValueChange={async (v) => {
|
||||
try {
|
||||
await patchAppConfig({ useSubStore: v })
|
||||
if (v) await startSubStoreServer()
|
||||
} catch (e) {
|
||||
alert(e)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
{useSubStore && (
|
||||
<SettingItem title="使用自建 Sub-Store 后端" 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="自建 Sub-Store 后端地址">
|
||||
<Input
|
||||
size="sm"
|
||||
className="w-[60%]"
|
||||
value={customSubStoreUrlValue}
|
||||
placeholder="必须包含协议头"
|
||||
onValueChange={(v: string) => {
|
||||
setCustomSubStoreUrlValue(v)
|
||||
setCustomSubStoreUrl(v)
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
) : (
|
||||
<>
|
||||
<SettingItem title="定时同步订阅/文件" divider>
|
||||
<div className="flex w-[60%] gap-2">
|
||||
{subStoreBackendSyncCronValue !== subStoreBackendSyncCron && (
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
onPress={async () => {
|
||||
if (
|
||||
!subStoreBackendSyncCronValue ||
|
||||
isValidCron(subStoreBackendSyncCronValue)
|
||||
) {
|
||||
await patchAppConfig({
|
||||
subStoreBackendSyncCron: subStoreBackendSyncCronValue
|
||||
})
|
||||
new Notification('重启应用生效')
|
||||
} else {
|
||||
alert('Cron 表达式无效')
|
||||
}
|
||||
}}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
)}
|
||||
<Input
|
||||
size="sm"
|
||||
className="flex-grown"
|
||||
value={subStoreBackendSyncCronValue}
|
||||
placeholder="Cron 表达式"
|
||||
onValueChange={(v: string) => {
|
||||
setSubStoreBackendSyncCronValue(v)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SettingItem>
|
||||
<SettingItem title="定时恢复配置" divider>
|
||||
<div className="flex w-[60%] gap-2">
|
||||
{subStoreBackendDownloadCronValue !== subStoreBackendDownloadCron && (
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
onPress={async () => {
|
||||
if (
|
||||
!subStoreBackendDownloadCronValue ||
|
||||
isValidCron(subStoreBackendDownloadCronValue)
|
||||
) {
|
||||
await patchAppConfig({
|
||||
subStoreBackendDownloadCron: subStoreBackendDownloadCronValue
|
||||
})
|
||||
new Notification('重启应用生效')
|
||||
} else {
|
||||
alert('Cron 表达式无效')
|
||||
}
|
||||
}}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
)}
|
||||
<Input
|
||||
size="sm"
|
||||
className="flex-grown"
|
||||
value={subStoreBackendDownloadCronValue}
|
||||
placeholder="Cron 表达式"
|
||||
onValueChange={(v: string) => {
|
||||
setSubStoreBackendDownloadCronValue(v)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SettingItem>
|
||||
<SettingItem title="定时备份配置">
|
||||
<div className="flex w-[60%] gap-2">
|
||||
{subStoreBackendUploadCronValue !== subStoreBackendUploadCron && (
|
||||
<Button
|
||||
size="sm"
|
||||
color="primary"
|
||||
onPress={async () => {
|
||||
if (
|
||||
!subStoreBackendUploadCronValue ||
|
||||
isValidCron(subStoreBackendUploadCronValue)
|
||||
) {
|
||||
await patchAppConfig({
|
||||
subStoreBackendUploadCron: subStoreBackendUploadCronValue
|
||||
})
|
||||
new Notification('重启应用生效')
|
||||
} else {
|
||||
alert('Cron 表达式无效')
|
||||
}
|
||||
}}
|
||||
>
|
||||
确认
|
||||
</Button>
|
||||
)}
|
||||
<Input
|
||||
size="sm"
|
||||
className="flex-grown"
|
||||
value={subStoreBackendUploadCronValue}
|
||||
placeholder="Cron 表达式"
|
||||
onValueChange={(v: string) => {
|
||||
setSubStoreBackendUploadCronValue(v)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SettingItem>
|
||||
</>
|
||||
)}
|
||||
</SettingCard>
|
||||
)
|
||||
}
|
||||
|
||||
export default SubStoreConfig
|
|
@ -9,6 +9,7 @@ import Actions from '@renderer/components/settings/actions'
|
|||
import ShortcutConfig from '@renderer/components/settings/shortcut-config'
|
||||
import { FaTelegramPlane } from 'react-icons/fa'
|
||||
import SiderConfig from '@renderer/components/settings/sider-config'
|
||||
import SubStoreConfig from '@renderer/components/settings/substore-config'
|
||||
|
||||
const Settings: React.FC = () => {
|
||||
return (
|
||||
|
@ -56,6 +57,7 @@ const Settings: React.FC = () => {
|
|||
}
|
||||
>
|
||||
<GeneralConfig />
|
||||
<SubStoreConfig />
|
||||
<SiderConfig />
|
||||
<WebdavConfig />
|
||||
<MihomoConfig />
|
||||
|
|
3
src/shared/types.d.ts
vendored
3
src/shared/types.d.ts
vendored
|
@ -234,6 +234,9 @@ interface IAppConfig {
|
|||
sysproxyCardStatus?: CardStatus
|
||||
tunCardStatus?: CardStatus
|
||||
useSubStore: boolean
|
||||
subStoreBackendSyncCron?: string
|
||||
subStoreBackendDownloadCron?: string
|
||||
subStoreBackendUploadCron?: string
|
||||
autoQuitWithoutCore?: boolean
|
||||
autoQuitWithoutCoreDelay?: number
|
||||
useCustomSubStore?: boolean
|
||||
|
|
Loading…
Reference in New Issue
Block a user