1import { Picker } from '@react-native-picker/picker';
2import * as WebBrowser from 'expo-web-browser';
3import React from 'react';
4import { Alert, Platform, ScrollView, StyleSheet, Text, View } from 'react-native';
5
6import OpenAuthSessionAsyncDemo from './OpenAuthSessionAsyncDemo';
7import OpenBrowserAsyncDemo from './OpenBrowserAsyncDemo';
8import Button from '../../components/Button';
9
10const url = 'https://expo.dev';
11interface Package {
12  label: string;
13  value: string;
14}
15
16interface State {
17  packages?: Package[];
18  selectedPackage?: string;
19  lastWarmedPackage?: string;
20}
21
22// See: https://github.com/expo/expo/pull/10229#discussion_r490961694
23// eslint-disable-next-line @typescript-eslint/ban-types
24export default class WebBrowserScreen extends React.Component<{}, State> {
25  static navigationOptions = {
26    title: 'WebBrowser',
27  };
28
29  readonly state: State = {};
30
31  componentDidMount() {
32    if (Platform.OS === 'android') {
33      WebBrowser.getCustomTabsSupportingBrowsersAsync()
34        .then(({ browserPackages }) =>
35          browserPackages.map((name) => ({ label: name, value: name }))
36        )
37        .then((packages) => this.setState({ packages }));
38    }
39  }
40
41  componentWillUnmount() {
42    if (Platform.OS === 'android') {
43      WebBrowser.coolDownAsync(this.state.lastWarmedPackage);
44    }
45  }
46
47  showPackagesAlert = async () => {
48    const result = await WebBrowser.getCustomTabsSupportingBrowsersAsync();
49    Alert.alert('Result', JSON.stringify(result, null, 2));
50  };
51
52  handleWarmUpClicked = async () => {
53    const { selectedPackage: lastWarmedPackage } = this.state;
54    this.setState({
55      lastWarmedPackage,
56    });
57    const result = await WebBrowser.warmUpAsync(lastWarmedPackage);
58    Alert.alert('Result', JSON.stringify(result, null, 2));
59  };
60
61  handleMayInitWithUrlClicked = async () => {
62    const { selectedPackage: lastWarmedPackage } = this.state;
63    this.setState({
64      lastWarmedPackage,
65    });
66    const result = await WebBrowser.mayInitWithUrlAsync(url, lastWarmedPackage);
67    Alert.alert('Result', JSON.stringify(result, null, 2));
68  };
69
70  handleCoolDownClicked = async () => {
71    const result = await WebBrowser.coolDownAsync(this.state.selectedPackage);
72    Alert.alert('Result', JSON.stringify(result, null, 2));
73  };
74
75  packageSelected = (value: string | number) => {
76    if (typeof value === 'string') {
77      this.setState({ selectedPackage: value });
78    }
79  };
80
81  renderAndroidChoices = () =>
82    Platform.OS === 'android' && (
83      <>
84        <View style={styles.label}>
85          <Text>Force package:</Text>
86          <Picker
87            style={styles.picker}
88            selectedValue={this.state.selectedPackage}
89            onValueChange={this.packageSelected}>
90            {this.state.packages &&
91              [{ label: '(none)', value: '' }, ...this.state.packages].map(({ value, label }) => (
92                <Picker.Item key={value} label={label} value={value} />
93              ))}
94          </Picker>
95        </View>
96      </>
97    );
98
99  renderAndroidButtons = () =>
100    Platform.OS === 'android' && (
101      <>
102        <Button style={styles.button} onPress={this.handleWarmUpClicked} title="Warm up." />
103        <Button
104          style={styles.button}
105          onPress={this.handleMayInitWithUrlClicked}
106          title="May init with url."
107        />
108        <Button style={styles.button} onPress={this.handleCoolDownClicked} title="Cool down." />
109        <Button
110          style={styles.button}
111          onPress={this.showPackagesAlert}
112          title="Show supporting browsers."
113        />
114      </>
115    );
116
117  render() {
118    return (
119      <ScrollView contentContainerStyle={styles.container}>
120        <OpenBrowserAsyncDemo />
121        <OpenAuthSessionAsyncDemo />
122        {this.renderAndroidButtons()}
123      </ScrollView>
124    );
125  }
126}
127
128const styles = StyleSheet.create({
129  container: {
130    paddingHorizontal: 10,
131    justifyContent: 'center',
132  },
133  label: {
134    paddingBottom: 5,
135    flexDirection: 'row',
136    alignItems: 'center',
137  },
138  picker: {
139    padding: 10,
140    width: 150,
141  },
142  button: {
143    marginVertical: 10,
144    alignItems: 'flex-start',
145  },
146});
147