diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-09-06 22:07:28 -0400 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-09-06 22:07:28 -0400 |
commit | cab440c8a209ae92eba07d50f7b7127dadbd65c0 (patch) | |
tree | 95ad002ad00b6ae99baeb410cc23195286cf5d45 /webapp | |
parent | 77ed77bfa3480a06a3f36b072af5eb8712a1515c (diff) |
Move components to a separate module
Diffstat (limited to 'webapp')
-rw-r--r-- | webapp/src/components.rs | 27 | ||||
-rw-r--r-- | webapp/src/components/bidding_box.rs | 37 | ||||
-rw-r--r-- | webapp/src/components/bidding_table.rs | 48 | ||||
-rw-r--r-- | webapp/src/components/card.rs | 26 | ||||
-rw-r--r-- | webapp/src/components/hand.rs | 38 | ||||
-rw-r--r-- | webapp/src/main.rs | 164 |
6 files changed, 180 insertions, 160 deletions
diff --git a/webapp/src/components.rs b/webapp/src/components.rs new file mode 100644 index 0000000..fed31b0 --- /dev/null +++ b/webapp/src/components.rs @@ -0,0 +1,27 @@ +use crate::card::Suit; + +mod card; +mod hand; +mod bidding_table; +mod bidding_box; + +pub use self::card::*; +pub use self::bidding_box::*; +pub use self::bidding_table::*; +pub use self::hand::*; + +pub fn suit_css_class(suit: Suit) -> &'static str { + match suit { + Suit::Club => "suit-club", + Suit::Diamond => "suit-diamond", + Suit::Heart => "suit-heart", + Suit::Spade => "suit-spade", + } +} + +pub fn bid_css_class(suit: Option<Suit>) -> &'static str { + match suit { + None => "suit-notrump", + Some(x) => suit_css_class(x), + } +} diff --git a/webapp/src/components/bidding_box.rs b/webapp/src/components/bidding_box.rs new file mode 100644 index 0000000..38a543f --- /dev/null +++ b/webapp/src/components/bidding_box.rs @@ -0,0 +1,37 @@ +use yew::prelude::*; +use crate::bridge_engine::Raise; +use crate::components::bid_css_class; + +#[function_component(BiddingBox)] +pub fn bidding_box(props: &BiddingBoxProps) -> Html { + let bids: Html = Raise::all_raises() + .iter() + .map(|bid| { + let mut class = if Some(*bid) <= props.current_bid { + classes!("disabled") + } else { + classes!("enabled") + }; + class.extend(classes!(bid_css_class(bid.suit))); + html! { + <div class={class}> + { bid.level } + </div> + } + }) + .collect(); + + html! { + <div class="bidding-box"> + { bids } + <div>{ "Pass" }</div> + <div>{ "X" }</div> + <div>{ "XX" }</div> + </div> + } +} + +#[derive(PartialEq, Properties, Clone)] +pub struct BiddingBoxProps { + pub current_bid: Option<Raise>, +} diff --git a/webapp/src/components/bidding_table.rs b/webapp/src/components/bidding_table.rs new file mode 100644 index 0000000..f4b692a --- /dev/null +++ b/webapp/src/components/bidding_table.rs @@ -0,0 +1,48 @@ +use yew::prelude::*; +use crate::bridge_engine::{Bid, Bidding, Player}; +use crate::components::bid_css_class; + +#[function_component(BiddingTable)] +pub fn bidding_table(props: &BiddingTableProps) -> Html { + let bid = |bid: &Bid| match bid.as_raise() { + None => html!{ <div class="bid">{ bid }</div> }, + Some(raise) => html!{ + <div class="bid"> + { raise.level } + <div class={ bid_css_class(raise.suit) }/> + </div> + }, + }; + let bids: Html = props + .bidding + .bids + .iter() + .map(|b| { bid(b) }) + .collect(); + let padding : Html = padding(props.bidding.dealer); + html! { + <div class="bidding-table"> + <div class="header">{ "West" }</div> + <div class="header">{ "North" }</div> + <div class="header">{ "East" }</div> + <div class="header">{ "South" }</div> + { padding } + { bids } + </div> + } +} + +fn padding(dealer: Player) -> Html { + let mut padding : Vec<Html> = vec![]; + let mut player = Player::West; + while player != dealer { + padding.push(html! { <div/> }); + player = player.next(); + } + padding.into_iter().collect() +} + +#[derive(PartialEq, Properties, Clone)] +pub struct BiddingTableProps { + pub bidding: Bidding, +} diff --git a/webapp/src/components/card.rs b/webapp/src/components/card.rs new file mode 100644 index 0000000..6fbe7e7 --- /dev/null +++ b/webapp/src/components/card.rs @@ -0,0 +1,26 @@ +use yew::prelude::*; +use crate::card::{self, Suit, Rank}; +use crate::components::suit_css_class; + +#[function_component(Card)] +pub fn ccard(props: &CardProps) -> Html { + html! { + <div class="card"> + <div class={ suit_css_class(props.suit) }> + { props.rank } + </div> + </div> + } +} + +#[derive(PartialEq, Properties, Clone)] +pub struct CardProps { + pub suit: Suit, + pub rank: Rank, +} + +impl From<card::Card> for CardProps { + fn from(card::Card(suit, rank): card::Card) -> Self { + CardProps { suit, rank } + } +} diff --git a/webapp/src/components/hand.rs b/webapp/src/components/hand.rs new file mode 100644 index 0000000..1a2727c --- /dev/null +++ b/webapp/src/components/hand.rs @@ -0,0 +1,38 @@ +use yew::prelude::*; +use crate::components::card::{Card, CardProps}; + +#[function_component(Hand)] +pub fn hand(props: &HandProps) -> Html { + let cards: Html = props + .cards + .iter() + .map(|c| { + html! { + <Card ..c.clone() /> + } + }) + .collect(); + + html! { + <div class="hand"> + { cards } + </div> + } +} + +#[derive(Clone, Default, PartialEq, Properties)] +pub struct HandProps { + #[prop_or_default] + cards: Vec<CardProps>, +} + +impl<C: Into<CardProps>> FromIterator<C> for HandProps { + fn from_iter<Cards>(cards: Cards) -> Self + where + Cards: std::iter::IntoIterator<Item = C>, + { + HandProps { + cards: cards.into_iter().map(Into::into).collect(), + } + } +} diff --git a/webapp/src/main.rs b/webapp/src/main.rs index c99eeee..8f94899 100644 --- a/webapp/src/main.rs +++ b/webapp/src/main.rs @@ -1,14 +1,12 @@ -use crate::card::{Rank, Suit}; +use crate::card::Suit; #[allow(unused_imports)] use log::{debug, error, info, warn}; use yew::prelude::*; pub mod bridge_engine; pub mod card; -use bridge_engine::Bid; -use bridge_engine::Bidding; -use bridge_engine::BiddingResult; -use bridge_engine::Player; -use bridge_engine::Raise; +pub mod components; +use bridge_engine::{Player, BiddingResult}; +use components::{BiddingTable, BiddingBox, Hand, HandProps}; extern crate wee_alloc; // Use `wee_alloc` as the global allocator. @@ -73,160 +71,6 @@ pub fn app() -> Html { } } -#[function_component(Hand)] -pub fn hand(props: &HandProps) -> Html { - let cards: Html = props - .cards - .iter() - .map(|c| { - html! { - <Card ..c.clone() /> - } - }) - .collect(); - - html! { - <div class="hand"> - { cards } - </div> - } -} - -pub fn suit_css_class(suit: Suit) -> &'static str { - match suit { - Suit::Club => "suit-club", - Suit::Diamond => "suit-diamond", - Suit::Heart => "suit-heart", - Suit::Spade => "suit-spade", - } -} - -#[derive(Clone, Default, PartialEq, Properties)] -pub struct HandProps { - #[prop_or_default] - cards: Vec<CardProps>, -} - -impl<C: Into<CardProps>> FromIterator<C> for HandProps { - fn from_iter<Cards>(cards: Cards) -> Self - where - Cards: std::iter::IntoIterator<Item = C>, - { - HandProps { - cards: cards.into_iter().map(Into::into).collect(), - } - } -} - -#[function_component(Card)] -pub fn wcard(props: &CardProps) -> Html { - html! { - <div class="card"> - <div class={ suit_css_class(props.suit) }> - { props.rank } - </div> - </div> - } -} - -#[derive(PartialEq, Properties, Clone)] -pub struct CardProps { - suit: Suit, - rank: Rank, -} - -impl From<card::Card> for CardProps { - fn from(card::Card(suit, rank): card::Card) -> Self { - CardProps { suit, rank } - } -} - -pub fn bid_css_class(suit: Option<Suit>) -> &'static str { - match suit { - None => "suit-notrump", - Some(x) => suit_css_class(x), - } -} - -fn padding(dealer: Player) -> Html { - let mut padding : Vec<Html> = vec![]; - let mut player = Player::West; - while player != dealer { - padding.push(html! { <div/> }); - player = player.next(); - } - padding.into_iter().collect() -} - -#[function_component(BiddingTable)] -pub fn bidding_table(props: &BiddingTableProps) -> Html { - let bid = |bid: &Bid| match bid.as_raise() { - None => html!{ <div class="bid">{ bid }</div> }, - Some(raise) => html!{ - <div class="bid"> - { raise.level } - <div class={ bid_css_class(raise.suit) }/> - </div> - }, - }; - let bids: Html = props - .bidding - .bids - .iter() - .map(|b| { bid(b) }) - .collect(); - let padding : Html = padding(props.bidding.dealer); - html! { - <div class="bidding-table"> - <div class="header">{ "West" }</div> - <div class="header">{ "North" }</div> - <div class="header">{ "East" }</div> - <div class="header">{ "South" }</div> - { padding } - { bids } - </div> - } -} - -#[derive(PartialEq, Properties, Clone)] -pub struct BiddingTableProps { - bidding: Bidding, -} - -#[function_component(BiddingBox)] -pub fn bidding_box(props: &BiddingBoxProps) -> Html { - let bids: Html = Raise::all_raises() - .iter() - .map(|bid| { - let mut class = if Some(*bid) <= props.current_bid { - classes!("disabled") - } else { - classes!("enabled") - }; - class.extend(classes!(bid_css_class(bid.suit))); - html! { - <div class={class}> - { bid.level } - </div> - } - }) - .collect(); - - html! { - <div class="bidding-box"> - { bids } - <div>{ "Pass" }</div> - <div>{ "X" }</div> - <div>{ "XX" }</div> - </div> - } -} - -#[derive(PartialEq, Properties, Clone)] -pub struct BiddingBoxProps { - current_bid: Option<Raise>, -} - #[cfg(test)] mod tests { pub fn test_setup() { |