dioxus_leaflet/
interop.rs1use dioxus::prelude::*;
2use dioxus_use_js::{JsError, SerdeJsonValue};
3use std::error::Error;
4
5use crate::{LatLng, MapOptions, MapPosition, MarkerIcon, PathOptions, PopupOptions, types::Id};
6
7pub const DL_JS: Asset = asset!("/assets/dioxus_leaflet.js");
8
9mod js_api {
10 use dioxus::prelude::*;
11 use dioxus_use_js::use_js;
12
13 use_js!("js_utils/src/map.ts", "assets/dioxus_leaflet.js"::{update_map, delete_map, on_map_click, on_map_move});
14 use_js!("js_utils/src/marker.ts", "assets/dioxus_leaflet.js"::{update_marker, delete_marker});
15 use_js!("js_utils/src/polygon.ts", "assets/dioxus_leaflet.js"::{update_polygon, delete_polygon});
16 use_js!("js_utils/src/popup.ts", "assets/dioxus_leaflet.js"::{update_popup});
17}
18
19fn js_to_eval(err: JsError) -> Box<dyn Error + Send + Sync> {
20 match err {
21 JsError::Eval { error, .. } => error.into(),
22 JsError::Threw { func, .. } => Box::<dyn Error + Send + Sync>::from(func),
23 }
24}
25
26pub async fn update_map<'a>(
27 id: &Id,
28 initial_position: &MapPosition,
29 options: &MapOptions,
30) -> Result<(), Box<dyn Error + Send + Sync>> {
31 js_api::update_map(id, initial_position, options)
32 .await
33 .map_err(js_to_eval)
34}
35
36pub async fn delete_map<'a>(id: &Id) -> Result<(), Box<dyn Error + Send + Sync>> {
37 js_api::delete_map(id).await.map_err(js_to_eval)
38}
39
40pub async fn on_map_click(map_id: &Id, callback: EventHandler<LatLng>) -> Result<(), Box<dyn Error + Send + Sync>> {
41 let mapper_cb = Callback::new(move |coords: Vec<f64>| async move {
42 callback.call(LatLng::new(coords[0], coords[1]));
43 Result::<(), SerdeJsonValue>::Ok(())
44 });
45 js_api::on_map_click(map_id, mapper_cb).await.map_err(js_to_eval)
46}
47
48pub async fn on_map_move(map_id: &Id, callback: EventHandler<MapPosition>) -> Result<(), Box<dyn Error + Send + Sync>> {
49 let mapper_cb = Callback::new(move |data: Vec<f64>| async move {
50 let pos = MapPosition { coordinates: LatLng::new(data[0], data[1]), zoom: data[2] };
51 callback.call(pos);
52 Result::<(), SerdeJsonValue>::Ok(())
53 });
54 js_api::on_map_move(map_id, mapper_cb).await.map_err(js_to_eval)
55}
56
57pub async fn update_marker(
58 marker_id: &Id,
59 coordinate: &LatLng,
60 icon: &Option<MarkerIcon>,
61) -> Result<(), Box<dyn Error + Send + Sync>> {
62 js_api::update_marker(
63 marker_id.parent().unwrap(),
64 marker_id.id(),
65 coordinate,
66 icon,
67 )
68 .await
69 .map_err(js_to_eval)
70}
71
72pub async fn delete_marker(marker_id: &Id) -> Result<(), Box<dyn Error + Send + Sync>> {
73 js_api::delete_marker(marker_id.parent().unwrap(), marker_id.id())
74 .await
75 .map_err(js_to_eval)
76}
77
78pub async fn update_polygon(
79 polygon_id: &Id,
80 coordinates: &Vec<Vec<Vec<LatLng>>>,
81 options: &PathOptions,
82) -> Result<(), Box<dyn Error + Send + Sync>> {
83 js_api::update_polygon(
84 polygon_id.parent().unwrap(),
85 polygon_id.id(),
86 coordinates,
87 options,
88 )
89 .await
90 .map_err(js_to_eval)
91}
92
93pub async fn delete_polygon(polygon_id: &Id) -> Result<(), Box<dyn Error + Send + Sync>> {
94 js_api::delete_polygon(polygon_id.parent().unwrap(), polygon_id.id())
95 .await
96 .map_err(js_to_eval)
97}
98
99pub async fn update_popup(
100 popup_id: &Id,
101 options: &PopupOptions,
102) -> Result<(), Box<dyn Error + Send + Sync>> {
103 let marker_id = popup_id.parent().unwrap();
104 js_api::update_popup(marker_id, popup_id, options)
105 .await
106 .map_err(js_to_eval)
107}