react-native#AppState TypeScript Examples

The following examples show how to use react-native#AppState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExposureNotificationServiceProvider.tsx    From mobile with Apache License 2.0 6 votes vote down vote up
export function useExposureNotificationSystemStatusAutomaticUpdater() {
  const exposureNotificationService = useExposureNotificationService();
  return useCallback(() => {
    const updateStatus = async (newState: AppStateStatus) => {
      if (newState === 'active') {
        await exposureNotificationService.updateSystemStatus();
        await exposureNotificationService.updateExposureStatus();
      }
    };
    AppState.addEventListener('change', updateStatus);

    const bluetoothListenerPromise = SystemSetting.addBluetoothListener(() => {
      exposureNotificationService.updateSystemStatus();
    });

    return () => {
      AppState.removeEventListener('change', updateStatus);
      bluetoothListenerPromise.then(listener => listener.remove()).catch(() => {});
    };
  }, [exposureNotificationService]);
}
Example #2
Source File: UseAppState.ts    From nyxo-app with GNU General Public License v3.0 6 votes vote down vote up
function useAppState(): string {
  const [appState, setAppState] = useState(AppState.currentState)

  useEffect(() => {
    const handleAppStateChange = (nextAppState: AppStateStatus) => {
      setAppState(nextAppState)
    }

    AppState.addEventListener('change', handleAppStateChange)

    return () => {
      AppState.removeEventListener('change', handleAppStateChange)
    }
  }, [])

  return appState
}
Example #3
Source File: App.tsx    From companion-kit with MIT License 6 votes vote down vote up
private _initializeControllers = async () => {
        await this._initializeFirebase();

        this._onAppStateChanged(AppState.currentState);

        this.showDevAlert();

        const AnalyticsService = new AnalyticsExpo();
        InitAnalytics(AnalyticsService);
    }
Example #4
Source File: useAppStateListener.ts    From react-native-sdk with MIT License 6 votes vote down vote up
function useAppStateListener() {
    const appStateEventName = "change"
    const appState = useRef(AppState.currentState)
    const [appStateVisibility, setAppStateVisibility] = useState(appState.current)

    useEffect(() => {
        AppState.addEventListener(
            appStateEventName,
            (nextAppState) => {
                appState.current = nextAppState;
                setAppStateVisibility(appState.current)
            }
        )

        return () => {
            AppState.removeEventListener(
                appStateEventName,
                () => { }
            )
        }
    }, [])

    return appStateVisibility
}
Example #5
Source File: ExposureNotificationServiceProvider.tsx    From mobile with Apache License 2.0 6 votes vote down vote up
export function useExposureNotificationSystemStatusAutomaticUpdater() {
  const exposureNotificationService = useExposureNotificationService();
  return useCallback(() => {
    const updateStatus = async (newState: AppStateStatus) => {
      if (newState !== 'active') return;
      await exposureNotificationService.updateSystemStatus();
    };
    AppState.addEventListener('change', updateStatus);

    const bluetoothListenerPromise = SystemSetting.addBluetoothListener(() => {
      exposureNotificationService.updateSystemStatus();
    });

    const locationListenerPromise =
      Platform.OS === 'android'
        ? SystemSetting.addLocationListener(() => {
            exposureNotificationService.updateSystemStatus();
          })
        : undefined;

    return () => {
      AppState.removeEventListener('change', updateStatus);
      bluetoothListenerPromise.then(listener => listener.remove()).catch(() => {});
      locationListenerPromise?.then(listener => listener.remove()).catch(() => {});
    };
  }, [exposureNotificationService]);
}
Example #6
Source File: contact-scanner.ts    From SQUID with MIT License 6 votes vote down vote up
constructor({ ttl, locationAccuracy, type }: { ttl?: number, locationAccuracy?: number, type: 'bluetooth' | 'qrscan' }) {
    this.locationAccuracy = locationAccuracy
    this.ttl = ttl
    this.type = type
    let prevState
    AppState.addEventListener('change', state => {
      if (prevState !== state) {
        if (state === 'background') {
          this.upload() // trigger upload immediately when user go to background
        }
      }
      prevState = state
    })
  }
Example #7
Source File: app-state.tsx    From protect-scotland with Apache License 2.0 6 votes vote down vote up
export function useAppState(): [AppStateStatus] {
  const [state, setState] = useState<AppStateStatus>(AppState.currentState);
  const handler = (nextState: AppStateStatus) => {
    setState(nextState);
  };

  useEffect(() => {
    AppState.addEventListener('change', handler);
    return () => {
      AppState.removeEventListener('change', handler);
    };
  }, []);

  return [state];
}
Example #8
Source File: ReceiveSharingIntent.ts    From react-native-receive-sharing-intent with MIT License 6 votes vote down vote up
getReceivedFiles(handler: Function, errorHandler: Function, protocol: string = "ShareMedia"){
        if(this.isIos){
            Linking.getInitialURL().then((res:any) => {
                if (res && res.startsWith(`${protocol}://dataUrl`) && !this.isClear) {
                    this.getFileNames(handler, errorHandler, res);
                }
            }).catch(() => { });
            Linking.addEventListener("url", (res:any) => {
                const url = res ? res.url : "";
                if (url.startsWith(`${protocol}://dataUrl`) && !this.isClear) {
                    this.getFileNames(handler,errorHandler, res.url);
                }
            });
        }else{
            AppState.addEventListener('change', (status: string) => {
                if (status === 'active' && !this.isClear) {
                    this.getFileNames(handler,errorHandler, "");
                }
              });
           if(!this.isClear) this.getFileNames(handler,errorHandler, "");
        }
    }
