mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-28 18:06:30 +02:00
fix: chat sidebar buttons and sidebar collapse behaviour
This commit is contained in:
parent
2bb27e477f
commit
2efc80a7e2
2 changed files with 51 additions and 15 deletions
|
|
@ -6,7 +6,7 @@ import type { LanguageModelUsage, ToolUIPart } from 'ai';
|
|||
import './App.css'
|
||||
import z from 'zod';
|
||||
import { Button } from './components/ui/button';
|
||||
import { CheckIcon, LoaderIcon, ArrowUp, PanelLeftIcon, PanelRightIcon, Square } from 'lucide-react';
|
||||
import { CheckIcon, LoaderIcon, ArrowUp, PanelLeftIcon, PanelRightIcon, Square, X } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { MarkdownEditor } from './components/markdown-editor';
|
||||
import { ChatInputBar } from './components/chat-button';
|
||||
|
|
@ -497,6 +497,7 @@ function App() {
|
|||
const [expandedPaths, setExpandedPaths] = useState<Set<string>>(new Set())
|
||||
const [recentWikiFiles, setRecentWikiFiles] = useState<string[]>([])
|
||||
const [isGraphOpen, setIsGraphOpen] = useState(false)
|
||||
const [expandedFrom, setExpandedFrom] = useState<{ path: string | null; graph: boolean } | null>(null)
|
||||
const [graphData, setGraphData] = useState<{ nodes: GraphNode[]; edges: GraphEdge[] }>({
|
||||
nodes: [],
|
||||
edges: [],
|
||||
|
|
@ -1303,9 +1304,28 @@ function App() {
|
|||
}
|
||||
|
||||
const handleOpenFullScreenChat = useCallback(() => {
|
||||
// Remember where we came from so the close button can return
|
||||
if (selectedPath || isGraphOpen) {
|
||||
setExpandedFrom({ path: selectedPath, graph: isGraphOpen })
|
||||
}
|
||||
// Copy sidebar input text to full-screen input (keep sidebar message intact for return)
|
||||
if (message.trim()) {
|
||||
setPresetMessage(message)
|
||||
}
|
||||
setSelectedPath(null)
|
||||
setIsGraphOpen(false)
|
||||
}, [])
|
||||
}, [selectedPath, isGraphOpen, message])
|
||||
|
||||
const handleCloseFullScreenChat = useCallback(() => {
|
||||
if (expandedFrom) {
|
||||
if (expandedFrom.graph) {
|
||||
setIsGraphOpen(true)
|
||||
} else if (expandedFrom.path) {
|
||||
setSelectedPath(expandedFrom.path)
|
||||
}
|
||||
setExpandedFrom(null)
|
||||
}
|
||||
}, [expandedFrom])
|
||||
|
||||
// File navigation with history tracking
|
||||
const navigateToFile = useCallback((path: string | null) => {
|
||||
|
|
@ -1320,6 +1340,7 @@ function App() {
|
|||
setSelectedPath(path)
|
||||
// Clear background task selection when navigating to a file
|
||||
setSelectedBackgroundTask(null)
|
||||
setExpandedFrom(null)
|
||||
}, [selectedPath])
|
||||
|
||||
const navigateBack = useCallback(() => {
|
||||
|
|
@ -1394,17 +1415,22 @@ function App() {
|
|||
}
|
||||
}, [])
|
||||
|
||||
// Keyboard shortcut: Ctrl+L to open main chat view
|
||||
// Keyboard shortcut: Ctrl+L to toggle main chat view
|
||||
const isFullScreenChat = !selectedPath && !isGraphOpen && !selectedBackgroundTask
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'l') {
|
||||
e.preventDefault()
|
||||
handleOpenFullScreenChat()
|
||||
if (isFullScreenChat && expandedFrom) {
|
||||
handleCloseFullScreenChat()
|
||||
} else {
|
||||
handleOpenFullScreenChat()
|
||||
}
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', handleKeyDown)
|
||||
return () => document.removeEventListener('keydown', handleKeyDown)
|
||||
}, [handleOpenFullScreenChat])
|
||||
}, [handleOpenFullScreenChat, handleCloseFullScreenChat, isFullScreenChat, expandedFrom])
|
||||
|
||||
const toggleExpand = (path: string, kind: 'file' | 'dir') => {
|
||||
if (kind === 'file') {
|
||||
|
|
@ -1889,6 +1915,16 @@ function App() {
|
|||
Close Graph
|
||||
</Button>
|
||||
)}
|
||||
{!selectedPath && !isGraphOpen && expandedFrom && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCloseFullScreenChat}
|
||||
className="titlebar-no-drag flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
||||
aria-label="Return to file"
|
||||
>
|
||||
<X className="size-4" />
|
||||
</button>
|
||||
)}
|
||||
{(selectedPath || isGraphOpen) && (
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { ArrowUp, Expand, LoaderIcon, Plus, Square } from 'lucide-react'
|
||||
import { ArrowUp, Expand, LoaderIcon, SquarePen, Square } from 'lucide-react'
|
||||
import type { ToolUIPart } from 'ai'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
|
@ -465,24 +465,24 @@ export function ChatSidebar({
|
|||
<>
|
||||
{/* Header - minimal, expand and new chat buttons */}
|
||||
<header className="titlebar-drag-region flex h-10 shrink-0 items-center justify-end gap-1 px-2 bg-sidebar">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="icon" onClick={onNewChat} className="titlebar-no-drag h-8 w-8 text-muted-foreground hover:text-foreground">
|
||||
<SquarePen className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">New chat</TooltipContent>
|
||||
</Tooltip>
|
||||
{onOpenFullScreen && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="icon" onClick={onOpenFullScreen} className="h-8 w-8 text-muted-foreground hover:text-foreground">
|
||||
<Button variant="ghost" size="icon" onClick={onOpenFullScreen} className="titlebar-no-drag h-8 w-8 text-muted-foreground hover:text-foreground">
|
||||
<Expand className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">Full screen chat</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="icon" onClick={onNewChat} className="h-8 w-8 text-muted-foreground hover:text-foreground">
|
||||
<Plus className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">New chat</TooltipContent>
|
||||
</Tooltip>
|
||||
</header>
|
||||
|
||||
{/* Conversation area */}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue