import React, { useCallback, useEffect, useState } from "react"; import { Modal, Pressable, ScrollView, Text, TextInput, View, } from "react-native"; import * as Haptics from "expo-haptics"; import { WsSession } from "../types"; import { useChat } from "../contexts/ChatContext"; interface SessionPickerProps { visible: boolean; onClose: () => void; } export function SessionPicker({ visible, onClose }: SessionPickerProps) { const { sessions, requestSessions, switchSession, renameSession } = useChat(); const [editingId, setEditingId] = useState(null); const [editName, setEditName] = useState(""); useEffect(() => { if (visible) { requestSessions(); } }, [visible, requestSessions]); const handleSwitch = useCallback( (session: WsSession) => { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); switchSession(session.id); onClose(); }, [switchSession, onClose] ); const handleStartRename = useCallback((session: WsSession) => { setEditingId(session.id); setEditName(session.name); }, []); const handleConfirmRename = useCallback(() => { if (editingId && editName.trim()) { renameSession(editingId, editName.trim()); } setEditingId(null); setEditName(""); }, [editingId, editName, renameSession]); return ( {/* Handle bar */} {/* Header */} Sessions requestSessions()} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }} style={{ paddingHorizontal: 12, paddingVertical: 6, borderRadius: 12, backgroundColor: "#1E1E2E", }} > Refresh {/* Session list */} {sessions.length === 0 ? ( No sessions found ) : ( sessions.map((session) => ( {editingId === session.id ? ( /* Rename mode */ Save setEditingId(null)} style={{ flex: 1, backgroundColor: "#252538", borderRadius: 10, paddingVertical: 10, alignItems: "center", }} > Cancel ) : ( /* Normal session row */ handleSwitch(session)} onLongPress={() => handleStartRename(session)} style={({ pressed }) => ({ backgroundColor: pressed ? "#252538" : "#1E1E2E", borderRadius: 16, padding: 16, flexDirection: "row", alignItems: "center", borderWidth: session.isActive ? 2 : 1, borderColor: session.isActive ? "#4A9EFF" : "#2E2E45", })} > {/* Number badge */} {session.index} {/* Session info */} {session.name} {session.kind === "api" ? "Headless" : session.kind === "visual" ? "Visual" : session.type === "terminal" ? "Terminal" : "Claude"} {session.isActive ? " — active" : ""} {/* Active indicator */} {session.isActive && ( )} )} )) )} {/* Hint */} Tap to switch — Long press to rename ); }