Example #9
Source File: App.tsx    From react-native-chatapp-socket with MIT License 5 votes vote down vote up
AppState.addEventListener('change', handleAppStateChange);
Example #10
Source File: NotificationPermissionStatus.tsx    From mobile with Apache License 2.0 5 votes vote down vote up
NotificationPermissionStatusProvider = ({children}: NotificationPermissionStatusProviderProps) => {
  const [status, setStatus] = useState<NotificationPermissionStatusContextProps['status']>('granted');

  useEffect(() => {
    const {callable, cancelable} = createCancellableCallbackPromise<Status>(
      () =>
        checkNotifications()
          .then(({status}) => status)
          .catch(() => 'unavailable'),
      setStatus,
    );
    callable();
    return cancelable;
  }, []);

  const {callable: request, cancelable} = useMemo(() => {
    return createCancellableCallbackPromise<Status>(
      () =>
        requestNotifications(['alert'])
          .then(({status}) => status)
          .catch(() => 'unavailable'),
      setStatus,
    );
  }, []);
  useEffect(() => {
    return cancelable;
  }, [cancelable]);

  useEffect(() => {
    const {callable: onChange, cancelable: onCancel} = createCancellableCallbackPromise<Status>(
      () =>
        checkNotifications()
          .then(({status}) => status)
          .catch(() => 'unavailable'),
      setStatus,
    );
    AppState.addEventListener('change', onChange);
    return () => {
      onCancel();
      AppState.removeEventListener('change', onChange);
    };
  }, []);

  const props = useMemo(() => request && {status, request}, [status, request]);

  return (
    <NotificationPermissionStatusContext.Provider value={props}>
      {children}
    </NotificationPermissionStatusContext.Provider>
  );
}
Example #11
Source File: ExposureNotificationServiceProvider.tsx    From mobile with Apache License 2.0 5 votes vote down vote up
ExposureNotificationServiceProvider = ({
  backendInterface,
  backgroundScheduler = BackgroundScheduler,
  exposureNotification,
  storage,
  secureStorage,
  children,
}: ExposureNotificationServiceProviderProps) => {
  const i18n = useI18nRef();
  const exposureNotificationService = useMemo(
    () =>
      new ExposureNotificationService(
        backendInterface,
        i18n,
        storage || AsyncStorage,
        secureStorage || RNSecureKeyStore,
        exposureNotification || ExposureNotification,
      ),
    [backendInterface, exposureNotification, i18n, secureStorage, storage],
  );

  useEffect(() => {
    backgroundScheduler.registerPeriodicTask(async () => {
      await exposureNotificationService.updateExposureStatusInBackground();
    });
  }, [backgroundScheduler, exposureNotificationService]);

  useEffect(() => {
    const onAppStateChange = async (newState: AppStateStatus) => {
      captureMessage(`ExposureNotificationServiceProvider onAppStateChange: ${newState}`);
      if (newState !== 'active') return;
      exposureNotificationService.updateExposure();
      await exposureNotificationService.updateExposureStatus();
    };

    // Note: The next two lines, calling updateExposure() and startExposureCheck() happen on app launch.
    exposureNotificationService.updateExposure();
    exposureNotificationService.updateExposureStatus();

    AppState.addEventListener('change', onAppStateChange);
    return () => {
      AppState.removeEventListener('change', onAppStateChange);
    };
  }, [exposureNotificationService]);

  return (
    <ExposureNotificationServiceContext.Provider value={exposureNotificationService}>
      {children}
    </ExposureNotificationServiceContext.Provider>
  );
}
Example #12
Source File: enforce-update.tsx    From SQUID with MIT License 5 votes vote down vote up
withEnforceUpdate = isEnforced => Component => props => {
  useEffect(() => {
    const check = () => {
      if (isEnforced) {
        Alert.alert(
          I18n.t('important_update'),
          I18n.t('pls_update_latest_version_from') +
            (Platform.OS === 'ios' ? 'App Store' : 'Play Store'),
          [
            {
              text: I18n.t('ok'),
              onPress: async () => {
                const url =
                  Platform.OS === 'ios'
                    ? 'https://apps.apple.com/th/app/allthaialert/id1505185420'
                    : 'https://play.google.com/store/apps/details?id=com.thaialert.app'

                await Linking.openURL(url)
              },
            },
          ],
        )
      }
    }
    let prevState
    AppState.addEventListener('change', state => {
      if (state === 'active' && prevState !== state) {
        check()
      }
      prevState = state
    })
    check()
  }, [])
  if (isEnforced) {
    return (
      <View
        style={[
          StyleSheet.absoluteFill,
          {
            backgroundColor: '#00A0D7',
          },
        ]}
      />
    )
  }
  return <Component {...props} />
}
Example #13
Source File: App.tsx    From SQUID with MIT License 5 votes vote down vote up
async load() {
    if (__DEV__) {
      // await this.purgeAll()
    }

    AppState.addEventListener('change', this.handleAppStateChange)

    const locale = () => AsyncStorage.getItem('locale')

    const credential = () =>
      Promise.all([
        applicationState.load(),
        userPrivateData.load(),
        refetchJWKs(),
      ])

    const setUpId = () =>
      NativeModules.ContactTracerModule.setUserId(
        userPrivateData.getAnonymousId(),
      )

    return Promise.all([
      locale(),
      credential(),
      setUpId(),
      refetchDDCPublicKey(),
    ])
      .then((resp) => {
        const lng = resp[0]
        I18n.locale = lng ? lng : 'th'

        backgroundTracking.setup(
          Boolean(applicationState.getData('isPassedOnboarding')),
        )

        this.setState({ loaded: true }, () => {
          SplashScreen.hide()
        })
      })
      .catch(console.log)
  }
