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" yew = "0.19"
log = "0.4.6" log = "0.4.6"
wasm-logger = "0.2.0" 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-row: 9;
grid-column: 1 / 8; grid-column: 1 / 8;
} }
div.info_text_side_wrapper { div.info_text_turn_wrapper {
grid-row: 1 / 9; grid-row: 1;
grid-column: 8; grid-column: 8;
} }
div.info_text0 { div.info_text0 {
@ -30,15 +30,21 @@
flex-direction: column-reverse; flex-direction: column-reverse;
} }
div.info_text1 { div.info_text1 {
background-color: #DDD; background-color: #333;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: hidden;
word-wrap: break-word; word-wrap: break-word;
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
} }
b.cyan {
color: #0FF;
}
b.magenta {
color: #F0F;
}
button.slot { button.slot {
width: 50px; width: 50px;
height: 50px; height: 50px;

View file

@ -1,7 +1,6 @@
use std::cell::Cell; use std::cell::Cell;
use std::fmt::Display; use std::fmt::Display;
use std::rc::Rc; use std::rc::Rc;
use yew::prelude::*;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum BoardState { 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)] #[derive(Clone, Debug, PartialEq)]
pub struct SharedState { pub struct SharedState {
pub board: [Rc<Cell<BoardState>>; 56], pub board: [Rc<Cell<BoardState>>; 56],
pub turn: Rc<Cell<Turn>>, pub turn: Rc<Cell<Turn>>,
pub info_text_ref: [NodeRef; 2],
} }
impl Default for SharedState { impl Default for SharedState {
@ -111,8 +118,6 @@ impl Default for SharedState {
Rc::new(Cell::new(BoardState::default())), Rc::new(Cell::new(BoardState::default())),
], ],
turn: Rc::new(Cell::new(Turn::CyanPlayer)), 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"> <div class="info_text_wrapper">
<InfoText id=0 /> <InfoText id=0 />
</div> </div>
<div class="info_text_side_wrapper"> <div class="info_text_turn_wrapper">
<InfoText id=1 /> <InfoText id=1 />
</div> </div>
</div> // wrapper </div> // wrapper
@ -197,7 +197,7 @@ impl Component for Wrapper {
//log::info!("{}", &output_str); //log::info!("{}", &output_str);
// info text below the grid // 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(); let height = info_text.client_height();
// create the new text to be appended in the output // create the new text to be appended in the output
@ -249,14 +249,19 @@ impl Component for Wrapper {
} }
// info text right of the grid // 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(); let height = info_text.client_height();
// create the new text to be appended in the output // create the new text to be appended in the output
let p = document let p = document
.create_element("p") .create_element("p")
.expect("document should be able to create <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 // check if scrolled to top
let at_top: bool = info_text.scroll_top() <= height - info_text.scroll_height(); let at_top: bool = info_text.scroll_top() <= height - info_text.scroll_height();
@ -265,7 +270,7 @@ impl Component for Wrapper {
info_text info_text
.append_with_node_1(&p) .append_with_node_1(&p)
.expect("should be able to append to info_text"); .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 info_text
.remove_child(&info_text.first_child().unwrap()) .remove_child(&info_text.first_child().unwrap())
.expect("should be able to limit items in info_text"); .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 { fn view(&self, ctx: &Context<Self>) -> Html {
let (shared, _) = ctx match ctx.props().id {
.link() 0 => {
.context::<SharedState>(Callback::noop())
.expect("state to be set");
html! { html! {
<div ref={shared.info_text_ref[ctx.props().id].clone()} class={format!("info_text{}", ctx.props().id)}> <div id={format!("info_text{}", ctx.props().id)} class={format!("info_text{}", ctx.props().id)}>
{ if ctx.props().id == 1 { "It is CyanPlayer's turn" } else { "Hello" } } {"Hello"}
</div> </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!();
}
}
}
} }