ContextMenu.res

  1let show: Preact.Signal.t<option<Maplibre.mapLayerMouseEvent>> = Preact.Signal.make(None)
  2let handleWaypoint = async (lon: float, lat: float, editor: option<Tiptap.t>) => {
  3  let params: Waldo.Reverse.params = {lon, lat}
  4
  5  switch await Waldo.Reverse.geocode(~params) {
  6  | Success(results) => switch results->Array.get(0) {
  7    | Some(result) => {
  8        let waypointContent = Obj.magic({
  9          "type": "waypoint",
 10          "attrs": {
 11            "id": NanoID.make(),
 12            "point": (lon, lat),
 13            "label": result.name,
 14            "country": result.country,
 15            "gid": Int.toString(result.gid),
 16            "from": None,
 17            "cons": [],
 18            "nonroutable": false,
 19            "error": None,
 20          },
 21        })
 22
 23        let textContent = Obj.magic({"type": "text", "content": " "})
 24
 25        switch editor {
 26        | Some(ed) => {
 27            ed->Tiptap.Commands.insertContent(waypointContent)
 28            ed->Tiptap.Commands.insertContent(textContent)
 29          }
 30        | None => ()
 31        }
 32      }
 33    | None => Log.warn(
 34        "Reverse geocode returned no results",
 35        ~kv={
 36          "lon": Float.toString(lon),
 37          "lat": Float.toString(lat),
 38        },
 39      )
 40    }
 41  | Error(msg) => Log.error(
 42      "Reverse geocode error",
 43      ~kv={
 44        "error": msg,
 45        "lon": Float.toString(lon),
 46        "lat": Float.toString(lat),
 47      },
 48    )
 49  | NetworkError(msg) => Log.error(
 50      "Reverse geocode network error",
 51      ~kv={
 52        "error": msg,
 53        "lon": Float.toString(lon),
 54        "lat": Float.toString(lat),
 55      },
 56    )
 57  }
 58
 59  show->Preact.Signal.set(None)
 60}
 61
 62@jsx.component
 63let make = (~doc: string) => {
 64  let editor = State.Editor.get(doc)
 65  let (lon, lat) = switch show->Preact.Signal.get {
 66  | Some(evt) => (evt.lngLat.lng, evt.lngLat.lat)
 67  | None => (0.0, 0.0)
 68  }
 69  show->Preact.Signal.get->Option.isSome
 70    ? <>
 71        <Maplibre.Marker latitude={lat} longitude={lon}>
 72          <Icons.Dot className="text-(--color-orange)" strokeWidth={6} />
 73        </Maplibre.Marker>
 74        <Maplibre.Popup
 75          anchor={TopLeft}
 76          longitude={lon}
 77          latitude={lat}
 78          closeButton={false}
 79          onClose={_ => show->Preact.Signal.set(None)}
 80          closeOnClick={true}
 81          closeOnMove={true}
 82          className="m-0 p-0 bg-[#FFFFFF00]"
 83          style={{"margin": 0, "padding": 0, "background": "#FFFFFF00"}}
 84        >
 85          <style>
 86            {"
 87        .maplibregl-popup-content {
 88          margin: 0;
 89          padding: 0;
 90          padding-top: 2px;
 91        }
 92      "->Preact.string}
 93          </style>
 94          <div
 95            className="flex flex-col m-0 p-0 rounded-b-sm rounded-r-sm gap-1 justify-start items-start"
 96          >
 97            <div className="flex flex-row gap-1 hover:bg-blue-100 justify-start px-1 w-full">
 98              <Icons.MapPinned className="my-auto" />
 99              <a
100                className="w-full px-2 py-1 text-md"
101                href={`https://www.google.com/maps/@${lat->Float.toString},${lon->Float.toString},15z`}
102                target="_blank"
103                onClick={_ => show->Preact.Signal.set(None)}
104              >
105                {"Open Google Maps"->Preact.string}
106              </a>
107            </div>
108            <div className="flex flex-row gap-1 hover:bg-blue-100 justify-start px-1 w-full">
109              <Icons.Waypoint className="my-auto" />
110              <button
111                className="w-full py-1 px-2 text-md"
112                onClick={_ => {
113                  let _ = handleWaypoint(lon, lat, editor)
114                }}
115              >
116                {"Add waypoint"->Preact.string}
117              </button>
118            </div>
119          </div>
120        </Maplibre.Popup>
121      </>
122    : Preact.null
123}