lobby/settings ui touchups

This commit is contained in:
emilis 2025-11-16 18:51:19 +00:00
parent 4a41ace4d0
commit 6be2263f40
No known key found for this signature in database
5 changed files with 76 additions and 48 deletions

View File

@ -231,15 +231,7 @@ impl GameSettings {
} }
pub fn min_players_needed(&self) -> usize { pub fn min_players_needed(&self) -> usize {
let (wolves, villagers) = (self.wolves_count(), self.village_roles_count()); (2 * self.wolves_count() + 1).max(3)
if wolves > villagers {
wolves + 1 + wolves
} else if wolves < villagers {
wolves + villagers
} else {
wolves + villagers + 1
}
} }
pub fn new_slot(&mut self, role: RoleTitle) -> SlotId { pub fn new_slot(&mut self, role: RoleTitle) -> SlotId {

View File

@ -81,8 +81,8 @@ body {
body { body {
min-height: 100vh; min-height: 100vh;
max-width: 100vw; max-width: 100vw;
top: 0; top: 0px;
left: 0; left: 0px;
font-size: 1.5vh; font-size: 1.5vh;
user-select: none; user-select: none;
@ -174,7 +174,10 @@ nav.host-nav {
} }
.lobby-player-list { .lobby-player-list {
overflow: hidden;
padding-bottom: 80px; padding-bottom: 80px;
flex-shrink: 1;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
@ -334,23 +337,29 @@ button {
&:disabled:hover::after { &:disabled:hover::after {
content: attr(reason); content: attr(reason);
overflow-y: hidden;
position: absolute; position: absolute;
margin-top: 10px; margin-top: 100px;
top: 90%; min-width: 20vw;
// left: 0;
font: 'Cute Font'; font: 'Cute Font';
// color: #000;
// background-color: #fff;
color: rgba(255, 0, 0, 1); color: rgba(255, 0, 0, 1);
background-color: rgba(255, 0, 0, 0.3); background-color: black;
border: 1px solid rgba(255, 0, 0, 0.3); border: 1px solid rgba(255, 0, 0, 0.3);
min-width: 50vw;
width: fit-content;
padding: 3px; padding: 3px;
z-index: 4; z-index: 4;
align-self: center;
justify-self: center;
} }
} }
.host-setup {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
font-family: 'Cute Font';
font-size: 1.5em;
overflow-y: hidden;
}
.settings { .settings {
list-style: none; list-style: none;
@ -369,6 +378,15 @@ button {
padding: 0px; padding: 0px;
font-size: 0.7em; font-size: 0.7em;
} }
.settings-info {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
gap: 5px;
text-align: left;
width: fit-content;
}
} }
.wolves-intro { .wolves-intro {
@ -822,7 +840,7 @@ clients {
.client-nav { .client-nav {
max-width: 100%; max-width: 100%;
padding: 10px; padding: 10px;
height: 37px; height: 38px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: baseline; justify-content: baseline;
@ -2219,3 +2237,7 @@ li.choice {
.has-confirm { .has-confirm {
cursor: pointer; cursor: pointer;
} }
.dimmed {
filter: opacity(70%);
}

View File

@ -467,7 +467,7 @@ impl Component for Host {
let _ = loc.replace("/"); let _ = loc.replace("/");
} }
}); });
let screen = if self.big_screen { let screen = self.big_screen.then_some({
let to_normal = Callback::from(|_| { let to_normal = Callback::from(|_| {
if let Some(loc) = gloo::utils::document().location() { if let Some(loc) = gloo::utils::document().location() {
let _ = loc.replace("/host"); let _ = loc.replace("/host");
@ -476,20 +476,7 @@ impl Component for Host {
html! { html! {
<Button on_click={to_normal}>{"small screen"}</Button> <Button on_click={to_normal}>{"small screen"}</Button>
} }
} else { });
// let to_big = Callback::from(|_| {
// if let Some(loc) = gloo::utils::document().location() {
// let _ = loc.replace("/host/big");
// }
// });
html! {
<a href="/host/big">
<Button on_click={Callback::default()}>
{"big screen 📺"}
</Button>
</a>
}
};
let story_on_click = if let HostState::Story { .. } = &self.state { let story_on_click = if let HostState::Story { .. } = &self.state {
crate::callback::send_message(HostMessage::GetState, self.send.clone()) crate::callback::send_message(HostMessage::GetState, self.send.clone())
} else { } else {
@ -765,7 +752,7 @@ impl Host {
}) })
}); });
html! { html! {
<div class="column-list"> <div class="host-setup">
{settings} {settings}
<Lobby players={players} on_action={on_action}/> <Lobby players={players} on_action={on_action}/>
</div> </div>

View File

@ -29,8 +29,6 @@ pub struct LobbyProps {
#[function_component] #[function_component]
pub fn Lobby(LobbyProps { players, on_action }: &LobbyProps) -> Html { pub fn Lobby(LobbyProps { players, on_action }: &LobbyProps) -> Html {
html! { html! {
<div class="column-list">
<p style="text-align: center;">{format!("Players in lobby: {}", players.len())}</p>
<div class="lobby-player-list"> <div class="lobby-player-list">
{ {
players players
@ -39,6 +37,5 @@ pub fn Lobby(LobbyProps { players, on_action }: &LobbyProps) -> Html {
.collect::<Html>() .collect::<Html>()
} }
</div> </div>
</div>
} }
} }

View File

@ -285,6 +285,11 @@ pub fn Settings(
<Signin callback={on_add_player.clone()}/> <Signin callback={on_add_player.clone()}/>
</div> </div>
}; };
let current_roles = settings.slots().len();
let min_roles = settings.min_players_needed();
let min_roles_class = (current_roles < min_roles).then_some("red");
let player_count = players_in_lobby.len();
let player_count_class = (player_count != current_roles).then_some("red");
html! { html! {
<div class="settings"> <div class="settings">
@ -301,11 +306,36 @@ pub fn Settings(
> >
{"add player"} {"add player"}
</ClickableField> </ClickableField>
<p>{format!("min roles for setup: {}", settings.min_players_needed())}</p>
<p>{format!("current role count: {}", settings.slots().len())}</p>
<div class="roles-add-list"> <div class="roles-add-list">
{add_roles_buttons} {add_roles_buttons}
</div> </div>
<div class="settings-info">
<span class="current-min-role-count">
<span class="dimmed">{"current/minimum roles: "}</span>
<span class={classes!(min_roles_class)}>
<span class="current-roles">
{current_roles}
</span>
{"/"}
<span class="min-roles">
{min_roles}
</span>
</span>
</span>
<span class="player-role-count">
<span class="dimmed">{"players/roles: "}</span>
<span class={classes!(player_count_class)}>
<span>
{player_count}
</span>
{"/"}
<span>
{current_roles}
</span>
</span>
</span>
</div>
<div class="roles-in-setup"> <div class="roles-in-setup">
<h3>{"roles in the game"}</h3> <h3>{"roles in the game"}</h3>
<div class="role-list"> <div class="role-list">