Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ class RegularMessageMapper @Inject constructor(

is MessageContent.Composite -> {
val text = content.textContent?.let { textContent ->
val quotedMessage = textContent.quotedMessageDetails?.let { mapQuoteData(message.conversationId, it) }
val quotedMessage = textContent.quotedMessageDetails?.let {
mapQuoteData(
conversationId = textContent.quotedMessageReference?.quotedMessageConversationId ?: message.conversationId,
details = it
)
}
?: if (textContent.quotedMessageReference?.quotedMessageId != null) {
UIQuotedMessage.UnavailableData
} else {
Expand Down Expand Up @@ -169,7 +174,12 @@ class RegularMessageMapper @Inject constructor(
): UIMessageContent.TextMessage {
val messageTextContent = (content as? MessageContent.Text)

val quotedMessage = messageTextContent?.quotedMessageDetails?.let { mapQuoteData(conversationId, it) }
val quotedMessage = messageTextContent?.quotedMessageDetails?.let {
mapQuoteData(
conversationId = messageTextContent.quotedMessageReference?.quotedMessageConversationId ?: conversationId,
details = it
)
}
?: if (messageTextContent?.quotedMessageReference?.quotedMessageId != null) {
UIQuotedMessage.UnavailableData
} else {
Expand Down Expand Up @@ -207,6 +217,7 @@ class RegularMessageMapper @Inject constructor(
private fun mapQuoteData(conversationId: ConversationId, details: MessageContent.QuotedMessageDetails) =
UIQuotedMessage.UIQuotedData(
messageId = details.messageId,
conversationId = conversationId,
senderId = details.senderId,
senderName = details.senderName.orUnknownName(),
senderAccent = Accent.fromAccentId(details.accentId),
Expand Down Expand Up @@ -330,7 +341,12 @@ class RegularMessageMapper @Inject constructor(
deliveryStatus: DeliveryStatus
): UIMessageContent.Multipart {

val quotedMessage = content.quotedMessageDetails?.let { mapQuoteData(conversationId = conversationId, details = it) }
val quotedMessage = content.quotedMessageDetails?.let {
mapQuoteData(
conversationId = content.quotedMessageReference?.quotedMessageConversationId ?: conversationId,
details = it
)
}
?: if (content.quotedMessageReference?.quotedMessageId != null) {
UIQuotedMessage.UnavailableData
} else {
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/kotlin/com/wire/android/ui/edit/ReplyMessageOption.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,17 @@ fun ReplyMessageOption(onReplyItemClick: () -> Unit) {
onItemClick = onReplyItemClick
)
}

@Composable
fun ReplyInPrivateMessageOption(onReplyItemClick: () -> Unit) {
MenuBottomSheetItem(
leading = {
MenuItemIcon(
id = R.drawable.ic_reply,
contentDescription = stringResource(R.string.content_description_reply_in_private_to_message),
)
},
title = stringResource(R.string.message_option_reply_in_private),
onItemClick = onReplyItemClick
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.wire.android.ui.home.conversations.messagedetails.usecase.ObserveRece
import com.wire.android.ui.home.conversations.migration.ConversationMigrationViewModel
import com.wire.android.ui.home.conversations.model.messagetypes.multipart.CellAssetRefreshHelper
import com.wire.android.ui.home.conversations.model.messagetypes.multipart.MultipartAttachmentsViewModelImpl
import com.wire.android.ui.home.conversations.privateReply.ReplyInPrivateViewModel
import com.wire.android.ui.home.conversations.sendmessage.SendMessageViewModel
import com.wire.android.ui.home.conversations.usecase.GetMessagesForConversationUseCase
import com.wire.android.ui.home.conversations.usecase.GetQuoteMessageForConversationUseCase
Expand Down Expand Up @@ -80,6 +81,7 @@ import com.wire.kalium.logic.feature.client.IsWireCellsEnabledForConversationUse
import com.wire.kalium.logic.feature.client.IsWireCellsEnabledUseCase
import com.wire.kalium.logic.feature.conversation.ClearUsersTypingEventsUseCase
import com.wire.kalium.logic.feature.conversation.GetConversationUnreadEventsCountUseCase
import com.wire.kalium.logic.feature.conversation.GetOrCreateOneToOneConversationUseCase
import com.wire.kalium.logic.feature.conversation.MarkConversationAsReadLocallyUseCase
import com.wire.kalium.logic.feature.conversation.MembersToMentionUseCase
import com.wire.kalium.logic.feature.conversation.NotifyConversationIsOpenUseCase
Expand Down Expand Up @@ -184,6 +186,7 @@ class ConversationCoreViewModelFactory @Inject constructor(
private val getAssetMessages: GetAssetMessagesFromConversationUseCase,
private val observeConversationMembersByTypes: ObserveConversationMembersByTypesUseCase,
private val notifyConversationIsOpen: NotifyConversationIsOpenUseCase,
private val getOrCreateOneToOneConversation: GetOrCreateOneToOneConversationUseCase,
private val qualifiedIdMapper: QualifiedIdMapper,
private val fetchConversationMLSVerificationStatus: FetchConversationMLSVerificationStatusUseCase,
private val observeReactionsForMessage: ObserveReactionsForMessageUseCase,
Expand Down Expand Up @@ -272,6 +275,11 @@ class ConversationCoreViewModelFactory @Inject constructor(
saveMessageDraft = saveMessageDraft,
)

fun replyInPrivateViewModel() = ReplyInPrivateViewModel(
getOrCreateOneToOneConversation = getOrCreateOneToOneConversation,
saveMessageDraft = saveMessageDraft,
)

fun messageAttachmentsViewModel(savedStateHandle: SavedStateHandle) = MessageAttachmentsViewModel(
savedStateHandle = savedStateHandle,
handleUriAsset = handleUriAsset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.wire.android.ui.home.conversations.messages.item.ConversationAssetPat
import com.wire.android.ui.home.conversations.migration.ConversationMigrationViewModel
import com.wire.android.ui.home.conversations.model.messagetypes.multipart.MultipartAttachmentsViewModel
import com.wire.android.ui.home.conversations.model.messagetypes.multipart.MultipartAttachmentsViewModelImpl
import com.wire.android.ui.home.conversations.privateReply.ReplyInPrivateViewModel
import com.wire.android.ui.home.conversations.sendmessage.SendMessageViewModel
import com.wire.android.ui.home.gallery.MediaGalleryViewModel
import com.wire.android.ui.home.messagecomposer.location.LocationPickerViewModel
Expand All @@ -67,6 +68,10 @@ fun sendMessageViewModel(): SendMessageViewModel =
fun messageDraftViewModel(): MessageDraftViewModel =
conversationSavedStateViewModel { this.messageDraftViewModel(it) }

@Composable
fun replyInPrivateViewModel(): ReplyInPrivateViewModel =
conversationViewModel { this.replyInPrivateViewModel() }

@Composable
fun messageAttachmentsViewModel(): MessageAttachmentsViewModel =
conversationSavedStateViewModel { this.messageAttachmentsViewModel(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ import com.wire.android.ui.home.conversations.model.UIMessage
import com.wire.android.ui.home.conversations.model.UIMessageContent
import com.wire.android.ui.home.conversations.model.UIQuotedMessage
import com.wire.android.ui.home.conversations.model.UriAsset
import com.wire.android.ui.home.conversations.privateReply.ReplyInPrivateAction
import com.wire.android.ui.home.conversations.privateReply.ReplyInPrivateViewModel
import com.wire.android.ui.home.conversations.selfdeletion.SelfDeletionOptionsModalSheetLayout
import com.wire.android.ui.home.conversations.sendmessage.SendMessageViewModel
import com.wire.android.ui.home.gallery.MediaGalleryActionType
Expand Down Expand Up @@ -269,10 +271,12 @@ fun ConversationScreen(
conversationMigrationViewModel: ConversationMigrationViewModel = conversationMigrationViewModel(),
messageDraftViewModel: MessageDraftViewModel = messageDraftViewModel(),
messageAttachmentsViewModel: MessageAttachmentsViewModel = messageAttachmentsViewModel(),
replyInPrivateViewModel: ReplyInPrivateViewModel = replyInPrivateViewModel(),
) {
val coroutineScope = rememberCoroutineScope()
val uriHandler = LocalUriHandler.current
val resources = LocalContext.current.resources
val snackbarHostState = LocalSnackbarHostState.current
val showDialog = remember { mutableStateOf(ConversationScreenDialogType.NONE) }
val messageComposerViewState = messageComposerViewModel.messageComposerViewState
val messageComposerStateHolder = rememberMessageComposerStateHolder(
Expand Down Expand Up @@ -348,7 +352,10 @@ fun ConversationScreen(
LaunchedEffect(messageDraftViewModel.state.value.quotedMessageId) {
val compositionState = messageDraftViewModel.state.value
if (compositionState.quotedMessage != null) {
messageComposerStateHolder.messageCompositionHolder.value.updateQuote(compositionState.quotedMessage)
messageComposerStateHolder.messageCompositionHolder.value.updateQuote(
quotedMessage = compositionState.quotedMessage,
quotedMessageConversationId = compositionState.quotedMessageConversationId
)
}
}

Expand All @@ -372,6 +379,21 @@ fun ConversationScreen(
}
}

HandleActions(replyInPrivateViewModel.actions) { action ->
when (action) {
ReplyInPrivateAction.Failure -> coroutineScope.launch {
snackbarHostState.showSnackbar(resources.getString(R.string.error_conversation_generic))
}

is ReplyInPrivateAction.Navigate -> navigator.navigate(
NavigationCommand(
ConversationScreenDestination(action.conversationId),
BackStackMode.UPDATE_EXISTED
)
)
}
}

conversationMigrationViewModel.migratedConversationId?.let { migratedConversationId ->
navigator.navigate(
NavigationCommand(
Expand Down Expand Up @@ -625,6 +647,7 @@ fun ConversationScreen(
onReactionClick = { messageId, emoji ->
conversationMessagesViewModel.toggleReaction(messageId, emoji)
},
onReplyInPrivateClick = replyInPrivateViewModel::replyInPrivate,
onResetSessionClick = conversationMessagesViewModel::onResetSession,
onUpdateConversationReadDate = messageComposerViewModel::updateConversationReadDate,
onDropDownClick = {
Expand Down Expand Up @@ -671,7 +694,22 @@ fun ConversationScreen(
shareAsset = conversationMessagesViewModel::shareAsset,
onDownloadAssetClick = conversationMessagesViewModel::openOrFetchAsset,
onOpenAssetClick = conversationMessagesViewModel::downloadAndOpenAsset,
onNavigateToReplyOriginalMessage = conversationMessagesViewModel::navigateToReplyOriginalMessage,
onNavigateToReplyOriginalMessage = { message ->
message.quotedMessageData()?.let { quotedData ->
navigator.navigate(
NavigationCommand(
ConversationScreenDestination(
navArgs = ConversationNavArgs(
conversationId = quotedData.conversationId,
searchedMessageId = quotedData.messageId
)
),
BackStackMode.REMOVE_CURRENT_AND_REPLACE,
launchSingleTop = false
)
)
}
},
onSelfDeletingMessageRead = messageComposerViewModel::startSelfDeletion,
onNewSelfDeletingMessagesStatus = messageComposerViewModel::updateSelfDeletingMessages,
tempWritableImageUri = messageComposerViewModel.tempWritableImageUri,
Expand Down Expand Up @@ -977,6 +1015,7 @@ private fun ConversationScreen(
onStartCall: () -> Unit,
onJoinCall: () -> Unit,
onReactionClick: (messageId: String, reactionEmoji: String) -> Unit,
onReplyInPrivateClick: (UIMessage.Regular) -> Unit,
onResetSessionClick: (senderUserId: UserId, clientId: String?) -> Unit,
onUpdateConversationReadDate: (String) -> Unit,
onDropDownClick: () -> Unit,
Expand Down Expand Up @@ -1123,6 +1162,8 @@ private fun ConversationScreen(
onReactionClick = onReactionClick,
onDetailsClick = onMessageDetailsClick,
onReplyClick = messageComposerStateHolder::toReply,
onReplyInPrivateClick = onReplyInPrivateClick,
isGroupConversation = conversationInfoViewState.conversationType is Conversation.Type.Group,
onEditClick = messageComposerStateHolder::toEdit,
onShareAssetClick = { shareAsset(context, it) },
onDownloadAssetClick = onDownloadAssetClick,
Expand Down Expand Up @@ -1943,6 +1984,14 @@ private fun CoroutineScope.withSmoothScreenLoad(block: () -> Unit) = launch {
block()
}

private fun UIMessage.quotedMessageData(): UIQuotedMessage.UIQuotedData? =
when (val content = messageContent) {
is UIMessageContent.TextMessage -> content.messageBody.quotedMessage as? UIQuotedMessage.UIQuotedData
is UIMessageContent.Composite -> content.messageBody?.quotedMessage as? UIQuotedMessage.UIQuotedData
is UIMessageContent.Multipart -> content.messageBody?.quotedMessage as? UIQuotedMessage.UIQuotedData
else -> null
}

enum class ConversationActionPermissionType {
CaptureVideo, TakePicture, ChooseImage, ChooseFile, CallAudio
}
Expand Down Expand Up @@ -1985,6 +2034,7 @@ fun PreviewConversationScreen() = WireTheme {
onStartCall = { },
onJoinCall = { },
onReactionClick = { _, _ -> },
onReplyInPrivateClick = { },
onResetSessionClick = { _, _ -> },
onUpdateConversationReadDate = { },
onDropDownClick = { },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.wire.android.ui.edit.DownloadAssetExternallyOption
import com.wire.android.ui.edit.MessageDetailsMenuOption
import com.wire.android.ui.edit.OpenAssetExternallyOption
import com.wire.android.ui.edit.ReactionOption
import com.wire.android.ui.edit.ReplyInPrivateMessageOption
import com.wire.android.ui.edit.ReplyMessageOption
import com.wire.android.ui.edit.ShareAssetMenuOption

Expand All @@ -36,6 +37,8 @@ fun assetMessageOptionsMenuItems(
onShareAsset: () -> Unit,
onDownloadAsset: () -> Unit,
onReplyClick: () -> Unit,
onReplyInPrivateClick: () -> Unit,
isReplyInPrivateAllowed: Boolean,
onReactionClick: (emoji: String) -> Unit,
isOpenable: Boolean = false,
onOpenAsset: () -> Unit = {},
Expand All @@ -58,6 +61,7 @@ fun assetMessageOptionsMenuItems(
add { ReactionOption(ownReactions, onReactionClick) }
add { MessageDetailsMenuOption(onDetailsClick) }
add { ReplyMessageOption(onReplyClick) }
if (isReplyInPrivateAllowed) add { ReplyInPrivateMessageOption(onReplyInPrivateClick) }
add { DownloadAssetExternallyOption(onDownloadAsset) }
add { ShareAssetMenuOption(onShareAsset) }
if (isOpenable) add { OpenAssetExternallyOption(onOpenAsset) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ fun messageOptionsMenuItems(
onReactionClick: (reactionEmoji: String) -> Unit,
onDetailsClick: () -> Unit,
onReplyClick: () -> Unit,
onReplyInPrivateClick: () -> Unit,
isReplyInPrivateAllowed: Boolean,
onEditClick: () -> Unit,
onShareAssetClick: () -> Unit,
onDownloadAssetClick: () -> Unit,
Expand All @@ -51,6 +53,8 @@ fun messageOptionsMenuItems(
onShareAsset = onShareAssetClick,
onDownloadAsset = onDownloadAssetClick,
onReplyClick = onReplyClick,
onReplyInPrivateClick = onReplyInPrivateClick,
isReplyInPrivateAllowed = isReplyInPrivateAllowed,
onReactionClick = onReactionClick,
onOpenAsset = onOpenAssetClick,
)
Expand All @@ -67,7 +71,9 @@ fun messageOptionsMenuItems(
onReactionClick = onReactionClick,
onEditClick = onEditClick,
onCopyClick = onCopyClick,
onReplyClick = onReplyClick
onReplyClick = onReplyClick,
onReplyInPrivateClick = onReplyInPrivateClick,
isReplyInPrivateAllowed = isReplyInPrivateAllowed,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ fun MessageOptionsModalSheetLayout(
onReactionClick: (messageId: String, reactionEmoji: String) -> Unit,
onDetailsClick: (messageId: String, isSelfMessage: Boolean) -> Unit,
onReplyClick: (UIMessage.Regular) -> Unit,
onReplyInPrivateClick: (UIMessage.Regular) -> Unit,
isGroupConversation: Boolean,
onEditClick: (messageId: String, messageBody: String, mentions: List<MessageMention>, isMultipart: Boolean) -> Unit,
onShareAssetClick: (messageId: String) -> Unit,
onDownloadAssetClick: (messageId: String) -> Unit,
Expand All @@ -78,6 +80,8 @@ fun MessageOptionsModalSheetLayout(
onReactionClick = onReactionClick,
onDetailsClick = onDetailsClick,
onReplyClick = onReplyClick,
onReplyInPrivateClick = onReplyInPrivateClick,
isGroupConversation = isGroupConversation,
onEditClick = onEditClick,
onShareAssetClick = onShareAssetClick,
onDownloadAssetClick = onDownloadAssetClick,
Expand Down Expand Up @@ -111,6 +115,8 @@ private fun MessageOptionsModalContent(
onReactionClick: (messageId: String, reactionEmoji: String) -> Unit,
onDetailsClick: (messageId: String, isSelfMessage: Boolean) -> Unit,
onReplyClick: (UIMessage.Regular) -> Unit,
onReplyInPrivateClick: (UIMessage.Regular) -> Unit,
isGroupConversation: Boolean,
onEditClick: (messageId: String, messageBody: String, mentions: List<MessageMention>, isMultipart: Boolean) -> Unit,
onShareAssetClick: (messageId: String) -> Unit,
onDownloadAssetClick: (messageId: String) -> Unit,
Expand All @@ -121,6 +127,7 @@ private fun MessageOptionsModalContent(
val isDeleted = message.isDeleted
val isMyMessage = message.isMyMessage
val isEphemeral = message.header.messageStatus.expirationStatus is ExpirationStatus.Expirable
val isReplyInPrivateAllowed = isGroupConversation && message.isReplyable && !isMyMessage && message.header.userId != null
WireMenuModalSheetContent(
header = MenuModalSheetHeader.Gone,
menuItems = messageOptionsMenuItems(
Expand Down Expand Up @@ -172,6 +179,14 @@ private fun MessageOptionsModalContent(
}
}
},
onReplyInPrivateClick = remember(message.header.messageId) {
{
sheetState.hide {
onReplyInPrivateClick(message)
}
}
},
isReplyInPrivateAllowed = isReplyInPrivateAllowed,
onEditClick = remember(message.header.messageId, message.messageContent) {
{
when (message.messageContent) {
Expand Down Expand Up @@ -255,6 +270,8 @@ fun PreviewMessageOptionsModalSheetLayout() = WireTheme {
onReactionClick = { _, _ -> },
onDetailsClick = { _, _ -> },
onReplyClick = { },
onReplyInPrivateClick = { },
isGroupConversation = true,
onEditClick = { _, _, _, _ -> },
onShareAssetClick = { },
onDownloadAssetClick = { },
Expand Down
Loading
Loading