feat: ChatGPT/Claude-style persistent sidebar for desktop fullscreen chat (v0.57.0)
Cooking assistant's fullscreen mode gets a real left sidebar (always- visible conversation list, hover-reveal rename/delete) on desktop (md+), replacing the small dropdown menu that made sense in the narrow 420px drawer but not in a full-viewport layout. Mobile fullscreen and the normal drawer keep the dropdown (ConversationMenu) — no room for a persistent sidebar there. Extracted the shared fetch/rename/delete/create logic into use-conversation-list.ts so the dropdown (ConversationMenu) and the new sidebar (ConversationSidebar) can't silently diverge — both are thin render layers over the same hook. ConversationMenu gained an optional className prop so the panel can hide it with `md:hidden` specifically when the sidebar is already covering that job. Per-recipe chat is untouched — it's single-threaded by design and never used either of these components. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import ReactMarkdown from "react-markdown";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChatHistorySearch } from "./chat-history-search";
|
||||
import { ConversationMenu, type Conversation } from "./conversation-menu";
|
||||
import { ConversationSidebar } from "./conversation-sidebar";
|
||||
import { ShoppingListProposalCard, type ShoppingListProposal } from "./shopping-list-proposal-card";
|
||||
|
||||
type RecipeProposal = {
|
||||
@@ -224,10 +225,20 @@ export function CookingAssistantPanel() {
|
||||
<SheetContent
|
||||
side="right"
|
||||
className={cn(
|
||||
"flex flex-col p-0",
|
||||
fullscreen ? "!w-screen !max-w-none !h-screen !inset-0" : "w-full sm:w-[420px]"
|
||||
"p-0",
|
||||
fullscreen ? "!w-screen !max-w-none !h-screen !inset-0 flex flex-row" : "flex flex-col w-full sm:w-[420px]"
|
||||
)}
|
||||
>
|
||||
{fullscreen && (
|
||||
<ConversationSidebar
|
||||
className="hidden md:flex w-64 shrink-0"
|
||||
activeId={conversationId}
|
||||
onSelect={handleSelectConversation}
|
||||
onCreated={handleConversationCreated}
|
||||
onDeletedActive={handleActiveConversationDeleted}
|
||||
/>
|
||||
)}
|
||||
<div className="flex flex-col flex-1 min-w-0 h-full">
|
||||
<SheetHeader className="px-4 py-3 pr-10 border-b shrink-0">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<SheetTitle className="text-base flex items-center gap-2">
|
||||
@@ -244,7 +255,11 @@ export function CookingAssistantPanel() {
|
||||
{fullscreen ? <Minimize2 className="h-4 w-4" /> : <Maximize2 className="h-4 w-4" />}
|
||||
</button>
|
||||
<ChatHistorySearch />
|
||||
{/* On desktop fullscreen, ConversationSidebar (left) replaces this
|
||||
dropdown — kept for mobile fullscreen and the normal drawer,
|
||||
where there's no room for a persistent sidebar. */}
|
||||
<ConversationMenu
|
||||
className={cn(fullscreen && "md:hidden")}
|
||||
activeId={conversationId}
|
||||
onSelect={handleSelectConversation}
|
||||
onCreated={handleConversationCreated}
|
||||
@@ -389,6 +404,7 @@ export function CookingAssistantPanel() {
|
||||
<Send className="h-4 w-4" />
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user