Format long listen times in days and center the pin dot
This commit is contained in:
@@ -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"
|
||||
/// - 45 seconds → "45s"
|
||||
/// - 120 seconds → "2m"
|
||||
/// - 3660 seconds → "1h 01m"
|
||||
/// - 0 seconds → "0s"
|
||||
/// - 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");
|
||||
|
||||
Reference in New Issue
Block a user