From de6462cbd241efd5b6147078da8be4d55cfa07a5 Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Sun, 24 May 2026 21:27:21 +0300 Subject: [PATCH] fix(now-playing): hide zero-valued track metadata badges (#865) * fix(now-playing): hide zero-valued track metadata badges Use explicit > 0 checks instead of truthy && so missing numeric fields (bitDepth, bitRate, samplingRate, year, rating) no longer render as "0". * chore: note PR #865 in changelog and credits * chore: drop PR #865 from settings credits (minor fix) * fix(now-playing): null-safe numeric badge guards for tsc Use (value ?? 0) > 0 so optional metadata fields satisfy strict TS while still omitting zero-valued badges in the UI. --- CHANGELOG.md | 8 ++++++++ src/components/nowPlaying/Hero.tsx | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ee3dbd..da846552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -290,6 +290,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +### Now Playing — stray zero metadata badges + +**By [@cucadmuh](https://github.com/cucadmuh), PR [#865](https://github.com/Psychotoxical/psysonic/pull/865)** + +* Hero track-info badges no longer render literal `0` when numeric metadata fields (bit depth, bitrate, sample rate, year, rating) are missing and arrive as zero from the server. + + + ## [1.46.0] - 2026-05-18 > **🙏 Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) — several of the polish fixes in this release landed directly off the back of his messages. diff --git a/src/components/nowPlaying/Hero.tsx b/src/components/nowPlaying/Hero.tsx index f3e6c7c8..91cabd0b 100644 --- a/src/components/nowPlaying/Hero.tsx +++ b/src/components/nowPlaying/Hero.tsx @@ -43,7 +43,7 @@ function renderStars(rating?: number) { const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, lfmTrack, lfmArtist, starred, lfmLoved, lfmLoveEnabled, activeLyricsTab, coverUrl, onNavigate, onToggleStar, onToggleLfmLove, onOpenLyrics }: HeroProps) { const { t } = useTranslation(); const rating = userRatingOverride ?? track.userRating; - const hiRes = (track.bitDepth && track.bitDepth > 16) || (track.samplingRate && track.samplingRate > 48000); + const hiRes = (track.bitDepth ?? 0) > 16 || (track.samplingRate ?? 0) > 48000; const releaseAge = track.year ? new Date().getFullYear() - track.year : 0; return ( @@ -67,7 +67,7 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l style={{ cursor: track.albumId ? 'pointer' : 'default' }}> {track.album} - {track.year && <>·{track.year}} + {track.year != null && track.year > 0 && <>·{track.year}} {releaseAge > 0 && ( <>· @@ -79,9 +79,9 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l
{genre && {genre}} {track.suffix && {track.suffix.toUpperCase()}} - {track.bitRate && {track.bitRate} kbps} - {track.samplingRate && {(track.samplingRate / 1000).toFixed(1)} kHz} - {track.bitDepth && {track.bitDepth}-bit} + {(track.bitRate ?? 0) > 0 && {track.bitRate} kbps} + {(track.samplingRate ?? 0) > 0 && {((track.samplingRate ?? 0) / 1000).toFixed(1)} kHz} + {(track.bitDepth ?? 0) > 0 && {track.bitDepth}-bit} {hiRes && Hi-Res} {track.duration > 0 && {formatTrackTime(track.duration)}}
@@ -104,7 +104,7 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l style={{ color: activeLyricsTab ? 'var(--accent)' : undefined }}> - {rating && renderStars(rating)} + {rating != null && rating > 0 && renderStars(rating)} {(playCount != null && playCount > 0) && (