Two requested features in one ship.
Autoplay:
* Settings → Autoplay section. Three modes: Off, Same channel,
YouTube related. Default Same channel — per Cobb 2026-05-26,
"plays next account's video".
* Skip-already-watched toggle, default on. Autoplay picks the
first un-watched candidate (filters History.watches by videoId).
* When STATE_ENDED fires and the queue has no next item,
PlaybackService's autoplay handler picks a candidate per mode,
resolves it via strawcore, and enqueues — which auto-starts
because the queue is empty (enqueueLast routes through
setPlayingFrom in that case).
* SameChannel calls strawcore.channelInfo(uploaderUrl).take(1).
Plumbed NowPlayingItem.uploaderUrl + setPlayingFrom/enqueueLast
sig to carry it forward so the autoplay handler has what it
needs without re-resolving.
* YtRelated re-resolves the current streamInfo and picks
info.related[0]. strawcore returns empty for related today, so
YtRelated falls open to no-op until that extractor work lands —
documented in the AutoplayMode enum help text.
SponsorBlock for queued items:
* The vc=47 known-limitation. Now: when onMediaItemTransition
surfaces a queued item with empty SB segments, fire a
background fetch of SB for that video, then NowPlaying.claim()
again with the freshened segments. The skip-loop (reactive on
NowPlaying.current.segments) picks them up.
* Fetch lives in StrawApp.globalScope — outlives the controller
transition + sheet UI.
Refactor:
* StrawMediaController extensions retyped from MediaController →
Player so PlaybackService can call them on the ExoPlayer
directly. MediaController IS a Player so all existing UI call
sites continue to work.
* Shared extractYtVideoId util in feature/detail/StreamResolution.kt.
The duplicate VIDEO_ID_RE in StrawHome.kt will fold into it next
time that file is touched.
60 lines
2.8 KiB
Kotlin
60 lines
2.8 KiB
Kotlin
/*
|
||
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
|
||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||
*/
|
||
|
||
const val NEWPIPE_VERSION_SDK_COMPILE_MAJOR = 36
|
||
const val NEWPIPE_VERSION_SDK_COMPILE_MINOR = 1
|
||
const val NEWPIPE_VERSION_SDK_MIN = 23
|
||
const val NEWPIPE_VERSION_SDK_TARGET = 35
|
||
|
||
const val NEWPIPE_VERSION_CODE = 1012
|
||
const val NEWPIPE_VERSION_NAME = "0.28.7"
|
||
|
||
const val NEWPIPE_APPLICATION_ID_OLD = "org.schabi.newpipe"
|
||
const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
|
||
|
||
// Sulkta fork — Straw
|
||
//
|
||
// vc=23 / 0.1.0-AI — minibar + downloads UI + green theme:
|
||
// * MediaController/MediaSessionService unification — single ExoPlayer
|
||
// owned by PlaybackService, every UI surface is a controller client.
|
||
// Inline player on VideoDetail, fullscreen Player, and the new
|
||
// minibar overlay all drive the same underlying player; nothing
|
||
// restarts on screen transitions.
|
||
// * Persistent minibar overlay at the bottom of every non-Player
|
||
// screen whenever something is loaded. Tap → expand to fullscreen.
|
||
// Drag-down on fullscreen → minimize to minibar. ⌄ overlay button
|
||
// also minimizes. × on the minibar stops + clears.
|
||
// * Downloads page wired into the drawer.
|
||
// * Theme: forest-green primary palette in place of M3 default
|
||
// lavender / NewPipe red — modern, clean, distinct.
|
||
//
|
||
// vc=22 / 0.1.0-AH — V-2 player polish + local playlists:
|
||
// * Inline → fullscreen now hands off seek position. Tap Play (or the
|
||
// ⛶ pill on the inline player) while the inline is mid-track and
|
||
// the fullscreen Player picks up at the same point. Same handoff
|
||
// pattern as fullscreen → background from vc=21.
|
||
// * Local playlists: drawer entry "Playlists", "Save" button on
|
||
// VideoDetail. SharedPreferences-backed, no queue/autoplay yet
|
||
// (tap an entry to open VideoDetail as normal).
|
||
//
|
||
// vc=21 / 0.1.0-AG — player hand-off polish:
|
||
// * 🎧 background-audio button now captures the current position and
|
||
// resumes the foreground service from there instead of restarting.
|
||
// * HOME / recents button while on the player now hands off seamlessly
|
||
// to background audio (same position-preserving path) instead of
|
||
// auto-entering Picture-in-Picture. Manual PiP via the ⊟ overlay
|
||
// button is unchanged.
|
||
//
|
||
// vc=20 / 0.1.0-AF — channel-videos fix on top of the rust pipeline
|
||
// cutover. vc=19 returned empty subscription feeds because
|
||
// strawcore-core's channel_info wasn't doing the second browse for the
|
||
// Videos tab AND wasn't parsing the new lockupViewModel shape.
|
||
//
|
||
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
|
||
// strawcore-core (Sulkta-Coop/strawcore) via the UniFFI wrapper; no
|
||
// NewPipeExtractor in the runtime path.
|
||
const val STRAW_VERSION_CODE = 48
|
||
const val STRAW_VERSION_NAME = "0.1.0-BH"
|
||
const val STRAW_APPLICATION_ID = "com.sulkta.straw"
|