Example #14
Source File: MainTabStack.tsx    From vsinder-app with Apache License 2.0 5 votes vote down vote up
MainTabStack: React.FC<MainTabStackProps> = ({}) => {
  const { show } = useShowTabs();
  const {
    editorBackground,
    buttonBackground,
    buttonHoverBackground,
  } = useTheme();

  useEffect(() => {
    const _handleAppStateChange = (nextAppState: AppStateStatus) => {
      if (nextAppState === "active") {
        getSocket().reconnect();
      } else if (nextAppState === "background") {
        getSocket().close();
      }
    };

    AppState.addEventListener("change", _handleAppStateChange);

    return () => {
      AppState.removeEventListener("change", _handleAppStateChange);
    };
  }, []);

  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused }) => {
          const size = 24;
          const color = focused ? buttonHoverBackground : buttonBackground;

          if (route.name === "swiper") {
            return <Entypo name="code" size={size} color={color} />;
          } else if (route.name === "profile") {
            return (
              <MaterialCommunityIcons
                name="account"
                size={size}
                color={color}
              />
            );
          } else if (route.name === "matches") {
            return <MessageIcon size={size} color={color} />;
          }

          return null;
        },
      })}
      swipeEnabled={false}
      tabBarOptions={{
        style: {
          height: show ? undefined : 0,
          backgroundColor: editorBackground,
        },
        indicatorStyle: {
          backgroundColor: buttonHoverBackground,
        },
        showIcon: true,
        showLabel: false,
      }}
      initialRouteName={"swiper"}
    >
      <Tab.Screen name="swiper" component={SwiperScreen} />
      <Tab.Screen name="matches" component={MatchesStack} />
      <Tab.Screen name="profile" component={ProfileStack} />
    </Tab.Navigator>
  );
}
Example #15
Source File: MainTabStack.tsx    From vsinder with Apache License 2.0 5 votes vote down vote up
MainTabStack: React.FC<MainTabStackProps> = ({}) => {
  const { show } = useShowTabs();
  const {
    editorBackground,
    buttonBackground,
    buttonHoverBackground,
  } = useTheme();
  const cache = useQueryCache();

  useEffect(() => {
    const _handleAppStateChange = (nextAppState: AppStateStatus) => {
      if (nextAppState === "active") {
        cache.invalidateQueries(`/matches/0`);
        getSocket().reconnect();
      } else if (nextAppState === "background") {
        getSocket().close();
      }
    };

    AppState.addEventListener("change", _handleAppStateChange);

    return () => {
      AppState.removeEventListener("change", _handleAppStateChange);
    };
  }, []);

  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused }) => {
          const size = 24;
          const color = focused ? buttonHoverBackground : buttonBackground;

          if (route.name === "swiper") {
            return <Entypo name="code" size={size} color={color} />;
          } else if (route.name === "profile") {
            return (
              <MaterialCommunityIcons
                name="account"
                size={size}
                color={color}
              />
            );
          } else if (route.name === "matches") {
            return <MessageIcon size={size} color={color} />;
          }

          return null;
        },
      })}
      swipeEnabled={false}
      tabBarOptions={{
        style: {
          height: show ? undefined : 0,
          backgroundColor: editorBackground,
        },
        indicatorStyle: {
          backgroundColor: buttonHoverBackground,
        },
        showIcon: true,
        showLabel: false,
      }}
      initialRouteName={"swiper"}
    >
      <Tab.Screen name="swiper" component={SwiperScreen} />
      <Tab.Screen name="matches" component={MatchesStack} />
      <Tab.Screen name="profile" component={ProfileStack} />
    </Tab.Navigator>
  );
}
Example #16
Source File: Utils.ts    From BleInTheBackground-iOS with Apache License 2.0 5 votes vote down vote up
AppState.addEventListener('change', state => {
  inForeground = state === 'active';
  log(`App state: ${state}`);
});
Example #17
Source File: LocationIOS.tsx    From hamagen-react-native with MIT License 5 votes vote down vote up
LocationIOS = ({ navigation, strings: { locationIOS: { title, subTitle1, subTitle2, goToSettings, set } }, isRTL }: Props) => {
  const appStateStatus = useRef<AppStateStatus>('active');
  const [isLocationAllowed, setIsLocationAllowed] = useState(false);

  useEffect(() => {
    checkIOSLocation();

    AppState.addEventListener('change', onAppStateChange);
    return () => { AppState.removeEventListener('change', onAppStateChange); };
  });

  const onAppStateChange = async (state: AppStateStatus) => {
    if (state === 'active' && appStateStatus.current !== 'active') {
      await checkIOSLocation();
    }

    appStateStatus.current = state;
  };

  const checkIOSLocation = async () => {
    try {
      const res = await check(PERMISSIONS.IOS.LOCATION_ALWAYS);
      setIsLocationAllowed(res === RESULTS.GRANTED);
    } catch (error) {
      onError({ error });
    }
  };

  return (
    <GeneralContainer style={styles.container}>
      <OnboardingHeader />

      <View style={[{ alignItems: 'center' }, IS_SMALL_SCREEN && { paddingHorizontal: 10, paddingTop: 5 }]}>
        <Text style={styles.title} bold>{title}</Text>
        <Text style={styles.subTitle}>{subTitle1}</Text>
      </View>

      <View style={{ alignItems: 'center' }}>
        <Text bold>{subTitle2}</Text>

        <Icon source={require('../../assets/onboarding/locationTutorial.png')} width={SCREEN_WIDTH - 50} height={106} customStyles={{ marginVertical: 25 }} />

        <TouchableOpacity onPress={() => Linking.openURL('app-settings:')}>
          <View style={{ flexDirection: isRTL ? 'row-reverse' : 'row', alignItems: 'center', paddingHorizontal: IS_SMALL_SCREEN ? 20 : 0 }}>
            <Icon source={require('../../assets/onboarding/settings.png')} width={17} customStyles={{ marginHorizontal: 7 }} />
            <Text style={{ color: MAIN_COLOR, textDecorationLine: 'underline' }} bold>{goToSettings}</Text>
          </View>
        </TouchableOpacity>
      </View>

      <ActionButton
        text={set}
        isDisabled={!isLocationAllowed}
        onPress={() => { navigation.navigate('FilterDrivingOnBoarding'); }
        }
        containerStyle={{ marginVertical: IS_SMALL_SCREEN ? 0 : 20 }}
      />
    </GeneralContainer>
  );
}
Example #18
Source File: App.tsx    From companion-kit with MIT License 5 votes vote down vote up
componentWillUnmount() {
        AppState.removeEventListener('change', this._onAppStateChanged);
        AppQueryService.destroy();
    }
