Skip to content

Commit

Permalink
support narrow sidebar style
Browse files Browse the repository at this point in the history
  • Loading branch information
pompurin404 committed Oct 19, 2024
1 parent a5f825d commit 1be9c62
Show file tree
Hide file tree
Showing 14 changed files with 463 additions and 80 deletions.
117 changes: 78 additions & 39 deletions src/renderer/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,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 (
Expand All @@ -167,7 +167,9 @@ const App: React.FC = () => {
}}
onMouseMove={(e) => {
if (!resizing) return
if (e.clientX <= 250) {
if (e.clientX <= 150) {
setSiderWidthValue(70)
} else if (e.clientX <= 250) {
setSiderWidthValue(250)
} else if (e.clientX >= 400) {
setSiderWidthValue(400)
Expand All @@ -177,19 +179,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 === 70 ? (
<div className="side h-full w-[70px]">
<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"
Expand All @@ -199,23 +205,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)
Expand Down
33 changes: 29 additions & 4 deletions src/renderer/src/components/sider/conn-card.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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)
Expand Down Expand Up @@ -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={{
Expand Down
33 changes: 30 additions & 3 deletions src/renderer/src/components/sider/dns-card.tsx
Original file line number Diff line number Diff line change
@@ -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 || {}
Expand All @@ -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={{
Expand Down
34 changes: 31 additions & 3 deletions src/renderer/src/components/sider/log-card.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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={{
Expand Down
34 changes: 30 additions & 4 deletions src/renderer/src/components/sider/mihomo-core-card.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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={{
Expand Down
Loading

0 comments on commit 1be9c62

Please sign in to comment.