"use client"; import { useAtom, useAtomValue } from "jotai"; import { AlertCircle, Pencil, Play, Podcast, RefreshCw, Sparkles } from "lucide-react"; import { motion } from "motion/react"; import { useCallback, useContext, useTransition } from "react"; import { cn } from "@/lib/utils"; import { activeChatAtom } from "@/stores/chat/active-chat.atom"; import { chatUIAtom } from "@/stores/chat/chat-ui.atom"; import { getPodcastStalenessMessage, isPodcastStale } from "../PodcastUtils"; import type { GeneratePodcastRequest } from "./ChatPanelContainer"; import { ConfigModal } from "./ConfigModal"; import { PodcastPlayer } from "./PodcastPlayer"; interface ChatPanelViewProps { generatePodcast: (request: GeneratePodcastRequest) => Promise; } export function ChatPanelView(props: ChatPanelViewProps) { const [chatUIState, setChatUIState] = useAtom(chatUIAtom); const { data: activeChatState } = useAtomValue(activeChatAtom); const { isChatPannelOpen } = chatUIState; const podcast = activeChatState?.podcast; const chatDetails = activeChatState?.chatDetails; const { generatePodcast } = props; // Check if podcast is stale const podcastIsStale = podcast && chatDetails && isPodcastStale(chatDetails.state_version, podcast.chat_state_version); const handleGeneratePost = useCallback(async () => { if (!chatDetails) return; await generatePodcast({ type: "CHAT", ids: [chatDetails.id], search_space_id: chatDetails.search_space_id, podcast_title: chatDetails.title, }); }, [chatDetails, generatePodcast]); return (
{isChatPannelOpen ? (
{/* Show stale podcast warning if applicable */} {podcastIsStale && (

Podcast Outdated

{getPodcastStalenessMessage( chatDetails?.state_version || 0, podcast?.chat_state_version )}

)}
{ if (e.key === "Enter") { e.preventDefault(); handleGeneratePost(); } }} className={cn( "relative w-full rounded-2xl p-4 transition-all duration-300 cursor-pointer group overflow-hidden", "border-2", podcastIsStale ? "bg-gradient-to-br from-amber-500/10 via-orange-500/10 to-amber-500/10 dark:from-amber-500/20 dark:via-orange-500/20 dark:to-amber-500/20 border-amber-400/50 hover:border-amber-400 hover:shadow-lg hover:shadow-amber-500/20" : "bg-gradient-to-br from-primary/10 via-primary/5 to-primary/10 border-primary/30 hover:border-primary/60 hover:shadow-lg hover:shadow-primary/20" )} > {/* Background gradient animation */}
{podcastIsStale ? ( ) : ( )}

{podcastIsStale ? "Regenerate Podcast" : "Generate Podcast"}

{podcastIsStale ? "Update with latest changes" : "Create podcasts of your chat"}

) : ( setChatUIState((prev) => ({ ...prev, isChatPannelOpen: !isChatPannelOpen, })) } whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} className={cn( "p-2.5 rounded-full transition-colors shadow-sm", podcastIsStale ? "bg-amber-500/20 hover:bg-amber-500/30 text-amber-600 dark:text-amber-400" : "bg-primary/20 hover:bg-primary/30 text-primary" )} > {podcastIsStale ? : } )}
{podcast ? (
{isChatPannelOpen ? ( ) : podcast ? ( setChatUIState((prev) => ({ ...prev, isChatPannelOpen: true }))} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} className="p-2.5 rounded-full bg-green-500/20 hover:bg-green-500/30 text-green-600 dark:text-green-400 transition-colors shadow-sm" > ) : null}
) : null}
); }