src/Welcome.tsx (181 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import React, {useEffect, useCallback, useContext, useMemo} from 'react'; import {Alert, Linking, Platform, View} from 'react-native'; import LogoLight from './assets/IoT-Plug-And-Play_Dark.svg'; import LogoDark from './assets/IoT-Plug-And-Play_Light.svg'; import * as Animatable from 'react-native-animatable'; import {defaults} from './contexts/defaults'; import DeviceInfo from 'react-native-device-info'; import {StateUpdater, StyleDefinition, ThemeMode} from './types'; import {CircleSnail} from 'react-native-progress'; import {useScreenDimensions} from './hooks/layout'; import {StorageContext, ThemeContext} from 'contexts'; import {Name} from 'components/typography'; import VersionCheck from 'react-native-version-check'; import Strings, {resolveString} from 'strings'; const animations = { slideOutLogo: { from: { left: '50%', }, to: { left: '25%', }, }, slideInName: { from: { left: '100%', }, to: { left: '65%', }, }, }; Animatable.initializeRegistryWithDefinitions(animations); export function Welcome(props: { title: string; setInitialized: StateUpdater<boolean>; }) { const {setInitialized, title} = props; const {read, save, initialized} = useContext(StorageContext); const {screen} = useScreenDimensions(); const {mode, theme} = useContext(ThemeContext); const style = useMemo<StyleDefinition>( () => ({ container: { flex: 1, backgroundColor: theme.backgroundColor, justifyContent: 'center', alignItems: 'center', }, logo: { paddingVertical: 100, }, name: { color: theme.textColor, fontSize: 20, }, spinner: { marginTop: 50, }, }), [theme.backgroundColor, theme.textColor], ); const initDefaults = useCallback(async () => { defaults.emulator = await DeviceInfo.isEmulator(); defaults.dev = __DEV__; await new Promise(r => setTimeout(r, 2000)); const storage = await read(); try { const minorOrPatchUpdateDetails = await VersionCheck.needUpdate({ packageName: Platform.select({ ios: defaults.packageNameIOS, android: defaults.packageNameAndroid, }), }); if (minorOrPatchUpdateDetails.isNeeded) { await handleUpdate( false, storage.skipVersion, minorOrPatchUpdateDetails.latestVersion, minorOrPatchUpdateDetails.storeUrl, save, ); } const breakingUpdateDetails = await VersionCheck.needUpdate({ depth: 1, packageName: Platform.select({ ios: defaults.packageNameIOS, android: defaults.packageNameAndroid, }), }); if (breakingUpdateDetails.isNeeded) { await handleUpdate( true, storage.skipVersion, breakingUpdateDetails.latestVersion, breakingUpdateDetails.storeUrl, save, ); } } catch (e) {} }, [read, save]); useEffect(() => { setInitialized(initialized); }, [initialized, setInitialized]); // init authentication useEffect(() => { initDefaults(); }, [initDefaults]); return ( <View style={style.container}> {mode === ThemeMode.DARK ? ( <LogoDark width={100} height={100} style={style.logo} /> ) : ( <LogoLight width={100} height={100} style={style.logo} /> )} <Name style={style.name}>{title}</Name> <CircleSnail style={style.spinner} size={Math.floor(screen.width / 8)} indeterminate={true} thickness={3} color={theme.textColor} spinDuration={1000} duration={1000} /> </View> ); } function handleUpdate( mandatory: boolean, skipVersion: string | null, availableVersion: string, url: string, save: any, ) { return new Promise<boolean>(resolve => { if (skipVersion && skipVersion === availableVersion) { return resolve(true); } if (mandatory) { Alert.alert( Strings.Update.Mandatory.Title, resolveString(Strings.Update.Mandatory.Text, Strings.Title), [ { text: Strings.Update.Mandatory.Confirm, onPress: async () => { await Linking.openURL(url); }, }, ], {cancelable: false}, ); } else { Alert.alert( Strings.Update.Optional.Title, resolveString(Strings.Update.Optional.Text, Strings.Title), [ { text: Strings.Update.Optional.Skip, onPress: async () => { await save({skipVersion: availableVersion}); resolve(true); }, }, { text: Strings.Update.Optional.Cancel, onPress: () => resolve(false), }, { text: Strings.Update.Optional.Confirm, onPress: async () => { await Linking.openURL(url); resolve(true); }, }, ], {cancelable: false}, ); } }); }