Compare commits

..

2 Commits

Author SHA1 Message Date
emilis 27752727a3
fix icon sizes 2026-02-04 09:43:07 +00:00
emilis 76ac113a8e
votes summary improved, message for dead chat 2026-02-03 16:13:15 +00:00
18 changed files with 76 additions and 40 deletions

View File

@ -3050,6 +3050,17 @@ dialog {
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: baseline; justify-content: baseline;
.id {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: baseline;
}
.votes {
margin-left: 1ch;
}
} }
} }
@ -3061,6 +3072,10 @@ dialog {
font-size: 2em; font-size: 2em;
align-items: center; align-items: center;
.clear {
width: 100%;
}
.mode-buttons { .mode-buttons {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -3101,4 +3116,14 @@ dialog {
flex-direction: column; flex-direction: column;
flex-wrap: nowrap; flex-wrap: nowrap;
align-items: center; align-items: center;
min-width: 5cm;
max-width: 9cm;
overflow-x: hidden;
}
.vote-buttons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 1ch;
} }

View File

@ -188,7 +188,10 @@ pub fn Client2(ClientProps { auto_join }: &ClientProps) -> Html {
<Signin callback={on_signin} /> <Signin callback={on_signin} />
}, },
ClientEvent2::GameInProgress => html! { ClientEvent2::GameInProgress => html! {
<CoverOfDarkness message={"game in progress".to_string()}/> <div class="game-in-progress">
<h1>{"game in progress"}</h1>
<h3>{"if you're playing, you can come back when dead for dead chat"}</h3>
</div>
}, },
ClientEvent2::Story(story) => html! { ClientEvent2::Story(story) => html! {
<div class="post-game"> <div class="post-game">
@ -196,11 +199,11 @@ pub fn Client2(ClientProps { auto_join }: &ClientProps) -> Html {
</div> </div>
}, },
ClientEvent2::Sleep => html! { ClientEvent2::Sleep => html! {
<CoverOfDarkness /> <CoverOfDarkness message={"cool. come back when dead.".to_string()}/>
}, },
ClientEvent2::Disconnected => html! { ClientEvent2::Disconnected => html! {
<div class="column-list"> <div class="disconnected">
<p>{"disconnected"}</p> <h1>{"disconnected"}</h1>
</div> </div>
}, },
ClientEvent2::Connecting => { ClientEvent2::Connecting => {

View File

@ -623,7 +623,6 @@ impl Component for Host {
} }
_ => None, _ => None,
}; };
log::info!("voting mode button: {}", voting_mode_btn.is_some());
let nav = self.big_screen.not().then(|| { let nav = self.big_screen.not().then(|| {
html! { html! {
<nav class="host-nav" style="z-index: 3;"> <nav class="host-nav" style="z-index: 3;">

View File

@ -87,18 +87,27 @@ pub fn VotingMode(VotingModeProps { characters }: &VotingModeProps) -> Html {
.map(|(c, v)| { .map(|(c, v)| {
html! { html! {
<li> <li>
<IdentitySpan ident={c.identity.clone().into_public()}/> <span class="id"><IdentitySpan ident={c.identity.clone().into_public()}/>{":"}</span>
{": "} <span class="votes"><span class="red">{*v}</span>{" votes"}</span>
{*v}
{" votes"}
</li> </li>
} }
}) })
.collect::<Html>(); .collect::<Html>();
let on_clear = {
let votes = votes.clone();
move |_| {
let mut v = (*votes).clone();
for (_, v) in v.iter_mut() {
*v = 0;
}
votes.set(v);
}
};
html! { html! {
<div class="character-picker"> <div class="character-picker">
<div class="top-of-day-info"> <div class="top-of-day-info">
<div class="voting-mode"> <div class="voting-mode">
<Button classes={classes!("clear")} on_click={on_clear}>{"clear votes"}</Button>
<span class="red">{"voting mode"}</span> <span class="red">{"voting mode"}</span>
<div class="mode-buttons"> <div class="mode-buttons">
<Button classes={classes!(add)} on_click={set_add}>{"add"}</Button> <Button classes={classes!(add)} on_click={set_add}>{"add"}</Button>
@ -106,7 +115,7 @@ pub fn VotingMode(VotingModeProps { characters }: &VotingModeProps) -> Html {
</div> </div>
</div> </div>
</div> </div>
<div class="player-list"> <div class="vote-buttons">
{buttons} {buttons}
</div> </div>
<ol class="vote-summary"> <ol class="vote-summary">

View File

@ -15,7 +15,7 @@
use werewolves_proto::{message::PublicIdentity, role::Killer}; use werewolves_proto::{message::PublicIdentity, role::Killer};
use yew::prelude::*; use yew::prelude::*;
use crate::components::{Icon, IconSource, IdentitySpan}; use crate::components::{Icon, IconSource, IconType, IdentitySpan};
#[function_component] #[function_component]
pub fn AdjudicatorPage1() -> Html { pub fn AdjudicatorPage1() -> Html {
@ -24,7 +24,7 @@ pub fn AdjudicatorPage1() -> Html {
<h1 class="defensive">{"ADJUDICATOR"}</h1> <h1 class="defensive">{"ADJUDICATOR"}</h1>
<div class="information defensive faint"> <div class="information defensive faint">
<h4>{"PICK A PLAYER"}</h4> <h4>{"PICK A PLAYER"}</h4>
<Icon source={IconSource::Killer}/> <Icon source={IconSource::Killer} icon_type={IconType::Fit}/>
<h4 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h4> <h4 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h4>
</div> </div>
</div> </div>
@ -48,12 +48,12 @@ pub fn AdjudicatorResult(
let icon = match killer { let icon = match killer {
Killer::Killer => html! { Killer::Killer => html! {
<Icon <Icon
source={IconSource::Killer} source={IconSource::Killer} icon_type={IconType::Fit}
/> />
}, },
Killer::NotKiller => html! { Killer::NotKiller => html! {
<Icon <Icon
source={IconSource::RedX} source={IconSource::RedX} icon_type={IconType::Fit}
/> />
}, },
}; };

View File

@ -26,10 +26,10 @@ pub fn ArcanistPage1() -> Html {
{"PICK TWO PLAYERS"} {"PICK TWO PLAYERS"}
<div class="icons"> <div class="icons">
<Icon source={IconSource::Village} <Icon source={IconSource::Village}
icon_type={IconType::Informational} icon_type={IconType::Fit}
/> />
<Icon source={IconSource::Wolves} <Icon source={IconSource::Wolves}
icon_type={IconType::Informational} icon_type={IconType::Fit}
/> />
</div> </div>
<span class="yellow">{"YOU WILL COMPARE THEIR ALIGNMENTS"}</span> <span class="yellow">{"YOU WILL COMPARE THEIR ALIGNMENTS"}</span>
@ -57,10 +57,10 @@ pub fn ArcanistResult(
}; };
let icons = match alignment_eq { let icons = match alignment_eq {
AlignmentEq::Same => html! { AlignmentEq::Same => html! {
<Icon source={IconSource::Equal} icon_type={IconType::Informational} /> <Icon source={IconSource::Equal} icon_type={IconType::Fit} />
}, },
AlignmentEq::Different => html! { AlignmentEq::Different => html! {
<Icon source={IconSource::NotEqual} icon_type={IconType::Informational} /> <Icon source={IconSource::NotEqual} icon_type={IconType::Fit} />
}, },
}; };
html! { html! {

View File

@ -23,7 +23,7 @@ pub fn BeholderPage1() -> Html {
<h1 class="intel">{"BEHOLDER"}</h1> <h1 class="intel">{"BEHOLDER"}</h1>
<div class="information intel faint"> <div class="information intel faint">
{"PICK A PLAYER"} {"PICK A PLAYER"}
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/> <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/>
{"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"} {"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"}
<span class="yellow">{"SHOULD THEY DIE TONIGHT"}</span> <span class="yellow">{"SHOULD THEY DIE TONIGHT"}</span>
</div> </div>
@ -38,7 +38,7 @@ pub fn BeholderWakePage1() -> Html {
<h1 class="intel">{"BEHOLDER"}</h1> <h1 class="intel">{"BEHOLDER"}</h1>
<div class="information intel faint"> <div class="information intel faint">
{"YOUR TARGET HAS DIED"} {"YOUR TARGET HAS DIED"}
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/> <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/>
<span class="yellow">{"THIS IS THE LAST PIECE OF INFORMATION THEY SAW"}</span> <span class="yellow">{"THIS IS THE LAST PIECE OF INFORMATION THEY SAW"}</span>
</div> </div>
</div> </div>
@ -53,7 +53,7 @@ pub fn BeholderSawNothing() -> Html {
<div class="information intel faint"> <div class="information intel faint">
<h1>{"YOUR TARGET HAS DIED"}</h1> <h1>{"YOUR TARGET HAS DIED"}</h1>
<div class="info-icon-grow"> <div class="info-icon-grow">
<Icon source={IconSource::RedX}/> <Icon source={IconSource::RedX} icon_type={IconType::Fit}/>
</div> </div>
<h1>{"BUT SAW NOTHING"}</h1> <h1>{"BUT SAW NOTHING"}</h1>
</div> </div>
@ -68,7 +68,7 @@ pub fn BeholderSawEverything() -> Html {
<h1 class="intel">{"BEHOLDER"}</h1> <h1 class="intel">{"BEHOLDER"}</h1>
<div class="information intel faint"> <div class="information intel faint">
{"YOUR TARGET HAS DIED"} {"YOUR TARGET HAS DIED"}
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/> <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/>
<span> <span>
{"BUT SAW "} {"BUT SAW "}
<em class="red"> <em class="red">

View File

@ -47,12 +47,12 @@ pub fn EmpathResult(EmpathResultProps { scapegoat, target }: &EmpathResultProps)
let icon = match scapegoat { let icon = match scapegoat {
true => html! { true => html! {
<Icon <Icon
source={IconSource::Scapegoat} icon_type={IconType::Informational} source={IconSource::Scapegoat} icon_type={IconType::Fit}
/> />
}, },
false => html! { false => html! {
<Icon <Icon
source={IconSource::RedX} icon_type={IconType::Informational} source={IconSource::RedX} icon_type={IconType::Fit}
/> />
}, },
}; };

View File

@ -29,7 +29,7 @@ pub fn GravediggerPage1() -> Html {
<span class="yellow">{"DEAD"}</span> <span class="yellow">{"DEAD"}</span>
{" PLAYER"} {" PLAYER"}
</span> </span>
<Icon source={IconSource::Gravedigger} icon_type={IconType::Informational}/> <Icon source={IconSource::Gravedigger} icon_type={IconType::Fit}/>
<span class="yellow"> <span class="yellow">
{"YOU WILL LEARN THEIR ROLE"} {"YOU WILL LEARN THEIR ROLE"}
</span> </span>
@ -74,7 +74,7 @@ pub fn GravediggerResultPage(
<h1 class="intel">{"GRAVEDIGGER"}</h1> <h1 class="intel">{"GRAVEDIGGER"}</h1>
<div class="information intel faint"> <div class="information intel faint">
<IdentitySpan ident={target.clone()}/> <IdentitySpan ident={target.clone()}/>
<Icon source={icon} icon_type={IconType::Informational}/> <Icon source={icon} icon_type={IconType::Fit}/>
{text} {text}
</div> </div>
</div> </div>

View File

@ -90,7 +90,7 @@ pub fn GuardianPagePreviousGuard(GuardianPageProps { previous }: &GuardianPagePr
<h1 class="defensive">{"GUARDIAN"}</h1> <h1 class="defensive">{"GUARDIAN"}</h1>
<div class="information defensive faint"> <div class="information defensive faint">
{"LAST TIME YOU GUARDED"} {"LAST TIME YOU GUARDED"}
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/> <Icon source={IconSource::ShieldAndSword} icon_type={IconType::Fit}/>
<div class="info-player-list"> <div class="info-player-list">
<CharacterTargetCard ident={previous.clone()} /> <CharacterTargetCard ident={previous.clone()} />
</div> </div>

View File

@ -23,7 +23,7 @@ pub fn HunterPage1() -> Html {
<h1 class="offensive">{"HUNTER"}</h1> <h1 class="offensive">{"HUNTER"}</h1>
<div class="information offensive faint"> <div class="information offensive faint">
{"SET A HUNTER'S TRAP ON A PLAYER"} {"SET A HUNTER'S TRAP ON A PLAYER"}
<Icon source={IconSource::Hunter} icon_type={IconType::Informational}/> <Icon source={IconSource::Hunter} icon_type={IconType::Fit}/>
<span class="yellow"> <span class="yellow">
{"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW "} {"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW "}
{"THIS PLAYER WILL DIE AT NIGHT"} {"THIS PLAYER WILL DIE AT NIGHT"}

View File

@ -24,7 +24,7 @@ pub fn InsomniacPage1() -> Html {
<h1 class="intel">{"INSOMNIAC"}</h1> <h1 class="intel">{"INSOMNIAC"}</h1>
<div class="information intel faint"> <div class="information intel faint">
{"YOUR SLEEP IS INTERRUPTED"} {"YOUR SLEEP IS INTERRUPTED"}
<Icon source={IconSource::Insomniac} icon_type={IconType::Informational}/> <Icon source={IconSource::Insomniac} icon_type={IconType::Fit}/>
{"YOU'VE NOTICED VISITORS IN THE NIGHT"} {"YOU'VE NOTICED VISITORS IN THE NIGHT"}
</div> </div>
</div> </div>

View File

@ -27,7 +27,7 @@ pub fn MilitiaPage1() -> Html {
<span class="yellow">{"ONCE PER GAME"}</span> <span class="yellow">{"ONCE PER GAME"}</span>
{" KILL ABILITY"} {" KILL ABILITY"}
</span> </span>
<Icon source={IconSource::Sword} icon_type={IconType::Informational}/> <Icon source={IconSource::Sword} icon_type={IconType::Fit}/>
<span class="yellow"> <span class="yellow">
{"PICK A PLAYER "} {"PICK A PLAYER "}
{"OR GO BACK TO SLEEP"} {"OR GO BACK TO SLEEP"}

View File

@ -24,7 +24,7 @@ pub fn MorticianPage1() -> Html {
<h1 class="intel">{"MORTICIAN"}</h1> <h1 class="intel">{"MORTICIAN"}</h1>
<div class="information intel faint"> <div class="information intel faint">
<span>{"PICK A "}<span class="yellow">{"DEAD"}</span>{" PLAYER"}</span> <span>{"PICK A "}<span class="yellow">{"DEAD"}</span>{" PLAYER"}</span>
<Icon source={IconSource::Mortician} icon_type={IconType::Informational}/> <Icon source={IconSource::Mortician} icon_type={IconType::Fit}/>
<span class="yellow"> <span class="yellow">
{"YOU WILL LEARN THE CAUSE "} {"YOU WILL LEARN THE CAUSE "}
{"OF THEIR DEATH"} {"OF THEIR DEATH"}
@ -66,7 +66,7 @@ pub fn MorticianResultPage(
<div class="information intel faint"> <div class="information intel faint">
<IdentitySpan ident={target.clone()}/> <IdentitySpan ident={target.clone()}/>
{"DIED TO"} {"DIED TO"}
<Icon source={icon} icon_type={IconType::Informational}/> <Icon source={icon} icon_type={IconType::Fit}/>
<span class="yellow">{text}</span> <span class="yellow">{text}</span>
</div> </div>
</div> </div>

View File

@ -16,7 +16,7 @@
use werewolves_proto::{message::PublicIdentity, role::Powerful}; use werewolves_proto::{message::PublicIdentity, role::Powerful};
use yew::prelude::*; use yew::prelude::*;
use crate::components::{Icon, IconSource, IdentitySpan}; use crate::components::{Icon, IconSource, IconType, IdentitySpan};
#[function_component] #[function_component]
pub fn PowerSeerPage1() -> Html { pub fn PowerSeerPage1() -> Html {
@ -26,7 +26,7 @@ pub fn PowerSeerPage1() -> Html {
<div class="information intel faint"> <div class="information intel faint">
{"PICK A PLAYER"} {"PICK A PLAYER"}
<div class="info-icon-grow"> <div class="info-icon-grow">
<Icon source={IconSource::Powerful} /> <Icon source={IconSource::Powerful} icon_type={IconType::Fit}/>
</div> </div>
<span class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</span> <span class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</span>
</div> </div>
@ -49,12 +49,12 @@ pub fn PowerSeerResult(PowerSeerResultProps { powerful, target }: &PowerSeerResu
let icon = match powerful { let icon = match powerful {
Powerful::Powerful => html! { Powerful::Powerful => html! {
<Icon <Icon
source={IconSource::Powerful} source={IconSource::Powerful} icon_type={IconType::Fit}
/> />
}, },
Powerful::NotPowerful => html! { Powerful::NotPowerful => html! {
<Icon <Icon
source={IconSource::RedX} source={IconSource::RedX} icon_type={IconType::Fit}
/> />
}, },
}; };

View File

@ -23,7 +23,7 @@ pub fn ProtectorPage1() -> Html {
<h1 class="defensive">{"PROTECTOR"}</h1> <h1 class="defensive">{"PROTECTOR"}</h1>
<div class="information defensive faint"> <div class="information defensive faint">
{"PICK A PLAYER"} {"PICK A PLAYER"}
<Icon source={IconSource::Shield} icon_type={IconType::Informational}/> <Icon source={IconSource::Shield} icon_type={IconType::Fit}/>
<span class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</span> <span class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</span>
</div> </div>
</div> </div>

View File

@ -23,7 +23,7 @@ pub fn PyremasterPage1() -> Html {
<h1 class="offensive">{"PYREMASTER"}</h1> <h1 class="offensive">{"PYREMASTER"}</h1>
<div class="information offensive faint"> <div class="information offensive faint">
{"YOU CAN CHOOSE TO THROW A PLAYER ON THE PYRE"} {"YOU CAN CHOOSE TO THROW A PLAYER ON THE PYRE"}
<Icon source={IconSource::Pyremaster} icon_type={IconType::Informational}/> <Icon source={IconSource::Pyremaster} icon_type={IconType::Fit}/>
<span> <span>
{"IF YOU KILL "} {"IF YOU KILL "}
<span class="yellow">{"TWO"}</span> <span class="yellow">{"TWO"}</span>

View File

@ -30,8 +30,8 @@ pub fn SeerPage1() -> Html {
<div class="information intel faint"> <div class="information intel faint">
{"PICK A PLAYER"} {"PICK A PLAYER"}
<div class="icons"> <div class="icons">
<Icon source={IconSource::Village} icon_type={IconType::Informational} /> <Icon source={IconSource::Village} icon_type={IconType::Fit} />
<Icon source={IconSource::Wolves} icon_type={IconType::Informational} /> <Icon source={IconSource::Wolves} icon_type={IconType::Fit} />
</div> </div>
<span class="yellow">{"YOU WILL CHECK THEIR ALIGNMENT"}</span> <span class="yellow">{"YOU WILL CHECK THEIR ALIGNMENT"}</span>
</div> </div>