Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -45,6 +46,7 @@ import io.getstream.chat.android.client.utils.attachment.isAudio
import io.getstream.chat.android.client.utils.attachment.isFile
import io.getstream.chat.android.client.utils.attachment.isImage
import io.getstream.chat.android.client.utils.attachment.isVideo
import io.getstream.chat.android.compose.R
import io.getstream.chat.android.compose.state.messages.attachments.AttachmentState
import io.getstream.chat.android.compose.ui.attachments.preview.handler.AttachmentPreviewHandler
import io.getstream.chat.android.compose.ui.components.LoadingIndicator
Expand Down Expand Up @@ -100,6 +102,7 @@ public fun FileAttachmentContent(
)
.testTag("Stream_MultipleFileAttachmentsColumn"),
) {
val openAttachmentLabel = stringResource(R.string.stream_compose_message_attachment_open)
for (attachment in message.attachments) {
if (attachment.isFile() || attachment.isAudio()) {
ChatTheme.componentFactory.FileAttachmentItem(
Expand All @@ -114,6 +117,7 @@ public fun FileAttachmentContent(
.combinedClickable(
indication = ripple(),
interactionSource = remember { MutableInteractionSource() },
onClickLabel = openAttachmentLabel,
onClick = { onItemClick(previewHandlers, attachment) },
onLongClick = { attachmentState.onLongItemClick(message) },
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import androidx.compose.ui.layout.ContentScale
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.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -105,6 +106,7 @@ public fun LinkAttachmentContent(
}

val context = LocalContext.current
val openAttachmentLabel = stringResource(R.string.stream_compose_message_attachment_open)
val textColor = MessageStyling.textColor(outgoing = state.isMine)
val baseModifier = modifier
.padding(MessageStyling.messageSectionPadding)
Expand All @@ -114,6 +116,7 @@ public fun LinkAttachmentContent(
.combinedClickable(
indication = ripple(),
interactionSource = remember { MutableInteractionSource() },
onClickLabel = openAttachmentLabel,
onClick = {
onItemClick(
LinkAttachmentClickData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ internal fun MediaAttachmentContentItem(
attachment.uploadState is Attachment.UploadState.InProgress ||
attachment.uploadState is Attachment.UploadState.Idle

val openAttachmentLabel = stringResource(R.string.stream_compose_message_attachment_open)
Box(
modifier = modifier
.semantics {
Expand All @@ -465,6 +466,7 @@ internal fun MediaAttachmentContentItem(
.combinedClickable(
interactionSource = remember { MutableInteractionSource() },
indication = ripple(),
onClickLabel = openAttachmentLabel,
onClick = {
if (message.syncStatus == SyncStatus.COMPLETED) {
onItemClick(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.style.TextOverflow
import io.getstream.chat.android.client.extensions.getCreatedAtOrNull
import io.getstream.chat.android.client.utils.message.isDeleted
Expand Down Expand Up @@ -91,9 +89,7 @@ public fun MessageFooter(
if (!messageItem.isMine) {
Text(
modifier = Modifier
.clearAndSetSemantics {
testTag = "Stream_MessageAuthorName"
}
.testTag("Stream_MessageAuthorName")
.padding(end = StreamTokens.spacingXs)
.weight(1f, fill = false),
text = message.user.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.getstream.chat.android.compose.R
import io.getstream.chat.android.compose.previewdata.PreviewReactionData
import io.getstream.chat.android.compose.state.messages.MessageReactionItemState
import io.getstream.chat.android.compose.ui.components.reactions.ReactionIconSize
Expand Down Expand Up @@ -67,6 +69,7 @@ public fun ClusteredMessageReactions(
reactions.size,
reactions.size,
)
val openLabel = stringResource(R.string.stream_compose_message_reactions_show)
val colors = ChatTheme.colors
val count = reactions.sumOf(MessageReactionItemState::count)

Expand All @@ -78,7 +81,7 @@ public fun ClusteredMessageReactions(
}
.background(colors.backgroundCoreElevation1, CircleShape)
.border(1.dp, color = colors.borderCoreSubtle, shape = CircleShape)
.ifNotNull(onClick) { clip(CircleShape).clickable(onClick = it) }
.ifNotNull(onClick) { clip(CircleShape).clickable(onClickLabel = openLabel, onClick = it) }
.padding(horizontal = StreamTokens.spacingXs, vertical = StreamTokens.spacing2xs),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacing2xs),
Expand Down Expand Up @@ -175,13 +178,14 @@ private fun ReactionChip(
onClick: (() -> Unit)?,
content: @Composable RowScope.() -> Unit,
) {
val openLabel = stringResource(R.string.stream_compose_message_reactions_show)
val colors = ChatTheme.colors
Row(
modifier = Modifier
.fillMaxHeight()
.background(colors.backgroundCoreElevation1, CircleShape)
.border(1.dp, color = colors.borderCoreSubtle, shape = CircleShape)
.ifNotNull(onClick) { clip(CircleShape).clickable(onClick = it) }
.ifNotNull(onClick) { clip(CircleShape).clickable(onClickLabel = openLabel, onClick = it) }
.padding(horizontal = StreamTokens.spacingXs, vertical = StreamTokens.spacing2xs),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacing2xs),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.getstream.chat.android.compose.ui.theme.ChatTheme
import io.getstream.chat.android.compose.ui.theme.ReactionIconParams
import io.getstream.chat.android.compose.ui.util.ReactionResolver
import io.getstream.chat.android.compose.ui.util.applyIf
import io.getstream.chat.android.compose.ui.util.clickable
import io.getstream.chat.android.compose.ui.util.ifNotNull

/**
Expand Down Expand Up @@ -69,7 +70,11 @@ internal fun ReactionToggle(
background(ChatTheme.colors.backgroundUtilitySelected, CircleShape)
}
.ifNotNull(onCheckedChange) { onChange ->
clip(CircleShape).clickable { onChange(!checked) }
clip(CircleShape).toggleable(
value = checked,
role = Role.Checkbox,
onValueChange = onChange,
)
}
.defaultMinSize(minWidth = containerSize, minHeight = containerSize)
.wrapContentSize(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection
Expand Down Expand Up @@ -177,12 +175,16 @@ public fun MessageContainer(
val canOpenActions = !message.isDeleted() && !message.isUploading()
val onLongItemClick = rememberHapticLongClick(onLongItemClick)

val openThreadLabel = stringResource(R.string.stream_compose_message_item_open_thread)
val messageOptionsLabel = stringResource(R.string.stream_compose_message_item_options)
val clickModifier = Modifier.combinedClickable(
interactionSource = remember(::MutableInteractionSource),
indication = null,
enabled = canOpenThread || canOpenActions,
onClick = { if (canOpenThread) onThreadClick(message) },
onLongClick = { if (canOpenActions) onLongItemClick(message) },
onClickLabel = openThreadLabel.takeIf { canOpenThread },
onLongClickLabel = messageOptionsLabel.takeIf { canOpenActions },
)

val highlightColor = ChatTheme.colors.backgroundCoreHighlight
Expand All @@ -198,7 +200,6 @@ public fun MessageContainer(
)

val messageAlignment = ChatTheme.messageAlignmentProvider.provideMessageAlignment(messageItem)
val description = stringResource(id = R.string.stream_compose_cd_message_item)
val optionsVisibility = ChatTheme.config.messageActions.optionsVisibility
val isSwipeable = remember(message, messageItem.ownCapabilities, optionsVisibility) {
optionsVisibility.canReplyToMessage(message, messageItem.ownCapabilities)
Expand All @@ -223,8 +224,7 @@ public fun MessageContainer(
.fillMaxWidth()
.wrapContentHeight()
.background(color = color)
.then(clickModifier)
.semantics { contentDescription = description },
.then(clickModifier),
horizontalArrangement = if (messageAlignment == MessageAlignment.Start) {
Arrangement.Start
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.style.TextAlign
Expand Down Expand Up @@ -220,6 +224,7 @@ internal fun DefaultMessageDateSeparatorContent(dateSeparator: DateSeparatorItem
modifier = Modifier
.semantics(mergeDescendants = true) {
testTag = "Stream_MessageDateSeparator"
heading()
}
.padding(vertical = StreamTokens.spacingXs)
.fillMaxWidth(),
Expand All @@ -233,13 +238,16 @@ internal fun DefaultMessageDateSeparatorContent(dateSeparator: DateSeparatorItem
*/
@Composable
internal fun DefaultMessageUnreadSeparatorContent(unreadSeparatorItemState: UnreadSeparatorItemState) {
val unreadCount = unreadSeparatorItemState.unreadCount
MessagesStripDivider(
modifier = Modifier.semantics(mergeDescendants = true) {
testTag = "Stream_UnreadMessagesBadge"
heading()
},
text = stringResource(
R.string.stream_compose_message_list_unread_separator,
unreadSeparatorItemState.unreadCount,
text = pluralStringResource(
R.plurals.stream_compose_message_list_unread_separator,
unreadCount,
unreadCount,
),
)
}
Expand Down Expand Up @@ -326,10 +334,15 @@ internal fun DefaultMessageModeratedContent(moderatedMessageItemState: Moderated
*/
@Composable
internal fun DefaultMessageTypingIndicatorContent(state: TypingItemState) {
val typingDescription = typingUsersDescription(state.typingUsers)
Row(
modifier = Modifier
.padding(StreamTokens.spacingXs)
.testTag("Stream_MessageListTypingIndicator"),
.testTag("Stream_MessageListTypingIndicator")
.semantics(mergeDescendants = true) {
contentDescription = typingDescription
liveRegion = LiveRegionMode.Polite
},
horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingXs),
verticalAlignment = Alignment.Bottom,
) {
Expand Down Expand Up @@ -364,6 +377,25 @@ internal fun DefaultMessageTypingIndicatorContent(state: TypingItemState) {
}
}

@Composable
private fun typingUsersDescription(typingUsers: List<User>): String =
when (typingUsers.size) {
1 -> stringResource(
R.string.stream_compose_channel_list_typing_one,
typingUsers.first().name,
)
2 -> stringResource(
R.string.stream_compose_channel_list_typing_two,
typingUsers[0].name,
typingUsers[1].name,
)
else -> pluralStringResource(
R.plurals.stream_compose_channel_list_typing_many,
typingUsers.size,
typingUsers.size,
)
}

private const val MaxTypingUsersAvatars = 3

@Preview(showBackground = true)
Expand Down
10 changes: 8 additions & 2 deletions stream-chat-android-compose/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
<string name="stream_compose_channel_item_muted">"silenciado"</string>
<string name="stream_compose_channel_item_open">"Abrir conversación"</string>
<string name="stream_compose_channel_item_options">"Abrir opciones de conversación"</string>
<string name="stream_compose_cd_message_item">"Elemento de mensaje"</string>
<string name="stream_compose_cd_play_button">"Botón de reproducción"</string>
<string name="stream_compose_channel_list_draft">"Borrador: "</string>
<string name="stream_compose_channel_list_empty_channels">"No hay conversaciones aún"</string>
Expand Down Expand Up @@ -123,6 +122,10 @@
<string name="stream_compose_message_composer_attachments_expanded">"expandido"</string>
<string name="stream_compose_message_deleted">"Mensaje eliminado"</string>
<string name="stream_compose_message_deleted_preview">"Mensaje eliminado"</string>
<string name="stream_compose_message_item_open_thread">"Abrir hilo"</string>
<string name="stream_compose_message_item_options">"Mostrar opciones del mensaje"</string>
<string name="stream_compose_message_attachment_open">"Abrir archivo adjunto"</string>
<string name="stream_compose_message_reactions_show">"Mostrar reacciones"</string>
<string name="stream_compose_message_list_auto_translated">"Traducido"</string>
<string name="stream_compose_message_list_empty_messages">"Sin mensajes"</string>
<string name="stream_compose_message_list_error_cannot_open_link">"No hay ninguna aplicación para ver esta URL:\n%s"</string>
Expand All @@ -135,7 +138,10 @@
<string name="stream_compose_message_list_show_translation">"Mostrar traducción"</string>
<string name="stream_compose_message_list_thread_footnote_thread_replies">"%d respuestas"</string>
<string name="stream_compose_message_list_thread_footnote_thread_reply">"%d respuesta"</string>
<string name="stream_compose_message_list_unread_separator">"%d mensajes no leídos"</string>
<plurals name="stream_compose_message_list_unread_separator">
<item quantity="one">"%d mensaje no leído"</item>
<item quantity="other">"%d mensajes no leídos"</item>
</plurals>
<string name="stream_compose_message_list_unsupported_attachment">"Archivo adjunto no compatible"</string>
<string name="stream_compose_message_list_view">"Ver"</string>
<string name="stream_compose_message_list_view_original">"Ver original"</string>
Expand Down
10 changes: 8 additions & 2 deletions stream-chat-android-compose/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
<string name="stream_compose_channel_item_muted">"en sourdine"</string>
<string name="stream_compose_channel_item_open">"Ouvrir la conversation"</string>
<string name="stream_compose_channel_item_options">"Ouvrir les options de conversation"</string>
<string name="stream_compose_cd_message_item">"Élément de message"</string>
<string name="stream_compose_cd_play_button">"Bouton de lecture"</string>
<string name="stream_compose_channel_list_draft">"Brouillon : "</string>
<string name="stream_compose_channel_list_empty_channels">"Aucune conversation pour le moment"</string>
Expand Down Expand Up @@ -123,6 +122,10 @@
<string name="stream_compose_message_composer_attachments_expanded">"développé"</string>
<string name="stream_compose_message_deleted">"Message supprimé"</string>
<string name="stream_compose_message_deleted_preview">"Message supprimé"</string>
<string name="stream_compose_message_item_open_thread">"Ouvrir le fil"</string>
<string name="stream_compose_message_item_options">"Afficher les options du message"</string>
<string name="stream_compose_message_attachment_open">"Ouvrir la pièce jointe"</string>
<string name="stream_compose_message_reactions_show">"Afficher les réactions"</string>
<string name="stream_compose_message_list_auto_translated">"Traduit"</string>
<string name="stream_compose_message_list_empty_messages">"Aucun message"</string>
<string name="stream_compose_message_list_error_cannot_open_link">"Aucune application pour ouvrir cette URL :\n%s"</string>
Expand All @@ -135,7 +138,10 @@
<string name="stream_compose_message_list_show_translation">"Afficher la traduction"</string>
<string name="stream_compose_message_list_thread_footnote_thread_replies">"%d réponses"</string>
<string name="stream_compose_message_list_thread_footnote_thread_reply">"%d réponse"</string>
<string name="stream_compose_message_list_unread_separator">"%d messages non lus"</string>
<plurals name="stream_compose_message_list_unread_separator">
<item quantity="one">"%d message non lu"</item>
<item quantity="other">"%d messages non lus"</item>
</plurals>
<string name="stream_compose_message_list_unsupported_attachment">"Pièce jointe non prise en charge"</string>
<string name="stream_compose_message_list_view">"Voir"</string>
<string name="stream_compose_message_list_view_original">"Voir l\'original"</string>
Expand Down
Loading
Loading