refactor: gate only draft create, and colocate compose composables

- sendDraftSync no longer short-circuits the delete-on-blank path when
  automatic draft creation is disabled. Clearing a composer now always
  cleans up any existing draft; the setting only suppresses creation.
- Physically move AiWritingHelpChoice and TrackedBroadcastsChoice from
  AppSettingsScreen.kt into ComposeSettingsScreen.kt so the composable
  definitions live alongside the screen that hosts them.

https://claude.ai/code/session_019b6cF7Ukkv7GL9A3m6bXym
This commit is contained in:
Claude
2026-05-13 19:28:27 +00:00
parent 1b8b508816
commit d5860841c9
9 changed files with 48 additions and 55 deletions
@@ -422,10 +422,9 @@ class ChatNewMessageViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
if (message.text.toString().isBlank()) {
account.deleteDraftIgnoreErrors(draftTag.current)
} else {
} else if (accountViewModel.settings.automaticallyCreateDrafts()) {
innerSendPost(draftTag.current)
}
}
@@ -304,10 +304,9 @@ open class ChannelNewMessageViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
if (message.text.toString().isBlank()) {
account.deleteDraftIgnoreErrors(draftTag.current)
} else {
} else if (accountViewModel.settings.automaticallyCreateDrafts()) {
val attachments = mutableSetOf<Event>()
nip95attachments.forEach {
attachments.add(it.first)
@@ -346,10 +346,9 @@ class LongFormPostViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
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())
}
@@ -325,10 +325,9 @@ open class NewProductViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
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)
}
@@ -895,10 +895,9 @@ open class ShortNotePostViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
if (message.text.toString().isBlank()) {
accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current)
} else {
} else if (accountViewModel.settings.automaticallyCreateDrafts()) {
val attachments = mutableSetOf<Event>()
nip95attachments.forEach {
attachments.add(it.first)
@@ -308,10 +308,9 @@ open class NestNewMessageViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
if (message.text.toString().isBlank()) {
account.deleteDraftIgnoreErrors(draftTag.current)
} else {
} else if (accountViewModel.settings.automaticallyCreateDrafts()) {
val attachments = mutableSetOf<Event>()
nip95attachments.forEach {
attachments.add(it.first)
@@ -350,10 +350,9 @@ class NewPublicMessageViewModel :
}
suspend fun sendDraftSync() {
if (!accountViewModel.settings.automaticallyCreateDrafts()) return
if (message.text.toString().isBlank()) {
accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current)
} else {
} else if (accountViewModel.settings.automaticallyCreateDrafts()) {
val broadcast = mutableSetOf<Event>()
nip95attachments.forEach {
broadcast.add(it.first)
@@ -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
@@ -403,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,
@@ -34,6 +34,7 @@ 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.ConnectivityType
import com.vitorpamplona.amethyst.model.UiSettingsFlow
import com.vitorpamplona.amethyst.model.parseBooleanType
import com.vitorpamplona.amethyst.ui.components.TitleExplainer
@@ -106,3 +107,43 @@ fun AutoCreateDraftsChoice(sharedPrefs: UiSettingsFlow) {
sharedPrefs.automaticallyCreateDrafts.tryEmit(parseBooleanType(it))
}
}
@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))
}
}