1import { borderRadius } from '@expo/styleguide-native'; 2import { View, Text, Button, useExpoTheme, Spacer } from 'expo-dev-client-components'; 3import { isDevice } from 'expo-device'; 4import React from 'react'; 5import { Platform, StyleSheet, TouchableOpacity as TouchableOpacityRN } from 'react-native'; 6import { TouchableOpacity as TouchableOpacityGH } from 'react-native-gesture-handler'; 7 8type Props = { 9 onClose: () => void; 10}; 11 12// When rendered inside bottom sheet, touchables from RN don't work on Android, but the ones from GH don't work on iOS. 13const TouchableOpacity = Platform.OS === 'android' ? TouchableOpacityGH : TouchableOpacityRN; 14 15const KEYBOARD_CODES: { [key: string]: string } = { 16 ios: '^\u2318Z', 17 android: '\u2318M on macOS or Ctrl+M on other platforms', 18}; 19 20const ONBOARDING_MESSAGE = (() => { 21 let fragment; 22 if (isDevice) { 23 if (Platform.OS === 'ios') { 24 fragment = 25 'you can shake your device or long press anywhere on the screen with three fingers'; 26 } else { 27 fragment = 'you can shake your device'; 28 } 29 } else { 30 fragment = `in a simulator you can press ${KEYBOARD_CODES[Platform.OS]}`; 31 } 32 return `Since this is your first time opening Expo Go, we wanted to show you this menu and let you know that ${fragment} to get back to it at any time.`; 33})(); 34 35export function DevMenuOnboarding({ onClose }: Props) { 36 const theme = useExpoTheme(); 37 38 return ( 39 <View style={styles.onboardingContainer}> 40 <View style={styles.onboardingBackground} bg="default" /> 41 <View style={styles.onboardingTopMargin} /> 42 <View> 43 <Text type="InterBold" align="center" size="large"> 44 Hello there, friend! 45 </Text> 46 <Spacer.Vertical size="small" /> 47 <Text type="InterRegular" align="center" style={styles.onboardingTooltip}> 48 {ONBOARDING_MESSAGE} 49 </Text> 50 <Spacer.Vertical size="medium" /> 51 <TouchableOpacity 52 style={[styles.onboardingButton, { backgroundColor: theme.button.primary.background }]} 53 onPress={onClose}> 54 <Button.Text type="InterSemiBold" color="primary"> 55 Got it 56 </Button.Text> 57 </TouchableOpacity> 58 </View> 59 </View> 60 ); 61} 62 63const styles = StyleSheet.create({ 64 onboardingContainer: { 65 flex: 1, 66 paddingHorizontal: 36, 67 position: 'absolute', 68 top: 0, 69 right: 0, 70 bottom: 0, 71 left: 0, 72 zIndex: 2, 73 }, 74 onboardingBackground: { 75 borderTopLeftRadius: borderRadius.large, 76 borderTopRightRadius: borderRadius.large, 77 position: 'absolute', 78 top: 0, 79 right: 0, 80 bottom: 0, 81 left: 0, 82 opacity: 0.9, 83 }, 84 onboardingTopMargin: { 85 // Moves the actual onboarding content a little bit down. 86 // This percentage value is also a percentage of screen's height. 87 height: '20%', 88 }, 89 onboardingTooltip: { 90 lineHeight: 20, 91 textAlign: 'center', 92 }, 93 onboardingButton: { 94 alignItems: 'center', 95 marginVertical: 12, 96 paddingVertical: 12, 97 borderRadius: 4, 98 }, 99}); 100