From bfaa85778c3f22482eb149ef9263aa7723a1de17 Mon Sep 17 00:00:00 2001 From: Kanat Kiialbaev Date: Fri, 9 Aug 2024 00:28:40 -0400 Subject: [PATCH] [PBE-3977] add onMessageLinkClick to MessagesScreen (#5346) --- CHANGELOG.md | 1 + .../api/stream-chat-android-compose.api | 14 +++---- .../detekt-baseline.xml | 4 +- .../ui/components/messages/MessageContent.kt | 6 +++ .../ui/components/messages/MessageText.kt | 16 +++++--- .../components/messages/QuotedMessageText.kt | 41 ------------------- .../compose/ui/messages/MessagesScreen.kt | 2 + .../ui/messages/list/MessageContainer.kt | 7 ++++ .../compose/ui/messages/list/MessageItem.kt | 16 ++++++++ .../compose/ui/messages/list/MessageList.kt | 14 +++++++ 10 files changed, 65 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b065e8ba820..71309455ec4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ ### ⬆️ Improved ### ✅ Added +- Added `onMessageLinkClick` to `MessagesScreen` to handle message link clicks. [#5346](https://github.com/GetStream/stream-chat-android/pull/5346) ### ⚠️ Changed diff --git a/stream-chat-android-compose/api/stream-chat-android-compose.api b/stream-chat-android-compose/api/stream-chat-android-compose.api index e8d414cda2f..e9f9abef0ab 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -1125,7 +1125,7 @@ public final class io/getstream/chat/android/compose/ui/components/messages/Mess } public final class io/getstream/chat/android/compose/ui/components/messages/MessageContentKt { - public static final fun MessageContent (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V + public static final fun MessageContent (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class io/getstream/chat/android/compose/ui/components/messages/MessageFooterKt { @@ -1147,7 +1147,7 @@ public final class io/getstream/chat/android/compose/ui/components/messages/Mess } public final class io/getstream/chat/android/compose/ui/components/messages/MessageTextKt { - public static final fun MessageText (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V + public static final fun MessageText (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V } public final class io/getstream/chat/android/compose/ui/components/messages/MessageThreadFooterKt { @@ -1436,7 +1436,7 @@ public final class io/getstream/chat/android/compose/ui/composables/AudioWaveSee } public final class io/getstream/chat/android/compose/ui/messages/MessagesScreenKt { - public static final fun MessagesScreen (Lio/getstream/chat/android/compose/viewmodel/messages/MessagesViewModelFactory;ZLio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ZZLio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lio/getstream/chat/android/compose/state/messages/attachments/StatefulStreamMediaRecorder;Landroidx/compose/runtime/Composer;III)V + public static final fun MessagesScreen (Lio/getstream/chat/android/compose/viewmodel/messages/MessagesViewModelFactory;ZLio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ZZLio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lio/getstream/chat/android/compose/state/messages/attachments/StatefulStreamMediaRecorder;Landroidx/compose/runtime/Composer;III)V } public final class io/getstream/chat/android/compose/ui/messages/attachments/AttachmentsPickerKt { @@ -1773,17 +1773,17 @@ public final class io/getstream/chat/android/compose/ui/messages/list/Composable } public final class io/getstream/chat/android/compose/ui/messages/list/MessageContainerKt { - public static final fun MessageContainer (Lio/getstream/chat/android/ui/common/state/messages/list/MessageListItemState;Lio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V + public static final fun MessageContainer (Lio/getstream/chat/android/ui/common/state/messages/list/MessageListItemState;Lio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V } public final class io/getstream/chat/android/compose/ui/messages/list/MessageItemKt { public static final field HighlightFadeOutDurationMillis I - public static final fun MessageItem (Lio/getstream/chat/android/ui/common/state/messages/list/MessageItemState;Lio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;III)V + public static final fun MessageItem (Lio/getstream/chat/android/ui/common/state/messages/list/MessageItemState;Lio/getstream/chat/android/models/ReactionSorting;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;IIII)V } public final class io/getstream/chat/android/compose/ui/messages/list/MessageListKt { - public static final fun MessageList (Lio/getstream/chat/android/compose/viewmodel/messages/MessageListViewModel;Lio/getstream/chat/android/models/ReactionSorting;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Lio/getstream/chat/android/compose/ui/messages/list/MessagesLazyListState;Lio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V - public static final fun MessageList (Lio/getstream/chat/android/ui/common/state/messages/list/MessageListState;Lio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lio/getstream/chat/android/models/ReactionSorting;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Lio/getstream/chat/android/compose/ui/messages/list/MessagesLazyListState;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V + public static final fun MessageList (Lio/getstream/chat/android/compose/viewmodel/messages/MessageListViewModel;Lio/getstream/chat/android/models/ReactionSorting;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Lio/getstream/chat/android/compose/ui/messages/list/MessagesLazyListState;Lio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V + public static final fun MessageList (Lio/getstream/chat/android/ui/common/state/messages/list/MessageListState;Lio/getstream/chat/android/compose/ui/messages/list/ThreadMessagesStart;Lio/getstream/chat/android/models/ReactionSorting;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;Lio/getstream/chat/android/compose/ui/messages/list/MessagesLazyListState;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;IIII)V } public final class io/getstream/chat/android/compose/ui/messages/list/MessagesKt { diff --git a/stream-chat-android-compose/detekt-baseline.xml b/stream-chat-android-compose/detekt-baseline.xml index 9788831453b..4f3e24e2d5f 100644 --- a/stream-chat-android-compose/detekt-baseline.xml +++ b/stream-chat-android-compose/detekt-baseline.xml @@ -20,7 +20,7 @@ LongMethod:MediaGalleryPreviewActivity.kt$MediaGalleryPreviewActivity$@Composable private fun VideoPreviewContent( attachment: Attachment, pagerState: PagerState, page: Int, onPlaybackError: () -> Unit, ) LongMethod:MessageComposer.kt$@Composable internal fun DefaultComposerIntegrations( messageInputState: MessageComposerState, onAttachmentsClick: () -> Unit, onCommandsClick: () -> Unit, ownCapabilities: Set<String>, ) LongMethod:MessageComposer.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable internal fun DefaultMessageComposerTrailingContent( value: String, coolDownTime: Int, attachments: List<Attachment>, validationErrors: List<ValidationError>, ownCapabilities: Set<String>, isInEditMode: Boolean, onSendMessage: (String, List<Attachment>) -> Unit, onRecordingSaved: (Attachment) -> Unit, statefulStreamMediaRecorder: StatefulStreamMediaRecorder?, ) - LongMethod:MessageItem.kt$@Composable internal fun RegularMessageContent( messageItem: MessageItemState, modifier: Modifier = Modifier, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, ) + LongMethod:MessageItem.kt$@Composable internal fun RegularMessageContent( messageItem: MessageItemState, modifier: Modifier = Modifier, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, ) LongMethod:MessageOptions.kt$@Composable public fun defaultMessageOptionsState( selectedMessage: Message, currentUser: User?, isInThread: Boolean, ownCapabilities: Set<String>, ): List<MessageOptionItemState> LongMethod:MessagesScreen.kt$@OptIn(ExperimentalAnimationApi::class) @Composable private fun BoxScope.AttachmentsPickerMenu( listViewModel: MessageListViewModel, attachmentsPickerViewModel: AttachmentsPickerViewModel, composerViewModel: MessageComposerViewModel, ) LongMethod:PollCreationDiscardDialog.kt$@Composable public fun PollCreationDiscardDialog( usePlatformDefaultWidth: Boolean = false, onCancelClicked: () -> Unit, onDiscardClicked: () -> Unit, ) @@ -36,7 +36,7 @@ LongParameterList:MediaGalleryPreviewActivity.kt$MediaGalleryPreviewActivity$( context: Context, mediaGalleryPreviewAction: MediaGalleryPreviewAction, currentPage: Int, attachments: List<Attachment>, writePermissionState: PermissionState, downloadPayload: MutableState<Attachment?>, ) LongParameterList:MediaGalleryPreviewActivityAttachmentState.kt$MediaGalleryPreviewActivityAttachmentState$( val name: String?, val thumbUrl: String?, val imageUrl: String?, val assetUrl: String?, val originalWidth: Int?, val originalHeight: Int?, val type: String?, ) LongParameterList:MessageComposer.kt$( value: String, coolDownTime: Int, attachments: List<Attachment>, validationErrors: List<ValidationError>, ownCapabilities: Set<String>, isInEditMode: Boolean, onSendMessage: (String, List<Attachment>) -> Unit, onRecordingSaved: (Attachment) -> Unit, statefulStreamMediaRecorder: StatefulStreamMediaRecorder?, ) - LongParameterList:MessageItem.kt$( messageItem: MessageItemState, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit, onCastVote: (Message, Poll, Option) -> Unit, onRemoveVote: (Message, Poll, Vote) -> Unit, selectPoll: (Message, Poll, PollSelectionType) -> Unit, onClosePoll: (String) -> Unit, ) + LongParameterList:MessageItem.kt$( messageItem: MessageItemState, onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit, onCastVote: (Message, Poll, Option) -> Unit, onRemoveVote: (Message, Poll, Vote) -> Unit, selectPoll: (Message, Poll, PollSelectionType) -> Unit, onClosePoll: (String) -> Unit, ) LongParameterList:MessagesScreen.kt$( listViewModel: MessageListViewModel, composerViewModel: MessageComposerViewModel, selectedMessageState: SelectedMessageState?, selectedMessage: Message, skipPushNotification: Boolean, skipEnrichUrl: Boolean, ) LongParameterList:PollMessageContent.kt$( message: Message, poll: Poll, isMine: Boolean, onClosePoll: (String) -> Unit, onCastVote: (Option) -> Unit, onRemoveVote: (Vote) -> Unit, selectPoll: (Message, Poll, PollSelectionType) -> Unit, ) LongParameterList:PollMessageContent.kt$( modifier: Modifier = Modifier, poll: Poll, option: Option, voteCount: Int, totalVoteCount: Int, users: List<User>, checkedCount: Int, checked: Boolean, onCastVote: () -> Unit, onRemoveVote: () -> Unit, ) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageContent.kt index 04308c2a6af..c1937bcbd3e 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageContent.kt @@ -43,6 +43,7 @@ import io.getstream.chat.android.ui.common.state.messages.list.GiphyAction * @param onLongItemClick Handler when the item is long clicked. * @param onGiphyActionClick Handler for Giphy actions. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param giphyEphemeralContent Composable that represents the default Giphy message content. * @param deletedMessageContent Composable that represents the default content of a deleted message. @@ -57,6 +58,7 @@ public fun MessageContent( onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, giphyEphemeralContent: @Composable () -> Unit = { DefaultMessageGiphyContent( @@ -74,6 +76,7 @@ public fun MessageContent( onLongItemClick = onLongItemClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) }, ) { @@ -131,6 +134,7 @@ internal fun DefaultMessageDeletedContent( * @param onLongItemClick Handler when the item is long clicked. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. */ @Composable internal fun DefaultMessageContent( @@ -139,6 +143,7 @@ internal fun DefaultMessageContent( onLongItemClick: (Message) -> Unit, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit, + onLinkClick: ((Message, String) -> Unit)? = null, ) { Column { MessageAttachmentsContent( @@ -153,6 +158,7 @@ internal fun DefaultMessageContent( currentUser = currentUser, onLongItemClick = onLongItemClick, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) } } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageText.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageText.kt index 60d3ccdd609..1f5a6f558fc 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageText.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/MessageText.kt @@ -58,6 +58,7 @@ import io.getstream.chat.android.ui.common.utils.extensions.isMine * @param currentUser The currently logged in user. * @param modifier Modifier for styling. * @param onLongItemClick Handler used for long pressing on the message text. + * @param onLinkClick Handler used for clicking on a link in the message. */ @Composable public fun MessageText( @@ -65,6 +66,7 @@ public fun MessageText( currentUser: User?, modifier: Modifier = Modifier, onLongItemClick: (Message) -> Unit, + onLinkClick: ((Message, String) -> Unit)? = null, ) { val context = LocalContext.current @@ -101,12 +103,14 @@ public fun MessageText( }?.item if (!targetUrl.isNullOrEmpty()) { - context.startActivity( - Intent( - Intent.ACTION_VIEW, - Uri.parse(targetUrl), - ), - ) + onLinkClick?.invoke(message, targetUrl) ?: run { + context.startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(targetUrl), + ), + ) + } } } } else { diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt index ecd653ed5a1..b5523e1b70c 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt @@ -56,47 +56,6 @@ public fun QuotedMessageText( } } - // val displayedText = when (ChatTheme.autoTranslationEnabled) { - // true -> currentUser?.language?.let { userLanguage -> - // message.getTranslation(userLanguage).ifEmpty { message.text } - // } ?: message.text - // else -> message.text - // } - // - // val attachment = message.attachments.firstOrNull() - // val quotedMessageText = when { - // displayedText.isNotBlank() -> displayedText - // - // attachment != null -> when { - // attachment.name != null -> attachment.name - // - // attachment.text != null -> attachment.text - // - // attachment.isImage() -> { - // stringResource(R.string.stream_compose_quoted_message_image_tag) - // } - // attachment.isGiphy() -> { - // stringResource(R.string.stream_compose_quoted_message_giphy_tag) - // } - // attachment.isAnyFileType() -> { - // stringResource(R.string.stream_compose_quoted_message_file_tag) - // } - // else -> displayedText - // } - // - // else -> displayedText - // } - // - // checkNotNull(quotedMessageText) { - // "quotedMessageText is null. Cannot display invalid message title." - // } - // - // val textColor = if (replyMessage?.isMine(currentUser) != false) { - // ChatTheme.ownMessageTheme.textStyle.color - // } else { - // ChatTheme.otherMessageTheme.textStyle.color - // } - // val styledText = buildAnnotatedMessageText(quotedMessageText, textColor) val styledText = ChatTheme.quotedMessageTextFormatter.format(message, replyMessage, currentUser) val horizontalPadding = ChatTheme.dimens.quotedMessageTextHorizontalPadding diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt index a8e5754bd56..a761db791fc 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/MessagesScreen.kt @@ -137,6 +137,7 @@ public fun MessagesScreen( onHeaderTitleClick: (channel: Channel) -> Unit = {}, onChannelAvatarClick: () -> Unit = {}, onComposerLinkPreviewClick: ((LinkPreview) -> Unit)? = null, + onMessageLinkClick: ((Message, String) -> Unit)? = null, onUserAvatarClick: (User) -> Unit = {}, skipPushNotification: Boolean = false, skipEnrichUrl: Boolean = false, @@ -262,6 +263,7 @@ public fun MessagesScreen( } }, onUserAvatarClick = onUserAvatarClick, + onMessageLinkClick = onMessageLinkClick, onMediaGalleryPreviewResult = remember(listViewModel, composerViewModel) { { result -> diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageContainer.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageContainer.kt index 284696b1f5a..40b9b781d1f 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageContainer.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageContainer.kt @@ -67,6 +67,7 @@ import io.getstream.chat.android.ui.common.state.messages.poll.PollSelectionType * @param onClosePoll Handler for closing a poll. * @param onQuotedMessageClick Handler for quoted message click action. * @param onUserAvatarClick Handler when users avatar is clicked. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user receives a result from the Media Gallery Preview. * @param dateSeparatorContent Composable that represents date separators. * @param threadSeparatorContent Composable that represents thread separators. @@ -92,6 +93,7 @@ public fun MessageContainer( onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onUserAvatarClick: ((User) -> Unit)? = null, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, dateSeparatorContent: @Composable (DateSeparatorItemState) -> Unit = { DefaultMessageDateSeparatorContent(dateSeparator = it) @@ -123,6 +125,7 @@ public fun MessageContainer( onUserAvatarClick = { onUserAvatarClick?.invoke(it.message.user) }, + onLinkClick = onLinkClick, ) }, typingIndicatorContent: @Composable (TypingItemState) -> Unit = { }, @@ -261,6 +264,8 @@ internal fun DefaultSystemMessageContent(systemMessageState: SystemMessageItemSt * @param onClosePoll Handler for closing a poll. * @param onGiphyActionClick Handler when the user selects a Giphy action. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. + * @param onUserAvatarClick Handler when users avatar is clicked. * @param onMediaGalleryPreviewResult Handler when the user receives a result from the Media Gallery Preview. */ @Suppress("LongParameterList") @@ -272,6 +277,7 @@ internal fun DefaultMessageItem( onReactionsClick: (Message) -> Unit = {}, onThreadClick: (Message) -> Unit, onGiphyActionClick: (GiphyAction) -> Unit, + onLinkClick: ((Message, String) -> Unit)? = null, onPollUpdated: (Message, Poll) -> Unit = { _, _ -> }, onCastVote: (Message, Poll, Option) -> Unit, onRemoveVote: (Message, Poll, Vote) -> Unit, @@ -295,6 +301,7 @@ internal fun DefaultMessageItem( onGiphyActionClick = onGiphyActionClick, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, + onLinkClick = onLinkClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, ) } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt index 0f1c6a739a8..69096e70ebe 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt @@ -113,6 +113,7 @@ import io.getstream.chat.android.ui.common.state.messages.poll.PollSelectionType * @param onGiphyActionClick Handler when the user taps on an action button in a giphy message item. * @param onQuotedMessageClick Handler for quoted message click action. * @param onUserAvatarClick Handler when users avatar is clicked. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param leadingContent The content shown at the start of a message list item. By default, we provide * [DefaultMessageItemLeadingContent], which shows a user avatar if the message doesn't belong to the @@ -143,6 +144,7 @@ public fun MessageItem( onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, onUserAvatarClick: (() -> Unit)? = null, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, leadingContent: @Composable RowScope.(MessageItemState) -> Unit = { DefaultMessageItemLeadingContent( @@ -164,6 +166,7 @@ public fun MessageItem( onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onGiphyActionClick = onGiphyActionClick, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, onPollUpdated = onPollUpdated, onCastVote = onCastVote, onRemoveVote = onRemoveVote, @@ -423,6 +426,7 @@ internal fun DefaultMessageItemTrailingContent( * @param onLongItemClick Handler when the user selects a message, on long tap. * @param onGiphyActionClick Handler when the user taps on an action button in a giphy message item. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param onCastVote Handler when a user cast a vote on an option. * @param onRemoveVote Handler when a user cast a remove on an option. @@ -434,6 +438,7 @@ internal fun DefaultMessageItemCenterContent( onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, onPollUpdated: (Message, Poll) -> Unit, onCastVote: (Message, Poll, Option) -> Unit, @@ -468,6 +473,7 @@ internal fun DefaultMessageItemCenterContent( onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) } else { RegularMessageContent( @@ -477,6 +483,7 @@ internal fun DefaultMessageItemCenterContent( onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) } } @@ -489,6 +496,7 @@ internal fun DefaultMessageItemCenterContent( * @param onLongItemClick Handler when the user selects a message, on long tap. * @param onGiphyActionClick Handler when the user taps on an action button in a giphy message item. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler used when the user selects an option in the Media Gallery Preview screen. */ @Composable @@ -498,6 +506,7 @@ internal fun EmojiMessageContent( onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, ) { val message = messageItem.message @@ -542,6 +551,7 @@ internal fun EmojiMessageContent( * @param onLongItemClick Handler when the user selects a message, on long tap. * @param onGiphyActionClick Handler when the user taps on an action button in a giphy message item. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. */ @Composable @@ -551,6 +561,7 @@ internal fun RegularMessageContent( onLongItemClick: (Message) -> Unit = {}, onGiphyActionClick: (GiphyAction) -> Unit = {}, onQuotedMessageClick: (Message) -> Unit = {}, + onLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = {}, ) { val message = messageItem.message @@ -591,6 +602,7 @@ internal fun RegularMessageContent( onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) }, ) @@ -608,6 +620,7 @@ internal fun RegularMessageContent( onGiphyActionClick = onGiphyActionClick, onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, + onLinkClick = onLinkClick, ) }, ) @@ -630,6 +643,7 @@ internal fun RegularMessageContent( * @param message The message to show. * @param onLongItemClick Handler when the item is long clicked. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onLinkClick Handler for link clicks. */ @Composable internal fun DefaultMessageTextContent( @@ -637,6 +651,7 @@ internal fun DefaultMessageTextContent( currentUser: User?, onLongItemClick: (Message) -> Unit, onQuotedMessageClick: (Message) -> Unit, + onLinkClick: ((Message, String) -> Unit)? = null, ) { val quotedMessage = message.replyTo @@ -655,6 +670,7 @@ internal fun DefaultMessageTextContent( message = message, currentUser = currentUser, onLongItemClick = onLongItemClick, + onLinkClick = onLinkClick, ) } } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageList.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageList.kt index 7fe4819f2c7..b91142e8428 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageList.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageList.kt @@ -72,6 +72,7 @@ import io.getstream.chat.android.ui.common.state.messages.poll.SelectedPoll * @param onGiphyActionClick Handler when the user clicks on a giphy action such as shuffle, send or cancel. * @param onQuotedMessageClick Handler for quoted message click action. * @param onUserAvatarClick Handler when users avatar is clicked. + * @param onMessageLinkClick Handler for clicking on a link in the message. * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param onMessagesPageEndReached Handler for pagination when the end of newest messages have been reached. * @param onScrollToBottomClicked Handler when the user requests to scroll to the bottom of the messages list. @@ -135,6 +136,7 @@ public fun MessageList( ) }, onUserAvatarClick: ((User) -> Unit)? = null, + onMessageLinkClick: ((Message, String) -> Unit)? = null, onMediaGalleryPreviewResult: (MediaGalleryPreviewResult?) -> Unit = { if (it?.resultType == MediaGalleryPreviewResultType.SHOW_IN_CHAT) { viewModel.scrollToMessage( @@ -171,6 +173,7 @@ public fun MessageList( onGiphyActionClick = onGiphyActionClick, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, + onLinkClick = onMessageLinkClick, ) }, ) { @@ -195,6 +198,7 @@ public fun MessageList( onQuotedMessageClick = onQuotedMessageClick, onMessagesPageEndReached = onMessagesPageEndReached, onScrollToBottom = onScrollToBottomClicked, + onMessageLinkClick = onMessageLinkClick, ) } @@ -211,6 +215,11 @@ public fun MessageList( * @param onQuotedMessageClick Handler for quoted message click action. * @param onCastVote Handler for casting a vote on an option. * @param onClosePoll Handler for closing a poll. + * @param onPollUpdated Handler for updating a poll. + * @param onRemoveVote Handler for removing a vote. + * @param selectPoll Handler for selecting a poll. + * @param onUserAvatarClick Handler when users avatar is clicked. + * @param onLinkClick Handler for clicking on a link in the message. */ @Suppress("LongParameterList") @Composable @@ -229,6 +238,7 @@ internal fun DefaultMessageContainer( onClosePoll: (String) -> Unit = { _ -> }, onQuotedMessageClick: (Message) -> Unit, onUserAvatarClick: ((User) -> Unit)? = null, + onLinkClick: ((Message, String) -> Unit)? = null, ) { MessageContainer( messageListItemState = messageListItemState, @@ -245,6 +255,7 @@ internal fun DefaultMessageContainer( onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, + onLinkClick = onLinkClick, ) } @@ -300,6 +311,7 @@ internal fun DefaultMessageListEmptyContent(modifier: Modifier) { * @param onMediaGalleryPreviewResult Handler when the user selects an option in the Media Gallery Preview screen. * @param onGiphyActionClick Handler when the user clicks on a giphy action such as shuffle, send or cancel. * @param onQuotedMessageClick Handler for quoted message click action. + * @param onMessageLinkClick Handler for clicking on a link in the message. * @param onMessagesPageEndReached Handler for pagination when the end of newest messages have been reached. * @param onScrollToBottom Handler when the user requests to scroll to the bottom of the messages list. * @param loadingContent Composable that represents the loading content, when we're loading the initial data. @@ -337,6 +349,7 @@ public fun MessageList( onMessagesPageEndReached: (String) -> Unit = {}, onScrollToBottom: (() -> Unit) -> Unit = {}, onUserAvatarClick: ((User) -> Unit)? = null, + onMessageLinkClick: ((Message, String) -> Unit)? = null, loadingContent: @Composable () -> Unit = { DefaultMessageListLoadingIndicator(modifier) }, emptyContent: @Composable () -> Unit = { DefaultMessageListEmptyContent(modifier) }, helperContent: @Composable BoxScope.() -> Unit = { @@ -366,6 +379,7 @@ public fun MessageList( onMediaGalleryPreviewResult = onMediaGalleryPreviewResult, onQuotedMessageClick = onQuotedMessageClick, onUserAvatarClick = onUserAvatarClick, + onLinkClick = onMessageLinkClick, ) }, ) {