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