Repository navigation
feat: add the YouTube layer's contract - #149
Merged
Merged
Conversation
- Add VideoId and ChannelId as value classes that check the format, because the Takeout import and other outside text can hold anything. Their messages and toString leave out the ID, which is user data under ADR 0007 - Add YouTubeResult and the YouTubeError enum, so the layer returns failures instead of throwing, and no library message can reach the crash handler - Add the models for search, video details, a channel's latest uploads, stream links and subtitles, with kotlin.time types for times and lengths, and PublishedTime to mark estimated times - Put them in :core:model, which :core:data exposes, so screens and reducers can see them without seeing :core:youtube
- VideoIdTest and ChannelIdTest cover the accepted format, wrong lengths, wrong prefixes, characters outside ASCII, handles and link paths, so a bad Takeout row can't become an ID - Both check that the error message and toString leave out the ID, as ADR 0007 asks
- Add one interface per function, so each caller depends only on what it uses, and a test can pass a lambda for the four fun interfaces - Each interface's KDoc states the contract: main-safe, every YouTube problem returned as a Failure, and CancellationException as the only exception - ChannelUploadsRemoteDataSource says its list holds long-form videos and live streams, never Shorts, with upcoming ones marked - SearchRemoteDataSource says a blank query returns empty lists without a request
- Compare a sealed result type, Kotlin's Result and Dewfall's own exceptions, and record why the sealed type won with MVI and ADR 0007 - Record the error categories, the strict ID value classes and the kotlin.time types, because Phases 4 to 8 build on them
- Add a YouTube layer section to architecture.md with the interfaces, the models, the plan for #35 to read the Videos and Live tabs, the exception mapping and the dev branch risks - Fill in the YouTube parts of Data flow and Error handling, so the path from a failure to a screen is written down - Add an AGENTS.md rule that the layer returns YouTubeResult, throws only CancellationException and uses the ID classes - Add the subtitles task (#148) to Phase 3 in the roadmap, because #35 no longer implements subtitles
- VideoDetails and VideoDetailsRemoteDataSource said YouTube gives no details for a video that hasn't started. No source says that. The cause is that the layer can't read them, so the KDoc now says so - The interfaces say the work moves to an injected dispatcher, to match AGENTS.md's rule on dispatchers - VideoKind.LIVE now covers a premiere that is playing now, so #35 doesn't have to guess its kind - AudioTrack's KDoc says its ID is user data, as ADR 0007 asks
- Narrow the AGENTS.md rule to video and channel IDs, because AudioTrack's ID is a YouTube ID typed as a string - Mark the error table's last column as a plan, because the OpenSpec changes for the screens and background jobs decide it - Limit "both tabs give the length" to videos that can be watched from start to end, and say that LIVE includes a premiere playing now - Say what ADR 0006 actually notes about Kotlin Multiplatform, and that the contract avoids depending on the dev branch's changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #34.
What changed and why
This pull request defines the YouTube layer's contract: Dewfall's interfaces, the models they return and the error type, with no NewPipeExtractor yet. #35 adds NewPipeExtractor and implements search, video details, a channel's latest uploads and stream links. #148 implements subtitles. Both stay open.
:core:youtube: five interfaces, one for each thing the app needs from YouTube: SearchRemoteDataSource, VideoDetailsRemoteDataSource, ChannelUploadsRemoteDataSource, StreamLinksRemoteDataSource and SubtitlesRemoteDataSource. Every function is a main-safe suspend function that returnsYouTubeResultand throws only CancellationException, and each KDoc says so. A blank search returns empty lists without a request. A channel's latest uploads hold its long-form videos and live streams, newest first, never Shorts, with upcoming ones markedVideoKind.UPCOMING.:core:model:VideoIdandChannelIdvalue classes that check the format strictly, withparseOrNullfor outside text such as the Takeout import. Their error messages and toString leave out the ID, which ADR 0007 counts as user data.YouTubeResultand theYouTubeErrorenum, and the models for search results, video details, channel uploads, stream links and subtitles. Times are kotlin.time's Instant, and lengths its Duration.YouTubeResult, throws only CancellationException, lets no NewPipeExtractor exception out, and uses the ID classes.New dependencies
None.
Checklist
Reviewer
Final verdict: Ready.
Ready after two rounds. Round 1 found one Must fix. The KDoc of VideoDetails and VideoDetailsRemoteDataSource said YouTube gives no details for a video that hasn't started, which no source supports. It now says the layer can't read them, so the call fails with UNAVAILABLE. Round 1 also found six Should fix items, all fixed in two follow-up commits:
VideoKind.LIVEcovers a premiere that is playing now.The reviewer checked the cited facts against their sources: the NewPipeExtractor v0.26.5 line links, the dev branch at 405f549, Room 2.6.0's value class support, Kotlin 2.3 making Instant stable, kotlinx-datetime's Alpha status and the data layer guide's quotes.
The reviewer's questions for the maintainer are both answered:
Round 3, on the sort order and one Stream links sentence: Ready, with one Should fix (upcoming videos come first only when they have a scheduled start), now fixed.
🤖 Generated with Claude Code