Skip to content

feat(player): mirror likes onto YouTube Music - #318

Merged
ajisth69 merged 5 commits into
mainfrom
feat/yt-music-like-mirror
Oct 13, 2026
Merged

ajisth69 merged 5 commits into
mainfrom
feat/yt-music-like-mirror

Conversation

@ajisth69

Copy link
Copy Markdown
Member

Likes in the player now also land on the connected YouTube Music account.

What

  • InnerTubeMusicApi.likeVideo / removeVideoLike — POST the rate endpoints (like/like, like/removelike) with the shared target.videoId body, through the same authenticated WEB_REMIX channel the playlist writes already use. Both guard on connection + videoId and return false instead of throwing, matching the other mutation helpers in the file.
  • YtMusicLibraryManager.mirrorLikeToYouTube(track, loved) — owns the "is there anything to mirror?" decision and returns true, explicitly not a failure, when there's no account connected or the track has no YouTube videoId (imported local files). Those cases can never toast the user as an error.
  • PlayerViewModel — mirrors after the local write from both entry points: the heart toggle (toggleLiked) and the double-tap (like). Unliking mirrors as like/removelike, so the YT like state follows the player.

The local Like stays the source of truth: the mirror runs after a successful local write, and a failed mirror only toasts ("Couldn't like this song on YouTube Music") — it never undoes a local like.

Tests

YtMusicLikeTest pins the wire contract: the two rate endpoints, the target payload shape (videoId only), and its JSON round-trip.

Note

CI is watched to green before merge — last two PRs taught us that.

The player's like was local-only: it wrote Liked Songs and mirrored to
Last.fm, while the connected YouTube Music account never learned about
it. Liking (or unliking) now mirrors through the same authenticated
WEB_REMIX channel the playlist writes already use.

- InnerTubeMusicApi.likeVideo / removeVideoLike POST the rate endpoints
  (like/like, like/removelike) with the shared `target.videoId` body;
  both guards on connection and videoId and return false instead of
  throwing.
- YtMusicLibraryManager.mirrorLikeToYouTube owns the "is there anything
  to mirror" decision and returns true — explicitly not a failure —
  with no account or for an imported local file, so those cases never
  read as errors or toast the user.
- PlayerViewModel mirrors after the local write from both entry points
  (the heart toggle and the double-tap). The local like stays the source
  of truth: a failed mirror is reported with a toast and left for the
  next toggle, never used to undo a successful local like.

Tests: YtMusicLikeTest pins the rate endpoints and the target payload.
@rx6500M

rx6500M commented Oct 13, 2026

Copy link
Copy Markdown

@ajisth69 Bhai yaar abhi vi slow as fuck hai page loading

@rx6500M

rx6500M commented Oct 13, 2026

Copy link
Copy Markdown

@rx6500M Lol

Identical to the repair in #317: the #315 merge landed the feed change without its fixup commit, so main does not compile from add(it to ...) inside the forEachIndexed lambdas. This branch needs main to compile; once #317 merges, the two sides carry identical content for these lines.
The endpoints sat in the class's private companion, which hides them even from same-module tests. Moved to file-level internal consts.
In-flight search/login work: repository, view model, search screen and the YouTube login flow + its view model.
@ajisth69
ajisth69 merged commit 3102689 into main Oct 13, 2026
1 check failed
DChitale pushed a commit to DChitale/LastWave-Native that referenced this pull request Oct 14, 2026
The guard rethrows CancellationException from the catch block, which never had the import, so :app:compileDebugKotlin failed on main after Clash-Projects#318 merged. One import, no behaviour change.
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.

2 participants