add edit draft in the dropdown menu and the long press popup

This commit is contained in:
greenart7c3 2024-03-20 14:50:53 -03:00
parent 090b643f43
commit ea33cc77ed
14 changed files with 150 additions and 35 deletions

View File

@ -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)

View File

@ -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)

View File

@ -129,7 +129,7 @@ object LocalCache {
val users = LargeCache<HexKey, User>()
val notes = LargeCache<HexKey, Note>()
val addressables = LargeCache<String, AddressableNote>()
val drafts = ConcurrentHashMap<String, MutableList<HexKey>>()
val drafts = ConcurrentHashMap<String, MutableList<Drafts>>()
val channels = ConcurrentHashMap<HexKey, Channel>()
val awaitingPaymentRequests = ConcurrentHashMap<HexKey, Pair<Note?, (LnZapPaymentResponseEvent) -> Unit>>(10)
@ -144,25 +144,30 @@ object LocalCache {
fun draftNotes(draftTag: String): List<Note> {
return drafts[draftTag]?.mapNotNull {
checkGetOrCreateNote(it)
getNoteIfExists(it.mainId)
} ?: listOf()
}
fun getDrafts(eventId: String): List<Note> {
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 {

View File

@ -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())
}
}
}

View File

@ -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()
}

View File

@ -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,

View File

@ -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<Color>? = 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<Color>? = 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<Color>? = 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<Color>? = 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<Int>,
showDetails: State<Boolean>,
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<Boolean>,
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<Color>,
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<Color>,
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,
)

View File

@ -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(

View File

@ -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<Boolean>,
showDeleteAlertDialog: MutableState<Boolean>,
showReportDialog: MutableState<Boolean>,
editDraftDialog: MutableState<Boolean>,
) {
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) {

View File

@ -237,7 +237,7 @@ fun NoteDropDownMenu(
},
)
HorizontalDivider(thickness = DividerThickness)
if (!note.isDraft()) {
if (note.isDraft()) {
DropdownMenuItem(
text = { Text(stringResource(R.string.edit_draft)) },
onClick = {

View File

@ -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,
)

View File

@ -637,7 +637,7 @@ fun NoteMaster(
)
}
NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel)
NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel, null)
}
}

View File

@ -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 = {},
)

View File

@ -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(