summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-10-16 02:33:51 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-10-16 02:33:51 +0000
commit146d750ebb38ba91f04e9747a26052b78dcf14c1 (patch)
tree6bdfab9273e2a9c383e972e0226471c4a58ee7d1
parentaf281fa817ce2691bb460e30ce183798af282244 (diff)
Trim offered playback speeds to 1x, 1.1x, 1.25x, 2x
1.1 and 1.25 cover the gap 1x leaves and 2x is the fastest speech stays easy to follow at; 1.5x and 1.75x are dropped. A show, episode or rule speed stored before this change keeps playing at its old value -- the speed pickers just don't highlight a chip for it, same as any value typed outside the list already worked. speedLabel() is made internal and covered by a test; Float.toString() already formats 1.1x correctly on the JVM, so no formatting fix was needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
-rw-r--r--app/src/main/java/org/terst/listen/ui/PlayerScreen.kt6
-rw-r--r--app/src/main/java/org/terst/listen/ui/RuleEditScreen.kt2
-rw-r--r--app/src/test/java/org/terst/listen/ui/SpeedLabelTest.kt35
3 files changed, 39 insertions, 4 deletions
diff --git a/app/src/main/java/org/terst/listen/ui/PlayerScreen.kt b/app/src/main/java/org/terst/listen/ui/PlayerScreen.kt
index d9dd5e6..b826406 100644
--- a/app/src/main/java/org/terst/listen/ui/PlayerScreen.kt
+++ b/app/src/main/java/org/terst/listen/ui/PlayerScreen.kt
@@ -44,8 +44,8 @@ import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import org.terst.listen.feed.Chapter
-/** Offered speeds. Beyond 2x speech becomes hard to follow, so the list stops there. */
-private val SPEEDS = listOf(1.0f, 1.25f, 1.5f, 1.75f, 2.0f)
+/** Offered speeds. 1.0x stays in the list as the way back to normal. */
+private val SPEEDS = listOf(1.0f, 1.1f, 1.25f, 2.0f)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -241,7 +241,7 @@ private fun SpeedRow(current: Float, onSelect: (Float) -> Unit) {
private val SPEED_PADDING = androidx.compose.foundation.layout.PaddingValues(horizontal = 12.dp, vertical = 6.dp)
/** Drops the trailing zero so 1.0x and 1.5x are as short as they can be. */
-private fun speedLabel(speed: Float): String {
+internal fun speedLabel(speed: Float): String {
val text = if (speed % 1f == 0f) speed.toInt().toString() else speed.toString().trimEnd('0').trimEnd('.')
return "${text}\u00d7"
}
diff --git a/app/src/main/java/org/terst/listen/ui/RuleEditScreen.kt b/app/src/main/java/org/terst/listen/ui/RuleEditScreen.kt
index 5215c88..2462871 100644
--- a/app/src/main/java/org/terst/listen/ui/RuleEditScreen.kt
+++ b/app/src/main/java/org/terst/listen/ui/RuleEditScreen.kt
@@ -40,7 +40,7 @@ import org.terst.listen.data.SubscriptionEntity
import org.terst.listen.queue.RuleSummary
/** Speeds a rule can pin an episode to. Matches the settings screen's list. */
-private val RULE_SPEEDS = listOf(1.0f, 1.25f, 1.5f, 1.75f, 2.0f)
+private val RULE_SPEEDS = listOf(1.0f, 1.1f, 1.25f, 2.0f)
private val ACTIONS = listOf(
RuleAction.QUEUE_TOP to "Queue at top",
diff --git a/app/src/test/java/org/terst/listen/ui/SpeedLabelTest.kt b/app/src/test/java/org/terst/listen/ui/SpeedLabelTest.kt
new file mode 100644
index 0000000..2f3a896
--- /dev/null
+++ b/app/src/test/java/org/terst/listen/ui/SpeedLabelTest.kt
@@ -0,0 +1,35 @@
+package org.terst.listen.ui
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Compact speed chip labels, including 1.1x -- the one new offered speed whose decimal digit is
+ * not a round number and so is the one most at risk of a trailing-zero formatter mangling it
+ * (e.g. dropping the "1" and reading as "1x", or losing the point and reading as "11x").
+ *
+ * Also covers 1.5x and 1.75x, which the settings and player screens no longer offer as choices
+ * but which a show, episode or rule saved before this change can still be carrying -- see
+ * [org.terst.listen.playback.PlaybackSpeedTest] for the precedence that value still has to win.
+ */
+class SpeedLabelTest {
+
+ @Test
+ fun `whole numbers drop the decimal point`() {
+ assertEquals("1×", speedLabel(1.0f))
+ assertEquals("2×", speedLabel(2.0f))
+ }
+
+ @Test
+ fun `a single decimal place survives intact`() {
+ assertEquals("1.1×", speedLabel(1.1f))
+ assertEquals("1.25×", speedLabel(1.25f))
+ }
+
+ /** No longer offered, but a value stored before this change must still render correctly. */
+ @Test
+ fun `a speed outside the offered list still formats correctly`() {
+ assertEquals("1.5×", speedLabel(1.5f))
+ assertEquals("1.75×", speedLabel(1.75f))
+ }
+}