From ec5562876dd5cede97d125aea18af1d86cc9ca21 Mon Sep 17 00:00:00 2001 From: Diego Beraldin Date: Tue, 19 Sep 2023 23:01:22 +0200 Subject: [PATCH] fix(common-ui): comment ordering in post detail --- .../postdetail/PostDetailViewModel.kt | 68 ++++++++++++++++++- .../domain/lemmy/data/CommentModel.kt | 5 ++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/core-commonui/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/commonui/postdetail/PostDetailViewModel.kt b/core-commonui/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/commonui/postdetail/PostDetailViewModel.kt index f586af006..6fd164f23 100644 --- a/core-commonui/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/commonui/postdetail/PostDetailViewModel.kt +++ b/core-commonui/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/commonui/postdetail/PostDetailViewModel.kt @@ -146,9 +146,12 @@ class PostDetailViewModel( page = currentPage, sort = sort, maxDepth = CommentRepository.MAX_COMMENT_DEPTH, - ) + ).let { + processCommentsToGetNestedOrder(it) + } currentPage++ - val canFetchMore = commentList.size >= CommentRepository.DEFAULT_PAGE_SIZE + val topLevelItems = commentList.filter { it.depth == 0 } + val canFetchMore = topLevelItems.size >= CommentRepository.DEFAULT_PAGE_SIZE mvi.updateState { val newcomments = if (refreshing) { commentList @@ -180,7 +183,9 @@ class PostDetailViewModel( parentId = parentId, sort = sort, maxDepth = CommentRepository.MAX_COMMENT_DEPTH, - ) + ).let { + processCommentsToGetNestedOrder(it) + } val newList = uiState.value.comments.let { list -> val index = list.indexOfFirst { c -> c.id == parentId } list.toMutableList().apply { @@ -452,3 +457,60 @@ class PostDetailViewModel( } } } + + +private data class Node( + val comment: CommentModel?, + val children: MutableList = mutableListOf(), +) + +private fun findNode(id: String, node: Node): Node? { + if (node.comment?.id.toString() == id) { + return node + } + for (c in node.children) { + val res = findNode(id, c) + if (res != null) { + return res + } + } + return null +} + + +private fun linearize(node: Node, list: MutableList) { + if (node.children.isEmpty()) { + if (node.comment != null) { + list.add(node.comment) + } + return + } + for (c in node.children) { + linearize(c, list) + } + if (node.comment != null) { + list.add(node.comment) + } +} + +private fun processCommentsToGetNestedOrder(items: List): List { + val root = Node(null) + // reconstructs the tree + for (c in items) { + val parentId = c.parentId + if (parentId == null) { + root.children += Node(c) + } else { + val parent = findNode(parentId, root) + if (parent != null) { + parent.children += Node(c) + } + } + } + + // linearize the tree depth first + val result = mutableListOf() + linearize(root, result) + + return result.reversed().toList() +} \ No newline at end of file diff --git a/domain-lemmy/data/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/domain/lemmy/data/CommentModel.kt b/domain-lemmy/data/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/domain/lemmy/data/CommentModel.kt index 80b628dfe..8e1560867 100644 --- a/domain-lemmy/data/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/domain/lemmy/data/CommentModel.kt +++ b/domain-lemmy/data/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/domain/lemmy/data/CommentModel.kt @@ -14,4 +14,9 @@ data class CommentModel( val path: String = "", ) : JavaSerializable { val depth: Int get() = (path.split(".").size - 2).coerceAtLeast(0) + val parentId: String? + get() = path.split(".") + .let { + it.getOrNull(it.lastIndex - 1) + }?.takeIf { it != "0" } }