toggle achievements

This commit is contained in:
2023-06-11 15:50:59 +02:00
parent fb1b863746
commit e12d616436
8 changed files with 972 additions and 21 deletions

View File

@@ -1 +1,60 @@
use common::Achievement;
use common::ToggleAchievement;
use reqwasm::http::Request;
use wasm_bindgen_futures::spawn_local;
use yew::function_component;
use yew::html;
use yew::Callback;
use yew::Html;
use yew::Properties;
#[derive(Properties, PartialEq)]
pub struct Props {
pub achievement: Achievement,
}
#[function_component]
pub fn AchievementComponent(props: &Props) -> Html {
let Achievement {
goal,
completed,
uuid,
} = &props.achievement;
let uuid = *uuid;
let onclick = Callback::from(move |_| {
log::info!("button click, toggling achievement");
let payload = ToggleAchievement { uuid };
let payload = serde_json::to_string(&payload).unwrap();
spawn_local(async move {
let req = Request::post("http://127.0.0.1:4000/toggle")
.header("Content-Type", "application/json")
.body(payload);
let res = req.send().await;
match res {
Ok(response) => {
dbg!(response);
}
Err(err) => {
log::error!("Request failed: {err:?}");
}
}
});
});
let button_class = if *completed { "button-primary" } else { "button" };
html! {
<div class="row">
<div class="nine columns">
<p>{goal}</p>
</div>
<div class="three columns">
<button {onclick} class={button_class}>{""}</button>
</div>
</div>
}
}

View File

@@ -1,19 +1,17 @@
use crate::components::achievement::AchievementComponent;
use crate::event_bus::EventBus;
use crate::services::websocket::WebsocketService;
use crate::AppState;
use crate::Route;
use common::Achievement;
use std::rc::Rc;
use yew::functional::*;
use yew::prelude::*;
use yew_agent::Bridge;
use yew_agent::Bridged;
use yew_router::prelude::*;
pub struct Root {
wss: WebsocketService,
_producer: Box<dyn Bridge<EventBus>>,
achievements: Vec<Achievement>,
/// None until the first websocket message is received.
state: Option<common::State>,
}
pub enum Msg {
@@ -22,15 +20,9 @@ pub enum Msg {
impl Component for Root {
type Message = Msg;
type Properties = ();
fn create(ctx: &Context<Self>) -> Self {
// let ctx_link = ctx
// .link()
// .context::<AppState>(Callback::noop())
// .expect("context to be set");
let wss = WebsocketService::new();
let cb = {
@@ -41,7 +33,7 @@ impl Component for Root {
Self {
wss,
_producer: EventBus::bridge(Rc::new(cb)),
achievements: vec![],
state: None,
}
}
@@ -49,26 +41,39 @@ impl Component for Root {
match msg {
Msg::HandleMsg(s) => {
let msg: common::WebSocketMessage = serde_json::from_str(&s).unwrap();
self.achievements = msg.achievements;
self.state = Some(msg);
true
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let achievements = self
let Some(state) = &self.state else {
return html! {
<p>{"loading..."}</p>
};
};
let achievements = state
.achievements
.iter()
.cloned()
.map(|a| {
html! {
<p>{format!("{}", a.goal)}</p>
<AchievementComponent achievement={a} />
}
})
.collect::<Html>();
html! {
<div>
{achievements}
<div class="container">
<div class="row">
<div class="twelve columns" style="margin-top: 25%">
<h4>{"Achievements"}</h4>
</div>
</div>
{achievements}
</div>
}
}