All files / src/hooks useLocationService.ts

100% Statements 51/51
100% Branches 14/14
100% Functions 15/15
100% Lines 47/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124                  213x 213x 32x 213x   32x 213x   213x 213x 32x 32x                 32x   32x   32x             32x 2x 1x 1x   1x     32x 15x     32x 22x 5x 5x 5x   5x 3x 3x 2x       5x 2x 2x 2x 1x   1x       5x     22x       22x 22x                   32x 22x 5x   17x       32x 15x 15x       32x                                
import { useCallback, useEffect, useRef } from "react";
import { AppState, AppStateStatus, Linking, Platform } from "react-native";
import useLocationStore from "./useLocationStore";
import useNavigationState from "./useNavigationState";
import useLocationPermission from "./useLocationPermission";
import useLocationWatcher from "./useLocationWatcher";
import useNearbyBuildings from "./useNearbyBuildings";
 
export default function useLocationService() {
  const isInitialized = useLocationStore((s) => s.isInitialized);
  const permissionStatus = useLocationStore((s) => s.permissionStatus);
  const hasSeenPermissionScreen = useLocationStore(
    (s) => s.hasSeenPermissionScreen,
  );
  const userSkippedPermission = useLocationStore(
    (s) => s.userSkippedPermission,
  );
  const movementMode = useLocationStore((s) => s.movementMode);
  const setIsAppInBackground = useLocationStore((s) => s.setIsAppInBackground);
  const { isNavigating } = useNavigationState();
  const appStateRef = useRef<AppStateStatus>(AppState.currentState);
 
  const {
    initialize,
    checkLocationServices,
    checkPermission,
    requestPermission,
    markPermissionScreenSeen,
    markUserSkipped,
  } = useLocationPermission();
 
  const { getNearbyBuildingUpdates } = useNearbyBuildings();
  const { startWatching, stopWatching, getCurrentPosition } =
    useLocationWatcher({
      permissionStatus,
      movementMode,
      isNavigating,
      getNearbyBuildingUpdates,
    });
 
  const openSettings = useCallback(async () => {
    if (Platform.OS === "ios") {
      await Linking.openURL("app-settings:");
      return;
    }
    await Linking.openSettings();
  }, []);
 
  useEffect(() => {
    void initialize();
  }, [initialize]);
 
  useEffect(() => {
    const handleAppStateChange = async (nextAppState: AppStateStatus) => {
      const wasInBackground = appStateRef.current.match(/inactive|background/);
      const isGoingToBackground = nextAppState.match(/inactive|background/);
      const isComingToForeground = wasInBackground && nextAppState === "active";
 
      if (isGoingToBackground) {
        setIsAppInBackground(true);
        if (!isNavigating) {
          stopWatching();
        }
      }
 
      if (isComingToForeground) {
        setIsAppInBackground(false);
        const status = await checkPermission();
        if (status === "granted") {
          void startWatching();
        } else {
          stopWatching();
        }
      }
 
      appStateRef.current = nextAppState;
    };
 
    const subscription = AppState.addEventListener(
      "change",
      handleAppStateChange,
    );
    return () => {
      subscription.remove();
    };
  }, [
    checkPermission,
    isNavigating,
    setIsAppInBackground,
    startWatching,
    stopWatching,
  ]);
 
  useEffect(() => {
    if (permissionStatus === "granted") {
      void startWatching();
    } else {
      stopWatching();
    }
  }, [permissionStatus, startWatching, stopWatching]);
 
  useEffect(() => {
    return () => {
      stopWatching();
    };
  }, [stopWatching]);
 
  return {
    isInitialized,
    permissionStatus,
    hasSeenPermissionScreen,
    userSkippedPermission,
    checkLocationServices,
    checkPermission,
    requestPermission,
    markPermissionScreenSeen,
    markUserSkipped,
    openSettings,
    startWatching,
    stopWatching,
    getCurrentPosition,
  };
}