1import { borderRadius, spacing } from '@expo/styleguide-native'; 2import { 3 Button, 4 ChevronRightIcon, 5 Divider, 6 Row, 7 Spacer, 8 Text, 9 TextInput, 10 useExpoTheme, 11 View, 12} from 'expo-dev-client-components'; 13import * as React from 'react'; 14import { Animated, Linking } from 'react-native'; 15import { TouchableOpacity } from 'react-native-gesture-handler'; 16 17import * as UrlUtils from '../../utils/UrlUtils'; 18 19export function DevelopmentServersOpenURL() { 20 const [showInput, setShowInput] = React.useState(false); 21 const [url, setUrl] = React.useState(''); 22 23 const theme = useExpoTheme(); 24 const rotateAnimation = React.useRef(new Animated.Value(0)).current; 25 26 const interpolateRotating = rotateAnimation.interpolate({ 27 inputRange: [0, 1], 28 outputRange: ['0deg', '90deg'], 29 }); 30 31 React.useEffect( 32 function animateChevron() { 33 Animated.timing(rotateAnimation, { 34 toValue: showInput ? 1 : 0, 35 duration: 100, 36 useNativeDriver: false, 37 }).start(() => { 38 rotateAnimation.setValue(showInput ? 1 : 0); 39 }); 40 }, 41 [showInput] 42 ); 43 44 function openURL() { 45 if (url) { 46 const normalizedUrl = UrlUtils.normalizeUrl(url); 47 Linking.openURL(normalizedUrl); 48 } 49 } 50 51 return ( 52 <> 53 <Divider style={{ height: 1 }} /> 54 <View> 55 <TouchableOpacity 56 style={{ padding: 16 }} 57 onPress={() => setShowInput((prevState) => !prevState)}> 58 <Row align="center"> 59 <Animated.View 60 style={{ transform: [{ rotate: interpolateRotating }], marginRight: spacing[2] }}> 61 <ChevronRightIcon size="small" style={{ tintColor: theme.icon.default }} /> 62 </Animated.View> 63 <Text type="InterRegular">Enter URL manually</Text> 64 </Row> 65 </TouchableOpacity> 66 {showInput ? <Spacer.Vertical size="medium" /> : null} 67 {showInput ? ( 68 <View padding="medium" style={{ marginTop: -32 }}> 69 <TextInput 70 onChangeText={(newUrl) => setUrl(newUrl.trim())} 71 border="default" 72 rounded="medium" 73 shadow="input" 74 autoCorrect={false} 75 autoComplete="off" 76 autoCapitalize="none" 77 returnKeyType="go" 78 onSubmitEditing={openURL} 79 style={{ backgroundColor: theme.background.default }} 80 px="4" 81 py="3" 82 type="InterRegular" 83 placeholder="exp://" 84 placeholderTextColor={theme.text.secondary} 85 /> 86 <Spacer.Vertical size="small" /> 87 <TouchableOpacity 88 onPress={openURL} 89 disabled={!url} 90 style={[ 91 { 92 backgroundColor: theme.button.tertiary.background, 93 padding: spacing[2], 94 borderRadius: borderRadius.medium, 95 justifyContent: 'center', 96 alignItems: 'center', 97 }, 98 ]}> 99 <Button.Text color="tertiary" type="InterSemiBold"> 100 Connect 101 </Button.Text> 102 </TouchableOpacity> 103 </View> 104 ) : null} 105 </View> 106 </> 107 ); 108} 109