Skip to content

feat(sidebar): highlight currently-playing playlist - #441

Open
tsibog wants to merge 2 commits into
sozercan:mainfrom
tsibog:feat/sidebar-now-playing
Open

feat(sidebar): highlight currently-playing playlist#441
tsibog wants to merge 2 commits into
sozercan:mainfrom
tsibog:feat/sidebar-now-playing

Conversation

@tsibog

@tsibog tsibog commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Description

When a track is playing from a playlist, there's no indication in the sidebar of which playlist is currently playing. This PR tracks the source playlist ID in PlayerService and tints the matching sidebar row's title with the brand accent.

The sourcePlaylistId is set when playing from a playlist view and cleared when playing from non-playlist sources (radio, mix, individual track, stop).

Demo

AI Prompt (Optional)

🤖 AI Prompt Used
N/A - Manual implementation

AI Tool: Claude

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📚 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Refactoring (no functional changes)
  • 🧪 Test update
  • 🔧 Build/CI configuration

Related Issues

Closes #433

Changes Made

  • PlayerService.swift: Added sourcePlaylistId: String? property
  • Protocols.swift: Added sourcePlaylistId to PlayerServiceProtocol
  • PlayerService+Queue.swift: Set sourcePlaylistId in playQueue when called from a playlist context
  • PlayerService+PlaybackControls.swift: Clear sourcePlaylistId on stop
  • PlayerService+PlaybackBoundaries.swift: Clear sourcePlaylistId on playback end
  • PlaylistPlaybackActions.swift: Set sourcePlaylistId when playing from playlist
  • PlaylistDetailView.swift: Set sourcePlaylistId when playing a track from the playlist view
  • KasetSidebarRow.swift: Added isNowPlayingSource parameter; tints the row title with the brand accent when set, keeping the row's own icon
  • Sidebar.swift: Pass isNowPlayingSource to pinned item rows by comparing playerService.sourcePlaylistId with item.contentId
  • MockPlayerService.swift: Added sourcePlaylistId for protocol conformance

Testing

  • Unit tests pass (swift test --skip KasetUITests) — 2956 tests in 232 suites
  • Manual testing performed
  • UI tested on macOS 26+

Built and tested locally on macOS 26 (Apple Silicon). Manual verification in a packaged build: the pinned playlist's title tints while it is the playing source, the tint moves when switching playlists, and it clears when playback moves to a non-playlist source.

Two suites fail nondeterministically in local full-suite runs — FavoritesManagerTestsLegacyMigrationClaims and SettingsManagerTests (a locale leak: LaunchPage.home.displayName resolving to "홈"). A different suite fails on each run and both pass in isolation (FavoritesManagerTestsLegacyMigrationClaims was re-run 3x on its own: 19 tests, all passing each time), so this is pre-existing parallel-execution flakiness in shared global state, unrelated to this change — nothing here touches FavoritesManager or SettingsManager.

Checklist

  • My code follows the project's style guidelines
  • I have run swiftlint --strict && swiftformat . — both clean (0/622 files need formatting)
  • I have added tests that prove my fix/feature works
  • New and existing unit tests pass locally
  • I have updated documentation if needed
  • I have checked for any performance implications
  • My changes generate no new warnings

Additional Notes

The sourcePlaylistId is cleared in all non-playlist play paths to prevent stale highlights.

Why a tint rather than an equalizer indicator

An earlier version of this PR replaced the row's icon with the animated NowPlayingIndicator used in track rows. That was dropped in favour of tinting the title:

  • It keeps each playlist's own icon instead of replacing it, so the row still carries its normal meaning.
  • No animation in the sidebar — the indicator would have run continuously for as long as something was playing.
  • The pinned rows' icons are already brand accent, so an accent title reads as one coherent "active" row.

The parameter is named isNowPlayingSource rather than isPlaying because it means "this is the playing source", not "audio is currently playing". The earlier naming is precisely what made NowPlayingIndicator(isPlaying: true) look correct at the call site, which left the bars animating even while playback was paused.

NowPlayingIndicator and EqualizerView are untouched by this PR; playlist track rows continue to use them as before.

Track which playlist the current track was played from via
sourcePlaylistId on PlayerService. Show NowPlayingIndicator
(equalizer bars) on the matching sidebar row instead of the
static system image.

Closes sozercan#433
@tsibog

tsibog commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Keeps each row's own icon and drops the animated equalizer, so the
sidebar indicates the playing playlist with colour alone and no motion.

Renames isPlaying to isNowPlayingSource: the flag means "this is the
playing source", not "audio is currently playing". The old name is what
made NowPlayingIndicator(isPlaying: true) look correct at the call site,
which kept the bars animating while paused.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Highlight currently-playing playlist in the sidebar

1 participant