From e6f30b6e43aab021437605abdda1d217df20925a Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Mon, 17 Aug 2026 22:10:06 -0400 Subject: [PATCH] fix(a11y): draw an unfavourited track as an outline, not a dimmer fill `favCtrl.iconName` returned the solid glyph in both states, so "not a favourite" was a filled heart in a duller colour and the only thing separating the two states was hue. That fails outright for anyone who cannot tell the two colours apart (WCAG 1.4.1), and reads as "everything is a favourite" to everyone else. `iconFor(favorited)` returns the outline or the fill, and the nine `` call sites split into the two cases they always were. The three that show a *state* -- the mini player, the phone's now-playing view, and the sidebar's marker for the favourites playlist itself -- pass it. The rest are context-menu items, which are actions rather than states and take the outline `iconName` still returns. `track-list` and `album-dropdown` already had this right, from inline SVG paths of their own; this is the same rule for the call sites that go through the icon library. `regular/star` is vendored to go with `regular/heart`, which was already there. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01MeQt5hgXg5YGoNZQ9ozG7L --- frontend/src/assets/icons/fa/regular/star.svg | 1 + .../now-playing-view/now-playing-view.ts | 2 +- .../src/components/now-playing/now-playing.ts | 2 +- .../components/playlist-view/playlist-view.ts | 2 +- frontend/src/icons/names.txt | 1 + .../store/controllers/favorites-controller.ts | 32 ++++++++++++++++--- 6 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 frontend/src/assets/icons/fa/regular/star.svg diff --git a/frontend/src/assets/icons/fa/regular/star.svg b/frontend/src/assets/icons/fa/regular/star.svg new file mode 100644 index 0000000..2b82988 --- /dev/null +++ b/frontend/src/assets/icons/fa/regular/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/now-playing-view/now-playing-view.ts b/frontend/src/components/now-playing-view/now-playing-view.ts index cfdb99b..f90dc64 100644 --- a/frontend/src/components/now-playing-view/now-playing-view.ts +++ b/frontend/src/components/now-playing-view/now-playing-view.ts @@ -307,7 +307,7 @@ export class NowPlayingView extends LitElement { : `Add ${track.title} to ${this.favCtrl.playlistName}`} @click=${this.toggleFavorite} > - + diff --git a/frontend/src/components/now-playing/now-playing.ts b/frontend/src/components/now-playing/now-playing.ts index 48d0524..4405695 100644 --- a/frontend/src/components/now-playing/now-playing.ts +++ b/frontend/src/components/now-playing/now-playing.ts @@ -527,7 +527,7 @@ export class NowPlaying extends LitElement { )} > diff --git a/frontend/src/components/playlist-view/playlist-view.ts b/frontend/src/components/playlist-view/playlist-view.ts index 0f69572..4e7aa62 100644 --- a/frontend/src/components/playlist-view/playlist-view.ts +++ b/frontend/src/components/playlist-view/playlist-view.ts @@ -1756,7 +1756,7 @@ export class PlaylistView extends ViewLifecycleMixin(LitElement) { ${entry.summary.ID === this.favCtrl.playlistId ? html`` : entry.summary.IsSmart ? html`` call sites. + * + * The Font Awesome family is part of the name — `regular/heart` is + * the outline, a bare `heart` is the solid one (`src/icons`). + */ + iconFor(favorited: boolean): string { + const shape = this.iconStyle === 'star' ? 'star' : 'heart'; + + return favorited ? shape : `regular/${shape}`; } // ===============================================================