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.
This commit is contained in:
cucadmuh
2026-05-24 21:27:21 +03:00
committed by GitHub
parent 11974e1438
commit de6462cbd2
2 changed files with 14 additions and 6 deletions
+8
View File
@@ -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 ## [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. > **🙏 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.
+6 -6
View File
@@ -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 Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, lfmTrack, lfmArtist, starred, lfmLoved, lfmLoveEnabled, activeLyricsTab, coverUrl, onNavigate, onToggleStar, onToggleLfmLove, onOpenLyrics }: HeroProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const rating = userRatingOverride ?? track.userRating; 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; const releaseAge = track.year ? new Date().getFullYear() - track.year : 0;
return ( return (
@@ -67,7 +67,7 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l
style={{ cursor: track.albumId ? 'pointer' : 'default' }}> style={{ cursor: track.albumId ? 'pointer' : 'default' }}>
{track.album} {track.album}
</span> </span>
{track.year && <><span className="np-sep">·</span><span>{track.year}</span></>} {track.year != null && track.year > 0 && <><span className="np-sep">·</span><span>{track.year}</span></>}
{releaseAge > 0 && ( {releaseAge > 0 && (
<><span className="np-sep">·</span> <><span className="np-sep">·</span>
<span className="np-dash-hero-age"> <span className="np-dash-hero-age">
@@ -79,9 +79,9 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l
<div className="np-dash-hero-badges"> <div className="np-dash-hero-badges">
{genre && <span className="np-badge">{genre}</span>} {genre && <span className="np-badge">{genre}</span>}
{track.suffix && <span className="np-badge">{track.suffix.toUpperCase()}</span>} {track.suffix && <span className="np-badge">{track.suffix.toUpperCase()}</span>}
{track.bitRate && <span className="np-badge">{track.bitRate} kbps</span>} {(track.bitRate ?? 0) > 0 && <span className="np-badge">{track.bitRate} kbps</span>}
{track.samplingRate && <span className="np-badge">{(track.samplingRate / 1000).toFixed(1)} kHz</span>} {(track.samplingRate ?? 0) > 0 && <span className="np-badge">{((track.samplingRate ?? 0) / 1000).toFixed(1)} kHz</span>}
{track.bitDepth && <span className="np-badge">{track.bitDepth}-bit</span>} {(track.bitDepth ?? 0) > 0 && <span className="np-badge">{track.bitDepth}-bit</span>}
{hiRes && <span className="np-badge np-badge-hires">Hi-Res</span>} {hiRes && <span className="np-badge np-badge-hires">Hi-Res</span>}
{track.duration > 0 && <span className="np-badge">{formatTrackTime(track.duration)}</span>} {track.duration > 0 && <span className="np-badge">{formatTrackTime(track.duration)}</span>}
</div> </div>
@@ -104,7 +104,7 @@ const Hero = memo(function Hero({ track, genre, playCount, userRatingOverride, l
style={{ color: activeLyricsTab ? 'var(--accent)' : undefined }}> style={{ color: activeLyricsTab ? 'var(--accent)' : undefined }}>
<MicVocal size={18} /> <MicVocal size={18} />
</button> </button>
{rating && renderStars(rating)} {rating != null && rating > 0 && renderStars(rating)}
</div> </div>
{(playCount != null && playCount > 0) && ( {(playCount != null && playCount > 0) && (