From dcb59e767ce59aaca512b92b9bd532d217d66b05 Mon Sep 17 00:00:00 2001 From: pompurin404 Date: Mon, 14 Oct 2024 23:49:59 +0800 Subject: [PATCH] auto pin global group --- src/main/core/manager.ts | 3 +- src/main/core/mihomoApi.ts | 6 + src/main/resolve/tray.ts | 3 + .../src/components/base/collapse-input.tsx | 2 +- .../connections/connection-item.tsx | 2 +- src/renderer/src/components/logs/log-item.tsx | 2 +- .../components/profiles/edit-file-modal.tsx | 2 +- .../src/components/proxies/proxy-item.tsx | 2 +- .../components/resources/proxy-provider.tsx | 6 +- .../components/resources/rule-provider.tsx | 6 +- .../src/components/rules/rule-item.tsx | 2 +- .../sider/outbound-mode-switcher.tsx | 3 + src/renderer/src/hooks/use-groups.tsx | 4 +- src/renderer/src/hooks/use-rules.tsx | 4 +- src/renderer/src/pages/proxies.tsx | 354 +++++++++--------- 15 files changed, 213 insertions(+), 188 deletions(-) diff --git a/src/main/core/manager.ts b/src/main/core/manager.ts index 78b9437..4970a81 100644 --- a/src/main/core/manager.ts +++ b/src/main/core/manager.ts @@ -147,7 +147,8 @@ export async function startCore(detached = false): Promise[]> { child.stdout?.on('data', async (data) => { if (data.toString().includes('Start initial Compatible provider default')) { try { - mainWindow?.webContents.send('coreRestart') + mainWindow?.webContents.send('groupsUpdated') + mainWindow?.webContents.send('rulesUpdated') await uploadRuntimeConfig() } catch { // ignore diff --git a/src/main/core/mihomoApi.ts b/src/main/core/mihomoApi.ts index f53c95c..89d309d 100644 --- a/src/main/core/mihomoApi.ts +++ b/src/main/core/mihomoApi.ts @@ -76,6 +76,8 @@ export const mihomoProxies = async (): Promise => { } export const mihomoGroups = async (): Promise => { + const { mode = 'rule' } = await getControledMihomoConfig() + if (mode === 'direct') return [] const proxies = await mihomoProxies() const runtime = await getRuntimeConfig() const groups: IMihomoMixedGroup[] = [] @@ -95,6 +97,10 @@ export const mihomoGroups = async (): Promise => { groups.push({ ...newGlobal, all: newAll }) } } + if (mode === 'global') { + const global = groups.findIndex((group) => group.name === 'GLOBAL') + groups.unshift(groups.splice(global, 1)[0]) + } return groups } diff --git a/src/main/resolve/tray.ts b/src/main/resolve/tray.ts index b0f29f6..a17544b 100644 --- a/src/main/resolve/tray.ts +++ b/src/main/resolve/tray.ts @@ -111,6 +111,7 @@ export const buildContextMenu = async (): Promise => { await patchControledMihomoConfig({ mode: 'rule' }) await patchMihomoConfig({ mode: 'rule' }) mainWindow?.webContents.send('controledMihomoConfigUpdated') + mainWindow?.webContents.send('groupsUpdated') ipcMain.emit('updateTrayMenu') } }, @@ -124,6 +125,7 @@ export const buildContextMenu = async (): Promise => { await patchControledMihomoConfig({ mode: 'global' }) await patchMihomoConfig({ mode: 'global' }) mainWindow?.webContents.send('controledMihomoConfigUpdated') + mainWindow?.webContents.send('groupsUpdated') ipcMain.emit('updateTrayMenu') } }, @@ -137,6 +139,7 @@ export const buildContextMenu = async (): Promise => { await patchControledMihomoConfig({ mode: 'direct' }) await patchMihomoConfig({ mode: 'direct' }) mainWindow?.webContents.send('controledMihomoConfigUpdated') + mainWindow?.webContents.send('groupsUpdated') ipcMain.emit('updateTrayMenu') } }, diff --git a/src/renderer/src/components/base/collapse-input.tsx b/src/renderer/src/components/base/collapse-input.tsx index 6651567..5085764 100644 --- a/src/renderer/src/components/base/collapse-input.tsx +++ b/src/renderer/src/components/base/collapse-input.tsx @@ -22,7 +22,7 @@ const CollapseInput: React.FC = (props) => { }} endContent={
{ e.stopPropagation() inputRef.current?.focus() diff --git a/src/renderer/src/components/connections/connection-item.tsx b/src/renderer/src/components/connections/connection-item.tsx index 640dc48..7e40faf 100644 --- a/src/renderer/src/components/connections/connection-item.tsx +++ b/src/renderer/src/components/connections/connection-item.tsx @@ -51,7 +51,7 @@ const ConnectionItem: React.FC = (props) => { info.metadata.destinationIP || info.metadata.remoteDestination}
- + {dayjs(info.start).fromNow()} diff --git a/src/renderer/src/components/logs/log-item.tsx b/src/renderer/src/components/logs/log-item.tsx index 6608a4b..d30122b 100644 --- a/src/renderer/src/components/logs/log-item.tsx +++ b/src/renderer/src/components/logs/log-item.tsx @@ -16,7 +16,7 @@ const LogItem: React.FC = (props) => {
{props.type.toUpperCase()}
- {time} + {time} {payload} diff --git a/src/renderer/src/components/profiles/edit-file-modal.tsx b/src/renderer/src/components/profiles/edit-file-modal.tsx index 49051c6..4e7fc5e 100644 --- a/src/renderer/src/components/profiles/edit-file-modal.tsx +++ b/src/renderer/src/components/profiles/edit-file-modal.tsx @@ -34,7 +34,7 @@ const EditFileModal: React.FC = (props) => {
编辑订阅
- + 注意:此处编辑配置更新订阅后会还原,如需要自定义配置请使用
{proxyDisplayMode === 'full' && ( -
+
{proxy.type}
)} diff --git a/src/renderer/src/components/resources/proxy-provider.tsx b/src/renderer/src/components/resources/proxy-provider.tsx index f705f95..70ba307 100644 --- a/src/renderer/src/components/resources/proxy-provider.tsx +++ b/src/renderer/src/components/resources/proxy-provider.tsx @@ -71,7 +71,7 @@ const ProxyProvider: React.FC = () => { divider={!provider.subscriptionInfo && index !== providers.length - 1} > { -
+
{dayjs(provider.updatedAt).fromNow()}
} + title={
{provider.format}
} divider={index !== providers.length - 1} > -
+
{provider.vehicleType}::{provider.behavior}
diff --git a/src/renderer/src/components/rules/rule-item.tsx b/src/renderer/src/components/rules/rule-item.tsx index 4bf75a9..fa6ca36 100644 --- a/src/renderer/src/components/rules/rule-item.tsx +++ b/src/renderer/src/components/rules/rule-item.tsx @@ -10,7 +10,7 @@ const RuleItem: React.FC = (props) => {
{payload}
-
+
{type}
{proxy}
diff --git a/src/renderer/src/components/sider/outbound-mode-switcher.tsx b/src/renderer/src/components/sider/outbound-mode-switcher.tsx index 9fc9404..11d2df6 100644 --- a/src/renderer/src/components/sider/outbound-mode-switcher.tsx +++ b/src/renderer/src/components/sider/outbound-mode-switcher.tsx @@ -1,11 +1,13 @@ import { Tabs, Tab } from '@nextui-org/react' import { useAppConfig } from '@renderer/hooks/use-app-config' import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config' +import { useGroups } from '@renderer/hooks/use-groups' import { mihomoCloseAllConnections, patchMihomoConfig } from '@renderer/utils/ipc' import { Key } from 'react' const OutboundModeSwitcher: React.FC = () => { const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig() + const { mutate: mutateGroups } = useGroups() const { appConfig } = useAppConfig() const { autoCloseConnection = true } = appConfig || {} const { mode } = controledMihomoConfig || {} @@ -16,6 +18,7 @@ const OutboundModeSwitcher: React.FC = () => { if (autoCloseConnection) { await mihomoCloseAllConnections() } + mutateGroups() window.electron.ipcRenderer.send('updateTrayMenu') } if (!mode) return null diff --git a/src/renderer/src/hooks/use-groups.tsx b/src/renderer/src/hooks/use-groups.tsx index 90990c0..c78af9d 100644 --- a/src/renderer/src/hooks/use-groups.tsx +++ b/src/renderer/src/hooks/use-groups.tsx @@ -16,11 +16,11 @@ export const GroupsProvider: React.FC<{ children: ReactNode }> = ({ children }) }) React.useEffect(() => { - window.electron.ipcRenderer.on('coreRestart', () => { + window.electron.ipcRenderer.on('groupsUpdated', () => { mutate() }) return (): void => { - window.electron.ipcRenderer.removeAllListeners('coreRestart') + window.electron.ipcRenderer.removeAllListeners('groupsUpdated') } }, []) diff --git a/src/renderer/src/hooks/use-rules.tsx b/src/renderer/src/hooks/use-rules.tsx index 638ea1a..357880d 100644 --- a/src/renderer/src/hooks/use-rules.tsx +++ b/src/renderer/src/hooks/use-rules.tsx @@ -16,11 +16,11 @@ export const RulesProvider: React.FC<{ children: ReactNode }> = ({ children }) = }) React.useEffect(() => { - window.electron.ipcRenderer.on('coreRestart', () => { + window.electron.ipcRenderer.on('rulesUpdated', () => { mutate() }) return (): void => { - window.electron.ipcRenderer.removeAllListeners('coreRestart') + window.electron.ipcRenderer.removeAllListeners('rulesUpdated') } }, []) diff --git a/src/renderer/src/pages/proxies.tsx b/src/renderer/src/pages/proxies.tsx index 8edc398..57659c6 100644 --- a/src/renderer/src/pages/proxies.tsx +++ b/src/renderer/src/pages/proxies.tsx @@ -15,12 +15,15 @@ import { useEffect, useMemo, useRef, useState } from 'react' import { GroupedVirtuoso, GroupedVirtuosoHandle } from 'react-virtuoso' import ProxyItem from '@renderer/components/proxies/proxy-item' import { IoIosArrowBack } from 'react-icons/io' -import { MdOutlineSpeed } from 'react-icons/md' +import { MdDoubleArrow, MdOutlineSpeed } from 'react-icons/md' import { useGroups } from '@renderer/hooks/use-groups' import CollapseInput from '@renderer/components/base/collapse-input' import { includesIgnoreCase } from '@renderer/utils/includes' +import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config' const Proxies: React.FC = () => { + const { controledMihomoConfig } = useControledMihomoConfig() + const { mode = 'rule' } = controledMihomoConfig || {} const { groups = [], mutate } = useGroups() const { appConfig, patchAppConfig } = useAppConfig() const { @@ -197,184 +200,193 @@ const Proxies: React.FC = () => { } > -
- { - if ( - groups[index] && - groups[index].icon && - groups[index].icon.startsWith('http') && - !localStorage.getItem(groups[index].icon) - ) { - getImageDataURL(groups[index].icon).then((dataURL) => { - localStorage.setItem(groups[index].icon, dataURL) - mutate() - }) - } - return groups[index] ? ( -
- { - setIsOpen((prev) => { - const newOpen = [...prev] - newOpen[index] = !prev[index] - return newOpen - }) - }} + {mode === 'direct' ? ( +
+
+ +

直连模式

+
+
+ ) : ( +
+ { + if ( + groups[index] && + groups[index].icon && + groups[index].icon.startsWith('http') && + !localStorage.getItem(groups[index].icon) + ) { + getImageDataURL(groups[index].icon).then((dataURL) => { + localStorage.setItem(groups[index].icon, dataURL) + mutate() + }) + } + return groups[index] ? ( +
- -
-
- {groups[index].icon ? ( - - ) : null} -
-
- {groups[index].name} -
- {proxyDisplayMode === 'full' && ( + { + setIsOpen((prev) => { + const newOpen = [...prev] + newOpen[index] = !prev[index] + return newOpen + }) + }} + > + +
+
+ {groups[index].icon ? ( + + ) : null} +
- {groups[index].type} + {groups[index].name}
- )} + {proxyDisplayMode === 'full' && ( +
+ {groups[index].type} +
+ )} + {proxyDisplayMode === 'full' && ( +
+ {groups[index].now} +
+ )} +
+
+
{proxyDisplayMode === 'full' && ( -
- {groups[index].now} -
+ + {groups[index].all.length} + )} + { + setSearchValue((prev) => { + const newSearchValue = [...prev] + newSearchValue[index] = v + return newSearchValue + }) + }} + /> + + +
-
- {proxyDisplayMode === 'full' && ( - - {groups[index].all.length} - - )} - { - setSearchValue((prev) => { - const newSearchValue = [...prev] - newSearchValue[index] = v - return newSearchValue - }) - }} - /> - - - -
-
- - -
- ) : ( -
Never See This
- ) - }} - itemContent={(index, groupIndex) => { - let innerIndex = index - groupCounts.slice(0, groupIndex).forEach((count) => { - innerIndex -= count - }) - return allProxies[groupIndex] ? ( -
- {Array.from({ length: cols }).map((_, i) => { - if (!allProxies[groupIndex][innerIndex * cols + i]) return null - return ( - - ) - })} -
- ) : ( -
Never See This
- ) - }} - /> -
+
+ +
+ ) : ( +
Never See This
+ ) + }} + itemContent={(index, groupIndex) => { + let innerIndex = index + groupCounts.slice(0, groupIndex).forEach((count) => { + innerIndex -= count + }) + return allProxies[groupIndex] ? ( +
+ {Array.from({ length: cols }).map((_, i) => { + if (!allProxies[groupIndex][innerIndex * cols + i]) return null + return ( + + ) + })} +
+ ) : ( +
Never See This
+ ) + }} + /> +
+ )} ) }