diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt index e1ebf5fa8c..17f756030d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt @@ -43,6 +43,7 @@ data class UiSettings( val gallerySet: ProfileGalleryType = ProfileGalleryType.CLASSIC, val automaticallyProposeAiImprovements: BooleanType = BooleanType.ALWAYS, val useTrackedBroadcasts: BooleanType = BooleanType.ALWAYS, + val automaticallyCreateDrafts: BooleanType = BooleanType.ALWAYS, val bottomBarItems: List = DefaultBottomBarItems, val showHomeNewThreadsTab: Boolean = true, val showHomeConversationsTab: Boolean = true, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt index 8a57956362..a6a00acbb3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt @@ -43,6 +43,7 @@ class UiSettingsFlow( val gallerySet: MutableStateFlow = MutableStateFlow(ProfileGalleryType.CLASSIC), val automaticallyProposeAiImprovements: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), val useTrackedBroadcasts: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), + val automaticallyCreateDrafts: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), val bottomBarItems: MutableStateFlow> = MutableStateFlow(DefaultBottomBarItems), val showHomeNewThreadsTab: MutableStateFlow = MutableStateFlow(true), val showHomeConversationsTab: MutableStateFlow = MutableStateFlow(true), @@ -64,6 +65,7 @@ class UiSettingsFlow( gallerySet, automaticallyProposeAiImprovements, useTrackedBroadcasts, + automaticallyCreateDrafts, bottomBarItems, showHomeNewThreadsTab, showHomeConversationsTab, @@ -89,10 +91,11 @@ class UiSettingsFlow( flows[11] as ProfileGalleryType, flows[12] as BooleanType, flows[13] as BooleanType, - flows[14] as List, - flows[15] as Boolean, + flows[14] as BooleanType, + flows[15] as List, flows[16] as Boolean, flows[17] as Boolean, + flows[18] as Boolean, ) } @@ -112,6 +115,7 @@ class UiSettingsFlow( gallerySet.value, automaticallyProposeAiImprovements.value, useTrackedBroadcasts.value, + automaticallyCreateDrafts.value, bottomBarItems.value, showHomeNewThreadsTab.value, showHomeConversationsTab.value, @@ -177,6 +181,10 @@ class UiSettingsFlow( useTrackedBroadcasts.tryEmit(torSettings.useTrackedBroadcasts) any = true } + if (automaticallyCreateDrafts.value != torSettings.automaticallyCreateDrafts) { + automaticallyCreateDrafts.tryEmit(torSettings.automaticallyCreateDrafts) + any = true + } if (bottomBarItems.value != torSettings.bottomBarItems) { bottomBarItems.tryEmit(torSettings.bottomBarItems) any = true @@ -226,6 +234,7 @@ class UiSettingsFlow( MutableStateFlow(uiSettings.gallerySet), MutableStateFlow(uiSettings.automaticallyProposeAiImprovements), MutableStateFlow(uiSettings.useTrackedBroadcasts), + MutableStateFlow(uiSettings.automaticallyCreateDrafts), MutableStateFlow(uiSettings.bottomBarItems), MutableStateFlow(uiSettings.showHomeNewThreadsTab), MutableStateFlow(uiSettings.showHomeConversationsTab), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt index c1eefef1e5..36dbe92863 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt @@ -107,6 +107,7 @@ class UiSharedPreferences( val UI_GALLERY_SET = stringPreferencesKey("ui.gallery_set") val UI_PROPOSE_AI_IMPROVEMENTS = stringPreferencesKey("ui.propose_ai_improvements") val UI_USE_TRACKED_BROADCASTS = stringPreferencesKey("ui.use_tracked_broadcasts") + val UI_AUTOMATICALLY_CREATE_DRAFTS = stringPreferencesKey("ui.automatically_create_drafts") val UI_BOTTOM_BAR_ITEMS = stringPreferencesKey("ui.bottom_bar_items") val UI_SHOW_HOME_NEW_THREADS_TAB = booleanPreferencesKey("ui.show_home_new_threads_tab") val UI_SHOW_HOME_CONVERSATIONS_TAB = booleanPreferencesKey("ui.show_home_conversations_tab") @@ -136,6 +137,7 @@ class UiSharedPreferences( useTrackedBroadcasts = preferences[UI_USE_TRACKED_BROADCASTS]?.let { BooleanType.valueOf(it) } ?: if (featureSet == FeatureSetType.COMPLETE) BooleanType.ALWAYS else BooleanType.NEVER, + automaticallyCreateDrafts = preferences[UI_AUTOMATICALLY_CREATE_DRAFTS]?.let { BooleanType.valueOf(it) } ?: BooleanType.ALWAYS, bottomBarItems = preferences[UI_BOTTOM_BAR_ITEMS]?.let { decodeBottomBarItems(it) } ?: DefaultBottomBarItems, showHomeNewThreadsTab = preferences[UI_SHOW_HOME_NEW_THREADS_TAB] ?: true, showHomeConversationsTab = preferences[UI_SHOW_HOME_CONVERSATIONS_TAB] ?: true, @@ -178,6 +180,7 @@ class UiSharedPreferences( preferences[UI_GALLERY_SET] = sharedSettings.gallerySet.name preferences[UI_PROPOSE_AI_IMPROVEMENTS] = sharedSettings.automaticallyProposeAiImprovements.name preferences[UI_USE_TRACKED_BROADCASTS] = sharedSettings.useTrackedBroadcasts.name + preferences[UI_AUTOMATICALLY_CREATE_DRAFTS] = sharedSettings.automaticallyCreateDrafts.name preferences[UI_BOTTOM_BAR_ITEMS] = sharedSettings.bottomBarItems.joinToString(",") { it.name } preferences[UI_SHOW_HOME_NEW_THREADS_TAB] = sharedSettings.showHomeNewThreadsTab preferences[UI_SHOW_HOME_CONVERSATIONS_TAB] = sharedSettings.showHomeConversationsTab diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index e0beff8e37..44e61bcfdd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -156,6 +156,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.AllSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.BottomBarSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.CallSettingsScreen +import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.ComposeSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.HomeTabsSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NamecoinSettingsScreen @@ -307,6 +308,7 @@ fun BuildNavigation( composableFromEnd { DraftListScreen(accountViewModel, nav) } composableFromEnd { ScheduledPostsScreen(accountViewModel, nav) } composableFromEnd { SettingsScreen(accountViewModel, nav) } + composableFromEnd { ComposeSettingsScreen(accountViewModel, nav) } composableFromEnd { UserSettingsScreen(accountViewModel, nav) } composableFromEnd { ReactionsSettingsScreen(accountViewModel, nav) } composableFromEnd { BottomBarSettingsScreen(accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt index 8c1ac58dcb..7607abd2f6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt @@ -215,6 +215,8 @@ sealed class Route { @Serializable object Settings : Route() + @Serializable object ComposeSettings : Route() + @Serializable object UserSettings : Route() @Serializable object ReactionsSettings : Route() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UiSettingsState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UiSettingsState.kt index bd28f91bf7..d0a3e1c387 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UiSettingsState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UiSettingsState.kt @@ -133,6 +133,8 @@ class UiSettingsState( fun useTrackedBroadcasts() = uiSettingsFlow.useTrackedBroadcasts.value == BooleanType.ALWAYS + fun automaticallyCreateDrafts() = uiSettingsFlow.automaticallyCreateDrafts.value == BooleanType.ALWAYS + fun isImmersiveScrollingActive() = uiSettingsFlow.automaticallyHideNavigationBars.value == BooleanType.ALWAYS fun showProfilePictures() = showProfilePictures.value diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/ChatNewMessageViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/ChatNewMessageViewModel.kt index 17e74d75a3..18181978ea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/ChatNewMessageViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/ChatNewMessageViewModel.kt @@ -424,7 +424,7 @@ class ChatNewMessageViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { innerSendPost(draftTag.current) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelNewMessageViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelNewMessageViewModel.kt index 805f6f5a99..1380c965b4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelNewMessageViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelNewMessageViewModel.kt @@ -306,7 +306,7 @@ open class ChannelNewMessageViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val attachments = mutableSetOf() nip95attachments.forEach { attachments.add(it.first) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostViewModel.kt index 972ed92cc5..cc508bf0d7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostViewModel.kt @@ -348,7 +348,7 @@ class LongFormPostViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank() && title.text.isBlank()) { accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val template = createTemplate() ?: return accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template, emptySet()) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductViewModel.kt index 608fdc5cf3..14d7a13347 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductViewModel.kt @@ -327,7 +327,7 @@ open class NewProductViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val template = createTemplate() ?: return accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt index 5339a4a253..1504473697 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt @@ -897,7 +897,7 @@ open class ShortNotePostViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val attachments = mutableSetOf() nip95attachments.forEach { attachments.add(it.first) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/chat/NestNewMessageViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/chat/NestNewMessageViewModel.kt index a2ba9be4d9..648a369000 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/chat/NestNewMessageViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/chat/NestNewMessageViewModel.kt @@ -310,7 +310,7 @@ open class NestNewMessageViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val attachments = mutableSetOf() nip95attachments.forEach { attachments.add(it.first) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt index 25b5fd7330..43d8ac6ca6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt @@ -352,7 +352,7 @@ class NewPublicMessageViewModel : suspend fun sendDraftSync() { if (message.text.toString().isBlank()) { accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) - } else { + } else if (accountViewModel.settings.automaticallyCreateDrafts()) { val broadcast = mutableSetOf() nip95attachments.forEach { broadcast.add(it.first) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt index a6cec1a382..a24133ff43 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt @@ -236,6 +236,12 @@ fun AllSettingsScreen( onClick = { nav.nav(Route.Settings) }, ) SettingsDivider() + SettingsItem( + title = R.string.compose_settings, + icon = MaterialSymbols.Edit, + onClick = { nav.nav(Route.ComposeSettings) }, + ) + SettingsDivider() SettingsItem( title = R.string.reactions_settings, icon = MaterialSymbols.ThumbUp, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt index f31857f149..9be0e54f6b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt @@ -55,7 +55,6 @@ import androidx.core.os.LocaleListCompat import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.BooleanType import com.vitorpamplona.amethyst.model.ConnectivityType import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.ProfileGalleryType @@ -136,8 +135,6 @@ fun SettingsScreen( ImmersiveScrollingChoice(sharedPrefs) FeatureSetChoice(sharedPrefs) GalleryChoice(sharedPrefs) - AiWritingHelpChoice(sharedPrefs) - TrackedBroadcastsChoice(sharedPrefs) PushNotificationSettingsRow(sharedPrefs) if (accountViewModel != null) { AlwaysOnNotificationServiceChoice(accountViewModel) @@ -405,46 +402,6 @@ fun GalleryChoice(sharedPrefs: UiSettingsFlow) { } } -@Composable -fun AiWritingHelpChoice(sharedPrefs: UiSettingsFlow) { - val aiIndex by sharedPrefs.automaticallyProposeAiImprovements.collectAsState() - - val booleanItems = - persistentListOf( - TitleExplainer(stringRes(ConnectivityType.ALWAYS.resourceId)), - TitleExplainer(stringRes(ConnectivityType.NEVER.resourceId)), - ) - - SettingsRow( - R.string.ai_writing_setting_title, - R.string.ai_writing_setting_description, - booleanItems, - aiIndex.screenCode, - ) { - sharedPrefs.automaticallyProposeAiImprovements.tryEmit(parseBooleanType(it)) - } -} - -@Composable -fun TrackedBroadcastsChoice(sharedPrefs: UiSettingsFlow) { - val useTrackedBroadcastsIndex by sharedPrefs.useTrackedBroadcasts.collectAsState() - - val booleanItems = - persistentListOf( - TitleExplainer(stringRes(BooleanType.ALWAYS.reourceId)), - TitleExplainer(stringRes(BooleanType.NEVER.reourceId)), - ) - - SettingsRow( - R.string.tracked_broadcasts_setting_title, - R.string.tracked_broadcasts_setting_description, - booleanItems, - useTrackedBroadcastsIndex.screenCode, - ) { - sharedPrefs.useTrackedBroadcasts.tryEmit(parseBooleanType(it)) - } -} - @Composable fun SettingsRow( name: Int, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt new file mode 100644 index 0000000000..1c5baba82f --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.BooleanType +import com.vitorpamplona.amethyst.model.UiSettingsFlow +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.RowColSpacing +import com.vitorpamplona.amethyst.ui.theme.Size10dp +import com.vitorpamplona.amethyst.ui.theme.Size20dp +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow +import kotlinx.coroutines.flow.MutableStateFlow + +@Composable +fun ComposeSettingsScreen( + accountViewModel: AccountViewModel, + nav: INav, +) { + Scaffold( + topBar = { + TopBarWithBackButton(stringRes(id = R.string.compose_settings), nav) + }, + ) { + Column(Modifier.padding(it)) { + ComposeSettingsContent(accountViewModel.settings.uiSettingsFlow) + } + } +} + +@Preview(device = "spec:width=2160px,height=2340px,dpi=440") +@Composable +fun ComposeSettingsScreenPreview() { + ThemeComparisonRow { + ComposeSettingsContent(UiSettingsFlow()) + } +} + +@Composable +fun ComposeSettingsContent(sharedPrefs: UiSettingsFlow) { + Column( + Modifier + .fillMaxSize() + .padding(top = Size10dp, start = Size20dp, end = Size20dp) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = RowColSpacing, + ) { + BooleanSwitchRow( + sharedPrefs.automaticallyCreateDrafts, + R.string.auto_create_drafts_setting_title, + R.string.auto_create_drafts_setting_description, + ) + BooleanSwitchRow( + sharedPrefs.automaticallyProposeAiImprovements, + R.string.ai_writing_setting_title, + R.string.ai_writing_setting_description, + ) + BooleanSwitchRow( + sharedPrefs.useTrackedBroadcasts, + R.string.tracked_broadcasts_setting_title, + R.string.tracked_broadcasts_setting_description, + ) + } +} + +@Composable +private fun BooleanSwitchRow( + flow: MutableStateFlow, + title: Int, + description: Int, +) { + val value by flow.collectAsState() + + SettingsRow(title, description) { + Switch( + checked = value == BooleanType.ALWAYS, + onCheckedChange = { isOn -> + flow.tryEmit(if (isOn) BooleanType.ALWAYS else BooleanType.NEVER) + }, + ) + } +} diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 4ec6447448..b31283c26d 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -2794,6 +2794,9 @@ Uses an on-device AI model to propose text corrections and tone changes. Tracked broadcasts Use the tracked broadcaster when sending events. Shows live progress and per-relay status while broadcasting. + Compose Settings + Automatically create drafts + Saves a draft event automatically when you leave a composer with unsent text. Disable to keep your unfinished posts local until you publish. Use This Dismiss Correct