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