Skip to content

Commit 4eb03e3

Browse files
committed
feat(ui): Improve distro name and user display
This commit introduces several improvements to the UI for displaying installed distributions. - Adds a new parser to format the distribution name and version from the internal folder name, making it more readable (e.g., `alpine-edge-rolling` becomes `Alpine (Edge-Rolling)`). - Updates the user display to a more concise format: `(root)` if only root exists, or `(root & username)` for additional users. - Applies the new display format to both the main dashboard list and the launch selection popup. Fixes: - Corrects a compilation error by providing the required radix to `is_digit(10)`.
1 parent e8a3f72 commit 4eb03e3

1 file changed

Lines changed: 64 additions & 3 deletions

File tree

src/ui.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,21 @@ fn render_dashboard(f: &mut Frame, app: &App, area: ratatui::layout::Rect) {
106106
let items: Vec<ListItem> = app.installed_distros
107107
.iter()
108108
.map(|d| {
109-
let user_count = d.users.len().saturating_sub(1);
110-
let desc = format!("{} (Users: root + {})", d.name, user_count);
109+
let (distro_display, version_display) = parse_distro_display_name(&d.name);
110+
111+
let mut display_name = distro_display;
112+
if !version_display.is_empty() {
113+
display_name = format!("{} ({})", display_name, version_display);
114+
}
115+
116+
let user_desc = if d.users.len() > 1 {
117+
let other_users: Vec<&str> = d.users.iter().filter(|&u| u != "root").map(|s| s.as_str()).collect();
118+
format!("(root & {})", other_users.join(", "))
119+
} else {
120+
"(root)".to_string()
121+
};
122+
123+
let desc = format!("{} {}", display_name, user_desc);
111124
ListItem::new(Line::from(vec![
112125
Span::styled("  ", Style::default().fg(Color::Green)),
113126
Span::raw(desc)
@@ -134,9 +147,57 @@ fn render_dashboard(f: &mut Frame, app: &App, area: ratatui::layout::Rect) {
134147
f.render_stateful_widget(list, chunks[1], &mut state);
135148
}
136149

150+
fn parse_distro_display_name(name: &str) -> (String, String) {
151+
let parts: Vec<&str> = name.split('-').collect();
152+
if parts.is_empty() {
153+
return (name.to_string(), "".to_string());
154+
}
155+
156+
let mut unique_parts: Vec<&str> = Vec::new();
157+
for part in parts.iter() {
158+
if unique_parts.is_empty() || unique_parts.last().unwrap() != part {
159+
unique_parts.push(part);
160+
}
161+
}
162+
163+
let mut distro_name_parts: Vec<String> = Vec::new();
164+
let mut version_info_parts: Vec<String> = Vec::new();
165+
let mut version_found = false;
166+
167+
distro_name_parts.push(
168+
unique_parts[0].chars().next().unwrap().to_uppercase().to_string() + &unique_parts[0][1..]
169+
);
170+
171+
for part in &unique_parts[1..] {
172+
let is_version_keyword = *part == "rolling" || *part == "latest" || *part == "edge";
173+
let is_numeric_version = part.chars().any(|c| c.is_digit(10));
174+
175+
if is_version_keyword || is_numeric_version {
176+
version_found = true;
177+
}
178+
179+
if version_found {
180+
version_info_parts.push(
181+
part.chars().next().unwrap().to_uppercase().to_string() + &part[1..]
182+
);
183+
} else {
184+
distro_name_parts.push(
185+
part.chars().next().unwrap().to_uppercase().to_string() + &part[1..]
186+
);
187+
}
188+
}
189+
190+
(distro_name_parts.join(" "), version_info_parts.join("-"))
191+
}
192+
137193
fn render_launch_select(f: &mut Frame, app: &App) {
138194
let distro = &app.installed_distros[app.selected_installed_index];
139-
let title = format!(" Launch: {} ", distro.name);
195+
let (distro_display, version_display) = parse_distro_display_name(&distro.name);
196+
let mut display_name = distro_display;
197+
if !version_display.is_empty() {
198+
display_name = format!("{} ({})", display_name, version_display);
199+
}
200+
let title = format!(" Launch: {} ", display_name);
140201
let instruction = "Select user to login:";
141202

142203
let items: Vec<ListItem> = distro.users.iter().map(|u| {

0 commit comments

Comments
 (0)