-
This commit is contained in:
253
web/src/pages/Settings.tsx
Normal file
253
web/src/pages/Settings.tsx
Normal file
@@ -0,0 +1,253 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user