-
-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathuseWalkingDurationQuery.ts
More file actions
117 lines (96 loc) · 3.35 KB
/
Copy pathuseWalkingDurationQuery.ts
File metadata and controls
117 lines (96 loc) · 3.35 KB
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
import { useQuery } from '@tanstack/react-query';
import type { ResourceEntry } from 'types/ResourceEntry';
import getUserLocation from 'utils/getUserLocation';
import useActiveSearchLocation from 'hooks/useActiveSearchLocation';
import { env } from 'config';
const BASE_URL = 'https://api.openrouteservice.org/v2';
const PATH = '/directions/foot-walking';
type UseWalkingDurationQueryOptions = {
selectedResource: ResourceEntry;
};
type UserLocationWalkingDurationResponse = {
locationPermissionState: 'granted';
minutes: number;
from: 'your location';
};
type ActiveSearchWalkingDurationResponse = {
locationPermissionState: Omit<PermissionState, 'granted'>;
minutes: number;
from: 'current search';
};
type WalkingDurationNotFoundResponse = {
locationPermissionState: PermissionState;
minutes: null;
from: null;
};
type UseWalkingDurationResponse =
| UserLocationWalkingDurationResponse
| ActiveSearchWalkingDurationResponse
| WalkingDurationNotFoundResponse;
const getUserLocationIfGranted = async (
state: PermissionState
): Promise<google.maps.LatLngLiteral | null> => {
if (state !== 'granted') {
return null;
}
const [userLocation, isUserLocationDisabled] = await getUserLocation();
if (isUserLocationDisabled) {
return null;
}
return userLocation;
};
export const useWalkingDurationQuery = ({
selectedResource
}: UseWalkingDurationQueryOptions) => {
const { activeSearchLocation } = useActiveSearchLocation();
const { latitude, longitude } = selectedResource;
const queryFn = async (): Promise<UseWalkingDurationResponse> => {
const locationPermission = await navigator.permissions.query({
name: 'geolocation'
});
const { state } = locationPermission;
if (state === 'denied' && !activeSearchLocation) {
return { locationPermissionState: 'denied', from: null, minutes: null };
}
const userLocation = await getUserLocationIfGranted(state);
const location = userLocation || activeSearchLocation;
if (!location) {
return { locationPermissionState: state, minutes: null, from: null };
}
const startingLocation = [location.lng, location.lat].join(',');
const endingLocation = [longitude, latitude].join(',');
const params = new URLSearchParams({
api_key: env.VITE_OPEN_ROUTE_SERVICE_API_KEY,
start: startingLocation,
end: endingLocation
});
const url = `${BASE_URL}${PATH}${`?${params.toString()}`}`;
const response = await fetch(url);
if (!response.ok) {
return { locationPermissionState: state, from: null, minutes: null };
}
const data: OpenRouteServiceFootWalkingDirectionResponse =
await response.json();
const firstFeature = data.features.at(0);
if (!firstFeature) {
return { locationPermissionState: state, minutes: null, from: null };
}
const { duration } = firstFeature.properties.summary;
const minutes = Math.round(duration / 60);
if (state === 'granted') {
return { locationPermissionState: state, minutes, from: 'your location' };
}
return { locationPermissionState: state, minutes, from: 'current search' };
};
const { data, refetch, isPending, isRefetching, isError } = useQuery({
queryKey: ['walking-duration', { selectedResource, longitude, latitude }],
queryFn
});
return {
data,
isPending,
isRefetching,
refetch,
isError
};
};