straw/buildSrc/src/main/kotlin/ProjectConfig.kt
Sulkta 005aef395c Fix ExoPlayer wrong-thread crash + recordSearch off Main (perf-audit pass-2) — vc=79
- PlaybackService: the pauseOnHeadphoneDisconnect settings-watcher collector
  ran on globalScope (Dispatchers.IO) and called setHandleAudioBecomingNoisy
  on the ExoPlayer, which is thread-affine to the Main thread it was built on
  → latent IllegalStateException('Player accessed on the wrong thread') that
  fires every service start (the StateFlow emits on first subscription). Run
  the collector on Dispatchers.Main (mirrors resumePollJob).
- SearchViewModel: recordSearch (json-encode + SharedPrefs write) was on Main;
  wrap in withContext(Dispatchers.IO).

Both adversarially verified in the multi-agent perf audit (pass 2).
2026-06-21 05:04:39 -07:00

113 lines
6.2 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* SPDX-FileCopyrightText: 2026 Sulkta
* SPDX-License-Identifier: GPL-3.0-or-later
*/
const val STRAW_SDK_COMPILE_MAJOR = 36
const val STRAW_SDK_COMPILE_MINOR = 1
const val STRAW_SDK_TARGET = 35
// Sulkta fork — Straw
//
// vc=79 / 0.1.0-CM — perf-audit pass-2 (app-side slam-dunks):
// * FIX a wrong-thread crash: the headphone-disconnect settings watcher
// ran on the IO scope and touched the ExoPlayer (thread-affine to the
// Main thread it was built on) → "Player accessed on the wrong thread"
// latent on every session. Collector now runs on Dispatchers.Main.
// * recordSearch (json-encode + SharedPrefs write) moved off the Main
// thread into withContext(Dispatchers.IO).
//
// vc=78 / 0.1.0-CL — perf-audit batch 1 (app-side):
// * Autoplay-next no longer drops the user's max-resolution cap. The
// enter-video track-selection reset built params from scratch, wiping
// the data-saver ceiling on every URL change; now it re-enables the
// video track surgically + re-asserts applyMaxResolutionCap().
// * VideoDetail body is now a LazyColumn, not a verticalScroll Column.
// The related + more-from-channel lists recycle and defer each row's
// image decode + its two progress-overlay flow collectors until
// scrolled into view (was ~40 decodes + ~80 collectors mounted eagerly
// on every video open). Namespaced item keys; dialogs hoisted out.
//
// vc=77 / 0.1.0-CK — morph perf: static poster during collapse/morph:
// * The minibar + the whole collapse/expand morph now render the video's
// static poster, not the live TextureView. Scaling a live-playing
// TextureView through the morph's graphicsLayer every frame was the
// remaining sluggishness; the live PlayerView only mounts once settled
// fully expanded. Audio is unaffected (it's in the foreground service).
//
// vc=76 / 0.1.0-CJ — expandable-player smoothness pass:
// * The detail body no longer renders to an offscreen buffer every
// frame during the morph (CompositingStrategy.ModulateAlpha) — that
// offscreen alpha pass on the whole scroll subtree was the main
// cause of the sluggish feel.
// * Morph animation is now a snappy no-bounce spring instead of a
// 300ms FastOutSlowIn tween (which ramped slowly at both ends).
//
// vc=75 / 0.1.0-CI — expandable player (full rearchitect):
// * The video page and the bottom minibar are now ONE container that
// morphs continuously between them, both directions. Replaces the
// old separate Screen.VideoDetail page + MinibarOverlay (which just
// appeared/vanished). One fraction (0=minibar, 1=full page) drives a
// graphicsLayer scale+translate on a single mounted TextureView, so
// the morph runs in the render phase (smooth) and the same video
// surface stays live across the whole range — a true shared-element
// transition. Swipe the player down → it shrinks into the toolbar;
// swipe/tap the toolbar up → it grows back into the page.
// * Opening a video is no longer a nav push — it sets OpenVideo +
// expands. The browse screen underneath stays put, so collapsing
// drops you right back where you were.
// * Playback plumbing unchanged: shared controller, NowPlaying,
// setPlayingFrom, SponsorBlock, autoplay-next, PiP, background audio,
// and the true-fullscreen Player (⛶) all still key off NowPlaying.
//
// vc=73 / 0.1.0-CG — VideoDetail cleanup:
// * Inline player → TextureView surface so the swipe-down-to-minimize
// drag is smooth (a SurfaceView won't follow the Compose graphicsLayer
// transform — that was the stutter).
// * Description folded into a collapsible "Details" section, collapsed
// by default, sitting just above the recommendations.
// * Action buttons restyled into one tidy horizontally-scrollable row
// of uniform icon pills (dropped the redundant "Play").
//
// 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-OSS/strawcore) via the UniFFI wrapper; no
// NewPipeExtractor in the runtime path.
const val STRAW_VERSION_CODE = 79
const val STRAW_VERSION_NAME = "0.1.0-CM"
const val STRAW_APPLICATION_ID = "com.sulkta.straw"