1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
use std::future::Future;
use std::pin::Pin;
use crate::components::{BiddingBox, BiddingTable, Hand};
use crate::use_app_context;
use crate::utils::ok_json;
use anyhow::Context;
use gloo_net::http::Request;
use log::info;
use protocol::bridge_engine::{
Bid, BiddingState, BiddingStatePlayerView, GameStatePlayerView,
PlayStatePlayerView,
};
use yew::prelude::*;
#[function_component(OnlineTable)]
pub fn online_table(props: &OnlineTableProps) -> Html {
let ctx = use_app_context();
let table_state: UseStateHandle<Option<GameStatePlayerView>> =
use_state(|| None);
let update_table_state = {
let table_state = table_state.clone();
let props = props.clone();
|| {
Box::pin(async move {
// let table_state = table_state.clone();
let props = props.clone();
let response =
Request::get(&format!("/api/table/{}", props.table.id))
.send()
.await
.context("fetching table data")?;
let table = ok_json(response).await?;
table_state.set(Some(table));
Ok(())
})
as Pin<Box<dyn Future<Output = Result<(), anyhow::Error>>>>
}
};
{
let ctx = ctx.clone();
let update_table_state = update_table_state.clone();
use_effect_with_deps(
move |_| {
ctx.spawn_async(async move {
update_table_state().await?;
Ok(())
});
|| ()
},
(),
);
}
let on_bid = {
let ctx = ctx.clone();
let props = props.clone();
let update_table_state = update_table_state.clone();
Callback::from(move |bid| {
let update_table_state = update_table_state.clone();
info!("Bid clicked: {:?}", bid);
ctx.spawn_async(async move {
let bid_response = Request::post(&format!(
"/api/table/{}/bid",
props.table.id
))
.json(&bid)?
.send()
.await
.context("submitting bid")?;
let () = ok_json(bid_response).await?;
update_table_state().await?;
Ok(())
});
})
};
let leave_table = {
let ctx = ctx.clone();
Callback::from(move |_| {
ctx.leave_table();
})
};
let center = match &*table_state {
Some(GameStatePlayerView::Bidding(bidding)) =>
bidding_view(bidding, on_bid),
Some(GameStatePlayerView::Playing(playing)) => todo!(),
None => html! { <p>{"Loading table"}</p> },
};
html! {
<>
p<>{ format!("This is table {}", props.table.id) }</p>
<button onclick={leave_table}>
{ "Leave table" }
</button>
{ center }
</>
}
}
#[derive(PartialEq, Properties, Clone)]
pub struct OnlineTableProps {
pub table: protocol::Table,
}
pub fn bidding_view(
bidding: &BiddingStatePlayerView,
on_bid: Callback<Bid>,
) -> Html {
html! {
<>
<div class="center">
<BiddingTable bidding={bidding.bidding.clone()} />
<BiddingBox current_bid={bidding.bidding.highest_bid().clone()} on_bid={ on_bid } />
{ format!("It is {:?} to bid", bidding.bidding.current_bidder()) }
</div>
<div class="hand south">
<Hand cards={ bidding.hand.clone() } on_card_clicked={ Callback::from(|card| {}) } />
</div>
<h2>{ "Table view" }</h2>
<pre>{ format!("{:#?}", bidding) }</pre>
</>
}
}
|