From b86080ac62d8d34a0a783fc792a493a7d0c89501 Mon Sep 17 00:00:00 2001 From: Julian Chang Date: Thu, 1 Oct 2026 01:35:20 -0400 Subject: [PATCH] improve design in some areas --- packages/oneclient_app/src/components/mod.rs | 4 +- .../src/components/package_row.rs | 16 -- .../oneclient_app/src/components/tab_bar.rs | 2 +- .../src/view/app/clusters/instance/cards.rs | 56 +++---- .../src/view/app/clusters/instance/create.rs | 2 +- .../src/view/app/clusters/instance/edit.rs | 1 - .../src/view/app/clusters/instance/rail.rs | 137 ++++-------------- .../src/view/app/clusters/instance/steps.rs | 14 +- .../src/view/app/clusters/page.rs | 14 +- 9 files changed, 65 insertions(+), 181 deletions(-) diff --git a/packages/oneclient_app/src/components/mod.rs b/packages/oneclient_app/src/components/mod.rs index e055899e..2317c6b6 100644 --- a/packages/oneclient_app/src/components/mod.rs +++ b/packages/oneclient_app/src/components/mod.rs @@ -97,8 +97,8 @@ pub use overlay_popup::{OVERLAY_BASE_LEVEL, OVERLAY_MAX_LEVEL, OverlayPopup, ove pub use package_delete_dialog::use_shared_delete; pub(crate) use package_row::{ CARD_BG, CARD_GRID_H, CARD_H, CARD_NAME, GRID_GAP, GRID_MIN_W, badge, disable_warning_body, - filled_pill, grid_card, icon_box, kebab_button, meta_size, meta_text, on_secondary, - package_icon, pill, remote_icon, toggle_action, + grid_card, icon_box, kebab_button, meta_size, meta_text, on_secondary, package_icon, pill, + remote_icon, toggle_action, }; pub use package_row::{ CardLayout, PackageEntry, PackageRow, github_badge, package_context_menu, provider_badge, diff --git a/packages/oneclient_app/src/components/package_row.rs b/packages/oneclient_app/src/components/package_row.rs index e50770ac..add8bb26 100644 --- a/packages/oneclient_app/src/components/package_row.rs +++ b/packages/oneclient_app/src/components/package_row.rs @@ -898,19 +898,3 @@ pub(crate) fn pill(icon: Option, text: String, accent: Color) -> Elemen ) .into_element() } - -pub(crate) fn filled_pill(text: String, background: Color, foreground: Color) -> Element { - rect() - .padding(Gaps::new_symmetric(2., 8.)) - .corner_radius(CornerRadius::new_all(6.)) - .background(background) - .child( - label() - .text(text) - .font_size(10.) - .font_weight(FontWeight::SEMI_BOLD) - .letter_spacing(1.) - .color(foreground), - ) - .into_element() -} diff --git a/packages/oneclient_app/src/components/tab_bar.rs b/packages/oneclient_app/src/components/tab_bar.rs index c761e612..4c0739b2 100644 --- a/packages/oneclient_app/src/components/tab_bar.rs +++ b/packages/oneclient_app/src/components/tab_bar.rs @@ -230,7 +230,7 @@ impl Component for TabButton { .margin(Gaps::new_symmetric(0., 4.0)) .corner_radius(CornerRadius::new_all(2.)) .background(if underline_on { - colors::brand() + colors::fg_primary() } else { Color::TRANSPARENT }), diff --git a/packages/oneclient_app/src/view/app/clusters/instance/cards.rs b/packages/oneclient_app/src/view/app/clusters/instance/cards.rs index 73c8826d..e64cebc6 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/cards.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/cards.rs @@ -2,7 +2,7 @@ use freya::prelude::*; use super::model::{LoaderChoice, VersionRow}; use crate::AppAssets; -use crate::components::{AssetImage, Icon, IconType, filled_pill, pill}; +use crate::components::{AssetImage, Icon, IconType, pill}; use crate::theme::colors; use crate::ui::border_all_color; @@ -181,36 +181,24 @@ pub fn wide_card(card: WideCard) -> Element { .horizontal() .width(Size::fill()) .content(Content::Flex) - .cross_align(Alignment::Start) - .spacing(16.) - .child( - rect() - .width(Size::px(44.)) - .height(Size::px(44.)) - .center() - .corner_radius(CornerRadius::new_all(10.)) - .background(if selected { - colors::brand() - } else { - colors::page_elevated() - }) - .border(border_all_color(1., colors::component_border())) - .child(Icon::new(icon).size(22.).color(if selected { - Color::WHITE - } else { - colors::fg_primary() - })), - ) + .cross_align(Alignment::Center) + .spacing(14.) + .child(marker(selected, false)) + .child(Icon::new(icon).size(20.).color(if selected { + colors::fg_primary() + } else { + colors::fg_secondary() + })) .child( rect() .vertical() .width(Size::flex(1.0)) - .spacing(7.) + .spacing(2.) .child( rect() .horizontal() .cross_align(Alignment::Center) - .spacing(10.) + .spacing(8.) .child( label() .text(title) @@ -218,32 +206,28 @@ pub fn wide_card(card: WideCard) -> Element { .font_weight(FontWeight::MEDIUM) .color(colors::fg_primary()), ) - .maybe_child( - badge.map(|badge| filled_pill(badge, colors::brand(), Color::WHITE)), - ), + .maybe_child(badge.map(|badge| { + label() + .text(badge) + .font_size(12.) + .color(colors::fg_secondary()) + })), ) .child( label() - .text(blurb) - .font_size(12.) + .text(format!("{blurb} {meta}")) + .font_size(13.) .line_height(1.45) .color(colors::fg_secondary()), - ) - .child( - label() - .text(meta) - .font_size(11.) - .color(colors::fg_secondary()), ), ) - .child(marker(selected, false)) .into_element(); SelectCard { id: title_id, selected, height: None, - padding: Gaps::new_all(16.), + padding: Gaps::new_symmetric(16., 18.), content, on_press, } diff --git a/packages/oneclient_app/src/view/app/clusters/instance/create.rs b/packages/oneclient_app/src/view/app/clusters/instance/create.rs index 41858c5d..1efec3df 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/create.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/create.rs @@ -98,7 +98,7 @@ fn wizard_rail(wizard: Wizard, picks: &Picks) -> Element { art, title, subtitle, - card: steps_card(picks.progress(), rows), + card: steps_card(rows), tags: if picks.step == Step::Customize { tags } else { diff --git a/packages/oneclient_app/src/view/app/clusters/instance/edit.rs b/packages/oneclient_app/src/view/app/clusters/instance/edit.rs index 176728a2..238523c7 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/edit.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/edit.rs @@ -108,7 +108,6 @@ impl Component for EditInstanceModal { title, subtitle, card: facts_card( - "Instance".to_string(), vec![ ("Type", kind_label(self.facts.kind).to_string()), ("Version", self.facts.mc_version.clone()), diff --git a/packages/oneclient_app/src/view/app/clusters/instance/rail.rs b/packages/oneclient_app/src/view/app/clusters/instance/rail.rs index b7b28ec3..892b7992 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/rail.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/rail.rs @@ -3,11 +3,8 @@ use oneclient_common::domain::GameLoader; use oneclient_common::parse_mc_version; use super::shell::RAIL_WIDTH; -use crate::components::{DynamicArt, Icon, IconType}; -use crate::theme::colors; -use crate::ui::border_all_color; +use crate::components::DynamicArt; -const CARD_BG: Color = Color::from_argb(158, 11, 16, 19); const HAIRLINE: Color = Color::from_argb(31, 255, 255, 255); const CHIP_BG: Color = Color::from_argb(26, 255, 255, 255); const SUB: Color = Color::from_argb(184, 213, 219, 255); @@ -35,126 +32,52 @@ pub fn version_art(version: Option<&str>, loader: Option) -> Dynamic } } -pub fn steps_card(progress: String, rows: Vec<(&'static str, String, RowState)>) -> Element { - card( - progress, +pub fn steps_card(rows: Vec<(&'static str, String, RowState)>) -> Element { + rows_list( rows.into_iter() - .enumerate() - .map(|(index, (name, value, state))| step_row(index, name, &value, state)) + .map(|(name, value, state)| { + let name_color = match state { + RowState::Current => Color::WHITE, + RowState::Done => SUB, + RowState::Pending => MUTED, + }; + row(name, &value, name_color) + }) .collect(), ) } -pub fn facts_card(heading: String, rows: Vec<(&'static str, String)>) -> Element { - card( - heading, +pub fn facts_card(rows: Vec<(&'static str, String)>) -> Element { + rows_list( rows.into_iter() - .map(|(name, value)| fact_row(name, &value)) + .map(|(name, value)| row(name, &value, SUB)) .collect(), ) } -fn card(heading: String, rows: Vec) -> Element { +fn rows_list(rows: Vec) -> Element { rect() .vertical() .width(Size::fill()) + .spacing(10.) + .children(rows) + .into_element() +} + +fn row(name: &'static str, value: &str, name_color: Color) -> Element { + rect() + .horizontal() + .width(Size::fill()) + .content(Content::Flex) + .cross_align(Alignment::Center) .spacing(12.) - .child( - label() - .text(heading) - .font_size(11.) - .font_weight(FontWeight::MEDIUM) - .letter_spacing(1.6) - .color(SUB), - ) - .child( - rect() - .vertical() - .width(Size::fill()) - .spacing(10.) - .children(rows), - ) - .into_element() -} - -fn step_row(index: usize, name: &'static str, value: &str, state: RowState) -> Element { - let done = state == RowState::Done; - let now = state == RowState::Current; - - rect() - .horizontal() - .width(Size::fill()) - .content(Content::Flex) - .cross_align(Alignment::Center) - .spacing(11.) - .child( - rect() - .width(Size::px(20.)) - .height(Size::px(20.)) - .center() - .corner_radius(CornerRadius::new_all(6.)) - .background(if done { - colors::brand() - } else { - Color::TRANSPARENT - }) - .border(border_all_color( - 1., - if done || now { - colors::brand() - } else { - HAIRLINE - }, - )) - .child(if done { - Icon::new(IconType::Check) - .size(12.) - .color(Color::WHITE) - .into_element() - } else { - label() - .text((index + 1).to_string()) - .font_size(11.) - .font_weight(FontWeight::MEDIUM) - .color(if now { Color::WHITE } else { MUTED }) - .into_element() - }), - ) .child( label() .text(name) .width(Size::px(76.)) - .font_size(12.) - .max_lines(1) - .color(if now { Color::WHITE } else { SUB }), - ) - .child( - label() - .text(value.to_string()) - .width(Size::flex(1.0)) .font_size(13.) - .font_weight(FontWeight::MEDIUM) .max_lines(1) - .text_align(TextAlign::Right) - .color(if done { Color::WHITE } else { SUB }), - ) - .into_element() -} - -fn fact_row(name: &'static str, value: &str) -> Element { - rect() - .horizontal() - .width(Size::fill()) - .content(Content::Flex) - .cross_align(Alignment::Center) - .spacing(11.) - .child( - label() - .text(name) - .width(Size::px(76.)) - .font_size(12.) - .max_lines(1) - .color(SUB), + .color(name_color), ) .child( label() @@ -233,11 +156,7 @@ pub fn rail(parts: Rail) -> Element { rect() .vertical() .width(Size::fill()) - .spacing(12.) - .padding(Gaps::new_all(16.)) - .corner_radius(CornerRadius::new_all(12.)) - .background(CARD_BG) - .border(border_all_color(1., HAIRLINE)) + .spacing(14.) .child(card) .maybe_child((!tags.is_empty()).then(|| { rect() diff --git a/packages/oneclient_app/src/view/app/clusters/instance/steps.rs b/packages/oneclient_app/src/view/app/clusters/instance/steps.rs index 7aa0cf4f..382b6cd3 100644 --- a/packages/oneclient_app/src/view/app/clusters/instance/steps.rs +++ b/packages/oneclient_app/src/view/app/clusters/instance/steps.rs @@ -59,25 +59,25 @@ fn type_step(mut wizard: Wizard, picks: &Picks) -> Element { TypeChoice::OneClient, IconType::Rocket02, "OneClient", - Some("RECOMMENDED"), - "Polyfrost's client. OneConfig, the performance stack and cosmetics are wired up, so it is playable the moment it finishes downloading.", - "Shares the game folder, worlds and packs with your other OneClient instances.", + Some("Recommended"), + "Polyfrost's client with OneConfig, performance mods and cosmetics set up.", + "Shares worlds and packs with your other OneClient instances.", ), ( TypeChoice::Scratch, IconType::Sliders04, "Start from scratch", None, - "Pick a loader and a version and build the instance yourself. Packages can be added once it exists.", - "Fabric, Forge, NeoForge, or no loader at all. Keeps its own game folder.", + "Pick a loader and version, then add mods yourself.", + "Has its own game folder.", ), ( TypeChoice::Modpack, IconType::DownloadCloud02, "Modpack", None, - "Install a ready-made pack from Modrinth or CurseForge, or one you already downloaded. Its version, loader, mods and configs come with it.", - "Modrinth .mrpack or CurseForge .zip. Keeps its own game folder.", + "Install a pack from Modrinth or CurseForge, or a file you downloaded.", + "Has its own game folder.", ), ]; diff --git a/packages/oneclient_app/src/view/app/clusters/page.rs b/packages/oneclient_app/src/view/app/clusters/page.rs index e7bff3d9..975e91be 100644 --- a/packages/oneclient_app/src/view/app/clusters/page.rs +++ b/packages/oneclient_app/src/view/app/clusters/page.rs @@ -254,15 +254,13 @@ impl Component for Clusters { shown_lines.is_empty() && shown_custom.is_empty() && shown_packs.is_empty(); let tabs = [ - (Filter::All, "All", lines.len() + instances.len()), - (Filter::OneClient, "OneClient", lines.len()), - (Filter::Custom, "Custom", custom.len()), - (Filter::Modpacks, "Modpacks", packs.len()), + (Filter::All, "All"), + (Filter::OneClient, "OneClient"), + (Filter::Custom, "Custom"), + (Filter::Modpacks, "Modpacks"), ] - .map(|(value, name, count)| { - TabItem::new(name, active_filter == value) - .count_text(count.to_string()) - .on_press(move |_| filter.set(value)) + .map(|(value, name)| { + TabItem::new(name, active_filter == value).on_press(move |_| filter.set(value)) }); let line_cards: Vec = shown_lines