removing bubble self/other layer

This commit is contained in:
Adam Brown 2022-04-01 20:33:07 +01:00
parent b817929a2b
commit ff248fceb0
1 changed files with 81 additions and 100 deletions

View File

@ -159,18 +159,31 @@ private fun ColumnScope.RoomContent(self: UserId, state: RoomState) {
) { index, item -> ) { index, item ->
val previousEvent = if (index != 0) state.events[index - 1] else null val previousEvent = if (index != 0) state.events[index - 1] else null
val wasPreviousMessageSameSender = previousEvent?.author?.id == item.author.id val wasPreviousMessageSameSender = previousEvent?.author?.id == item.author.id
AlignedBubble(item, self, wasPreviousMessageSameSender) {
when (item) { when (item) {
is Message -> Message(self, item, wasPreviousMessageSameSender) is RoomEvent.Image -> MessageImage(it as BubbleContent<RoomEvent.Image>)
is RoomEvent.Reply -> Reply(self, item, wasPreviousMessageSameSender) is Message -> TextBubbleContent(it as BubbleContent<RoomEvent.Message>)
is RoomEvent.Image -> Image(self, item, wasPreviousMessageSameSender) is RoomEvent.Reply -> ReplyBubbleContent(it as BubbleContent<RoomEvent.Reply>)
}
} }
} }
} }
} }
private data class BubbleContent<T : RoomEvent>(
val shape: RoundedCornerShape,
val background: Color,
val isNotSelf: Boolean,
val message: T
)
@Composable @Composable
private fun LazyItemScope.Image(self: UserId, message: RoomEvent.Image, wasPreviousMessageSameSender: Boolean) { private fun <T : RoomEvent> LazyItemScope.AlignedBubble(
message: T,
self: UserId,
wasPreviousMessageSameSender: Boolean,
content: @Composable (BubbleContent<T>) -> Unit
) {
when (message.author.id == self) { when (message.author.id == self) {
true -> { true -> {
Box(modifier = Modifier.fillParentMaxWidth(), contentAlignment = Alignment.TopEnd) { Box(modifier = Modifier.fillParentMaxWidth(), contentAlignment = Alignment.TopEnd) {
@ -180,7 +193,7 @@ private fun LazyItemScope.Image(self: UserId, message: RoomEvent.Image, wasPrevi
isNotSelf = false, isNotSelf = false,
wasPreviousMessageSameSender = wasPreviousMessageSameSender wasPreviousMessageSameSender = wasPreviousMessageSameSender
) { ) {
MessageImage(selfBackgroundShape, SmallTalkTheme.extendedColors.selfBubble, false, message) content(BubbleContent(selfBackgroundShape, SmallTalkTheme.extendedColors.selfBubble, false, message))
} }
} }
} }
@ -192,7 +205,7 @@ private fun LazyItemScope.Image(self: UserId, message: RoomEvent.Image, wasPrevi
isNotSelf = true, isNotSelf = true,
wasPreviousMessageSameSender = wasPreviousMessageSameSender wasPreviousMessageSameSender = wasPreviousMessageSameSender
) { ) {
MessageImage(othersBackgroundShape, SmallTalkTheme.extendedColors.othersBubble, true, message) content(BubbleContent(othersBackgroundShape, SmallTalkTheme.extendedColors.othersBubble, true, message))
} }
} }
} }
@ -200,13 +213,13 @@ private fun LazyItemScope.Image(self: UserId, message: RoomEvent.Image, wasPrevi
} }
@Composable @Composable
private fun MessageImage(shape: RoundedCornerShape, background: Color, isNotSelf: Boolean, message: RoomEvent.Image) { private fun MessageImage(content: BubbleContent<RoomEvent.Image>) {
Box(modifier = Modifier.padding(start = 6.dp)) { Box(modifier = Modifier.padding(start = 6.dp)) {
Box( Box(
Modifier Modifier
.padding(4.dp) .padding(4.dp)
.clip(shape) .clip(content.shape)
.background(background) .background(content.background)
.height(IntrinsicSize.Max), .height(IntrinsicSize.Max),
) { ) {
Column( Column(
@ -215,22 +228,22 @@ private fun MessageImage(shape: RoundedCornerShape, background: Color, isNotSelf
.width(IntrinsicSize.Max) .width(IntrinsicSize.Max)
.defaultMinSize(minWidth = 50.dp) .defaultMinSize(minWidth = 50.dp)
) { ) {
if (isNotSelf) { if (content.isNotSelf) {
Text( Text(
fontSize = 11.sp, fontSize = 11.sp,
text = message.author.displayName ?: message.author.id.value, text = content.message.author.displayName ?: content.message.author.id.value,
maxLines = 1, maxLines = 1,
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
} }
val width = with(LocalDensity.current) { message.imageMeta.width.toDp() } val width = with(LocalDensity.current) { content.message.imageMeta.width.toDp() }
val height = with(LocalDensity.current) { message.imageMeta.height.toDp() } val height = with(LocalDensity.current) { content.message.imageMeta.height.toDp() }
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
Image( Image(
modifier = Modifier.size(width, height), modifier = Modifier.size(width, height),
painter = rememberImagePainter( painter = rememberImagePainter(
data = message, data = content.message,
builder = { fetcher(DecryptingFetcher()) } builder = { fetcher(DecryptingFetcher()) }
), ),
contentDescription = null, contentDescription = null,
@ -238,15 +251,15 @@ private fun MessageImage(shape: RoundedCornerShape, background: Color, isNotSelf
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
val editedPrefix = if (message.edited) "(edited) " else null val editedPrefix = if (content.message.edited) "(edited) " else null
Text( Text(
fontSize = 9.sp, fontSize = 9.sp,
text = "${editedPrefix ?: ""}${message.time}", text = "${editedPrefix ?: ""}${content.message.time}",
textAlign = TextAlign.End, textAlign = TextAlign.End,
color = MaterialTheme.colors.onPrimary, color = MaterialTheme.colors.onPrimary,
modifier = Modifier.wrapContentSize() modifier = Modifier.wrapContentSize()
) )
SendStatus(message) SendStatus(content.message)
} }
} }
} }
@ -255,67 +268,6 @@ private fun MessageImage(shape: RoundedCornerShape, background: Color, isNotSelf
} }
@Composable
private fun LazyItemScope.Message(self: UserId, message: Message, wasPreviousMessageSameSender: Boolean) {
when (message.author.id == self) {
true -> {
Box(modifier = Modifier.fillParentMaxWidth(), contentAlignment = Alignment.TopEnd) {
Box(modifier = Modifier.fillParentMaxWidth(0.85f), contentAlignment = Alignment.TopEnd) {
Bubble(
message = message,
isNotSelf = false,
wasPreviousMessageSameSender = wasPreviousMessageSameSender
) {
TextBubbleContent(selfBackgroundShape, SmallTalkTheme.extendedColors.selfBubble, false, message)
}
}
}
}
false -> {
Box(modifier = Modifier.fillParentMaxWidth(0.95f), contentAlignment = Alignment.TopStart) {
Bubble(
message = message,
isNotSelf = true,
wasPreviousMessageSameSender = wasPreviousMessageSameSender
) {
TextBubbleContent(othersBackgroundShape, SmallTalkTheme.extendedColors.othersBubble, true, message)
}
}
}
}
}
@Composable
private fun LazyItemScope.Reply(self: UserId, message: RoomEvent.Reply, wasPreviousMessageSameSender: Boolean) {
when (message.message.author.id == self) {
true -> {
Box(modifier = Modifier.fillParentMaxWidth(), contentAlignment = Alignment.TopEnd) {
Box(modifier = Modifier.fillParentMaxWidth(0.85f), contentAlignment = Alignment.TopEnd) {
Bubble(
message = message.message,
isNotSelf = false,
wasPreviousMessageSameSender = wasPreviousMessageSameSender
) {
ReplyBubbleContent(selfBackgroundShape, SmallTalkTheme.extendedColors.selfBubble, false, message)
}
}
}
}
false -> {
Box(modifier = Modifier.fillParentMaxWidth(0.95f), contentAlignment = Alignment.TopStart) {
Bubble(
message = message.message,
isNotSelf = true,
wasPreviousMessageSameSender = wasPreviousMessageSameSender
) {
ReplyBubbleContent(othersBackgroundShape, SmallTalkTheme.extendedColors.othersBubble, true, message)
}
}
}
}
}
private val selfBackgroundShape = RoundedCornerShape(12.dp, 0.dp, 12.dp, 12.dp) private val selfBackgroundShape = RoundedCornerShape(12.dp, 0.dp, 12.dp, 12.dp)
private val othersBackgroundShape = RoundedCornerShape(0.dp, 12.dp, 12.dp, 12.dp) private val othersBackgroundShape = RoundedCornerShape(0.dp, 12.dp, 12.dp, 12.dp)
@ -348,13 +300,13 @@ private fun Bubble(
} }
@Composable @Composable
private fun TextBubbleContent(shape: RoundedCornerShape, background: Color, isNotSelf: Boolean, message: Message) { private fun TextBubbleContent(content: BubbleContent<RoomEvent.Message>) {
Box(modifier = Modifier.padding(start = 6.dp)) { Box(modifier = Modifier.padding(start = 6.dp)) {
Box( Box(
Modifier Modifier
.padding(4.dp) .padding(4.dp)
.clip(shape) .clip(content.shape)
.background(background) .background(content.background)
.height(IntrinsicSize.Max), .height(IntrinsicSize.Max),
) { ) {
Column( Column(
@ -363,16 +315,16 @@ private fun TextBubbleContent(shape: RoundedCornerShape, background: Color, isNo
.width(IntrinsicSize.Max) .width(IntrinsicSize.Max)
.defaultMinSize(minWidth = 50.dp) .defaultMinSize(minWidth = 50.dp)
) { ) {
if (isNotSelf) { if (content.isNotSelf) {
Text( Text(
fontSize = 11.sp, fontSize = 11.sp,
text = message.author.displayName ?: message.author.id.value, text = content.message.author.displayName ?: content.message.author.id.value,
maxLines = 1, maxLines = 1,
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
} }
Text( Text(
text = message.content, text = content.message.content,
color = MaterialTheme.colors.onPrimary, color = MaterialTheme.colors.onPrimary,
fontSize = 15.sp, fontSize = 15.sp,
modifier = Modifier.wrapContentSize(), modifier = Modifier.wrapContentSize(),
@ -381,15 +333,15 @@ private fun TextBubbleContent(shape: RoundedCornerShape, background: Color, isNo
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))
Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
val editedPrefix = if (message.edited) "(edited) " else null val editedPrefix = if (content.message.edited) "(edited) " else null
Text( Text(
fontSize = 9.sp, fontSize = 9.sp,
text = "${editedPrefix ?: ""}${message.time}", text = "${editedPrefix ?: ""}${content.message.time}",
textAlign = TextAlign.End, textAlign = TextAlign.End,
color = MaterialTheme.colors.onPrimary, color = MaterialTheme.colors.onPrimary,
modifier = Modifier.wrapContentSize() modifier = Modifier.wrapContentSize()
) )
SendStatus(message) SendStatus(content.message)
} }
} }
} }
@ -397,13 +349,13 @@ private fun TextBubbleContent(shape: RoundedCornerShape, background: Color, isNo
} }
@Composable @Composable
private fun ReplyBubbleContent(shape: RoundedCornerShape, background: Color, isNotSelf: Boolean, reply: RoomEvent.Reply) { private fun ReplyBubbleContent(content: BubbleContent<RoomEvent.Reply>) {
Box(modifier = Modifier.padding(start = 6.dp)) { Box(modifier = Modifier.padding(start = 6.dp)) {
Box( Box(
Modifier Modifier
.padding(4.dp) .padding(4.dp)
.clip(shape) .clip(content.shape)
.background(background) .background(content.background)
.height(IntrinsicSize.Max), .height(IntrinsicSize.Max),
) { ) {
Column( Column(
@ -414,17 +366,18 @@ private fun ReplyBubbleContent(shape: RoundedCornerShape, background: Color, isN
) { ) {
Column( Column(
Modifier Modifier
.background(if (isNotSelf) SmallTalkTheme.extendedColors.otherBubbleReplyBackground else SmallTalkTheme.extendedColors.selfBubbleReplyBackground) .background(if (content.isNotSelf) SmallTalkTheme.extendedColors.otherBubbleReplyBackground else SmallTalkTheme.extendedColors.selfBubbleReplyBackground)
.padding(4.dp) .padding(4.dp)
) { ) {
val replyName = if (!isNotSelf && reply.replyingToSelf) "You" else reply.replyingTo.author.displayName ?: reply.replyingTo.author.id.value val replyName = if (!content.isNotSelf && content.message.replyingToSelf) "You" else content.message.replyingTo.author.displayName
?: content.message.replyingTo.author.id.value
Text( Text(
fontSize = 11.sp, fontSize = 11.sp,
text = replyName, text = replyName,
maxLines = 1, maxLines = 1,
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
when (val replyingTo = reply.replyingTo) { when (val replyingTo = content.message.replyingTo) {
is Message -> { is Message -> {
Text( Text(
text = replyingTo.content, text = replyingTo.content,
@ -434,20 +387,34 @@ private fun ReplyBubbleContent(shape: RoundedCornerShape, background: Color, isN
textAlign = TextAlign.Start, textAlign = TextAlign.Start,
) )
} }
is RoomEvent.Image -> {
val width = with(LocalDensity.current) { replyingTo.imageMeta.width.toDp() }
val height = with(LocalDensity.current) { replyingTo.imageMeta.height.toDp() }
Spacer(modifier = Modifier.height(4.dp))
Image(
modifier = Modifier.size(width, height),
painter = rememberImagePainter(
data = replyingTo,
builder = { fetcher(DecryptingFetcher()) }
),
contentDescription = null,
)
Spacer(modifier = Modifier.height(4.dp))
}
} }
} }
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
if (isNotSelf) { if (content.isNotSelf) {
Text( Text(
fontSize = 11.sp, fontSize = 11.sp,
text = reply.message.author.displayName ?: reply.message.author.id.value, text = content.message.message.author.displayName ?: content.message.message.author.id.value,
maxLines = 1, maxLines = 1,
color = MaterialTheme.colors.onPrimary color = MaterialTheme.colors.onPrimary
) )
} }
when (val message = reply.message) { when (val message = content.message.message) {
is Message -> { is Message -> {
Text( Text(
text = message.content, text = message.content,
@ -457,18 +424,32 @@ private fun ReplyBubbleContent(shape: RoundedCornerShape, background: Color, isN
textAlign = TextAlign.Start, textAlign = TextAlign.Start,
) )
} }
is RoomEvent.Image -> {
val width = with(LocalDensity.current) { message.imageMeta.width.toDp() }
val height = with(LocalDensity.current) { message.imageMeta.height.toDp() }
Spacer(modifier = Modifier.height(4.dp))
Image(
modifier = Modifier.size(width, height),
painter = rememberImagePainter(
data = content.message,
builder = { fetcher(DecryptingFetcher()) }
),
contentDescription = null,
)
Spacer(modifier = Modifier.height(4.dp))
}
} }
Spacer(modifier = Modifier.height(2.dp)) Spacer(modifier = Modifier.height(2.dp))
Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.End, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
Text( Text(
fontSize = 9.sp, fontSize = 9.sp,
text = reply.time, text = content.message.time,
textAlign = TextAlign.End, textAlign = TextAlign.End,
color = MaterialTheme.colors.onPrimary, color = MaterialTheme.colors.onPrimary,
modifier = Modifier.wrapContentSize() modifier = Modifier.wrapContentSize()
) )
SendStatus(reply.message) SendStatus(content.message.message)
} }
} }
} }