[TV] Play latest episode from featured cards and search discover - #5793
Conversation
|
Claude finished @sztomek's task in 4m 32s —— View job ReviewThe wiring is correct: Note that Non-blocking
Nits
I did not build the module or run |
|
Claude finished @sztomek's task in 27s —— View job ReviewNo new commits since my previous review — the branch is still at All three earlier findings are still open: Non-blocking
Nits
I did not build the module or run |
|
Claude finished @sztomek's task in 1m 31s —— View job Review
Non-blocking
The duplication note from last time still stands ( I did not build the module or run |
|
Claude finished @sztomek's task in 5m 25s —— View job ReviewReviewed only the two commits since my last review: Non-blocking
Nits
I did not build the module or run |
Description
Fixes two dead play-actions on Android TV that already work on the Apple TV app (parity audit section 1.2, items F3 and F4), plus three discover-attribution fidelity fixes surfaced by the v2 parity audit (§3.10, F8/F9).
F3 (P0) — Home featured carousel "Play latest episode" was a no-op. The focus-revealed button rendered but
onPlayLastEpisode = {}. It now resolves the featured podcast's newest episode and starts playback, opening Now Playing on success and showing the generic "playback failed" toast on failure — matchingTVDataManager.playLatestEpisodeon tvOS.F4 (P1) — Search-idle discover episode tiles didn't play. The idle Search screen is a full discover feed; its episode tiles had
onEpisodePlay = { _, _ -> }with a TODO. They now play immediately and open Now Playing, matching Home. The idle feed's featured cards also play their latest episode (same machinery), for parity with tvOS.How "latest episode" is resolved
podcastManager.findOrDownloadPodcastRxSingle(uuid)loads the podcast (unsubscribed OK), thenepisodeManager.findEpisodesByPodcastOrderedByPublishDate(podcast).first()gives the newest-by-publish-date episode — the Android equivalent of tvOSfetchEpisodes(sortOrder: .newestToOldest).first. Playback uses the existingPlaybackManager.playNowSuspend(...)path already used by the discover episode-row tiles.Follow-up parity & attribution fidelity (audit v2)
Three ride-along commits addressing analytics-fidelity gaps from the v2 parity audit:
SourceView.SEARCH(source=search), notSourceView.DISCOVER. iOS stamps the hosting surface —"search"from search discover (DiscoverAnalytics.searchSource),"discover"/"home"from Home. Home playback keepsSourceView.DISCOVER. Downstreamplayback_playetc. now carry the correctsource.list_idvalue fidelity. The analytics list id now follows the iOS chainitem uuid → fetched list payloadlistId→ layout id(DiscoverManager.listIdForPodcast), carried on the row model as a dedicated nullablelistIdseparate from the row's dedup identity. Two behavioural changes vs. before: the fetchedListFeed.listIdis now consulted (curated lists whose uuid lives only in the list JSON report correctly), and the human-readable title fallback is removed — a row with no uuid/list-id/layout-id is simply excluded from list-attributed events instead of emitting a title (e.g.list_id="Trending") that pollutes the property's cardinality. Local rows carry a nulllistIdand are excluded, same as before.list_datetimeondiscover_list_podcast_tapped. The section'sdatetimeis now carried through the row model and emitted on podcast taps, matching iOS which sends it whenever the section provides it.Analytics
Wired via the existing
TvDiscoverFeedAnalyticshelper the discover rows already use:home): on success firesdiscover_list_episode_tapped(list_id, podcast_uuid, episode_uuid, source) +discover_list_episode_play(list_id, podcast_uuid), matchingDiscoverFeaturedPodcastCellon tvOS.search): the episode tiles fire the samediscover_list_episode_tapped+discover_list_episode_playpair; featured cards fire them on success.discover_list_podcast_tappednow carrieslist_datetimewhen the section provides it, and itslist_iduses the corrected chain above.Fixes PCDROID-738 https://linear.app/a8c/issue/PCDROID-738/implement-missing-click-handlers
Testing Instructions
source=discover.source=search. "Go to podcast" still works.search).LoggingAnalyticsListenerlogcat, confirmdiscover_list_podcast_tappedcarries alist_idfrom the list payload (never a row title) and alist_datetimewhen the section provides one.Checklist
./gradlew spotlessApply)modules/services/localization/...(no new strings)list_datetimeparameter)