Initial Sulkta fork of NewPipe with a new :strawApp module that ships a clean Compose-based Android APK at applicationId com.sulkta.straw. What's here: - :strawApp — thin Android application shell, MaterialTheme + StrawHome Composable. Lives alongside legacy :app so we don't break upstream. - buildSrc — STRAW_APPLICATION_ID/VERSION constants alongside the existing NEWPIPE_APPLICATION_ID_OLD/NEW. - docs/sulkta — RECON.md (NewPipe codebase breakdown) + DECISIONS.md (stack + scope decisions). NewPipe's :shared KMP scaffold is at 892 LOC and renders nothing; this fork picks up there and races ahead. Day-1 ships a hello APK; day-2 wires NewPipeExtractor + Media3 player + SponsorBlock + Return YouTube Dislike. GPL-3.0-or-later per upstream.
95 lines
4 KiB
Markdown
95 lines
4 KiB
Markdown
# NewPipe-fork decisions — 2026-05-23
|
|
|
|
## Name: `straw`
|
|
|
|
- Single short word, on-pattern with the rest of Sulkta's app family (cwho,
|
|
tny, hawk, adhdo, tny).
|
|
- Evokes "drawing content through a thin pipe" — fits the YouTube-extractor
|
|
metaphor without leaning on the "pipe" word (NewPipe already owns that).
|
|
- Easy to type, easy to read.
|
|
|
|
If Cobb hates it, alts: `siphon`, `decant`, `funnel`, `kettle`.
|
|
|
|
## Approach: fork NewPipe master, rebrand, build on `:shared`
|
|
|
|
Not starting fresh. NewPipe has already done the gradle/CI/buildSrc/Koin/nav3
|
|
scaffold work — we'd be reinventing wheels to redo it. Forking lets us:
|
|
|
|
- Keep upstream as a remote, cherry-pick their improvements as they land.
|
|
- Build directly on `:shared` (the KMP module that has the scaffold but no
|
|
features).
|
|
- Keep the legacy `:app` module around as **reference for working extractor
|
|
wiring patterns** (search, channel, video resolve, player setup). Eventually
|
|
drop it once `:shared` is feature-complete.
|
|
|
|
## Repo: `Sulkta-Coop/straw` on LAN Gitea
|
|
|
|
- License: keep GPL-3.0-or-later (upstream's license, required for derivative).
|
|
- Branches:
|
|
- `master` — tracks upstream NewPipe master for clean rebase pulls.
|
|
- `sulkta` — our work branch, default branch for clones.
|
|
- Remote `upstream` pointing at `github.com:TeamNewPipe/NewPipe.git` for
|
|
periodic merges.
|
|
|
|
## App identity
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Application ID | `com.sulkta.straw` (replaces `net.newpipe.app`) |
|
|
| App name | "Straw" (debug suffix `Straw debug`) |
|
|
| Min SDK | 24 (Android 7, NewPipe is 23 — minor bump for Media3) |
|
|
| Target SDK | 35 (NewPipe matches) |
|
|
| Compile SDK | 36 (NewPipe matches) |
|
|
| Java toolchain | 21 (NewPipe matches) |
|
|
| Kotlin | 2.3.21 (NewPipe matches) |
|
|
|
|
Legacy `:app` (id `org.schabi.newpipe`) stays unchanged for now — we don't
|
|
ship it but we read it.
|
|
|
|
## Stack (matches NewPipe + 1 modernization)
|
|
|
|
- **UI**: Jetpack Compose + Compose Multiplatform (commonMain Composables,
|
|
androidMain ComposeActivity host).
|
|
- **Nav**: androidx-navigation3 (type-safe sealed `Screen` interface).
|
|
- **DI**: Koin 4.x with `koin-plugin` annotation processor (`@KoinApplication`,
|
|
`@Single`, `@KoinViewModel`).
|
|
- **State**: ViewModels + StateFlow.
|
|
- **HTTP for SponsorBlock + RYD**: **Ktor 3.x client** (KMP-ready). NewPipe
|
|
uses OkHttp; we use Ktor because we want SB/RYD clients to live in
|
|
`commonMain` for future iOS/desktop.
|
|
- **Player**: **`androidx.media3` 1.4+** — NewPipe is still on legacy ExoPlayer
|
|
2.19.1. Media3 is the upstream-replacement, better lifecycle, better DASH.
|
|
- **Image loading**: Coil 3 (NewPipe matches).
|
|
- **Serialization**: kotlinx-serialization (NewPipe matches).
|
|
- **Extractor**: `NewPipeExtractor v0.26.2` via JitPack (NewPipe matches).
|
|
JVM-only — lives in `androidMain` source set; `commonMain` declares an
|
|
expected interface, `androidMain` wires the actual extractor.
|
|
|
|
## What we don't try to do on day 1
|
|
|
|
- **iOS target.** Extractor port is multi-week. iosApp stays a stub.
|
|
- **Desktop target.** Same constraint; no point until extractor ported.
|
|
- **History/subscriptions persistence.** Room is Android-only, fine for v0,
|
|
but we want SQLDelight (KMP) eventually.
|
|
- **Settings.** Use `:shared/SettingsModule` interface that already exists;
|
|
Android impl backed by DataStore.
|
|
- **F-Droid metadata.** Worry about it later.
|
|
- **Background audio + queue + autoplay.** Phase 2 work.
|
|
- **DRM / age-gated content.** Phase 2.
|
|
|
|
## Day-1 deliverable scope
|
|
|
|
A working APK with:
|
|
|
|
1. **Search screen** — type a query, list video results from YouTube. Tap
|
|
opens video detail.
|
|
2. **Video detail screen** — title, channel, description, RYD like/dislike
|
|
row, "Play" button.
|
|
3. **Player screen** — Media3 ExoPlayer playing the resolved video stream.
|
|
SponsorBlock segments auto-skip during playback. Shows skip toast each
|
|
time.
|
|
4. **Settings sketch** — toggle for SponsorBlock categories (sponsor on by
|
|
default).
|
|
|
|
That's the demo. **No** channel pages, subscriptions, history, downloads,
|
|
PiP, background audio, kiosks, comments, related videos. Those are Phase 2+.
|