use dioxus::{
hooks::{use_resource, use_signal},
prelude::{Props, component, dioxus_elements, rsx},
signals::ReadableExt as _,
};
use dioxus_core::Element;
use oparl_types::{BodyListUrl, SystemUrl};
use crate::{components::BodyList, route::UrlEncoded};
#[derive(Debug, Clone, PartialEq, Props)]
pub struct OParlSystemProps {
system_url: UrlEncoded<SystemUrl>,
}
async fn get_system(system_url: &SystemUrl) -> Result<oparl_types::System, String> {
let response = reqwest::get(format!("{system_url}"))
.await
.map_err(|e| format!("{e}"))?;
response
.json::<oparl_types::System>()
.await
.map_err(|e| format!("{e}"))
}
async fn get_bodies(
body_list_url: &BodyListUrl,
) -> Result<oparl_types::DataListPage<oparl_types::Body>, String> {
let response = reqwest::get(format!("{body_list_url}"))
.await
.map_err(|e| format!("{e}"))?;
response
.json::<oparl_types::DataListPage<oparl_types::Body>>()
.await
.map_err(|e| format!("{e}"))
}
#[derive(Debug, Clone, PartialEq)]
struct OParlSystemData {
system: oparl_types::System,
bodies: Vec<oparl_types::Body>,
}
impl OParlSystemData {
async fn get(system_url: &SystemUrl) -> Result<Self, String> {
let system = get_system(system_url).await?;
let bodies = get_bodies(&system.body).await?;
Ok(Self {
system,
bodies: bodies.data,
})
}
}
#[component]
pub fn OParlSystem(props: OParlSystemProps) -> Element {
let system_url = use_signal(|| props.system_url.get_inner().unwrap().clone());
let data = { use_resource(move || async move { OParlSystemData::get(&system_url()).await }) };
rsx! {
"OParl System URL: {system_url}"
match &*data.read_unchecked() {
Some(Ok(data)) => {
let system_name = data.system.name.clone().unwrap_or("Unknown system".into());
rsx! {
dioxus::document::Title { "{system_name}" }
h1 {
"{system_name}"
}
BodyList {
bodies: data.bodies.clone(),
}
}
},
Some(Err(e)) => rsx! {
dioxus::document::Title { "Loading failed." },
p { "Loading system failed, {e}" }
},
None => rsx! {
dioxus::document::Title { "Loading…" },
p { "Loading..." }
}
}
}
}