summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/androidTest/java/org/terst/listen/ui/LibraryRowTest.kt42
-rw-r--r--app/src/main/java/org/terst/listen/ui/EpisodeTransport.kt8
-rw-r--r--app/src/main/java/org/terst/listen/ui/SubscriptionRow.kt13
3 files changed, 59 insertions, 4 deletions
diff --git a/app/src/androidTest/java/org/terst/listen/ui/LibraryRowTest.kt b/app/src/androidTest/java/org/terst/listen/ui/LibraryRowTest.kt
index a66337f..af45221 100644
--- a/app/src/androidTest/java/org/terst/listen/ui/LibraryRowTest.kt
+++ b/app/src/androidTest/java/org/terst/listen/ui/LibraryRowTest.kt
@@ -4,7 +4,9 @@ import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.performTouchInput
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Rule
@@ -108,6 +110,46 @@ class LibraryRowTest {
}
/**
+ * Press and hold a show to play what it is offering.
+ *
+ * The same gesture the episode list already had, and for the same reason: the row's three
+ * buttons are the deliberate ones, and "just play it" wants no width at all. Without this,
+ * playing the newest episode of a show from the library meant opening the show first.
+ */
+ @Test
+ fun holdingAShowPlaysTheEpisodeItOffers() {
+ var played = 0
+ compose.setContent {
+ SubscriptionRow(
+ listing = SubscriptionListing(show("s", "Zebra Hour"), waiting = 1),
+ latest = episode("e", "s", "The one about stripes"),
+ actions = noActions().copy(play = { played++ }),
+ ) {}
+ }
+
+ compose.onNodeWithText("The one about stripes").performTouchInput { longClick() }
+
+ assertEquals(1, played)
+ }
+
+ /** A tap still opens the show, so holding has not replaced the ordinary gesture. */
+ @Test
+ fun tappingAShowStillOpensIt() {
+ var opened = 0
+ compose.setContent {
+ SubscriptionRow(
+ listing = SubscriptionListing(show("s", "Zebra Hour"), waiting = 1),
+ latest = episode("e", "s", "The one about stripes"),
+ actions = noActions(),
+ ) { opened++ }
+ }
+
+ compose.onNodeWithText("Zebra Hour").performClick()
+
+ assertEquals(1, opened)
+ }
+
+ /**
* Marking it played is the control that was missing, and the reason the row changed: saying
* "not now" without opening the show is what sends a long library back to being scrollable.
*/
diff --git a/app/src/main/java/org/terst/listen/ui/EpisodeTransport.kt b/app/src/main/java/org/terst/listen/ui/EpisodeTransport.kt
index b8185bf..837b98a 100644
--- a/app/src/main/java/org/terst/listen/ui/EpisodeTransport.kt
+++ b/app/src/main/java/org/terst/listen/ui/EpisodeTransport.kt
@@ -112,13 +112,17 @@ fun EpisodeTransport(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
+ // Sleep, speed, ad -- Peter's order, and it was backwards. Sleep is the one set
+ // deliberately before settling down, so it gets the near edge; the ad button is
+ // pressed mid-listen when something slips through, so it sits furthest out where a
+ // stray press costs least.
+ SleepChip(sleep, onSleep)
+ SpeedChip(speed, actions.setSpeed)
// A circle-and-slash, the same mark the notification uses, so the two read as one
// control in two places rather than two features.
IconButton(onClick = actions.reportAd, enabled = playback.isPlaying) {
Icon(Icons.Default.Block, contentDescription = "This is an ad")
}
- SpeedChip(speed, actions.setSpeed)
- SleepChip(sleep, onSleep)
}
}
}
diff --git a/app/src/main/java/org/terst/listen/ui/SubscriptionRow.kt b/app/src/main/java/org/terst/listen/ui/SubscriptionRow.kt
index 7b793bb..c8b2dd5 100644
--- a/app/src/main/java/org/terst/listen/ui/SubscriptionRow.kt
+++ b/app/src/main/java/org/terst/listen/ui/SubscriptionRow.kt
@@ -1,7 +1,8 @@
package org.terst.listen.ui
import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -45,6 +46,7 @@ private const val CAUGHT_UP_ALPHA = 0.38f
* refresh looks exactly like a feed with nothing new, and that is the one case where "nothing
* waiting" is a lie worth shouting about.
*/
+@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun SubscriptionRow(
listing: SubscriptionListing,
@@ -56,7 +58,14 @@ internal fun SubscriptionRow(
val alpha = if (listing.hasWaiting) 1f else CAUGHT_UP_ALPHA
Row(
- Modifier.fillMaxWidth().clickable(onClick = onClick).padding(start = 16.dp, end = 4.dp),
+ Modifier
+ .fillMaxWidth()
+ // Tap opens the show; press and hold plays what it is offering. The same pair the
+ // episode list carries, for the same reason -- the three buttons are the deliberate
+ // actions, and "just play it" should cost no width. Null when the show is offering
+ // nothing, so holding an empty row does nothing rather than something arbitrary.
+ .combinedClickable(onClick = onClick, onLongClick = actions?.play)
+ .padding(start = 16.dp, end = 4.dp),
verticalAlignment = Alignment.Top,
) {
AsyncImage(