Reach the gear from the top of the menu, and drop a stale message (0.73.1)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# Orbit TV 0.73.1: gear reach
|
||||
|
||||
Found walking through 0.73 on the box. Up from All Channels did nothing, so the gear could only be reached through the picture; it now goes straight there. A leftover "Saved connection restored" message no longer sits at the top of Channels.
|
||||
|
||||
On 0.73, by remote keys on the box: Settings opened, Channels showed 29 of 29 on, Watching and Back behaved, Terra and Paradox topped up again on 201 and 106, and the catalogue was unchanged. Checked here: build, lint and all unit tests pass. The fix isn't checked on the box until installed.
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId = "tv.orbit.classic"
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
versionCode = 76
|
||||
versionName = "0.73.0-only-whats-needed"
|
||||
versionCode = 77
|
||||
versionName = "0.73.1-gear-reach"
|
||||
}
|
||||
buildFeatures { compose = true }
|
||||
compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 }
|
||||
|
||||
@@ -66,7 +66,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.73.0\"")
|
||||
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.73.1\"")
|
||||
request.token?.let { connection.setRequestProperty("X-Emby-Token", it) }
|
||||
if (request.method == "POST") {
|
||||
val bytes = request.body.orEmpty().toByteArray(Charsets.UTF_8)
|
||||
|
||||
@@ -188,7 +188,6 @@ internal fun EmbyConnectionScreen(modifier: Modifier = Modifier, visible: Boolea
|
||||
} catch (cancelled: CancellationException) { throw cancelled } catch (_: Exception) { emptyMap() }
|
||||
session = resumed; sample = resumed.sample; applyChoices(saved)
|
||||
saveTicket = savedStore.ticket()
|
||||
message = "Saved connection restored."
|
||||
} else if (saved != null && session == null) message = "Sign in again to restore your saved channel choices."
|
||||
} catch (cancelled: CancellationException) { throw cancelled }
|
||||
catch (failure: EmbyCheckException) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusProperties
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -127,12 +128,13 @@ internal fun HomeScreen(session: EmbySampleSession, channels: List<SampleChannel
|
||||
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
||||
LaunchedEffect(Unit) { while (true) { delay(1000); now = System.currentTimeMillis() } }
|
||||
val firstFocus = remember { FocusRequester() }
|
||||
val gear = LocalGearFocus.current
|
||||
LaunchedEffect(Unit) { firstFocus.requestFocus() }
|
||||
Column(modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(Modifier.fillMaxWidth().weight(1f), horizontalArrangement = Arrangement.spacedBy(14.dp)) {
|
||||
Column(Modifier.width(176.dp).fillMaxHeight(), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
homeCategories(channels.map { it.number }).forEachIndexed { index, category ->
|
||||
HomeCard(Modifier.fillMaxWidth().weight(1f), if (index == 0) firstFocus else null, onClick = { onCategory(category) }) { focused ->
|
||||
HomeCard(Modifier.fillMaxWidth().weight(1f).focusProperties { if (index == 0 && gear != null) up = gear }, if (index == 0) firstFocus else null, onClick = { onCategory(category) }) { focused ->
|
||||
Row(Modifier.fillMaxSize().padding(horizontal = 10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
Image(painterResource(category.icon), null, Modifier.size(26.dp), colorFilter = if (focused) ColorFilter.tint(Navy) else null)
|
||||
Text(category.label, color = if (focused) Navy else Color.White, fontSize = 15.sp, fontWeight = FontWeight.SemiBold, maxLines = 1)
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
@@ -32,6 +33,8 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/** The gear, so the menu's top row can reach it directly. Left to itself, up finds nothing above the first column. */
|
||||
internal val LocalGearFocus = staticCompositionLocalOf<FocusRequester?> { null }
|
||||
internal val Barlow = FontFamily(Font(R.font.barlow_regular), Font(R.font.barlow_semibold, FontWeight.SemiBold), Font(R.font.barlow_semibold, FontWeight.Bold))
|
||||
internal val Navy = Color(0xFF071632)
|
||||
internal val Panel = Color(0xFF12356B)
|
||||
@@ -82,7 +85,9 @@ private fun OrbitApp() {
|
||||
}
|
||||
// Back on the main menu closes the app.
|
||||
BackHandler(realChannelAvailable && section != "TV Guide" && section != "Home") { section = "Home" }
|
||||
val gearFocus = remember { FocusRequester() }
|
||||
Box(Modifier.fillMaxSize().background(Navy)) {
|
||||
CompositionLocalProvider(LocalGearFocus provides gearFocus) {
|
||||
// The Drive-In takes the whole screen.
|
||||
Column(if (section == "Drive-In") Modifier.fillMaxSize() else Modifier.fillMaxSize().padding(horizontal = 36.dp, vertical = 16.dp)) {
|
||||
if (section != "Drive-In") {
|
||||
@@ -92,7 +97,7 @@ private fun OrbitApp() {
|
||||
Text(SimpleDateFormat("EEE d MMM HH:mm", Locale.UK).format(Date(now)), color = Color.White, fontSize = 17.sp)
|
||||
if (realChannelAvailable) {
|
||||
Spacer(Modifier.width(12.dp))
|
||||
HomeCard(Modifier.size(38.dp, 32.dp), onClick = { section = "Connect Emby" }) { focused ->
|
||||
HomeCard(Modifier.size(38.dp, 32.dp), gearFocus, onClick = { section = "Connect Emby" }) { focused ->
|
||||
Image(painterResource(R.drawable.orbit_icon_gear), "Settings", Modifier.fillMaxSize().padding(5.dp), colorFilter = if (focused) ColorFilter.tint(Navy) else null)
|
||||
}
|
||||
}
|
||||
@@ -107,5 +112,6 @@ private fun OrbitApp() {
|
||||
onChannelAvailable = { realChannelAvailable = it }, onRestoreChecked = { restoreChecked = true },
|
||||
onGuide = { section = "TV Guide" }, onHome = { section = "Home" }, onDriveIn = { section = "Drive-In" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.73.0")
|
||||
next.setRequestProperty("User-Agent", "OrbitTV/0.73.1")
|
||||
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()) {
|
||||
|
||||
Reference in New Issue
Block a user