sidebar part 1: character image, name, class, level, xp, hp
This commit is contained in:
1 parent
9c211d46de
commit
37f2232af1
4 files changed
+300
-14
No files matched your search
+100
-3
@@ -1,12 +1,109 @@
|
||||
use crate::prelude::*;
|
||||
use leptos::prelude::*;
|
||||
|
||||
use crate::{entities::{DashboardStoreFields, NameStoreFields, PlayerDataStoreFields}, prelude::*};
|
||||
use leptos::{attr::Target, ev::{Event, Targeted}, html, logging, prelude::*};
|
||||
use leptos::web_sys::HtmlInputElement;
|
||||
|
||||
#[component]
|
||||
pub fn Sidebar () -> impl IntoView {
|
||||
let state = expect_context::<Context>();
|
||||
|
||||
let player = state.player();
|
||||
let name = player.name();
|
||||
|
||||
let first = name.first();
|
||||
let last = name.last();
|
||||
let alias = name.alias();
|
||||
|
||||
let name_input_class = "header-input header-input-3";
|
||||
|
||||
let class = player.class();
|
||||
let level = player.level();
|
||||
let xp = player.xp();
|
||||
|
||||
let hp = player.hp();
|
||||
let max_hp = player.max_hp();
|
||||
let temp_hp = player.temp_hp();
|
||||
|
||||
let image = player.image();
|
||||
|
||||
let adjust_level = move |adjustment: i8| level.update(|l| {
|
||||
if let Some(new) = l.checked_add_signed(adjustment) {
|
||||
*l = new;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let adjust_xp = move |ev: Targeted<Event, HtmlInputElement>| {
|
||||
utils::adjust_checked(ev, xp);
|
||||
};
|
||||
|
||||
let adjust_hp = move |ev: Targeted<Event, HtmlInputElement>| {
|
||||
utils::adjust_checked(ev, hp);
|
||||
};
|
||||
|
||||
let adjust_max_hp = move |ev: Targeted<Event, HtmlInputElement>| {
|
||||
utils::adjust_checked(ev, max_hp);
|
||||
};
|
||||
|
||||
let adjust_temp_hp = move |ev: Targeted<Event, HtmlInputElement>| {
|
||||
utils::adjust_checked(ev, temp_hp);
|
||||
};
|
||||
|
||||
|
||||
let pc_hp = move |a: u16, b: u16| {
|
||||
format!("width: {}%", utils::filled_pc(a, b).min(100.))
|
||||
};
|
||||
|
||||
view! {
|
||||
<aside>
|
||||
sidebar
|
||||
<Show when=move || !image.get().is_empty() >
|
||||
<div class="character-image">
|
||||
<img src=image.get() />
|
||||
</div>
|
||||
</Show>
|
||||
<div class="names">
|
||||
<input id="first-name" type="text" class=name_input_class bind:value=first />
|
||||
<div class="alias-field">
|
||||
"«"
|
||||
<input id="alias" type="text" class=name_input_class bind:value=alias/>
|
||||
"»"
|
||||
</div>
|
||||
<input id="last-name" type="text" class=name_input_class bind:value=last />
|
||||
</div>
|
||||
<div class="about">
|
||||
<div class="class">
|
||||
<input id="class" type="text" class="header-input" bind:value=class/>
|
||||
</div>
|
||||
<div class="level">
|
||||
{move || level.get()}
|
||||
<span> уровня</span>
|
||||
</div>
|
||||
<div class="level-adjust">
|
||||
<button title="Уменьшить уровень" on:click=move |_| adjust_level(-1)>-</button>
|
||||
<button title="Увеличить уровень" on:click=move |_| adjust_level( 1)>+</button>
|
||||
</div>
|
||||
<div class="xp">
|
||||
<input id="xp" type="number" class="header-input" on:input:target=move |e| adjust_xp(e) prop:value=move || xp.get() />
|
||||
<span> XP</span>
|
||||
</div>
|
||||
</div>
|
||||
<h6>hp/оз:</h6>
|
||||
<div class="hp">
|
||||
<div class="perm">
|
||||
<div style=move || pc_hp(hp.get(), max_hp.get()) class="bar"></div>
|
||||
<div class="val">
|
||||
<input title="Текущее количество хитпойнтов" id="current_hp" type="number" class="header-input" on:input:target=move |e| adjust_hp(e) prop:value=move || hp.get() />
|
||||
"/"
|
||||
<input title="Максимальное количество хитпойнтов" id="max_hp" type="number" class="header-input" on:input:target=move |e| adjust_max_hp(e) prop:value=move || max_hp.get() />
|
||||
</div>
|
||||
</div>
|
||||
<div class="temp">
|
||||
<div style=move || pc_hp(temp_hp.get(), 10) class="bar"></div>
|
||||
<div class="val">
|
||||
<input title="Временные хитпойнты" id="temp_hp" type="number" class="header-input" on:input:target=move |e| adjust_temp_hp(e) prop:value=move || temp_hp.get() />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
use crate::prelude::*;
|
||||
use std::str::FromStr;
|
||||
use leptos::ev::{ Event, Targeted };
|
||||
use leptos::web_sys::HtmlInputElement;
|
||||
use leptos::reactive::traits::{ Get, Set };
|
||||
|
||||
|
||||
pub fn read_items (contents: &str, map: &mut HashMap<String, Item>) -> usize {
|
||||
@@ -19,3 +23,24 @@ pub fn read_items (contents: &str, map: &mut HashMap<String, Item>) -> usize {
|
||||
|
||||
map.len() - start
|
||||
}
|
||||
|
||||
pub fn adjust_checked <T, U> (ev: Targeted<Event, HtmlInputElement>, store: U) -> ()
|
||||
where
|
||||
U: Set<Value = T> + Get<Value = T>,
|
||||
T: FromStr + ToString
|
||||
{
|
||||
let target = ev.target();
|
||||
let val = target.value();
|
||||
|
||||
if let Ok(val) = val.parse::<T>() {
|
||||
store.set(val);
|
||||
} else {
|
||||
target.set_value(&store.get().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filled_pc <T> (cur: T, max: T) -> f32 where T: Into<f32> {
|
||||
let cur: f32 = cur.into();
|
||||
let max: f32 = max.into();
|
||||
cur / max * 100.
|
||||
}
|
||||
Reference in new issue
Block a user