client: Create stopwatch frontend
Create the frontend for the stopwatch which does not yet communicate with the server.
This commit is contained in:
parent
0d0f26d6c0
commit
b12b8765a9
3 changed files with 99 additions and 8 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -247,6 +247,8 @@ name = "client"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"gloo-timers",
|
||||
"instant",
|
||||
"log",
|
||||
"wasm-logger",
|
||||
"yew",
|
||||
|
@ -550,6 +552,18 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.4.1"
|
||||
|
|
|
@ -14,3 +14,5 @@ yew = "0.19"
|
|||
console_error_panic_hook = "0.1"
|
||||
log = "0.4"
|
||||
wasm-logger = "0.2"
|
||||
gloo-timers = "0.2"
|
||||
instant = { version = "0.1", features = [ "wasm-bindgen" ] }
|
||||
|
|
|
@ -1,13 +1,88 @@
|
|||
use gloo_timers::callback::Interval;
|
||||
use instant::Instant;
|
||||
use yew::prelude::*;
|
||||
|
||||
#[function_component(LockWatch)]
|
||||
fn lock_watch() -> Html {
|
||||
html! {
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{ "LockWatch" }</h1>
|
||||
</div>
|
||||
</section>
|
||||
enum Msg {
|
||||
Start,
|
||||
Stop,
|
||||
UpdateDuration,
|
||||
}
|
||||
|
||||
struct LockWatch {
|
||||
duration: Option<Instant>,
|
||||
duration_handle: Option<Interval>,
|
||||
}
|
||||
|
||||
impl LockWatch {
|
||||
fn get_duration(&self) -> String {
|
||||
self.duration.map_or_else(
|
||||
|| "00:00:00.000".to_string(),
|
||||
|instant| {
|
||||
let elapsed = instant.elapsed();
|
||||
|
||||
format!(
|
||||
"{:02}:{:02}:{:02}.{:03}",
|
||||
elapsed.as_secs() / 60 / 60,
|
||||
(elapsed.as_secs() / 60) % 60,
|
||||
elapsed.as_secs() % 60,
|
||||
elapsed.as_millis() % 1_000
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for LockWatch {
|
||||
type Message = Msg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_ctx: &Context<Self>) -> Self {
|
||||
Self {
|
||||
duration: None,
|
||||
duration_handle: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
||||
match msg {
|
||||
Msg::Start => {
|
||||
self.duration = Some(Instant::now());
|
||||
self.duration_handle = {
|
||||
let link = ctx.link().clone();
|
||||
Some(Interval::new(1, move || {
|
||||
link.send_message(Msg::UpdateDuration);
|
||||
}))
|
||||
};
|
||||
}
|
||||
Msg::Stop => self.duration_handle = None,
|
||||
Msg::UpdateDuration => {}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
html! {
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{ "LockWatch" }</h1>
|
||||
<div class="block is-size-1">
|
||||
{ &self.get_duration() }
|
||||
</div>
|
||||
<div class="block">
|
||||
if self.duration_handle.is_some() {
|
||||
<button class="button is-danger" onclick={ctx.link().callback(|_| Msg::Stop)}>{ "Stop" }</button>
|
||||
} else {
|
||||
if self.duration.is_some() {
|
||||
<button class="button" disabled=true>{ "Start" }</button>
|
||||
} else {
|
||||
<button class="button is-primary" onclick={ctx.link().callback(|_| Msg::Start)}>{ "Start" }</button>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue