Skip to content

Commit 39e5805

Browse files
authored
Merge pull request #397 from getAlby/fix/dismissable-keyboard
fix: dismissable keyboard not working in android
2 parents 07a4127 + 6cfa321 commit 39e5805

File tree

3 files changed

+173
-60
lines changed

3 files changed

+173
-60
lines changed
Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,54 @@
1+
import { useHeaderHeight } from "@react-navigation/elements";
2+
import React from "react";
13
import {
24
Keyboard,
35
KeyboardAvoidingView,
46
Platform,
57
TouchableWithoutFeedback,
8+
View,
69
} from "react-native";
710

8-
function DismissableKeyboardView({ children }: { children?: React.ReactNode }) {
11+
function AndroidDismissableKeyboardView({
12+
children,
13+
}: {
14+
children?: React.ReactNode;
15+
}) {
16+
const [keyboardHeight, setKeyboardHeight] = React.useState(0);
17+
18+
React.useEffect(() => {
19+
const showSub = Keyboard.addListener("keyboardDidShow", (event) => {
20+
setKeyboardHeight(event.endCoordinates.height);
21+
});
22+
const hideSub = Keyboard.addListener("keyboardDidHide", () => {
23+
setKeyboardHeight(0);
24+
});
25+
26+
return () => {
27+
showSub.remove();
28+
hideSub.remove();
29+
};
30+
}, []);
31+
32+
return (
33+
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
34+
<View className="flex-1" style={{ paddingBottom: keyboardHeight }}>
35+
{children}
36+
</View>
37+
</TouchableWithoutFeedback>
38+
);
39+
}
40+
41+
function IOSDismissableKeyboardView({
42+
children,
43+
}: {
44+
children?: React.ReactNode;
45+
}) {
46+
const height = useHeaderHeight();
47+
948
return (
1049
<KeyboardAvoidingView
1150
behavior={Platform.OS === "ios" ? "padding" : "height"}
12-
keyboardVerticalOffset={Platform.OS === "ios" ? 100 : 0}
51+
keyboardVerticalOffset={height}
1352
className="flex-1"
1453
>
1554
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
@@ -19,4 +58,16 @@ function DismissableKeyboardView({ children }: { children?: React.ReactNode }) {
1958
);
2059
}
2160

61+
function DismissableKeyboardView({ children }: { children?: React.ReactNode }) {
62+
const isIOS = Platform.OS === "ios";
63+
64+
if (isIOS) {
65+
return <IOSDismissableKeyboardView>{children}</IOSDismissableKeyboardView>;
66+
}
67+
68+
return (
69+
<AndroidDismissableKeyboardView>{children}</AndroidDismissableKeyboardView>
70+
);
71+
}
72+
2273
export default DismissableKeyboardView;

components/DualCurrencyInput.tsx

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@ import {
66
BottomSheetView,
77
} from "@gorhom/bottom-sheet";
88
import React, { useCallback, useRef, useState } from "react";
9-
import { Keyboard, Pressable, TouchableOpacity, View } from "react-native";
9+
import {
10+
Keyboard,
11+
Platform,
12+
Pressable,
13+
TouchableOpacity,
14+
View,
15+
} from "react-native";
1016
import Toast from "react-native-toast-message";
17+
import DismissableKeyboardView from "~/components/DismissableKeyboardView";
1118
import {
1219
ArrowLeftIcon,
1320
EditLineIcon,
@@ -16,6 +23,7 @@ import {
1623
XIcon,
1724
} from "~/components/Icons";
1825
import { Button } from "~/components/ui/button";
26+
import { Input } from "~/components/ui/input";
1927
import { Text } from "~/components/ui/text";
2028
import { useGetFiatAmount, useGetSatsAmount } from "~/hooks/useGetFiatAmount";
2129
import { MAX_SATS_THRESHOLD } from "~/lib/constants";
@@ -70,6 +78,9 @@ function DescriptionInput({
7078
bottomSheetModalRef.current?.dismiss();
7179
};
7280

81+
const isIOS = Platform.OS === "ios";
82+
const Wrapper = isIOS ? React.Fragment : DismissableKeyboardView;
83+
7384
return (
7485
<>
7586
{readOnly ? (
@@ -82,7 +93,12 @@ function DescriptionInput({
8293
</Text>
8394
) : (
8495
<TouchableOpacity
85-
onPress={() => bottomSheetModalRef.current?.present()}
96+
onPress={() => {
97+
if (Keyboard.isVisible()) {
98+
Keyboard.dismiss();
99+
}
100+
bottomSheetModalRef.current?.present();
101+
}}
86102
className="flex flex-row items-center justify-center gap-2 px-12 py-4"
87103
>
88104
{!description && <NotesIcon className="text-muted-foreground" />}
@@ -110,33 +126,50 @@ function DescriptionInput({
110126
enablePanDownToClose
111127
>
112128
<BottomSheetView className="p-6 pt-2">
113-
<View className="relative flex flex-row items-center justify-center">
114-
<TouchableOpacity
115-
onPress={() => {
116-
Keyboard.dismiss();
117-
bottomSheetModalRef.current?.dismiss();
118-
}}
119-
className="absolute -left-4 p-4"
120-
>
121-
<XIcon className="text-muted-foreground" width={24} height={24} />
122-
</TouchableOpacity>
123-
<Text className="text-2xl font-semibold2 text-muted-foreground">
124-
Add Description
125-
</Text>
126-
</View>
127-
<BottomSheetTextInput
128-
placeholder="Sats for Satoshi"
129-
className="text-foreground border-transparent bg-transparent text-center my-16 p-3 border text-2xl leading-[1.25] font-semibold2 caret-primary"
130-
placeholderClassName="text-muted-foreground"
131-
selectionColor={"hsl(47 100% 50%)"} // translates to primary
132-
value={input}
133-
onChangeText={setInput}
134-
onSubmitEditing={save}
135-
autoFocus
136-
/>
137-
<Button size="lg" onPress={save}>
138-
<Text>Save</Text>
139-
</Button>
129+
<Wrapper>
130+
<View className="relative flex flex-row items-center justify-center">
131+
<TouchableOpacity
132+
onPress={() => {
133+
Keyboard.dismiss();
134+
bottomSheetModalRef.current?.dismiss();
135+
}}
136+
className="absolute -left-4 p-4"
137+
>
138+
<XIcon
139+
className="text-muted-foreground"
140+
width={24}
141+
height={24}
142+
/>
143+
</TouchableOpacity>
144+
<Text className="text-2xl font-semibold2 text-muted-foreground">
145+
Add Description
146+
</Text>
147+
</View>
148+
{isIOS ? (
149+
<BottomSheetTextInput
150+
placeholder="Sats for Satoshi"
151+
className="text-foreground border-transparent bg-transparent text-center my-16 p-3 border native:text-2xl leading-[1.25] font-semibold2 caret-primary"
152+
placeholderClassName="text-muted-foreground"
153+
selectionColor={"hsl(47 100% 50%)"} // translates to primary
154+
value={input}
155+
onChangeText={setInput}
156+
onSubmitEditing={save}
157+
autoFocus
158+
/>
159+
) : (
160+
<Input
161+
placeholder="Sats for Satoshi"
162+
className="text-foreground border-0 border-transparent bg-transparent text-center my-16 p-3 native:text-2xl font-semibold2"
163+
value={input}
164+
onChangeText={setInput}
165+
onSubmitEditing={save}
166+
autoFocus
167+
/>
168+
)}
169+
<Button size="lg" onPress={save}>
170+
<Text>Save</Text>
171+
</Button>
172+
</Wrapper>
140173
</BottomSheetView>
141174
</BottomSheetModal>
142175
</>

pages/send/Address.tsx

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import {
88
} from "@gorhom/bottom-sheet";
99
import * as Clipboard from "expo-clipboard";
1010
import React, { useCallback, useRef, useState } from "react";
11-
import { Keyboard, ScrollView, TouchableOpacity, View } from "react-native";
11+
import {
12+
Keyboard,
13+
Platform,
14+
ScrollView,
15+
TouchableOpacity,
16+
View,
17+
} from "react-native";
1218
import Contact from "~/components/Contact";
1319
import DismissableKeyboardView from "~/components/DismissableKeyboardView";
1420
import {
@@ -67,6 +73,9 @@ function ContactInput({
6773
bottomSheetModalRef.current?.dismiss();
6874
};
6975

76+
const isIOS = Platform.OS === "ios";
77+
const Wrapper = isIOS ? React.Fragment : DismissableKeyboardView;
78+
7079
return (
7180
<>
7281
<TouchableOpacity
@@ -75,6 +84,9 @@ function ContactInput({
7584
setInput("");
7685
setContactName("");
7786
} else {
87+
if (Keyboard.isVisible()) {
88+
Keyboard.dismiss();
89+
}
7890
bottomSheetModalRef.current?.present();
7991
}
8092
}}
@@ -109,33 +121,50 @@ function ContactInput({
109121
enablePanDownToClose
110122
>
111123
<BottomSheetView className="p-6 pt-2">
112-
<View className="relative flex flex-row items-center justify-center">
113-
<TouchableOpacity
114-
onPress={() => {
115-
Keyboard.dismiss();
116-
bottomSheetModalRef.current?.dismiss();
117-
}}
118-
className="absolute -left-4 p-4"
119-
>
120-
<XIcon className="text-muted-foreground" width={24} height={24} />
121-
</TouchableOpacity>
122-
<Text className="text-2xl font-semibold2 text-muted-foreground">
123-
Add to Contacts
124-
</Text>
125-
</View>
126-
<BottomSheetTextInput
127-
placeholder="Satoshi Nakamoto"
128-
className="text-foreground border-transparent bg-transparent text-center my-16 p-3 border text-2xl leading-[1.25] font-semibold2 caret-primary"
129-
placeholderClassName="text-muted-foreground"
130-
selectionColor={"hsl(47 100% 50%)"} // translates to primary
131-
value={input}
132-
onChangeText={setInput}
133-
onSubmitEditing={save}
134-
autoFocus
135-
/>
136-
<Button size="lg" onPress={save} disabled={!input}>
137-
<Text>Save</Text>
138-
</Button>
124+
<Wrapper>
125+
<View className="relative flex flex-row items-center justify-center">
126+
<TouchableOpacity
127+
onPress={() => {
128+
Keyboard.dismiss();
129+
bottomSheetModalRef.current?.dismiss();
130+
}}
131+
className="absolute -left-4 p-4"
132+
>
133+
<XIcon
134+
className="text-muted-foreground"
135+
width={24}
136+
height={24}
137+
/>
138+
</TouchableOpacity>
139+
<Text className="text-2xl font-semibold2 text-muted-foreground">
140+
Add to Contacts
141+
</Text>
142+
</View>
143+
{isIOS ? (
144+
<BottomSheetTextInput
145+
placeholder="Satoshi Nakamoto"
146+
className="text-foreground border-transparent bg-transparent text-center my-16 p-3 border native:text-2xl leading-[1.25] font-semibold2 caret-primary"
147+
placeholderClassName="text-muted-foreground"
148+
selectionColor={"hsl(47 100% 50%)"} // translates to primary
149+
value={input}
150+
onChangeText={setInput}
151+
onSubmitEditing={save}
152+
autoFocus
153+
/>
154+
) : (
155+
<Input
156+
placeholder="Satoshi Nakamoto"
157+
className="text-foreground border-0 border-transparent bg-transparent text-center my-16 p-3 native:text-2xl font-semibold2"
158+
value={input}
159+
onChangeText={setInput}
160+
onSubmitEditing={save}
161+
autoFocus
162+
/>
163+
)}
164+
<Button size="lg" onPress={save} disabled={!input}>
165+
<Text>Save</Text>
166+
</Button>
167+
</Wrapper>
139168
</BottomSheetView>
140169
</BottomSheetModal>
141170
</>
@@ -152,7 +181,7 @@ export function Address() {
152181
setSubmitting(true);
153182
try {
154183
const result = await initiatePaymentFlow(keyboardText, "");
155-
if (result) {
184+
if (contactName && result) {
156185
useAppStore.getState().addAddressBookEntry({
157186
name: contactName,
158187
lightningAddress: keyboardText,

0 commit comments

Comments
 (0)