in Jetchat/app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt [208:287]
fun Messages(
messages: List<Message>,
navigateToProfile: (String) -> Unit,
scrollState: LazyListState,
modifier: Modifier = Modifier
) {
val scope = rememberCoroutineScope()
Box(modifier = modifier) {
val authorMe = stringResource(id = R.string.author_me)
LazyColumn(
reverseLayout = true,
state = scrollState,
// Add content padding so that the content can be scrolled (y-axis)
// below the status bar + app bar
// TODO: Get height from somewhere
contentPadding = rememberInsetsPaddingValues(
insets = LocalWindowInsets.current.statusBars,
additionalTop = 90.dp
),
modifier = Modifier
.testTag(ConversationTestTag)
.fillMaxSize()
) {
for (index in messages.indices) {
val prevAuthor = messages.getOrNull(index - 1)?.author
val nextAuthor = messages.getOrNull(index + 1)?.author
val content = messages[index]
val isFirstMessageByAuthor = prevAuthor != content.author
val isLastMessageByAuthor = nextAuthor != content.author
// Hardcode day dividers for simplicity
if (index == messages.size - 1) {
item {
DayHeader("20 Aug")
}
} else if (index == 2) {
item {
DayHeader("Today")
}
}
item {
Message(
onAuthorClick = { name -> navigateToProfile(name) },
msg = content,
isUserMe = content.author == authorMe,
isFirstMessageByAuthor = isFirstMessageByAuthor,
isLastMessageByAuthor = isLastMessageByAuthor
)
}
}
}
// Jump to bottom button shows up when user scrolls past a threshold.
// Convert to pixels:
val jumpThreshold = with(LocalDensity.current) {
JumpToBottomThreshold.toPx()
}
// Show the button if the first visible item is not the first one or if the offset is
// greater than the threshold.
val jumpToBottomButtonEnabled by remember {
derivedStateOf {
scrollState.firstVisibleItemIndex != 0 ||
scrollState.firstVisibleItemScrollOffset > jumpThreshold
}
}
JumpToBottom(
// Only show if the scroller is not at the bottom
enabled = jumpToBottomButtonEnabled,
onClicked = {
scope.launch {
scrollState.animateScrollToItem(0)
}
},
modifier = Modifier.align(Alignment.BottomCenter)
)
}
}