Skip to content
Snippets Groups Projects
Verified Commit dcdf36cc authored by Torsten Grote's avatar Torsten Grote
Browse files

Implement loading of forum posts and stubs for rendering posts

parent 2bc9d689
No related branches found
No related tags found
1 merge request!240Forum List and Adding Forums
...@@ -30,15 +30,20 @@ import org.briarproject.bramble.api.sync.GroupId ...@@ -30,15 +30,20 @@ import org.briarproject.bramble.api.sync.GroupId
import org.briarproject.bramble.api.sync.event.GroupAddedEvent import org.briarproject.bramble.api.sync.event.GroupAddedEvent
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent import org.briarproject.bramble.api.sync.event.GroupRemovedEvent
import org.briarproject.briar.api.forum.ForumManager import org.briarproject.briar.api.forum.ForumManager
import org.briarproject.briar.client.MessageTreeImpl
import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.threading.BriarExecutors
import org.briarproject.briar.desktop.utils.clearAndAddAll import org.briarproject.briar.desktop.utils.clearAndAddAll
import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel
import org.briarproject.briar.desktop.viewmodel.asState import org.briarproject.briar.desktop.viewmodel.asState
import javax.inject.Inject import javax.inject.Inject
class ForumsViewModel sealed class PostsState
@Inject object Loading : PostsState()
constructor( class Loaded(private val messageTree: MessageTreeImpl<ThreadItem>) : PostsState() {
val posts: MutableList<ThreadItem> get() = messageTree.depthFirstOrder()
}
class ForumsViewModel @Inject constructor(
private val forumManager: ForumManager, private val forumManager: ForumManager,
briarExecutors: BriarExecutors, briarExecutors: BriarExecutors,
lifecycleManager: LifecycleManager, lifecycleManager: LifecycleManager,
...@@ -60,6 +65,9 @@ constructor( ...@@ -60,6 +65,9 @@ constructor(
private val _filterBy = mutableStateOf("") private val _filterBy = mutableStateOf("")
val filterBy = _filterBy.asState() val filterBy = _filterBy.asState()
private val _posts = mutableStateOf<PostsState>(Loading)
val posts: State<PostsState> = _posts
override fun onInit() { override fun onInit() {
super.onInit() super.onInit()
loadGroups() loadGroups()
...@@ -96,10 +104,24 @@ constructor( ...@@ -96,10 +104,24 @@ constructor(
fun selectGroup(groupItem: GroupItem) { fun selectGroup(groupItem: GroupItem) {
_selectedGroupItem.value = groupItem _selectedGroupItem.value = groupItem
loadPosts(groupItem.id)
} }
fun isSelected(groupId: GroupId) = _selectedGroupItem.value?.id == groupId fun isSelected(groupId: GroupId) = _selectedGroupItem.value?.id == groupId
private fun loadPosts(groupId: GroupId) {
_posts.value = Loading
runOnDbThreadWithTransaction(true) { txn ->
val items = forumManager.getPostHeaders(txn, groupId).map { header ->
ForumPostItem(header, forumManager.getPostText(txn, header.id))
}
val tree = MessageTreeImpl<ThreadItem>().apply { add(items) }
txn.attach {
_posts.value = Loaded(tree)
}
}
}
fun setFilterBy(filter: String) { fun setFilterBy(filter: String) {
_filterBy.value = filter _filterBy.value = filter
} }
......
...@@ -53,7 +53,6 @@ import org.briarproject.briar.desktop.contact.ContactDropDown.State.CLOSED ...@@ -53,7 +53,6 @@ import org.briarproject.briar.desktop.contact.ContactDropDown.State.CLOSED
import org.briarproject.briar.desktop.contact.ContactDropDown.State.MAIN import org.briarproject.briar.desktop.contact.ContactDropDown.State.MAIN
import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
import org.briarproject.briar.desktop.ui.HorizontalDivider import org.briarproject.briar.desktop.ui.HorizontalDivider
import org.briarproject.briar.desktop.ui.UiPlaceholder
import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
import org.briarproject.briar.desktop.viewmodel.viewModel import org.briarproject.briar.desktop.viewmodel.viewModel
...@@ -67,8 +66,7 @@ fun GroupConversationScreen( ...@@ -67,8 +66,7 @@ fun GroupConversationScreen(
GroupConversationHeader(groupItem) { viewModel.deleteGroup(groupItem) } GroupConversationHeader(groupItem) { viewModel.deleteGroup(groupItem) }
}, },
content = { padding -> content = { padding ->
// Loader() ThreadedConversationScreen(viewModel.posts.value)
UiPlaceholder()
}, },
) )
} }
......
/*
* Briar Desktop
* Copyright (C) 2021-2022 The Briar Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.briarproject.briar.desktop.forums
import org.briarproject.bramble.api.identity.Author
import org.briarproject.bramble.api.sync.MessageId
import org.briarproject.briar.api.client.MessageTree
import org.briarproject.briar.api.forum.ForumPostHeader
import org.briarproject.briar.api.identity.AuthorInfo
import org.briarproject.briar.desktop.utils.UiUtils.getContactDisplayName
import javax.annotation.concurrent.NotThreadSafe
@NotThreadSafe
class ForumPostItem(h: ForumPostHeader, text: String?) : ThreadItem(
messageId = h.id,
parentId = h.parentId,
text = text ?: "",
timestamp = h.timestamp,
author = h.author,
authorInfo = h.authorInfo,
isRead = h.isRead
)
@NotThreadSafe
abstract class ThreadItem(
private val messageId: MessageId,
private val parentId: MessageId?,
val text: String,
private val timestamp: Long,
val author: Author,
val authorInfo: AuthorInfo,
var isRead: Boolean,
) : MessageTree.MessageNode {
companion object {
const val UNDEFINED = -1
}
private var level: Int = UNDEFINED
var isHighlighted = false
fun getLevel(): Int {
return level
}
override fun getId(): MessageId {
return messageId
}
override fun getParentId(): MessageId? {
return parentId
}
override fun getTimestamp(): Long {
return timestamp
}
/**
* Returns the author's name, with an alias if one exists.
*/
val authorName: String
get() = getContactDisplayName(author.name, authorInfo.alias)
override fun setLevel(level: Int) {
this.level = level
}
override fun hashCode(): Int {
return messageId.hashCode()
}
override fun equals(other: Any?): Boolean {
return other is ThreadItem && messageId == other.messageId
}
}
/*
* Briar Desktop
* Copyright (C) 2021-2022 The Briar Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.briarproject.briar.desktop.forums
import androidx.compose.foundation.VerticalScrollbar
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment.Companion.CenterEnd
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.briarproject.briar.desktop.forums.ThreadItem.Companion.UNDEFINED
import org.briarproject.briar.desktop.ui.HorizontalDivider
import org.briarproject.briar.desktop.ui.Loader
@Composable
fun ThreadedConversationScreen(
postsState: PostsState,
) = when (postsState) {
Loading -> Loader()
is Loaded -> {
val scrollState = rememberLazyListState()
Box(modifier = Modifier.fillMaxSize()) {
LazyColumn(
state = scrollState,
modifier = Modifier.selectableGroup()
) {
items(postsState.posts) { item ->
ThreadItemComposable(item)
HorizontalDivider()
}
}
VerticalScrollbar(
adapter = rememberScrollbarAdapter(scrollState),
modifier = Modifier.align(CenterEnd).fillMaxHeight()
)
}
}
}
@Composable
fun ThreadItemComposable(item: ThreadItem) {
Text(
text = item.text ?: "",
modifier = Modifier
.padding(4.dp)
.padding(
start = 4.dp +
if (item.getLevel() == UNDEFINED) 0.dp else (item.getLevel() * 8).dp
),
)
}
...@@ -19,5 +19,5 @@ ...@@ -19,5 +19,5 @@
package org.briarproject.briar.desktop package org.briarproject.briar.desktop
fun main() = RunWithTemporaryAccount { fun main() = RunWithTemporaryAccount {
getTestDataCreator().createTestData(5, 20, 50, 4, 10, 10) getTestDataCreator().createTestData(5, 20, 50, 4, 10, 42)
}.run() }.run()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment