Label track search results as Songs, remove the home-only search eyebrow, and keep Heavy rotation exclusive to the unfiltered home view.

Hop-State: A_06FNQD6K116P1K9BB54GZAG
Hop-Proposal: R_06FNQD5C2X5HW2388XX74QR
Hop-Task: T_06FNQCQPFA437RBCP725WJG
Hop-Attempt: AT_06FNQCQPFBGSEHJ0RNKFMP0
This commit is contained in:
2026-07-13 06:40:05 -07:00
committed by Hop
parent ea4c17fa96
commit 38dc9b80e2
2 changed files with 11 additions and 1 deletions
+10
View File
@@ -98,6 +98,16 @@ describe("App bootstrap", () => {
expect(screen.queryByRole("button", { name: "Profile" })).toBeNull();
});
it("labels track search results as Songs instead of Heavy rotation", async () => {
await renderDemoApp();
fireEvent.change(screen.getByPlaceholderText("Search your library"), { target: { value: "Violet" } });
const songsHeading = screen.getByRole("heading", { level: 2, name: "Songs" });
expect(songsHeading.closest(".track-section")?.querySelector(".eyebrow")).toBeNull();
expect(screen.queryByRole("heading", { level: 2, name: "Heavy rotation" })).toBeNull();
});
it("defaults Albums and Songs to AZ and remembers reordered views", async () => {
await renderDemoApp();
+1 -1
View File
@@ -670,7 +670,7 @@ export default function App() {
</section>}
{view !== "albums" && <section className="content-section track-section" aria-labelledby="tracks-heading">
<div className="section-heading"><div><span className="eyebrow">{view === "favorites" ? "Kept close" : view === "songs" ? "Every track" : query ? "Matching your search" : "Most played by listen count"}</span><h2 id="tracks-heading">{view === "favorites" ? "Favorite tracks" : view === "songs" ? "Songs" : "Heavy rotation"}</h2></div><div className="section-heading-actions"><span>{view === "home" && !query ? hasHeavyRotation ? "By play count" : "Still learning" : `${visibleTracks.length} tracks`}</span>{view === "songs" && <SortControl label="Sort songs" value={trackSort} options={trackSortOptions} onChange={changeTrackSort} />}</div></div>
<div className="section-heading"><div>{!(view === "home" && query) && <span className="eyebrow">{view === "favorites" ? "Kept close" : view === "songs" ? "Every track" : "Most played by listen count"}</span>}<h2 id="tracks-heading">{view === "favorites" ? "Favorite tracks" : view === "songs" || query ? "Songs" : "Heavy rotation"}</h2></div><div className="section-heading-actions"><span>{view === "home" && !query ? hasHeavyRotation ? "By play count" : "Still learning" : `${visibleTracks.length} tracks`}</span>{view === "songs" && <SortControl label="Sort songs" value={trackSort} options={trackSortOptions} onChange={changeTrackSort} />}</div></div>
{view === "home" && !query && !hasHeavyRotation ? <div className="empty-state"><AudioLines size={26} /><h3>Heavy rotation is still taking shape</h3><p>Finish a few songs more than once and your most-played tracks will appear here.</p></div> : view === "favorites" && visibleTracks.length === 0 ? <div className="empty-state"><Heart size={26} /><h3>No favorite tracks yet</h3><p>Use the heart beside a song to keep it here.</p></div> : <div className="track-list" role="list">{displayedTracks.map((track, index) => { const justQueued = queuedTrackIds.has(track.id); const favoritePending = favoritePendingIds.has(track.id); return <div className={`track-row ${player.current.id === track.id ? "is-current" : ""}`} role="listitem" key={track.id}><button className="track-main" type="button" onClick={() => player.playFromContext(track, displayedTracks)}><span className="track-number">{player.current.id === track.id && player.isPlaying ? <AudioLines size={15} /> : String(index + 1).padStart(2, "0")}</span><Cover album={track} size="small" /><span><strong>{track.title}</strong><small>{track.artist}</small></span></button><span className="track-album">{track.album}</span><IconButton label={favoritePending ? `Saving favorite for ${track.title}` : favorites.has(track.id) ? `Remove ${track.title} from favorites` : `Add ${track.title} to favorites`} active={favorites.has(track.id)} disabled={favoritePending} onClick={() => void toggleFavorite(track)}><Heart size={16} fill={favorites.has(track.id) ? "currentColor" : "none"} /></IconButton><span className="track-time">{formatTime(track.duration)}</span><IconButton label={justQueued ? `Add ${track.title} to queue again` : `Add ${track.title} to queue`} className={`queue-add-button ${justQueued ? "is-confirmed" : ""}`} onClick={() => addTrackToQueue(track)}>{justQueued ? <Check size={17} strokeWidth={2.5} /> : <Plus size={17} />}</IconButton></div>; })}</div>}
<span className="sr-only" key={queueAnnouncement.key} role="status" aria-live="polite">{queueAnnouncement.message}</span>
</section>}