feat: 添加聊天助手功能,创建 ChatDev 页面及相关状态管理;更新路由配置,支持聊天助手的路径

This commit is contained in:
xiongxiao
2026-03-16 00:09:30 +08:00
committed by cnb
parent b4980ab4f9
commit 070d8d8cd1
3 changed files with 116 additions and 0 deletions

View File

@@ -53,6 +53,7 @@
"sigma": "^3.0.2",
"sonner": "^2.0.7",
"three": "^0.183.2",
"three-spritetext": "^1.10.0",
"zustand": "^5.0.11"
},
"publishConfig": {

View File

@@ -0,0 +1,65 @@
import { SlidersHorizontalIcon } from 'lucide-react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@/components/ui/button';
import { Graph3DConfig } from '../modules/graph3d-config';
interface Graph3DConfigDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
config: Graph3DConfig;
onUpdate: (patch: Partial<Graph3DConfig>) => void;
onReset: () => void;
}
export function Graph3DConfigDialog({ open, onOpenChange, config, onUpdate, onReset }: Graph3DConfigDialogProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className='max-w-md'>
<DialogHeader>
<DialogTitle className='flex items-center gap-2'>
<SlidersHorizontalIcon className='w-4 h-4' />
3D
</DialogTitle>
<DialogDescription> 3D </DialogDescription>
</DialogHeader>
<div className='py-2 space-y-5'>
{/* ── 显示 ── */}
<section>
<p className='text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3'></p>
<div className='space-y-3'>
<label className='flex items-center gap-3 cursor-pointer select-none group'>
<Checkbox
checked={config.showLabels}
onCheckedChange={(checked) => onUpdate({ showLabels: !!checked })}
/>
<div>
<p className='text-sm font-medium text-slate-100'></p>
<p className='text-xs text-slate-400'> 3D </p>
</div>
</label>
</div>
</section>
{/* ── 其他配置暂留 ── */}
<section>
<p className='text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3'></p>
<div className='rounded-md border border-dashed border-white/10 px-4 py-3 text-xs text-slate-500'>
</div>
</section>
</div>
<div className='flex justify-between pt-2'>
<Button variant='ghost' size='sm' className='text-slate-400 hover:text-slate-200' onClick={onReset}>
</Button>
<Button size='sm' onClick={() => onOpenChange(false)}>
</Button>
</div>
</DialogContent>
</Dialog>
);
}

View File

@@ -0,0 +1,50 @@
import { useState, useCallback } from 'react';
const STORAGE_KEY = 'code-graph-3d-config';
export interface Graph3DConfig {
/** 是否默认显示文字标签SpriteText */
showLabels: boolean;
// 其他配置项暂留
}
const DEFAULT_CONFIG: Graph3DConfig = {
showLabels: true,
};
function loadConfig(): Graph3DConfig {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return { ...DEFAULT_CONFIG };
return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
} catch {
return { ...DEFAULT_CONFIG };
}
}
function saveConfig(config: Graph3DConfig): void {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
} catch {
// ignore
}
}
export function useGraph3DConfig() {
const [config, setConfigState] = useState<Graph3DConfig>(() => loadConfig());
const updateConfig = useCallback((patch: Partial<Graph3DConfig>) => {
setConfigState((prev) => {
const next = { ...prev, ...patch };
saveConfig(next);
return next;
});
}, []);
const resetConfig = useCallback(() => {
saveConfig(DEFAULT_CONFIG);
setConfigState({ ...DEFAULT_CONFIG });
}, []);
return { config, updateConfig, resetConfig };
}