Stop the guide flashing on open; Back on the menu closes the app (0.34.0)
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 1m54s
pauljd/davidson-ci: Davidson CI / ai-review (push) Failing after 1m24s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-11-01 23:23:04 +00:00
co-authored by Claude Opus 5.5
parent bef3bfcc7c
commit 7002cd4a77
6 changed files with 25 additions and 13 deletions
+14
View File
@@ -0,0 +1,14 @@
# Orbit TV 0.34.0 verification
Two things Paul found on 0.33.
## Changed
- The guide no longer flashes on opening. The app now starts on the main menu's section rather than moving there once channels load.
- Back on the main menu closes the app, as Paul asked, instead of going full screen as in the design. OK on the picture still goes full screen. The menu's legend says so.
## Checked
- assembleDebug, testDebugUnitTest and lintDebug pass; 138 tests, 0 failures. None of these exercise opening or Back.
- APK signature verified with apksigner.
## Not checked
- Not yet run on the box. Opening, and Back on the menu, need Paul's on-TV check.
+2 -2
View File
@@ -9,8 +9,8 @@ android {
applicationId = "tv.orbit.classic"
minSdk = 26
targetSdk = 36
versionCode = 34
versionName = "0.33.0-open-home"
versionCode = 35
versionName = "0.34.0-back-closes"
}
buildFeatures { compose = true }
compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 }
@@ -41,7 +41,7 @@ internal class HttpsEmbyTransport(internal val deviceId: String = UUID.randomUUI
connection.connectTimeout = 10_000
connection.readTimeout = request.readTimeoutMs ?: if (request.path == "/Sessions/Logout") 5_000 else 15_000
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.33.0\"")
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.34.0\"")
request.token?.let { connection.setRequestProperty("X-Emby-Token", it) }
if (request.method == "POST") {
val bytes = request.body.orEmpty().toByteArray(Charsets.UTF_8)
@@ -1,6 +1,5 @@
package tv.orbit.classic
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -64,7 +63,7 @@ private fun ProgressBar(fraction: Float, modifier: Modifier = Modifier, focused:
}
}
/** Home opens onto the tuned channel playing, one press from anything else. Back takes it full screen. */
/** Home opens onto the tuned channel playing, one press from anything else. */
@Composable
internal fun HomeScreen(channels: List<SampleChannel>, tuned: SampleChannel, modifier: Modifier = Modifier,
picture: @Composable () -> Unit, onCategory: (ChannelCategory) -> Unit, onWatch: (Int) -> Unit, onDriveIn: () -> Unit) {
@@ -72,7 +71,6 @@ internal fun HomeScreen(channels: List<SampleChannel>, tuned: SampleChannel, mod
LaunchedEffect(Unit) { while (true) { delay(1000); now = System.currentTimeMillis() } }
val firstFocus = remember { FocusRequester() }
LaunchedEffect(Unit) { firstFocus.requestFocus() }
BackHandler { onWatch(tuned.number) }
Column(modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp)) {
Row(Modifier.fillMaxWidth().weight(1f), horizontalArrangement = Arrangement.spacedBy(14.dp)) {
Column(Modifier.width(176.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
@@ -135,6 +133,6 @@ internal fun HomeScreen(channels: List<SampleChannel>, tuned: SampleChannel, mod
}
}
}
Text("▲▼ Move OK Select ► Picture and events Back Full screen", color = Muted, fontSize = 11.sp)
Text("▲▼ Move OK Select ► Picture and events Back Close", color = Muted, fontSize = 11.sp)
}
}
@@ -72,7 +72,7 @@ private fun OrbitApp() {
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
LaunchedEffect(Unit) { while (true) { now = System.currentTimeMillis(); delay(1000) } }
var realChannelAvailable by remember { mutableStateOf(false) }
var section by remember { mutableStateOf("TV Guide") }
var section by remember { mutableStateOf("Home") }
// The demo guide is only for a box with no saved channels, so it waits until that's known.
var restoreChecked by remember { mutableStateOf(false) }
val showDemo = section == "TV Guide" && !realChannelAvailable && restoreChecked
@@ -84,9 +84,8 @@ private fun OrbitApp() {
var pinned by remember { mutableStateOf(false) }
val tabFocus = remember { List(3) { FocusRequester() } }
val gearFocus = remember { FocusRequester() }
LaunchedEffect(realChannelAvailable) {
if (realChannelAvailable && section == "TV Guide") section = "Home"
if (!realChannelAvailable && section == "Home") section = "TV Guide"
LaunchedEffect(realChannelAvailable, restoreChecked) {
if (!realChannelAvailable && restoreChecked && section == "Home") section = "TV Guide"
}
val programme = Schedule.programme(Schedule.channels[tuned], now)
val context = androidx.compose.ui.platform.LocalContext.current
@@ -133,7 +132,8 @@ private fun OrbitApp() {
lifecycle.addObserver(observer)
onDispose { lifecycle.removeObserver(observer) }
}
BackHandler(fullscreen || pinned || section != "TV Guide") {
// Back on the main menu, or on the demo guide, closes the app.
BackHandler(fullscreen || pinned || (section != "TV Guide" && section != "Home")) {
when { fullscreen -> fullscreen = false; pinned -> pinned = false; section == "Services" || section == "Connect Emby" -> section = "Menu"; else -> section = if (realChannelAvailable) "Home" else "TV Guide" }
}
LaunchedEffect(section, fullscreen, realChannelAvailable, restoreChecked) {
@@ -33,7 +33,7 @@ internal class SecureMediaDataSource(private val session: EmbySampleSession) : B
next.instanceFollowRedirects = false
next.connectTimeout = 10_000
next.readTimeout = 20_000
next.setRequestProperty("User-Agent", "OrbitTV/0.33.0")
next.setRequestProperty("User-Agent", "OrbitTV/0.34.0")
next.setRequestProperty("Accept-Encoding", "identity")
session.mediaHeaders(address).forEach { (key, value) -> next.setRequestProperty(key, value) }
if (dataSpec.position != 0L || dataSpec.length != C.LENGTH_UNSET.toLong()) {