feat: drag and drop tracks onto sidebar playlists#363
Conversation
- Song rows and cards are drag sources everywhere a Song is rendered: playlist track rows, HoverObservingRow (search, history, artist pages, top songs), and HomeSectionItemCard song cards (home, explore, charts, moods, new releases) - .dropDestination(for:action:isTargeted:) on owned sidebar playlists, ignores albums - error handling with do/catch + success/error haptic feedback
Visual feedback for drag-and-drop to playlist sidebar: - playlist rows get a brand-accent tinted highlight + bounce icon while a track is dragged over them (albums excluded) - green checkmark badge flashes on the row for ~900ms after a successful drop KasetSidebarRow gains isDropTargeted (default false, backwards compatible).
23e4c70 to
182eed5
Compare
Liked Music is the LM auto-playlist: membership means liked, so edit_playlist does not apply. Drops route through SongLikeStatusManager so like buttons update everywhere. Both the Collection row and a pinned LM playlist row accept drops; shared drop handling extracted.
6c8a7a2 to
c440b97
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40e52941ad
ℹ️ 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".
Deepen LibraryMutationActions with a single addSong(_:to:) entry owning LM-vs-editable routing, cache invalidation, and logging; return AddSongOutcome for callers to map to feedback. Sidebar drop + add-to-playlist menu now converge on it, so the "adding to Liked Music means liking" rule lives in one place. Add PlaylistDropTarget value type classifying the target once (folding the VL browse-id prefix). Eligibility and routing read the same classifier, fixing a latent bug where a VLLM-pinned Liked Music row passed eligibility then misrouted to addSongToPlaylist and failed.
Replace copy-pasted .draggable at HoverObservingRow, HomeSectionItemCard, and playlist track rows with one .songDraggable modifier — the single place a shared drag preview would live. Fixes HomeSectionItemCard branch ordering that silently left play-action song cards non-draggable.
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
# Conflicts: # Tests/KasetTests/LibraryMutationActionsTests.swift
e341b45 to
f334553
Compare
Description
Adds drag-and-drop of tracks onto playlists in the sidebar. Any track row (search results, history, home sections, playlist detail, etc.) can be dragged onto an owned playlist in the sidebar to add it. The target playlist highlights while dragging over it, and a brief success badge confirms the drop.
AI Prompt (Optional)
🤖 AI Prompt Used
AI Tool: Claude Code
Type of Change
Related Issues
Changes Made
Songis a drag source (via the existingTransferableconformance), attached at the shared wrappers rather than per view: playlist track rows,HoverObservingRow(search, history, artist pages, top songs), andHomeSectionItemCardsong cards (home, explore, charts, moods, new releases).dropDestination(for: Song.self, action:isTargeted:)on owned sidebar playlist rows; drops callYTMusicClient.addSongToPlaylistSongLikeStatusManager(optimistic, broadcasts so like buttons update everywhere, rollback on failure)Testing
swift test --skip KasetUITests) — 1774 passed, 148 suitesChecklist
swiftlint --strict && swiftformat .Screenshots
kaset-drag-drop-pr363.mp4
Additional Notes
View-layer only: no API or model changes. The drop path reuses the existing add-to-playlist client call (and the existing like flow for Liked Music).