Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: filter markdown by query [5164] #2752

Merged
merged 16 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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 @@ -116,7 +116,7 @@
text = it.text,
isSelected = it.isSelected
)
}
}.toPersistentList()

Check warning on line 119 in app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/mapper/RegularMessageContentMapper.kt#L119

Added line #L119 was not covered by tests
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -895,14 +895,14 @@ fun MessageList(
) {
val prevItemCount = remember { mutableStateOf(lazyPagingMessages.itemCount) }
LaunchedEffect(lazyPagingMessages.itemCount) {
if (lazyPagingMessages.itemCount > prevItemCount.value) {
prevItemCount.value = lazyPagingMessages.itemCount

if (lazyListState.firstVisibleItemIndex > 0
&& lazyListState.firstVisibleItemIndex <= MAXIMUM_SCROLLED_MESSAGES_UNTIL_AUTOSCROLL_STOPS
) {
if (lazyPagingMessages.itemCount > prevItemCount.value && selectedMessageId == null) {
val canScrollToLastMessage = prevItemCount.value > 0
&& lazyListState.firstVisibleItemIndex > 0
&& lazyListState.firstVisibleItemIndex <= MAXIMUM_SCROLLED_MESSAGES_UNTIL_AUTOSCROLL_STOPS
if (canScrollToLastMessage) {
lazyListState.animateScrollToItem(0)
}
prevItemCount.value = lazyPagingMessages.itemCount
}
}

Expand Down Expand Up @@ -965,7 +965,7 @@ fun MessageList(
showAuthor = showAuthor,
useSmallBottomPadding = useSmallBottomPadding,
audioMessagesState = audioMessagesState,
assetStatus = assetStatuses[message.header.messageId],
assetStatus = assetStatuses[message.header.messageId]?.transferStatus,
onAudioClick = onAudioItemClicked,
onChangeAudioPosition = onChangeAudioPosition,
onLongClicked = onShowEditingOption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.launchGeoIntent
import com.wire.kalium.logic.data.asset.AssetTransferStatus
import com.wire.kalium.logic.data.asset.isSaved
import com.wire.kalium.logic.data.message.MessageAssetStatus
import com.wire.kalium.logic.data.user.UserId
import kotlinx.collections.immutable.PersistentMap

Expand All @@ -102,7 +101,7 @@ fun MessageItem(
showAuthor: Boolean = true,
useSmallBottomPadding: Boolean = false,
audioMessagesState: PersistentMap<String, AudioState>,
assetStatus: MessageAssetStatus? = null,
assetStatus: AssetTransferStatus? = null,
onLongClicked: (UIMessage.Regular) -> Unit,
onAssetMessageClicked: (String) -> Unit,
onAudioClick: (String) -> Unit,
Expand Down Expand Up @@ -132,7 +131,7 @@ fun MessageItem(
) {
selfDeletionTimerState.startDeletionTimer(
message = message,
assetTransferStatus = assetStatus?.transferStatus,
assetTransferStatus = assetStatus,
onStartMessageSelfDeletion = onSelfDeletingMessageRead
)
}
Expand Down Expand Up @@ -231,7 +230,7 @@ fun MessageItem(
MessageAuthorRow(messageHeader = message.header)
}
if (selfDeletionTimerState is SelfDeletionTimerHelper.SelfDeletionTimerState.Expirable) {
MessageExpireLabel(messageContent, assetStatus?.transferStatus, selfDeletionTimerState.timeLeftFormatted)
MessageExpireLabel(messageContent, assetStatus, selfDeletionTimerState.timeLeftFormatted)

// if the message is marked as deleted and is [SelfDeletionTimer.SelfDeletionTimerState.Expirable]
// the deletion responsibility belongs to the receiver, therefore we need to wait for the receiver
Expand Down Expand Up @@ -507,8 +506,8 @@ private fun MessageContent(
message: UIMessage.Regular,
messageContent: UIMessageContent.Regular?,
searchQuery: String,
audioMessagesState: Map<String, AudioState>,
assetStatus: MessageAssetStatus?,
audioMessagesState: PersistentMap<String, AudioState>,
assetStatus: AssetTransferStatus?,
onAssetClick: Clickable,
onImageClick: Clickable,
onAudioClick: (String) -> Unit,
Expand All @@ -525,7 +524,7 @@ private fun MessageContent(
MessageImage(
asset = messageContent.asset,
imgParams = ImageMessageParams(messageContent.width, messageContent.height),
transferStatus = assetStatus?.transferStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
transferStatus = assetStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
onImageClick = onImageClick
)
PartialDeliveryInformation(messageContent.deliveryStatus)
Expand Down Expand Up @@ -593,7 +592,7 @@ private fun MessageContent(
assetName = messageContent.assetName,
assetExtension = messageContent.assetExtension,
assetSizeInBytes = messageContent.assetSizeInBytes,
assetTransferStatus = assetStatus?.transferStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
assetTransferStatus = assetStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
onAssetClick = onAssetClick
)
PartialDeliveryInformation(messageContent.deliveryStatus)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ private fun AssetMessagesListContent(
message = message,
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = audioMessagesState,
assetStatus = assetStatuses[message.header.messageId],
assetStatus = assetStatuses[message.header.messageId]?.transferStatus,
onLongClicked = { },
onAssetMessageClicked = onAssetItemClicked,
onAudioClick = onAudioItemClicked,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,27 @@ val mockMessageWithText = UIMessage.Regular(
messageFooter = mockEmptyFooter
)

val mockMessageWithTextLoremIpsum = UIMessage.Regular(
userAvatarData = UserAvatarData(null, UserAvailabilityStatus.AVAILABLE),
header = mockHeader,
messageContent = UIMessageContent.TextMessage(
messageBody = MessageBody(
UIText.DynamicString(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus volutpat lorem tortor, " +
"nec porttitor sapien pulvinar eu. Nullam orci dolor, eleifend quis massa non, posuere bibendum risus. " +
"Praesent velit ipsum, hendrerit et ante in, placerat pretium nunc. Sed orci velit, venenatis non vulputate non, " +
"venenatis sit amet enim. Quisque vestibulum, ligula in interdum rhoncus, magna ante porta velit, " +
"ut dignissim augue est et leo. Vestibulum in nunc eu velit elementum porttitor vitae eu nunc. " +
"Aliquam consectetur orci sit amet turpis consectetur, ut tempus velit pulvinar. Pellentesque et lorem placerat, " +
"aliquet odio non, consequat metus. Maecenas ultricies mauris quis lorem cursus dignissim. " +
"Nullam lacinia, nisl et dapibus consequat, sapien dolor maximus erat, quis aliquet dolor elit tincidunt orci."
)
)
),
source = MessageSource.Self,
messageFooter = mockEmptyFooter
)

val mockMessageWithMarkdownTextAndLinks = UIMessage.Regular(
userAvatarData = UserAvatarData(null, UserAvailabilityStatus.AVAILABLE),
header = mockHeader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ import com.wire.android.ui.home.conversations.model.messagetypes.image.ImportedI
import com.wire.android.ui.markdown.DisplayMention
import com.wire.android.ui.markdown.MarkdownConstants.MENTION_MARK
import com.wire.android.ui.markdown.MarkdownDocument
import com.wire.android.ui.markdown.MarkdownNode
import com.wire.android.ui.markdown.NodeData
import com.wire.android.ui.markdown.toContent
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
Expand All @@ -67,6 +69,7 @@ import com.wire.kalium.logic.data.asset.AssetTransferStatus.FAILED_DOWNLOAD
import com.wire.kalium.logic.data.asset.AssetTransferStatus.FAILED_UPLOAD
import com.wire.kalium.logic.data.asset.AssetTransferStatus.NOT_FOUND
import com.wire.kalium.logic.data.asset.AssetTransferStatus.UPLOAD_IN_PROGRESS
import kotlinx.collections.immutable.PersistentList
import okio.Path
import org.commonmark.Extension
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension
Expand All @@ -84,7 +87,7 @@ internal fun MessageBody(
searchQuery: String = "",
onLongClick: (() -> Unit)? = null,
onOpenProfile: (String) -> Unit,
buttonList: List<MessageButton>?,
buttonList: PersistentList<MessageButton>?,
onLinkClick: (String) -> Unit,
clickable: Boolean = true
) {
Expand All @@ -110,8 +113,9 @@ internal fun MessageBody(
TablesExtension.create()
)
text?.also {
val document = (Parser.builder().extensions(extensions).build().parse(it) as Document).toContent() as MarkdownNode.Document
MarkdownDocument(
Parser.builder().extensions(extensions).build().parse(it) as Document,
document,
nodeData,
clickable
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownListAn
import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownTablesAndBlocks
import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownTextAndLinks
import com.wire.android.ui.home.conversations.mock.mockMessageWithText
import com.wire.android.ui.home.conversations.mock.mockMessageWithTextLoremIpsum
import com.wire.android.ui.home.conversations.mock.mockedImageUIMessage
import com.wire.android.ui.theme.WireTheme
import com.wire.android.util.ui.PreviewMultipleThemes
import com.wire.android.util.ui.UIText
import com.wire.kalium.logic.data.asset.AssetTransferStatus
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.message.MessageAssetStatus
import com.wire.kalium.logic.data.user.UserId
import kotlinx.collections.immutable.persistentMapOf

Expand Down Expand Up @@ -336,11 +335,7 @@ fun PreviewImageMessageUploaded() {
message = mockedImageUIMessage(messageId = "assetMessageId"),
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
assetStatus = MessageAssetStatus(
"assetMessageId",
ConversationId("value", "domain"),
transferStatus = AssetTransferStatus.UPLOADED
),
assetStatus = AssetTransferStatus.UPLOADED,
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
Expand All @@ -363,11 +358,7 @@ fun PreviewImageMessageUploading() {
message = mockedImageUIMessage("assetMessageId"),
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
assetStatus = MessageAssetStatus(
"assetMessageId",
ConversationId("value", "domain"),
transferStatus = AssetTransferStatus.UPLOAD_IN_PROGRESS
),
assetStatus = AssetTransferStatus.UPLOAD_IN_PROGRESS,
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
Expand Down Expand Up @@ -396,11 +387,7 @@ fun PreviewImageMessageFailedUpload() {
),
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
assetStatus = MessageAssetStatus(
"assetMessageId",
ConversationId("value", "domain"),
transferStatus = AssetTransferStatus.FAILED_UPLOAD
),
assetStatus = AssetTransferStatus.FAILED_UPLOAD,
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
Expand Down Expand Up @@ -618,3 +605,92 @@ fun PreviewMessageWithMarkdownTablesAndBlocks() {
)
}
}

@PreviewMultipleThemes
@Composable
fun PreviewMessageWithMarkdownQuery() {
WireTheme {
Column {
MessageItem(
message = mockMessageWithTextLoremIpsum,
searchQuery = "ed",
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
onChangeAudioPosition = { _, _ -> },
onImageMessageClicked = { _, _ -> },
onOpenProfile = { _ -> },
onReactionClicked = { _, _ -> },
onResetSessionClicked = { _, _ -> },
onSelfDeletingMessageRead = {},
onReplyClickable = null
)
MessageItem(
message = mockMessageWithMarkdownTextAndLinks,
searchQuery = "code",
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
onChangeAudioPosition = { _, _ -> },
onImageMessageClicked = { _, _ -> },
onOpenProfile = { _ -> },
onReactionClicked = { _, _ -> },
onResetSessionClicked = { _, _ -> },
onSelfDeletingMessageRead = {},
onReplyClickable = null
)
MessageItem(
message = mockMessageWithMarkdownTextAndLinks,
searchQuery = ".com",
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
onChangeAudioPosition = { _, _ -> },
onImageMessageClicked = { _, _ -> },
onOpenProfile = { _ -> },
onReactionClicked = { _, _ -> },
onResetSessionClicked = { _, _ -> },
onSelfDeletingMessageRead = {},
onReplyClickable = null
)
MessageItem(
message = mockMessageWithMarkdownListAndImages,
searchQuery = "can",
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
onChangeAudioPosition = { _, _ -> },
onImageMessageClicked = { _, _ -> },
onOpenProfile = { _ -> },
onReactionClicked = { _, _ -> },
onResetSessionClicked = { _, _ -> },
onSelfDeletingMessageRead = {},
onReplyClickable = null
)
MessageItem(
message = mockMessageWithMarkdownTablesAndBlocks,
searchQuery = "Joh",
conversationDetailsData = ConversationDetailsData.None,
audioMessagesState = persistentMapOf(),
onLongClicked = {},
onAssetMessageClicked = {},
onAudioClick = {},
onChangeAudioPosition = { _, _ -> },
onImageMessageClicked = { _, _ -> },
onOpenProfile = { _ -> },
onReactionClicked = { _, _ -> },
onResetSessionClicked = { _, _ -> },
onSelfDeletingMessageRead = {},
onReplyClickable = null
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.wire.kalium.logic.data.user.UserId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList
Expand Down Expand Up @@ -220,7 +221,7 @@

data class Composite(
val messageBody: MessageBody?,
val buttonList: List<MessageButton>
val buttonList: PersistentList<MessageButton>

Check warning on line 224 in app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt#L224

Added line #L224 was not covered by tests
) : Regular(), Copyable {
override fun textToCopy(resources: Resources): String? = messageBody?.message?.asString(resources)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package com.wire.android.ui.markdown
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
Expand All @@ -31,10 +30,9 @@ import androidx.compose.ui.text.font.FontStyle
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireTypography
import org.commonmark.node.BlockQuote

@Composable
fun MarkdownBlockQuote(blockQuote: BlockQuote, nodeData: NodeData) {
fun MarkdownBlockQuote(blockQuote: MarkdownNode.Block.BlockQuote, nodeData: NodeData) {
val color = MaterialTheme.wireColorScheme.onBackground
val xOffset = dimensions().spacing12x.value
Column(modifier = Modifier
Expand All @@ -48,23 +46,30 @@ fun MarkdownBlockQuote(blockQuote: BlockQuote, nodeData: NodeData) {
}
.padding(start = dimensions().spacing16x, top = dimensions().spacing4x, bottom = dimensions().spacing4x)) {

var child = blockQuote.firstChild
while (child != null) {
blockQuote.children.map { child ->
when (child) {
is BlockQuote -> MarkdownBlockQuote(child, nodeData)
else -> {
is MarkdownNode.Block.BlockQuote -> MarkdownBlockQuote(child, nodeData)
is MarkdownNode.Block.Paragraph -> {
val text = buildAnnotatedString {
pushStyle(
MaterialTheme.wireTypography.body01.toSpanStyle()
.plus(SpanStyle(fontStyle = FontStyle.Italic))
)
inlineChildren(child, this, nodeData)
inlineNodeChildren(child.children, this, nodeData)
pop()
}
Text(text)
MarkdownText(
text,
onLongClick = nodeData.onLongClick,
onOpenProfile = nodeData.onOpenProfile
)
}

else -> MarkdownNodeBlockChildren(
children = child.children.filterIsInstance<MarkdownNode.Block>(),
nodeData = nodeData
)
}
child = child.next
}
}
}
Loading
Loading