progress bars

This commit is contained in:
Connor Johnstone
2026-03-25 15:20:12 -04:00
parent a893a84f16
commit 1a478dea8e
3 changed files with 99 additions and 33 deletions
+37 -13
View File
@@ -383,6 +383,35 @@ pub fn artist_page(props: &Props) -> Html {
let tc = album.track_count;
// Progress bar styles
let owned_pct = if tc > 0 {
(album.owned_tracks as f64 / tc as f64 * 100.0) as u32
} else {
0
};
let owned_color = if album.owned_tracks >= tc && tc > 0 {
"var(--success)"
} else if album.owned_tracks > 0 {
"var(--warning)"
} else {
"var(--text-muted)"
};
let owned_bar_style =
format!("width:{owned_pct}%;background:{owned_color};");
let watched_pct = if tc > 0 {
(album.watched_tracks as f64 / tc as f64 * 100.0) as u32
} else {
0
};
let watched_color = if album.watched_tracks > 0 {
"var(--accent)"
} else {
"var(--text-muted)"
};
let watched_bar_style =
format!("width:{watched_pct}%;background:{watched_color};");
// Watch/Unwatch buttons for albums — show both when partially watched
let is_fully_owned = album.status == "owned";
let is_album_watched = album.status != "unwatched";
@@ -473,23 +502,18 @@ pub fn artist_page(props: &Props) -> Html {
<td class="text-muted">{ album.date.as_deref().unwrap_or("") }</td>
<td>
if tc > 0 {
<span class="text-sm" style={
if album.owned_tracks >= tc { "color: var(--success);" }
else if album.owned_tracks > 0 { "color: var(--warning);" }
else { "color: var(--text-muted);" }
}>
{ format!("{}/{}", album.owned_tracks, tc) }
</span>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" style={owned_bar_style}></div>
<span class="progress-bar-text">{ format!("{}/{}", album.owned_tracks, tc) }</span>
</div>
}
</td>
<td>
if tc > 0 {
<span class="text-sm" style={
if album.watched_tracks > 0 { "color: var(--accent);" }
else { "color: var(--text-muted);" }
}>
{ format!("{}/{}", album.watched_tracks, tc) }
</span>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" style={watched_bar_style}></div>
<span class="progress-bar-text">{ format!("{}/{}", album.watched_tracks, tc) }</span>
</div>
}
</td>
<td>{ watch_btn }</td>
+31 -19
View File
@@ -57,7 +57,6 @@ pub fn library_page() -> Html {
<th>{ "Monitored" }</th>
<th>{ "Owned" }</th>
<th>{ "Watched" }</th>
<th>{ "Tracks" }</th>
<th></th>
</tr>
</thead>
@@ -134,6 +133,29 @@ pub fn library_page() -> Html {
})
};
// Pre-compute progress bar styles
let owned_pct = if a.total_watched > 0 {
(a.total_owned as f64 / a.total_watched as f64 * 100.0) as u32
} else {
0
};
let owned_color = if a.total_owned >= a.total_watched && a.total_watched > 0 {
"var(--success)"
} else if a.total_owned > 0 {
"var(--warning)"
} else {
"var(--text-muted)"
};
let owned_bar_style = format!("width:{owned_pct}%;background:{owned_color};");
let watched_pct = if a.total_items > 0 {
(a.total_watched as f64 / a.total_items as f64 * 100.0) as u32
} else {
0
};
let watched_color = if a.total_watched > 0 { "var(--accent)" } else { "var(--text-muted)" };
let watched_bar_style = format!("width:{watched_pct}%;background:{watched_color};");
html! {
<tr>
<td>
@@ -148,32 +170,22 @@ pub fn library_page() -> Html {
</td>
if a.enriched {
<td>
<span class="text-sm" style={
if a.total_owned >= a.total_watched && a.total_watched > 0 { "color: var(--success);" }
else if a.total_owned > 0 { "color: var(--warning);" }
else { "color: var(--text-muted);" }
}>
{ format!("{}/{}", a.total_owned, a.total_watched) }
</span>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" style={owned_bar_style.clone()}></div>
<span class="progress-bar-text">{ format!("{}/{}", a.total_owned, a.total_watched) }</span>
</div>
</td>
<td>
<span class="text-sm" style={
if a.total_watched > 0 { "color: var(--accent);" }
else { "color: var(--text-muted);" }
}>
{ format!("{}/{}", a.total_watched, a.total_items) }
</span>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" style={watched_bar_style.clone()}></div>
<span class="progress-bar-text">{ format!("{}/{}", a.total_watched, a.total_items) }</span>
</div>
</td>
} else {
<td colspan="2" class="text-sm text-muted loading">
{ "Awaiting artist enrichment..." }
</td>
}
<td class="text-muted text-sm">
if a.enriched && a.total_items > 0 {
{ a.total_items }
}
</td>
<td class="actions">
<button class="btn btn-sm btn-lib"
onclick={on_watch}