diff options
Diffstat (limited to 'app/src/main')
| -rw-r--r-- | app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt | 50 |
1 files changed, 49 insertions, 1 deletions
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 3bd6e3e..5f8eca7 100644 --- a/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt +++ b/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt @@ -44,6 +44,7 @@ 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.FeedEntity import org.terst.feedreader.data.FilterAction import org.terst.feedreader.data.FilterRuleEntity import org.terst.feedreader.data.Net @@ -73,6 +74,11 @@ fun SettingsScreen(onBack: () -> Unit) { var newRuleAction by remember { mutableStateOf(FilterAction.MUTE) } var actionMenuExpanded by remember { mutableStateOf(false) } val rules by db.filterRuleDao().observeAll().collectAsState(initial = emptyList()) + val feeds by db.feedDao().observeAll().collectAsState(initial = emptyList()) + val feedTitleById = remember(feeds) { feeds.associate { it.id to it.title } } + // null = applies to every feed (the only option before this scope picker existed). + var newRuleFeedId by remember { mutableStateOf<String?>(null) } + var feedMenuExpanded by remember { mutableStateOf(false) } Scaffold( topBar = { @@ -189,6 +195,14 @@ fun SettingsScreen(onBack: () -> Unit) { } } Spacer(modifier = Modifier.height(8.dp)) + FeedScopePicker( + feeds = feeds, + selectedFeedId = newRuleFeedId, + expanded = feedMenuExpanded, + onExpandedChange = { feedMenuExpanded = it }, + onSelect = { newRuleFeedId = it } + ) + Spacer(modifier = Modifier.height(8.dp)) Button( enabled = newRulePattern.isNotBlank(), onClick = { @@ -197,10 +211,12 @@ fun SettingsScreen(onBack: () -> Unit) { FilterRuleEntity( pattern = newRulePattern.trim(), action = newRuleAction, + feedId = newRuleFeedId, createdAt = System.currentTimeMillis() ) ) newRulePattern = "" + newRuleFeedId = null } }, modifier = Modifier.fillMaxWidth() @@ -211,7 +227,11 @@ fun SettingsScreen(onBack: () -> Unit) { items(rules, key = { it.id }) { rule -> ListItem( headlineContent = { Text(rule.pattern) }, - supportingContent = { Text(if (rule.action == FilterAction.MUTE) "Mute" else "Highlight") }, + supportingContent = { + val actionLabel = if (rule.action == FilterAction.MUTE) "Mute" else "Highlight" + val scopeLabel = rule.feedId?.let { feedTitleById[it] ?: it } ?: "All feeds" + Text("$actionLabel · $scopeLabel") + }, trailingContent = { IconButton(onClick = { scope.launch { db.filterRuleDao().delete(rule.id) } }) { Icon(Icons.Default.Delete, contentDescription = "Delete rule") @@ -223,3 +243,31 @@ fun SettingsScreen(onBack: () -> Unit) { } } } + +/** Scope picker for a new filter rule: "All feeds" (feedId = null) or one specific feed. */ +@Composable +private fun FeedScopePicker( + feeds: List<FeedEntity>, + selectedFeedId: String?, + expanded: Boolean, + onExpandedChange: (Boolean) -> Unit, + onSelect: (String?) -> Unit +) { + Box { + Button(onClick = { onExpandedChange(true) }, modifier = Modifier.fillMaxWidth()) { + Text(feeds.find { it.id == selectedFeedId }?.title ?: "All feeds") + } + DropdownMenu(expanded = expanded, onDismissRequest = { onExpandedChange(false) }) { + DropdownMenuItem( + text = { Text("All feeds") }, + onClick = { onSelect(null); onExpandedChange(false) } + ) + feeds.forEach { feed -> + DropdownMenuItem( + text = { Text(feed.title) }, + onClick = { onSelect(feed.id); onExpandedChange(false) } + ) + } + } + } +} |
