Skip to content

Commit

Permalink
Merge pull request #22 from ciza99/game-interactions
Browse files Browse the repository at this point in the history
added player, die and pawn components
  • Loading branch information
ciza99 authored Jan 30, 2022
2 parents 497e8ea + 594f845 commit 65727b7
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 59 deletions.
58 changes: 58 additions & 0 deletions client/src/components/die/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use yew::prelude::*;

use gloo::timers::callback::Timeout;
use crate::components::icon::Icon;

#[derive(Properties, PartialEq, Clone)]
pub struct DieProps {
pub number: u32,
}

const SPIN_TIME: u32 = 1000;

#[function_component(Die)]
pub fn die(props: &DieProps) -> Html {
let DieProps {number: prop_number} = props.clone();
let number = use_state(|| prop_number);
let spinning = use_state(|| false);
let is_mount = use_mut_ref(|| true);

{
let spinning = spinning.clone();
let number = number.clone();
use_effect_with_deps::<_, Box<dyn FnOnce() -> ()>, _>(move |_| {
if *is_mount.borrow() {
*is_mount.borrow_mut() = false;
return Box::new(|| {});
};

spinning.set(true);

let number_change_timeout = Timeout::new(SPIN_TIME / 2, move || {
number.set(prop_number);
});

let spin_timeout = Timeout::new(SPIN_TIME, move || {
spinning.set(false);
});

Box::new(move || {
drop(number_change_timeout);
drop(spin_timeout);
})
}, [prop_number]);
}

let classes: String = match *number {
1 => "fa-dice-one".into(),
2 => "fa-dice-two".into(),
3 => "fa-dice-three".into(),
4 => "fa-dice-four".into(),
5 => "fa-dice-five".into(),
_ => "fa-dice-six".into(),
};

html! {
<Icon class={classes!(String::from("fas text-4xl text-neutral-600"), classes, spinning.then(|| "animate-spin"))} />
}
}
11 changes: 3 additions & 8 deletions client/src/components/field/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use yew::prelude::*;

use crate::utils::resolve_color_class;
use crate::utils::{resolve_bg_color_class, resolve_text_color_class};
use crate::models::color::Color;

