diff --git a/packages/ui/src/components/chat/MobileAgentButton.tsx b/packages/ui/src/components/chat/MobileAgentButton.tsx index 7197cb48..944a6f30 100644 --- a/packages/ui/src/components/chat/MobileAgentButton.tsx +++ b/packages/ui/src/components/chat/MobileAgentButton.tsx @@ -13,58 +13,63 @@ interface MobileAgentButtonProps { const LONG_PRESS_MS = 500; -export const MobileAgentButton: React.FC = ({ onOpenAgentPanel, onCycleAgent, className }) => { +// NOTE: Use pointer events instead of onClick to keep soft keyboard open on mobile +export const MobileAgentButton: React.FC = ({ onCycleAgent, onOpenAgentPanel, className }) => { const { currentAgentName, getVisibleAgents } = useConfigStore(); const currentSessionId = useSessionStore((state) => state.currentSessionId); const sessionAgentName = useSessionStore((state) => currentSessionId ? state.getSessionAgentSelection(currentSessionId) : null ); - const longPressTimerRef = React.useRef | null>(null); - const longPressTriggeredRef = React.useRef(false); const agents = getVisibleAgents(); const uiAgentName = currentSessionId ? (sessionAgentName || currentAgentName) : currentAgentName; const agentLabel = getAgentDisplayName(agents, uiAgentName); const agentColor = getAgentColor(uiAgentName); - const clearLongPressTimer = React.useCallback(() => { + const longPressTimerRef = React.useRef | null>(null); + const isLongPressRef = React.useRef(false); + + const handlePointerDown = () => { + isLongPressRef.current = false; + longPressTimerRef.current = setTimeout(() => { + isLongPressRef.current = true; + onOpenAgentPanel(); + }, LONG_PRESS_MS); + }; + + // Use onPointerUp (not onClick) to prevent focus transfer that closes mobile keyboard + const handlePointerUp = () => { if (longPressTimerRef.current) { clearTimeout(longPressTimerRef.current); longPressTimerRef.current = null; } - }, []); + if (!isLongPressRef.current) { + onCycleAgent(); + } + }; - const startLongPressTimer = React.useCallback(() => { - clearLongPressTimer(); - longPressTriggeredRef.current = false; - longPressTimerRef.current = setTimeout(() => { - longPressTriggeredRef.current = true; - onOpenAgentPanel(); - }, LONG_PRESS_MS); - }, [clearLongPressTimer, onOpenAgentPanel]); + const handlePointerLeave = () => { + if (longPressTimerRef.current) { + clearTimeout(longPressTimerRef.current); + longPressTimerRef.current = null; + } + }; React.useEffect(() => { - return () => clearLongPressTimer(); - }, [clearLongPressTimer]); + return () => { + if (longPressTimerRef.current) { + clearTimeout(longPressTimerRef.current); + } + }; + }, []); return ( ); };