Format long listen times in days and center the pin dot

This commit is contained in:
2026-06-09 20:35:40 +01:00
parent 8dd316f6ae
commit f6e1a6d4ea

View File

@@ -51,24 +51,44 @@ const MIN_BAR_WIDTH: usize = 8;
/// Format a duration in seconds into a human-readable string.
///
/// Once the duration reaches a full day it is reported in days and hours
/// (minutes are dropped, with the leftover hour rounded to the nearest hour).
///
/// Examples:
/// - 45 seconds → "45s"
/// - 120 seconds → "2m"
/// - 3660 seconds → "1h 01m"
/// - 0 seconds → "0s"
/// - 90000 secs → "1d 1h"
/// - 86400 secs → "1d"
pub fn format_duration(secs: i64) -> String {
const HOUR: i64 = 3600;
const DAY: i64 = 86400;
if secs < 60 {
format!("{}s", secs)
} else if secs < 3600 {
} else if secs < HOUR {
format!("{}m", secs / 60)
} else {
let hours = secs / 3600;
let mins = (secs % 3600) / 60;
} else if secs < DAY {
let hours = secs / HOUR;
let mins = (secs % HOUR) / 60;
if mins == 0 {
format!("{}h", hours)
} else {
format!("{}h {:02}m", hours, mins)
}
} else {
let mut days = secs / DAY;
// Round the leftover hours to the nearest hour, carrying into days.
let mut hours = (secs % DAY + HOUR / 2) / HOUR;
if hours == 24 {
days += 1;
hours = 0;
}
if hours == 0 {
format!("{}d", days)
} else {
format!("{}d {}h", days, hours)
}
}
}
@@ -1333,8 +1353,9 @@ tr:last-child td { border-bottom: none; }
color: #a99984;
background: linear-gradient(135deg, #17130d, #2c2116); font-size: 12px; }
.pin-dot { position: absolute; top: 5px; right: 5px; width: 22px; height: 22px;
border-radius: 50%; background: rgba(0,0,0,0.45); border: none;
cursor: pointer; font-size: 12px; line-height: 22px; text-align: center;
border-radius: 50%; background: rgba(0,0,0,0.45); border: none; padding: 0;
cursor: pointer; font-size: 12px; line-height: 1;
display: flex; align-items: center; justify-content: center;
opacity: 0; transition: opacity 0.15s; z-index: 1; }
.album:hover .pin-dot { opacity: 1; }
.pin-dot:hover { background: rgba(0,0,0,0.75); }
@@ -1752,6 +1773,16 @@ mod tests {
assert_eq!(format_duration(0), "0s");
}
#[test]
fn test_format_duration_days() {
assert_eq!(format_duration(86400), "1d");
assert_eq!(format_duration(90000), "1d 1h");
// 1d 5h 40m rounds up to 1d 6h.
assert_eq!(format_duration(106800), "1d 6h");
// Leftover hours rounding up to 24 carries into the next day.
assert_eq!(format_duration(172799), "2d");
}
#[test]
fn test_format_play_count() {
assert_eq!(format_play_count(0), "0 plays");