use futuresdr_pmt::Pmt;
use reqwasm::http::Request;
use std::rc::Rc;
use yew::prelude::*;
#[derive(Clone, Properties, PartialEq)]
pub struct RadioItemProps {
pub value: Pmt,
#[prop_or(false)]
pub checked: bool,
}
#[derive(Clone)]
pub struct RadioItem;
impl Component for RadioItem {
type Message = ();
type Properties = RadioItemProps;
fn create(_ctx: &Context<Self>) -> Self {
Self
}
fn view(&self, ctx: &Context<Self>) -> Html {
let parent = ctx.link().get_parent().unwrap().clone();
let radio = parent.downcast::<Radio>();
let p = ctx.props().value.clone();
let onclick = radio.callback(move |_| Msg::Value(p.clone()));
html! {
<>
<input type="radio" {onclick} checked={ctx.props().checked}/>
<label>{format!("{:?}", &ctx.props().value)}</label>
</>
}
}
}
#[derive(Clone, Properties, PartialEq)]
pub struct Props {
pub children: ChildrenWithProps<RadioItem>,
pub url: String,
pub block: u64,
pub callback: u64,
}
pub struct Radio {
value: Pmt,
status: String,
}
pub enum Msg {
Submit,
Value(Pmt),
Reply(String),
Error,
}
impl Radio {
fn endpoint(props: &Props) -> String {
format!(
"{}/api/block/{}/call/{}",
props.url, props.block, props.callback
)
}
fn callback(ctx: &Context<Self>, p: &Pmt) {
let p = p.clone();
let endpoint = Self::endpoint(ctx.props());
gloo_console::log!(format!("radio: sending request {:?}", &p));
ctx.link().send_future(async move {
let response = Request::post(&endpoint)
.header("Content-Type", "application/json")
.body(serde_json::to_string(&p).unwrap())
.send()
.await;
if let Ok(response) = response {
if response.ok() {
return Msg::Reply(response.text().await.unwrap());
}
}
Msg::Error
});
}
}
impl Component for Radio {
type Message = Msg;
type Properties = Props;
fn create(_ctx: &Context<Self>) -> Self {
Self {
status: "Init".to_string(),
value: Pmt::Null,
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Submit => {
self.status = "Fetching".to_string();
Self::callback(ctx, &self.value);
}
Msg::Value(p) => {
self.value = p;
}
Msg::Error => {
self.status = "Error".to_string();
}
Msg::Reply(v) => {
self.status = v;
}
};
true
}
fn view(&self, ctx: &Context<Self>) -> Html {
let onclick = ctx.link().callback(|_| Msg::Submit);
html! {
<>
{
for ctx.props().children.iter().map(|mut item| {
let mut props = Rc::make_mut(&mut item.props);
if props.value == self.value {
props.checked = true;
} else {
props.checked = false;
}
item
})
}
<button type="submit" {onclick}>{"Submit"}</button>
<div>{&self.status}</div>
</>
}
}
}