fix: Various android keyboard problems

This commit is contained in:
LukeGus
2025-10-30 17:50:51 -05:00
parent 0488901398
commit 163cfe7094
3 changed files with 15 additions and 180 deletions
+2 -57
View File
@@ -57,9 +57,7 @@ export default function TabBar({
}, 50);
} else {
onHideKeyboard?.();
setTimeout(() => {
Keyboard.dismiss();
}, 50);
Keyboard.dismiss();
}
};
@@ -76,18 +74,6 @@ export default function TabBar({
minHeight: 60,
maxHeight: 60,
}}
onStartShouldSetResponder={() => true}
onResponderGrant={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
onResponderTerminationRequest={() => false}
onTouchEndCapture={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
focusable={false}
>
<View
@@ -99,17 +85,7 @@ export default function TabBar({
}}
>
<TouchableOpacity
onPressIn={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
onPress={() => router.navigate("/hosts" as any)}
onPressOut={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
focusable={false}
className="items-center justify-center rounded-md"
activeOpacity={0.7}
@@ -162,17 +138,7 @@ export default function TabBar({
return (
<TouchableOpacity
key={session.id}
onPressIn={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
onPress={() => onTabPress(session.id)}
onPressOut={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
focusable={false}
className="flex-row items-center rounded-md"
style={{
@@ -199,20 +165,10 @@ export default function TabBar({
</View>
<TouchableOpacity
onPressIn={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
onPress={(e) => {
e.stopPropagation();
onTabClose(session.id);
}}
onPressOut={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
focusable={false}
className="items-center justify-center"
activeOpacity={0.7}
@@ -235,8 +191,7 @@ export default function TabBar({
</ScrollView>
</View>
{!isCustomKeyboardVisible &&
(isKeyboardVisible || keyboardIntentionallyHiddenRef.current) && (
{!isCustomKeyboardVisible && (
<TouchableOpacity
onPress={handleToggleSystemKeyboard}
focusable={false}
@@ -265,17 +220,7 @@ export default function TabBar({
)}
<TouchableOpacity
onPressIn={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
onPress={() => onToggleKeyboard?.()}
onPressOut={() => {
if (!keyboardIntentionallyHiddenRef.current) {
hiddenInputRef.current?.focus();
}
}}
focusable={false}
className="items-center justify-center rounded-md"
activeOpacity={0.7}
+11 -99
View File
@@ -117,36 +117,18 @@ export default function Sessions() {
};
}, [sessions.length, isCustomKeyboardVisible, activeSessionId]);
useEffect(() => {
const keyboardDidHideListener = Keyboard.addListener(
"keyboardDidHide",
() => {
if (
sessions.length > 0 &&
!isCustomKeyboardVisible &&
!keyboardIntentionallyHiddenRef.current
) {
setTimeout(() => {
hiddenInputRef.current?.focus();
}, 50);
}
},
);
return () => {
keyboardDidHideListener?.remove();
};
}, [
sessions.length,
isCustomKeyboardVisible,
keyboardIntentionallyHiddenRef,
]);
useEffect(() => {
if (Platform.OS === "android" && sessions.length > 0) {
const backHandler = BackHandler.addEventListener(
"hardwareBackPress",
() => {
if (isKeyboardVisible) {
setKeyboardIntentionallyHidden(true);
Keyboard.dismiss();
return true;
}
return true;
},
);
@@ -155,7 +137,7 @@ export default function Sessions() {
backHandler.remove();
};
}
}, [sessions.length]);
}, [sessions.length, isKeyboardVisible]);
useEffect(() => {
if (
@@ -185,23 +167,12 @@ export default function Sessions() {
? terminalRefs.current[activeSessionId]
: null;
activeRef?.current?.fit();
if (
sessions.length > 0 &&
!isCustomKeyboardVisible &&
!keyboardIntentionallyHiddenRef.current
) {
hiddenInputRef.current?.focus();
}
}, 300);
});
return () => subscription?.remove();
}, [
activeSessionId,
sessions.length,
isCustomKeyboardVisible,
keyboardIntentionallyHiddenRef,
activeSessionId
]);
useEffect(() => {
@@ -459,7 +430,7 @@ export default function Sessions() {
left: 0,
right: 0,
height: keyboardIntentionallyHiddenRef.current ? 66 : 50,
zIndex: 999,
zIndex: 1003,
}}
>
<KeyboardBar
@@ -490,7 +461,7 @@ export default function Sessions() {
left: 0,
right: 0,
height: 60,
zIndex: 1000,
zIndex: 1004,
}}
>
<TabBar
@@ -531,45 +502,7 @@ export default function Sessions() {
</View>
)}
{sessions.length > 0 &&
!isCustomKeyboardVisible &&
!keyboardIntentionallyHiddenRef.current &&
!isKeyboardVisible && (
<Pressable
style={{
position: "absolute",
bottom: 0,
left: 0,
right: 0,
height:
keyboardHeight > 0
? keyboardHeight
: Math.max(80, screenDimensions.height * 0.1),
backgroundColor: "#09090b",
justifyContent: "center",
alignItems: "center",
borderTopWidth: 1,
borderTopColor: "#303032",
zIndex: 1000,
}}
onPress={() => {
setKeyboardIntentionallyHidden(false);
hiddenInputRef.current?.focus();
}}
>
<Text
style={{
color: "#9CA3AF",
fontSize: Math.min(14, screenDimensions.width / 30),
textAlign: "center",
fontWeight: "500",
paddingHorizontal: 20,
}}
>
Tap anywhere to bring back the keyboard
</Text>
</Pressable>
)}
{sessions.length > 0 && !isCustomKeyboardVisible && (
<TextInput
@@ -657,28 +590,7 @@ export default function Sessions() {
onFocus={() => {
setKeyboardIntentionallyHidden(false);
}}
onBlur={() => {
setTimeout(() => {
if (
sessions.length > 0 &&
!isCustomKeyboardVisible &&
!keyboardIntentionallyHiddenRef.current
) {
hiddenInputRef.current?.focus();
}
}, 100);
}}
onSubmitEditing={() => {
setTimeout(() => {
if (
sessions.length > 0 &&
!isCustomKeyboardVisible &&
!keyboardIntentionallyHiddenRef.current
) {
hiddenInputRef.current?.focus();
}
}, 100);
}}
/>
)}
</View>
+2 -24
View File
@@ -48,7 +48,6 @@ export type TerminalHandle = {
export const Terminal = forwardRef<TerminalHandle, TerminalProps>(
({ hostConfig, isVisible, title = "Terminal", onClose }, ref) => {
const webViewRef = useRef<WebView>(null);
const hiddenInputRef = useRef<TextInput>(null);
const { config } = useTerminalCustomization();
const [webViewKey, setWebViewKey] = useState(0);
const [screenDimensions, setScreenDimensions] = useState(
@@ -315,7 +314,7 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(
}
const terminalElement = document.getElementById('terminal');
['touchstart','touchend','touchmove','mousedown','mouseup','click','dblclick','contextmenu'].forEach(function(ev){
['touchstart','touchend','mousedown','mouseup','click','dblclick','contextmenu'].forEach(function(ev){
terminalElement.addEventListener(ev, function(e){
e.preventDefault();
e.stopPropagation();
@@ -603,11 +602,7 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(
};
}, []);
const handleTerminalPress = useCallback(() => {
if (Platform.OS === "android") {
hiddenInputRef.current?.focus();
}
}, []);
return (
<View
@@ -632,7 +627,6 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(
zIndex: isVisible ? 1 : -1,
}}
>
<TouchableWithoutFeedback onPress={handleTerminalPress}>
<View style={{ flex: 1 }}>
<WebView
key={`terminal-${hostConfig.id}-${webViewKey}`}
@@ -672,23 +666,7 @@ export const Terminal = forwardRef<TerminalHandle, TerminalProps>(
showsVerticalScrollIndicator={false}
nestedScrollEnabled={false}
/>
{Platform.OS === "android" && (
<TextInput
ref={hiddenInputRef}
style={{
position: "absolute",
width: 1,
height: 1,
opacity: 0,
top: -1000,
}}
autoFocus={false}
showSoftInputOnFocus={true}
caretHidden={true}
/>
)}
</View>
</TouchableWithoutFeedback>
{(showConnectingOverlay || isRetrying) && (
<View