Skip to content

feat: drill down album and track browsing#3

Open
treyturner wants to merge 17 commits intomainfrom
feat/drill-down_album_and_track_browsing
Open

feat: drill down album and track browsing#3
treyturner wants to merge 17 commits intomainfrom
feat/drill-down_album_and_track_browsing

Conversation

@treyturner
Copy link
Copy Markdown
Owner

@treyturner treyturner commented Mar 6, 2026

Summary

This PR:

  • Introduces hierarchical browsing in the TUI:
    • artist -> albums -> tracks
    • album -> tracks
    • playlist -> tracks
  • Allows for direct album/track playback via those views
  • Improves playback timeline refresh behavior after play actions

What Changed

Plex API client

  • Added PlexTrack and PlexTrackContainer XML models.
  • Added FetchAlbumTracks(serverAddr, albumRatingKey, token).
  • Added FetchPlaylistTracks(serverAddr, playlistRatingKey, token).
  • Fixed FetchArtistAlbums(...) to return actual album results, filter by album type, and sort albums by title.

UI state and panel routing

  • Added new list models: artistAlbumList, trackList.
  • Added browse/playback context fields:
    • currentArtistKey, currentArtistName
    • currentAlbumKey, currentAlbumName
    • currentPlaylistKey, currentPlaylistName
    • trackReturnMode
    • suppressTimeline
  • Added new panel modes:
    • plex-artist-albums
    • plex-album-tracks
    • plex-playlist-tracks
  • Updated update/view/resize handling to support these modes.
  • Updated refreshCurrentPanel() to refresh artist albums, album tracks, and playlist tracks when applicable.

New browse flows

  • Added internal/ui/plex_artist_album_browse.go:
    • Browse albums for a selected artist.
    • Enter -> view album tracks.
    • P -> play album.
    • f -> toggle favorite.
    • R -> refresh.
  • Added internal/ui/plex_track_browse.go:
    • Browse tracks for selected albums/playlists.
    • Enter -> play selected track.
    • Esc/q -> return to originating panel.

Existing browse behavior changes

  • Artist browse:
    • Enter now opens artist albums.
    • P plays selected artist.
  • Album browse:
    • Enter now opens album tracks.
    • P plays selected album.
  • Playlist browse:
    • Enter now opens playlist tracks.
    • P plays selected playlist.
    • Fixed refresh status text to Refreshing playlists....

Playback/timeline improvements

  • Added:
    • beginPlaybackPending(...)
    • beginPlaybackRefresh(...)
  • Playback success paths now trigger refresh via beginPlaybackRefresh("").
  • Timeline updates are suppressed during pending handoff to avoid stale now-playing state.

User Impact

  • Navigation is now hierarchical instead of always playing immediately on Enter.
  • Playback is still one key away via P in artist/album/playlist views.
  • Users can now play individual tracks from track lists.
  • Now-playing and timeline state updates are more consistent during playback transitions.

@treyturner treyturner marked this pull request as ready for review March 6, 2026 04:40
@treyturner treyturner self-assigned this Mar 6, 2026
chatgpt-codex-connector[bot]

This comment was marked as outdated.

@treyturner treyturner changed the title Feat/drill down album and track browsing feat: drill down album and track browsing Mar 6, 2026
@treyturner

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

- add playback-list drill-down on Enter and direct play on P
- open favorite artists/albums/playlists in browse views using metadata-aware lookup
- harden timeline transition handling with pending/ignore windows to avoid stale echoes
- reset playhead state immediately on previous-track command
- add regression tests for favorites navigation and timeline behavior
- switch artist/album/playlist playback commands to playbackTriggeredMsg
- remove per-view playback message types and duplicate success/error handlers
- set immediate status feedback on artist play keypress
- add artist browse test coverage for status update behavior
@treyturner

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@treyturner

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@treyturner

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@treyturner

This comment was marked as outdated.

chatgpt-codex-connector[bot]

This comment was marked as outdated.

@treyturner
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e14d9e5e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

log.Debug(fmt.Sprintf("Toggling favorite for album: %s (ratingKey: %s)", selected.title, selected.ratingKey))
m.lastCommand = fmt.Sprintf("Toggling favorite for %s", selected.title)

_, cmd := m.addRemoveFavorite(selected.title, selected.ratingKey, "album")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject favorite toggle on placeholder album rows

While artist albums are loading, the selected row is the placeholder Loading albums... with an empty ratingKey; pressing f still calls addRemoveFavorite with that empty key. This persists an invalid favorite entry and can conflict with other empty-key entries because favorites are keyed by metadata key, so the user can accidentally corrupt their favorites list just by toggling too early.

Useful? React with 👍 / 👎.

title: item.Name,
ratingKey: item.MetadataKey,
})
return m.fetchArtistAlbumsCmd(item.MetadataKey)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard favorite drill-down when metadata key is missing

findFavoriteItem explicitly falls back to name/type for legacy favorites, but openFavoriteItem immediately dispatches fetch commands using item.MetadataKey without checking that it is non-empty. For legacy rows without keys, pressing Enter navigates into drill-down mode and issues requests with an empty key (for example /library/metadata//children), so the new browse flow fails reliably instead of giving a recoverable message.

Useful? React with 👍 / 👎.

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.

1 participant