From cd8f70b4ea3422fcd11d0fbf23985c207c95d27c Mon Sep 17 00:00:00 2001 From: Jonas Kalderstam Date: Tue, 3 Dec 2024 22:00:39 +0100 Subject: [PATCH] added setting for opening feeds drawer when pressing FAB fixes #425 Signed-off-by: Jonas Kalderstam --- .../feeder/archmodel/Repository.kt | 4 + .../feeder/archmodel/SettingsStore.kt | 10 + .../feeder/ui/compose/feed/FeedScreen.kt | 6 +- .../ui/compose/feedarticle/FeedViewModel.kt | 5 + .../feeder/ui/compose/settings/Settings.kt | 447 +++++++++--------- .../ui/compose/settings/SettingsViewModel.kt | 7 + app/src/main/res/values/strings.xml | 1 + 7 files changed, 259 insertions(+), 221 deletions(-) diff --git a/app/src/main/java/com/nononsenseapps/feeder/archmodel/Repository.kt b/app/src/main/java/com/nononsenseapps/feeder/archmodel/Repository.kt index 0f31401bc..14ff1ec75 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/archmodel/Repository.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/archmodel/Repository.kt @@ -292,6 +292,10 @@ class Repository(override val di: DI) : DIAware { fun setShowTitleUnreadCount(value: Boolean) = settingsStore.setShowTitleUnreadCount(value) + val isOpenDrawerOnFab = settingsStore.isOpenDrawerOnFab + + fun setOpenDrawerOnFab(value: Boolean) = settingsStore.setOpenDrawerOnFab(value) + /** * Returns true if the latest sync timestamp is within the last 10 seconds */ diff --git a/app/src/main/java/com/nononsenseapps/feeder/archmodel/SettingsStore.kt b/app/src/main/java/com/nononsenseapps/feeder/archmodel/SettingsStore.kt index cffa91c8f..b49dc5ef4 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/archmodel/SettingsStore.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/archmodel/SettingsStore.kt @@ -507,6 +507,14 @@ class SettingsStore(override val di: DI) : DIAware { sp.edit().putBoolean(PREF_SHOW_TITLE_UNREAD_COUNT, value).apply() } + private val _openDrawerOnFab = MutableStateFlow(sp.getBoolean(PREF_OPEN_DRAWER_ON_FAB, false)) + val isOpenDrawerOnFab = _openDrawerOnFab.asStateFlow() + + fun setOpenDrawerOnFab(value: Boolean) { + _openDrawerOnFab.value = value + sp.edit().putBoolean(PREF_OPEN_DRAWER_ON_FAB, value).apply() + } + fun getAllSettings(): Map { val all = sp.all ?: emptyMap() @@ -599,6 +607,8 @@ const val PREF_LIST_SHOW_ONLY_TITLES = "prefs_list_show_only_titles" const val PREF_LIST_SHOW_READING_TIME = "pref_show_reading_time" +const val PREF_OPEN_DRAWER_ON_FAB = "pref_open_drawer_on_fab" + /** * Read Aloud Settings */ diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feed/FeedScreen.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feed/FeedScreen.kt index 48527dbc6..aeea23a3e 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feed/FeedScreen.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feed/FeedScreen.kt @@ -5,7 +5,6 @@ import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.core.MutableTransitionState import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn @@ -906,7 +905,6 @@ fun FeedScreen( @OptIn( ExperimentalMaterial3Api::class, - ExperimentalAnimationApi::class, ) @Composable fun FeedScreen( @@ -957,7 +955,9 @@ fun FeedScreen( FloatingActionButton( onClick = { onMarkAllAsRead() - onOpenNavDrawer() + if (viewState.isOpenDrawerOnFab) { + onOpenNavDrawer() + } }, modifier = Modifier diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feedarticle/FeedViewModel.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feedarticle/FeedViewModel.kt index d9827a61c..e7036877d 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feedarticle/FeedViewModel.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/feedarticle/FeedViewModel.kt @@ -250,6 +250,8 @@ class FeedViewModel( repository.showReadingTime, repository.showTitleUnreadCount, repository.syncWorkerRunning, + // 25 + repository.isOpenDrawerOnFab, ) { params: Array -> val haveVisibleFeedItems = (params[7] as Int) > 0 val currentFeedOrTag = params[13] as FeedOrTag @@ -286,6 +288,7 @@ class FeedViewModel( showOnlyTitle = params[21] as Boolean, showReadingTime = params[22] as Boolean, showTitleUnreadCount = params[23] as Boolean, + isOpenDrawerOnFab = params[25] as Boolean, ) } .stateIn( @@ -417,6 +420,7 @@ data class FeedState( override val filter: FeedListFilter = emptyFeedListFilter, val isArticleOpen: Boolean = false, override val showTitleUnreadCount: Boolean = false, + override val isOpenDrawerOnFab: Boolean = false, ) : FeedScreenViewState @Immutable @@ -445,6 +449,7 @@ interface FeedScreenViewState { val filter: FeedListFilter val showFilterMenu: Boolean val showTitleUnreadCount: Boolean + val isOpenDrawerOnFab: Boolean } @Immutable diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/Settings.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/Settings.kt index eceb4d093..faab77f02 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/Settings.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/Settings.kt @@ -3,10 +3,12 @@ package com.nononsenseapps.feeder.ui.compose.settings import android.content.Intent import android.os.Build import android.provider.Settings +import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer @@ -208,6 +210,8 @@ fun SettingsScreen( }, openAIState = viewState.openAIState, onOpenAIEvent = settingsViewModel::onOpenAISettingsEvent, + isOpenDrawerOnFab = viewState.isOpenDrawerOnFab, + onOpenDrawerOnFab = settingsViewModel::setOpenDrawerOnFab, modifier = Modifier.padding(padding), ) } @@ -276,7 +280,9 @@ private fun SettingsScreenPreview() { onShowTitleUnreadCountChange = {}, onStartActivity = {}, openAIState = OpenAISettingsState(), - onOpenAIEvent = { _ -> }, + onOpenAIEvent = {}, + isOpenDrawerOnFab = false, + onOpenDrawerOnFab = {}, modifier = Modifier, ) } @@ -342,6 +348,8 @@ fun SettingsList( onStartActivity: (intent: Intent) -> Unit, openAIState: OpenAISettingsState, onOpenAIEvent: (OpenAISettingsEvent) -> Unit, + isOpenDrawerOnFab: Boolean, + onOpenDrawerOnFab: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { val scrollState = rememberScrollState() @@ -439,282 +447,285 @@ fun SettingsList( HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.text_scale), - modifier = innerModifier, + SettingsGroup( + title = R.string.text_scale, + ) { + ScaleSetting( + currentValue = textScale, + onValueChange = setTextScale, + valueRange = 1f..2f, + steps = 9, ) } - ScaleSetting( - currentValue = textScale, - onValueChange = setTextScale, - valueRange = 1f..2f, - steps = 9, - ) - HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.synchronization), - modifier = innerModifier, + SettingsGroup( + title = R.string.synchronization, + ) { + MenuSetting( + currentValue = currentSyncFrequencyValue.asSyncFreqOption(), + values = + ImmutableHolder( + SyncFrequency.values().map { + it.asSyncFreqOption() + }, + ), + title = stringResource(id = R.string.check_for_updates), + onSelection = { + onSyncFrequencyChange(it.syncFrequency) + }, ) - } - MenuSetting( - currentValue = currentSyncFrequencyValue.asSyncFreqOption(), - values = - ImmutableHolder( - SyncFrequency.values().map { - it.asSyncFreqOption() - }, - ), - title = stringResource(id = R.string.check_for_updates), - onSelection = { - onSyncFrequencyChange(it.syncFrequency) - }, - ) + SwitchSetting( + title = stringResource(id = R.string.on_startup), + checked = syncOnStartupValue, + onCheckedChange = onSyncOnStartupChange, + ) - SwitchSetting( - title = stringResource(id = R.string.on_startup), - checked = syncOnStartupValue, - onCheckedChange = onSyncOnStartupChange, - ) + SwitchSetting( + title = stringResource(id = R.string.only_on_wifi), + checked = syncOnlyOnWifiValue, + onCheckedChange = onSyncOnlyOnWifiChange, + ) - SwitchSetting( - title = stringResource(id = R.string.only_on_wifi), - checked = syncOnlyOnWifiValue, - onCheckedChange = onSyncOnlyOnWifiChange, - ) + SwitchSetting( + title = stringResource(id = R.string.only_when_charging), + checked = syncOnlyWhenChargingValue, + onCheckedChange = onSyncOnlyWhenChargingChange, + ) - SwitchSetting( - title = stringResource(id = R.string.only_when_charging), - checked = syncOnlyWhenChargingValue, - onCheckedChange = onSyncOnlyWhenChargingChange, - ) + MenuSetting( + currentValue = maxItemsPerFeedValue, + values = + immutableListHolderOf( + 50, + 100, + 200, + 500, + 1000, + ), + title = stringResource(id = R.string.max_feed_items), + onSelection = onMaxItemsPerFeedChange, + ) - MenuSetting( - currentValue = maxItemsPerFeedValue, - values = - immutableListHolderOf( - 50, - 100, - 200, - 500, - 1000, - ), - title = stringResource(id = R.string.max_feed_items), - onSelection = onMaxItemsPerFeedChange, - ) + ExternalSetting( + currentValue = + when (batteryOptimizationIgnoredValue) { + true -> stringResource(id = R.string.battery_optimization_disabled) + false -> stringResource(id = R.string.battery_optimization_enabled) + }, + title = stringResource(id = R.string.battery_optimization), + ) { + onStartActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)) + } - ExternalSetting( - currentValue = - when (batteryOptimizationIgnoredValue) { - true -> stringResource(id = R.string.battery_optimization_disabled) - false -> stringResource(id = R.string.battery_optimization_enabled) - }, - title = stringResource(id = R.string.battery_optimization), - ) { - onStartActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)) + ExternalSetting( + currentValue = "", + title = stringResource(id = R.string.device_sync), + ) { + onOpenSyncSettings() + } } - ExternalSetting( - currentValue = "", - title = stringResource(id = R.string.device_sync), + HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) + + SettingsGroup( + title = R.string.article_list_settings, ) { - onOpenSyncSettings() - } + MenuSetting( + currentValue = currentSortingValue, + values = + immutableListHolderOf( + SortingOptions.NEWEST_FIRST.asSortOption(), + SortingOptions.OLDEST_FIRST.asSortOption(), + ), + title = stringResource(id = R.string.sort), + onSelection = onSortingChange, + ) - HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) + SwitchSetting( + title = stringResource(id = R.string.show_fab), + checked = showFabValue, + onCheckedChange = onShowFabChange, + ) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.article_list_settings), - modifier = innerModifier, + SwitchSetting( + title = stringResource(id = R.string.open_drawer_on_fab), + checked = isOpenDrawerOnFab, + onCheckedChange = onOpenDrawerOnFab, ) - } - MenuSetting( - currentValue = currentSortingValue, - values = - immutableListHolderOf( - SortingOptions.NEWEST_FIRST.asSortOption(), - SortingOptions.OLDEST_FIRST.asSortOption(), - ), - title = stringResource(id = R.string.sort), - onSelection = onSortingChange, - ) + if (isCompactDevice()) { + MenuSetting( + title = stringResource(id = R.string.feed_item_style), + currentValue = feedItemStyleValue.asFeedItemStyleOption(), + values = ImmutableHolder(FeedItemStyle.values().map { it.asFeedItemStyleOption() }), + onSelection = { + onFeedItemStyleChange(it.feedItemStyle) + }, + ) + } - SwitchSetting( - title = stringResource(id = R.string.show_fab), - checked = showFabValue, - onCheckedChange = onShowFabChange, - ) + MenuSetting( + title = stringResource(id = R.string.max_lines), + currentValue = maxLines, + values = ImmutableHolder(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), + onSelection = setMaxLines, + ) + + SwitchSetting( + title = stringResource(id = R.string.show_only_title), + checked = showOnlyTitle, + onCheckedChange = onShowOnlyTitle, + ) - if (isCompactDevice()) { MenuSetting( - title = stringResource(id = R.string.feed_item_style), - currentValue = feedItemStyleValue.asFeedItemStyleOption(), - values = ImmutableHolder(FeedItemStyle.values().map { it.asFeedItemStyleOption() }), + title = stringResource(id = R.string.swipe_to_mark_as_read), + currentValue = swipeAsReadValue.asSwipeAsReadOption(), + values = ImmutableHolder(SwipeAsRead.values().map { it.asSwipeAsReadOption() }), onSelection = { - onFeedItemStyleChange(it.feedItemStyle) + onSwipeAsReadOptionChange(it.swipeAsRead) }, ) - } - - MenuSetting( - title = stringResource(id = R.string.max_lines), - currentValue = maxLines, - values = ImmutableHolder(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), - onSelection = setMaxLines, - ) - - SwitchSetting( - title = stringResource(id = R.string.show_only_title), - checked = showOnlyTitle, - onCheckedChange = onShowOnlyTitle, - ) - - MenuSetting( - title = stringResource(id = R.string.swipe_to_mark_as_read), - currentValue = swipeAsReadValue.asSwipeAsReadOption(), - values = ImmutableHolder(SwipeAsRead.values().map { it.asSwipeAsReadOption() }), - onSelection = { - onSwipeAsReadOptionChange(it.swipeAsRead) - }, - ) - SwitchSetting( - title = stringResource(id = R.string.mark_as_read_on_scroll), - checked = isMarkAsReadOnScroll, - onCheckedChange = onMarkAsReadOnScroll, - ) + SwitchSetting( + title = stringResource(id = R.string.mark_as_read_on_scroll), + checked = isMarkAsReadOnScroll, + onCheckedChange = onMarkAsReadOnScroll, + ) - SwitchSetting( - title = stringResource(id = R.string.show_thumbnails), - checked = showThumbnailsValue, - onCheckedChange = onShowThumbnailsChange, - ) + SwitchSetting( + title = stringResource(id = R.string.show_thumbnails), + checked = showThumbnailsValue, + onCheckedChange = onShowThumbnailsChange, + ) - SwitchSetting( - title = stringResource(id = R.string.show_reading_time), - checked = showReadingTime, - onCheckedChange = onShowReadingTimeChange, - ) + SwitchSetting( + title = stringResource(id = R.string.show_reading_time), + checked = showReadingTime, + onCheckedChange = onShowReadingTimeChange, + ) - SwitchSetting( - title = stringResource(id = R.string.show_title_unread_count), - checked = showTitleUnreadCount, - onCheckedChange = onShowTitleUnreadCountChange, - ) + SwitchSetting( + title = stringResource(id = R.string.show_title_unread_count), + checked = showTitleUnreadCount, + onCheckedChange = onShowTitleUnreadCountChange, + ) + } HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.reader_settings), - modifier = innerModifier, + SettingsGroup( + title = R.string.reader_settings, + ) { + MenuSetting( + currentValue = currentItemOpenerValue.asItemOpenerOption(), + values = + immutableListHolderOf( + ItemOpener.READER.asItemOpenerOption(), + ItemOpener.CUSTOM_TAB.asItemOpenerOption(), + ItemOpener.DEFAULT_BROWSER.asItemOpenerOption(), + ), + title = stringResource(id = R.string.open_item_by_default_with), + onSelection = { + onItemOpenerChange(it.itemOpener) + }, ) - } - - MenuSetting( - currentValue = currentItemOpenerValue.asItemOpenerOption(), - values = - immutableListHolderOf( - ItemOpener.READER.asItemOpenerOption(), - ItemOpener.CUSTOM_TAB.asItemOpenerOption(), - ItemOpener.DEFAULT_BROWSER.asItemOpenerOption(), - ), - title = stringResource(id = R.string.open_item_by_default_with), - onSelection = { - onItemOpenerChange(it.itemOpener) - }, - ) - MenuSetting( - currentValue = currentLinkOpenerValue.asLinkOpenerOption(), - values = - immutableListHolderOf( - LinkOpener.CUSTOM_TAB.asLinkOpenerOption(), - LinkOpener.DEFAULT_BROWSER.asLinkOpenerOption(), - ), - title = stringResource(id = R.string.open_links_with), - onSelection = { - onLinkOpenerChange(it.linkOpener) - }, - ) + MenuSetting( + currentValue = currentLinkOpenerValue.asLinkOpenerOption(), + values = + immutableListHolderOf( + LinkOpener.CUSTOM_TAB.asLinkOpenerOption(), + LinkOpener.DEFAULT_BROWSER.asLinkOpenerOption(), + ), + title = stringResource(id = R.string.open_links_with), + onSelection = { + onLinkOpenerChange(it.linkOpener) + }, + ) - val notCompactScreen = LocalConfiguration.current.smallestScreenWidthDp >= 600 + val notCompactScreen = LocalConfiguration.current.smallestScreenWidthDp >= 600 - if (notCompactScreen) { - SwitchSetting( - title = stringResource(id = R.string.open_browser_in_split_screen), - checked = isOpenAdjacent, - onCheckedChange = onOpenAdjacent, - ) + if (notCompactScreen) { + SwitchSetting( + title = stringResource(id = R.string.open_browser_in_split_screen), + checked = isOpenAdjacent, + onCheckedChange = onOpenAdjacent, + ) + } } HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.image_loading), - modifier = innerModifier, + SettingsGroup( + title = R.string.image_loading, + ) { + SwitchSetting( + title = stringResource(id = R.string.only_on_wifi), + checked = loadImageOnlyOnWifiValue, + onCheckedChange = onLoadImageOnlyOnWifiChange, ) } - SwitchSetting( - title = stringResource(id = R.string.only_on_wifi), - checked = loadImageOnlyOnWifiValue, - onCheckedChange = onLoadImageOnlyOnWifiChange, - ) - HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.text_to_speech), - modifier = innerModifier, + SettingsGroup( + title = R.string.text_to_speech, + ) { + SwitchSetting( + title = stringResource(id = R.string.use_detect_language), + checked = useDetectLanguage, + description = + when { + isAndroidQAndAbove -> stringResource(id = R.string.description_for_read_aloud) + else -> + stringResource( + id = R.string.only_available_on_android_n, + "10", + ) + }, + enabled = isAndroidQAndAbove, + onCheckedChange = onUseDetectLanguageChange, ) } - SwitchSetting( - title = stringResource(id = R.string.use_detect_language), - checked = useDetectLanguage, - description = - when { - isAndroidQAndAbove -> stringResource(id = R.string.description_for_read_aloud) - else -> - stringResource( - id = R.string.only_available_on_android_n, - "10", - ) - }, - enabled = isAndroidQAndAbove, - onCheckedChange = onUseDetectLanguageChange, - ) - HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) - GroupTitle { innerModifier -> - Text( - stringResource(id = R.string.openai_settings), - modifier = innerModifier, + SettingsGroup( + title = R.string.openai_settings, + ) { + OpenAISection( + state = openAIState, + onEvent = onOpenAIEvent, ) } - OpenAISection( - state = openAIState, - onEvent = onOpenAIEvent, - ) - HorizontalDivider(modifier = Modifier.width(dimens.maxContentWidth)) Spacer(modifier = Modifier.navigationBarsPadding()) } } +@Composable +fun ColumnScope.SettingsGroup( + @StringRes title: Int, + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + GroupTitle( + modifier = modifier, + ) { innerModifier -> + Text( + stringResource(id = title), + modifier = innerModifier, + ) + } + + content() +} + @Composable fun GroupTitle( modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/SettingsViewModel.kt b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/SettingsViewModel.kt index 3bf9edb37..78da777d4 100644 --- a/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/nononsenseapps/feeder/ui/compose/settings/SettingsViewModel.kt @@ -155,6 +155,10 @@ class SettingsViewModel(di: DI) : DIAwareViewModel(di) { repository.setShowTitleUnreadCount(value) } + fun setOpenDrawerOnFab(value: Boolean) { + repository.setOpenDrawerOnFab(value) + } + fun onOpenAISettingsEvent(event: OpenAISettingsEvent) { when (event) { is OpenAISettingsEvent.LoadModels -> loadOpenAIModels(event.settings) @@ -227,6 +231,7 @@ class SettingsViewModel(di: DI) : DIAwareViewModel(di) { repository.showTitleUnreadCount, repository.openAISettings, openAIModelsState, + repository.isOpenDrawerOnFab, ) { params: Array -> @Suppress("UNCHECKED_CAST") SettingsViewState( @@ -262,6 +267,7 @@ class SettingsViewModel(di: DI) : DIAwareViewModel(di) { settings = params[27] as OpenAISettings, modelsResult = params[28] as OpenAIModelsState, ), + isOpenDrawerOnFab = params[29] as Boolean, ) }.collect { _viewState.value = it @@ -321,6 +327,7 @@ data class SettingsViewState( val openAIState: OpenAISettingsState = OpenAISettingsState(), val showReadingTime: Boolean = false, val showTitleUnreadCount: Boolean = false, + val isOpenDrawerOnFab: Boolean = false, ) data class UIFeedSettings( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 96064d9c3..7b26da93d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -274,4 +274,5 @@ Azure deployment id List of available models Show message + Show feeds after marking all as read