client-side max len for input + number input bugfix

This commit is contained in:
emilis 2025-10-29 23:29:27 +00:00
parent 1751e446f4
commit ee1d3c8b8e
No known key found for this signature in database
6 changed files with 48 additions and 14 deletions

View File

@ -615,7 +615,6 @@ clients {
.role-reveal-cards { .role-reveal-cards {
list-style: none; list-style: none;
// max-width: 80vw;
font-family: 'Cute Font'; font-family: 'Cute Font';
display: flex; display: flex;
@ -623,20 +622,20 @@ clients {
flex-direction: row; flex-direction: row;
justify-content: space-evenly; justify-content: space-evenly;
color: black; color: black;
// align-content: stretch; align-items: center;
// flex: 1 1 0px;
gap: 10px; gap: 10px;
} }
.role-reveal-card { .role-reveal-card {
justify-content: center;
min-width: 5cm; min-width: 5cm;
display: flex; display: flex;
align-items: center; align-items: center;
align-content: center; align-content: center;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
padding: 10px; padding: 1cm;
border: 1px solid $wolves_color; border: 1px solid $wolves_color;
background-color: color.change($wolves_color, $alpha: 0.1); background-color: color.change($wolves_color, $alpha: 0.1);
min-width: 100px; min-width: 100px;
@ -1784,3 +1783,10 @@ input {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
} }
.add-player {
background-color: black;
border: 1px solid white;
padding: 20px;
margin: 0px;
}

View File

@ -135,7 +135,7 @@ impl Connection2 {
.send(Self::encode_message(&ClientMessage::GetState)) .send(Self::encode_message(&ClientMessage::GetState))
.await .await
{ {
log::error!("websocket identification send: {err}"); log::error!("websocket get state send: {err}");
continue 'outer; continue 'outer;
}; };
log::debug!("beginning listening loop"); log::debug!("beginning listening loop");

View File

@ -179,6 +179,8 @@ struct ClickableTextEditProps {
pub on_submit: Callback<String, Option<PublicIdentity>>, pub on_submit: Callback<String, Option<PublicIdentity>>,
pub field_name: &'static str, pub field_name: &'static str,
pub state: UseStateHandle<bool>, pub state: UseStateHandle<bool>,
#[prop_or(100)]
pub max_length: usize,
} }
#[function_component] #[function_component]
@ -190,9 +192,10 @@ fn ClickableTextEdit(
field_name, field_name,
on_submit, on_submit,
state, state,
max_length,
}: &ClickableTextEditProps, }: &ClickableTextEditProps,
) -> Html { ) -> Html {
let on_input = crate::components::input_element_string_oninput(value.setter()); let on_input = crate::components::input_element_string_oninput(value.setter(), *max_length);
let submit_ident = submit_ident.clone(); let submit_ident = submit_ident.clone();
let message_callback = on_submit.clone(); let message_callback = on_submit.clone();
let value = value.clone(); let value = value.clone();

View File

@ -77,7 +77,7 @@ pub fn ClickableNumberEdit(
state, state,
}: &ClickableNumberEditProps, }: &ClickableNumberEditProps,
) -> Html { ) -> Html {
let on_input = crate::components::input_element_string_oninput(value.setter()); let on_input = crate::components::input_element_string_oninput(value.setter(), 20);
let on_submit = on_submit.clone(); let on_submit = on_submit.clone();
let options = html! { let options = html! {

View File

@ -12,6 +12,10 @@ pub fn input_element_number_oninput(num_value: UseStateHandle<String>) -> Callba
return; return;
}; };
let value = target.value(); let value = target.value();
if value.is_empty() {
num_value.set(value);
return;
}
if let Ok(z) = value.trim().parse::<NonZeroU8>() { if let Ok(z) = value.trim().parse::<NonZeroU8>() {
num_value.set(z.to_string()); num_value.set(z.to_string());
} else { } else {
@ -20,10 +24,18 @@ pub fn input_element_number_oninput(num_value: UseStateHandle<String>) -> Callba
}) })
} }
pub fn input_element_string_oninput(value: UseStateSetter<String>) -> Callback<InputEvent> { pub fn input_element_string_oninput(
value: UseStateSetter<String>,
max_len: usize,
) -> Callback<InputEvent> {
Callback::from(move |ev: InputEvent| { Callback::from(move |ev: InputEvent| {
if let Some(target) = ev.target_dyn_into::<HtmlInputElement>() { if let Some(target) = ev.target_dyn_into::<HtmlInputElement>() {
value.set(target.value()); let mut str = target.value();
let char_count = str.chars().count();
if char_count > max_len {
str.truncate(max_len);
}
value.set(str);
} }
}) })
} }

View File

@ -10,7 +10,10 @@ use werewolves_proto::{
}; };
use yew::prelude::*; use yew::prelude::*;
use crate::components::{Button, ClickableField, Identity, client::Signin}; use crate::components::{
Button, ClickableField, Icon, IconSource, IconType, Identity, PartialAssociatedIcon,
client::Signin,
};
#[derive(Debug, PartialEq, Properties)] #[derive(Debug, PartialEq, Properties)]
pub struct SettingsProps { pub struct SettingsProps {
@ -102,10 +105,18 @@ pub fn Settings(
}); });
let class = Into::<SetupRole>::into(r).category().class(); let class = Into::<SetupRole>::into(r).category().class();
let name = r.to_string().to_case(Case::Title); let name = r.to_string().to_case(Case::Title);
// let icon = r.icon().map(|icon| {
// html! {
// <Icon source={icon} icon_type={IconType::Small}/>
// }
// });
html! { html! {
<Button on_click={on_click} classes={classes!(class, "add-role")}> <button
{name} onclick={on_click}
</Button> class={classes!(class, "add-role")}
>
<span>{name}</span>
</button>
} }
}) })
.collect::<Html>(); .collect::<Html>();
@ -253,7 +264,9 @@ pub fn Settings(
let add_player_open = use_state(|| false); let add_player_open = use_state(|| false);
let add_player_opts = html! { let add_player_opts = html! {
<div class="add-player">
<Signin callback={on_add_player.clone()}/> <Signin callback={on_add_player.clone()}/>
</div>
}; };
html! { html! {