mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-16 03:32:17 +08:00
support narrow sidebar style
This commit is contained in:
parent
a5f825d5ca
commit
f193dbe696
|
@ -37,6 +37,7 @@ import { driver } from 'driver.js'
|
|||
import 'driver.js/dist/driver.css'
|
||||
|
||||
let navigate: NavigateFunction
|
||||
const narrowWidth = platform === 'darwin' ? 70 : 60
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
|
@ -142,19 +143,19 @@ const App: React.FC = () => {
|
|||
}
|
||||
|
||||
const componentMap = {
|
||||
sysproxy: <SysproxySwitcher key="sysproxy" />,
|
||||
tun: <TunSwitcher key="tun" />,
|
||||
profile: <ProfileCard key="profile" />,
|
||||
proxy: <ProxyCard key="proxy" />,
|
||||
mihomo: <MihomoCoreCard key="mihomo" />,
|
||||
connection: <ConnCard key="connection" />,
|
||||
dns: <DNSCard key="dns" />,
|
||||
sniff: <SniffCard key="sniff" />,
|
||||
log: <LogCard key="log" />,
|
||||
rule: <RuleCard key="rule" />,
|
||||
resource: <ResourceCard key="resource" />,
|
||||
override: <OverrideCard key="override" />,
|
||||
substore: <SubStoreCard key="substore" />
|
||||
sysproxy: SysproxySwitcher,
|
||||
tun: TunSwitcher,
|
||||
profile: ProfileCard,
|
||||
proxy: ProxyCard,
|
||||
mihomo: MihomoCoreCard,
|
||||
connection: ConnCard,
|
||||
dns: DNSCard,
|
||||
sniff: SniffCard,
|
||||
log: LogCard,
|
||||
rule: RuleCard,
|
||||
resource: ResourceCard,
|
||||
override: OverrideCard,
|
||||
substore: SubStoreCard
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -167,7 +168,9 @@ const App: React.FC = () => {
|
|||
}}
|
||||
onMouseMove={(e) => {
|
||||
if (!resizing) return
|
||||
if (e.clientX <= 250) {
|
||||
if (e.clientX <= 150) {
|
||||
setSiderWidthValue(narrowWidth)
|
||||
} else if (e.clientX <= 250) {
|
||||
setSiderWidthValue(250)
|
||||
} else if (e.clientX >= 400) {
|
||||
setSiderWidthValue(400)
|
||||
|
@ -177,19 +180,23 @@ const App: React.FC = () => {
|
|||
}}
|
||||
className={`w-full h-[100vh] flex ${resizing ? 'cursor-ew-resize' : ''}`}
|
||||
>
|
||||
<div
|
||||
style={{ width: `${siderWidthValue}px` }}
|
||||
className="side h-full overflow-y-auto no-scrollbar"
|
||||
>
|
||||
<div className="app-drag sticky top-0 z-40 backdrop-blur bg-transparent h-[49px]">
|
||||
<div
|
||||
className={`flex justify-between p-2 ${!useWindowFrame && platform === 'darwin' ? 'ml-[60px]' : ''}`}
|
||||
>
|
||||
<div className="flex ml-1">
|
||||
{siderWidthValue === narrowWidth ? (
|
||||
<div style={{ width: `${narrowWidth}px` }} className="side h-full">
|
||||
<div className="app-drag flex justify-center items-center z-40 bg-transparent h-[49px]">
|
||||
{platform !== 'darwin' && (
|
||||
<MihomoIcon className="h-[32px] leading-[32px] text-lg mx-[1px]" />
|
||||
<h3 className="text-lg font-bold leading-[32px]">ihomo Party</h3>
|
||||
)}
|
||||
</div>
|
||||
<div className="h-[calc(100%-110px)] overflow-y-auto no-scrollbar">
|
||||
<div className="h-full w-full flex flex-col gap-2">
|
||||
{order.map((key: string) => {
|
||||
const Component = componentMap[key]
|
||||
if (!Component) return null
|
||||
return <Component key={key} iconOnly={true} />
|
||||
})}
|
||||
</div>
|
||||
<UpdaterButton />
|
||||
</div>
|
||||
<div className="mt-2 flex justify-center items-center h-[48px]">
|
||||
<Button
|
||||
size="sm"
|
||||
className="app-nodrag"
|
||||
|
@ -199,23 +206,56 @@ const App: React.FC = () => {
|
|||
onPress={() => {
|
||||
navigate('/settings')
|
||||
}}
|
||||
startContent={<IoSettings className="text-[20px]" />}
|
||||
/>
|
||||
>
|
||||
<IoSettings className="text-[20px]" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2 mx-2">
|
||||
<OutboundModeSwitcher />
|
||||
</div>
|
||||
<DndContext sensors={sensors} collisionDetection={closestCorners} onDragEnd={onDragEnd}>
|
||||
<div className="grid grid-cols-2 gap-2 m-2">
|
||||
<SortableContext items={order}>
|
||||
{order.map((key: string) => {
|
||||
return componentMap[key]
|
||||
})}
|
||||
</SortableContext>
|
||||
) : (
|
||||
<div
|
||||
style={{ width: `${siderWidthValue}px` }}
|
||||
className="side h-full overflow-y-auto no-scrollbar"
|
||||
>
|
||||
<div className="app-drag sticky top-0 z-40 backdrop-blur bg-transparent h-[49px]">
|
||||
<div
|
||||
className={`flex justify-between p-2 ${!useWindowFrame && platform === 'darwin' ? 'ml-[60px]' : ''}`}
|
||||
>
|
||||
<div className="flex ml-1">
|
||||
<MihomoIcon className="h-[32px] leading-[32px] text-lg mx-[1px]" />
|
||||
<h3 className="text-lg font-bold leading-[32px]">ihomo Party</h3>
|
||||
</div>
|
||||
<UpdaterButton />
|
||||
<Button
|
||||
size="sm"
|
||||
className="app-nodrag"
|
||||
isIconOnly
|
||||
color={location.pathname.includes('/settings') ? 'primary' : 'default'}
|
||||
variant={location.pathname.includes('/settings') ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/settings')
|
||||
}}
|
||||
>
|
||||
<IoSettings className="text-[20px]" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DndContext>
|
||||
</div>
|
||||
<div className="mt-2 mx-2">
|
||||
<OutboundModeSwitcher />
|
||||
</div>
|
||||
<DndContext sensors={sensors} collisionDetection={closestCorners} onDragEnd={onDragEnd}>
|
||||
<div className="grid grid-cols-2 gap-2 m-2">
|
||||
<SortableContext items={order}>
|
||||
{order.map((key: string) => {
|
||||
const Component = componentMap[key]
|
||||
if (!Component) return null
|
||||
return <Component key={key} />
|
||||
})}
|
||||
</SortableContext>
|
||||
</div>
|
||||
</DndContext>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
onMouseDown={() => {
|
||||
setResizing(true)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { FaCircleArrowDown, FaCircleArrowUp } from 'react-icons/fa6'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { calcTraffic } from '@renderer/utils/calc'
|
||||
import { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { IoLink } from 'react-icons/io5'
|
||||
|
@ -16,11 +16,16 @@ let currentDownload: number | undefined = undefined
|
|||
let hasShowTraffic = false
|
||||
let drawing = false
|
||||
|
||||
const ConnCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
const ConnCard: React.FC<Props> = (props) => {
|
||||
const { theme = 'system', systemTheme = 'dark' } = useTheme()
|
||||
const { iconOnly } = props
|
||||
const { appConfig } = useAppConfig()
|
||||
const { showTraffic = false, connectionCardStatus = 'col-span-2', customTheme } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/connections')
|
||||
|
||||
const [upload, setUpload] = useState(0)
|
||||
|
@ -87,6 +92,26 @@ const ConnCard: React.FC = () => {
|
|||
}
|
||||
}, [showTraffic])
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${connectionCardStatus} flex justify-center`}>
|
||||
<Tooltip content="连接" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/connections')
|
||||
}}
|
||||
>
|
||||
<IoLink className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { LuServer } from 'react-icons/lu'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { patchMihomoConfig } from '@renderer/utils/ipc'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
const DNSCard: React.FC = () => {
|
||||
import React from 'react'
|
||||
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
const DNSCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/dns')
|
||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||
const { dns, tun } = controledMihomoConfig || {}
|
||||
|
@ -31,6 +38,26 @@ const DNSCard: React.FC = () => {
|
|||
await patchMihomoConfig({ dns: { enable } })
|
||||
}
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''} flex justify-center`}>
|
||||
<Tooltip content="DNS" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/dns')
|
||||
}}
|
||||
>
|
||||
<LuServer className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { IoJournalOutline } from 'react-icons/io5'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
const LogCard: React.FC = () => {
|
||||
import React from 'react'
|
||||
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const LogCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { logCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/logs')
|
||||
const {
|
||||
attributes,
|
||||
|
@ -20,6 +28,26 @@ const LogCard: React.FC = () => {
|
|||
id: 'log'
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${logCardStatus} flex justify-center`}>
|
||||
<Tooltip content="日志" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/logs')
|
||||
}}
|
||||
>
|
||||
<IoJournalOutline className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { calcTraffic } from '@renderer/utils/calc'
|
||||
import { mihomoVersion, restartCore } from '@renderer/utils/ipc'
|
||||
import { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { IoMdRefresh } from 'react-icons/io'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import PubSub from 'pubsub-js'
|
||||
import useSWR from 'swr'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { LuCpu } from 'react-icons/lu'
|
||||
|
||||
const MihomoCoreCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const MihomoCoreCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { mihomoCoreCardStatus = 'col-span-2' } = appConfig || {}
|
||||
const { data: version, mutate } = useSWR('mihomoVersion', mihomoVersion)
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/mihomo')
|
||||
const {
|
||||
attributes,
|
||||
|
@ -43,6 +49,26 @@ const MihomoCoreCard: React.FC = () => {
|
|||
}
|
||||
}, [])
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${mihomoCoreCardStatus} flex justify-center`}>
|
||||
<Tooltip content="内核设置" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/mihomo')
|
||||
}}
|
||||
>
|
||||
<LuCpu className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import React from 'react'
|
||||
import { MdFormatOverline } from 'react-icons/md'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
|
||||
const OverrideCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const OverrideCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { overrideCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/override')
|
||||
const {
|
||||
attributes,
|
||||
|
@ -22,6 +28,25 @@ const OverrideCard: React.FC = () => {
|
|||
id: 'override'
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${overrideCardStatus} flex justify-center`}>
|
||||
<Tooltip content="覆写" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/override')
|
||||
}}
|
||||
>
|
||||
<MdFormatOverline className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Button, Card, CardBody, CardFooter, Chip, Progress, Tooltip } from '@nextui-org/react'
|
||||
import { useProfileConfig } from '@renderer/hooks/use-profile-config'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { calcTraffic, calcPercent } from '@renderer/utils/calc'
|
||||
import { CgLoadbarDoc } from 'react-icons/cg'
|
||||
import { IoMdRefresh } from 'react-icons/io'
|
||||
|
@ -9,7 +9,7 @@ import { useSortable } from '@dnd-kit/sortable'
|
|||
import { CSS } from '@dnd-kit/utilities'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import dayjs from 'dayjs'
|
||||
import { useState } from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import ConfigViewer from './config-viewer'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { TiFolder } from 'react-icons/ti'
|
||||
|
@ -17,10 +17,16 @@ import { TiFolder } from 'react-icons/ti'
|
|||
dayjs.extend(relativeTime)
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
const ProfileCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const ProfileCard: React.FC<Props> = (props) => {
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { profileCardStatus = 'col-span-2', profileDisplayDate = 'expire' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/profiles')
|
||||
const [updating, setUpdating] = useState(false)
|
||||
const [showRuntimeConfig, setShowRuntimeConfig] = useState(false)
|
||||
|
@ -47,6 +53,26 @@ const ProfileCard: React.FC = () => {
|
|||
const usage = (extra?.upload ?? 0) + (extra?.download ?? 0)
|
||||
const total = extra?.total ?? 0
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${profileCardStatus} flex justify-center`}>
|
||||
<Tooltip content="订阅管理" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/profiles')
|
||||
}}
|
||||
>
|
||||
<TiFolder className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
import { Button, Card, CardBody, CardFooter, Chip } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Chip, Tooltip } from '@nextui-org/react'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { LuGroup } from 'react-icons/lu'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useGroups } from '@renderer/hooks/use-groups'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import React from 'react'
|
||||
|
||||
const ProxyCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const ProxyCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { proxyCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/proxies')
|
||||
const { groups = [] } = useGroups()
|
||||
const {
|
||||
|
@ -24,6 +31,25 @@ const ProxyCard: React.FC = () => {
|
|||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${proxyCardStatus} flex justify-center`}>
|
||||
<Tooltip content="代理组" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/proxies')
|
||||
}}
|
||||
>
|
||||
<LuGroup className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import React from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { IoLayersOutline } from 'react-icons/io5'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
const ResourceCard: React.FC = () => {
|
||||
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const ResourceCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { resourceCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/resources')
|
||||
const {
|
||||
attributes,
|
||||
|
@ -21,6 +28,26 @@ const ResourceCard: React.FC = () => {
|
|||
id: 'resource'
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${resourceCardStatus} flex justify-center`}>
|
||||
<Tooltip content="外部资源" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/resources')
|
||||
}}
|
||||
>
|
||||
<IoLayersOutline className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
import { Button, Card, CardBody, CardFooter, Chip } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Chip, Tooltip } from '@nextui-org/react'
|
||||
import { MdOutlineAltRoute } from 'react-icons/md'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useRules } from '@renderer/hooks/use-rules'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import React from 'react'
|
||||
|
||||
const RuleCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const RuleCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { ruleCardStatus = 'col-span-1' } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/rules')
|
||||
const { rules } = useRules()
|
||||
const {
|
||||
|
@ -23,6 +30,26 @@ const RuleCard: React.FC = () => {
|
|||
id: 'rule'
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${ruleCardStatus} flex justify-center`}>
|
||||
<Tooltip content="规则" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/rules')
|
||||
}}
|
||||
>
|
||||
<MdOutlineAltRoute className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { RiScan2Fill } from 'react-icons/ri'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { patchMihomoConfig } from '@renderer/utils/ipc'
|
||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import React from 'react'
|
||||
|
||||
const SniffCard: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
const SniffCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { sniffCardStatus = 'col-span-1', controlSniff = true } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/sniffer')
|
||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||
const { sniffer } = controledMihomoConfig || {}
|
||||
|
@ -32,6 +38,26 @@ const SniffCard: React.FC = () => {
|
|||
await patchMihomoConfig({ sniffer: { enable } })
|
||||
}
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''} flex justify-center`}>
|
||||
<Tooltip content="域名嗅探" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/sniffer')
|
||||
}}
|
||||
>
|
||||
<RiScan2Fill className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import SubStoreIcon from '../base/substore-icon'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
const SubStoreCard: React.FC = () => {
|
||||
import React from 'react'
|
||||
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const SubStoreCard: React.FC<Props> = (props) => {
|
||||
const { appConfig } = useAppConfig()
|
||||
const { iconOnly } = props
|
||||
const { substoreCardStatus = 'col-span-1', useSubStore = true } = appConfig || {}
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/substore')
|
||||
const {
|
||||
attributes,
|
||||
|
@ -20,6 +28,27 @@ const SubStoreCard: React.FC = () => {
|
|||
id: 'substore'
|
||||
})
|
||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${substoreCardStatus} flex justify-center`}>
|
||||
<Tooltip content="Sub-Store" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/substore')
|
||||
}}
|
||||
>
|
||||
<SubStoreIcon className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
import { triggerSysProxy } from '@renderer/utils/ipc'
|
||||
import { AiOutlineGlobal } from 'react-icons/ai'
|
||||
|
@ -8,8 +8,14 @@ import React from 'react'
|
|||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
|
||||
const SysproxySwitcher: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const SysproxySwitcher: React.FC<Props> = (props) => {
|
||||
const { iconOnly } = props
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/sysproxy')
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const { sysProxy, sysproxyCardStatus = 'col-span-1' } = appConfig || {}
|
||||
|
@ -36,6 +42,26 @@ const SysproxySwitcher: React.FC = () => {
|
|||
}
|
||||
}
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${sysproxyCardStatus} flex justify-center`}>
|
||||
<Tooltip content="系统代理" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/sysproxy')
|
||||
}}
|
||||
>
|
||||
<AiOutlineGlobal className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
|
||||
import { Button, Card, CardBody, CardFooter, Tooltip } from '@nextui-org/react'
|
||||
import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-config'
|
||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||
import { TbDeviceIpadHorizontalBolt } from 'react-icons/tb'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { restartCore } from '@renderer/utils/ipc'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import React from 'react'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
|
||||
const TunSwitcher: React.FC = () => {
|
||||
interface Props {
|
||||
iconOnly?: boolean
|
||||
}
|
||||
|
||||
const TunSwitcher: React.FC<Props> = (props) => {
|
||||
const { iconOnly } = props
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const match = location.pathname.includes('/tun') || false
|
||||
const { appConfig } = useAppConfig()
|
||||
const { tunCardStatus = 'col-span-1' } = appConfig || {}
|
||||
|
@ -39,6 +45,26 @@ const TunSwitcher: React.FC = () => {
|
|||
window.electron.ipcRenderer.send('updateTrayMenu')
|
||||
}
|
||||
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<div className={`${tunCardStatus} flex justify-center`}>
|
||||
<Tooltip content="虚拟网卡" placement="right">
|
||||
<Button
|
||||
size="sm"
|
||||
isIconOnly
|
||||
color={match ? 'primary' : 'default'}
|
||||
variant={match ? 'solid' : 'light'}
|
||||
onPress={() => {
|
||||
navigate('/tun')
|
||||
}}
|
||||
>
|
||||
<TbDeviceIpadHorizontalBolt className="text-[20px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
|
Loading…
Reference in New Issue
Block a user