idk lol
This commit is contained in:
parent
dc7b3efd4f
commit
54d16b2c01
6 changed files with 133 additions and 50 deletions
|
@ -9,11 +9,14 @@ use std::collections::BTreeSet;
|
|||
#[component]
|
||||
pub fn Browser() -> impl IntoView {
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
|
||||
// TODO: don't do this
|
||||
let tx = websocket.clone();
|
||||
|
||||
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
let game_update_context = expect_context::<ReadSignal<Option<GamesUpdate>>>();
|
||||
let game_browser_context = expect_context::<ReadSignal<Vec<GameBrowserMeta>>>();
|
||||
let card_packs = expect_context::<ReadSignal<CardPacksMeta>>();
|
||||
let (active_games, set_active_games) = create_signal::<Vec<String>>(vec![]);
|
||||
|
||||
let new_game_name_ref = create_node_ref::<Input>();
|
||||
let (selected_packs, set_selected_packs) = create_signal::<BTreeSet<u8>>(BTreeSet::new());
|
||||
|
@ -24,18 +27,15 @@ pub fn Browser() -> impl IntoView {
|
|||
// Game stuff
|
||||
let new_game = move |_| {
|
||||
if let Some(input) = new_game_name_ref.get() {
|
||||
if input.value() == String::from("") {
|
||||
if input.value() == *"" {
|
||||
logging::log!("New game name is empty!");
|
||||
} else if selected_packs().is_empty() {
|
||||
logging::log!("New game selected packs is empty!");
|
||||
} else {
|
||||
(websocket.send)(
|
||||
tx.send(
|
||||
&to_string(&NewGameRequest {
|
||||
name: input.value(),
|
||||
packs: selected_packs()
|
||||
.into_iter()
|
||||
.map(|n| n.clone()) // hax
|
||||
.collect::<Vec<_>>(),
|
||||
packs: selected_packs().into_iter().collect::<Vec<_>>(),
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
|
@ -44,33 +44,65 @@ pub fn Browser() -> impl IntoView {
|
|||
}
|
||||
};
|
||||
|
||||
create_effect(move |_| {
|
||||
game_update_context.with(move |games| {
|
||||
if let Some(games) = games {
|
||||
set_active_games(games.games.clone());
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Clear games list on disconnect
|
||||
create_effect(move |_| {
|
||||
if !connected() {
|
||||
set_active_games(vec![]);
|
||||
}
|
||||
});
|
||||
let (show_packs, set_show_packs) = create_signal(false);
|
||||
|
||||
let show_packs_button = move |_| set_show_packs(!show_packs());
|
||||
|
||||
let (join_id, set_join_id) = create_signal("".to_string());
|
||||
|
||||
create_effect(move |_| {
|
||||
websocket.send(&to_string(&GameJoinRequest { id: join_id() }).unwrap());
|
||||
});
|
||||
|
||||
view! {
|
||||
<div class="p-1">
|
||||
<h2 class="text-2xl">Game Browser</h2>
|
||||
<ul>
|
||||
{move || active_games().into_iter().map(|n| view! { <li>{n}</li> }).collect_view()}
|
||||
</ul>
|
||||
<table class="min-w-full border border-collapse table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="border-b">Name</th>
|
||||
<th class="border-b">Host</th>
|
||||
<th class="border-b">Players</th>
|
||||
<th class="border-b">Card Packs</th>
|
||||
<th class="border-b"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{move || {
|
||||
game_browser_context()
|
||||
.iter()
|
||||
.map(|game| {
|
||||
view! {
|
||||
<tr>
|
||||
<td class="text-center border-b">{&game.name}</td>
|
||||
<td class="text-center border-b">{&game.host}</td>
|
||||
<td class="text-center border-b">
|
||||
{&game.players.to_string()}
|
||||
</td>
|
||||
<td class="text-center border-b">
|
||||
{&game.packs.len().to_string()}
|
||||
</td>
|
||||
<td class="text-center border-b">
|
||||
<button
|
||||
type="button"
|
||||
value=&game.uuid
|
||||
on:click=move |e| {
|
||||
set_join_id(event_target_value(&e));
|
||||
}
|
||||
>
|
||||
Join
|
||||
</button>
|
||||
<button type="button">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
})
|
||||
.collect_view()
|
||||
}}
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
<div class="flex p-1">
|
||||
<form onsubmit="return false" on:submit=new_game>
|
||||
<h2 class="text-2xl">Create Game</h2>
|
||||
|
@ -129,6 +161,8 @@ pub fn Browser() -> impl IntoView {
|
|||
|
||||
<label for=n.pack>{n.name}</label>
|
||||
<br/>
|
||||
|
||||
// hax
|
||||
{set_selected_packs
|
||||
.update(|packs| {
|
||||
packs.insert(n.pack);
|
||||
|
@ -148,6 +182,7 @@ pub fn Browser() -> impl IntoView {
|
|||
.map(|n| {
|
||||
view! {
|
||||
<input
|
||||
checked
|
||||
type="checkbox"
|
||||
value=n.pack
|
||||
id=n.pack
|
||||
|
@ -170,6 +205,12 @@ pub fn Browser() -> impl IntoView {
|
|||
|
||||
<label for=n.pack>{n.name}</label>
|
||||
<br/>
|
||||
|
||||
// hax
|
||||
{set_selected_packs
|
||||
.update(|packs| {
|
||||
packs.insert(n.pack);
|
||||
})}
|
||||
}
|
||||
})
|
||||
.collect_view()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
// use crate::components::websocket::WebSocketContext;
|
||||
use leptos::*;
|
||||
use lib::*;
|
||||
|
||||
#[component]
|
||||
pub fn Game() -> impl IntoView {
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
// let websocket = expect_context::<WebSocketContext>();
|
||||
let game_meta = expect_context::<ReadSignal<Option<GameMeta>>>();
|
||||
|
||||
let (game_name, set_game_name) = create_signal("".to_string());
|
||||
|
@ -27,18 +27,31 @@ pub fn Game() -> impl IntoView {
|
|||
|
||||
view! {
|
||||
<div class="p-1">
|
||||
<h2 class="text-2xl">Game</h2>
|
||||
<span class="flex">
|
||||
<p class="p-3">Name: {move || game_name()}</p>
|
||||
<p class="p-3">Host: {move || game_host()}</p>
|
||||
<p class="p-3">Czar: {move || game_czar()}</p>
|
||||
<p class="p-3">Players: {move || game_players()}</p>
|
||||
</span>
|
||||
<div class="relative w-40 h-60 text-white bg-black rounded-lg">
|
||||
<div class="relative">
|
||||
<h2 class="text-2xl">Game</h2>
|
||||
<span>
|
||||
<p>Name: {move || game_name()}</p>
|
||||
<p>Host: {move || game_host()}</p>
|
||||
<p>Czar: {move || game_czar()}</p>
|
||||
</span>
|
||||
<span class="absolute top-0 right-0">
|
||||
<p>Players:</p>
|
||||
<ul>
|
||||
{move || {
|
||||
game_players()
|
||||
.iter()
|
||||
.map(|player| view! { <li>{player}</li> })
|
||||
.collect_view()
|
||||
}}
|
||||
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="relative m-auto w-40 h-60 text-white bg-black rounded-lg">
|
||||
<p class="p-4">{move || game_black().0}</p>
|
||||
<p class="absolute right-4 bottom-4">Pick: {move || game_black().1}</p>
|
||||
</div>
|
||||
<div class="inline-flex flex-wrap">
|
||||
<div class="inline-flex flex-wrap justify-center">
|
||||
{move || {
|
||||
game_white()
|
||||
.iter()
|
||||
|
|
|
@ -72,7 +72,7 @@ pub fn Websocket() -> impl IntoView {
|
|||
let (user_update, set_user_update) = create_signal::<Option<UserUpdate>>(Option::None);
|
||||
let (chat_update, set_chat_update) = create_signal::<Option<ChatUpdate>>(Option::None);
|
||||
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
|
||||
let (active_games, set_active_games) = create_signal::<Option<GamesUpdate>>(Option::None);
|
||||
let (active_games, set_active_games) = create_signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (current_game, set_current_game) = create_signal::<Option<GameMeta>>(Option::None);
|
||||
let (card_packs_meta, set_card_packs_meta) = create_signal::<CardPacksMeta>(CardPacksMeta {
|
||||
official_meta: vec![],
|
||||
|
@ -83,7 +83,7 @@ pub fn Websocket() -> impl IntoView {
|
|||
provide_context::<ReadSignal<Option<UserUpdate>>>(user_update);
|
||||
provide_context::<ReadSignal<Option<ChatUpdate>>>(chat_update);
|
||||
provide_context::<ReadSignal<Option<ChatMessage>>>(chat_message);
|
||||
provide_context::<ReadSignal<Option<GamesUpdate>>>(active_games);
|
||||
provide_context::<ReadSignal<Vec<GameBrowserMeta>>>(active_games);
|
||||
provide_context::<ReadSignal<Option<GameMeta>>>(current_game);
|
||||
provide_context::<ReadSignal<CardPacksMeta>>(card_packs_meta);
|
||||
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
||||
|
@ -106,7 +106,7 @@ pub fn Websocket() -> impl IntoView {
|
|||
} else if let Ok(chat_update) = from_str::<ChatUpdate>(message) {
|
||||
set_chat_update(Some(chat_update));
|
||||
} else if let Ok(games_update) = from_str::<GamesUpdate>(message) {
|
||||
set_active_games(Some(games_update));
|
||||
set_active_games(games_update.games);
|
||||
} else if let Ok(game_update) = from_str::<GameMeta>(message) {
|
||||
set_current_game(Some(game_update));
|
||||
} else if let Ok(packs_meta_update) = from_str::<CardPacksMeta>(message) {
|
||||
|
|
|
@ -1,14 +1,32 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Game join request
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct GameJoinRequest {
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
/// Game meta
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct GameMeta {
|
||||
pub uuid: String,
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub players: Vec<String>,
|
||||
pub czar: String,
|
||||
pub black: (String, u8),
|
||||
pub white: Vec<String>,
|
||||
pub packs: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Game browser meta
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct GameBrowserMeta {
|
||||
pub uuid: String,
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub players: usize,
|
||||
pub packs: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Card Pack Meta
|
||||
|
@ -30,7 +48,7 @@ pub struct CardPacksMeta {
|
|||
/// Games update
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GamesUpdate {
|
||||
pub games: Vec<String>,
|
||||
pub games: Vec<GameBrowserMeta>,
|
||||
}
|
||||
|
||||
/// Chat update
|
||||
|
|
|
@ -161,7 +161,7 @@ struct NewGameManifest {
|
|||
|
||||
/// A struct that represents a player
|
||||
#[derive(Debug)]
|
||||
struct Player {
|
||||
pub struct Player {
|
||||
/// The player's hand
|
||||
white: Vec<CardWhite>,
|
||||
/// The player's wins
|
||||
|
@ -171,6 +171,8 @@ struct Player {
|
|||
/// The game master
|
||||
#[derive(Debug)]
|
||||
pub struct Game {
|
||||
/// Game's UUID
|
||||
pub uuid: Uuid,
|
||||
/// The name of the game
|
||||
pub name: String,
|
||||
/// The host user of the game
|
||||
|
@ -179,20 +181,25 @@ pub struct Game {
|
|||
white: Vec<CardWhite>,
|
||||
/// Black draw pile
|
||||
black: Vec<CardBlack>,
|
||||
players: HashMap<Uuid, Player>,
|
||||
pub players: HashMap<Uuid, Player>,
|
||||
/// Black card for the current round
|
||||
current_black: Option<CardBlack>,
|
||||
pub packs: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new(state: Arc<AppState>, request: NewGameManifest) -> Result<Self> {
|
||||
tracing::debug!("{:#?}", request.packs);
|
||||
tracing::debug!("{:#?}", request.packs.len());
|
||||
let mut game = Game {
|
||||
uuid: Uuid::now_v7(),
|
||||
name: request.host.read().unwrap().name.clone(),
|
||||
host: request.host.clone(),
|
||||
white: vec![],
|
||||
black: vec![],
|
||||
players: HashMap::new(),
|
||||
current_black: Option::None,
|
||||
packs: request.packs.clone(),
|
||||
};
|
||||
tracing::debug!(
|
||||
"Creating game {} with {} as host",
|
||||
|
@ -367,6 +374,7 @@ impl GameHandler {
|
|||
}
|
||||
|
||||
let meta = GameMeta {
|
||||
uuid: new_game_object.uuid.to_string(),
|
||||
name: new_game_object.name.clone(),
|
||||
host: new_game_object.host.read().unwrap().name.clone(),
|
||||
players: new_game_object
|
||||
|
@ -377,7 +385,7 @@ impl GameHandler {
|
|||
.user_uuid
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&player.0)
|
||||
.get(player.0)
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -395,6 +403,7 @@ impl GameHandler {
|
|||
.iter()
|
||||
.map(|card| card.text.clone())
|
||||
.collect(),
|
||||
packs: new_game_object.packs.clone(),
|
||||
};
|
||||
|
||||
tx.send(serde_json::to_string(&meta).unwrap())
|
||||
|
|
|
@ -283,17 +283,19 @@ pub fn meta_server_summary_update(state: &Arc<AppState>) -> String {
|
|||
/// Generate games list update
|
||||
pub fn meta_games_browser_update(state: &Arc<AppState>) -> String {
|
||||
// TODO: this may get expensive if there are many games
|
||||
let mut names = vec![];
|
||||
let mut games = vec![];
|
||||
|
||||
for game in state.games.read().unwrap().values() {
|
||||
names.push(format!(
|
||||
"Name: {} Host: {}",
|
||||
game.read().unwrap().name,
|
||||
game.read().unwrap().host.read().unwrap().name
|
||||
));
|
||||
games.push(GameBrowserMeta {
|
||||
uuid: game.read().unwrap().uuid.to_string(),
|
||||
name: game.read().unwrap().name.clone(),
|
||||
host: game.read().unwrap().host.read().unwrap().name.clone(),
|
||||
players: game.read().unwrap().players.len(),
|
||||
packs: game.read().unwrap().packs.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
to_string::<GamesUpdate>(&GamesUpdate { games: names }).unwrap()
|
||||
to_string::<GamesUpdate>(&GamesUpdate { games }).unwrap()
|
||||
}
|
||||
|
||||
/// Generate chatroom join announcement
|
||||
|
|
Loading…
Add table
Reference in a new issue