mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-16 18:25:17 +02:00
Fix compose box issues
This commit is contained in:
parent
8e16ac6204
commit
ef378ba802
4 changed files with 48 additions and 4 deletions
|
|
@ -53,6 +53,7 @@ const App = forwardRef<{ handleCopyChat: () => void }, AppProps>(function App({
|
|||
const [lastResponse, setLastResponse] = useState<unknown | null>(null);
|
||||
const [currentStatus, setCurrentStatus] = useState<'thinking' | 'planning' | 'generating'>('thinking');
|
||||
const statusIntervalRef = useRef<NodeJS.Timeout>();
|
||||
const [isLastInteracted, setIsLastInteracted] = useState(isInitialState);
|
||||
|
||||
// Notify parent of message changes
|
||||
useEffect(() => {
|
||||
|
|
@ -85,6 +86,7 @@ const App = forwardRef<{ handleCopyChat: () => void }, AppProps>(function App({
|
|||
content: prompt
|
||||
}]);
|
||||
setResponseError(null);
|
||||
setIsLastInteracted(true);
|
||||
}
|
||||
|
||||
const handleApplyChange = useCallback((
|
||||
|
|
@ -313,6 +315,8 @@ const App = forwardRef<{ handleCopyChat: () => void }, AppProps>(function App({
|
|||
loading={loadingResponse}
|
||||
disabled={loadingResponse}
|
||||
initialFocus={isInitialState}
|
||||
shouldAutoFocus={isLastInteracted}
|
||||
onFocus={() => setIsLastInteracted(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ export function Chat({
|
|||
const [lastAgenticRequest, setLastAgenticRequest] = useState<unknown | null>(null);
|
||||
const [lastAgenticResponse, setLastAgenticResponse] = useState<unknown | null>(null);
|
||||
const [optimisticMessages, setOptimisticMessages] = useState<z.infer<typeof apiV1.ChatMessage>[]>(chat.messages);
|
||||
const [isLastInteracted, setIsLastInteracted] = useState(false);
|
||||
|
||||
const getCopyContent = useCallback(() => {
|
||||
return JSON.stringify({
|
||||
|
|
@ -90,6 +91,7 @@ export function Chat({
|
|||
}];
|
||||
setMessages(updatedMessages);
|
||||
setFetchResponseError(null);
|
||||
setIsLastInteracted(true);
|
||||
}
|
||||
|
||||
// reset state when workflow changes
|
||||
|
|
@ -293,6 +295,8 @@ export function Chat({
|
|||
handleUserMessage={handleUserMessage}
|
||||
messages={messages.filter(msg => msg.content !== undefined) as any}
|
||||
loading={loadingAssistantResponse}
|
||||
shouldAutoFocus={isLastInteracted}
|
||||
onFocus={() => setIsLastInteracted(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ interface ComposeBoxCopilotProps {
|
|||
loading: boolean;
|
||||
disabled?: boolean;
|
||||
initialFocus?: boolean;
|
||||
shouldAutoFocus?: boolean;
|
||||
onFocus?: () => void;
|
||||
}
|
||||
|
||||
export function ComposeBoxCopilot({
|
||||
|
|
@ -28,18 +30,29 @@ export function ComposeBoxCopilot({
|
|||
loading,
|
||||
disabled = false,
|
||||
initialFocus = false,
|
||||
shouldAutoFocus = false,
|
||||
onFocus,
|
||||
}: ComposeBoxCopilotProps) {
|
||||
const [input, setInput] = useState('');
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const previousMessagesLength = useRef(messages.length);
|
||||
|
||||
// Add effect to handle initial focus
|
||||
// Handle initial focus
|
||||
useEffect(() => {
|
||||
if (initialFocus && textareaRef.current) {
|
||||
textareaRef.current.focus();
|
||||
}
|
||||
}, [initialFocus]);
|
||||
|
||||
// Handle auto-focus when new messages arrive
|
||||
useEffect(() => {
|
||||
if (shouldAutoFocus && messages.length > previousMessagesLength.current && textareaRef.current) {
|
||||
textareaRef.current.focus();
|
||||
}
|
||||
previousMessagesLength.current = messages.length;
|
||||
}, [messages.length, shouldAutoFocus]);
|
||||
|
||||
function handleInput() {
|
||||
const prompt = input.trim();
|
||||
if (!prompt) {
|
||||
|
|
@ -56,6 +69,11 @@ export function ComposeBoxCopilot({
|
|||
}
|
||||
}
|
||||
|
||||
const handleFocus = () => {
|
||||
setIsFocused(true);
|
||||
onFocus?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative group">
|
||||
{/* Keyboard shortcut hint */}
|
||||
|
|
@ -74,7 +92,7 @@ export function ComposeBoxCopilot({
|
|||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
onKeyDown={handleInputKeyDown}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onFocus={handleFocus}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
disabled={disabled || loading}
|
||||
placeholder="Type a message..."
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useRef } from 'react';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Button, Spinner } from "@heroui/react";
|
||||
|
||||
|
|
@ -7,6 +7,8 @@ interface ComposeBoxPlaygroundProps {
|
|||
messages: any[];
|
||||
loading: boolean;
|
||||
disabled?: boolean;
|
||||
shouldAutoFocus?: boolean;
|
||||
onFocus?: () => void;
|
||||
}
|
||||
|
||||
export function ComposeBoxPlayground({
|
||||
|
|
@ -14,10 +16,21 @@ export function ComposeBoxPlayground({
|
|||
messages,
|
||||
loading,
|
||||
disabled = false,
|
||||
shouldAutoFocus = false,
|
||||
onFocus,
|
||||
}: ComposeBoxPlaygroundProps) {
|
||||
const [input, setInput] = useState('');
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const previousMessagesLength = useRef(messages.length);
|
||||
|
||||
// Handle auto-focus when new messages arrive
|
||||
useEffect(() => {
|
||||
if (shouldAutoFocus && messages.length > previousMessagesLength.current && textareaRef.current) {
|
||||
textareaRef.current.focus();
|
||||
}
|
||||
previousMessagesLength.current = messages.length;
|
||||
}, [messages.length, shouldAutoFocus]);
|
||||
|
||||
function handleInput() {
|
||||
const prompt = input.trim();
|
||||
|
|
@ -35,6 +48,11 @@ export function ComposeBoxPlayground({
|
|||
}
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
setIsFocused(true);
|
||||
onFocus?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative group">
|
||||
{/* Keyboard shortcut hint */}
|
||||
|
|
@ -53,7 +71,7 @@ export function ComposeBoxPlayground({
|
|||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
onKeyDown={handleInputKeyDown}
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onFocus={handleFocus}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
disabled={disabled || loading}
|
||||
placeholder="Type a message..."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue