aboutsummaryrefslogtreecommitdiff
path: root/src/View/Map.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/View/Map.ml')
-rw-r--r--src/View/Map.ml109
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