From 65457e5c11f99d7d6ac7b8730d5394b7514d3494 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 09:20:04 +0000 Subject: [PATCH] fix: spannable link in markdown (#2119) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub Żerko --- .../ui/home/conversations/mock/Mock.kt | 146 ++++++++++++++++++ .../model/MessageTypesPreview.kt | 66 ++++++++ .../android/ui/markdown/MarkdownComposer.kt | 2 +- 3 files changed, 213 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt index 9c50a96780b..5fb59824cf0 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/mock/Mock.kt @@ -90,6 +90,152 @@ val mockMessageWithText = UIMessage.Regular( messageFooter = mockEmptyFooter ) +val mockMessageWithMarkdownTextAndLinks = UIMessage.Regular( + userAvatarData = UserAvatarData(null, UserAvailabilityStatus.AVAILABLE), + header = mockHeader, + messageContent = UIMessageContent.TextMessage( + messageBody = MessageBody( + UIText.DynamicString( + """ +**bold text** + +_italic text_ + +**_bold and italic_** + +~~Strikethrough~~ + +# header + +# Code + +Inline `code` + +Indented code + +// Some comments +line 1 of code +line 2 of code +line 3 of code + + +Block code "fences" + +``` +Sample text here... +``` + +# Links +[AR PR](https://github.com/wireapp/wire-android-reloaded/pulls) + +Autoconverted link https://github.com/wireapp/kalium/pulls +""" + ) + ) + ), + source = MessageSource.Self, + messageFooter = mockEmptyFooter +) + +val mockMessageWithMarkdownListAndImages = UIMessage.Regular( + userAvatarData = UserAvatarData(null, UserAvailabilityStatus.AVAILABLE), + header = mockHeader, + messageContent = UIMessageContent.TextMessage( + messageBody = MessageBody( + UIText.DynamicString( + """ +## Lists + +Bullet List + ++ Create a list by starting a line with `+`, `-`, or `*` ++ Sub-lists are made by indenting 2 spaces: +- Marker character change forces new list start: +* Ac tristique libero volutpat at ++ Facilisis in pretium nisl aliquet +- Nulla volutpat aliquam velit ++ Very easy! + +Ordered + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit +3. Integer molestie lorem at massa + + +1. You can use sequential numbers... +1. ...or keep all the numbers as `1.` + +Start numbering with offset: + +57. foo +1. bar + +# Images + +Webp + +![Wire](https://wire.com/wp-content/uploads/2022/02/Independently-Audited-_-Open-Source-2.webp) + +Svg + +![Wire](https://wire.com/wp-content/uploads/2021/08/wire-logo.svg) + +Png + +![Wire](https://avatars.githubusercontent.com/u/16047324?s=280&v=4) +""" + ) + ) + ), + source = MessageSource.Self, + messageFooter = mockEmptyFooter +) + +val mockMessageWithMarkdownTablesAndBlocks = UIMessage.Regular( + userAvatarData = UserAvatarData(null, UserAvailabilityStatus.AVAILABLE), + header = mockHeader, + messageContent = UIMessageContent.TextMessage( + messageBody = MessageBody( + UIText.DynamicString( + """ +# Tables +| Task | Person | +| ------ | ----------- | +| MLS | John | +| Federation | Will | +| Navigation | Ashley | + + +## Thematic Break + +___ + +--- + +*** + + +# Blockquotes + + +> Blockquotes can also be nested... +>> ...by using additional greater-than signs right next to each other... +> > > ...or with spaces between arrows. + + +# Typographic replacements + +Enable typographer option to see result. + +(c) (C) (r) (R) (tm) (TM) (p) (P) +-""" + ) + ) + ), + source = MessageSource.Self, + messageFooter = mockEmptyFooter +) + val mockMessageWithKnock = UIMessage.System( header = mockHeader, messageContent = UIMessageContent.SystemMessage.Knock(UIText.DynamicString("John Doe pinged")), diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/MessageTypesPreview.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/MessageTypesPreview.kt index 1adc4cc8f4c..3c1e6bc5e00 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/MessageTypesPreview.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/MessageTypesPreview.kt @@ -33,6 +33,9 @@ import com.wire.android.ui.home.conversations.mock.mockAssetMessage import com.wire.android.ui.home.conversations.mock.mockFooter import com.wire.android.ui.home.conversations.mock.mockHeader import com.wire.android.ui.home.conversations.mock.mockMessageWithKnock +import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownTextAndLinks +import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownListAndImages +import com.wire.android.ui.home.conversations.mock.mockMessageWithMarkdownTablesAndBlocks import com.wire.android.ui.home.conversations.mock.mockMessageWithText import com.wire.android.ui.home.conversations.mock.mockedImageUIMessage import com.wire.android.ui.theme.WireTheme @@ -522,3 +525,66 @@ fun PreviewAggregatedMessagesWithErrorMessage() { } } } + +@PreviewMultipleThemes +@Composable +fun PreviewMessageWithMarkdownTextAndLinks() { + WireTheme { + MessageItem( + message = mockMessageWithMarkdownTextAndLinks, + audioMessagesState = emptyMap(), + onLongClicked = {}, + onAssetMessageClicked = {}, + onAudioClick = {}, + onChangeAudioPosition = { _, _ -> }, + onImageMessageClicked = { _, _ -> }, + onOpenProfile = { _ -> }, + onReactionClicked = { _, _ -> }, + onResetSessionClicked = { _, _ -> }, + onSelfDeletingMessageRead = {}, + conversationDetailsData = ConversationDetailsData.None + ) + } +} + +@PreviewMultipleThemes +@Composable +fun PreviewMessageWithMarkdownListAndImages() { + WireTheme { + MessageItem( + message = mockMessageWithMarkdownListAndImages, + audioMessagesState = emptyMap(), + onLongClicked = {}, + onAssetMessageClicked = {}, + onAudioClick = {}, + onChangeAudioPosition = { _, _ -> }, + onImageMessageClicked = { _, _ -> }, + onOpenProfile = { _ -> }, + onReactionClicked = { _, _ -> }, + onResetSessionClicked = { _, _ -> }, + onSelfDeletingMessageRead = {}, + conversationDetailsData = ConversationDetailsData.None + ) + } +} + +@PreviewMultipleThemes +@Composable +fun PreviewMessageWithMarkdownTablesAndBlocks() { + WireTheme { + MessageItem( + message = mockMessageWithMarkdownTablesAndBlocks, + audioMessagesState = emptyMap(), + onLongClicked = {}, + onAssetMessageClicked = {}, + onAudioClick = {}, + onChangeAudioPosition = { _, _ -> }, + onImageMessageClicked = { _, _ -> }, + onOpenProfile = { _ -> }, + onReactionClicked = { _, _ -> }, + onResetSessionClicked = { _, _ -> }, + onSelfDeletingMessageRead = {}, + conversationDetailsData = ConversationDetailsData.None + ) + } +} diff --git a/app/src/main/kotlin/com/wire/android/ui/markdown/MarkdownComposer.kt b/app/src/main/kotlin/com/wire/android/ui/markdown/MarkdownComposer.kt index 60ff8d40785..99abdd3f29c 100644 --- a/app/src/main/kotlin/com/wire/android/ui/markdown/MarkdownComposer.kt +++ b/app/src/main/kotlin/com/wire/android/ui/markdown/MarkdownComposer.kt @@ -236,7 +236,7 @@ fun appendLinksAndMentions( with(nodeData.colorScheme) { linkInfos.forEach { val safeStart = max(it.start, 0) - val safeEnd = min(it.end, length - 1) + val safeEnd = min(it.end, length) if (safeStart > safeEnd) { return@forEach }