Made scrolling faster (#961)

This commit is contained in:
Stanislav Dmitrenko
2022-08-22 14:14:46 +03:00
committed by GitHub
parent 985f3dffd3
commit 3c2f5d14f5

View File

@@ -252,22 +252,21 @@ fun ChatLayout(
sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp)
) { ) {
val floatingButton: MutableState<@Composable () -> Unit> = remember { mutableStateOf({}) } val floatingButton: MutableState<@Composable () -> Unit> = remember { mutableStateOf({}) }
val setFloatingButton = { button: @Composable () -> Unit ->
floatingButton.value = button
}
Scaffold( Scaffold(
topBar = { ChatInfoToolbar(chat, back, info, startCall, addMembers, onSearchValueChanged) }, topBar = { ChatInfoToolbar(chat, back, info, startCall, addMembers, onSearchValueChanged) },
bottomBar = composeView, bottomBar = composeView,
modifier = Modifier.navigationBarsWithImePadding(), modifier = Modifier.navigationBarsWithImePadding(),
floatingActionButton = floatingButton.value, floatingActionButton = { floatingButton.value() },
) { contentPadding -> ) { contentPadding ->
CompositionLocalProvider(
// Makes horizontal and vertical scrolling to coexist nicely.
// With default touchSlop when you scroll LazyColumn, you can unintentionally open reply view
LocalViewConfiguration provides LocalViewConfiguration.current.bigTouchSlop()
) {
BoxWithConstraints(Modifier.padding(contentPadding)) { BoxWithConstraints(Modifier.padding(contentPadding)) {
ChatItemsList( ChatItemsList(
user, chat, unreadCount, composeState, chatItems, searchValue, user, chat, unreadCount, composeState, chatItems, searchValue,
useLinkPreviews, openDirectChat, loadPrevMessages, deleteMessage, useLinkPreviews, openDirectChat, loadPrevMessages, deleteMessage,
receiveFile, joinGroup, acceptCall, markRead, floatingButton receiveFile, joinGroup, acceptCall, markRead, setFloatingButton
) )
} }
} }
@@ -275,7 +274,6 @@ fun ChatLayout(
} }
} }
} }
}
@Composable @Composable
fun ChatInfoToolbar( fun ChatInfoToolbar(
@@ -412,7 +410,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
joinGroup: (Long) -> Unit, joinGroup: (Long) -> Unit,
acceptCall: (Contact) -> Unit, acceptCall: (Contact) -> Unit,
markRead: (CC.ItemRange, unreadCountAfter: Int?) -> Unit, markRead: (CC.ItemRange, unreadCountAfter: Int?) -> Unit,
floatingButton: MutableState<@Composable () -> Unit> setFloatingButton: (@Composable () -> Unit) -> Unit,
) { ) {
val listState = rememberLazyListState() val listState = rememberLazyListState()
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@@ -451,6 +449,11 @@ fun BoxWithConstraintsScope.ChatItemsList(
val reversedChatItems by remember { derivedStateOf { chatItems.reversed() } } val reversedChatItems by remember { derivedStateOf { chatItems.reversed() } }
LazyColumn(state = listState, reverseLayout = true) { LazyColumn(state = listState, reverseLayout = true) {
itemsIndexed(reversedChatItems) { i, cItem -> itemsIndexed(reversedChatItems) { i, cItem ->
CompositionLocalProvider(
// Makes horizontal and vertical scrolling to coexist nicely.
// With default touchSlop when you scroll LazyColumn, you can unintentionally open reply view
LocalViewConfiguration provides LocalViewConfiguration.current.bigTouchSlop()
) {
val dismissState = rememberDismissState(initialValue = DismissValue.Default) { false } val dismissState = rememberDismissState(initialValue = DismissValue.Default) { false }
val directions = setOf(DismissDirection.EndToStart) val directions = setOf(DismissDirection.EndToStart)
val swipeableModifier = SwipeToDismissModifier( val swipeableModifier = SwipeToDismissModifier(
@@ -528,7 +531,8 @@ fun BoxWithConstraintsScope.ChatItemsList(
} }
} }
} }
FloatingButtons(chatItems, unreadCount, chat.chatStats.minUnreadItemId, searchValue, markRead, floatingButton, listState) }
FloatingButtons(chatItems, unreadCount, chat.chatStats.minUnreadItemId, searchValue, markRead, setFloatingButton, listState)
} }
@Composable @Composable
@@ -538,7 +542,7 @@ fun BoxWithConstraintsScope.FloatingButtons(
minUnreadItemId: Long, minUnreadItemId: Long,
searchValue: State<String>, searchValue: State<String>,
markRead: (CC.ItemRange, unreadCountAfter: Int?) -> Unit, markRead: (CC.ItemRange, unreadCountAfter: Int?) -> Unit,
floatingButton: MutableState<@Composable () -> Unit>, setFloatingButton: (@Composable () -> Unit) -> Unit,
listState: LazyListState listState: LazyListState
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@@ -577,7 +581,8 @@ fun BoxWithConstraintsScope.FloatingButtons(
LaunchedEffect(bottomUnreadCount, firstItemIsVisible) { LaunchedEffect(bottomUnreadCount, firstItemIsVisible) {
val showButtonWithCounter = bottomUnreadCount > 0 && !firstItemIsVisible && searchValue.value.isEmpty() val showButtonWithCounter = bottomUnreadCount > 0 && !firstItemIsVisible && searchValue.value.isEmpty()
val showButtonWithArrow = !showButtonWithCounter && !firstItemIsVisible val showButtonWithArrow = !showButtonWithCounter && !firstItemIsVisible
floatingButton.value = bottomEndFloatingButton( setFloatingButton(
bottomEndFloatingButton(
bottomUnreadCount, bottomUnreadCount,
showButtonWithCounter, showButtonWithCounter,
showButtonWithArrow, showButtonWithArrow,
@@ -587,7 +592,7 @@ fun BoxWithConstraintsScope.FloatingButtons(
onClickCounter = { onClickCounter = {
scope.launch { listState.animateScrollToItem(kotlin.math.max(0, bottomUnreadCount - 1), firstVisibleOffset) } scope.launch { listState.animateScrollToItem(kotlin.math.max(0, bottomUnreadCount - 1), firstVisibleOffset) }
} }
) ))
} }
// Don't show top FAB if is in search // Don't show top FAB if is in search
if (searchValue.value.isNotEmpty()) return if (searchValue.value.isNotEmpty()) return
@@ -735,7 +740,7 @@ private fun bottomEndFloatingButton(
} }
} }
private fun ViewConfiguration.bigTouchSlop(slop: Float = 80f) = object: ViewConfiguration { private fun ViewConfiguration.bigTouchSlop(slop: Float = 50f) = object: ViewConfiguration {
override val longPressTimeoutMillis override val longPressTimeoutMillis
get() = get() =
this@bigTouchSlop.longPressTimeoutMillis this@bigTouchSlop.longPressTimeoutMillis