support global override

This commit is contained in:
pompurin404 2024-09-11 23:59:56 +08:00
parent 1f911d5632
commit 50898906c1
No known key found for this signature in database
6 changed files with 93 additions and 59 deletions

View File

@ -4,9 +4,6 @@
### New Features ### New Features
- 支持自动开启轻量模式 - 代理组图标支持SVG格式
- 优化覆写启用逻辑
### Bug Fixes - 覆写支持全局启用
- 修复日志等级为静默时无法正常启动的问题
- 修复后台运行时的内存泄漏问题

View File

@ -4,7 +4,8 @@ import {
getProfile, getProfile,
getProfileItem, getProfileItem,
getOverride, getOverride,
getOverrideItem getOverrideItem,
getOverrideConfig
} from '../config' } from '../config'
import { mihomoWorkConfigPath, overridePath } from '../utils/dirs' import { mihomoWorkConfigPath, overridePath } from '../utils/dirs'
import yaml from 'yaml' import yaml from 'yaml'
@ -32,8 +33,10 @@ async function overrideProfile(
current: string | undefined, current: string | undefined,
profile: IMihomoConfig profile: IMihomoConfig
): Promise<IMihomoConfig> { ): Promise<IMihomoConfig> {
const { items = [] } = (await getOverrideConfig()) || {}
const globalOverride = items.filter((item) => item.global).map((item) => item.id)
const { override = [] } = (await getProfileItem(current)) || {} const { override = [] } = (await getProfileItem(current)) || {}
for (const ov of override) { for (const ov of globalOverride.concat(override)) {
const item = await getOverrideItem(ov) const item = await getOverrideItem(ov)
const content = await getOverride(ov, item?.ext || 'js') const content = await getOverride(ov, item?.ext || 'js')
switch (item?.ext) { switch (item?.ext) {

View File

@ -5,7 +5,8 @@ import {
ModalBody, ModalBody,
ModalFooter, ModalFooter,
Button, Button,
Input Input,
Switch
} from '@nextui-org/react' } from '@nextui-org/react'
import React, { useState } from 'react' import React, { useState } from 'react'
import SettingItem from '../base/base-setting-item' import SettingItem from '../base/base-setting-item'
@ -57,6 +58,15 @@ const EditInfoModal: React.FC<Props> = (props) => {
/> />
</SettingItem> </SettingItem>
)} )}
<SettingItem title="全局启用">
<Switch
size="sm"
isSelected={values.global}
onValueChange={(v) => {
setValues({ ...values, global: v })
}}
/>
</SettingItem>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button variant="light" onPress={onClose}> <Button variant="light" onPress={onClose}>

View File

@ -10,7 +10,7 @@ import {
} from '@nextui-org/react' } from '@nextui-org/react'
import { IoMdMore, IoMdRefresh } from 'react-icons/io' import { IoMdMore, IoMdRefresh } from 'react-icons/io'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import React, { Key, useEffect, useState } from 'react' import React, { Key, useEffect, useMemo, useState } from 'react'
import EditFileModal from './edit-file-modal' import EditFileModal from './edit-file-modal'
import EditInfoModal from './edit-info-modal' import EditInfoModal from './edit-info-modal'
import { useSortable } from '@dnd-kit/sortable' import { useSortable } from '@dnd-kit/sortable'
@ -34,44 +34,6 @@ interface MenuItem {
className: string className: string
} }
const menuItems: MenuItem[] = [
{
key: 'edit-info',
label: '编辑信息',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'edit-file',
label: '编辑文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'open-file',
label: '打开文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'exec-log',
label: '执行日志',
showDivider: true,
color: 'default',
className: ''
} as MenuItem,
{
key: 'delete',
label: '删除',
showDivider: false,
color: 'danger',
className: 'text-danger'
} as MenuItem
]
const OverrideItem: React.FC<Props> = (props) => { const OverrideItem: React.FC<Props> = (props) => {
const { info, addOverrideItem, removeOverrideItem, mutateOverrideConfig, updateOverrideItem } = const { info, addOverrideItem, removeOverrideItem, mutateOverrideConfig, updateOverrideItem } =
props props
@ -91,7 +53,49 @@ const OverrideItem: React.FC<Props> = (props) => {
}) })
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
const [disableOpen, setDisableOpen] = useState(false) const [disableOpen, setDisableOpen] = useState(false)
const menuItems: MenuItem[] = useMemo(() => {
const list = [
{
key: 'edit-info',
label: '编辑信息',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'edit-file',
label: '编辑文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'open-file',
label: '打开文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'exec-log',
label: '执行日志',
showDivider: true,
color: 'default',
className: ''
} as MenuItem,
{
key: 'delete',
label: '删除',
showDivider: false,
color: 'danger',
className: 'text-danger'
} as MenuItem
]
if (info.ext === 'yaml') {
list.splice(3, 1)
}
return list
}, [info])
const onMenuAction = (key: Key): void => { const onMenuAction = (key: Key): void => {
switch (key) { switch (key) {
case 'edit-info': { case 'edit-info': {
@ -219,10 +223,15 @@ const OverrideItem: React.FC<Props> = (props) => {
</div> </div>
<div className="flex justify-between"> <div className="flex justify-between">
<div className={`mt-2 flex justify-start`}> <div className={`mt-2 flex justify-start`}>
<Chip size="sm" variant="bordered"> {info.global && (
<Chip size="sm" variant="dot" color="primary" className="mr-2">
</Chip>
)}
<Chip size="sm" variant="bordered" className="mr-2">
{info.type === 'local' ? '本地' : '远程'} {info.type === 'local' ? '本地' : '远程'}
</Chip> </Chip>
<Chip size="sm" variant="bordered" className="ml-2"> <Chip size="sm" variant="bordered">
{info.ext === 'yaml' ? 'YAML' : 'JavaScript'} {info.ext === 'yaml' ? 'YAML' : 'JavaScript'}
</Chip> </Chip>
</div> </div>

View File

@ -31,7 +31,13 @@ const EditInfoModal: React.FC<Props> = (props) => {
const onSave = async (): Promise<void> => { const onSave = async (): Promise<void> => {
try { try {
await updateProfileItem(values) await updateProfileItem({
...values,
override: values.override?.filter(
(i) =>
overrideItems.find((t) => t.id === i) && !overrideItems.find((t) => t.id === i)?.global
)
})
await restartCore() await restartCore()
onClose() onClose()
} catch (e) { } catch (e) {
@ -97,8 +103,20 @@ const EditInfoModal: React.FC<Props> = (props) => {
)} )}
<SettingItem title="覆写"> <SettingItem title="覆写">
<div> <div>
{overrideItems
.filter((i) => i.global)
.map((i) => {
return (
<div className="flex mb-2" key={i.id}>
<Button disabled fullWidth variant="flat" size="sm">
{i.name} ()
</Button>
</div>
)
})}
{values.override?.map((i) => { {values.override?.map((i) => {
if (!overrideItems.find((t) => t.id === i)) return null if (!overrideItems.find((t) => t.id === i)) return null
if (overrideItems.find((t) => t.id === i)?.global) return null
return ( return (
<div className="flex mb-2" key={i}> <div className="flex mb-2" key={i}>
<Button disabled fullWidth variant="flat" size="sm"> <Button disabled fullWidth variant="flat" size="sm">
@ -112,9 +130,7 @@ const EditInfoModal: React.FC<Props> = (props) => {
onPress={() => { onPress={() => {
setValues({ setValues({
...values, ...values,
override: values.override override: values.override?.filter((t) => t !== i)
?.filter((i) => overrideItems.find((t) => t.id === i))
.filter((t) => t !== i)
}) })
}} }}
> >
@ -134,14 +150,12 @@ const EditInfoModal: React.FC<Props> = (props) => {
onAction={(key) => { onAction={(key) => {
setValues({ setValues({
...values, ...values,
override: Array.from(values.override || []) override: Array.from(values.override || []).concat(key.toString())
.filter((i) => overrideItems.find((t) => t.id === i))
.concat(key.toString())
}) })
}} }}
> >
{overrideItems {overrideItems
.filter((i) => !values.override?.includes(i.id)) .filter((i) => !values.override?.includes(i.id) && !i.global)
.map((i) => ( .map((i) => (
<DropdownItem key={i.id}>{i.name}</DropdownItem> <DropdownItem key={i.id}>{i.name}</DropdownItem>
))} ))}

View File

@ -389,6 +389,7 @@ interface IOverrideItem {
ext: 'js' | 'yaml' ext: 'js' | 'yaml'
name: string name: string
updated: number updated: number
global?: boolean
url?: string url?: string
file?: string file?: string
} }