From 0cd94d0821661fef3fc34b51011be95034e51a5b Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Mon, 31 Aug 2026 15:43:02 +0000 Subject: Add reader font size setting, rewrite paywall-avoidance settings copy Font size was hardcoded at 18px in ReaderWebView's injected CSS. Added a DataStore-backed setting (Settings.readerFontSizePx, 14-28px range) with a slider in Settings, threaded through ReaderScreen/ReaderContent into wrapReaderHtml. The reload-tracking key in ReaderContent's AndroidView now includes font size alongside content, so changing it and returning to an already-open article picks up the new size without reloading on every unrelated recomposition (matches the existing comment there about avoiding scroll-position jank). Rewrote the Settings screen's paywall note -- it read as defensive throat-clearing about what the app won't do. Restated as what it's actually for: avoiding tracking, manipulation, and junk fees, with reader mode pulling up anything findable by search anyway. Regenerated the detekt baseline: ReaderContent's pre-existing LongMethod/LongParameterList/CyclomaticComplexMethod findings are keyed by exact function signature text, and adding the fontSizePx parameter changed that text, invalidating the old baseline entries. The underlying debt (a 300+ line, 9-now-10-parameter composable) predates this change and isn't what this commit is about. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B --- .../java/org/terst/feedreader/ui/SettingsScreen.kt | 32 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt') diff --git a/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt b/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt index 5f8eca7..966d36b 100644 --- a/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt +++ b/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt @@ -27,6 +27,7 @@ import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold +import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable @@ -44,13 +45,16 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import kotlinx.coroutines.launch import org.terst.feedreader.data.AppDatabase +import org.terst.feedreader.data.DEFAULT_READER_FONT_SIZE_PX import org.terst.feedreader.data.FeedEntity import org.terst.feedreader.data.FilterAction import org.terst.feedreader.data.FilterRuleEntity import org.terst.feedreader.data.Net +import org.terst.feedreader.data.READER_FONT_SIZE_RANGE_PX import org.terst.feedreader.data.Settings import org.terst.feedreader.stash.StashClient import org.terst.feedreader.stash.StashVerifyResult +import kotlin.math.roundToInt @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -65,9 +69,11 @@ fun SettingsScreen(onBack: () -> Unit) { var stashKeyVisible by remember { mutableStateOf(false) } var isVerifyingStash by remember { mutableStateOf(false) } var stashStatus by remember { mutableStateOf(null) } + var fontSizePx by remember { mutableStateOf(DEFAULT_READER_FONT_SIZE_PX) } LaunchedEffect(Unit) { stashUrl = settings.stashBaseUrlNow() stashKey = settings.stashApiKeyNow() + fontSizePx = settings.readerFontSizePxNow() } var newRulePattern by remember { mutableStateOf("") } @@ -98,16 +104,34 @@ fun SettingsScreen(onBack: () -> Unit) { Text("FeeDreader", style = MaterialTheme.typography.titleMedium) Spacer(modifier = Modifier.height(4.dp)) Text( - "If a site paywalls its own feed, that's the site's call. But this reader " + - "won't go out of its way to help a soft paywall block you from reading " + - "something you already subscribed to get -- reader mode extracts the " + - "article you were sent, nothing more, nothing sneaky.", + "FeeDreader exists to avoid tracking, manipulation, and junk fees. If an " + + "article's full text is something you could just as easily find with a " + + "search, reader mode will pull it up here too.", style = MaterialTheme.typography.bodyMedium ) } HorizontalDivider() } + item { + Column(modifier = Modifier.padding(16.dp)) { + Text("Reading", style = MaterialTheme.typography.titleMedium) + Spacer(modifier = Modifier.height(8.dp)) + Text("Font size: ${fontSizePx}px", style = MaterialTheme.typography.bodyMedium) + Slider( + value = fontSizePx.toFloat(), + onValueChange = { fontSizePx = it.roundToInt() }, + valueRange = READER_FONT_SIZE_RANGE_PX.first.toFloat()..READER_FONT_SIZE_RANGE_PX.last.toFloat(), + steps = READER_FONT_SIZE_RANGE_PX.last - READER_FONT_SIZE_RANGE_PX.first - 1, + // Persist on release, not on every onValueChange -- a drag crosses many + // integer values in a fraction of a second, and there's no reason to hit + // DataStore that often for a value nothing reads until the next article load. + onValueChangeFinished = { scope.launch { settings.setReaderFontSizePx(fontSizePx) } } + ) + } + HorizontalDivider() + } + item { Column(modifier = Modifier.padding(16.dp)) { Text("Stash", style = MaterialTheme.typography.titleMedium) -- cgit v1.2.3