summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-10-14 17:03:20 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-10-14 17:03:20 +0000
commit061e1f8b7a0eb3d182fb63b716e583d2df25bfc4 (patch)
tree601436de45b7899e1abd74191837d6d6abcd4581 /app
parent687e2bd0f94e5c7dfa925609151c4df4e10ce97b (diff)
Put the furniture toggle on screen
Settings now has a switch for skipping a show's own intro, break cue and credits, following the existing Compose state-holder pattern (rememberFurnitureSkipSettings) rather than inventing a view model -- there isn't one in this app. Bundled with SkipServerSettings into a single SkipSettings parameter to stay under detekt's parameter-count limit, since both live in the same settings section. Advertising has no toggle and stays always-skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/org/terst/listen/ui/FurnitureSkipSettingsState.kt40
-rw-r--r--app/src/main/java/org/terst/listen/ui/MainActivity.kt2
-rw-r--r--app/src/main/java/org/terst/listen/ui/SettingsScreen.kt14
-rw-r--r--app/src/main/java/org/terst/listen/ui/SkipServerSettingsState.kt19
4 files changed, 71 insertions, 4 deletions
diff --git a/app/src/main/java/org/terst/listen/ui/FurnitureSkipSettingsState.kt b/app/src/main/java/org/terst/listen/ui/FurnitureSkipSettingsState.kt
new file mode 100644
index 0000000..ad0474b
--- /dev/null
+++ b/app/src/main/java/org/terst/listen/ui/FurnitureSkipSettingsState.kt
@@ -0,0 +1,40 @@
+package org.terst.listen.ui
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.platform.LocalContext
+import kotlinx.coroutines.launch
+import org.terst.listen.data.Graph
+
+/**
+ * Reads and writes whether a show's own intro, break cue and credits are skipped.
+ *
+ * Trivial glue, kept out of the composable that renders it, same reason and same shape as
+ * [rememberSkipServerSettings]: DataStore rather than Room, and a screen that stays a screen.
+ * Advertising has no toggle here on purpose -- it is always skipped and that is not meant to be
+ * configurable.
+ */
+@Composable
+internal fun rememberFurnitureSkipSettings(): FurnitureSkipSettings {
+ val context = LocalContext.current
+ val preferences = remember(context) { Graph.get(context).preferences }
+ val scope = rememberCoroutineScope()
+
+ val skipShowFurniture by preferences.skipShowFurniture.collectAsState(initial = true)
+
+ return FurnitureSkipSettings(
+ skipShowFurniture = skipShowFurniture,
+ onSkipShowFurnitureChange = { value ->
+ scope.launch { preferences.setSkipShowFurniture(value) }
+ },
+ )
+}
+
+/** Whether the show's own furniture is skipped, as the settings screen reads and writes it. */
+data class FurnitureSkipSettings(
+ val skipShowFurniture: Boolean,
+ val onSkipShowFurnitureChange: (Boolean) -> Unit,
+)
diff --git a/app/src/main/java/org/terst/listen/ui/MainActivity.kt b/app/src/main/java/org/terst/listen/ui/MainActivity.kt
index 771e844..2558937 100644
--- a/app/src/main/java/org/terst/listen/ui/MainActivity.kt
+++ b/app/src/main/java/org/terst/listen/ui/MainActivity.kt
@@ -229,7 +229,7 @@ private fun NavGraphBuilder.settingsRoute(
SettingsScreen(
opml = opml,
player = player,
- server = rememberSkipServerSettings(),
+ skip = rememberSkipSettings(),
onOpenRules = { nav.navigate("rules") },
onBack = { nav.popBackStack() },
)
diff --git a/app/src/main/java/org/terst/listen/ui/SettingsScreen.kt b/app/src/main/java/org/terst/listen/ui/SettingsScreen.kt
index 9afa3e9..5da9e85 100644
--- a/app/src/main/java/org/terst/listen/ui/SettingsScreen.kt
+++ b/app/src/main/java/org/terst/listen/ui/SettingsScreen.kt
@@ -50,7 +50,7 @@ private val OPML_MIME_TYPES = arrayOf("text/x-opml", "text/xml", "application/xm
fun SettingsScreen(
opml: OpmlViewModel,
player: PlayerViewModel,
- server: SkipServerSettings,
+ skip: SkipSettings,
onOpenRules: () -> Unit,
onBack: () -> Unit,
) {
@@ -108,7 +108,7 @@ fun SettingsScreen(
onExport = { exportLauncher.launch("listen-subscriptions.opml") },
)
HorizontalDivider()
- SkipServerSection(server)
+ SkipServerSection(skip.server, skip.furniture)
}
}
}
@@ -133,7 +133,7 @@ data class SkipServerSettings(
* Left blank the app behaves as it did before: downloads from publishers, no detected skips.
*/
@Composable
-private fun SkipServerSection(settings: SkipServerSettings) {
+private fun SkipServerSection(settings: SkipServerSettings, furniture: FurnitureSkipSettings) {
var url by remember(settings.url) { mutableStateOf(settings.url) }
var token by remember(settings.token) { mutableStateOf(settings.token) }
@@ -162,6 +162,14 @@ private fun SkipServerSection(settings: SkipServerSettings) {
},
style = MaterialTheme.typography.bodySmall,
)
+ SwitchRow(
+ label = "Skip the show's own intro and credits",
+ description = "Turn skipping the show's own intro and credits on or off",
+ checked = furniture.skipShowFurniture,
+ onCheckedChange = furniture.onSkipShowFurnitureChange,
+ detail = "Advertising is always skipped. This covers a show's opening theme, " +
+ "its break cue and its closing credits.",
+ )
}
}
diff --git a/app/src/main/java/org/terst/listen/ui/SkipServerSettingsState.kt b/app/src/main/java/org/terst/listen/ui/SkipServerSettingsState.kt
index fc0e49d..3dceb80 100644
--- a/app/src/main/java/org/terst/listen/ui/SkipServerSettingsState.kt
+++ b/app/src/main/java/org/terst/listen/ui/SkipServerSettingsState.kt
@@ -33,3 +33,22 @@ internal fun rememberSkipServerSettings(): SkipServerSettings {
},
)
}
+
+/**
+ * The skip server address/token and the show-furniture toggle, bundled as one parameter.
+ *
+ * They are two different preferences -- [SkipServerSettings] is where detection comes from,
+ * [FurnitureSkipSettings] is which of what it finds gets acted on -- but the settings screen
+ * renders them in the same section, and passing them separately pushed `SettingsScreen` past
+ * detekt's parameter-count limit.
+ */
+data class SkipSettings(
+ val server: SkipServerSettings,
+ val furniture: FurnitureSkipSettings,
+)
+
+@Composable
+internal fun rememberSkipSettings(): SkipSettings = SkipSettings(
+ server = rememberSkipServerSettings(),
+ furniture = rememberFurnitureSkipSettings(),
+)