mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-22 13:44:46 +08:00
feat: add Replay Mode
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "~/components/ui/card";
|
||||
import type { Option } from "~/core/messages";
|
||||
import { sendMessage, useStore } from "~/core/store";
|
||||
import { cn } from "~/lib/utils";
|
||||
@@ -10,10 +17,12 @@ import { cn } from "~/lib/utils";
|
||||
import { ConversationStarter } from "./conversation-starter";
|
||||
import { InputBox } from "./input-box";
|
||||
import { MessageListView } from "./message-list-view";
|
||||
import { RainbowText } from "./rainbow-text";
|
||||
|
||||
export function MessagesBlock({ className }: { className?: string }) {
|
||||
const messageCount = useStore((state) => state.messageIds.length);
|
||||
const responding = useStore((state) => state.responding);
|
||||
const replaying = useSearchParams().get("replay") !== null;
|
||||
const abortControllerRef = useRef<AbortController | null>(null);
|
||||
const [feedback, setFeedback] = useState<{ option: Option } | null>(null);
|
||||
const handleSend = useCallback(
|
||||
@@ -56,22 +65,39 @@ export function MessagesBlock({ className }: { className?: string }) {
|
||||
onFeedback={handleFeedback}
|
||||
onSendMessage={handleSend}
|
||||
/>
|
||||
<div className="relative flex h-42 shrink-0 pb-4">
|
||||
{!responding && messageCount === 0 && (
|
||||
<ConversationStarter
|
||||
className="absolute top-[-218px] left-0"
|
||||
{!replaying ? (
|
||||
<div className="relative flex h-42 shrink-0 pb-4">
|
||||
{!responding && messageCount === 0 && (
|
||||
<ConversationStarter
|
||||
className="absolute top-[-218px] left-0"
|
||||
onSend={handleSend}
|
||||
/>
|
||||
)}
|
||||
<InputBox
|
||||
className="h-full w-full"
|
||||
responding={responding}
|
||||
feedback={feedback}
|
||||
onSend={handleSend}
|
||||
onCancel={handleCancel}
|
||||
onRemoveFeedback={handleRemoveFeedback}
|
||||
/>
|
||||
)}
|
||||
<InputBox
|
||||
className="h-full w-full"
|
||||
responding={responding}
|
||||
feedback={feedback}
|
||||
onSend={handleSend}
|
||||
onCancel={handleCancel}
|
||||
onRemoveFeedback={handleRemoveFeedback}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-42 w-full items-center justify-center">
|
||||
<Card className="w-full">
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<RainbowText animated={responding}>Replay Mode</RainbowText>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<RainbowText animated={responding}>
|
||||
DeerFlow is now replaying the conversation...
|
||||
</RainbowText>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
import { GithubOutlined } from "@ant-design/icons";
|
||||
import Link from "next/link";
|
||||
import { useMemo } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { useStore } from "~/core/store";
|
||||
import { useReplay } from "~/core/replay";
|
||||
import { sendMessage, useStore } from "~/core/store";
|
||||
import { cn } from "~/lib/utils";
|
||||
|
||||
import { Logo } from "./_components/logo";
|
||||
@@ -19,11 +20,17 @@ import { Tooltip } from "./_components/tooltip";
|
||||
import { SettingsDialog } from "./_settings/dialogs/settings-dialog";
|
||||
|
||||
export default function HomePage() {
|
||||
const { isReplay } = useReplay();
|
||||
const openResearchId = useStore((state) => state.openResearchId);
|
||||
const doubleColumnMode = useMemo(
|
||||
() => openResearchId !== null,
|
||||
[openResearchId],
|
||||
);
|
||||
useEffect(() => {
|
||||
if (isReplay) {
|
||||
void sendMessage();
|
||||
}
|
||||
}, [isReplay]);
|
||||
return (
|
||||
<div className="flex h-full w-full justify-center">
|
||||
<header className="fixed top-0 left-0 flex h-12 w-full w-screen items-center justify-between px-4">
|
||||
|
||||
Reference in New Issue
Block a user