#[derive(Properties, PartialEq, Clone)]
Expand All @@ -17,17 +17,12 @@ pub fn field(props: &FieldProps) -> Html {
let FieldProps {children, color, color_background} = props.clone();

let bg_class = if color_background {
resolve_color_class(&color)
resolve_bg_color_class(&color)
} else {
"".into()
};

let text_class: String = match color {
Color::Red => "text-red-400".into(),
Color::Green => "text-green-400".into(),
Color::Blue => "text-blue-400".into(),
Color::Yellow => "text-yellow-400".into(),
};
let text_class = resolve_text_color_class(&color);

html! {
<div class={classes!(String::from("border border-neutral-300 shadow-inner grid place-items-center"), bg_class, text_class)}>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub fn fields(props: &FieldsProps) -> Html {
>
{
if *position == 6 {
html! { <Icon class={arrow_class.clone()} /> }
html! { <Icon class={classes!(arrow_class.clone())} /> }
} else {
html! { format!("{}", position) }
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/icon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use yew::prelude::*;

#[derive(Properties, PartialEq, Clone)]
pub struct IconProps {
pub class: String,
pub class: Classes,
}

#[function_component(Icon)]
pub fn icon(props: &IconProps) -> Html {
let IconProps { class } = props;
let IconProps { class } = props.clone();

html! {
<span class={class} />
<span class={classes!(class)} />
}
}
2 changes: 2 additions & 0 deletions client/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ pub mod pawn;
pub mod fields;
pub mod field;
pub mod board_middle;
pub mod player;
pub mod die;
17 changes: 11 additions & 6 deletions client/src/components/pawn/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
use yew::prelude::*;
use stylist::css;

use crate::{models::color::Color, utils::resolve_color_class};
use crate::{models::color::Color, utils::resolve_text_color_class};
use crate::components::icon::Icon;

#[derive(Properties, PartialEq, Clone)]
pub struct PawnProps {
pub color: Color,
#[prop_or_default]
pub onclick: Option<Callback<MouseEvent>>,
}

#[function_component(Pawn)]
pub fn pawn(props: &PawnProps) -> Html {
let PawnProps {color} = props.clone();
let PawnProps {color, onclick} = props.clone();

let color_class = resolve_color_class(&color);
let text_class = resolve_text_color_class(&color);
let hover_anim: Option<String> = onclick.is_some().then(|| "hover:scale-110".into());

html! {
<div class="p-2 w-full h-full">
<div class={classes!(String::from("rounded-full w-full h-full shadow-md"), color_class)}></div>
</div>
<button {onclick} class={classes!(onclick.is_none().then(|| "cursor-default"))}>
<Icon class={classes!(String::from("fas text-xl sm:text-3xl md:text-4xl w-min fa-chess-pawn drop-shadow-md hue-rotate-15 saturate-50"), text_class, hover_anim, css!("text-shadow: 2px 2px 2px gray;"))} />
</button>
}
}
71 changes: 71 additions & 0 deletions client/src/components/player/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use gloo::timers::callback::Interval;
use yew::prelude::*;

use crate::components::card::Card;
use crate::components::button::Button;
use crate::components::icon::Icon;
use crate::components::die::Die;

#[derive(PartialEq, Clone)]
pub enum PlayerButtonPosition {
Top,
Bottom,
}

#[derive(Properties, PartialEq, Clone)]
pub struct PlayerProps {
pub name: String,
#[prop_or(PlayerButtonPosition::Top)]
pub position: PlayerButtonPosition,
#[prop_or_default]
pub on_roll: Option<Callback<MouseEvent>>,
}

#[function_component(Player)]
pub fn player(props: &PlayerProps) -> Html {
let PlayerProps {name, position, on_roll} = props.clone();
let die_number = use_state::<u32, _>(|| 1);

let icon = html! { <Icon class="fas fa-sync-alt" /> };

let button = if let Some(on_roll) = on_roll {
html! { <Button {icon} onclick={on_roll.clone()}>{"Roll the die"}</Button> }
} else {
html! {}
};

{
let die_number = die_number.clone();
use_effect(move || {
let interval = Interval::new(10000, move || {
die_number.set(*die_number + 1);
});

|| {
drop(interval);
}
});
}

html! {
<div class="flex flex-col gap-4">
{
if position == PlayerButtonPosition::Top {
button.clone()
} else { html! {} }
}
<Card>
<div class="flex justify-between items-center p-4">
<span class="text-lg font-semibold text-neutral-700">{ name }</span>
<Die number={*die_number} />
</div>
// TODO: add timeline
</Card>
{
if position == PlayerButtonPosition::Bottom {
button.clone()
} else { html! {} }
}
</div>
}
}
11 changes: 7 additions & 4 deletions client/src/components/player_corner/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use yew::prelude::*;
use stylist::{style, Style};

use crate::models::color::Color;
use crate::components::pawn::Pawn;
use crate::utils::{clamp, resolve_color_class};
use crate::utils::{clamp, resolve_bg_color_class};

#[derive(Properties, PartialEq, Clone)]
pub struct PlayerCornerProps {
Expand All @@ -17,13 +16,17 @@ pub fn player_corner(props: &PlayerCornerProps) -> Html {

let pawn_count = clamp(pawn_count, 0, 4);

let color_class = resolve_color_class(&color);
let color_class = resolve_bg_color_class(&color);

html! {
<div class={classes!(String::from("h-full w-full grid place-items-center drop-shadow-lg"), color_class)}>
<div class="w-1/2 h-1/2 rounded-full bg-neutral-100 grid grid-cols-2 grid-rows-2 p-4 drop-shadow-lg border border-neutral-300">
{
(0..pawn_count).map(|index| html! {<Pawn key={index} color={color.clone()}/>}).collect::<Vec<Html>>()
(0..pawn_count).map(|index| html! {
<div class="grid place-items-center h-full w-full">
<Pawn key={index} color={color.clone()}/>
</div>
}).collect::<Vec<Html>>()
}
</div>
</div>
Expand Down
Loading

0 comments on commit 65727b7

Please sign in to comment.