1import * as Linking from 'expo-linking'; 2import React from 'react'; 3import { ScrollView, StyleSheet, TextInput, View } from 'react-native'; 4 5import Button from '../components/Button'; 6import MonoText from '../components/MonoText'; 7import Colors from '../constants/Colors'; 8 9function TextInputButton({ text }: { text: string }) { 10 const [link, setLink] = React.useState<string>(text); 11 const [parsed, setParsed] = React.useState<string>(''); 12 const [canOpen, setCanOpen] = React.useState<boolean>(false); 13 14 React.useEffect(() => { 15 onChangeText(text); 16 }, [text]); 17 18 const onChangeText = async (text: string) => { 19 let parsedTextResult = ''; 20 const canOpenURL = await Linking.canOpenURL(text); 21 if (canOpenURL) { 22 const parsedText = await Linking.parse(text); 23 parsedTextResult = JSON.stringify(parsedText, null, 2); 24 } 25 26 setLink(text); 27 setParsed(parsedTextResult); 28 setCanOpen(canOpenURL); 29 }; 30 31 const handleClick = async () => { 32 try { 33 const supported = await Linking.canOpenURL(link); 34 35 if (supported) { 36 Linking.openURL(link); 37 } else { 38 const message = `Don't know how to open URI: ${link}`; 39 console.log(message); 40 alert(message); 41 } 42 } catch ({ message }) { 43 console.error(message); 44 } 45 }; 46 47 const buttonTitle = canOpen ? 'Open ' : 'Cannot Open '; 48 return ( 49 <View> 50 <View style={styles.textInputContainer}> 51 <TextInput style={styles.textInput} onChangeText={onChangeText} value={link} /> 52 <Button title={buttonTitle} onPress={handleClick} disabled={!canOpen} /> 53 </View> 54 <MonoText containerStyle={styles.itemText}>{parsed}</MonoText> 55 </View> 56 ); 57} 58 59export default function LinkingScreen() { 60 const url = Linking.useURL(); 61 62 React.useEffect(() => { 63 if (url) { 64 alert(`Linking url event: ${url}`); 65 } 66 }); 67 68 return ( 69 <ScrollView style={styles.container}> 70 <Button 71 title="Open Settings" 72 onPress={() => { 73 Linking.openSettings(); 74 }} 75 /> 76 {url && <TextInputButton text={Linking.makeUrl('deep-link')} />} 77 <TextInputButton text="https://github.com/search?q=Expo" /> 78 <TextInputButton text="https://www.expo.io" /> 79 <TextInputButton text="http://www.expo.io" /> 80 <TextInputButton text="http://expo.io" /> 81 <TextInputButton text="fb://notifications" /> 82 <TextInputButton text="geo:37.484847,-122.148386" /> 83 <TextInputButton text="tel:9876543210" /> 84 </ScrollView> 85 ); 86} 87 88LinkingScreen.navigationOptions = { 89 title: 'Linking', 90}; 91 92const styles = StyleSheet.create({ 93 container: { 94 paddingVertical: 16, 95 paddingHorizontal: 24, 96 flex: 1, 97 backgroundColor: Colors.greyBackground, 98 }, 99 textInputContainer: { 100 flexDirection: 'row', 101 maxWidth: '100%', 102 flexWrap: 'wrap', 103 justifyContent: 'space-between', 104 }, 105 textInput: { 106 height: 40, 107 flex: 1, 108 borderColor: Colors.border, 109 borderWidth: StyleSheet.hairlineWidth, 110 paddingHorizontal: 16, 111 marginRight: 16, 112 }, 113 itemText: { 114 borderWidth: 0, 115 flex: 1, 116 marginTop: 8, 117 marginBottom: 16, 118 paddingVertical: 18, 119 paddingLeft: 12, 120 }, 121}); 122