Show BPM (left) and track length (right) at 2x, above the progress bar
New track_length ("M:SS" from duration) and bpm ("N bpm", rounded)
formatted fields on the now-playing fetch. 2x only, tied to the
progress bar's own presence (both come from data that's only
meaningful on a long-lived server -- see _track_progress's own
comment), since the row is meant to sit directly above it rather than
float with nothing below it.
Right-aligns track_length via a computed left Padding/spacer Box (same
estimated-width approach already used for time_temp's centering), not
render.Row(expanded=True, main_align="space_between") -- that pattern
already caused a real bug once this session (the time_temp centering
fix): `expanded` on a Row grabs extra *vertical* space from the
enclosing Column (main_align="space_between"), pushing the progress
bar out of view. Caught this before it shipped by pixel-sampling the
bottom rows and confirming the progress bar's exact "bar_empty" color
is still present where expected, not just eyeballing the render.
Verified: renders between time_temp and the progress bar at 2x ("136
bpm" / "6:45"), 1x unaffected (no new row, unchanged layout).
This commit is contained in:
1 parent
c1b4cf2118
commit
eaaded770d
1 file changed
+44
@@ -356,6 +356,34 @@ def main(config):
|
|||||||
] + show_lines + [time_temp_line]
|
] + show_lines + [time_temp_line]
|
||||||
|
|
||||||
children = [render.Column(children = top_lines)]
|
children = [render.Column(children = top_lines)]
|
||||||
|
|
||||||
|
# BPM (left) / track length (right), 2x only -- same reasoning as the
|
||||||
|
# other 2x-only additions above: no spare row for it at 1x's tighter
|
||||||
|
# layout. Tied to the progress bar's own presence (both come from
|
||||||
|
# _track_progress/duration data that's only meaningful on a
|
||||||
|
# long-lived server, not a one-shot CLI render -- see _track_progress's
|
||||||
|
# own comment), since it's meant to sit directly above it, not float
|
||||||
|
# on its own if there's nothing below it.
|
||||||
|
#
|
||||||
|
# Right-aligns track_length via a computed left Padding (same
|
||||||
|
# estimated-width approach as time_temp's centering), not
|
||||||
|
# render.Row(expanded=True, main_align="space_between") -- that
|
||||||
|
# pattern already caused a real bug once this session (the
|
||||||
|
# time_temp centering fix): `expanded` on a Row grabs extra
|
||||||
|
# *vertical* space from this same enclosing Column
|
||||||
|
# (main_align="space_between"), which pushed the progress bar below
|
||||||
|
# it out of view. A plain Row with a computed Box spacer between the
|
||||||
|
# two texts can't do that, since nothing in it is flexible/expanding.
|
||||||
|
if scale == 2 and progress != None:
|
||||||
|
bpm_width = int(len(list(now["bpm"].codepoints())) * 3.9)
|
||||||
|
length_width = int(len(list(now["track_length"].codepoints())) * 3.9)
|
||||||
|
gap = max(0, text_width - bpm_width - length_width)
|
||||||
|
children.append(render.Row(children = [
|
||||||
|
render.Text(now["bpm"], font = "tom-thumb", color = colors["meta"]),
|
||||||
|
render.Box(width = gap, height = 1),
|
||||||
|
render.Text(now["track_length"], font = "tom-thumb", color = colors["meta"]),
|
||||||
|
]))
|
||||||
|
|
||||||
if progress != None:
|
if progress != None:
|
||||||
children.append(_progress_bar(progress["fraction"], colors, width = text_width, height = 2 * scale))
|
children.append(_progress_bar(progress["fraction"], colors, width = text_width, height = 2 * scale))
|
||||||
|
|
||||||
@@ -1002,6 +1030,8 @@ def _fetch_now_playing(station_url):
|
|||||||
"host": dj.get("name", ""),
|
"host": dj.get("name", ""),
|
||||||
"time_temp": _format_time_temp(context.get("clock", {}) or {}, context.get("weather", {}) or {}),
|
"time_temp": _format_time_temp(context.get("clock", {}) or {}, context.get("weather", {}) or {}),
|
||||||
"album_year": _format_album_year(np.get("album", ""), np.get("year", None)),
|
"album_year": _format_album_year(np.get("album", ""), np.get("year", None)),
|
||||||
|
"track_length": _format_track_length(np.get("duration", 0)),
|
||||||
|
"bpm": _format_bpm(np.get("bpm", None)),
|
||||||
"online": bool(data.get("streamOnline", False)),
|
"online": bool(data.get("streamOnline", False)),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,6 +1043,20 @@ def _format_album_year(album, year):
|
|||||||
parts.append(str(int(year)))
|
parts.append(str(int(year)))
|
||||||
return " · ".join(parts)
|
return " · ".join(parts)
|
||||||
|
|
||||||
|
def _format_track_length(duration):
|
||||||
|
if not duration:
|
||||||
|
return ""
|
||||||
|
total = int(duration)
|
||||||
|
minutes = total // 60
|
||||||
|
seconds = total % 60
|
||||||
|
secs_str = "0" + str(seconds) if seconds < 10 else str(seconds)
|
||||||
|
return str(minutes) + ":" + secs_str
|
||||||
|
|
||||||
|
def _format_bpm(bpm):
|
||||||
|
if not bpm:
|
||||||
|
return ""
|
||||||
|
return str(int(bpm + 0.5)) + " bpm"
|
||||||
|
|
||||||
def _format_time_temp(clock, weather):
|
def _format_time_temp(clock, weather):
|
||||||
parts = []
|
parts = []
|
||||||
display_time = clock.get("display", "")
|
display_time = clock.get("display", "")
|
||||||
|
|||||||