support multi column

This commit is contained in:
pompurin404 2024-08-25 19:06:36 +08:00
parent c72618570a
commit d4698583ba
No known key found for this signature in database
6 changed files with 94 additions and 33 deletions

View File

@ -1,6 +1,7 @@
### New Features
- Linux支持手动授权内核
- 代理节点支持多列展示
### Bug Fixes

View File

@ -157,9 +157,6 @@ export function createWindow(show = false): void {
mainWindow.webContents.on('did-fail-load', () => {
mainWindow?.webContents.reload()
})
mainWindow.on('resize', () => {
mainWindow?.webContents.send('resize')
})
mainWindow.on('show', () => {
startMihomoMemory()

View File

@ -58,12 +58,11 @@ export const BaseEditor: React.FC<Props> = (props) => {
}
useEffect(() => {
window.electron.ipcRenderer.on('resize', () => {
window.onresize = (): void => {
editorRef.current?.layout()
})
}
return (): void => {
window.electron.ipcRenderer.removeAllListeners('resize')
window.onresize = null
editorRef.current?.dispose()
editorRef.current = undefined
}

View File

@ -1,7 +1,7 @@
import React, { useState } from 'react'
import SettingCard from '../base/base-setting-card'
import SettingItem from '../base/base-setting-item'
import { Input, Switch } from '@nextui-org/react'
import { Input, Select, SelectItem, Switch } from '@nextui-org/react'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import debounce from '@renderer/utils/debounce'
import { patchControledMihomoConfig } from '@renderer/utils/ipc'
@ -14,7 +14,8 @@ const MihomoConfig: React.FC = () => {
delayTestTimeout,
autoCloseConnection = true,
delayTestUrl,
userAgent
userAgent,
proxyCols = 'auto'
} = appConfig || {}
const [url, setUrl] = useState(delayTestUrl)
const setUrlDebounce = debounce((v: string) => {
@ -62,6 +63,22 @@ const MihomoConfig: React.FC = () => {
}}
/>
</SettingItem>
<SettingItem title="代理节点展示列数" divider>
<Select
className="w-[150px]"
size="sm"
selectedKeys={new Set([proxyCols])}
onSelectionChange={async (v) => {
await patchAppConfig({ proxyCols: v.currentKey as 'auto' | '1' | '2' | '3' | '4' })
}}
>
<SelectItem key="auto"></SelectItem>
<SelectItem key="1"></SelectItem>
<SelectItem key="2"></SelectItem>
<SelectItem key="3"></SelectItem>
<SelectItem key="4"></SelectItem>
</Select>
</SettingItem>
<SettingItem title="接管DNS设置" divider>
<Switch
size="sm"

View File

@ -13,7 +13,7 @@ import { FaBoltLightning } from 'react-icons/fa6'
import { TbCircleLetterD } from 'react-icons/tb'
import { FaLocationCrosshairs } from 'react-icons/fa6'
import { RxLetterCaseCapitalize } from 'react-icons/rx'
import { useMemo, useRef, useState } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import useSWR from 'swr'
import { GroupedVirtuoso, GroupedVirtuosoHandle } from 'react-virtuoso'
import ProxyItem from '@renderer/components/proxies/proxy-item'
@ -26,15 +26,19 @@ const Proxies: React.FC = () => {
const {
proxyDisplayMode = 'simple',
proxyDisplayOrder = 'default',
autoCloseConnection = true
autoCloseConnection = true,
proxyCols = 'auto'
} = appConfig || {}
const [cols, setCols] = useState(1)
const [isOpen, setIsOpen] = useState(Array(groups.length).fill(false))
const virtuosoRef = useRef<GroupedVirtuosoHandle>(null)
const { groupCounts, allProxies } = useMemo(() => {
const groupCounts = groups.map((group, index) => {
return isOpen[index] ? group.all.length : 0
if (!isOpen[index]) return 0
const count = Math.floor(group.all.length / cols)
return group.all.length % cols === 0 ? count : count + 1
})
const allProxies: (IMihomoProxy | IMihomoGroup)[] = []
const allProxies: (IMihomoProxy | IMihomoGroup)[][] = []
groups.forEach((group, index) => {
if (isOpen[index]) {
let groupProxies = [...group.all]
@ -50,7 +54,9 @@ const Proxies: React.FC = () => {
if (proxyDisplayOrder === 'name') {
groupProxies = groupProxies.sort((a, b) => a.name.localeCompare(b.name))
}
allProxies.push(...groupProxies)
allProxies.push(groupProxies)
} else {
allProxies.push([])
}
})
@ -74,6 +80,33 @@ const Proxies: React.FC = () => {
await mihomoGroupDelay(group, url)
}
const calcCols = (): void => {
if (window.innerWidth >= 1280) {
setCols(4)
return
}
if (window.innerWidth >= 1024) {
setCols(3)
return
}
if (window.innerWidth >= 768) {
setCols(2)
return
}
}
useEffect(() => {
if (proxyCols !== 'auto') {
setCols(parseInt(proxyCols))
return
}
calcCols()
window.onresize = calcCols
return (): void => {
window.onresize = null
}
}, [])
return (
<BasePage
title="代理组"
@ -155,7 +188,6 @@ const Proxies: React.FC = () => {
<div className="inline flag-emoji h-[32px] text-md leading-[32px]">
{groups[index].name}
</div>
{proxyDisplayMode === 'full' && (
<div className="inline ml-2 text-sm text-default-500">
{groups[index].type}
@ -185,13 +217,15 @@ const Proxies: React.FC = () => {
for (let j = 0; j < index; j++) {
i += groupCounts[j]
}
for (let j = 0; j < groupCounts[index]; j++) {
if (allProxies[i + j].name === groups[index].now) {
i += j
break
}
}
virtuosoRef.current?.scrollToIndex({ index: i, align: 'start' })
i += Math.floor(
allProxies[index].findIndex(
(proxy) => proxy.name === groups[index].now
) / cols
)
virtuosoRef.current?.scrollToIndex({
index: Math.floor(i),
align: 'start'
})
}}
>
<FaLocationCrosshairs className="text-lg text-default-500" />
@ -220,17 +254,29 @@ const Proxies: React.FC = () => {
)
}}
itemContent={(index, groupIndex) => {
return allProxies[index] ? (
<div className="pt-2 mx-2">
let innerIndex = index
groupCounts.slice(0, groupIndex).forEach((count) => {
innerIndex -= count
})
return allProxies[groupIndex] ? (
<div className={`grid grid-cols-${cols} gap-2 pt-2 mx-2`}>
{Array.from({ length: cols }).map((_, i) => {
if (!allProxies[groupIndex][innerIndex * cols + i]) return null
return (
<ProxyItem
key={allProxies[groupIndex][innerIndex * cols + i].name}
mutateProxies={mutate}
onProxyDelay={onProxyDelay}
onSelect={onChangeProxy}
proxy={allProxies[index]}
proxy={allProxies[groupIndex][innerIndex * cols + i]}
group={groups[groupIndex]}
proxyDisplayMode={proxyDisplayMode}
selected={allProxies[index]?.name === groups[groupIndex].now}
selected={
allProxies[groupIndex][innerIndex * cols + i]?.name === groups[groupIndex].now
}
/>
)
})}
</div>
) : (
<div>Never See This</div>

View File

@ -215,6 +215,7 @@ interface IAppConfig {
proxyDisplayMode: 'simple' | 'full'
proxyDisplayOrder: 'default' | 'delay' | 'name'
envType?: 'bash' | 'cmd' | 'powershell'
proxyCols: 'auto' | '1' | '2' | '3' | '4'
proxyInTray: boolean
siderOrder: string[]
appTheme: AppTheme