player self seat number update
This commit is contained in:
parent
6fb105ca82
commit
ab1cb29952
|
|
@ -592,6 +592,7 @@ dialog .tab-content {
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-lobby {
|
.player-lobby {
|
||||||
|
user-select: none;
|
||||||
margin: 5vh 15vw 5vh 15vw;
|
margin: 5vh 15vw 5vh 15vw;
|
||||||
padding: 3ch;
|
padding: 3ch;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
|
|
@ -604,6 +605,74 @@ dialog .tab-content {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.player-additional {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid rgb(0, 64, 0);
|
||||||
|
background-color: rgba(0, 64, 0, 0.3);
|
||||||
|
gap: 0.25ch;
|
||||||
|
width: fit-content;
|
||||||
|
padding: 3ch;
|
||||||
|
min-width: 40vw;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.unset {
|
||||||
|
border: 1px solid rgb(128, 0, 0);
|
||||||
|
background-color: rgba(64, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#player-number {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-text {
|
||||||
|
font-size: 1.5em;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
.number {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.unset {
|
||||||
|
font-size: 1.25em;
|
||||||
|
color: rgb(192, 0, 0);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-update:not([hidden]) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 0.25ch;
|
||||||
|
margin-top: 3ch;
|
||||||
|
font-size: 1.5em;
|
||||||
|
|
||||||
|
input::-webkit-outer-spin-button,
|
||||||
|
input::-webkit-inner-spin-button {
|
||||||
|
display: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=number] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit] {
|
||||||
|
@extend button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tutorial-box {
|
.tutorial-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use werewolves_macros::Titles;
|
||||||
|
|
||||||
use crate::{character::CharacterId, game::GameTime};
|
use crate::{character::CharacterId, game::GameTime};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Titles)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Titles)]
|
||||||
pub enum DiedTo {
|
pub enum DiedTo {
|
||||||
Execution {
|
Execution {
|
||||||
day: NonZeroU8,
|
day: NonZeroU8,
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ pub enum ServerToClientMessage {
|
||||||
LobbyInfo {
|
LobbyInfo {
|
||||||
joined: bool,
|
joined: bool,
|
||||||
players: Box<[PublicIdentity]>,
|
players: Box<[PublicIdentity]>,
|
||||||
|
current_number: Option<NonZeroU8>,
|
||||||
},
|
},
|
||||||
GameInProgress,
|
GameInProgress,
|
||||||
GameStart {
|
GameStart {
|
||||||
|
|
|
||||||
|
|
@ -197,14 +197,14 @@ impl DeadChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct DeadChatMessage {
|
pub struct DeadChatMessage {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub timestamp: DateTime<Utc>,
|
pub timestamp: DateTime<Utc>,
|
||||||
pub message: DeadChatContent,
|
pub message: DeadChatContent,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum DeadChatContent {
|
pub enum DeadChatContent {
|
||||||
PlayerMessage {
|
PlayerMessage {
|
||||||
from: CharacterIdentity,
|
from: CharacterIdentity,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ pub struct PublicIdentity {
|
||||||
pub number: Option<NonZeroU8>,
|
pub number: Option<NonZeroU8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct CharacterIdentity {
|
pub struct CharacterIdentity {
|
||||||
pub character_id: CharacterId,
|
pub character_id: CharacterId,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
||||||
|
|
@ -6,24 +6,20 @@ use leptos_router::hooks::use_url;
|
||||||
use reactive_stores::Store;
|
use reactive_stores::Store;
|
||||||
|
|
||||||
use crate::app::{
|
use crate::app::{
|
||||||
components::LinkButton,
|
components::{DialogModal, LinkButton},
|
||||||
storage::user::{AuthContext, AuthContextStoreFields},
|
storage::user::{AuthContext, AuthContextStoreFields},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn get_active_game(token: TokenString) -> Result<Option<GameId>, ServerError> {
|
pub async fn get_active_game(token: TokenString) -> Result<Option<GameId>, ServerError> {
|
||||||
let db = use_context::<api::state::AppState>()
|
let db = expect_context::<api::state::AppState>().db;
|
||||||
.expect("no app state")
|
|
||||||
.db;
|
|
||||||
let user = db.user().check_token(&token).await?;
|
let user = db.user().check_token(&token).await?;
|
||||||
Ok(db.game().get_joined_active_game(user.id).await?)
|
Ok(db.game().get_joined_active_game(user.id).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn new_game(token: TokenString) -> Result<GameId, ServerError> {
|
pub async fn new_game(token: TokenString) -> Result<GameId, ServerError> {
|
||||||
let db = use_context::<api::state::AppState>()
|
let db = expect_context::<api::state::AppState>().db;
|
||||||
.expect("no app state")
|
|
||||||
.db;
|
|
||||||
let user = db.user().check_token(&token).await?;
|
let user = db.user().check_token(&token).await?;
|
||||||
Ok(db.game().new_game(user.id).await?.id)
|
Ok(db.game().new_game(user.id).await?.id)
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +96,7 @@ pub fn Nav() -> impl IntoView {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
{home_button}
|
{home_button}
|
||||||
<span class="display-name">{session.name().to_string()}</span>
|
<span class="display-name">{session.name().to_string()}</span>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,21 @@
|
||||||
werewolves_macros::include_path!("werewolves/src/app/pages/game/player");
|
werewolves_macros::include_path!("werewolves/src/app/pages/game/player");
|
||||||
|
|
||||||
|
use core::{
|
||||||
|
hash::Hash,
|
||||||
|
num::{self, NonZeroU8},
|
||||||
|
ops::{Deref, Not},
|
||||||
|
};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use leptos::{ev::MouseEvent, prelude::*};
|
use leptos::{
|
||||||
|
ev::{Event, MouseEvent, SubmitEvent, Targeted},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use werewolves_proto::{
|
use werewolves_proto::{
|
||||||
message::{
|
message::{
|
||||||
ClientDeadChat, ClientMessage, ServerToClientMessage as Srv2Client, dead::DeadChatMessage,
|
ClientDeadChat, ClientMessage, ServerToClientMessage as Srv2Client, UpdateSelf,
|
||||||
|
dead::DeadChatMessage,
|
||||||
},
|
},
|
||||||
role::RoleTitle,
|
role::RoleTitle,
|
||||||
};
|
};
|
||||||
|
|
@ -13,8 +24,13 @@ use crate::{ConsoleLogError, app::components::ErrorBox};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum Page {
|
enum Page {
|
||||||
Lobby { joined: bool },
|
Lobby {
|
||||||
RoleReveal { role: RoleTitle },
|
joined: bool,
|
||||||
|
current_number: Option<NonZeroU8>,
|
||||||
|
},
|
||||||
|
RoleReveal {
|
||||||
|
role: RoleTitle,
|
||||||
|
},
|
||||||
GameInProgress,
|
GameInProgress,
|
||||||
Sleep,
|
Sleep,
|
||||||
DeadChat,
|
DeadChat,
|
||||||
|
|
@ -27,7 +43,7 @@ pub fn PlayerGamePage(
|
||||||
disconnect: RwSignal<bool>,
|
disconnect: RwSignal<bool>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let error = RwSignal::new(None);
|
let error = RwSignal::new(None);
|
||||||
let dead_chat: RwSignal<Option<Vec<DeadChatMessage>>> = RwSignal::new(None);
|
let dead_chat: RwSignal<Option<HashSet<HashedDeadChatMessage>>> = RwSignal::new(None);
|
||||||
let page: RwSignal<Option<Page>> = RwSignal::new(None);
|
let page: RwSignal<Option<Page>> = RwSignal::new(None);
|
||||||
Effect::new(move || {
|
Effect::new(move || {
|
||||||
let Some(message) = message.get() else {
|
let Some(message) = message.get() else {
|
||||||
|
|
@ -35,18 +51,30 @@ pub fn PlayerGamePage(
|
||||||
};
|
};
|
||||||
match message {
|
match message {
|
||||||
Srv2Client::Disconnect => disconnect.set(true),
|
Srv2Client::Disconnect => disconnect.set(true),
|
||||||
Srv2Client::LobbyInfo { joined, .. } => page.set(Some(Page::Lobby { joined })),
|
Srv2Client::LobbyInfo {
|
||||||
|
joined,
|
||||||
|
current_number,
|
||||||
|
..
|
||||||
|
} => page.set(Some(Page::Lobby {
|
||||||
|
joined,
|
||||||
|
current_number,
|
||||||
|
})),
|
||||||
Srv2Client::GameInProgress => page.set(Some(Page::GameInProgress)),
|
Srv2Client::GameInProgress => page.set(Some(Page::GameInProgress)),
|
||||||
Srv2Client::GameStart { role } => page.set(Some(Page::RoleReveal { role })),
|
Srv2Client::GameStart { role } => page.set(Some(Page::RoleReveal { role })),
|
||||||
Srv2Client::Story(game_story) => todo!("{game_story:#?}"),
|
Srv2Client::Story(game_story) => todo!("{game_story:#?}"),
|
||||||
Srv2Client::Update(_) => {}
|
Srv2Client::Update(_) => {}
|
||||||
Srv2Client::DeadChat(dead_chat_messages) => {
|
Srv2Client::DeadChat(dead_chat_messages) => {
|
||||||
dead_chat.set(Some(dead_chat_messages.to_vec()));
|
dead_chat.set(Some(
|
||||||
|
dead_chat_messages
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::<HashedDeadChatMessage>::into)
|
||||||
|
.collect(),
|
||||||
|
));
|
||||||
page.set(Some(Page::DeadChat));
|
page.set(Some(Page::DeadChat));
|
||||||
}
|
}
|
||||||
Srv2Client::DeadChatMessage(dead_chat_message) => {
|
Srv2Client::DeadChatMessage(dead_chat_message) => {
|
||||||
if let Some(chat) = dead_chat.write().as_mut() {
|
if let Some(chat) = dead_chat.write().as_mut() {
|
||||||
chat.push(dead_chat_message);
|
chat.insert(dead_chat_message.into());
|
||||||
page.set(Some(Page::DeadChat));
|
page.set(Some(Page::DeadChat));
|
||||||
} else {
|
} else {
|
||||||
reply.set(Some(ClientMessage::DeadChat(ClientDeadChat::GetHistory)));
|
reply.set(Some(ClientMessage::DeadChat(ClientDeadChat::GetHistory)));
|
||||||
|
|
@ -61,6 +89,8 @@ pub fn PlayerGamePage(
|
||||||
}
|
}
|
||||||
// match message {}
|
// match message {}
|
||||||
});
|
});
|
||||||
|
let joined = RwSignal::new(false);
|
||||||
|
let current_number = RwSignal::new(None);
|
||||||
let content = move || {
|
let content = move || {
|
||||||
let Some(page) = page.get() else {
|
let Some(page) = page.get() else {
|
||||||
return ().into_any();
|
return ().into_any();
|
||||||
|
|
@ -68,32 +98,19 @@ pub fn PlayerGamePage(
|
||||||
match page {
|
match page {
|
||||||
Page::DeadChat => todo!("dead chat"),
|
Page::DeadChat => todo!("dead chat"),
|
||||||
Page::Sleep => view! { <h1>"go to sleep"</h1> }.into_any(),
|
Page::Sleep => view! { <h1>"go to sleep"</h1> }.into_any(),
|
||||||
Page::Lobby { joined } => {
|
Page::Lobby {
|
||||||
let click = move |ev: MouseEvent| {
|
joined: j,
|
||||||
ev.prevent_default();
|
current_number: c,
|
||||||
reply.set(Some(if joined {
|
} => {
|
||||||
ClientMessage::Goodbye
|
joined.set(j);
|
||||||
} else {
|
current_number.set(c);
|
||||||
ClientMessage::Hello
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
let text = match joined {
|
|
||||||
true => view! {
|
|
||||||
<h2>"you are in the lobby"</h2>
|
|
||||||
<p>"you're all good c:"</p>
|
|
||||||
}
|
|
||||||
.into_any(),
|
|
||||||
false => view! {
|
|
||||||
<h2>"you are not in the lobby"</h2>
|
|
||||||
<p>"join if you want to play"</p>
|
|
||||||
}
|
|
||||||
.into_any(),
|
|
||||||
};
|
|
||||||
view! {
|
view! {
|
||||||
<div class="player-lobby" class:joined=joined>
|
<PlayerLobby
|
||||||
{text}
|
reply=reply
|
||||||
<button on:click=click>{if joined { "leave" } else { "join" }}</button>
|
joined=joined.read_only()
|
||||||
</div>
|
current_number=current_number.read_only()
|
||||||
|
error=error
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
@ -123,3 +140,39 @@ pub fn PlayerGamePage(
|
||||||
}
|
}
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct HashedDeadChatMessage(DeadChatMessage);
|
||||||
|
impl Ord for HashedDeadChatMessage {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.timestamp.cmp(&other.timestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd for HashedDeadChatMessage {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Hash for HashedDeadChatMessage {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.id.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<DeadChatMessage> for HashedDeadChatMessage {
|
||||||
|
fn from(value: DeadChatMessage) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<HashedDeadChatMessage> for DeadChatMessage {
|
||||||
|
fn from(value: HashedDeadChatMessage) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Deref for HashedDeadChatMessage {
|
||||||
|
type Target = DeadChatMessage;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
use core::num::NonZeroU8;
|
||||||
|
|
||||||
|
use leptos::{
|
||||||
|
ev::{Event, MouseEvent, SubmitEvent, Targeted},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use werewolves_proto::message::{ClientMessage, UpdateSelf};
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn PlayerLobby(
|
||||||
|
reply: WriteSignal<Option<ClientMessage>>,
|
||||||
|
joined: ReadSignal<bool>,
|
||||||
|
current_number: ReadSignal<Option<NonZeroU8>>,
|
||||||
|
error: RwSignal<Option<String>>,
|
||||||
|
) -> impl IntoView {
|
||||||
|
let click = move |ev: MouseEvent| {
|
||||||
|
ev.prevent_default();
|
||||||
|
reply.set(Some(if joined.get() {
|
||||||
|
ClientMessage::Goodbye
|
||||||
|
} else {
|
||||||
|
ClientMessage::Hello
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
let text = move || match joined.get() {
|
||||||
|
true => view! {
|
||||||
|
<h2>"you are in the lobby"</h2>
|
||||||
|
<p>"you're all good c:"</p>
|
||||||
|
}
|
||||||
|
.into_any(),
|
||||||
|
false => view! {
|
||||||
|
<h2>"you are not in the lobby"</h2>
|
||||||
|
<p>"join if you want to play"</p>
|
||||||
|
}
|
||||||
|
.into_any(),
|
||||||
|
};
|
||||||
|
let number: RwSignal<Option<NonZeroU8>> = RwSignal::new(None);
|
||||||
|
let number = move || {
|
||||||
|
let form_hidden = RwSignal::new(true);
|
||||||
|
let number_update = {
|
||||||
|
let update = move |e: Targeted<Event, leptos::web_sys::HtmlInputElement>| {
|
||||||
|
let value = e.target().value();
|
||||||
|
if value.trim().is_empty() {
|
||||||
|
number.set(None);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let current = number.get_untracked();
|
||||||
|
let default = current.map(|c| c.get().to_string()).unwrap_or_default();
|
||||||
|
let value_u8 = match e.target().value().trim().parse::<u8>() {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => {
|
||||||
|
e.target().set_value(default.as_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(nz) = NonZeroU8::new(value_u8) {
|
||||||
|
number.set(Some(nz));
|
||||||
|
} else {
|
||||||
|
e.target().set_value(default.as_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let submit = move |ev: SubmitEvent| {
|
||||||
|
ev.prevent_default();
|
||||||
|
let Some(num) = number.get() else {
|
||||||
|
error.set(Some("please set a number".into()));
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
reply.set(Some(ClientMessage::UpdateSelf(UpdateSelf::Number(num))));
|
||||||
|
form_hidden.set(true);
|
||||||
|
};
|
||||||
|
view! {
|
||||||
|
<form class="number-update" on:submit=submit hidden=move || form_hidden.get()>
|
||||||
|
<label for="player-number">"change seat number"</label>
|
||||||
|
<input
|
||||||
|
id="player-number"
|
||||||
|
type="number"
|
||||||
|
autocomplete="off"
|
||||||
|
on:input:target=update
|
||||||
|
value=move || {
|
||||||
|
number.get().map(|n| n.get().to_string()).unwrap_or_default()
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<input value="submit" type="submit" />
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
.into_any()
|
||||||
|
};
|
||||||
|
match current_number.get() {
|
||||||
|
Some(num) => {
|
||||||
|
form_hidden.set(true);
|
||||||
|
view! {
|
||||||
|
<span class="number-text">
|
||||||
|
"you are in seat "<span class="number">{num.get()}</span>
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
on:click=move |_| form_hidden.set(false)
|
||||||
|
hidden=move || !form_hidden.get()
|
||||||
|
style="width: fit-content; font-size: 1.5em;"
|
||||||
|
>
|
||||||
|
"change seat"
|
||||||
|
</button>
|
||||||
|
{number_update}
|
||||||
|
}
|
||||||
|
.into_any()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
form_hidden.set(false);
|
||||||
|
view! {
|
||||||
|
<span class="number-text unset">"you don't have a seat number :c"</span>
|
||||||
|
<span class="number-text">"please put your seat number in below"</span>
|
||||||
|
{number_update}
|
||||||
|
}
|
||||||
|
.into_any()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
view! {
|
||||||
|
<div class="player-lobby" class:joined=joined>
|
||||||
|
{text}
|
||||||
|
<button on:click=click>{move || if joined.get() { "leave" } else { "join" }}</button>
|
||||||
|
</div>
|
||||||
|
<div class="player-additional">
|
||||||
|
<div class="number-info" class:unset=move || current_number.get().is_none()>
|
||||||
|
{number}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,9 +24,7 @@ pub fn UserSettings() -> impl IntoView {
|
||||||
match tut_read.read().enabled {
|
match tut_read.read().enabled {
|
||||||
true => view! { <button on:click=move |_| tut_write.write().enabled = false>"disable tutorials"</button> }
|
true => view! { <button on:click=move |_| tut_write.write().enabled = false>"disable tutorials"</button> }
|
||||||
.into_any(),
|
.into_any(),
|
||||||
false => view! {
|
false => view! { <button on:click=move |_| tut_write.write().enabled = true>"enable tutorials"</button> }.into_any(),
|
||||||
<button on:click=move |_| tut_write.write().enabled = true>"enable tutorials"</button>
|
|
||||||
}.into_any(),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
|
|
|
||||||
|
|
@ -69,19 +69,20 @@ impl<'a> Lobby<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_lobby_info_to_clients(&mut self) -> Result<(), ServerError> {
|
pub async fn send_lobby_info_to_clients(&mut self) -> Result<(), ServerError> {
|
||||||
let (players, identities) = self
|
let joined = self.db.game().get_joined_players(self.game_id).await?;
|
||||||
.db
|
let (players, identities) = joined
|
||||||
.game()
|
.iter()
|
||||||
.get_joined_players(self.game_id)
|
.map(|p| (p.player_id, p.public.clone()))
|
||||||
.await?
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| (p.player_id, p.public))
|
|
||||||
.collect::<(Vec<_>, Vec<_>)>();
|
.collect::<(Vec<_>, Vec<_>)>();
|
||||||
let identities = identities.into_boxed_slice();
|
let identities = identities.into_boxed_slice();
|
||||||
super::send_to_all_players_in_game_filtered(self.game_id, move |pid| {
|
super::send_to_all_players_in_game_filtered(self.game_id, move |pid| {
|
||||||
Some(ServerToClientMessage::LobbyInfo {
|
Some(ServerToClientMessage::LobbyInfo {
|
||||||
joined: players.contains(&pid),
|
joined: players.contains(&pid),
|
||||||
players: identities.clone(),
|
players: identities.clone(),
|
||||||
|
current_number: joined
|
||||||
|
.iter()
|
||||||
|
.find_map(|j| (j.player_id == pid).then_some(j.public.number))
|
||||||
|
.flatten(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
@ -257,11 +258,16 @@ impl<'a> Lobby<'a> {
|
||||||
self.send_lobby_info_to_clients().await.log_debug(loc!());
|
self.send_lobby_info_to_clients().await.log_debug(loc!());
|
||||||
}
|
}
|
||||||
HostOrClientMessage::Client(IdentifiedClientMessage {
|
HostOrClientMessage::Client(IdentifiedClientMessage {
|
||||||
identity: Identification { player_id, .. },
|
identity:
|
||||||
|
Identification {
|
||||||
|
player_id,
|
||||||
|
public: PublicIdentity { number, .. },
|
||||||
|
},
|
||||||
update: ClientUpdate::Message(ClientMessage::GetState),
|
update: ClientUpdate::Message(ClientMessage::GetState),
|
||||||
}) => {
|
}) => {
|
||||||
let joined = self.db.game().get_joined_players(self.game_id).await?;
|
let joined = self.db.game().get_joined_players(self.game_id).await?;
|
||||||
let msg = ServerToClientMessage::LobbyInfo {
|
let msg = ServerToClientMessage::LobbyInfo {
|
||||||
|
current_number: number,
|
||||||
joined: joined.iter().any(|p| p.player_id == player_id),
|
joined: joined.iter().any(|p| p.player_id == player_id),
|
||||||
players: joined.into_iter().map(|p| p.public).collect(),
|
players: joined.into_iter().map(|p| p.public).collect(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue