From 2e573662d5ea486698d686c8b0cca77897c63871 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:07:49 +0700 Subject: [PATCH] android, desktop: hiding counters while scrolling (#5363) * android, desktop: hiding counters while scrolling * change --- .../simplex/common/views/chat/ChatView.kt | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index 913ea87c98..983b5e9682 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -984,6 +984,7 @@ fun BoxScope.ChatItemsList( }) val maxHeight = remember { derivedStateOf { listState.value.layoutInfo.viewportEndOffset - topPaddingToContentPx.value } } val loadingMoreItems = remember { mutableStateOf(false) } + val animatedScrollingInProgress = remember { mutableStateOf(false) } val ignoreLoadingRequests = remember(remoteHostId) { mutableSetOf() } if (!loadingMoreItems.value) { PreloadItems(chatInfo.id, if (searchValueIsEmpty.value) ignoreLoadingRequests else mutableSetOf(), mergedItems, listState, ChatPagination.UNTIL_PRELOAD_COUNT) { chatId, pagination -> @@ -1004,7 +1005,7 @@ fun BoxScope.ChatItemsList( val chatInfoUpdated = rememberUpdatedState(chatInfo) val highlightedItems = remember { mutableStateOf(setOf()) } val scope = rememberCoroutineScope() - val scrollToItem: (Long) -> Unit = remember { scrollToItem(searchValue, loadingMoreItems, highlightedItems, chatInfoUpdated, maxHeight, scope, reversedChatItems, mergedItems, listState, loadMessages) } + val scrollToItem: (Long) -> Unit = remember { scrollToItem(searchValue, loadingMoreItems, animatedScrollingInProgress, highlightedItems, chatInfoUpdated, maxHeight, scope, reversedChatItems, mergedItems, listState, loadMessages) } val scrollToQuotedItemFromItem: (Long) -> Unit = remember { findQuotedItemFromItem(remoteHostIdUpdated, chatInfoUpdated, scope, scrollToItem) } LoadLastItems(loadingMoreItems, remoteHostId, chatInfo) @@ -1314,7 +1315,7 @@ fun BoxScope.ChatItemsList( } } } - FloatingButtons(loadingMoreItems, mergedItems, unreadCount, maxHeight, composeViewHeight, searchValue, markChatRead, listState) + FloatingButtons(loadingMoreItems, animatedScrollingInProgress, mergedItems, unreadCount, maxHeight, composeViewHeight, searchValue, markChatRead, listState) FloatingDate(Modifier.padding(top = 10.dp + topPaddingToContent(true)).align(Alignment.TopCenter), mergedItems, listState) LaunchedEffect(Unit) { @@ -1323,6 +1324,15 @@ fun BoxScope.ChatItemsList( chatViewScrollState.value = it } } + LaunchedEffect(Unit) { + snapshotFlow { listState.value.isScrollInProgress } + .filter { !it } + .collect { + if (animatedScrollingInProgress.value) { + animatedScrollingInProgress.value = false + } + } + } } @Composable @@ -1400,6 +1410,7 @@ private fun NotifyChatListOnFinishingComposition( @Composable fun BoxScope.FloatingButtons( loadingMoreItems: MutableState, + animatedScrollingInProgress: MutableState, mergedItems: State, unreadCount: State, maxHeight: State, @@ -1439,8 +1450,14 @@ fun BoxScope.FloatingButtons( bottomUnreadCount, showBottomButtonWithCounter, showBottomButtonWithArrow, + animatedScrollingInProgress, composeViewHeight, - onClick = { scope.launch { tryBlockAndSetLoadingMore(loadingMoreItems) { listState.value.animateScrollToItem(0) } } } + onClick = { + scope.launch { + animatedScrollingInProgress.value = true + tryBlockAndSetLoadingMore(loadingMoreItems) { listState.value.animateScrollToItem(0) } + } + } ) // Don't show top FAB if is in search if (searchValue.value.isNotEmpty()) return @@ -1451,11 +1468,15 @@ fun BoxScope.FloatingButtons( TopEndFloatingButton( Modifier.padding(end = DEFAULT_PADDING, top = 24.dp + topPaddingToContent(true)).align(Alignment.TopEnd), topUnreadCount, + animatedScrollingInProgress, onClick = { val index = mergedItems.value.items.indexOfLast { it.hasUnread() } if (index != -1) { // scroll to the top unread item - scope.launch { tryBlockAndSetLoadingMore(loadingMoreItems) { listState.value.animateScrollToItem(index + 1, -maxHeight.value) } } + scope.launch { + animatedScrollingInProgress.value = true + tryBlockAndSetLoadingMore(loadingMoreItems) { listState.value.animateScrollToItem(index + 1, -maxHeight.value) } + } } }, onLongClick = { showDropDown.value = true } @@ -1595,10 +1616,11 @@ fun MemberImage(member: GroupMember) { private fun TopEndFloatingButton( modifier: Modifier = Modifier, unreadCount: State, + animatedScrollingInProgress: State, onClick: () -> Unit, onLongClick: () -> Unit ) { - if (unreadCount.value > 0) { + if (remember { derivedStateOf { unreadCount.value > 0 && !animatedScrollingInProgress.value } }.value) { val interactionSource = interactionSourceWithDetection(onClick, onLongClick) FloatingActionButton( {}, // no action here @@ -1839,6 +1861,7 @@ private fun lastFullyVisibleIemInListState(topPaddingToContentPx: State, de private fun scrollToItem( searchValue: State, loadingMoreItems: MutableState, + animatedScrollingInProgress: MutableState, highlightedItems: MutableState>, chatInfo: State, maxHeight: State, @@ -1876,6 +1899,7 @@ private fun scrollToItem( highlightedItems.value = setOf(itemId) } else { withContext(scope.coroutineContext) { + animatedScrollingInProgress.value = true listState.value.animateScrollToItem(min(reversedChatItems.value.lastIndex, index + 1), -maxHeight.value) highlightedItems.value = setOf(itemId) } @@ -1937,10 +1961,11 @@ private fun BoxScope.BottomEndFloatingButton( unreadCount: State, showButtonWithCounter: State, showButtonWithArrow: State, + animatedScrollingInProgress: State, composeViewHeight: State, onClick: () -> Unit ) = when { - showButtonWithCounter.value -> { + showButtonWithCounter.value && !animatedScrollingInProgress.value -> { FloatingActionButton( onClick = onClick, elevation = FloatingActionButtonDefaults.elevation(0.dp, 0.dp, 0.dp, 0.dp), @@ -1954,7 +1979,7 @@ private fun BoxScope.BottomEndFloatingButton( ) } } - showButtonWithArrow.value -> { + showButtonWithArrow.value && !animatedScrollingInProgress.value -> { FloatingActionButton( onClick = onClick, elevation = FloatingActionButtonDefaults.elevation(0.dp, 0.dp, 0.dp, 0.dp),