#![recursion_limit="1024"]
mod ws;
mod coapws;
mod binentry;
mod message_editor;
mod messageexchanger;
mod colorserver;
mod colorpicker;
mod blebridge;
mod about;
mod coapwsmessage;
mod util;
use wasm_bindgen::prelude::*;
use yew::prelude::*;
use yew_router::{prelude::*, Switch};
#[derive(Clone)]
struct FragmentOnlyRoute<I: Switch> {
pub inner: I,
}
impl<I: Switch> Switch for FragmentOnlyRoute<I> {
fn from_route_part<STATE>(part: String, state: Option<STATE>) -> (Option<Self>, Option<STATE>) {
let part = match part.find('#') {
Some(i) => &part[i..],
None => "",
}.to_string();
let (slef, outstate) = I::from_route_part(part, state);
(slef.map(|s| s.into()), outstate)
}
fn build_route_section<STATE>(self, route: &mut String) -> Option<STATE> {
self.inner.build_route_section(route)
}
}
impl<I: Switch> From<I> for FragmentOnlyRoute<I> {
fn from(inner: I) -> Self {
Self { inner }
}
}
struct Tabbing {
link: ComponentLink<Self>,
router: Box<dyn Bridge<RouteAgent>>,
}
impl Component for Tabbing {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
let callback = link.callback(|_| Msg::NoOp); let router = RouteAgent::bridge(callback);
Self { link, router }
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::ColorServerChange { ep, rd } => {
let route = Route::from(TabRoute::ColorServer { ep, rd });
self.router.send(yew_router::agent::RouteRequest::ChangeRoute(route));
}
Msg::NoOp => {}
}
false
}
fn change(&mut self, _: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
let colorserver_onchange = self.link.callback(|(ep, rd)| Msg::ColorServerChange { ep, rd });
html! { <>
<nav>
<ul>
<li><RouterAnchor<TabRoute> route=TabRoute::MessageExchanger>{ "Message exchanger" } </RouterAnchor<TabRoute>></li>
<li><RouterAnchor<TabRoute> route=TabRoute::ColorServer { ep: "-".to_string(), rd: "-".to_string()}> { "Color server" } </RouterAnchor<TabRoute>></li>
<li><RouterAnchor<TabRoute> route=TabRoute::ColorPicker> { "Color client" } </RouterAnchor<TabRoute>></li>
<li><RouterAnchor<TabRoute> route=TabRoute::BleBridge> { "BLE (GATT) bridge" } </RouterAnchor<TabRoute>></li>
<li><RouterAnchor<TabRoute> route=TabRoute::About> { "About Verdigris" } </RouterAnchor<TabRoute>></li>
</ul>
</nav>
<Router<FragmentOnlyRoute<TabRoute>>
render=Router::render(move |switch: FragmentOnlyRoute<TabRoute>| {
match switch.inner {
TabRoute::MessageExchanger => html! { <messageexchanger::CoAPWSMessageExchanger /> },
TabRoute::ColorServer { ep, rd } => html! {
<colorserver::ColorServer
ep=match ep.as_str() { "-" => None, x => Some(ep) }
rd=match rd.as_str() { "-" => None, x => Some(rd) }
onchange=&colorserver_onchange
/>
},
TabRoute::ColorPicker => html! { <colorpicker::ColorPicker /> },
TabRoute::BleBridge => html! { <blebridge::BleBridge /> },
TabRoute::About => html! { <about::About /> },
}})
redirect=Router::redirect(|route: Route| FragmentOnlyRoute::from(TabRoute::About))
/>
</> }
}
}
pub enum Msg {
ColorServerChange { ep: String, rd: String },
NoOp,
}
#[derive(Debug, Clone, Switch)]
pub enum TabRoute {
#[to = "#msgex"]
MessageExchanger,
#[to = "#colserv:{ep}:{*:rd}"]
ColorServer { ep: String, rd: String },
#[to = "#colcli"]
ColorPicker,
#[to = "#ble"]
BleBridge,
#[to = "#about"]
About,
}
#[wasm_bindgen(start)]
pub fn run_app() {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
console_log::init_with_level(log::Level::Debug)
.expect("Console not available for logging");
App::<Tabbing>::new().mount_to_body();
}