summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-12-23 16:41:50 -0500
committerKjetil Orbekk <kj@orbekk.com>2022-12-23 16:41:50 -0500
commitb62be3482bc8a69d59744964ec4f6d3574d8b918 (patch)
treec8bc8d42cbfcbb5fe8f075ec99d48d8ffd4b5ce4
parent45ce66a29b3d1c49ef8e86b125701e89d58e8a4a (diff)
Add ability to request the next deal when results are displayed
-rw-r--r--server/src/main.rs13
-rw-r--r--server/src/play.rs9
-rw-r--r--webapp/src/components/table.rs19
-rw-r--r--webapp/src/services.rs9
4 files changed, 48 insertions, 2 deletions
diff --git a/server/src/main.rs b/server/src/main.rs
index a9e8f69..c0ec4cb 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -117,6 +117,7 @@ async fn main() {
.route("/api/table/:id", get(get_table_view))
.route("/api/table/:id/bid", post(post_bid))
.route("/api/table/:id/play", post(post_play))
+ .route("/api/table/:id/admin/deal", post(table_new_deal))
.route("/api/login", get(login))
.route(auth::LOGIN_CALLBACK, get(login_callback))
.layer(CookieManagerLayer::new())
@@ -169,6 +170,18 @@ async fn get_table_view(
Ok(response)
}
+async fn table_new_deal(
+ _session: AuthenticatedSession,
+ State(state): ServerState,
+ Path(id): Path<Uuid>,
+) -> Result<Json<()>, BridgeError> {
+ info!("Getting table state for {id:}");
+ let jnl = DbJournal::new(state.db.clone(), id);
+ let mut table = play::Table::replay(jnl).await?;
+ table.new_deal().await?;
+ Ok(Json(()))
+}
+
async fn post_bid(
_session: AuthenticatedSession,
State(state): ServerState,
diff --git a/server/src/play.rs b/server/src/play.rs
index e0d4733..68ea94b 100644
--- a/server/src/play.rs
+++ b/server/src/play.rs
@@ -179,6 +179,15 @@ impl<J: Journal<TableUpdate>> Table<J> {
self.insert_and_apply(TableUpdate::Play(card)).await
}
+ pub async fn new_deal(&mut self) -> Result<(), BridgeError> {
+ let dealer = match &self.state {
+ TableState::Unknown => random(),
+ TableState::Game(g) => g.dealer(),
+ TableState::Result(_) => random(), // TODO: We should know the dealer here.
+ };
+ self.insert_and_apply(TableUpdate::NewDeal { deal: random(), dealer: dealer.next() }).await
+ }
+
async fn insert_and_apply(
&mut self,
update: TableUpdate,
diff --git a/webapp/src/components/table.rs b/webapp/src/components/table.rs
index 9702793..3bc52a3 100644
--- a/webapp/src/components/table.rs
+++ b/webapp/src/components/table.rs
@@ -35,6 +35,7 @@ struct OnlineTableInner {
pub enum Msg {
TableStateUpdated(Result<TableStatePlayerView, anyhow::Error>),
+ RequestNewDeal,
Bid(Bid),
Play(Card),
}
@@ -136,6 +137,15 @@ impl Component for OnlineTableInner {
ctx.props().app_ctx.set_error(error);
false
}
+ Msg::RequestNewDeal => {
+ let table = ctx.props().table.clone();
+ ctx.link().send_future(
+ async move {
+ services::new_deal(table.clone()).await?;
+ services::get_table_player_view(table).await
+ }.map(Msg::TableStateUpdated));
+ false
+ },
}
}
@@ -146,8 +156,13 @@ impl Component for OnlineTableInner {
<p>{"An error occurred."}</p>
},
Some(TableStatePlayerView::Game(game)) => self.view_game(ctx, game),
- Some(TableStatePlayerView::Result(result)) => html! {
- <p>{"A beautiful result."}</p>
+ Some(TableStatePlayerView::Result(_)) => html! {
+ <>
+ <p>{"A beautiful result."}</p>
+ <button onclick={ctx.link().callback(|_| Msg::RequestNewDeal)}>
+ {"New deal"}
+ </button>
+ </>
},
}
}
diff --git a/webapp/src/services.rs b/webapp/src/services.rs
index 43b1698..668530f 100644
--- a/webapp/src/services.rs
+++ b/webapp/src/services.rs
@@ -34,3 +34,12 @@ pub async fn play(table: Table, card: Card) -> Result<(), anyhow::Error> {
.context("submitting play")?;
ok_json(response).await
}
+
+pub async fn new_deal(table: Table) -> Result<(), anyhow::Error> {
+ let response =
+ Request::post(&format!("/api/table/{}/admin/deal", table.id))
+ .send()
+ .await
+ .context("requesting new deal")?;
+ ok_json(response).await
+}