Merge pull request #418 from simplex-chat/id/android/fix-chat-scrolling

id/android/fix chat scrolling
This commit is contained in:
Evgeny Poberezkin
2022-03-09 20:06:01 +00:00
committed by GitHub
@@ -5,12 +5,15 @@ import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
@@ -80,7 +83,10 @@ fun ChatLayout(
info: () -> Unit,
sendMessage: (String) -> Unit
) {
Surface(Modifier.fillMaxWidth().background(MaterialTheme.colors.background)) {
Surface(
Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.background)) {
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
Scaffold(
topBar = { ChatInfoToolbar(chat, back, info) },
@@ -135,9 +141,24 @@ fun ChatInfoToolbar(chat: Chat, back: () -> Unit, info: () -> Unit) {
}
}
data class MessageListState(val scrolled: Boolean, val msgCount: Int, val keyboardOffset: Int)
val MessageListStateSaver = run {
val scrolledKey = "scrolled"
val countKey = "msgCount"
val keyboardKey = "keyboardOffset"
mapSaver(
save = { mapOf(scrolledKey to it.scrolled, countKey to it.msgCount, keyboardKey to it.keyboardOffset) },
restore = { MessageListState(it[scrolledKey] as Boolean, it[countKey] as Int, it[keyboardKey] as Int) }
)
}
@Composable
fun ChatItemsList(chatItems: List<ChatItem>) {
val listState = rememberLazyListState()
var messageListState = rememberSaveable(stateSaver = MessageListStateSaver) {
mutableStateOf(MessageListState(false, chatItems.count(), listState.layoutInfo.viewportEndOffset))
}
val scope = rememberCoroutineScope()
val uriHandler = LocalUriHandler.current
LazyColumn(state = listState) {
@@ -145,8 +166,16 @@ fun ChatItemsList(chatItems: List<ChatItem>) {
ChatItemView(cItem, uriHandler)
}
val len = chatItems.count()
if (len > 1) {
if(listState.layoutInfo.viewportEndOffset != messageListState.value.keyboardOffset) {
scope.launch {
val scrollBy = maxOf(messageListState.value.keyboardOffset.toFloat() - listState.layoutInfo.viewportEndOffset.toFloat(), 0f)
listState.scrollBy( scrollBy)
messageListState.value = messageListState.value.copy(keyboardOffset = listState.layoutInfo.viewportEndOffset)
}
}
if (len > 1 && (!messageListState.value.scrolled || len != messageListState.value.msgCount)) {
scope.launch {
messageListState.value = MessageListState(true, chatItems.count(), listState.layoutInfo.viewportEndOffset)
listState.animateScrollToItem(len - 1)
}
}