Example #19
Source File: App.tsx    From companion-kit with MIT License 5 votes vote down vote up
componentDidMount() {
        AppState.addEventListener('change', this._onAppStateChanged);
        AppQueryService.prewarm();

        AudioManager.initialize();
    }
Example #20
Source File: App.tsx    From BleInTheBackground-iOS with Apache License 2.0 4 votes vote down vote up
App: () => ReactElement = () => {
  // Register log listener
  const [messages, setMessages] = useState<Array<string> | null>(null);

  const logListener = (message: string) => {
    setMessages(oldMessages => {
      if (oldMessages == null) {
        return [];
      }
      return [...oldMessages, message];
    });
  };

  useEffect(() => {
    addLogListener(logListener);
    collectLogs()
      .then(logs => {
        setMessages(oldMessages => {
          if (oldMessages == null) {
            return logs;
          } else {
            return [...logs, ...oldMessages];
          }
        });
      })
      .catch();
    return () => {
      removeLogListener(logListener);
    };
  }, []);

  // Handle connection
  const [device, setDevice] = useState<Device | null>(null);
  const [connecting, setConnecting] = useState<boolean>(false);

  // Handle execution
  const [executing, setExecuting] = useState<boolean>(false);

  // Handle forground / background modes for logs.
  useEffect(() => {
    const appListener = (state: AppStateStatus) => {
      if (state === 'active') {
        collectLogs()
          .then(logs => {
            setMessages(oldMessages => {
              if (oldMessages == null) {
                return logs;
              } else {
                return [...logs, ...oldMessages];
              }
            });
          })
          .catch();
      } else {
        setMessages([]);
      }
    };
    AppState.addEventListener('change', appListener);
    return () => {
      AppState.removeEventListener('change', appListener);
    };
  }, []);

  return (
    <SafeAreaView style={styles.mainView}>
      <View style={styles.header}>
        <Button
          title={'Connect'}
          disabled={device != null || connecting}
          onPress={() => {
            setConnecting(true);
            establishConnection(() => {
              setDevice(null);
              setExecuting(false);
            })
              .then(connectedDevice => {
                setDevice(connectedDevice);
                setConnecting(false);
              })
              .catch(error => {
                log(`Failed to connect: ${error.message}`);
                setDevice(null);
                setExecuting(false);
                setConnecting(false);
              });
          }}
        />
        <Button
          title={'Disconnect'}
          disabled={device == null}
          onPress={() => {
            if (device != null) {
              cancelAllConnections()
                .then(() => {
                  setDevice(null);
                  setExecuting(false);
                })
                .catch(error => {
                  log(`Failed to disconnect: ${error.message}`);
                  setDevice(null);
                  setExecuting(false);
                });
            }
          }}
        />
        <Button
          title={'Execute'}
          disabled={device == null || executing}
          onPress={() => {
            if (device != null) {
              setExecuting(true);
              executeJob(device)
                .then(() => {
                  setExecuting(false);
                })
                .catch(error => {
                  log(`Failed to execute: ${error.message}`);
                  setExecuting(false);
                });
            }
          }}
        />
        <Button
          title={'Schedule'}
          onPress={() => {
            scheduleBackgroundProcessingTask()
              .then(() => {
                log('Schedule registered');
              })
              .catch(error => {
                log(`Schedule failed with error: ${error.message}`);
              });
          }}
        />
        <Button
          title={'Clear'}
          onPress={() => {
            clearAllLogs();
            setMessages([]);
          }}
        />
      </View>
      {messages == null ? (
        <Text>Waiting for messages...</Text>
      ) : (
        <FlatList
          style={styles.flatList}
          data={messages}
          renderItem={({item}) => {
            return (
              <View style={styles.messageBox}>
                <Text style={styles.messageText}>{item}</Text>
              </View>
            );
          }}
          keyExtractor={(_item, index) => {
            return index.toString();
          }}
        />
      )}
    </SafeAreaView>
  );
}
Example #21
Source File: App.tsx    From protect-scotland with Apache License 2.0 4 votes vote down vote up
App = (props: {exposureNotificationClicked: boolean | null}) => {
  const [state, setState] = React.useState<ScotlandState>({
    loading: false,
    notification: null,
    exposureNotificationClicked: props.exposureNotificationClicked
  });

  useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        const imageAssets = cacheImages([
          require('./assets/images/logo/logo.png'),

          // Pre-load view-specific images so they don't flicker on Android on first load:

          // atoms/message
          require('./assets/images/symptoms/image.png'),

          // molecules/grid
          require('./assets/images/tracing/image.png'),
          require('./assets/images/tracing-inactive/image.png'),
          require('./assets/images/tracing-contact/image.png'),
          require('./assets/images/icon-comment/image.png'),
          require('./assets/images/icon-community-white/image.png'),
          require('./assets/images/icon-jar/image.png'),
          require('./assets/images/grid-paused/image.png'),

          // views/age-confirmation, views/age-under
          require('./assets/images/onboarding-logo/image.png'),
          require('./assets/images/onboarding-group/image.png'),
          require('./assets/images/wave/image.png'),

          // views/age-sorting
          require('./assets/images/age-sorting-age-group-2-illustration/image.png'),
          require('./assets/images/age-sorting-age-group-3-illustration/image.png'),

          // views/community
          require('./assets/images/icon-community-white/image.png'),
          require('./assets/images/community-illustration/image.png'),
          require('./assets/images/downloads-illustration/image.png'),

          // views/dashboard
          require('./assets/images/restrictions/image.png'),

          // views/tests
          require('./assets/images/icon-jar/image.png'),
          require('./assets/images/test-illustration/image.png'),
          require('./assets/images/icon-plus/image.png'),

          // views/tracing
          require('./assets/images/tracing-active/image.png'),
          require('./assets/images/icon-tracing-active-big/image.png'),
          require('./assets/images/icon-tracing-inactive-big/image.png'),
          require('./assets/images/tracing-illustration/image.png'),
          require('./assets/images/icon-close-green/image.png'),
          require('./assets/images/icon-paused/image.png'),

          // views/onboarding/agreement
          require('./assets/images/icon-opt-out/image.png'),

          // views/onboarding/permissions-info
          require('./assets/images/permissions-illustration/image.png'),

          // views/onboarding/privacy
          require('./assets/images/privacy-illustration/image.png'),

          // views/onboarding/test-result-modal
          require('./assets/images/test-result-modal-illustration/image.png'),
          require('./assets/images/message/android/image.png'),
          require('./assets/images/message/ios/image.png'),

          // views/onboarding/test-result
          require('./assets/images/test-result-illustration/image.png'),

          // views/onboarding/why-use
          require('./assets/images/why-use-illustration/image.png'),

          // views/onboarding/your-data-modal
          require('./assets/images/your-data-modal-illustration/image.png'),
          require('./assets/images/notification/android/age-group-1/image.png'),
          require('./assets/images/notification/android/age-group-2-3/image.png'),
          require('./assets/images/notification/ios/age-group-1/image.png'),
          require('./assets/images/notification/ios/age-group-2-3/image.png')
        ]);

        await Font.loadAsync({
          roboto: require('./assets/fonts/Roboto-Regular.ttf'),
          'roboto-bold': require('./assets/fonts/Roboto-Bold.ttf'),
          lato: require('./assets/fonts/Lato-Regular.ttf'),
          'lato-bold': require('./assets/fonts/Lato-Bold.ttf')
        });

        // @ts-ignore
        await Promise.all([...imageAssets]);
      } catch (e) {
        console.warn(e);
      } finally {
        console.log('done');
        setState({...state, loading: false});
      }
    }

    loadResourcesAndDataAsync();

    notificationHooks.handleNotification = async function (notification) {
      let requiresHandling = false;
      if (Platform.OS === 'ios') {
        if (
          (notification && notification.userInteraction) ||
          (AppState.currentState === 'active' && notification)
        ) {
          PushNotification.setApplicationIconBadgeNumber(0);
          requiresHandling = true;
          setTimeout(() => {
            notification.finish(
              Platform.OS === 'ios'
                ? PushNotificationIOS.FetchResult.NoData
                : ''
            );
          }, 3000);
        }
      }
      if (requiresHandling) {
        setTimeout(() => setState((s) => ({...s, notification})), 500);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <SafeAreaProvider>
      <Base>
        <StatusBar barStyle="default" />
        <SettingsProvider>
          <SettingsContext.Consumer>
            {(settingsValue) => {
              if (!settingsValue.loaded) {
                return <Loading />;
              }
              return (
                  <ApplicationProvider
                    user={settingsValue.user}
                    onboarded={settingsValue.onboarded}
                    completedExposureOnboarding={
                      settingsValue.completedExposureOnboarding
                    }>
                    <ExposureApp>
                      <ReminderProvider>
                        <StatusBar barStyle="default" />
                        <Navigation
                          notification={state.notification}
                          exposureNotificationClicked={state.exposureNotificationClicked}
                          completedExposureOnboarding={settingsValue.completedExposureOnboarding}
                          setState={setState}
                        />
                      </ReminderProvider>
                    </ExposureApp>
                  </ApplicationProvider>
              );
            }}
          </SettingsContext.Consumer>
        </SettingsProvider>
      </Base>
    </SafeAreaProvider>
  );
}
Example #22
Source File: ShareLocations.tsx    From hamagen-react-native with MIT License 4 votes vote down vote up
ShareLocations = ({ route, navigation }: Props) => {
  const { isRTL, strings: { shareLocation: { title, description, greeting, button, addBleDataText } } } = useSelector<Store, LocaleReducer>(state => state.locale);
  const dispatch = useDispatch();

  const [state, setState] = useState<ShareStates>('beforeShare');
  const [failState, setFailState] = useState<ShareFailState>('');
  const [canRetry, setRetryState] = useState(true);
  const [agreeToBle, onValueSelected] = useState(true);
  const { token } = route.params;

  useEffect(() => {
    const netInfoUnsubscribe = NetInfo.addEventListener((connectionState: NetInfoState) => {
      if (!connectionState.isConnected) {
        setState('shareNoConnection');
      }
    });

    AppState.addEventListener('change', (appState: AppStateStatus) => {
      if (appState === 'background') {
        navigation.pop();
      }
    });

    return () => {
      netInfoUnsubscribe();
      AppState.removeEventListener('change', () => { });
    };
  }, []);

  const onButtonPress = async () => {
    try {
      if (canRetry) {
        if (state === 'shareNoConnection') {
          const connectionState: NetInfoState = await NetInfo.fetch();
          if (!connectionState.isConnected) return;
        }
        const { statusCode, statusDesc }: any = await dispatch(shareUserLocations(token, agreeToBle));

        switch (statusCode) {
          case 'CompleteSuccessfully':
          case 'CompletSuccessfully': {
            setState('shareSuccess');
            setRetryState(false);
            break;
          }
          case 'CompleteWithWarnings': {
            setState('shareFail');
            setFailState('WithWarnings');
            setRetryState(false);
            break;
          }
          case 'RunTimeError': {
            setState('shareFail');
            setFailState('TokenError');
            break;
          }
          case 'InvalidOperation': {
            switch (statusDesc) {
              case '1':
              case '2':
              case 1:
              case 2: {
                setState('shareFail');
                setFailState('TokenError');
                break;
              }
              case '3':
              case 3: {
                setState('shareSuccess');
                setRetryState(false);
                break;
              }
              default: {
                setState('shareFail');
                setFailState('MissingToken');
                break;
              }
            }
            break;
          }
          default: {
            setState('shareFail');
          }
        }
      } else {
        navigation.goBack();
      }
    } catch (error) {
      setState('shareFail');
      setRetryState(false);
    }
  };

  const Header = canRetry ? <HeaderButton type="close" onPress={() => navigation.pop()} /> : null;
  // @ts-ignore
  const combinedState: ShareStates & ShareFailState = state + failState;

  const AgreeToBleCheckbox = () => {
    if (!IS_IOS && ENABLE_BLE && state === 'beforeShare') {
      return (
        <TouchableOpacity style={{ flexDirection: isRTL ? 'row-reverse' : 'row', marginBottom: 23, paddingHorizontal: 30, alignItems: 'center' }} onPress={() => onValueSelected(!agreeToBle)} accessibilityRole="checkbox" checked={agreeToBle}>
          <View style={styles.box}>
            {agreeToBle && <Icon source={require('../../assets/onboarding/checked.png')} height={8} width={12} customStyles={{ tintColor: TEXT_COLOR }} />}
          </View>

          <Text style={[styles.text, { textAlign: isRTL ? 'right' : 'left' }]}>{addBleDataText}</Text>

        </TouchableOpacity>
      );
    }

    return null;
  };

  return (
    <View style={styles.container}>
      {Header}

      <View style={{ alignItems: 'center' }}>
        <Icon source={ICON[state]} width={IS_SMALL_SCREEN ? 66 : 88} height={IS_SMALL_SCREEN ? 45 : 60} />

        <Text style={styles.title} bold>{title[state]}</Text>
        <Text style={{ ...styles.description, fontSize: IS_SMALL_SCREEN ? 14 : 16 }}>{description[combinedState]}</Text>
        <Text style={{ fontSize: IS_SMALL_SCREEN ? 14 : 16 }} bold>{greeting[state]}</Text>
      </View>
      <View style={{ alignItems: 'center' }}>
        <AgreeToBleCheckbox />
        <ActionButton text={button[combinedState]} onPress={onButtonPress} />
      </View>
    </View>
  );
}
Example #23
Source File: ScanHome.tsx    From hamagen-react-native with MIT License 4 votes vote down vote up
ScanHome: FunctionComponent<ScanHomeProps> = (
  {
    navigation,
    route,
    isRTL,
    strings,
    locale,
    languages,
    externalUrls,
    exposures,
    pastExposures,
    firstPoint,
    enableBle,
    batteryDisabled,
    hideLocationHistory,
    checkForceUpdate,
    checkIfHideLocationHistory,
    checkIfBleEnabled,
    checkIfBatteryDisabled
  }
) => {
  const appStateStatus = useRef<AppStateStatus>('active');
  const [{ hasLocation, hasNetwork, hasGPS }, setIsConnected] = useState({ hasLocation: true, hasNetwork: true, hasGPS: true });

  useEffect(() => {
    init();
  }, []);

  const init = async () => {
    checkIfHideLocationHistory();
    checkIfBatteryDisabled();
    checkConnectionStatusOnLoad();
    checkIfBleEnabled();
    SplashScreen.hide();

    if (exposures.length > 0) {
      navigation.navigate('ExposureDetected');
    } else {
      checkForceUpdate();

      await goToFilterDrivingIfNeeded(navigation);

      const url = await Linking.getInitialURL();


      if (url) {
        return onOpenedFromDeepLink(url, navigation);
      }

      await syncLocationsDBOnLocationEvent();
    }
  };

  useEffect(() => {
    AppState.addEventListener('change', onAppStateChange);
    NetInfo.addEventListener((state: NetInfoState) => setIsConnected({ hasLocation, hasNetwork: state.isConnected, hasGPS }));
    DeviceEventEmitter.addListener(RNSettings.GPS_PROVIDER_EVENT, handleGPSProviderEvent);

    return () => {
      AppState.removeEventListener('change', onAppStateChange);
      DeviceEventEmitter.removeListener(RNSettings.GPS_PROVIDER_EVENT, handleGPSProviderEvent);
    };
  }, [hasLocation, hasNetwork, hasGPS]);

  useFocusEffect(
    React.useCallback(() => {
      const onBackPress = () => {
        BackHandler.exitApp();
        return true;
      };

      BackHandler.addEventListener('hardwareBackPress', onBackPress);

      return () => {
        BackHandler.removeEventListener('hardwareBackPress', onBackPress);
      };
    }, [])
  );

  const checkConnectionStatusOnLoad = async () => {
    const locationPermission = await checkLocationPermissions();
    const networkStatus = await NetInfo.fetch();
    const GPSStatus = await RNSettings.getSetting(RNSettings.LOCATION_SETTING);

    setIsConnected({ hasLocation: locationPermission === RESULTS.GRANTED, hasNetwork: networkStatus.isConnected, hasGPS: GPSStatus === RNSettings.ENABLED });
  };

  const onAppStateChange = async (state: AppStateStatus) => {
    if (state === 'active' && appStateStatus.current !== 'active') {
      checkIfHideLocationHistory();
      checkConnectionStatusOnLoad();
      checkIfBatteryDisabled();
    }

    appStateStatus.current = state;
  };

  const handleGPSProviderEvent = (e: any) => {
    setIsConnected({ hasLocation, hasNetwork, hasGPS: e[RNSettings.LOCATION_SETTING] === RNSettings.ENABLED });
  };

  const exposureState = () => {
    // user never got any exposure detected
    if (exposures.length + pastExposures.length === 0) {
      return 'pristine';
    }

    // check if user past exposures are relevant
    // ie: is less then 14 days old
    if (exposures.some(isAfter14Days) || pastExposures.some(isAfter14Days)) {
      return 'relevant';
    }

    return 'notRelevant';
  };


  const RelevantState = () => {
    if (!hasGPS || !hasLocation) return (<NoGPS {...strings.scanHome.noGPS} />);
    if (!hasNetwork) return (<NoNetwork {...strings.scanHome.noNetwork} />);
    return (
      <NoExposures
        isRTL={isRTL}
        strings={strings}
        firstPoint={firstPoint}
        exposureState={exposureState()}
        hideLocationHistory={hideLocationHistory}
        enableBle={enableBle}
        batteryDisabled={batteryDisabled}
        locale={locale}
        languages={languages}
        externalUrls={externalUrls}
        goToLocationHistory={() => navigation.navigate('LocationHistory')}
        goToBluetoothPermission={() => navigation.navigate('Bluetooth')}
        goToBatteryPermission={() => navigation.navigate('Battery')}
        showBleInfo={route.params?.showBleInfo}
      />
    );
  };


  return (
    <View style={styles.container}>
      <ScanHomeHeader
        enableBle={enableBle}
        languages={languages}
        isRTL={isRTL}
        locale={locale}
        externalUrls={externalUrls}
        strings={strings}
        openDrawer={navigation.openDrawer}
      />
      {RelevantState()}
    </View>
  );
}
Example #24
Source File: NoExposures.tsx    From hamagen-react-native with MIT License 4 votes vote down vote up
NoExposures: FunctionComponent<NoExposuresProps> = ({ exposureState, languages, locale, externalUrls, isRTL, firstPoint, strings, hideLocationHistory, enableBle, batteryDisabled, goToLocationHistory, goToBluetoothPermission, goToBatteryPermission }) => {
  const appState = useRef<AppStateStatus>('active');
  const [showModal, setModalVisibility] = useState(false);

  const [now, setNow] = useState(moment().valueOf());
  const FPDate = useMemo(() => moment(firstPoint).format('D.M.YY'), [firstPoint]);

  const { nowDate, nowHour } = useMemo(() => ({
    nowDate: moment(now).format('D.M.YY'),
    nowHour: moment(now).format('HH:mm')
  }), [now]);

  const { scanHome: { noExposures: { bannerText, bannerTextPristine, workAllTheTime, instructionLinkUpper, instructionLinkLower, bluetoothServiceOff, turnBluetoothOn, canIdentifyWithBluetooth, bluetoothServiceOffTitle, BLESdkOffTitle, BLESdkOff, turnBLESdkOn, moreInformation, card: { title, atHour } } }, locationHistory: { info, moreInfo } } = strings;

  // redundant, ScanHome calls it
  useEffect(() => {
    AppState.addEventListener('change', onStateChange);


    return () => {
      AppState.removeEventListener('change', onStateChange);
    };

  }, []);

  useEffect(() => {
    if (batteryDisabled === null) {
      goToBatteryPermission()
    }
  }, [batteryDisabled])

  const RelevantCard = useMemo(() => {
    if (exposureState !== 'relevant') { return null; }

    const relevantLocale: string = Object.keys(languages.short).includes(locale) ? locale : 'he';

    const furtherInstructions = externalUrls.furtherInstructions[relevantLocale];

    return (
      <TouchableOpacity style={{ flexDirection: isRTL ? 'row' : 'row-reverse', alignContent: 'center', marginTop: IS_SMALL_SCREEN ? 15 : 20 }} onPress={() => Linking.openURL(furtherInstructions)}>
        <View style={{ alignContent: 'flex-end' }}>
          <Text style={{ textAlign: isRTL ? 'right' : 'left', fontSize: IS_SMALL_SCREEN ? 14 : 16 }}>{instructionLinkUpper}</Text>
          <Text bold style={{ textAlign: isRTL ? 'right' : 'left', fontSize: IS_SMALL_SCREEN ? 14 : 16 }}>{instructionLinkLower}</Text>
        </View>
        <Icon
          width={15}
          height={IS_SMALL_SCREEN ? 25 : 30}
          source={require('../../assets/main/isolation.png')}
          customStyles={isRTL ? { marginLeft: 10 } : { marginRight: 10 }}
        />
      </TouchableOpacity>
    );
  }, [exposureState, strings]);

  const onStateChange = async (state: AppStateStatus) => {
    if (state === 'active' && appState.current !== 'active') {
      setNow(moment().valueOf());
    }
    appState.current = state;
  };

  const LocationHistoryInfo = useMemo(() => {
    if (hideLocationHistory) { return null; }
    return (<InfoBubble isRTL={isRTL} info={info} moreInfo={moreInfo} onPress={goToLocationHistory} />);
  }, [hideLocationHistory, locale])

  const EnableBluetooth = useMemo(() => {
    switch (enableBle) {
      case 'false':
        return (<InfoBubble
          isRTL={isRTL}
          title={BLESdkOffTitle}
          info={BLESdkOff}
          moreInfo={turnBLESdkOn}
          onPress={() => toggleBLEService(true)}
        />)
      case 'true':
        return (<BluetoothBubble
          isRTL={isRTL}
          title={bluetoothServiceOffTitle}
          info={bluetoothServiceOff}
          moreInfo={turnBluetoothOn}
        />)
      case null:
        return (
          <InfoBubble
            isRTL={isRTL}
            info={canIdentifyWithBluetooth}
            moreInfo={moreInformation}
            onPress={goToBluetoothPermission}
          />
        )
      case 'blocked':
      default: 
      return null

    }

  },[enableBle, locale])

  return (
    <>
      <FadeInView style={styles.fadeContainer}>
        <ScrollView
          bounces={false}
          contentContainerStyle={{ paddingBottom: PADDING_BOTTOM(10), flexGrow: 1 }}
          showsVerticalScrollIndicator={false}
        >
          <View style={styles.container}>
            {LocationHistoryInfo}
            {EnableBluetooth}
            <LottieView
              style={styles.lottie}
              source={require('../../assets/lottie/magen logo.json')}
              resizeMode="cover"
              autoPlay
              loop
            />

            <Text bold style={styles.workAllTimeTxt}>{workAllTheTime}</Text>
            <Text bold style={styles.bannerText}>{exposureState === 'pristine' ? bannerTextPristine : bannerText}</Text>
          </View>
          <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'space-around' }}>

            <View style={styles.bottomCard}>

              <Text style={styles.cardHeaderText}>{title}</Text>
              <View style={styles.cardBody}>
                <TouchableOpacity
                  onPress={() => setModalVisibility(true)}
                  hitSlop={HIT_SLOP}
                >
                  <Icon
                    width={15}
                    source={require('../../assets/main/moreInfoBig.png')}
                    customStyles={styles.infoIcon}
                  />
                </TouchableOpacity>
                <Text>
                  <Text bold style={styles.toTimeDate}>{nowDate}</Text>
                  <Text style={styles.toTimeText}>{` ${atHour.trim()} `}</Text>
                  <Text bold style={styles.toTimeDate}>{nowHour}</Text>
                </Text>
              </View>

            </View>
            {RelevantCard}
          </View>
        </ScrollView>
      </FadeInView>

      <InfoModal
        strings={strings}
        showModal={showModal}
        firstPointDate={FPDate}
        closeModal={() => setModalVisibility(false)}
      />
    </>
  );
}
Example #25
Source File: Main.tsx    From hive-keychain-mobile with MIT License 4 votes vote down vote up
Main = ({
  loadAccount,
  loadProperties,
  loadPrices,
  fetchPhishingAccounts,
  user,
  properties,
  accounts,
  lastAccount,
  navigation,
  hive_authentication_service,
}: PropsFromRedux & {navigation: WalletNavigation}) => {
  const styles = getDimensionedStyles(useWindowDimensions());

  useEffect(() => {
    loadAccount(lastAccount || accounts[0].name);
    loadProperties();
    loadPrices();
    fetchPhishingAccounts();
  }, [
    loadAccount,
    accounts,
    loadProperties,
    loadPrices,
    fetchPhishingAccounts,
    lastAccount,
  ]);

  useLockedPortrait(navigation);

  const appState = useRef(AppState.currentState);

  useEffect(() => {
    const handler = (nextAppState: AppStateStatus) => {
      if (
        appState.current.match(/inactive|background/) &&
        nextAppState === 'active'
      ) {
        if (
          hive_authentication_service.instances.length &&
          !hive_authentication_service.instances.filter(
            (e) => e.init && e.connected,
          ).length
        ) {
          restartHASSockets();
        }
      }

      appState.current = nextAppState;
    };
    AppState.addEventListener('change', handler);

    return () => {
      AppState.removeEventListener('change', handler);
    };
  }, []);

  if (!user) {
    return null;
  }

  return (
    <WalletPage>
      <>
        <UserPicker
          accounts={accounts.map((account) => account.name)}
          username={user.name!}
          onAccountSelected={loadAccount}
        />
        <View style={styles.resourcesWrapper}>
          <PercentageDisplay
            name={translate('wallet.rc')}
            percent={user.rc.percentage / 100 || 100}
            color="#E59D15"
          />
          <PercentageDisplay
            name={translate('wallet.vp')}
            percent={getVP(user.account) || 100}
            color="#3BB26E"
            secondary={`$${
              getVotingDollarsPerAccount(
                100,
                properties,
                user.account,
                false,
              ) || '0'
            }`}
          />
        </View>
        <ScreenToggle
          style={styles.toggle}
          menu={[
            translate(`wallet.menu.hive`),
            translate(`wallet.menu.history`),
            translate(`wallet.menu.tokens`),
          ]}
          toUpperCase
          components={[<Primary />, <Transactions user={user} />, <Tokens />]}
        />
      </>
    </WalletPage>
  );
}