From 14c847e8433116b1add03a0c9d67d6be344438e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mion?= Date: Mon, 1 Jun 2026 15:47:42 +0100 Subject: [PATCH 1/4] Announce Giphy alt text to TalkBack The Giphy image had `contentDescription = null`, so TalkBack only announced the "Giphy" overlay badge on focus. Set the image's `contentDescription` to the attachment title (when non-blank), so screen-reader users hear the search query together with the badge, e.g. "Hello, giphy". When the title is blank or absent, falls back to the existing "Giphy" announcement. Improves both the ephemeral preview path and sent Giphy messages. --- .../compose/ui/attachments/content/GiphyAttachmentContent.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt index 538c1cabb60..048c9c7064d 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt @@ -142,7 +142,7 @@ public fun GiphyAttachmentContent( StreamAsyncImage( data = giphyInfo?.url, modifier = Modifier.fillMaxSize(), - contentDescription = null, + contentDescription = attachment.title?.takeIf(String::isNotBlank), contentScale = contentScale, ) From ca07128cc22e472df9015a7aab25b24856b7a98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mion?= Date: Mon, 1 Jun 2026 16:57:48 +0100 Subject: [PATCH 2/4] Focus the Giphy preview bubble for TalkBack on appearance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After a `/giphy` command, the ephemeral preview rendered in the message list but TalkBack focus stayed on the composer. Screen- reader users had no signal the preview arrived. Wrap the visible-to-you row + the Giphy image in a focusable `Column` with `Modifier.semantics(mergeDescendants = true) {}`, and request focus on it 100 ms after the message id is first composed. Mirrors the precedent in `MessageComposerAudioRecordingLockedContent`. Adds `interactive: Boolean = true` to `GiphyAttachmentContent` and `GiphyAttachmentContentParams`. The ephemeral preview passes `false`, which skips the inner `combinedClickable` — both its handlers are no-ops in the ephemeral case, and the inner clickable was a nested accessibility merge boundary that kept the image alt and "Giphy" badge from merging into the bubble's focus. TalkBack now announces the bubble as one focus, e.g. "Only visible to you, Hello, Giphy". --- .../api/stream-chat-android-compose.api | 12 +- .../content/GiphyAttachmentContent.kt | 42 ++++--- .../messages/GiphyMessageContent.kt | 110 +++++++++++++----- .../compose/ui/theme/ChatComponentFactory.kt | 1 + .../ui/theme/ChatComponentFactoryParams.kt | 3 + 5 files changed, 121 insertions(+), 47 deletions(-) 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 a09d5c3e41f..55b1a696adf 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -525,7 +525,7 @@ public final class io/getstream/chat/android/compose/ui/attachments/content/Giph } public final class io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContentKt { - public static final fun GiphyAttachmentContent (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/utils/GiphyInfoType;Lio/getstream/chat/android/ui/common/utils/GiphySizingMode;Landroidx/compose/ui/layout/ContentScale;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V + public static final fun GiphyAttachmentContent (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/ui/common/utils/GiphyInfoType;Lio/getstream/chat/android/ui/common/utils/GiphySizingMode;Landroidx/compose/ui/layout/ContentScale;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V } public final class io/getstream/chat/android/compose/ui/attachments/content/LinkAttachmentClickData { @@ -3924,13 +3924,15 @@ public final class io/getstream/chat/android/compose/ui/theme/FileAttachmentItem public final class io/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams { public static final field $stable I - public fun (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;)V - public synthetic fun (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Z)V + public synthetic fun (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState; public final fun component2 ()Landroidx/compose/ui/Modifier; - public final fun copy (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;)Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams; - public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams;Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;ILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams; + public final fun component3 ()Z + public final fun copy (Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;Z)Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams; + public static synthetic fun copy$default (Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams;Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState;Landroidx/compose/ui/Modifier;ZILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/GiphyAttachmentContentParams; public fun equals (Ljava/lang/Object;)Z + public final fun getInteractive ()Z public final fun getModifier ()Landroidx/compose/ui/Modifier; public final fun getState ()Lio/getstream/chat/android/compose/state/messages/attachments/AttachmentState; public fun hashCode ()I diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt index 048c9c7064d..13eb2a86abc 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt @@ -83,6 +83,8 @@ import io.getstream.chat.android.ui.common.utils.giphyInfo * the default Giphy width and height dimensions, however you can still clip maximum dimensions. * Setting it to fixed size mode will make it respect all given dimensions. * @param contentScale Used to determine the way Giphys are scaled inside the [Image] composable. + * @param interactive When `true` (default), the container is clickable and long-clickable. When + * `false`, both handlers are disabled. * @param onItemClick Lambda called when an item gets clicked (no-action by default). */ @OptIn(ExperimentalFoundationApi::class) @@ -94,6 +96,7 @@ public fun GiphyAttachmentContent( giphyInfoType: GiphyInfoType = GiphyInfoType.ORIGINAL, giphySizingMode: GiphySizingMode = GiphySizingMode.ADAPTIVE, contentScale: ContentScale = ContentScale.Crop, + interactive: Boolean = true, onItemClick: (GiphyAttachmentClickData) -> Unit = {}, ) { val context = LocalContext.current @@ -115,6 +118,7 @@ public fun GiphyAttachmentContent( val giphyDimensions: DpSize = calculateSize(giphyInfo, giphySizingMode) val shouldBeFullSize = message.shouldBeDisplayedAsFullSizeAttachment() + val interactionSource = remember { MutableInteractionSource() } Box( modifier = modifier .testTag("Stream_GiphyContent") @@ -123,21 +127,29 @@ public fun GiphyAttachmentContent( padding(MessageStyling.messageSectionPadding) .clip(RoundedCornerShape(StreamTokens.radiusLg)) } - .combinedClickable( - indication = ripple(), - interactionSource = remember { MutableInteractionSource() }, - onClick = { - onItemClick( - GiphyAttachmentClickData( - context = context, - url = previewUrl, - attachment = attachment, - message = message, - ), - ) - }, - onLongClick = { state.onLongItemClick(message) }, - ), + // Workaround: `interactive` gates `combinedClickable` so the ephemeral preview path + // can disable the clickable (its inner click and long-click are no-ops there) and let + // the surrounding bubble announce as a single TalkBack focus. The proper fix is to + // make `onItemClick` (and `AttachmentState.onLongItemClick`) nullable and gate on + // `!= null`, but that is a binary-breaking type change on a published API. Revisit in + // v8 and drop `interactive` once the handlers are nullable. + .applyIf(interactive) { + combinedClickable( + indication = ripple(), + interactionSource = interactionSource, + onClick = { + onItemClick( + GiphyAttachmentClickData( + context = context, + url = previewUrl, + attachment = attachment, + message = message, + ), + ) + }, + onLongClick = { state.onLongItemClick(message) }, + ) + }, ) { StreamAsyncImage( data = giphyInfo?.url, diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt index b58590a399c..19c172c8c92 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt @@ -16,7 +16,9 @@ package io.getstream.chat.android.compose.ui.components.messages +import android.view.accessibility.AccessibilityManager import androidx.compose.foundation.background +import androidx.compose.foundation.focusable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -27,13 +29,24 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.core.content.getSystemService import io.getstream.chat.android.compose.R import io.getstream.chat.android.compose.state.messages.attachments.AttachmentState import io.getstream.chat.android.compose.ui.components.button.StreamButtonStyleDefaults @@ -42,6 +55,7 @@ import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.ui.theme.GiphyAttachmentContentParams import io.getstream.chat.android.compose.ui.theme.MessageStyling import io.getstream.chat.android.compose.ui.theme.StreamTokens +import io.getstream.chat.android.compose.ui.util.applyIf import io.getstream.chat.android.models.Attachment import io.getstream.chat.android.models.AttachmentType import io.getstream.chat.android.models.Message @@ -50,6 +64,7 @@ import io.getstream.chat.android.ui.common.state.messages.list.CancelGiphy import io.getstream.chat.android.ui.common.state.messages.list.GiphyAction import io.getstream.chat.android.ui.common.state.messages.list.SendGiphy import io.getstream.chat.android.ui.common.state.messages.list.ShuffleGiphy +import kotlinx.coroutines.delay /** * Represents the content of an ephemeral giphy message. @@ -69,43 +84,62 @@ public fun GiphyMessageContent( ) { val colors = ChatTheme.colors + val isTouchExplorationEnabled = rememberIsTouchExplorationEnabled() + val previewFocusRequester = remember { FocusRequester() } + LaunchedEffect(message.id) { + if (!isTouchExplorationEnabled) return@LaunchedEffect + // Let Compose layout + the accessibility tree settle before stealing TalkBack focus, + // otherwise our request loses to the composer's post-command focus reshuffling. + delay(PreviewFocusRequestDelayMs) + previewFocusRequester.requestFocus() + } + Column( modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally, ) { - Row( + Column( modifier = Modifier - .fillMaxWidth() - .height(40.dp) - .padding(horizontal = StreamTokens.spacingSm, vertical = StreamTokens.spacingXs), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingXs), + .applyIf(isTouchExplorationEnabled) { + focusRequester(previewFocusRequester).focusable() + } + .semantics(mergeDescendants = true) {}, ) { - Icon( - painter = painterResource(R.drawable.stream_design_ic_eye_fill), - contentDescription = null, - tint = colors.chatTextOutgoing, + Row( + modifier = Modifier + .fillMaxWidth() + .height(40.dp) + .padding(horizontal = StreamTokens.spacingSm, vertical = StreamTokens.spacingXs), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingXs), + ) { + Icon( + painter = painterResource(R.drawable.stream_design_ic_eye_fill), + contentDescription = null, + tint = colors.chatTextOutgoing, + ) + Text( + text = stringResource(R.string.stream_compose_only_visible_to_you), + style = ChatTheme.typography.captionEmphasis, + color = colors.chatTextOutgoing, + ) + } + + val attachmentState = AttachmentState( + message = message, + isMine = message.user.id == currentUser?.id, + onLongItemClick = {}, + onMediaGalleryPreviewResult = {}, ) - Text( - text = stringResource(R.string.stream_compose_only_visible_to_you), - style = ChatTheme.typography.captionEmphasis, - color = colors.chatTextOutgoing, + ChatTheme.componentFactory.GiphyAttachmentContent( + params = GiphyAttachmentContentParams( + modifier = Modifier.fillMaxWidth(), + state = attachmentState, + interactive = false, + ), ) } - val attachmentState = AttachmentState( - message = message, - isMine = message.user.id == currentUser?.id, - onLongItemClick = {}, - onMediaGalleryPreviewResult = {}, - ) - ChatTheme.componentFactory.GiphyAttachmentContent( - params = GiphyAttachmentContentParams( - modifier = Modifier.fillMaxWidth(), - state = attachmentState, - ), - ) - Row( modifier = Modifier .padding(vertical = StreamTokens.spacingXs) @@ -142,6 +176,28 @@ public fun GiphyMessageContent( } } +private const val PreviewFocusRequestDelayMs = 100L + +/** + * Observes [AccessibilityManager.isTouchExplorationEnabled] and recomposes when it toggles. Used + * to gate focus-stealing behaviour so we only request TalkBack focus when an explore-by-touch + * service (e.g. TalkBack) is active — otherwise we would yank Compose focus away from the + * composer's text field for sighted users and dismiss the IME. + */ +@Composable +private fun rememberIsTouchExplorationEnabled(): Boolean { + val context = LocalContext.current + val manager = remember(context) { context.getSystemService() } ?: return false + var enabled by remember(manager) { mutableStateOf(manager.isTouchExplorationEnabled) } + DisposableEffect(manager) { + val listener = AccessibilityManager.TouchExplorationStateChangeListener { enabled = it } + manager.addTouchExplorationStateChangeListener(listener) + enabled = manager.isTouchExplorationEnabled + onDispose { manager.removeTouchExplorationStateChangeListener(listener) } + } + return enabled +} + @Preview @Composable private fun GiphyMessageContentPreview() { diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt index 837d14ce6ba..05940bfb6dc 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt @@ -2480,6 +2480,7 @@ public interface ChatComponentFactory { io.getstream.chat.android.compose.ui.attachments.content.GiphyAttachmentContent( state = params.state, modifier = params.modifier, + interactive = params.interactive, ) } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt index 0da471b28a3..5cf379f1d74 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt @@ -2247,10 +2247,13 @@ public data class FileAttachmentContentParams( * * @param state State providing context for the attachment. * @param modifier Modifier for styling. + * @param interactive When `true` (default), the Giphy container is clickable and long-clickable. + * When `false`, both handlers are disabled. */ public data class GiphyAttachmentContentParams( val state: AttachmentState, val modifier: Modifier = Modifier, + val interactive: Boolean = true, ) /** From 4ddd44b21fedb52d3f0e29f4da7df5e9056e8573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mion?= Date: Tue, 2 Jun 2026 09:14:53 +0100 Subject: [PATCH 3/4] Announce Giphy preview action state changes to TalkBack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After tapping Send / Shuffle / Cancel on the ephemeral Giphy preview, screen-reader users got no confirmation that their action took effect — focus drifted depending on TalkBack's fallback-recovery race after the bubble unmounted. Wrap each action button's onClick to fire a polite live region announce before forwarding to `onGiphyActionClick`: - `SendGiphy` → "Giphy sent" - `ShuffleGiphy` → "Giphy shuffled" - `CancelGiphy` → "Giphy preview cancelled" The announce queues before the state change, so users hear the confirmation regardless of where TalkBack focus lands afterward. New strings translated across the 7 supported locales. --- .../messages/GiphyMessageContent.kt | 20 ++++++++++++++++--- .../src/main/res/values-es/strings.xml | 3 +++ .../src/main/res/values-fr/strings.xml | 3 +++ .../src/main/res/values-hi/strings.xml | 3 +++ .../src/main/res/values-in/strings.xml | 3 +++ .../src/main/res/values-it/strings.xml | 3 +++ .../src/main/res/values-ja/strings.xml | 3 +++ .../src/main/res/values-ko/strings.xml | 3 +++ .../src/main/res/values/strings.xml | 3 +++ 9 files changed, 41 insertions(+), 3 deletions(-) diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt index 19c172c8c92..e0af9940e07 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -83,6 +84,10 @@ public fun GiphyMessageContent( onGiphyActionClick: (GiphyAction) -> Unit = {}, ) { val colors = ChatTheme.colors + val view = LocalView.current + val sentAnnouncement = stringResource(R.string.stream_compose_message_list_giphy_sent) + val cancelledAnnouncement = stringResource(R.string.stream_compose_message_list_giphy_cancelled) + val shuffledAnnouncement = stringResource(R.string.stream_compose_message_list_giphy_shuffled) val isTouchExplorationEnabled = rememberIsTouchExplorationEnabled() val previewFocusRequester = remember { FocusRequester() } @@ -147,7 +152,10 @@ public fun GiphyMessageContent( horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingXs), ) { StreamTextButton( - onClick = { onGiphyActionClick(SendGiphy(message)) }, + onClick = { + view.announceForAccessibility(sentAnnouncement) + onGiphyActionClick(SendGiphy(message)) + }, text = stringResource(R.string.stream_compose_message_list_giphy_send), style = StreamButtonStyleDefaults.primaryGhost, modifier = Modifier @@ -156,7 +164,10 @@ public fun GiphyMessageContent( ) StreamTextButton( - onClick = { onGiphyActionClick(ShuffleGiphy(message)) }, + onClick = { + view.announceForAccessibility(shuffledAnnouncement) + onGiphyActionClick(ShuffleGiphy(message)) + }, text = stringResource(R.string.stream_compose_message_list_giphy_shuffle), style = StreamButtonStyleDefaults.secondaryGhost, modifier = Modifier @@ -165,7 +176,10 @@ public fun GiphyMessageContent( ) StreamTextButton( - onClick = { onGiphyActionClick(CancelGiphy(message)) }, + onClick = { + view.announceForAccessibility(cancelledAnnouncement) + onGiphyActionClick(CancelGiphy(message)) + }, text = stringResource(R.string.stream_compose_message_list_giphy_cancel), style = StreamButtonStyleDefaults.secondaryGhost, modifier = Modifier diff --git a/stream-chat-android-compose/src/main/res/values-es/strings.xml b/stream-chat-android-compose/src/main/res/values-es/strings.xml index 0e328588b14..5ac1ee0726b 100644 --- a/stream-chat-android-compose/src/main/res/values-es/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-es/strings.xml @@ -144,8 +144,11 @@ "No hay ninguna aplicación para ver esta URL:\n%s" "Editado" "Cancelar" + "Vista previa de Giphy cancelada" "Enviar" + "Giphy enviado" "Aleatorio" + "Giphy intercambiado" "Recordarme" "Guardado para después" "Mostrar traducción" diff --git a/stream-chat-android-compose/src/main/res/values-fr/strings.xml b/stream-chat-android-compose/src/main/res/values-fr/strings.xml index 7f2816a1484..bb029bfea4d 100644 --- a/stream-chat-android-compose/src/main/res/values-fr/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-fr/strings.xml @@ -144,8 +144,11 @@ "Aucune application pour ouvrir cette URL :\n%s" "Modifié" "Annuler" + "Aperçu Giphy annulé" "Envoyer" + "Giphy envoyé" "Mélanger" + "Giphy mélangé" "Me rappeler" "Enregistré pour plus tard" "Afficher la traduction" diff --git a/stream-chat-android-compose/src/main/res/values-hi/strings.xml b/stream-chat-android-compose/src/main/res/values-hi/strings.xml index 7895f79f6ba..0581b835a00 100644 --- a/stream-chat-android-compose/src/main/res/values-hi/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-hi/strings.xml @@ -204,8 +204,11 @@ "इस url को देखने के लिए कोई ऐप नहीं है:\n%s" "संपादित" "रद्द करें" + "Giphy पूर्वावलोकन रद्द किया गया" "भेजें" + "Giphy भेजा गया" "बदलें" + "Giphy बदला गया" "मुझे याद दिलाएँ" "बाद के लिए सेव किया गया" "अनुवाद दिखाएँ" diff --git a/stream-chat-android-compose/src/main/res/values-in/strings.xml b/stream-chat-android-compose/src/main/res/values-in/strings.xml index 4a95f6f35a5..10b0507578c 100644 --- a/stream-chat-android-compose/src/main/res/values-in/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-in/strings.xml @@ -144,8 +144,11 @@ "Tidak ada aplikasi untuk membuka URL ini:\n%s" "Diedit" "Batal" + "Pratinjau Giphy dibatalkan" "Kirim" + "Giphy terkirim" "Acak" + "Giphy diacak" "Ingatkan saya" "Disimpan untuk nanti" "Tampilkan terjemahan" diff --git a/stream-chat-android-compose/src/main/res/values-it/strings.xml b/stream-chat-android-compose/src/main/res/values-it/strings.xml index f1c60dd3d8d..b6536cd1276 100644 --- a/stream-chat-android-compose/src/main/res/values-it/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-it/strings.xml @@ -204,8 +204,11 @@ "Nessuna app per aprire questo url:\n%s" "Modificato" "Annulla" + "Anteprima Giphy annullata" "Invia" + "Giphy inviato" "Casuale" + "Giphy cambiato" "Ricordami" "Salvato per dopo" "Mostra traduzione" diff --git a/stream-chat-android-compose/src/main/res/values-ja/strings.xml b/stream-chat-android-compose/src/main/res/values-ja/strings.xml index 553a50bcb49..237dc56e5a5 100644 --- a/stream-chat-android-compose/src/main/res/values-ja/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-ja/strings.xml @@ -156,8 +156,11 @@ "このURLを開くアプリがありません:\n%s" "編集済み" "キャンセル" + "Giphyプレビューをキャンセルしました" "送信" + "Giphyを送信しました" "シャッフル" + "Giphyをシャッフルしました" "リマインドする" "後で確認" "翻訳を表示" diff --git a/stream-chat-android-compose/src/main/res/values-ko/strings.xml b/stream-chat-android-compose/src/main/res/values-ko/strings.xml index 8506f63ca69..96733425c46 100644 --- a/stream-chat-android-compose/src/main/res/values-ko/strings.xml +++ b/stream-chat-android-compose/src/main/res/values-ko/strings.xml @@ -156,8 +156,11 @@ "이 URL을 열 수 있는 앱이 없습니다:\n%s" "수정됨" "취소" + "Giphy 미리보기 취소됨" "보내기" + "Giphy 전송됨" "섞기" + "Giphy 섞임" "리마인드" "나중에 보기" "번역 보기" diff --git a/stream-chat-android-compose/src/main/res/values/strings.xml b/stream-chat-android-compose/src/main/res/values/strings.xml index 20d4ebaacf8..bdc08dae3bf 100644 --- a/stream-chat-android-compose/src/main/res/values/strings.xml +++ b/stream-chat-android-compose/src/main/res/values/strings.xml @@ -88,6 +88,9 @@ Send Cancel Shuffle + Giphy sent + Giphy preview cancelled + Giphy shuffled Edited %d reply %d replies From 03801fca537788f9da3a1da7050d65f7f7f756b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mion?= Date: Tue, 2 Jun 2026 13:43:37 +0100 Subject: [PATCH 4/4] Add snapshot coverage for Giphy preview composables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new `GiphyMessageContent`, the `interactive = false` branch in `GiphyAttachmentContent`, and the `attachment.title.takeIf(String::isNotBlank)` null / blank paths had no test exercising them. Parameterize the existing `internal fun GiphyAttachmentContent()` preview helper to accept `interactive` and `title` with backward-compatible defaults, and add a sibling `internal fun GiphyMessageContent()` helper following the same fixture-data pattern. Add three Paparazzi snapshot tests in `AttachmentsContentTest`: - `giphy attachment content non-interactive` covers the `applyIf(interactive)` false branch. - `giphy attachment content blank title` covers the `takeIf(String::isNotBlank)` null path. - `giphy message content` covers `GiphyMessageContent`'s static rendering plus the new factory forwarding in `ChatComponentFactory.GiphyAttachmentContent` and the new `interactive` field in `GiphyAttachmentContentParams`. Runtime-only paths (`LaunchedEffect`, `requestFocus()`, accessibility listener callbacks, button `onClick` lambdas) remain uncovered — they require UI tests beyond snapshot scope. --- .../api/stream-chat-android-compose.api | 8 ++++- .../content/GiphyAttachmentContent.kt | 7 ++++- .../messages/GiphyMessageContent.kt | 28 +++++++++++++++--- .../content/AttachmentsContentTest.kt | 22 ++++++++++++++ ...t_giphy_attachment_content_blank_title.png | Bin 0 -> 10960 bytes ...phy_attachment_content_non-interactive.png | Bin 0 -> 10960 bytes ...mentsContentTest_giphy_message_content.png | Bin 0 -> 44834 bytes 7 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_blank_title.png create mode 100644 stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_non-interactive.png create mode 100644 stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_message_content.png 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 55b1a696adf..6ece7fc5996 100644 --- a/stream-chat-android-compose/api/stream-chat-android-compose.api +++ b/stream-chat-android-compose/api/stream-chat-android-compose.api @@ -477,7 +477,6 @@ public final class io/getstream/chat/android/compose/ui/attachments/content/Comp public static final field INSTANCE Lio/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$GiphyAttachmentContentKt; public fun ()V public final fun getLambda$-573709398$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$271803750$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2; } public final class io/getstream/chat/android/compose/ui/attachments/content/ComposableSingletons$LinkAttachmentContentKt { @@ -1510,6 +1509,13 @@ public final class io/getstream/chat/android/compose/ui/components/messageoption public static final fun defaultMessageOptionsState (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;ZLio/getstream/chat/android/models/Channel;Landroidx/compose/runtime/Composer;I)Ljava/util/List; } +public final class io/getstream/chat/android/compose/ui/components/messages/ComposableSingletons$GiphyMessageContentKt { + public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/messages/ComposableSingletons$GiphyMessageContentKt; + public fun ()V + public final fun getLambda$-2094128661$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-223271185$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2; +} + public final class io/getstream/chat/android/compose/ui/components/messages/ComposableSingletons$MessageAnnotationKt { public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/messages/ComposableSingletons$MessageAnnotationKt; public fun ()V diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt index 13eb2a86abc..80c334180ac 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/GiphyAttachmentContent.kt @@ -300,7 +300,10 @@ private fun GiphyAttachmentContentPreview() { } @Composable -internal fun GiphyAttachmentContent() { +internal fun GiphyAttachmentContent( + interactive: Boolean = true, + title: String? = "Funny cat", +) { val previewHandler = AsyncImagePreviewHandler { ColorImage(color = Color.Red.toArgb(), width = 200, height = 150) } @@ -313,10 +316,12 @@ internal fun GiphyAttachmentContent() { Attachment( titleLink = "https://giphy.com/gifs/funny-cat-3oEjI6SIIHBdRxXI40", type = AttachmentType.GIPHY, + title = title, ), ), ), ), + interactive = interactive, ) } } diff --git a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt index e0af9940e07..94260a7a5c0 100644 --- a/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt +++ b/stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/GiphyMessageContent.kt @@ -29,6 +29,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -39,6 +40,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.testTag @@ -48,6 +51,8 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.content.getSystemService +import coil3.ColorImage +import coil3.compose.LocalAsyncImagePreviewHandler import io.getstream.chat.android.compose.R import io.getstream.chat.android.compose.state.messages.attachments.AttachmentState import io.getstream.chat.android.compose.ui.components.button.StreamButtonStyleDefaults @@ -56,6 +61,7 @@ import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.compose.ui.theme.GiphyAttachmentContentParams import io.getstream.chat.android.compose.ui.theme.MessageStyling import io.getstream.chat.android.compose.ui.theme.StreamTokens +import io.getstream.chat.android.compose.ui.util.AsyncImagePreviewHandler import io.getstream.chat.android.compose.ui.util.applyIf import io.getstream.chat.android.models.Attachment import io.getstream.chat.android.models.AttachmentType @@ -212,11 +218,17 @@ private fun rememberIsTouchExplorationEnabled(): Boolean { return enabled } -@Preview @Composable -private fun GiphyMessageContentPreview() { - val attachment = Attachment(type = AttachmentType.GIPHY, ogUrl = "") - ChatTheme { +internal fun GiphyMessageContent() { + val previewHandler = AsyncImagePreviewHandler { + ColorImage(color = Color.Red.toArgb(), width = 200, height = 150) + } + CompositionLocalProvider(LocalAsyncImagePreviewHandler provides previewHandler) { + val attachment = Attachment( + type = AttachmentType.GIPHY, + titleLink = "https://giphy.com/gifs/funny-cat-3oEjI6SIIHBdRxXI40", + title = "Hello", + ) Box(Modifier.background(MessageStyling.backgroundColor(true))) { GiphyMessageContent( message = Message(attachments = listOf(attachment)), @@ -226,3 +238,11 @@ private fun GiphyMessageContentPreview() { } } } + +@Preview +@Composable +private fun GiphyMessageContentPreview() { + ChatTheme { + GiphyMessageContent() + } +} diff --git a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt index 70c122903e5..fc229d003ba 100644 --- a/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt +++ b/stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt @@ -21,6 +21,7 @@ import app.cash.paparazzi.DeviceConfig import app.cash.paparazzi.Paparazzi import com.android.ide.common.rendering.api.SessionParams import io.getstream.chat.android.compose.ui.PaparazziComposeTest +import io.getstream.chat.android.compose.ui.components.messages.GiphyMessageContent import org.junit.Rule import org.junit.Test @@ -70,6 +71,27 @@ internal class AttachmentsContentTest : PaparazziComposeTest { } } + @Test + fun `giphy attachment content non-interactive`() { + snapshotWithDarkModeRow { + GiphyAttachmentContent(interactive = false) + } + } + + @Test + fun `giphy attachment content blank title`() { + snapshotWithDarkModeRow { + GiphyAttachmentContent(title = "") + } + } + + @Test + fun `giphy message content`() { + snapshotWithDarkModeRow { + GiphyMessageContent() + } + } + @Test fun `single media attachment content`() { snapshotWithDarkModeRow { diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_blank_title.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_blank_title.png new file mode 100644 index 0000000000000000000000000000000000000000..15f0cfb302842d9372552e3a1926a2a8a8ad8449 GIT binary patch literal 10960 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 z zaSgxzN&i$z!d#@0GE>bdf2R;JUl&BL8q7+1lI@mm=^S7vPkg5 zI7%Q?d$>KdSA!2ReA;Qq+Ud+*+humnRYuH@1y6yiigY7x0^i?*zHlvWcUw~uek#kp z3r1LX=ejkUYM~c|yq{%8qw^T9lhU2fj0vTG9!8OId7~VB zY0DyYj^P`_BEpQx1udUuH*R!TlUDD-;?i>C>xN`ey!u&dQo~i#i9ein;Zd2#fZYx~ zdy`}tC?fu9YL&_>T1B-96MT^ZF8%G#+c^VDObq1@mgbsm@7?&8@4qB?5u(VnxZOQC zD#E&XN=8R!+EhN0xVVeApo;8c3ram7M&~9`?}(xVKmmHX|II7XDs$?5hW0!sjPT$+|=3L}(vQq9uyV1vcw%a)|%1p{Z zbi*IE1FGq)VgB;_?v|h&Db9BQHr6k^R=+bEQWgieQ%X{wz;SE~2X@ZoTFpfQ;q~{u zT9AiE6QiBh5#|Bsa zN?p(A_JdvFwx_qNP&TZEr)!peDNG&&fNC{Wc8P{s%~>oO&En-x^X>{J@4NQMKh-Bw z2EGD&Yn*501_CY_+v-zKn>=RKrg3f+z4r+rVaF3I{CG%FBRq)HX6j$9W@1J5)KevS zNSeNrxrm%^+<50Y)v1ZSc7s4pww;6&9Q`i5k@@Jj|69j^5&>TcB_)dbXmRapcZvS8 z5q-eCZt@xLSiePA(U`&$LdP#HVN_An%n#sEDu>euPPEmjbx_8?wuyW%;B}wrR^BDA z3J-)|WF&#F&pZj}m`v+7o(U*O5X7L??_0%kYI<|&nd8ls3s#{w%&jj;zXIwF2~ zh>|t$0|YsbjvH0RDiJ>C7g0NZfYl$}+Vb~!{o;nXFVR<*pPkcyZJ|%20kt)5V)&7Y zVV}I6xctP>(Q*_QZd@6sAN;FKK%@x-Pe%=!G!({fKV%jDh;_~^3oSX}=NZo*%$?bcK@^NT8~DC$1y2N(JlZtl$n*7a;+9y3am$&~^c~wYT2z>Bmj3qkap!|LB1iitgai8dM z7yACATDwc?=#)~!wsT=slUq@ORXPx85A9p5S#bzI`*fHHBq7HCnS_wv#yRBVWp;QZ z{JYr6g54#(6|Tw|km97e+ag#YDnPW#o?_ahogXN%8JkP~BQ~E`W&#nae>@tsbpsUuKJ#odX_nD}jgH*>a#fp%2J$Bu>-3;M4hoO3W0^s@M;D z2V|BTvR$`pdIw_w1)f<{oVM1CGcs)i-l!j??azf!H!~~O25xKFq$_#0CE;UPzM2n@ ztl5`zzdqTLd!%74|4PZ08(Gk->diOlOM9w6J>Sf>SVxJ=+-aPC06a?1XWN?1V6rpu z!cw;;>(rkI#sO+qHzogRjHY0E zJ+LFR$~^){Y8o6xy0h$i7wvjHllkz{>vdzI+4`NO7n1#k%xmzdB~0$A?8SqG!|ve? z$9kp3p6y@UQ(NQKpJd7K2({O~vYEQ*bHv_*d(Xi zF7)SYo+fg)EwsUCZ|F(YG4AsUq=v)+h?d_A{-LJBaDCvgi@24RP(Jb*^E;VC5J=Nn z#-<5;jy#q8lFK7eG{_Pf4es0v1MvqeCnl$tCN0<|2Zs(|4$8YM>)Ka3hC43k`OV=k z6@D8G6>+NtD@E9ezdMN|u+DV=H5?X*yv>6sMIULLub17W>4CR2Z!^n*99|=0|E}zm{t5166y^TX9ni3_9_kr%C&i8dufg+E$CARUiKC(q?e}`=a zd0}tCji(j7w34tDxehNxL~wIWG=q7=C<;&wgjg9#CB=6cizS8)x~m^_xYkfj2?rvb zv;=?Rpoz#nNZ%a#_Q=JkU%S?4WZRIGT+oe(HpH3281Jjb@4azQeikO|EU38&lP#D( z9zii8vmby>{pmR{dr)&jj>qjh!_rH(;Vt5b`b(wF5l!Nt`NO22U=;ZKdL)h!&F*(c z^%{Y$dBVl1*X>&}DKRpfIUk~%(w@ZdgCxAV`Q?F_vjE+Iscf2V2xSYojW!bd^EWET zLd*{U9$hFpFFtT;3pryFOv0aOcEK^U-m6Bt0mWbS`k-;m0rp&hamB0{!gwDSMm#eG zVy?5wTXYqMPZ-pi<5c`8tkagpBE6lWYs)uXj8zvw1fN*9D!Yu(W+(b*Zk-8F5RU zJ>|0>20tcIKU>U5Xv%0BSSWy=U4SQB+*i)i9=9{7bKTPR5&5P&Bkf}BI8b+Dp$U5C z2v4pcBy_AT$qLs!OELxl*~4xH@@Q{pQfNmBT$dn3V58q&uNCB7YA%lOTWph$eCsGH zp|ZPr?7HBAv^9)B2qsm6+r#lq$KIMnMu*^_ZCNLzPNHfww}ISsNza!$=M>%gYFuKa zIjuo`sd4li;olL21gsXwtpQvHMB2w%SlfGR%doKg%EMAEyd5JYg96HBM&<9HWK0!XMX}uhB!&iR1T%b}FWOv5tbmhs*fBQeP CL}o$& literal 0 HcmV?d00001 diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_non-interactive.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_attachment_content_non-interactive.png new file mode 100644 index 0000000000000000000000000000000000000000..15f0cfb302842d9372552e3a1926a2a8a8ad8449 GIT binary patch literal 10960 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 z zaSgxzN&i$z!d#@0GE>bdf2R;JUl&BL8q7+1lI@mm=^S7vPkg5 zI7%Q?d$>KdSA!2ReA;Qq+Ud+*+humnRYuH@1y6yiigY7x0^i?*zHlvWcUw~uek#kp z3r1LX=ejkUYM~c|yq{%8qw^T9lhU2fj0vTG9!8OId7~VB zY0DyYj^P`_BEpQx1udUuH*R!TlUDD-;?i>C>xN`ey!u&dQo~i#i9ein;Zd2#fZYx~ zdy`}tC?fu9YL&_>T1B-96MT^ZF8%G#+c^VDObq1@mgbsm@7?&8@4qB?5u(VnxZOQC zD#E&XN=8R!+EhN0xVVeApo;8c3ram7M&~9`?}(xVKmmHX|II7XDs$?5hW0!sjPT$+|=3L}(vQq9uyV1vcw%a)|%1p{Z zbi*IE1FGq)VgB;_?v|h&Db9BQHr6k^R=+bEQWgieQ%X{wz;SE~2X@ZoTFpfQ;q~{u zT9AiE6QiBh5#|Bsa zN?p(A_JdvFwx_qNP&TZEr)!peDNG&&fNC{Wc8P{s%~>oO&En-x^X>{J@4NQMKh-Bw z2EGD&Yn*501_CY_+v-zKn>=RKrg3f+z4r+rVaF3I{CG%FBRq)HX6j$9W@1J5)KevS zNSeNrxrm%^+<50Y)v1ZSc7s4pww;6&9Q`i5k@@Jj|69j^5&>TcB_)dbXmRapcZvS8 z5q-eCZt@xLSiePA(U`&$LdP#HVN_An%n#sEDu>euPPEmjbx_8?wuyW%;B}wrR^BDA z3J-)|WF&#F&pZj}m`v+7o(U*O5X7L??_0%kYI<|&nd8ls3s#{w%&jj;zXIwF2~ zh>|t$0|YsbjvH0RDiJ>C7g0NZfYl$}+Vb~!{o;nXFVR<*pPkcyZJ|%20kt)5V)&7Y zVV}I6xctP>(Q*_QZd@6sAN;FKK%@x-Pe%=!G!({fKV%jDh;_~^3oSX}=NZo*%$?bcK@^NT8~DC$1y2N(JlZtl$n*7a;+9y3am$&~^c~wYT2z>Bmj3qkap!|LB1iitgai8dM z7yACATDwc?=#)~!wsT=slUq@ORXPx85A9p5S#bzI`*fHHBq7HCnS_wv#yRBVWp;QZ z{JYr6g54#(6|Tw|km97e+ag#YDnPW#o?_ahogXN%8JkP~BQ~E`W&#nae>@tsbpsUuKJ#odX_nD}jgH*>a#fp%2J$Bu>-3;M4hoO3W0^s@M;D z2V|BTvR$`pdIw_w1)f<{oVM1CGcs)i-l!j??azf!H!~~O25xKFq$_#0CE;UPzM2n@ ztl5`zzdqTLd!%74|4PZ08(Gk->diOlOM9w6J>Sf>SVxJ=+-aPC06a?1XWN?1V6rpu z!cw;;>(rkI#sO+qHzogRjHY0E zJ+LFR$~^){Y8o6xy0h$i7wvjHllkz{>vdzI+4`NO7n1#k%xmzdB~0$A?8SqG!|ve? z$9kp3p6y@UQ(NQKpJd7K2({O~vYEQ*bHv_*d(Xi zF7)SYo+fg)EwsUCZ|F(YG4AsUq=v)+h?d_A{-LJBaDCvgi@24RP(Jb*^E;VC5J=Nn z#-<5;jy#q8lFK7eG{_Pf4es0v1MvqeCnl$tCN0<|2Zs(|4$8YM>)Ka3hC43k`OV=k z6@D8G6>+NtD@E9ezdMN|u+DV=H5?X*yv>6sMIULLub17W>4CR2Z!^n*99|=0|E}zm{t5166y^TX9ni3_9_kr%C&i8dufg+E$CARUiKC(q?e}`=a zd0}tCji(j7w34tDxehNxL~wIWG=q7=C<;&wgjg9#CB=6cizS8)x~m^_xYkfj2?rvb zv;=?Rpoz#nNZ%a#_Q=JkU%S?4WZRIGT+oe(HpH3281Jjb@4azQeikO|EU38&lP#D( z9zii8vmby>{pmR{dr)&jj>qjh!_rH(;Vt5b`b(wF5l!Nt`NO22U=;ZKdL)h!&F*(c z^%{Y$dBVl1*X>&}DKRpfIUk~%(w@ZdgCxAV`Q?F_vjE+Iscf2V2xSYojW!bd^EWET zLd*{U9$hFpFFtT;3pryFOv0aOcEK^U-m6Bt0mWbS`k-;m0rp&hamB0{!gwDSMm#eG zVy?5wTXYqMPZ-pi<5c`8tkagpBE6lWYs)uXj8zvw1fN*9D!Yu(W+(b*Zk-8F5RU zJ>|0>20tcIKU>U5Xv%0BSSWy=U4SQB+*i)i9=9{7bKTPR5&5P&Bkf}BI8b+Dp$U5C z2v4pcBy_AT$qLs!OELxl*~4xH@@Q{pQfNmBT$dn3V58q&uNCB7YA%lOTWph$eCsGH zp|ZPr?7HBAv^9)B2qsm6+r#lq$KIMnMu*^_ZCNLzPNHfww}ISsNza!$=M>%gYFuKa zIjuo`sd4li;olL21gsXwtpQvHMB2w%SlfGR%doKg%EMAEyd5JYg96HBM&<9HWK0!XMX}uhB!&iR1T%b}FWOv5tbmhs*fBQeP CL}o$& literal 0 HcmV?d00001 diff --git a/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_message_content.png b/stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_giphy_message_content.png new file mode 100644 index 0000000000000000000000000000000000000000..32d75ffb6c3ba3fb1795d128d8724fb897b298df GIT binary patch literal 44834 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 literal 0 HcmV?d00001