open on first unread message

This commit is contained in:
Diogo
2024-10-30 21:48:01 +00:00
parent 5ccf00f70e
commit ff42ca69de
3 changed files with 16 additions and 7 deletions
@@ -192,6 +192,11 @@ fun ChatSection.excessItemCount(): Int {
return max(boundary.maxIndex.minus(boundary.minIndex) + 1 - MAX_SECTION_SIZE, 0)
}
fun landingSectionToArea(chatLandingSection: ChatLandingSection) = when (chatLandingSection) {
ChatLandingSection.Latest -> ChatSectionArea.Bottom
ChatLandingSection.Unread -> ChatSectionArea.Current
}
suspend fun apiLoadMessagesAroundItem(chatInfo: ChatInfo, chatModel: ChatModel, aroundItemId: Long, rhId: Long?, chatSectionLoad: ChatSectionLoad) {
val pagination = ChatPagination.Around(aroundItemId, ChatPagination.PRELOAD_COUNT * 2)
val (chat) = chatModel.controller.apiGetChat(rhId, chatInfo.chatType, chatInfo.apiId, pagination) ?: return
@@ -94,7 +94,6 @@ fun ChatView(staleChatId: State<String?>, onComposed: suspend (chatId: String) -
showSearch.value = false
searchText.value = ""
selectedChatItems.value = null
chatModel.chatItemsSectionArea = mutableMapOf<Long, ChatSectionArea>().also { it.putAll(chatModel.chatItems.value.associate { it.id to ChatSectionArea.Bottom }) }
}
}
}
@@ -1009,8 +1008,10 @@ fun BoxWithConstraintsScope.ChatItemsList(
val sections by remember { derivedStateOf { reversedChatItems.putIntoSections(revealedItems.value) } }
val preloadItemsEnabled = remember { mutableStateOf(true) }
val boundaries = remember { derivedStateOf { sections.map { it.boundary } } }
val scrollPosition: (Int) -> Int = { idx -> min(reversedChatItems.lastIndex, idx + 1) }
PreloadItems(chatInfo.id, listState, ChatPagination.UNTIL_PRELOAD_COUNT, preloadItemsEnabled, boundaries, loadMessages)
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
LaunchedEffect(Unit) {
launch {
@@ -1019,13 +1020,15 @@ fun BoxWithConstraintsScope.ChatItemsList(
.collect {
revealedItems.value = setOf()
preloadItemsEnabled.value = true
val firstUnreadItemIndex = chatModel.chatItems.value.indexOfFirst { it.isRcvNew }
if (firstUnreadItemIndex != -1) {
listState.scrollToItem(scrollPosition(reversedChatItems.size - 1 - firstUnreadItemIndex), -maxHeightRounded)
}
}
}
}
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
val scrollToItem: (Long) -> Unit = { itemId: Long ->
val scrollPosition: (Int) -> Int = { idx -> min(reversedChatItems.lastIndex, idx + 1) }
val index = reversedChatItems.indexOfFirst { it.id == itemId }
preloadItemsEnabled.value = false
@@ -207,28 +207,29 @@ suspend fun noteFolderChatAction(rhId: Long?, noteFolder: NoteFolder) {
suspend fun openDirectChat(rhId: Long?, contactId: Long, chatModel: ChatModel) = coroutineScope {
val chat = chatModel.controller.apiGetChat(rhId, ChatType.Direct, contactId, ChatPagination.Initial(ChatPagination.INITIAL_COUNT))
if (chat != null && isActive) {
openLoadedChat(chat.first, chatModel)
openLoadedChat(chat.first, chatModel, chat.second)
}
}
suspend fun openGroupChat(rhId: Long?, groupId: Long, chatModel: ChatModel) = coroutineScope {
val chat = chatModel.controller.apiGetChat(rhId, ChatType.Group, groupId, ChatPagination.Initial(ChatPagination.INITIAL_COUNT))
if (chat != null && isActive) {
openLoadedChat(chat.first, chatModel)
openLoadedChat(chat.first, chatModel, chat.second)
}
}
suspend fun openChat(rhId: Long?, chatInfo: ChatInfo, chatModel: ChatModel) = coroutineScope {
val chat = chatModel.controller.apiGetChat(rhId, chatInfo.chatType, chatInfo.apiId, ChatPagination.Initial(ChatPagination.INITIAL_COUNT))
if (chat != null && isActive) {
openLoadedChat(chat.first, chatModel)
openLoadedChat(chat.first, chatModel, chat.second)
}
}
fun openLoadedChat(chat: Chat, chatModel: ChatModel) {
fun openLoadedChat(chat: Chat, chatModel: ChatModel, landingSection: ChatLandingSection = ChatLandingSection.Latest) {
chatModel.chatItemStatuses.clear()
chatModel.chatItems.replaceAll(chat.chatItems)
chatModel.chatId.value = chat.chatInfo.id
chatModel.chatItemsSectionArea = mutableMapOf<Long, ChatSectionArea>().also { map -> map.putAll(chatModel.chatItems.value.associate { it.id to landingSectionToArea(landingSection) }) }
}
suspend fun apiLoadPrevMessages(ch: Chat, chatModel: ChatModel, beforeChatItemId: Long, search: String, chatSectionLoad: ChatSectionLoad) {