diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index e95538198..3502f25a1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -212,6 +212,7 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import java.math.BigDecimal import java.util.Locale +import kotlin.coroutines.cancellation.CancellationException @OptIn(DelicateCoroutinesApi::class) @Stable @@ -1140,7 +1141,19 @@ class Account( return event } - suspend fun createAndSendDraft( + suspend fun createAndSendDraftIgnoreErrors( + draftTag: String, + template: EventTemplate, + broadcast: Set = emptySet(), + ) { + try { + createAndSendDraftInner(draftTag, template, broadcast) + } catch (e: Exception) { + if (e is CancellationException) throw e + } + } + + suspend fun createAndSendDraftInner( draftTag: String, template: EventTemplate, broadcast: Set = emptySet(), @@ -1164,7 +1177,15 @@ class Account( } } - suspend fun deleteDraft(draftTag: String) { + suspend fun deleteDraftIgnoreErrors(draftTag: String) { + try { + deleteDraftInner(draftTag) + } catch (e: Exception) { + if (e is CancellationException) throw e + } + } + + suspend fun deleteDraftInner(draftTag: String) { if (!isWriteable()) return val extraRelays = cache.getAddressableNoteIfExists(DraftWrapEvent.createAddressTag(signer.pubKey, draftTag))?.relays ?: emptyList() @@ -1293,7 +1314,7 @@ class Account( } if (draftTag != null) { - createAndSendDraft(draftTag, template) + createAndSendDraftIgnoreErrors(draftTag, template) } else { val it = signer.sign(template) cache.justConsumeMyOwnEvent(it) @@ -1338,7 +1359,7 @@ class Account( val broadcastNotes = mapEntitiesToNotes(quotes).toSet() if (draftTag != null) { - createAndSendDraft(draftTag, template) + createAndSendDraftIgnoreErrors(draftTag, template) } else { val it = signer.sign(template) cache.justConsumeMyOwnEvent(it) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/CommentPostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/CommentPostViewModel.kt index d9016fb11..6c05d9714 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/CommentPostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/CommentPostViewModel.kt @@ -317,12 +317,14 @@ open class CommentPostViewModel : cancel() accountViewModel.account.signAndComputeBroadcast(template, extraNotesToBroadcast) - accountViewModel.account.deleteDraft(version) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { if (message.text.isBlank()) { - accountViewModel.account.deleteDraft(draftTag.current) + accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) } else { val attachments = mutableSetOf() nip95attachments.forEach { @@ -331,7 +333,7 @@ open class CommentPostViewModel : } val template = createTemplate() ?: return - accountViewModel.account.createAndSendDraft(draftTag.current, template, attachments) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template, attachments) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt index d5874e824..d4b8eb958 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt @@ -45,7 +45,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp -import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note @@ -86,7 +85,6 @@ import com.vitorpamplona.amethyst.ui.theme.replyModifier import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @Composable @@ -144,16 +142,16 @@ fun GenericCommentPostScreen( onCancel = { // uses the accountViewModel scope to avoid cancelling this // function when the postViewModel is released - accountViewModel.viewModelScope.launch(Dispatchers.IO) { + accountViewModel.runIOCatching { postViewModel.sendDraftSync() - nav.popBack() postViewModel.cancel() } + nav.popBack() }, onPost = { // uses the accountViewModel scope to avoid cancelling this // function when the postViewModel is released - accountViewModel.viewModelScope.launch(Dispatchers.IO) { + accountViewModel.runIOCatching { postViewModel.sendPostSync() nav.popBack() } 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 dcb020516..056787bbb 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 @@ -351,12 +351,14 @@ class ChatNewMessageViewModel : val version = draftTag.current innerSendPost(null) cancel() - accountViewModel.account.deleteDraft(version) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { if (message.text.isBlank()) { - account.deleteDraft(draftTag.current) + account.deleteDraftIgnoreErrors(draftTag.current) } else { innerSendPost(draftTag.current) } @@ -471,7 +473,7 @@ class ChatNewMessageViewModel : } if (draftTag != null) { - accountViewModel.account.createAndSendDraft(draftTag, template) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag, template) } else { accountViewModel.account.sendNip17PrivateMessage(template) } @@ -488,7 +490,7 @@ class ChatNewMessageViewModel : ) if (draftTag != null) { - accountViewModel.account.createAndSendDraft(draftTag, template) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag, template) } else { accountViewModel.account.sendNip04PrivateMessage(template) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt index 94f18b6a6..cde640df8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt @@ -175,10 +175,9 @@ fun NewGroupDMScreen( // function when the postViewModel is released accountViewModel.runIOCatching { postViewModel.sendDraftSync() - delay(100) - nav.popBack() postViewModel.cancel() } + nav.popBack() }, onPost = { // uses the accountViewModel scope to avoid cancelling this @@ -188,7 +187,6 @@ fun NewGroupDMScreen( postViewModel.room?.let { nav.nav(routeToMessage(it, null, null, null, accountViewModel)) } - postViewModel.cancel() } nav.popBack() }, 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 71499c5fa..bc775bac9 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 @@ -276,12 +276,14 @@ open class ChannelNewMessageViewModel : cancel() accountViewModel.account.signAndSendPrivately(template, channelRelays) - accountViewModel.account.deleteDraft(version) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { if (message.text.isBlank()) { - account.deleteDraft(draftTag.current) + account.deleteDraftIgnoreErrors(draftTag.current) } else { val attachments = mutableSetOf() nip95attachments.forEach { @@ -290,7 +292,7 @@ open class ChannelNewMessageViewModel : } val template = createTemplate() ?: return - accountViewModel.account.createAndSendDraft(draftTag.current, template, attachments) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template, attachments) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt index 9d0ec5516..bd30e4666 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt @@ -142,22 +142,19 @@ fun NewProductScreen( titleRes = R.string.new_product, isActive = postViewModel::canPost, onCancel = { - try { - accountViewModel.viewModelScope.launch(Dispatchers.IO) { - postViewModel.sendDraftSync() - nav.popBack() - postViewModel.cancel() - } - } catch (e: SignerExceptions.ReadOnlyException) { - // do nothing. + // uses the accountViewModel scope to avoid cancelling this + // function when the postViewModel is released + accountViewModel.runIOCatching { + postViewModel.sendDraftSync() + postViewModel.cancel() } + nav.popBack() }, onPost = { try { accountViewModel.viewModelScope.launch(Dispatchers.IO) { postViewModel.sendPostSync() nav.popBack() - postViewModel.cancel() } } catch (e: SignerExceptions.ReadOnlyException) { accountViewModel.toastManager.toast( 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 d55c8fe79..265f6d544 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 @@ -293,24 +293,23 @@ open class NewProductViewModel : val accountViewModel = accountViewModel ?: return val template = createTemplate() ?: return - accountViewModel.account.signAndSendPrivatelyOrBroadcast( - template, - relayList = { relayList }, - ) - - accountViewModel.account.deleteDraft(draftTag.current) - + val version = draftTag.current cancel() + + accountViewModel.account.signAndSendPrivatelyOrBroadcast(template, relayList = { relayList }) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { val accountViewModel = accountViewModel ?: return if (message.text.isBlank()) { - accountViewModel.account.deleteDraft(draftTag.current) + accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) } else { val template = createTemplate() ?: return - accountViewModel.account.createAndSendDraft(draftTag.current, template) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt index c9821ec97..d8aa344ef 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt @@ -98,7 +98,6 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.delay import kotlinx.coroutines.withContext @OptIn(ExperimentalMaterial3Api::class, FlowPreview::class) @@ -174,7 +173,6 @@ private fun NewPostScreenInner( // function when the postViewModel is released accountViewModel.runIOCatching { postViewModel.sendPostSync() - delay(100) nav.popBack() } }, @@ -183,9 +181,9 @@ private fun NewPostScreenInner( // function when the postViewModel is released accountViewModel.runIOCatching { postViewModel.sendDraftSync() - nav.popBack() postViewModel.cancel() } + nav.popBack() }, ) }, 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 387bf4351..5b975b6bf 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 @@ -483,12 +483,14 @@ open class ShortNotePostViewModel : cancel() accountViewModel.account.signAndComputeBroadcast(template, extraNotesToBroadcast) - accountViewModel.account.deleteDraft(version) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { if (message.text.isBlank()) { - accountViewModel.account.deleteDraft(draftTag.current) + accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) } else { val attachments = mutableSetOf() nip95attachments.forEach { @@ -497,7 +499,7 @@ open class ShortNotePostViewModel : } val template = createTemplate() ?: return - accountViewModel.account.createAndSendDraft(draftTag.current, template, attachments) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template, attachments) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt index dd280e785..bd99422ba 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt @@ -138,10 +138,9 @@ fun NewPublicMessageScreen( // function when the postViewModel is released accountViewModel.runIOCatching { postViewModel.sendDraftSync() - delay(100) - nav.popBack() postViewModel.cancel() } + nav.popBack() }, onPost = { // uses the accountViewModel scope to avoid cancelling this @@ -149,9 +148,7 @@ fun NewPublicMessageScreen( accountViewModel.runIOCatching { postViewModel.sendPostSync() nav.popBack() - postViewModel.cancel() } - nav.popBack() }, ) }, 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 c0a1cd99f..3c42d85e1 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 @@ -321,12 +321,14 @@ class NewPublicMessageViewModel : cancel() accountViewModel.account.signAndComputeBroadcast(template, extraNotesToBroadcast) - accountViewModel.account.deleteDraft(version) + accountViewModel.viewModelScope.launch { + accountViewModel.account.deleteDraftIgnoreErrors(version) + } } suspend fun sendDraftSync() { if (message.text.isBlank()) { - accountViewModel.account.deleteDraft(draftTag.current) + accountViewModel.account.deleteDraftIgnoreErrors(draftTag.current) } else { val broadcast = mutableSetOf() nip95attachments.forEach { @@ -335,7 +337,7 @@ class NewPublicMessageViewModel : } val template = createTemplate() ?: return - accountViewModel.account.createAndSendDraft(draftTag.current, template, broadcast) + accountViewModel.account.createAndSendDraftIgnoreErrors(draftTag.current, template, broadcast) } }