Browse Source
* Redesign chat example * Minor typography improvements * Code cleanup * Update examples/chat/iosApp/iosApp/iosApp.swift Co-authored-by: Ivan Matkov <ivan.matkov@jetbrains.com> * Use JPG instead of PNG * Turn background in to a JPG Add raw PXD file. * Remove TEAM_ID * Move to sp sizes * Make Android text consistent with iOS variant * Prefer light color scheme to prevent unwanted text color switch * Remove PXD --------- Co-authored-by: Ivan Matkov <ivan.matkov@jetbrains.com>pull/3193/head
Sebastian Aigner
2 years ago
committed by
GitHub
15 changed files with 292 additions and 125 deletions
@ -0,0 +1,143 @@
|
||||
import androidx.compose.foundation.background |
||||
import androidx.compose.foundation.layout.Arrangement |
||||
import androidx.compose.foundation.layout.Box |
||||
import androidx.compose.foundation.layout.Column |
||||
import androidx.compose.foundation.layout.Row |
||||
import androidx.compose.foundation.layout.Spacer |
||||
import androidx.compose.foundation.layout.fillMaxWidth |
||||
import androidx.compose.foundation.layout.padding |
||||
import androidx.compose.foundation.layout.size |
||||
import androidx.compose.foundation.shape.RoundedCornerShape |
||||
import androidx.compose.material.MaterialTheme |
||||
import androidx.compose.material.Text |
||||
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.geometry.Size |
||||
import androidx.compose.ui.graphics.Color |
||||
import androidx.compose.ui.graphics.Outline |
||||
import androidx.compose.ui.graphics.Path |
||||
import androidx.compose.ui.graphics.Shape |
||||
import androidx.compose.ui.text.font.FontWeight |
||||
import androidx.compose.ui.text.style.TextAlign |
||||
import androidx.compose.ui.unit.Density |
||||
import androidx.compose.ui.unit.LayoutDirection |
||||
import androidx.compose.ui.unit.dp |
||||
import androidx.compose.ui.unit.sp |
||||
|
||||
@Composable |
||||
fun Triangle(risingToTheRight: Boolean, background: Color) { |
||||
Box( |
||||
Modifier |
||||
.padding(bottom = 10.dp, start = 0.dp) |
||||
.clip(TriangleEdgeShape(risingToTheRight)) |
||||
.background(background) |
||||
.size(6.dp) |
||||
) |
||||
} |
||||
|
||||
@Composable |
||||
inline fun ChatMessage(isMyMessage: Boolean, message: Message) { |
||||
Box( |
||||
modifier = Modifier.fillMaxWidth(), |
||||
contentAlignment = if (isMyMessage) Alignment.CenterEnd else Alignment.CenterStart |
||||
) { |
||||
|
||||
Row(verticalAlignment = Alignment.Bottom) { |
||||
if (!isMyMessage) { |
||||
Column { |
||||
UserPic(message.user) |
||||
} |
||||
Spacer(Modifier.size(2.dp)) |
||||
Column { |
||||
Triangle(true, ChatColors.OTHERS_MESSAGE) |
||||
} |
||||
} |
||||
|
||||
Column { |
||||
Box( |
||||
Modifier.clip( |
||||
RoundedCornerShape( |
||||
10.dp, |
||||
10.dp, |
||||
if (!isMyMessage) 10.dp else 0.dp, |
||||
if (!isMyMessage) 0.dp else 10.dp |
||||
) |
||||
) |
||||
.background(color = if (!isMyMessage) ChatColors.OTHERS_MESSAGE else ChatColors.MY_MESSAGE) |
||||
.padding(start = 10.dp, top = 5.dp, end = 10.dp, bottom = 5.dp), |
||||
) { |
||||
Column { |
||||
if(!isMyMessage) { |
||||
Row(verticalAlignment = Alignment.Bottom) { |
||||
Text( |
||||
text = message.user.name, |
||||
style = MaterialTheme.typography.body1.copy( |
||||
fontWeight = FontWeight.SemiBold, |
||||
letterSpacing = 0.sp, |
||||
fontSize = 14.sp |
||||
), |
||||
color = message.user.color |
||||
) |
||||
} |
||||
} |
||||
Spacer(Modifier.size(3.dp)) |
||||
Text( |
||||
text = message.text, |
||||
style = MaterialTheme.typography.body1.copy( |
||||
fontSize = 18.sp, |
||||
letterSpacing = 0.sp |
||||
) |
||||
) |
||||
Spacer(Modifier.size(4.dp)) |
||||
Row( |
||||
horizontalArrangement = Arrangement.End, |
||||
modifier = Modifier.align(Alignment.End) |
||||
) { |
||||
Text( |
||||
text = timeToString(message.timeMs), |
||||
textAlign = TextAlign.End, |
||||
style = MaterialTheme.typography.subtitle1.copy(fontSize = 10.sp), |
||||
color = ChatColors.TIME_TEXT |
||||
) |
||||
} |
||||
} |
||||
} |
||||
Box(Modifier.size(10.dp)) |
||||
} |
||||
if(isMyMessage) { |
||||
Column { |
||||
Triangle(false, ChatColors.MY_MESSAGE) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
// Adapted from https://stackoverflow.com/questions/65965852/jetpack-compose-create-chat-bubble-with-arrow-and-border-elevation |
||||
class TriangleEdgeShape(val risingToTheRight: Boolean) : Shape { |
||||
override fun createOutline( |
||||
size: Size, |
||||
layoutDirection: LayoutDirection, |
||||
density: Density |
||||
): Outline { |
||||
val trianglePath = if(risingToTheRight) { |
||||
Path().apply { |
||||
moveTo(x = 0f, y = size.height) |
||||
lineTo(x = size.width, y = 0f) |
||||
lineTo(x = size.width, y = size.height) |
||||
} |
||||
} else { |
||||
Path().apply { |
||||
moveTo(x = 0f, y = 0f) |
||||
lineTo(x = size.width, y = size.height) |
||||
lineTo(x = 0f, y = size.height) |
||||
} |
||||
} |
||||
|
||||
return Outline.Generic(path = trianglePath) |
||||
} |
||||
} |
After Width: | Height: | Size: 468 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in new issue