mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-03 19:25:19 +02:00
added expand buttons for middle and side pane and fixed issue with moving new chat to side pane
This commit is contained in:
parent
d981fa9206
commit
f78f1380eb
2 changed files with 32 additions and 45 deletions
|
|
@ -5,7 +5,7 @@ import { RunEvent, ListRunsResponse } from '@x/shared/src/runs.js';
|
||||||
import type { LanguageModelUsage, ToolUIPart } from 'ai';
|
import type { LanguageModelUsage, ToolUIPart } from 'ai';
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import z from 'zod';
|
import z from 'zod';
|
||||||
import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon, X } from 'lucide-react';
|
import { CheckIcon, LoaderIcon, PanelLeftIcon, ArrowRight, MessageSquare, ChevronLeftIcon, ChevronRightIcon, Plus, HistoryIcon } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { MarkdownEditor, type MarkdownEditorHandle } from './components/markdown-editor';
|
import { MarkdownEditor, type MarkdownEditorHandle } from './components/markdown-editor';
|
||||||
import { ChatSidebar } from './components/chat-sidebar';
|
import { ChatSidebar } from './components/chat-sidebar';
|
||||||
|
|
@ -3391,8 +3391,10 @@ function App() {
|
||||||
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
|
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
|
||||||
}, [selectedPath, isGraphOpen, isSuggestedTopicsOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isEmailOpen, isWorkspaceOpen, isKnowledgeViewOpen, isChatHistoryOpen, dismissBrowserOverlay])
|
}, [selectedPath, isGraphOpen, isSuggestedTopicsOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isEmailOpen, isWorkspaceOpen, isKnowledgeViewOpen, isChatHistoryOpen, dismissBrowserOverlay])
|
||||||
|
|
||||||
const handleCloseFullScreenChat = useCallback(() => {
|
const handleCloseFullScreenChat = useCallback((): boolean => {
|
||||||
|
let restored = false
|
||||||
if (expandedFrom) {
|
if (expandedFrom) {
|
||||||
|
restored = true
|
||||||
if (expandedFrom.graph) {
|
if (expandedFrom.graph) {
|
||||||
setIsGraphOpen(true)
|
setIsGraphOpen(true)
|
||||||
setIsSuggestedTopicsOpen(false)
|
setIsSuggestedTopicsOpen(false)
|
||||||
|
|
@ -3434,10 +3436,16 @@ function App() {
|
||||||
setIsSuggestedTopicsOpen(false)
|
setIsSuggestedTopicsOpen(false)
|
||||||
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
|
setIsMeetingsOpen(false); setIsLiveNotesOpen(false); setIsBgTasksOpen(false); setIsEmailOpen(false); setIsWorkspaceOpen(false); setIsKnowledgeViewOpen(false); setIsChatHistoryOpen(false); setIsHomeOpen(false)
|
||||||
setSelectedPath(expandedFrom.path)
|
setSelectedPath(expandedFrom.path)
|
||||||
|
} else {
|
||||||
|
// expandedFrom was captured from a view this restorer doesn't track
|
||||||
|
// (e.g. Home): there's nothing to re-open, so report it and let the
|
||||||
|
// caller fall back instead of leaving a blank full-screen chat.
|
||||||
|
restored = false
|
||||||
}
|
}
|
||||||
setExpandedFrom(null)
|
setExpandedFrom(null)
|
||||||
setIsRightPaneMaximized(false)
|
setIsRightPaneMaximized(false)
|
||||||
}
|
}
|
||||||
|
return restored
|
||||||
}, [expandedFrom])
|
}, [expandedFrom])
|
||||||
|
|
||||||
const currentViewState = React.useMemo<ViewState>(() => {
|
const currentViewState = React.useMemo<ViewState>(() => {
|
||||||
|
|
@ -3885,12 +3893,13 @@ function App() {
|
||||||
const pushChatToSidePane = useCallback(() => {
|
const pushChatToSidePane = useCallback(() => {
|
||||||
setIsRightPaneMaximized(false)
|
setIsRightPaneMaximized(false)
|
||||||
setIsChatSidebarOpen(true)
|
setIsChatSidebarOpen(true)
|
||||||
if (expandedFrom) {
|
// Restore the view we expanded from; if there was nothing to restore
|
||||||
handleCloseFullScreenChat()
|
// (e.g. the chat was started fresh from Home), fall back to Home so a
|
||||||
} else {
|
// single click always docks the chat instead of needing two.
|
||||||
|
if (!handleCloseFullScreenChat()) {
|
||||||
void navigateToView({ type: 'home' })
|
void navigateToView({ type: 'home' })
|
||||||
}
|
}
|
||||||
}, [expandedFrom, handleCloseFullScreenChat, navigateToView])
|
}, [handleCloseFullScreenChat, navigateToView])
|
||||||
|
|
||||||
const navigateBack = useCallback(async () => {
|
const navigateBack = useCallback(async () => {
|
||||||
const { back, forward } = historyRef.current
|
const { back, forward } = historyRef.current
|
||||||
|
|
@ -5375,7 +5384,7 @@ function App() {
|
||||||
: (viewOpen && !isChatSidebarOpen)
|
: (viewOpen && !isChatSidebarOpen)
|
||||||
? { onClick: openChatSidePane, icon: <MessageSquare className="size-5" />, label: 'Open chat' }
|
? { onClick: openChatSidePane, icon: <MessageSquare className="size-5" />, label: 'Open chat' }
|
||||||
: (viewOpen && isChatSidebarOpen && !isRightPaneMaximized)
|
: (viewOpen && isChatSidebarOpen && !isRightPaneMaximized)
|
||||||
? { onClick: toggleRightPaneMaximize, icon: <X className="size-5" />, label: 'Expand chat' }
|
? { onClick: () => setIsChatSidebarOpen(false), icon: <ArrowRight className="size-5" />, label: 'Expand pane' }
|
||||||
: null
|
: null
|
||||||
return (
|
return (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
|
|
@ -5899,7 +5908,6 @@ function App() {
|
||||||
}}
|
}}
|
||||||
onOpenChatHistory={() => void navigateToView({ type: 'chat-history' })}
|
onOpenChatHistory={() => void navigateToView({ type: 'chat-history' })}
|
||||||
onOpenFullScreen={toggleRightPaneMaximize}
|
onOpenFullScreen={toggleRightPaneMaximize}
|
||||||
onCloseChat={() => { setIsRightPaneMaximized(false); setIsChatSidebarOpen(false) }}
|
|
||||||
conversation={conversation}
|
conversation={conversation}
|
||||||
currentAssistantMessage={currentAssistantMessage}
|
currentAssistantMessage={currentAssistantMessage}
|
||||||
chatTabStates={chatViewStateByTab}
|
chatTabStates={chatViewStateByTab}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { ArrowRight, X } from 'lucide-react'
|
import { ArrowLeft, ArrowRight } from 'lucide-react'
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
@ -125,7 +125,6 @@ interface ChatSidebarProps {
|
||||||
onSelectRun?: (runId: string) => void
|
onSelectRun?: (runId: string) => void
|
||||||
onOpenChatHistory?: () => void
|
onOpenChatHistory?: () => void
|
||||||
onOpenFullScreen?: () => void
|
onOpenFullScreen?: () => void
|
||||||
onCloseChat?: () => void
|
|
||||||
conversation: ConversationItem[]
|
conversation: ConversationItem[]
|
||||||
currentAssistantMessage: string
|
currentAssistantMessage: string
|
||||||
chatTabStates?: Record<string, ChatTabViewState>
|
chatTabStates?: Record<string, ChatTabViewState>
|
||||||
|
|
@ -183,7 +182,6 @@ export function ChatSidebar({
|
||||||
onSelectRun,
|
onSelectRun,
|
||||||
onOpenChatHistory,
|
onOpenChatHistory,
|
||||||
onOpenFullScreen,
|
onOpenFullScreen,
|
||||||
onCloseChat,
|
|
||||||
conversation,
|
conversation,
|
||||||
currentAssistantMessage,
|
currentAssistantMessage,
|
||||||
chatTabStates = {},
|
chatTabStates = {},
|
||||||
|
|
@ -515,40 +513,21 @@ export function ChatSidebar({
|
||||||
onSelectRun={onSelectRun}
|
onSelectRun={onSelectRun}
|
||||||
onOpenChatHistory={onOpenChatHistory}
|
onOpenChatHistory={onOpenChatHistory}
|
||||||
/>
|
/>
|
||||||
{isMaximized ? (
|
{onOpenFullScreen && (
|
||||||
onOpenFullScreen && (
|
<Tooltip>
|
||||||
<Tooltip>
|
<TooltipTrigger asChild>
|
||||||
<TooltipTrigger asChild>
|
<Button
|
||||||
<Button
|
variant="ghost"
|
||||||
variant="ghost"
|
size="icon"
|
||||||
size="icon"
|
onClick={onOpenFullScreen}
|
||||||
onClick={onOpenFullScreen}
|
className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground"
|
||||||
className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground"
|
aria-label={isMaximized ? 'Dock chat to side pane' : 'Expand chat'}
|
||||||
aria-label="Dock chat to side pane"
|
>
|
||||||
>
|
{isMaximized ? <ArrowRight className="size-5" /> : <ArrowLeft className="size-5" />}
|
||||||
<ArrowRight className="size-5" />
|
</Button>
|
||||||
</Button>
|
</TooltipTrigger>
|
||||||
</TooltipTrigger>
|
<TooltipContent side="bottom">{isMaximized ? 'Dock to side pane' : 'Expand chat'}</TooltipContent>
|
||||||
<TooltipContent side="bottom">Dock to side pane</TooltipContent>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
onCloseChat && (
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
onClick={onCloseChat}
|
|
||||||
className="titlebar-no-drag my-1 mr-2 h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground"
|
|
||||||
aria-label="Close chat"
|
|
||||||
>
|
|
||||||
<X className="size-5" />
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="bottom">Close chat</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
)
|
|
||||||
)}
|
)}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue