diff options
Diffstat (limited to 'src/View/Map.ml')
-rw-r--r-- | src/View/Map.ml | 109 |
1 files changed, 84 insertions, 25 deletions
diff --git a/src/View/Map.ml b/src/View/Map.ml index bcd0506..969a95a 100644 --- a/src/View/Map.ml +++ b/src/View/Map.ml @@ -1,28 +1,87 @@ -let render () = - let - _ = - Js.Global.setTimeout - (fun () -> - let map = Leaflet.map("g-Map__Content") in - let tileLayer = Leaflet.tileLayer "http://{s}.tile.osm.org/{z}/{x}/{y}.png" in - let () = Leaflet.addTo tileLayer map in - let () = Leaflet.setView map [| 51.505; -0.09 |] 13 in - Leaflet.on map "contextmenu" (fun (event) -> - Leaflet.addTo (Leaflet.marker (Leaflet.latLng event) { title = "Hey"; }) map)) - 0 - in +let mapView = H.div - ~attributes:[| H.className "g-Layout__Page" |] - ~children: [| - H.div - ~attributes:[| H.className "g-Layout__Header" |] - ~children:[| H.text "Map" |] - (); - H.div - ~attributes:[| H.className "g-Map" |] - ~children:[| - H.div ~attributes:[| H.id "g-Map__Content" |] () + [| HA.class_ "g-Layout__Page" |] + [| H.div + [| HA.class_ "g-Layout__Header" |] + [| H.a + [| HA.class_ "g-Layout__Home" + ; HA.href "#" + |] + [| H.text "Map" |] + |] + ; H.div + [| HA.class_ "g-Map" |] + [| H.div + [| HA.id "g-Map__Content" |] + [||] |] - (); |] - () + +let state_from_hash () = + let hash = Js.String.sliceToEnd ~from:1 (Location.hash Document.location) in + State.from_string hash + +let installMap () = + let state = ref (state_from_hash ()) in + let map = Leaflet.map "g-Map__Content" in + let title_layer = Leaflet.title_layer "http://{s}.tile.osm.org/{z}/{x}/{y}.png" in + let markers = Leaflet.feature_group [| |] in + let () = Leaflet.add_layer map markers in + let () = Leaflet.add_layer map title_layer in + + let rec reload_from_hash focus = + let update_state new_state = + let () = History.push_state "" "" ("#" ^ State.to_string new_state) () in + reload_from_hash false + in + + let on_remove pos = + update_state (State.remove !state pos) in + + let on_update previousPos pos name color icon = + update_state (State.update !state previousPos { pos = pos; name = name; color = color; icon = icon }) in + + let () = + if Js.Array.length (Leaflet.get_layers markers ()) > 0 then + Leaflet.clear_layers markers + else + () + in + let () = state := state_from_hash () in + let () = + Js.Array.forEach + (fun (m: State.marker_state) -> Leaflet.add_layer markers (Marker.create on_remove on_update m.pos m.name m.color m.icon)) + !state + in + if focus then + if Js.Array.length (Leaflet.get_layers markers ()) > 0 then + Leaflet.fit_bounds map (Leaflet.get_bounds markers ()) { padding = [| 50.; 50. |] } + else + Leaflet.setView map [| 51.505; -0.09 |] 2 + else + () + in + + (* Init markers from url *) + let () = reload_from_hash true in + + (* Reload the map if the URL changes *) + let () = Element.addEventListener Window.window "popstate" (fun _ -> + reload_from_hash true) + in + + (* Add a marker on right click *) + Leaflet.on map "contextmenu" (fun (event) -> + let pos = Leaflet.lat_lng event in + let new_marker = + match State.last_added !state with + | Some m -> { m with pos = pos; name = "" } + | None -> { pos = pos; name = ""; color = "#3f92cf"; icon = "" } + in + let new_state = State.update !state pos new_marker in + let () = History.push_state "" "" ("#" ^ State.to_string new_state) () in + reload_from_hash false) + +let render () = + let _ = Js.Global.setTimeout installMap 0 in + mapView |