Skip to content

Commit

Permalink
fix: big padding around reaction pills #WPB-12094 #WPB-14269 (#3643)
Browse files Browse the repository at this point in the history
  • Loading branch information
damian-kaczmarek authored Nov 28, 2024
1 parent 48ed55e commit 8a60716
Show file tree
Hide file tree
Showing 6 changed files with 495 additions and 422 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -45,6 +45,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand Down Expand Up @@ -80,7 +81,7 @@ fun ReactionOption(
) {
listOf("❤️", "👍", "😁", "🙂", "☹️", "👎").forEach { emoji ->
CompositionLocalProvider(
LocalMinimumInteractiveComponentEnforcement provides false
LocalMinimumInteractiveComponentSize provides Dp.Unspecified,
) {
Button(
onClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,21 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.ui.PreviewMultipleThemes

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand Down Expand Up @@ -69,7 +71,7 @@ fun ReactionPill(
}

CompositionLocalProvider(
LocalMinimumInteractiveComponentEnforcement provides false
LocalMinimumInteractiveComponentSize provides Dp.Unspecified
) {
OutlinedButton(
onClick = onTap,
Expand All @@ -93,6 +95,17 @@ fun ReactionPill(
}
}

@PreviewMultipleThemes
@Composable
fun ReactionPillPreview() {
ReactionPill(
emoji = "👍",
count = 5,
isOwn = false,
onTap = {}
)
}

private val minDimension = 1.dp
private val borderRadius = 12.dp
private val borderStrokeWidth = 1.dp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
package com.wire.android.ui.home.conversations.messages.item

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.wire.android.R
import com.wire.android.media.audiomessage.AudioState
import com.wire.android.model.Clickable
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.spacers.HorizontalSpace
import com.wire.android.ui.common.spacers.VerticalSpace
import com.wire.android.ui.home.conversations.info.ConversationDetailsData
import com.wire.android.ui.home.conversations.messages.QuotedMessage
import com.wire.android.ui.home.conversations.messages.QuotedMessageStyle
import com.wire.android.ui.home.conversations.messages.QuotedUnavailable
import com.wire.android.ui.home.conversations.model.DeliveryStatusContent
import com.wire.android.ui.home.conversations.model.MessageBody
import com.wire.android.ui.home.conversations.model.MessageImage
import com.wire.android.ui.home.conversations.model.MessageSource
import com.wire.android.ui.home.conversations.model.UIMessage
import com.wire.android.ui.home.conversations.model.UIMessageContent
import com.wire.android.ui.home.conversations.model.UIQuotedMessage
import com.wire.android.ui.home.conversations.model.messagetypes.asset.MessageAsset
import com.wire.android.ui.home.conversations.model.messagetypes.asset.RestrictedAssetMessage
import com.wire.android.ui.home.conversations.model.messagetypes.asset.RestrictedGenericFileMessage
import com.wire.android.ui.home.conversations.model.messagetypes.audio.AudioMessage
import com.wire.android.ui.home.conversations.model.messagetypes.image.ImageMessageParams
import com.wire.android.ui.home.conversations.model.messagetypes.location.LocationMessageContent
import com.wire.android.util.launchGeoIntent
import com.wire.kalium.logic.data.asset.AssetTransferStatus

@Composable
internal fun UIMessage.Regular.MessageContentAndStatus(
message: UIMessage.Regular,
assetStatus: AssetTransferStatus?,
searchQuery: String,
audioState: AudioState?,
onAssetClicked: (String) -> Unit,
onImageClicked: (UIMessage.Regular, Boolean) -> Unit,
onAudioClicked: (String) -> Unit,
onAudioPositionChanged: (String, Int) -> Unit,
onProfileClicked: (String) -> Unit,
onLinkClicked: (String) -> Unit,
onReplyClicked: (UIMessage.Regular) -> Unit,
shouldDisplayMessageStatus: Boolean,
conversationDetailsData: ConversationDetailsData,
) {
val onAssetClickable = remember(message) {
Clickable(enabled = isAvailable, onClick = {
onAssetClicked(header.messageId)
})
}
val onImageClickable = remember(message) {
Clickable(enabled = isAvailable, onClick = {
onImageClicked(message, source == MessageSource.Self)
})
}
val onReplyClickable = remember(message) {
Clickable {
onReplyClicked(message)
}
}
Row {
Box(modifier = Modifier.weight(1F)) {
MessageContent(
message = message,
messageContent = messageContent,
searchQuery = searchQuery,
audioState = audioState,
assetStatus = assetStatus,
onAudioClick = onAudioClicked,
onChangeAudioPosition = onAudioPositionChanged,
onAssetClick = onAssetClickable,
onImageClick = onImageClickable,
onOpenProfile = onProfileClicked,
onLinkClick = onLinkClicked,
onReplyClick = onReplyClickable,
)
}
if (isMyMessage && shouldDisplayMessageStatus) {
MessageStatusIndicator(
status = message.header.messageStatus.flowStatus,
isGroupConversation = conversationDetailsData is ConversationDetailsData.Group,
modifier = Modifier.padding(
top = if (message.isTextContentWithoutQuote) dimensions().spacing2x else dimensions().spacing4x,
start = dimensions().spacing8x
)
)
} else {
HorizontalSpace.x24()
}
}
}

@Suppress("ComplexMethod")
@Composable
private fun MessageContent(
message: UIMessage.Regular,
messageContent: UIMessageContent.Regular?,
searchQuery: String,
audioState: AudioState?,
assetStatus: AssetTransferStatus?,
onAssetClick: Clickable,
onImageClick: Clickable,
onAudioClick: (String) -> Unit,
onChangeAudioPosition: (String, Int) -> Unit,
onOpenProfile: (String) -> Unit,
onLinkClick: (String) -> Unit,
onReplyClick: Clickable,
) {
when (messageContent) {
is UIMessageContent.ImageMessage -> {
Column {
MessageImage(
asset = messageContent.asset,
imgParams = ImageMessageParams(messageContent.width, messageContent.height),
transferStatus = assetStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
onImageClick = onImageClick
)
PartialDeliveryInformation(messageContent.deliveryStatus)
}
}

is UIMessageContent.TextMessage -> {
Column {
messageContent.messageBody.quotedMessage?.let {
VerticalSpace.x4()
when (it) {
is UIQuotedMessage.UIQuotedData -> QuotedMessage(
messageData = it,
clickable = onReplyClick
)

UIQuotedMessage.UnavailableData -> QuotedUnavailable(style = QuotedMessageStyle.COMPLETE)
}
VerticalSpace.x4()
}
MessageBody(
messageBody = messageContent.messageBody,
searchQuery = searchQuery,
isAvailable = !message.isPending && message.isAvailable,
onOpenProfile = onOpenProfile,
buttonList = null,
messageId = message.header.messageId,
onLinkClick = onLinkClick,
)
PartialDeliveryInformation(messageContent.deliveryStatus)
}
}

is UIMessageContent.Composite -> {
Column {
messageContent.messageBody?.quotedMessage?.let {
VerticalSpace.x4()
when (it) {
is UIQuotedMessage.UIQuotedData -> QuotedMessage(
messageData = it,
clickable = onReplyClick
)

UIQuotedMessage.UnavailableData -> QuotedUnavailable(style = QuotedMessageStyle.COMPLETE)
}
VerticalSpace.x4()
}
MessageBody(
messageBody = messageContent.messageBody,
isAvailable = !message.isPending && message.isAvailable,
onOpenProfile = onOpenProfile,
buttonList = messageContent.buttonList,
messageId = message.header.messageId,
onLinkClick = onLinkClick
)
}
}

is UIMessageContent.AssetMessage -> {
Column {
MessageAsset(
assetName = messageContent.assetName,
assetExtension = messageContent.assetExtension,
assetSizeInBytes = messageContent.assetSizeInBytes,
assetTransferStatus = assetStatus ?: AssetTransferStatus.NOT_DOWNLOADED,
onAssetClick = onAssetClick
)
PartialDeliveryInformation(messageContent.deliveryStatus)
}
}

is UIMessageContent.RestrictedAsset -> {
Column {
when {
messageContent.mimeType.contains("image/") -> {
RestrictedAssetMessage(
R.drawable.ic_gallery,
stringResource(id = R.string.prohibited_images_message)
)
}

messageContent.mimeType.contains("video/") -> {
RestrictedAssetMessage(R.drawable.ic_video, stringResource(id = R.string.prohibited_videos_message))
}

messageContent.mimeType.contains("audio/") -> {
RestrictedAssetMessage(
R.drawable.ic_speaker_on,
stringResource(id = R.string.prohibited_audio_message)
)
}

else -> {
RestrictedGenericFileMessage(messageContent.assetName, messageContent.assetSizeInBytes)
}
}
PartialDeliveryInformation(messageContent.deliveryStatus)
}
}

is UIMessageContent.AudioAssetMessage -> {
Column {
val audioMessageState: AudioState = audioState ?: AudioState.DEFAULT

val totalTimeInMs = remember(audioMessageState.totalTimeInMs) {
audioMessageState.sanitizeTotalTime(messageContent.audioMessageDurationInMs.toInt())
}

AudioMessage(
audioMediaPlayingState = audioMessageState.audioMediaPlayingState,
totalTimeInMs = totalTimeInMs,
currentPositionInMs = audioMessageState.currentPositionInMs,
onPlayButtonClick = { onAudioClick(message.header.messageId) },
onSliderPositionChange = { position ->
onChangeAudioPosition(message.header.messageId, position.toInt())
},
)
PartialDeliveryInformation(messageContent.deliveryStatus)
}
}

is UIMessageContent.Location -> with(messageContent) {
val context = LocalContext.current
val locationUrl = stringResource(urlCoordinates, zoom, latitude, longitude)
Column {
LocationMessageContent(
locationName = name,
locationUrl = locationUrl,
onLocationClick = Clickable(
enabled = message.isAvailable,
onClick = { launchGeoIntent(latitude, longitude, name, locationUrl, context) },
)
)
PartialDeliveryInformation(deliveryStatus)
}
}

UIMessageContent.Deleted -> {}
null -> {
throw NullPointerException("messageContent is null")
}
}
}

@Composable
private fun PartialDeliveryInformation(deliveryStatus: DeliveryStatusContent) {
(deliveryStatus as? DeliveryStatusContent.PartialDelivery)?.let { partialDelivery ->
if (partialDelivery.hasFailures) {
VerticalSpace.x4()
MessageSentPartialDeliveryFailures(partialDelivery)
}
}
}
Loading

0 comments on commit 8a60716

Please sign in to comment.