Remove NodeRef for getter, improve turn indicator

All NodeRefs have been removed in favor of "getElementById".

Turn indicator is now much more obvious to see.
This commit is contained in:
Stephen Seo 2022-03-03 17:36:51 +09:00
parent 52b841d98a
commit 462dec9ea1
4 changed files with 52 additions and 22 deletions

View file

@ -9,4 +9,4 @@ edition = "2021"
yew = "0.19"
log = "0.4.6"
wasm-logger = "0.2.0"
web-sys = { version = "0.3.56", features = ["HtmlDivElement", "HtmlButtonElement"] }
web-sys = { version = "0.3.56", features = ["Window", "Document", "Element"] }

View file

@ -15,8 +15,8 @@
grid-row: 9;
grid-column: 1 / 8;
}
div.info_text_side_wrapper {
grid-row: 1 / 9;
div.info_text_turn_wrapper {
grid-row: 1;
grid-column: 8;
}
div.info_text0 {
@ -30,15 +30,21 @@
flex-direction: column-reverse;
}
div.info_text1 {
background-color: #DDD;
background-color: #333;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
overflow-y: hidden;
word-wrap: break-word;
display: flex;
flex-direction: column-reverse;
}
b.cyan {
color: #0FF;
}
b.magenta {
color: #F0F;
}
button.slot {
width: 50px;
height: 50px;

View file

@ -1,7 +1,6 @@
use std::cell::Cell;
use std::fmt::Display;
use std::rc::Rc;
use yew::prelude::*;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum BoardState {
@ -41,11 +40,19 @@ impl Display for Turn {
}
}
impl Turn {
pub fn get_color(&self) -> &str {
match *self {
Turn::CyanPlayer => "cyan",
Turn::MagentaPlayer => "magenta",
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct SharedState {
pub board: [Rc<Cell<BoardState>>; 56],
pub turn: Rc<Cell<Turn>>,
pub info_text_ref: [NodeRef; 2],
}
impl Default for SharedState {
@ -111,8 +118,6 @@ impl Default for SharedState {
Rc::new(Cell::new(BoardState::default())),
],
turn: Rc::new(Cell::new(Turn::CyanPlayer)),
// NodeRef array needs to have unique values
info_text_ref: [NodeRef::default(), NodeRef::default()],
}
}
}

View file

@ -133,7 +133,7 @@ impl Component for Wrapper {
<div class="info_text_wrapper">
<InfoText id=0 />
</div>
<div class="info_text_side_wrapper">
<div class="info_text_turn_wrapper">
<InfoText id=1 />
</div>
</div> // wrapper
@ -197,7 +197,7 @@ impl Component for Wrapper {
//log::info!("{}", &output_str);
// info text below the grid
if let Some(info_text) = shared.info_text_ref[0].cast::<web_sys::HtmlDivElement>() {
if let Some(info_text) = document.get_element_by_id("info_text0") {
let height = info_text.client_height();
// create the new text to be appended in the output
@ -249,14 +249,19 @@ impl Component for Wrapper {
}
// info text right of the grid
if let Some(info_text) = shared.info_text_ref[1].cast::<web_sys::HtmlDivElement>() {
if let Some(info_text) = document.get_element_by_id("info_text1") {
let height = info_text.client_height();
// create the new text to be appended in the output
let p = document
.create_element("p")
.expect("document should be able to create <p>");
p.set_text_content(Some(&format!("It is {}'s turn", shared.turn.get())));
let turn = shared.turn.get();
p.set_inner_html(&format!(
"<b class=\"{}\">It is {}'s turn</b>",
turn.get_color(),
turn
));
// check if scrolled to top
let at_top: bool = info_text.scroll_top() <= height - info_text.scroll_height();
@ -265,7 +270,7 @@ impl Component for Wrapper {
info_text
.append_with_node_1(&p)
.expect("should be able to append to info_text");
while info_text.child_element_count() > INFO_TEXT_MAX_ITEMS {
while info_text.child_element_count() > 1 {
info_text
.remove_child(&info_text.first_child().unwrap())
.expect("should be able to limit items in info_text");
@ -302,14 +307,28 @@ impl Component for InfoText {
}
fn view(&self, ctx: &Context<Self>) -> Html {
let (shared, _) = ctx
.link()
.context::<SharedState>(Callback::noop())
.expect("state to be set");
html! {
<div ref={shared.info_text_ref[ctx.props().id].clone()} class={format!("info_text{}", ctx.props().id)}>
{ if ctx.props().id == 1 { "It is CyanPlayer's turn" } else { "Hello" } }
</div>
match ctx.props().id {
0 => {
html! {
<div id={format!("info_text{}", ctx.props().id)} class={format!("info_text{}", ctx.props().id)}>
{"Hello"}
</div>
}
}
1 => {
html! {
<div id={format!("info_text{}", ctx.props().id)} class={format!("info_text{}", ctx.props().id)}>
<p>
<b class={"cyan"}>
{"It is CyanPlayer's turn"}
</b>
</p>
</div>
}
}
_ => {
unreachable!();
}
}
}
}