Improve terminal keyboard and reconnection

This commit is contained in:
LukeGus
2025-09-23 00:32:03 -05:00
parent 154162ccc4
commit f4bc0187c8
3 changed files with 56 additions and 23 deletions
+1
View File
@@ -31,6 +31,7 @@ export default function TabBar({ sessions, activeSessionId, onTabPress, onTabClo
>
<ScrollView
horizontal
keyboardShouldPersistTaps="always"
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
paddingHorizontal: 12,
+39 -23
View File
@@ -76,6 +76,29 @@ export default function Sessions() {
}
}, [isKeyboardVisible, sessions.length]);
// Whenever keyboard height changes or active session changes, ask terminal to refit
useEffect(() => {
const activeRef = activeSessionId ? terminalRefs.current[activeSessionId] : null;
if (activeRef && activeRef.current) {
setTimeout(() => {
activeRef.current?.fit();
}, 0);
}
}, [keyboardHeight, activeSessionId]);
// Ensure keyboard shows immediately when entering sessions and fit terminal
useFocusEffect(
React.useCallback(() => {
if (sessions.length > 0) {
setTimeout(() => {
hiddenInputRef.current?.focus();
const activeRef = activeSessionId ? terminalRefs.current[activeSessionId] : null;
activeRef?.current?.fit();
}, 0);
}
}, [sessions.length, activeSessionId])
);
const handleTabPress = (sessionId: string) => {
setActiveSession(sessionId);
};
@@ -135,31 +158,24 @@ export default function Sessions() {
)}
</View>
<TouchableWithoutFeedback
onPress={() => {
// Prevent keyboard dismissal by maintaining focus
hiddenInputRef.current?.focus();
<View
style={{
position: 'absolute',
bottom: keyboardHeight > 0 ? keyboardHeight : 0,
left: 0,
right: 0,
height: 60,
zIndex: 1000, // Ensure tab bar is above everything
}}
>
<View
style={{
position: 'absolute',
bottom: keyboardHeight > 0 ? keyboardHeight : 0,
left: 0,
right: 0,
height: 60,
zIndex: 1000, // Ensure tab bar is above everything
}}
>
<TabBar
sessions={sessions}
activeSessionId={activeSessionId}
onTabPress={handleTabPress}
onTabClose={handleTabClose}
hiddenInputRef={hiddenInputRef}
/>
</View>
</TouchableWithoutFeedback>
<TabBar
sessions={sessions}
activeSessionId={activeSessionId}
onTabPress={handleTabPress}
onTabClose={handleTabClose}
hiddenInputRef={hiddenInputRef}
/>
</View>
{/* Hidden TextInput to maintain keyboard focus - positioned to not interfere with tab bar */}
{sessions.length > 0 && (
+16
View File
@@ -26,6 +26,7 @@ interface TerminalProps {
export type TerminalHandle = {
sendInput: (data: string) => void;
fit: () => void;
};
export const Terminal = forwardRef<TerminalHandle, TerminalProps>(({
@@ -442,6 +443,16 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(({
}));
}
}
// Expose a fit method for React Native to call when layout changes (e.g., keyboard height)
window.nativeFit = function() {
try {
fitAddon.fit();
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'resize', data: { cols: terminal.cols, rows: terminal.rows } }));
}
} catch (e) {}
}
// Listen for resize events
window.addEventListener('resize', handleResize);
@@ -538,6 +549,11 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(({
const escaped = JSON.stringify(data);
webViewRef.current?.injectJavaScript(`window.nativeInput(${escaped}); true;`);
} catch (e) {}
},
fit: () => {
try {
webViewRef.current?.injectJavaScript(`window.nativeFit && window.nativeFit(); true;`);
} catch (e) {}
}
}), []);