diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 619e70347..f3045fdbf 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1369,7 +1369,7 @@ class Account( Client.send(draftEvent, relayList = relayList) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it, relayList = relayList) @@ -1431,7 +1431,7 @@ class Account( Client.send(draftEvent, relayList = relayList) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it, relayList = relayList) @@ -1499,7 +1499,7 @@ class Account( Client.send(draftEvent, relayList = relayList) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it, relayList = relayList) @@ -1590,7 +1590,7 @@ class Account( Client.send(draftEvent, relayList = relayList) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it, relayList = relayList) @@ -1642,7 +1642,7 @@ class Account( Client.send(draftEvent) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it) @@ -1687,7 +1687,7 @@ class Account( Client.send(draftEvent) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it) @@ -1759,7 +1759,7 @@ class Account( Client.send(draftEvent) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it, null) - LocalCache.addDraft(draftTag, it.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.id()) } } else { Client.send(it) @@ -1805,7 +1805,7 @@ class Account( Client.send(draftEvent) LocalCache.justConsume(draftEvent, null) LocalCache.justConsume(it.msg, null) - LocalCache.addDraft(draftTag, it.msg.id()) + LocalCache.addDraft(draftTag, draftEvent.id(), it.msg.id()) } } else { broadcastPrivately(it) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Drafts.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Drafts.kt index f01d30a16..9dc3b1c44 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Drafts.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Drafts.kt @@ -1,2 +1,23 @@ +/** + * Copyright (c) 2024 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.model +data class Drafts(val mainId: String, val eventId: String) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 3e6a8309d..4ff2fd4f7 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -129,7 +129,7 @@ object LocalCache { val users = LargeCache() val notes = LargeCache() val addressables = LargeCache() - val drafts = ConcurrentHashMap>() + val drafts = ConcurrentHashMap>() val channels = ConcurrentHashMap() val awaitingPaymentRequests = ConcurrentHashMap Unit>>(10) @@ -144,25 +144,30 @@ object LocalCache { fun draftNotes(draftTag: String): List { return drafts[draftTag]?.mapNotNull { - checkGetOrCreateNote(it) + getNoteIfExists(it.mainId) } ?: listOf() } fun getDrafts(eventId: String): List { return drafts.filter { - it.value.any { it == eventId } - }.keys.mapNotNull { - checkGetOrCreateNote(it) - } + it.value.any { it.eventId == eventId } + }.values.map { + it.mapNotNull { + checkGetOrCreateNote(it.mainId) + } + }.flatten() } fun addDraft( key: String, - value: String, + mainId: String, + draftId: String, ) { val data = drafts[key] ?: mutableListOf() - data.add(value) - drafts[key] = data + if (data.none { it.mainId == mainId }) { + data.add(Drafts(mainId, draftId)) + drafts[key] = data + } } fun getOrCreateUser(key: HexKey): User { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index 5507975b7..34a51b4c6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -289,7 +289,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") { LocalCache.justConsume(it, relay) tag?.let { lTag -> - LocalCache.addDraft(lTag, it.id()) + LocalCache.addDraft(lTag, event.id(), it.id()) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt index a177a0b9c..2b48befa3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt @@ -315,7 +315,7 @@ open class NewPostViewModel() : ViewModel() { Log.d("draft", draft.event!!.toJson()) draftTag = LocalCache.drafts.filter { - it.value.contains(draft.idHex) + it.value.any { it.eventId == draft.event?.id() } }.keys.firstOrNull() ?: draftTag canAddInvoice = accountViewModel.userProfile().info?.lnAddress() != null @@ -394,7 +394,15 @@ open class NewPostViewModel() : ViewModel() { it.value == draft.event?.tags()?.filter { it.size > 1 && it[0] == "condition" }?.map { it[1] }?.firstOrNull() } ?: ClassifiedsEvent.CONDITION.USED_LIKE_NEW - message = TextFieldValue(draft.event?.content() ?: "") + message = + if (draft.event is PrivateDmEvent) { + val event = draft.event as PrivateDmEvent + TextFieldValue(event.cachedContentFor(accountViewModel.account.signer) ?: "") + } else { + TextFieldValue(draft.event?.content() ?: "") + } + + nip24 = draft.event is ChatMessageEvent urlPreview = findUrlInMessage() } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt index 251dfac0c..d701a8fc9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChannelCardCompose.kt @@ -134,7 +134,7 @@ fun ChannelCardCompose( ) } } else { - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup, + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup, -> BlankNote( remember { @@ -281,7 +281,7 @@ fun NormalChannelCard( accountViewModel: AccountViewModel, nav: (String) -> Unit, ) { - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup -> + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup -> CheckNewAndRenderChannelCard( baseNote, routeForLastRead, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index 5d67af21f..133d9833c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -66,6 +66,7 @@ import androidx.lifecycle.map import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User +import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.SensitivityWarning @@ -105,6 +106,7 @@ fun ChatroomMessageCompose( innerQuote: Boolean = false, parentBackgroundColor: MutableState? = null, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { @@ -118,11 +120,12 @@ fun ChatroomMessageCompose( innerQuote, parentBackgroundColor, accountViewModel, + newPostViewModel, nav, onWantsToReply, ) } else { - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup, + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = newPostViewModel) { showPopup, -> BlankNote( remember { @@ -144,6 +147,7 @@ fun CheckHiddenChatMessage( innerQuote: Boolean = false, parentBackgroundColor: MutableState? = null, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { @@ -162,6 +166,7 @@ fun CheckHiddenChatMessage( innerQuote, parentBackgroundColor, accountViewModel, + newPostViewModel, nav, onWantsToReply, ) @@ -175,6 +180,7 @@ fun LoadedChatMessageCompose( innerQuote: Boolean = false, parentBackgroundColor: MutableState? = null, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { @@ -220,6 +226,7 @@ fun LoadedChatMessageCompose( canPreview, parentBackgroundColor, accountViewModel, + newPostViewModel, nav, onWantsToReply, ) @@ -236,6 +243,7 @@ fun NormalChatNote( canPreview: Boolean = true, parentBackgroundColor: MutableState? = null, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { @@ -347,6 +355,7 @@ fun NormalChatNote( availableBubbleSize, showDetails, accountViewModel, + newPostViewModel, nav, ) } @@ -357,6 +366,7 @@ fun NormalChatNote( popupExpanded = popupExpanded, onDismiss = { popupExpanded = false }, accountViewModel = accountViewModel, + newPostViewModel = newPostViewModel, ) } } @@ -374,6 +384,7 @@ private fun RenderBubble( availableBubbleSize: MutableState, showDetails: State, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, ) { val bubbleSize = remember { mutableIntStateOf(0) } @@ -403,6 +414,7 @@ private fun RenderBubble( canPreview, showDetails, accountViewModel, + newPostViewModel, nav, ) } @@ -421,6 +433,7 @@ private fun MessageBubbleLines( canPreview: Boolean, showDetails: State, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, ) { if (drawAuthorInfo) { @@ -437,6 +450,7 @@ private fun MessageBubbleLines( innerQuote = innerQuote, backgroundBubbleColor = backgroundBubbleColor, accountViewModel = accountViewModel, + newPostViewModel = newPostViewModel, nav = nav, onWantsToReply = onWantsToReply, ) @@ -489,11 +503,12 @@ private fun RenderReplyRow( innerQuote: Boolean, backgroundBubbleColor: MutableState, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { if (!innerQuote && note.replyTo?.lastOrNull() != null) { - RenderReply(note, backgroundBubbleColor, accountViewModel, nav, onWantsToReply) + RenderReply(note, backgroundBubbleColor, accountViewModel, newPostViewModel, nav, onWantsToReply) } } @@ -502,6 +517,7 @@ private fun RenderReply( note: Note, backgroundBubbleColor: MutableState, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, nav: (String) -> Unit, onWantsToReply: (Note) -> Unit, ) { @@ -520,6 +536,7 @@ private fun RenderReply( innerQuote = true, parentBackgroundColor = backgroundBubbleColor, accountViewModel = accountViewModel, + newPostViewModel = newPostViewModel, nav = nav, onWantsToReply = onWantsToReply, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 8780d7dd0..93f6c41af 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -239,7 +239,7 @@ fun WatchNoteEvent( if (it) { onNoteEventFound() } else { - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup -> + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup -> BlankNote( remember { modifier.combinedClickable( @@ -414,7 +414,7 @@ fun AcceptableNote( nav = nav, ) else -> - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup, -> CheckNewAndRenderNote( @@ -450,7 +450,7 @@ fun AcceptableNote( is FileHeaderEvent -> FileHeaderDisplay(baseNote, false, accountViewModel) is FileStorageHeaderEvent -> FileStorageHeaderDisplay(baseNote, false, accountViewModel) else -> - LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { + LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel, newPostViewModel = null) { showPopup, -> CheckNewAndRenderNote( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index a60b15af4..97542e84e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -40,6 +40,7 @@ import androidx.compose.material.icons.filled.AlternateEmail import androidx.compose.material.icons.filled.Block import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.FormatQuote import androidx.compose.material.icons.filled.PersonAdd import androidx.compose.material.icons.filled.PersonRemove @@ -84,6 +85,8 @@ import androidx.core.graphics.ColorUtils import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.actions.NewPostView +import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.components.SelectTextDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog @@ -132,6 +135,7 @@ val externalLinkForNote = { note: Note -> fun LongPressToQuickAction( baseNote: Note, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, content: @Composable (() -> Unit) -> Unit, ) { val popupExpanded = remember { mutableStateOf(false) } @@ -140,7 +144,7 @@ fun LongPressToQuickAction( content(showPopup) - NoteQuickActionMenu(baseNote, popupExpanded.value, hidePopup, accountViewModel) + NoteQuickActionMenu(baseNote, popupExpanded.value, hidePopup, accountViewModel, newPostViewModel) } @Composable @@ -149,20 +153,24 @@ fun NoteQuickActionMenu( popupExpanded: Boolean, onDismiss: () -> Unit, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, ) { val showSelectTextDialog = remember { mutableStateOf(false) } val showDeleteAlertDialog = remember { mutableStateOf(false) } val showBlockAlertDialog = remember { mutableStateOf(false) } val showReportDialog = remember { mutableStateOf(false) } + val editDraftDialog = remember { mutableStateOf(false) } if (popupExpanded) { RenderMainPopup( accountViewModel, + newPostViewModel, note, onDismiss, showBlockAlertDialog, showDeleteAlertDialog, showReportDialog, + editDraftDialog, ) } @@ -199,16 +207,29 @@ fun NoteQuickActionMenu( onDismiss() } } + + if (editDraftDialog.value) { + NewPostView( + onClose = { + editDraftDialog.value = false + }, + accountViewModel = accountViewModel, + draft = note, + nav = { }, + ) + } } @Composable private fun RenderMainPopup( accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel?, note: Note, onDismiss: () -> Unit, showBlockAlertDialog: MutableState, showDeleteAlertDialog: MutableState, showReportDialog: MutableState, + editDraftDialog: MutableState, ) { val context = LocalContext.current val primaryLight = lightenColor(MaterialTheme.colorScheme.primary, 0.1f) @@ -279,6 +300,21 @@ private fun RenderMainPopup( } } + if (note.isDraft()) { + VerticalDivider(color = primaryLight) + NoteQuickActionItem( + Icons.Default.Edit, + stringResource(R.string.edit_draft), + ) { + if (newPostViewModel != null) { + newPostViewModel.load(accountViewModel, null, null, null, null, note) + onDismiss() + } else { + editDraftDialog.value = true + } + } + } + if (!isOwnNote) { VerticalDivider(color = primaryLight) @@ -389,14 +425,20 @@ fun NoteQuickActionItem( onClick: () -> Unit, ) { Column( - modifier = Modifier.size(70.dp).clickable { onClick() }, + modifier = + Modifier + .size(70.dp) + .clickable { onClick() }, verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( imageVector = icon, contentDescription = null, - modifier = Modifier.size(24.dp).padding(bottom = 5.dp), + modifier = + Modifier + .size(24.dp) + .padding(bottom = 5.dp), tint = Color.White, ) Text(text = label, fontSize = 12.sp, color = Color.White, textAlign = TextAlign.Center) @@ -527,7 +569,10 @@ fun QuickActionAlertDialog( text = { Text(textContent) }, confirmButton = { Row( - modifier = Modifier.padding(all = 8.dp).fillMaxWidth(), + modifier = + Modifier + .padding(all = 8.dp) + .fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, ) { TextButton(onClick = onClickDontShowAgain) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt index 70cc123c2..9683bb3c4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt @@ -237,7 +237,7 @@ fun NoteDropDownMenu( }, ) HorizontalDivider(thickness = DividerThickness) - if (!note.isDraft()) { + if (note.isDraft()) { DropdownMenuItem( text = { Text(stringResource(R.string.edit_draft)) }, onClick = { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt index 89c5c6b52..83760f6a0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ChatroomFeedView.kt @@ -38,6 +38,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel import com.vitorpamplona.amethyst.ui.note.ChatroomMessageCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.FeedPadding @@ -48,6 +49,7 @@ import com.vitorpamplona.amethyst.ui.theme.HalfPadding fun RefreshingChatroomFeedView( viewModel: FeedViewModel, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel, nav: (String) -> Unit, routeForLastRead: String, onWantsToReply: (Note) -> Unit, @@ -59,6 +61,7 @@ fun RefreshingChatroomFeedView( RenderChatroomFeedView( viewModel, accountViewModel, + newPostViewModel, listState, nav, routeForLastRead, @@ -72,6 +75,7 @@ fun RefreshingChatroomFeedView( fun RenderChatroomFeedView( viewModel: FeedViewModel, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel, listState: LazyListState, nav: (String) -> Unit, routeForLastRead: String, @@ -91,6 +95,7 @@ fun RenderChatroomFeedView( ChatroomFeedLoaded( state, accountViewModel, + newPostViewModel, listState, nav, routeForLastRead, @@ -108,6 +113,7 @@ fun RenderChatroomFeedView( fun ChatroomFeedLoaded( state: FeedState.Loaded, accountViewModel: AccountViewModel, + newPostViewModel: NewPostViewModel, listState: LazyListState, nav: (String) -> Unit, routeForLastRead: String, @@ -130,6 +136,7 @@ fun ChatroomFeedLoaded( baseNote = item, routeForLastRead = routeForLastRead, accountViewModel = accountViewModel, + newPostViewModel = newPostViewModel, nav = nav, onWantsToReply = onWantsToReply, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index c3cae7289..803b9f030 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -637,7 +637,7 @@ fun NoteMaster( ) } - NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel) + NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel, null) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt index d98153f89..ae1be0d8f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt @@ -175,6 +175,7 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +import java.util.UUID @Composable fun ChannelScreen( @@ -307,6 +308,7 @@ fun ChannelScreen( RefreshingChatroomFeedView( viewModel = feedViewModel, accountViewModel = accountViewModel, + newPostViewModel = newPostModel, nav = nav, routeForLastRead = "Channel/${channel.idHex}", onWantsToReply = { replyTo.value = it }, @@ -315,7 +317,7 @@ fun ChannelScreen( Spacer(modifier = DoubleVertSpacer) - replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, nav) { replyTo.value = null } } + replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, newPostModel, nav) { replyTo.value = null } } val scope = rememberCoroutineScope() @@ -358,6 +360,8 @@ fun ChannelScreen( } newPostModel.message = TextFieldValue("") replyTo.value = null + accountViewModel.deleteDraft(newPostModel.draftTag) + newPostModel.draftTag = UUID.randomUUID().toString() feedViewModel.sendToTop() } } @@ -368,6 +372,7 @@ fun ChannelScreen( fun DisplayReplyingToNote( replyingNote: Note?, accountViewModel: AccountViewModel, + newPostModel: NewPostViewModel, nav: (String) -> Unit, onCancel: () -> Unit, ) { @@ -386,6 +391,7 @@ fun DisplayReplyingToNote( null, innerQuote = true, accountViewModel = accountViewModel, + newPostViewModel = newPostModel, nav = nav, onWantsToReply = {}, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index da63ece2d..516594197 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -130,6 +130,7 @@ import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import java.util.UUID @Composable fun ChatroomScreen( @@ -332,6 +333,7 @@ fun ChatroomScreen( RefreshingChatroomFeedView( viewModel = feedViewModel, accountViewModel = accountViewModel, + newPostViewModel = newPostModel, nav = nav, routeForLastRead = "Room/${room.hashCode()}", onWantsToReply = { @@ -343,13 +345,16 @@ fun ChatroomScreen( Spacer(modifier = Modifier.height(10.dp)) - replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, nav) { replyTo.value = null } } + replyTo.value?.let { DisplayReplyingToNote(it, accountViewModel, newPostModel, nav) { replyTo.value = null } } val scope = rememberCoroutineScope() // LAST ROW PrivateMessageEditFieldRow(newPostModel, isPrivate = true, accountViewModel) { scope.launch(Dispatchers.IO) { + accountViewModel.deleteDraft(newPostModel.draftTag) + newPostModel.draftTag = UUID.randomUUID().toString() + val urls = findURLs(newPostModel.message.text) val usedAttachments = newPostModel.nip94attachments.filter { it.urls().intersect(urls.toSet()).isNotEmpty() } @@ -361,6 +366,7 @@ fun ChatroomScreen( mentions = null, wantsToMarkAsSensitive = false, nip94attachments = usedAttachments, + draftTag = null, ) } else { accountViewModel.account.sendPrivateMessage(