support new profile

This commit is contained in:
pompurin404 2024-08-31 21:50:13 +08:00
parent 1f90ae2eed
commit d8b9d59dbb
No known key found for this signature in database
8 changed files with 136 additions and 65 deletions

View File

@ -5,6 +5,7 @@
### New Features
- 支持使用外部编辑器打开文件
- 支持新建订阅/覆写
- 添加窗口置顶按钮
- 允许禁用系统标题栏
- 重写连接页面

View File

@ -2,6 +2,7 @@ export const defaultConfig: IAppConfig = {
core: 'mihomo',
silentStart: false,
appTheme: 'system',
useWindowFrame: true,
proxyInTray: true,
maxLogDays: 7,
proxyCols: 'auto',

View File

@ -104,7 +104,7 @@ const App: React.FC = () => {
// ignore
}
}
}, [appTheme])
}, [appTheme, systemTheme])
const onDragEnd = async (event: DragEndEvent): Promise<void> => {
const { active, over } = event

View File

@ -36,7 +36,7 @@ const BasePage = forwardRef<HTMLDivElement, Props>((props, ref) => {
<div className="sticky top-0 z-40 h-[49px] w-full bg-background">
<div className="app-drag p-2 flex justify-between h-[48px]">
<div className="title h-full text-lg leading-[32px]">{props.title}</div>
<div style={{ marginRight: overlayWidth }} className="header h-full">
<div style={{ marginRight: overlayWidth }} className="header flex gap-2 h-full">
{props.header}
</div>
</div>

View File

@ -1,4 +1,12 @@
import { Button, Divider, Input } from '@nextui-org/react'
import {
Button,
Divider,
Dropdown,
DropdownItem,
DropdownMenu,
DropdownTrigger,
Input
} from '@nextui-org/react'
import BasePage from '@renderer/components/base/base-page'
import { getFilePath, readTextFile } from '@renderer/utils/ipc'
import { useEffect, useRef, useState } from 'react'
@ -14,6 +22,7 @@ import {
import { SortableContext } from '@dnd-kit/sortable'
import { useOverrideConfig } from '@renderer/hooks/use-override-config'
import OverrideItem from '@renderer/components/override/override-item'
import { FaPlus } from 'react-icons/fa6'
const Override: React.FC = () => {
const {
@ -115,7 +124,7 @@ const Override: React.FC = () => {
<>
<Button
size="sm"
className="app-nodrag mr-2"
className="app-nodrag"
onPress={() => {
open('https://mihomo.party/guides/function/override/yaml/')
}}
@ -165,27 +174,52 @@ const Override: React.FC = () => {
>
</Button>
<Button
size="sm"
color="primary"
className="ml-2"
onPress={() => {
getFilePath(['js', 'yaml']).then(async (files) => {
if (files?.length) {
const content = await readTextFile(files[0])
const fileName = files[0].split('/').pop()?.split('\\').pop()
<Dropdown>
<DropdownTrigger>
<Button className="ml-2" size="sm" isIconOnly color="primary">
<FaPlus />
</Button>
</DropdownTrigger>
<DropdownMenu
onAction={async (key) => {
if (key === 'open') {
try {
const files = await getFilePath(['js', 'yaml'])
if (files?.length) {
const content = await readTextFile(files[0])
const fileName = files[0].split('/').pop()?.split('\\').pop()
await addOverrideItem({
name: fileName,
type: 'local',
file: content,
ext: fileName?.endsWith('.js') ? 'js' : 'yaml'
})
}
} catch (e) {
alert(e)
}
} else if (key === 'new-yaml') {
await addOverrideItem({
name: fileName,
name: '新建YAML',
type: 'local',
file: content,
ext: fileName?.endsWith('.js') ? 'js' : 'yaml'
file: '# https://mihomo.party/guides/function/override/yaml/',
ext: 'yaml'
})
} else if (key === 'new-js') {
await addOverrideItem({
name: '新建JS',
type: 'local',
file: '// https://mihomo.party/guides/function/override/js/\nfunction main(config) {\n return config\n}',
ext: 'js'
})
}
})
}}
>
</Button>
}}
>
<DropdownItem key="open"></DropdownItem>
<DropdownItem key="new-yaml"> YAML</DropdownItem>
<DropdownItem key="new-js"> JavaScript</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Divider />
</div>

View File

@ -1,4 +1,13 @@
import { Button, Checkbox, Divider, Input } from '@nextui-org/react'
import {
Button,
Checkbox,
Divider,
Dropdown,
DropdownItem,
DropdownMenu,
DropdownTrigger,
Input
} from '@nextui-org/react'
import BasePage from '@renderer/components/base/base-page'
import ProfileItem from '@renderer/components/profiles/profile-item'
import { useProfileConfig } from '@renderer/hooks/use-profile-config'
@ -14,6 +23,7 @@ import {
DragEndEvent
} from '@dnd-kit/core'
import { SortableContext } from '@dnd-kit/sortable'
import { FaPlus } from 'react-icons/fa6'
const Profiles: React.FC = () => {
const {
@ -101,27 +111,38 @@ const Profiles: React.FC = () => {
ref={pageRef}
title="订阅管理"
header={
<Button
size="sm"
className="app-nodrag"
color="primary"
isLoading={updating}
onPress={async () => {
setUpdating(true)
for (const item of items) {
if (item.id === current) continue
if (item.type !== 'remote') continue
await addProfileItem(item)
}
const currentItem = items.find((item) => item.id === current)
if (currentItem && currentItem.type === 'remote') {
await addProfileItem(currentItem)
}
setUpdating(false)
}}
>
</Button>
<>
<Button
size="sm"
className="app-nodrag"
onPress={async () => {
open('https://mihomo.party/ads/airport/')
}}
>
</Button>
<Button
size="sm"
className="app-nodrag"
color="primary"
isLoading={updating}
onPress={async () => {
setUpdating(true)
for (const item of items) {
if (item.id === current) continue
if (item.type !== 'remote') continue
await addProfileItem(item)
}
const currentItem = items.find((item) => item.id === current)
if (currentItem && currentItem.type === 'remote') {
await addProfileItem(currentItem)
}
setUpdating(false)
}}
>
</Button>
</>
}
>
<div className="sticky top-0 z-40 bg-background">
@ -165,25 +186,38 @@ const Profiles: React.FC = () => {
>
</Button>
<Button
size="sm"
color="primary"
className="ml-2"
onPress={async () => {
try {
const files = await getFilePath(['yml', 'yaml'])
if (files?.length) {
const content = await readTextFile(files[0])
const fileName = files[0].split('/').pop()?.split('\\').pop()
await addProfileItem({ name: fileName, type: 'local', file: content })
<Dropdown>
<DropdownTrigger>
<Button className="ml-2" size="sm" isIconOnly color="primary">
<FaPlus />
</Button>
</DropdownTrigger>
<DropdownMenu
onAction={async (key) => {
if (key === 'open') {
try {
const files = await getFilePath(['yml', 'yaml'])
if (files?.length) {
const content = await readTextFile(files[0])
const fileName = files[0].split('/').pop()?.split('\\').pop()
await addProfileItem({ name: fileName, type: 'local', file: content })
}
} catch (e) {
alert(e)
}
} else if (key === 'new') {
await addProfileItem({
name: '新建订阅',
type: 'local',
file: 'proxies: []\nproxy-groups: []\nrules: []'
})
}
} catch (e) {
alert(e)
}
}}
>
</Button>
}}
>
<DropdownItem key="open"></DropdownItem>
<DropdownItem key="new"></DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<Divider />
</div>

View File

@ -110,10 +110,11 @@ const Proxies: React.FC = () => {
<BasePage
title="代理组"
header={
<div className="app-nodrag">
<>
<Button
size="sm"
isIconOnly
className="app-nodrag"
onPress={() => {
patchAppConfig({
proxyDisplayOrder:
@ -136,7 +137,7 @@ const Proxies: React.FC = () => {
<Button
size="sm"
isIconOnly
className="ml-2"
className="app-nodrag"
onPress={() => {
patchAppConfig({
proxyDisplayMode: proxyDisplayMode === 'simple' ? 'full' : 'simple'
@ -149,7 +150,7 @@ const Proxies: React.FC = () => {
<CgDetailsLess size={20} title="简洁信息" />
)}
</Button>
</div>
</>
}
>
<div className="h-[calc(100vh-50px)]">

View File

@ -18,7 +18,7 @@ const Settings: React.FC = () => {
isIconOnly
size="sm"
title="官方文档"
className="app-nodrag mr-2"
className="app-nodrag"
onPress={() => {
window.open('https://mihomo.party')
}}