Skip to content

Commit 2431956

Browse files
authored
Fix link preview resolution and skipEnrichUrl in message composer (#6363)
* Set CallDispatcherProvider to test dispatcher in TestCoroutineExtension. TestCoroutineExtension already overrides DispatcherProvider for deterministic tests but was missing the equivalent CallDispatcherProvider setup. This caused Call.await() (via MapCall) to hop to real Dispatchers.IO, making tests non-deterministic. * - Track linkPreviewJob to cancel in-flight enrichment on clearData, preventing a resolved preview from appearing in an already-cleared composer after send. - Replace skipEnrichUrl derivation from linkPreviews.isEmpty() with intent-based logic aligned with the iOS SDK: default to false (let backend enrich), only skip when the user explicitly dismisses the preview or the text contains no URLs. Integrator overrides from ChannelScreen are preserved. * Add tests for link preview cancellation and skipEnrichUrl behavior * Given dismissed link preview When same URL text edited and sendMessage called Then skipEnrichUrl is true * Refactor `MessageComposerState` to support a single link preview instead of a list as per iOS. * Fix dismissed link preview reappearing after case change in URL.
1 parent 9c4fcf5 commit 2431956

7 files changed

Lines changed: 280 additions & 47 deletions

File tree

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ private fun MessageInputTop(
182182
) {
183183
val activeAction = messageComposerState.action
184184
val attachments = messageComposerState.attachments
185-
val linkPreviews = messageComposerState.linkPreviews
185+
val linkPreview = messageComposerState.linkPreview
186186
val showQuoted = activeAction is Reply
187187
val showEdit = activeAction is Edit
188188
val showAttachments = attachments.isNotEmpty()
189-
val showLinkPreview = ChatTheme.config.composer.linkPreviewEnabled && linkPreviews.isNotEmpty()
189+
val showLinkPreview = ChatTheme.config.composer.linkPreviewEnabled && linkPreview != null
190190
val isVisible = showQuoted || showEdit || showAttachments || showLinkPreview
191191

192192
if (isVisible) {
@@ -230,7 +230,7 @@ private fun MessageInputTop(
230230
if (showLinkPreview) {
231231
ChatTheme.componentFactory.MessageComposerLinkPreview(
232232
params = MessageComposerLinkPreviewParams(
233-
linkPreview = linkPreviews.first(),
233+
linkPreview = linkPreview,
234234
onContentClick = onLinkPreviewClick,
235235
onCancelClick = onCancelLinkPreviewClick,
236236
),
@@ -467,7 +467,7 @@ internal fun MessageComposerInputLink() {
467467
MessageInput(
468468
messageComposerState = PreviewMessageComposerState.copy(
469469
inputValue = PreviewLinkData.link1.originUrl,
470-
linkPreviews = listOf(PreviewLinkData.link1),
470+
linkPreview = PreviewLinkData.link1,
471471
),
472472
onCancelLinkPreviewClick = {},
473473
)
@@ -545,7 +545,7 @@ internal fun MessageComposerInputAttachmentsAndLink() {
545545
PreviewAttachmentData.attachmentImage1,
546546
PreviewAttachmentData.attachmentVideo1,
547547
),
548-
linkPreviews = listOf(PreviewLinkData.link1),
548+
linkPreview = PreviewLinkData.link1,
549549
),
550550
)
551551
}
@@ -571,7 +571,7 @@ internal fun MessageComposerInputReplyAttachmentsAndLink() {
571571
PreviewAttachmentData.attachmentImage1,
572572
PreviewAttachmentData.attachmentVideo1,
573573
),
574-
linkPreviews = listOf(PreviewLinkData.link1),
574+
linkPreview = PreviewLinkData.link1,
575575
),
576576
)
577577
}
@@ -597,7 +597,7 @@ internal fun MessageComposerInputEditAttachmentsAndLink() {
597597
PreviewAttachmentData.attachmentImage1,
598598
PreviewAttachmentData.attachmentVideo1,
599599
),
600-
linkPreviews = listOf(PreviewLinkData.link1),
600+
linkPreview = PreviewLinkData.link1,
601601
),
602602
)
603603
}

stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/ui/guides/ImplementingOwnCapabilities.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void customCapabilities() {
3131
Collections.emptyList(),
3232
Collections.emptyList(),
3333
Collections.emptyList(),
34-
Collections.emptyList(),
34+
null,
3535
0,
3636
MessageMode.Normal.INSTANCE,
3737
false,

stream-chat-android-test/src/main/java/io/getstream/chat/android/test/TestCoroutineExtension.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package io.getstream.chat.android.test
2020

2121
import io.getstream.chat.android.core.internal.coroutines.DispatcherProvider
22+
import io.getstream.result.call.dispatcher.CallDispatcherProvider
2223
import kotlinx.coroutines.Dispatchers
2324
import kotlinx.coroutines.ExperimentalCoroutinesApi
2425
import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -50,6 +51,10 @@ public class TestCoroutineExtension : BeforeEachCallback, BeforeAllCallback, Aft
5051
mainDispatcher = dispatcher,
5152
ioDispatcher = dispatcher,
5253
)
54+
CallDispatcherProvider.set(
55+
mainDispatcher = dispatcher,
56+
ioDispatcher = dispatcher,
57+
)
5358
beforeAllCalled = true
5459
}
5560

@@ -61,6 +66,7 @@ public class TestCoroutineExtension : BeforeEachCallback, BeforeAllCallback, Aft
6166
override fun afterAll(context: ExtensionContext) {
6267
Dispatchers.resetMain()
6368
DispatcherProvider.reset()
69+
CallDispatcherProvider.reset()
6470
_scope = null
6571
}
6672

stream-chat-android-ui-common/api/stream-chat-android-ui-common.api

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,19 +2290,19 @@ public final class io/getstream/chat/android/ui/common/state/messages/composer/M
22902290
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;)V
22912291
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;)V
22922292
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
2293-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
2294-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;I)V
2295-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;)V
2296-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;Z)V
2297-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;)V
2298-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;Z)V
2299-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;)V
2300-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;)V
2301-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;Z)V
2302-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZ)V
2303-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;)V
2304-
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;)V
2305-
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
2293+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;)V
2294+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;I)V
2295+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;)V
2296+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;Z)V
2297+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;)V
2298+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;Z)V
2299+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;)V
2300+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;)V
2301+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;Z)V
2302+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZ)V
2303+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;)V
2304+
public fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;)V
2305+
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
23062306
public final fun component1 ()Ljava/lang/String;
23072307
public final fun component10 ()Z
23082308
public final fun component11 ()Ljava/util/Set;
@@ -2318,11 +2318,11 @@ public final class io/getstream/chat/android/ui/common/state/messages/composer/M
23182318
public final fun component4 ()Ljava/util/List;
23192319
public final fun component5 ()Ljava/util/List;
23202320
public final fun component6 ()Ljava/util/List;
2321-
public final fun component7 ()Ljava/util/List;
2321+
public final fun component7 ()Lio/getstream/chat/android/models/LinkPreview;
23222322
public final fun component8 ()I
23232323
public final fun component9 ()Lio/getstream/chat/android/ui/common/state/messages/MessageMode;
2324-
public final fun copy (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;)Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;
2325-
public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;
2324+
public final fun copy (Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;)Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;
2325+
public static synthetic fun copy$default (Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;Ljava/lang/String;Ljava/util/List;Lio/getstream/chat/android/ui/common/state/messages/MessageAction;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lio/getstream/chat/android/models/LinkPreview;ILio/getstream/chat/android/ui/common/state/messages/MessageMode;ZLjava/util/Set;ZLio/getstream/chat/android/models/User;Lio/getstream/chat/android/ui/common/state/messages/composer/RecordingState;ZZLjava/util/Set;Lio/getstream/chat/android/models/Command;ILjava/lang/Object;)Lio/getstream/chat/android/ui/common/state/messages/composer/MessageComposerState;
23262326
public fun equals (Ljava/lang/Object;)Z
23272327
public final fun getAction ()Lio/getstream/chat/android/ui/common/state/messages/MessageAction;
23282328
public final fun getActiveCommand ()Lio/getstream/chat/android/models/Command;
@@ -2333,7 +2333,7 @@ public final class io/getstream/chat/android/ui/common/state/messages/composer/M
23332333
public final fun getCurrentUser ()Lio/getstream/chat/android/models/User;
23342334
public final fun getHasCommands ()Z
23352335
public final fun getInputValue ()Ljava/lang/String;
2336-
public final fun getLinkPreviews ()Ljava/util/List;
2336+
public final fun getLinkPreview ()Lio/getstream/chat/android/models/LinkPreview;
23372337
public final fun getMentionSuggestions ()Ljava/util/List;
23382338
public final fun getMessageMode ()Lio/getstream/chat/android/ui/common/state/messages/MessageMode;
23392339
public final fun getOwnCapabilities ()Ljava/util/Set;

0 commit comments

Comments
 (0)