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