feat: improved stats screen (#888)

This commit is contained in:
LynithDev 2026-09-29 20:31:42 +02:00 • committed by GitHub
parent 55125b551f
commit ef5847f417
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 77 deletions

View file

@ -11,10 +11,6 @@ pub fn page_elevated() -> Color {
Color::from_rgb(21, 28, 34)
}
pub fn page_overlay() -> Color {
Color::from_argb(140, 17, 23, 28)
}
pub fn fg_primary() -> Color {
Color::from_rgb(213, 219, 255)
}

View file

@ -47,63 +47,35 @@ fn analytics_body_inner(analytics: &Analytics, force_all: bool) -> Element {
}
pub fn analytics_placeholder(note: &str) -> Element {
AnalyticsPlaceholder {
note: note.to_string(),
}
.into_element()
}
#[derive(PartialEq)]
struct AnalyticsPlaceholder {
note: String,
}
impl Component for AnalyticsPlaceholder {
fn render(&self) -> impl IntoElement {
let mut body_height = use_state(|| 0f32);
let scrim_height = *body_height.read();
rect()
.width(Size::fill())
.child(
rect()
.width(Size::fill())
.on_sized(move |e: Event<SizedEventData>| {
let height = e.area.height();
if (*body_height.read() - height).abs() > 0.5 {
body_height.set(height);
}
})
.child(analytics_body_inner(&empty_analytics(), true)),
)
.child(
rect()
.position(Position::new_absolute())
.width(Size::fill())
.height(Size::px(scrim_height))
.layer(Layer::Relative(1))
.center()
.padding(40.)
.background(colors::page_overlay())
.on_press(|_| {})
.child(
rect()
.max_width(Size::px(360.))
.padding(Gaps::new_symmetric(16., 24.))
.corner_radius(CornerRadius::new_all(12.))
.background(colors::page_elevated())
.border(border_all_color(1., colors::component_border()))
.center()
.child(
label()
.text(self.note.clone())
.font_size(14.)
.text_align(TextAlign::Center)
.color(colors::fg_secondary()),
),
),
)
}
rect()
.vertical()
.width(Size::fill())
.spacing(24.)
.child(
rect()
.width(Size::fill())
.padding(Gaps::new_symmetric(16., 24.))
.corner_radius(CornerRadius::new_all(12.))
.background(colors::page_elevated())
.border(border_all_color(1., colors::component_border()))
.center()
.child(
label()
.text(note.to_string())
.width(Size::fill())
.font_size(14.)
.text_align(TextAlign::Center)
.color(colors::fg_secondary()),
),
)
.child(
rect()
.width(Size::fill())
.opacity(0.4)
.interactive(false)
.child(analytics_body_inner(&empty_analytics(), true)),
)
.into_element()
}
/// A run of zero-second days ending today so the timeline still renders columns for each range

View file

@ -122,12 +122,12 @@ impl Component for ServersSection {
.unit(m.unit())
.hovered(hovered),
)
.child(rect().width(Size::flex(1.0)).child(legend(
&values,
&labels,
*hovered.read(),
m.unit(),
))),
.child(
rect()
.width(Size::flex(1.0))
.max_width(Size::px(420.))
.child(legend(&values, &labels, *hovered.read(), m.unit())),
),
)
.maybe_child(show_all.read().then(|| {
OverlayPopup::new()

View file

@ -28,7 +28,11 @@ struct TilesRow {
impl Component for TilesRow {
fn render(&self) -> impl IntoElement {
let width = use_state(|| 0f32);
let cols = columns_for(*width.read(), TILE_MIN_W, 4, TILE_GAP);
let w = *width.read();
let cols = match columns_for(w, TILE_MIN_W, 4, TILE_GAP) {
3 => 2,
n => n,
};
let stats = &self.analytics.playtime;
let avg_session = if stats.session_count > 0 {
@ -81,18 +85,19 @@ impl Component for TilesRow {
if cols >= 3 {
let alongside: Vec<Element> = rest.drain(..(cols - 2).min(rest.len())).collect();
let col_w = (w - TILE_GAP * (cols - 1) as f32) / cols as f32;
let hero_w = if col_w > 0. {
Size::px(col_w * 2. + TILE_GAP)
} else {
Size::flex(2.0)
};
let mut lead = rect()
.horizontal()
.content(Content::Flex)
.width(Size::fill())
.height(Size::px(TILE_H))
.spacing(TILE_GAP)
.child(
rect()
.width(Size::flex(2.0))
.height(Size::fill())
.child(hero),
);
.child(rect().width(hero_w).height(Size::fill()).child(hero));
for tile in alongside {
lead = lead.child(
rect()
@ -145,8 +150,7 @@ fn hero_tile(icon: IconType, caption: &str, value: String, note: String) -> Elem
card()
.width(Size::fill())
.height(Size::fill())
.padding(Gaps::new_symmetric(16., 20.))
.spacing(10.)
.main_align(Alignment::SpaceBetween)
.background(colors::brand().with_a(18))
.border(border_all_color(1., colors::brand().with_a(90)))
.child(
@ -193,7 +197,7 @@ fn stat_tile(icon: IconType, caption: &str, value: String) -> Element {
card()
.width(Size::fill())
.height(Size::fill())
.spacing(10.)
.main_align(Alignment::SpaceBetween)
.child(
rect()
.horizontal()