Skip to content

Commit

Permalink
wip! pull detour points up into variables
Browse files Browse the repository at this point in the history
  • Loading branch information
firestack committed May 23, 2024
1 parent 44a246c commit 068d537
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 47 deletions.
87 changes: 44 additions & 43 deletions assets/src/hooks/useDetour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { OriginalRoute } from "../models/detour"
import { useApiCall } from "./useApiCall"
import { Ok, isErr, isOk } from "../util/result"
import { useNearestIntersection } from "./useNearestIntersection"
import { useMachine } from "@xstate/react"
import { useMachine, useSelector } from "@xstate/react"
import { createDetourMachine } from "../models/createDetourMachine"
import { SnapshotFrom } from "xstate"

const useDetourDirections = (shapePoints: ShapePoint[]) =>
useApiCall({
Expand All @@ -27,9 +28,9 @@ export enum DetourState {
Finished,
}

export const useDetour = ({ routePatternId, shape }: OriginalRoute) => {
const [snapshot, send] = useMachine(createDetourMachine)

const selectFinishedState = (
snapshot: SnapshotFrom<typeof createDetourMachine>
) => {
/*
* There's probably a better way to do this? Tags or maybe context?
* Tags seem more appropriate, but weird to manage Out-Of-Bounds state via tags.
Expand All @@ -41,49 +42,60 @@ export const useDetour = ({ routePatternId, shape }: OriginalRoute) => {
})
const isSharingDetour = snapshot.matches({ "Detour Drawing": "Share Detour" })
const isInFinishedDetourState = isFinishedDrawing || isSharingDetour
return isInFinishedDetourState
}

const selectWaypoints = (snapshot: SnapshotFrom<typeof createDetourMachine>) =>
snapshot.matches({
"Detour Drawing": { Editing: "Finished Drawing" },
})
? snapshot.context.waypoints.slice(1, -1)
: snapshot.matches({ "Detour Drawing": { Editing: "Place Waypoint" } })
? snapshot.context.waypoints.slice(1)
: []

const selectStartPoint = (snapshot: SnapshotFrom<typeof createDetourMachine>) =>
snapshot.context.waypoints.at(0)

const firstWaypoint = snapshot.context.waypoints.at(0)
const lastWaypoint = snapshot.context.waypoints.at(-1)
// Lets also just assert that we're not operating on the same array element
const has2Waypoints = snapshot.context.waypoints.length >= 2
const selectEndPoint = (snapshot: SnapshotFrom<typeof createDetourMachine>) =>
(selectFinishedState(snapshot) && snapshot.context.waypoints.at(-1)) ||
undefined

export const useDetour = ({ routePatternId, shape }: OriginalRoute) => {
const [snapshot, send, createDetourActor] = useMachine(createDetourMachine)
const startPoint = useSelector(createDetourActor, selectStartPoint)
const endPoint = useSelector(createDetourActor, selectEndPoint)
const waypoints = useSelector(createDetourActor, selectWaypoints)
const allPoints = snapshot.context.waypoints

const isInFinishedDetourState = useSelector(
createDetourActor,
selectFinishedState
)

const { result: finishedDetour } = useApiCall({
apiCall: useCallback(async () => {
if (!isInFinishedDetourState) {
return null
}

/* Until we have "typegen" in XState,
* we need to validate these exist for typescript
*
* > [Warning] XState Typegen does not fully support XState v5 yet. However,
* > strongly-typed machines can still be achieved without Typegen.
* > -- https://stately.ai/docs/migration#use-typestypegen-instead-of-tstypes
*/
if (
!has2Waypoints ||
firstWaypoint === undefined ||
lastWaypoint === undefined
) {
return null
if (isInFinishedDetourState && startPoint && endPoint) {
return fetchFinishedDetour(routePatternId, startPoint, endPoint)
}

return fetchFinishedDetour(routePatternId, firstWaypoint, lastWaypoint)
}, [
isInFinishedDetourState,
firstWaypoint,
lastWaypoint,
has2Waypoints,
routePatternId,
]),
return null
}, [isInFinishedDetourState, startPoint, endPoint, routePatternId]),
})

const { result: nearestIntersection } = useNearestIntersection({
latitude: snapshot.context.waypoints.at(0)?.lat,
longitude: snapshot.context.waypoints.at(0)?.lon,
latitude: startPoint?.lat,
longitude: startPoint?.lon,
})

const detourShape = useDetourDirections(snapshot.context.waypoints)
const detourShape = useDetourDirections(allPoints)

const coordinates =
detourShape.result && isOk(detourShape.result)
Expand Down Expand Up @@ -169,26 +181,15 @@ export const useDetour = ({ routePatternId, shape }: OriginalRoute) => {
/**
* The starting connection point of the detour.
*/
startPoint: snapshot.context.waypoints.at(0),
startPoint,
/**
* The ending connection point of the detour.
*/
endPoint:
(snapshot.matches({
"Detour Drawing": { Editing: "Finished Drawing" },
}) &&
snapshot.context.waypoints.at(-1)) ||
undefined,
endPoint,
/**
* The waypoints that connect {@link startPoint} and {@link endPoint}.
*/
waypoints: snapshot.matches({
"Detour Drawing": { Editing: "Finished Drawing" },
})
? snapshot.context.waypoints.slice(1, -1)
: snapshot.matches({ "Detour Drawing": { Editing: "Place Waypoint" } })
? snapshot.context.waypoints.slice(1)
: [],
waypoints,

/**
* The routing API generated detour shape.
Expand Down
8 changes: 4 additions & 4 deletions assets/src/models/createDetourMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export const createDetourMachine = setup({
target: "Place Waypoint",
actions: {
type: "detour.add-waypoint",
params: ({ event }) => ({
location: event.location,
params: ({ event: { location } }) => ({
location,
}),
},
},
Expand All @@ -72,8 +72,8 @@ export const createDetourMachine = setup({
"detour.edit.place-waypoint": {
actions: {
type: "detour.add-waypoint",
params: ({ event }) => ({
location: event.location,
params: ({ event: { location } }) => ({
location,
}),
},
},
Expand Down

0 comments on commit 068d537

Please sign in to comment.