improve design in some areas

This commit is contained in:
Julian Chang 2026-10-01 01:35:20 -04:00
parent 67cfc4eb83
commit b86080ac62
No known key found for this signature in database
9 changed files with 65 additions and 181 deletions

View file

@ -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,

View file

@ -898,19 +898,3 @@ pub(crate) fn pill(icon: Option<Element>, 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()
}

View file

@ -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
}),

View file

@ -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,
}

View file

@ -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 {

View file

@ -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()),

View file

@ -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<GameLoader>) -> 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>) -> Element {
fn rows_list(rows: Vec<Element>) -> 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()

View file

@ -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.",
),
];

View file

@ -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<Element> = shown_lines