253 lines
7.5 KiB
TypeScript
253 lines
7.5 KiB
TypeScript
import {ScrollableBody, ContentHeader, Container} from "@/components/app-content.tsx";
|
|
import {BadgeCheckIcon, SettingsIcon} from "lucide-react";
|
|
import {Item, ItemActions, ItemContent, ItemMedia, ItemTitle} from "@/components/ui/item.tsx";
|
|
import {Switch} from "@/components/ui/switch.tsx";
|
|
import {Button} from "@/components/ui/button.tsx";
|
|
import {TunConfigModal} from "@/components/settings/tun-config-modal.tsx";
|
|
import {useState} from "react";
|
|
import {TunConfig} from "@/lib/types.ts";
|
|
|
|
export function Settings() {
|
|
const [tunModalOpen, setTunModalOpen] = useState(false);
|
|
|
|
// 示例 TUN 配置数据
|
|
const [tunConfig, setTunConfig] = useState<TunConfig>({
|
|
enable: false,
|
|
stack: 'system',
|
|
dnsHijack: ['0.0.0.0:53'],
|
|
autoRoute: true,
|
|
autoDetectInterface: true,
|
|
mtu: 9000,
|
|
});
|
|
|
|
const handleSaveTunConfig = (newConfig: TunConfig) => {
|
|
setTunConfig(newConfig);
|
|
// TODO: 这里应该调用 Tauri 命令保存配置到后端
|
|
console.log('保存 TUN 配置:', newConfig);
|
|
};
|
|
|
|
const config = {
|
|
auto_route: false,
|
|
device: "",
|
|
dns_hijack: [],
|
|
enable: false,
|
|
mtu: 0,
|
|
stack: 'System',
|
|
strict_route: false
|
|
}
|
|
|
|
|
|
if (!config) {
|
|
return (
|
|
<ScrollableBody>
|
|
<ContentHeader>Settings</ContentHeader>
|
|
<div className="p-4">Loading...</div>
|
|
</ScrollableBody>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ScrollableBody>
|
|
<ContentHeader>Settings</ContentHeader>
|
|
<Container className={'py-2 px-4'}>
|
|
<span>App 设置</span>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>开机自启</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>静默启动</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>Clash 内核</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
</Container>
|
|
<Container className={'py-2 px-4 mt-2'}>
|
|
<span>Clash 设置</span>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle className="flex items-center gap-1.5">
|
|
<span>虚拟网卡模式</span>
|
|
<Button
|
|
size={'icon-sm'}
|
|
variant={'ghost'}
|
|
onClick={() => setTunModalOpen(true)}
|
|
className="h-5 w-5 p-0"
|
|
>
|
|
<SettingsIcon className="size-3.5 text-muted-foreground hover:text-foreground transition-colors" />
|
|
</Button>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch
|
|
checked={tunConfig.enable}
|
|
onCheckedChange={(checked) => {
|
|
setTunConfig({ ...tunConfig, enable: checked });
|
|
}}
|
|
/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>允许局域网</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>Ipv6</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>统一延迟</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Switch/>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>日志等级</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
INFO
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>端口设置</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Button size={'icon-sm'} variant={'link'}>7890</Button>
|
|
</ItemActions>
|
|
</Item>
|
|
</Container>
|
|
<Container>
|
|
<span>杂项</span>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>App 目录</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Button size={'icon-sm'} variant={'link'}>7890</Button>
|
|
</ItemActions>
|
|
</Item>
|
|
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>App 配置目录</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Button size={'icon-sm'} variant={'link'}>7890</Button>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>内核目录</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Button size={'icon-sm'} variant={'link'}>7890</Button>
|
|
</ItemActions>
|
|
</Item>
|
|
<Item className={'py-2 px-0'} variant="default" size="sm">
|
|
<ItemMedia>
|
|
<BadgeCheckIcon className="size-5"/>
|
|
</ItemMedia>
|
|
<ItemContent>
|
|
<ItemTitle>
|
|
<span>App 版本</span>
|
|
</ItemTitle>
|
|
</ItemContent>
|
|
<ItemActions>
|
|
<Button size={'icon-sm'} variant={'link'}>7890</Button>
|
|
</ItemActions>
|
|
</Item>
|
|
</Container>
|
|
|
|
<TunConfigModal
|
|
open={tunModalOpen}
|
|
onOpenChange={setTunModalOpen}
|
|
config={tunConfig}
|
|
onSave={handleSaveTunConfig}
|
|
/>
|
|
</ScrollableBody>
|
|
);
|
|
} |