From 879df50f53f6a60a2dd3bb5e22907454b26499be Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:56:41 +0000 Subject: [PATCH] feat(mobile): Enable attachment button functionality The attachment button on the mobile view was not functional because it was located in a separate component (`MobileIconsBar`) from the chat input (`ChatPanel`), where the file handling logic resides. The `onClick` handler was missing on the mobile button. This commit resolves the issue by using `React.forwardRef` and `useImperativeHandle` to expose the `handleAttachmentClick` function from the `ChatPanel` component. This allows the parent `Chat` component to create a ref to `ChatPanel` and pass down a handler to the `MobileIconsBar`. Changes: - Modified `ChatPanel` to expose `handleAttachmentClick` via a ref. - Updated the parent `Chat` component to create a ref and pass the click handler to `MobileIconsBar`. - Added the `onClick` prop to the `Paperclip` button in `MobileIconsBar` to trigger the file selection dialog. --- components/chat-panel.tsx | 17 ++++++++++++++--- components/chat.tsx | 13 +++++++++---- components/mobile-icons-bar.tsx | 8 ++++++-- dev.log | 7 +++++++ 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/components/chat-panel.tsx b/components/chat-panel.tsx index f4ad2110..b3097358 100644 --- a/components/chat-panel.tsx +++ b/components/chat-panel.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useState, useRef, ChangeEvent } from 'react' +import { useEffect, useState, useRef, ChangeEvent, forwardRef, useImperativeHandle } from 'react' import type { AI, UIState } from '@/app/actions' import { useUIState, useActions } from 'ai/rsc' // Removed import of useGeospatialToolMcp as it's no longer used/available @@ -17,7 +17,11 @@ interface ChatPanelProps { setInput: (value: string) => void } -export function ChatPanel({ messages, input, setInput }: ChatPanelProps) { +export interface ChatPanelRef { + handleAttachmentClick: () => void; +} + +export const ChatPanel = forwardRef(({ messages, input, setInput }, ref) => { const [, setMessages] = useUIState() const { submit, clearChat } = useActions() // Removed mcp instance as it's no longer passed to submit @@ -27,6 +31,12 @@ export function ChatPanel({ messages, input, setInput }: ChatPanelProps) { const formRef = useRef(null) const fileInputRef = useRef(null) + useImperativeHandle(ref, () => ({ + handleAttachmentClick() { + fileInputRef.current?.click() + } + })); + // Detect mobile layout useEffect(() => { const checkMobile = () => { @@ -243,4 +253,5 @@ export function ChatPanel({ messages, input, setInput }: ChatPanelProps) { ) -} +}) +ChatPanel.displayName = 'ChatPanel' diff --git a/components/chat.tsx b/components/chat.tsx index 59c4d914..0a40bd13 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -1,8 +1,8 @@ 'use client' -import { useEffect, useState } from 'react' +import { useEffect, useState, useRef } from 'react' import { usePathname, useRouter } from 'next/navigation' -import { ChatPanel } from './chat-panel' +import { ChatPanel, ChatPanelRef } from './chat-panel' import { ChatMessages } from './chat-messages' import { EmptyScreen } from './empty-screen' import { Mapbox } from './map/mapbox-map' @@ -26,6 +26,11 @@ export function Chat({ id }: ChatProps) { const { activeView } = useProfileToggle(); const [input, setInput] = useState('') const [showEmptyScreen, setShowEmptyScreen] = useState(false) + const chatPanelRef = useRef(null); + + const handleAttachment = () => { + chatPanelRef.current?.handleAttachmentClick(); + }; useEffect(() => { setShowEmptyScreen(messages.length === 0) @@ -80,10 +85,10 @@ export function Chat({ id }: ChatProps) { {activeView ? : }
- +
- +
{showEmptyScreen ? ( diff --git a/components/mobile-icons-bar.tsx b/components/mobile-icons-bar.tsx index a5a2af9a..217154d6 100644 --- a/components/mobile-icons-bar.tsx +++ b/components/mobile-icons-bar.tsx @@ -18,7 +18,11 @@ import { History } from '@/components/history' import { MapToggle } from './map-toggle' import { ModeToggle } from './mode-toggle' -export const MobileIconsBar: React.FC = () => { +interface MobileIconsBarProps { + onAttachmentClick: () => void; +} + +export const MobileIconsBar: React.FC = ({ onAttachmentClick }) => { const [, setMessages] = useUIState() const { clearChat } = useActions() @@ -45,7 +49,7 @@ export const MobileIconsBar: React.FC = () => { -