119 lines
2.9 KiB
JavaScript
119 lines
2.9 KiB
JavaScript
import { createAtom } from "~/lib/atomic-zustand";
|
|
|
|
import getNearbyDefibs from "~/data/getNearbyDefibs";
|
|
import {
|
|
computeCorridorQueryRadiusMeters,
|
|
filterDefibsInCorridor,
|
|
} from "~/utils/geo/corridor";
|
|
|
|
const DEFAULT_NEAR_USER_RADIUS_M = 10_000;
|
|
const DEFAULT_CORRIDOR_M = 10_000;
|
|
const DEFAULT_LIMIT = 200;
|
|
|
|
export default createAtom(({ merge, reset }) => {
|
|
const actions = {
|
|
reset,
|
|
|
|
setShowDefibsOnAlertMap: (showDefibsOnAlertMap) => {
|
|
merge({ showDefibsOnAlertMap });
|
|
},
|
|
|
|
setSelectedDefib: (selectedDefib) => {
|
|
merge({ selectedDefib });
|
|
},
|
|
|
|
setShowDaeSuggestModal: (showDaeSuggestModal) => {
|
|
merge({ showDaeSuggestModal });
|
|
},
|
|
|
|
setShowUnavailable: (showUnavailable) => {
|
|
merge({ showUnavailable });
|
|
},
|
|
|
|
loadNearUser: async ({
|
|
userLonLat,
|
|
radiusMeters = DEFAULT_NEAR_USER_RADIUS_M,
|
|
}) => {
|
|
merge({ loadingNearUser: true, errorNearUser: null });
|
|
try {
|
|
const [lon, lat] = userLonLat;
|
|
const nearUserDefibs = await getNearbyDefibs({
|
|
lat,
|
|
lon,
|
|
radiusMeters,
|
|
limit: DEFAULT_LIMIT,
|
|
progressive: true,
|
|
});
|
|
merge({ nearUserDefibs, loadingNearUser: false });
|
|
return { defibs: nearUserDefibs, error: null };
|
|
} catch (error) {
|
|
merge({
|
|
nearUserDefibs: [],
|
|
loadingNearUser: false,
|
|
errorNearUser: error,
|
|
});
|
|
return { defibs: [], error };
|
|
}
|
|
},
|
|
|
|
loadCorridor: async ({
|
|
userLonLat,
|
|
alertLonLat,
|
|
corridorMeters = DEFAULT_CORRIDOR_M,
|
|
}) => {
|
|
merge({ loadingCorridor: true, errorCorridor: null });
|
|
try {
|
|
const radiusMeters = computeCorridorQueryRadiusMeters({
|
|
userLonLat,
|
|
alertLonLat,
|
|
corridorMeters,
|
|
});
|
|
|
|
const midLon = (userLonLat[0] + alertLonLat[0]) / 2;
|
|
const midLat = (userLonLat[1] + alertLonLat[1]) / 2;
|
|
|
|
const candidates = await getNearbyDefibs({
|
|
lat: midLat,
|
|
lon: midLon,
|
|
radiusMeters,
|
|
limit: DEFAULT_LIMIT,
|
|
progressive: true,
|
|
});
|
|
|
|
const corridorDefibs = filterDefibsInCorridor({
|
|
defibs: candidates,
|
|
userLonLat,
|
|
alertLonLat,
|
|
corridorMeters,
|
|
}).slice(0, DEFAULT_LIMIT);
|
|
|
|
merge({ corridorDefibs, loadingCorridor: false });
|
|
return { defibs: corridorDefibs, error: null };
|
|
} catch (error) {
|
|
merge({
|
|
corridorDefibs: [],
|
|
loadingCorridor: false,
|
|
errorCorridor: error,
|
|
});
|
|
return { defibs: [], error };
|
|
}
|
|
},
|
|
};
|
|
|
|
return {
|
|
default: {
|
|
nearUserDefibs: [],
|
|
corridorDefibs: [],
|
|
showDefibsOnAlertMap: false,
|
|
selectedDefib: null,
|
|
showDaeSuggestModal: false,
|
|
showUnavailable: false,
|
|
|
|
loadingNearUser: false,
|
|
loadingCorridor: false,
|
|
errorNearUser: null,
|
|
errorCorridor: null,
|
|
},
|
|
actions,
|
|
};
|
|
});
|