feat(ai-optimized-editor): Add AIDisplayButton and store to add feature to view last AI generated optimized code

- 添加 AIDisplayButton组件,用于切换 AI 优化代码和原始代码
- 修改 AIOptimizeButton 组件,仅在非 AI 编辑模式下显示
- 在代码工具栏中集成 AIDisplayButton
- 更新 problem-editor store,添加 AIgenerate 和 LastOptimizedCode 状态
-优化 AIEditorWrapper 组件,支持生成优化代码和回退功能
This commit is contained in:
fly6516 2025-06-21 19:03:53 +08:00
parent ac67ad26a1
commit e7e843fee0
5 changed files with 90 additions and 24 deletions

View File

@ -5,24 +5,27 @@ import { DiffEditor } from "@monaco-editor/react";
import { useMonacoTheme } from "@/hooks/use-monaco-theme"; import { useMonacoTheme } from "@/hooks/use-monaco-theme";
import { optimizeCode } from "@/app/actions/ai-improve"; import { optimizeCode } from "@/app/actions/ai-improve";
import { useProblemEditorStore } from "@/stores/problem-editor"; import { useProblemEditorStore } from "@/stores/problem-editor";
// import {LanguageServerConfig} from "@/generated/client";
// import type {editor} from "monaco-editor";
export const AIEditorWrapper = ( export const AIEditorWrapper = () => {
) => {
const { const {
language, language,
value: originalCode, value: originalCode,
// setUseAIEditor,
setLoading, setLoading,
AIgenerate,
LastOptimizedCode,
setLastOptimizedCode,
} = useProblemEditorStore(); } = useProblemEditorStore();
const [optimizedCode, setOptimizedCode] = useState<string>(""); const [optimizedCode, setOptimizedCode] = useState<string>("");
const { theme } = useMonacoTheme(); const { theme } = useMonacoTheme();
useEffect(() => { useEffect(() => {
handleOptimize(); if (AIgenerate) {
}, []); handleOptimize();
} else if (LastOptimizedCode) {
setOptimizedCode(LastOptimizedCode);
}
}, [AIgenerate]);
const handleOptimize = async () => { const handleOptimize = async () => {
setLoading(true); setLoading(true);
@ -33,6 +36,7 @@ export const AIEditorWrapper = (
problemId: "", problemId: "",
}); });
setOptimizedCode(res.optimizedCode); setOptimizedCode(res.optimizedCode);
setLastOptimizedCode(res.optimizedCode);
} catch (err) { } catch (err) {
console.error("优化失败", err); console.error("优化失败", err);
setOptimizedCode("// 优化失败,请稍后重试"); setOptimizedCode("// 优化失败,请稍后重试");

View File

@ -0,0 +1,45 @@
"use client";
import { TooltipButton } from "@/components/tooltip-button";
import { ArrowLeftRight, LoaderCircleIcon, Undo2Icon } from "lucide-react";
import { useProblemEditorStore } from "@/stores/problem-editor";
export const AIDisplayButton = () => {
const { useAIEditor, setUseAIEditor,setAIgenerate ,loading } = useProblemEditorStore();
const handleClick = () => {
setAIgenerate(false);
if (!loading) {
setUseAIEditor(!useAIEditor);
}
};
const tooltipContent = loading
? "AI 正在优化中…"
: useAIEditor
? "返回原始编辑器"
: "查看 AI 优化代码";
return (
<TooltipButton
tooltipContent={tooltipContent}
onClick={handleClick}
disabled={loading}
>
{loading ? (
<LoaderCircleIcon
className="opacity-60 animate-spin"
size={16}
strokeWidth={2}
aria-hidden="true"
/>
) : useAIEditor ? (
<Undo2Icon size={16} strokeWidth={2} aria-hidden="true" />
)
: (
<ArrowLeftRight size={16} strokeWidth={2} aria-hidden="true" />
)
}
</TooltipButton>
);
};

View File

@ -1,40 +1,47 @@
"use client"; "use client";
import { TooltipButton } from "@/components/tooltip-button"; import { TooltipButton } from "@/components/tooltip-button";
import { Wand2Icon, LoaderCircleIcon, Undo2Icon } from "lucide-react"; import { Wand2Icon } from "lucide-react";
//import { LoaderCircleIcon, Undo2Icon } from "lucide-react";
import { useProblemEditorStore } from "@/stores/problem-editor"; import { useProblemEditorStore } from "@/stores/problem-editor";
export const AIOptimizeButton = () => { export const AIOptimizeButton = () => {
const { useAIEditor, setUseAIEditor, loading } = useProblemEditorStore(); const { useAIEditor, setUseAIEditor, setAIgenerate, loading } = useProblemEditorStore();
const handleClick = () => { const handleClick = () => {
setAIgenerate(true);
if (!loading) { if (!loading) {
setUseAIEditor(!useAIEditor); setUseAIEditor(!useAIEditor);
} }
}; };
const tooltipContent = loading // ? "AI 正在优化中…"
? "AI 正在优化中…" // : useAIEditor
: useAIEditor // ? "返回原始编辑器"
? "返回原始编辑器" // : "使用 AI 优化代码";
: "使用 AI 优化代码";
const tooltipContent = "使用 AI 优化代码"; // 仅保留默认提示内容
return ( return (
<TooltipButton <TooltipButton
tooltipContent={tooltipContent} tooltipContent={tooltipContent}
onClick={handleClick} onClick={handleClick}
disabled={loading} disabled={loading || useAIEditor}
> >
{loading ? ( {
<LoaderCircleIcon loading ? (
className="opacity-60 animate-spin" // <LoaderCircleIcon
size={16} // className="opacity-60 animate-spin"
strokeWidth={2} // size={16}
aria-hidden="true" // strokeWidth={2}
/> // aria-hidden="true"
// />
null
) : useAIEditor ? ( ) : useAIEditor ? (
<Undo2Icon size={16} strokeWidth={2} aria-hidden="true" /> // <Undo2Icon size={16} strokeWidth={2} aria-hidden="true" />
) : ( null
) :
(
<Wand2Icon size={16} strokeWidth={2} aria-hidden="true" /> <Wand2Icon size={16} strokeWidth={2} aria-hidden="true" />
)} )}
</TooltipButton> </TooltipButton>

View File

@ -10,6 +10,7 @@ import {
import { AnalyzeButton } from "./actions/analyze-button"; import { AnalyzeButton } from "./actions/analyze-button";
import { LspConnectionIndicator } from "./controls/lsp-connection-indicator"; import { LspConnectionIndicator } from "./controls/lsp-connection-indicator";
import {AIOptimizeButton} from "@/features/problems/code/components/toolbar/actions/AIOptimizeButton"; import {AIOptimizeButton} from "@/features/problems/code/components/toolbar/actions/AIOptimizeButton";
import {AIDisplayButton} from "@/features/problems/code/components/toolbar/actions/AIDisplayButton";
interface CodeToolbarProps { interface CodeToolbarProps {
className?: string; className?: string;
@ -27,6 +28,7 @@ export const CodeToolbar = async ({ className }: CodeToolbarProps) => {
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<AIOptimizeButton /> <AIOptimizeButton />
<AIDisplayButton />
<AnalyzeButton /> <AnalyzeButton />
<ResetButton /> <ResetButton />
<UndoButton /> <UndoButton />

View File

@ -18,6 +18,8 @@ type ProblemEditorState = {
markers: editor.IMarker[]; markers: editor.IMarker[];
useAIEditor: boolean; useAIEditor: boolean;
loading: boolean; loading: boolean;
AIgenerate: boolean;
LastOptimizedCode: string;
}; };
type ProblemEditorAction = { type ProblemEditorAction = {
@ -30,6 +32,8 @@ type ProblemEditorAction = {
setMarkers: (markers: editor.IMarker[]) => void; setMarkers: (markers: editor.IMarker[]) => void;
setUseAIEditor: (flag: boolean) => void; setUseAIEditor: (flag: boolean) => void;
setLoading: (flag: boolean) => void; setLoading: (flag: boolean) => void;
setAIgenerate: (flag: boolean) => void;
setLastOptimizedCode: (code: string) => void;
}; };
type ProblemEditorStore = ProblemEditorState & ProblemEditorAction; type ProblemEditorStore = ProblemEditorState & ProblemEditorAction;
@ -44,6 +48,10 @@ export const useProblemEditorStore = create<ProblemEditorStore>((set, get) => ({
markers: [], markers: [],
useAIEditor: false, useAIEditor: false,
loading: false, loading: false,
AIgenerate: false,
LastOptimizedCode: "",
setLastOptimizedCode: (code) => set({ LastOptimizedCode: code }),
setAIgenerate: (flag) => set({ AIgenerate: flag }),
setLoading: (loading) => set({loading}), setLoading: (loading) => set({loading}),
setUseAIEditor: (loading) => set({ useAIEditor: loading }), setUseAIEditor: (loading) => set({ useAIEditor: loading }),
setProblem: (problemId, templates) => { setProblem: (problemId, templates) => {