use crate::{LatLng, MapOptions, MapPosition, interop, types::Id};
use dioxus::{core::{use_drop, spawn_forever}, prelude::*};
use std::rc::Rc;
const MAP_CSS: Asset = asset!("/assets/dioxus_leaflet.scss");
#[component]
pub fn Map(
#[props(default = MapPosition::default())]
initial_position: MapPosition,
#[props(into)]
height: Option<String>,
#[props(into)]
width: Option<String>,
options: Option<MapOptions>,
#[props(into)]
class: Option<String>,
#[props(into)]
style: Option<String>,
on_click: Option<EventHandler<LatLng>>,
on_move: Option<EventHandler<MapPosition>>,
children: Element,
) -> Element {
let id = use_context_provider(|| Rc::new(Id::map(dioxus_core::current_scope_id().0)));
let options = options.unwrap_or(MapOptions::default());
let leaflet_css = options.leaflet_resources.css_url();
let leaflet_js = options.leaflet_resources.js_url();
let id2 = id.clone();
let load_error = use_resource(move || {
let id = id2.clone();
let pos = initial_position.clone();
let opts = options.clone();
async move {
interop::update_map(&id, &pos, &opts).await.map_err(|e| e.to_string())
}
});
let id2 = id.clone();
let _click_handle = use_resource(move || {
let id = id2.clone();
async move {
if let Some(on_click) = on_click {
interop::on_map_click(&id, on_click).await
}
else {
Ok(())
}
}
});
let id2 = id.clone();
let _move_handle = use_resource(move || {
let id = id2.clone();
async move {
if let Some(on_move) = on_move {
interop::on_map_move(&id, on_move).await
}
else {
Ok(())
}
}
});
let id2 = id.clone();
use_drop(move || {
let id = id2.clone();
spawn_forever(async move {
_ = interop::delete_map(&id).await;
});
});
rsx! {
document::Style { href: leaflet_css }
document::Style { href: MAP_CSS }
document::Script { src: leaflet_js }
document::Script { src: interop::DL_JS }
if let Some(Err(err)) = load_error() {
p {
"{err}"
}
}
else {
div {
class: "dioxus-leaflet-container {class.as_ref().map(|c| c.as_str()).unwrap_or(\"\")}",
div {
id: "dioxus-leaflet-{id}",
class: "dioxus-leaflet-map",
{children}
}
}
}
}
}