mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-09 23:16:50 +02:00
refactor: integrate sidebar toggle into ChatViewer header
- Add headerPrefix prop to ChatViewer for custom header content - Pass sidebar toggle button via headerPrefix on mobile - Remove duplicate mobile header from GroupListViewer - Reduces vertical space usage by reusing ChatViewer's existing header
This commit is contained in:
@@ -46,6 +46,8 @@ interface ChatViewerProps {
|
||||
protocol: ChatProtocol;
|
||||
identifier: ProtocolIdentifier;
|
||||
customTitle?: string;
|
||||
/** Optional content to render before the title (e.g., sidebar toggle on mobile) */
|
||||
headerPrefix?: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,6 +317,7 @@ export function ChatViewer({
|
||||
protocol,
|
||||
identifier,
|
||||
customTitle,
|
||||
headerPrefix,
|
||||
}: ChatViewerProps) {
|
||||
const { addWindow } = useGrimoire();
|
||||
|
||||
@@ -590,9 +593,10 @@ export function ChatViewer({
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
{/* Header with conversation info and controls */}
|
||||
<div className="pl-4 pr-0 border-b w-full py-0.5">
|
||||
<div className="pl-2 pr-0 border-b w-full py-0.5">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex flex-1 min-w-0 items-center gap-2">
|
||||
{headerPrefix}
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
||||
@@ -123,9 +123,11 @@ const MemoizedChatViewer = memo(
|
||||
function MemoizedChatViewer({
|
||||
groupId,
|
||||
relayUrl,
|
||||
headerPrefix,
|
||||
}: {
|
||||
groupId: string;
|
||||
relayUrl: string;
|
||||
headerPrefix?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<ChatViewer
|
||||
@@ -137,10 +139,12 @@ const MemoizedChatViewer = memo(
|
||||
relays: [relayUrl],
|
||||
} as ProtocolIdentifier
|
||||
}
|
||||
headerPrefix={headerPrefix}
|
||||
/>
|
||||
);
|
||||
},
|
||||
// Custom comparison: only re-render if group actually changed
|
||||
// Note: headerPrefix is intentionally excluded - it's expected to be stable or change with isMobile
|
||||
(prev, next) =>
|
||||
prev.groupId === next.groupId && prev.relayUrl === next.relayUrl,
|
||||
);
|
||||
@@ -469,11 +473,25 @@ export function GroupListViewer({ identifier }: GroupListViewerProps) {
|
||||
</div>
|
||||
);
|
||||
|
||||
// Sidebar toggle button for mobile - passed to ChatViewer's headerPrefix
|
||||
const sidebarToggle = isMobile ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 flex-shrink-0"
|
||||
onClick={() => setSidebarOpen(true)}
|
||||
>
|
||||
<PanelLeft className="size-4" />
|
||||
<span className="sr-only">Toggle sidebar</span>
|
||||
</Button>
|
||||
) : null;
|
||||
|
||||
// Chat view content
|
||||
const chatContent = selectedGroup ? (
|
||||
<MemoizedChatViewer
|
||||
groupId={selectedGroup.groupId}
|
||||
relayUrl={selectedGroup.relayUrl}
|
||||
headerPrefix={sidebarToggle}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
|
||||
@@ -496,37 +514,6 @@ export function GroupListViewer({ identifier }: GroupListViewerProps) {
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
{/* Mobile header with sidebar toggle */}
|
||||
<div className="flex items-center gap-2 border-b px-2 py-1.5">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
onClick={() => setSidebarOpen(true)}
|
||||
>
|
||||
<PanelLeft className="size-4" />
|
||||
<span className="sr-only">Toggle sidebar</span>
|
||||
</Button>
|
||||
{selectedGroup && (
|
||||
<span className="text-sm font-medium truncate">
|
||||
{groupsWithRecency.find(
|
||||
(g) =>
|
||||
g.groupId === selectedGroup.groupId &&
|
||||
g.relayUrl === selectedGroup.relayUrl,
|
||||
)?.metadata
|
||||
? getTagValue(
|
||||
groupsWithRecency.find(
|
||||
(g) =>
|
||||
g.groupId === selectedGroup.groupId &&
|
||||
g.relayUrl === selectedGroup.relayUrl,
|
||||
)!.metadata!,
|
||||
"name",
|
||||
) || selectedGroup.groupId
|
||||
: selectedGroup.groupId}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Mobile sheet sidebar */}
|
||||
<Sheet open={sidebarOpen} onOpenChange={setSidebarOpen}>
|
||||
<SheetContent side="left" className="w-[280px] p-0">
|
||||
@@ -537,7 +524,7 @@ export function GroupListViewer({ identifier }: GroupListViewerProps) {
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
|
||||
{/* Chat content */}
|
||||
{/* Chat content - takes full height, sidebar toggle is in ChatViewer header */}
|
||||
<div className="flex-1 min-h-0">{chatContent}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user