All files / src/hooks useLocationStore.ts

100% Statements 8/8
100% Branches 0/0
100% Functions 5/5
100% Lines 8/8

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                                                                                                                          5x 5x 65x 126x   5x 5x   5x                                                                   1x                            
import { create } from "zustand";
import { Building } from "../data/buildings";
import { Coordinate } from "../type";
 
export type PermissionStatus =
  | "undetermined"
  | "granted"
  | "denied"
  | "revoked";
 
export type MovementMode = "idle" | "walking" | "biking" | "transit";
 
export interface LocationState {
  isInitialized: boolean;
  setIsInitialized: (initialized: boolean) => void;
 
  permissionStatus: PermissionStatus;
  setPermissionStatus: (status: PermissionStatus) => void;
 
  locationServicesEnabled: boolean;
  setLocationServicesEnabled: (enabled: boolean) => void;
 
  canAskAgain: boolean;
  setCanAskAgain: (canAsk: boolean) => void;
 
  hasSeenPermissionScreen: boolean;
  setHasSeenPermissionScreen: (seen: boolean) => void;
 
  userSkippedPermission: boolean;
  setUserSkippedPermission: (skipped: boolean) => void;
 
  currentLocation: Coordinate | null;
  setCurrentLocation: (location: Coordinate | null) => void;
 
  currentSpeed: number;
  setCurrentSpeed: (speed: number) => void;
 
  currentHeading: number | null;
  setCurrentHeading: (heading: number | null) => void;
 
  movementMode: MovementMode;
  setMovementMode: (mode: MovementMode) => void;
 
  nearestBuilding: Building | null;
  nearestBuildingDistance: number | null;
  setNearestBuilding: (
    building: Building | null,
    distance: number | null,
  ) => void;
 
  isWatchingLocation: boolean;
  setIsWatchingLocation: (watching: boolean) => void;
 
  isAppInBackground: boolean;
  setIsAppInBackground: (inBackground: boolean) => void;
 
  lastPermissionCheck: number;
  setLastPermissionCheck: (timestamp: number) => void;
}
 
const setter =
  <T extends object>(set: (partial: Partial<T>) => void) =>
  <K extends keyof T>(key: K) =>
  (value: T[K]) =>
    set({ [key]: value } as unknown as Partial<T>);
 
const useLocationStore = create<LocationState>((set) => {
  const s = setter<LocationState>(set);
 
  return {
    isInitialized: false,
    setIsInitialized: s("isInitialized"),
 
    permissionStatus: "undetermined",
    setPermissionStatus: s("permissionStatus"),
 
    locationServicesEnabled: true,
    setLocationServicesEnabled: s("locationServicesEnabled"),
 
    canAskAgain: true,
    setCanAskAgain: s("canAskAgain"),
 
    hasSeenPermissionScreen: false,
    setHasSeenPermissionScreen: s("hasSeenPermissionScreen"),
 
    userSkippedPermission: false,
    setUserSkippedPermission: s("userSkippedPermission"),
 
    currentLocation: null,
    setCurrentLocation: s("currentLocation"),
 
    currentSpeed: 0,
    setCurrentSpeed: s("currentSpeed"),
 
    currentHeading: null,
    setCurrentHeading: s("currentHeading"),
 
    movementMode: "idle",
    setMovementMode: s("movementMode"),
 
    nearestBuilding: null,
    nearestBuildingDistance: null,
    setNearestBuilding: (building, distance) =>
      set({ nearestBuilding: building, nearestBuildingDistance: distance }),
 
    isWatchingLocation: false,
    setIsWatchingLocation: s("isWatchingLocation"),
 
    isAppInBackground: false,
    setIsAppInBackground: s("isAppInBackground"),
 
    lastPermissionCheck: 0,
    setLastPermissionCheck: s("lastPermissionCheck"),
  };
});
 
export default useLocationStore;