Skip to content
Snippets Groups Projects
Verified Commit 1f6c199a authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Correctly handle backlog requests, Fixes #68 #64 #56

parent d3892590
No related branches found
No related tags found
No related merge requests found
/*
* Quasseldroid - Quassel client for Android
*
* Copyright (c) 2018 Janne Koschinski
* Copyright (c) 2018 The Quassel Project
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.kuschku.quasseldroid.service
import de.kuschku.libquassel.protocol.BufferId
import de.kuschku.libquassel.protocol.Message
import de.kuschku.libquassel.protocol.MsgId
import de.kuschku.libquassel.util.helpers.value
import de.kuschku.quasseldroid.persistence.QuasselDatabase
import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
class BacklogRequester(
private val viewModel: QuasselViewModel,
private val database: QuasselDatabase
) {
fun loadMore(accountId: Long, buffer: BufferId, amount: Int, pageSize: Int,
lastMessageId: MsgId? = null,
untilVisible: Boolean = false,
finishCallback: () -> Unit) {
var missing = amount
viewModel.session.value?.orNull()?.backlogManager?.let {
it.requestBacklog(
bufferId = buffer,
last = lastMessageId ?: database.message().findFirstByBufferId(
buffer
)?.messageId ?: -1,
limit = amount
) {
if (untilVisible && it.isNotEmpty()) {
val filtered = database.filtered().get(accountId, buffer) ?: 0
missing -= it.count {
(it.type.value and filtered.inv()) != 0
}
val messageId = it.map(Message::messageId).min()
if (missing > 0) {
loadMore(accountId, buffer, missing, pageSize, messageId, untilVisible, finishCallback)
} else {
finishCallback()
}
} else {
finishCallback()
}
}
}
}
}
......@@ -107,7 +107,9 @@ class QuasselNotificationBackend @Inject constructor(
Message_Type.Action,
Message_Type.Notice).toInt(),
0
)
) {
processMessages(session, *it.toTypedArray())
}
}
NotificationSettings.Level.HIGHLIGHT -> {
val highlightCount = session.bufferSyncer.highlightCount(buffer.bufferId)
......@@ -118,7 +120,9 @@ class QuasselNotificationBackend @Inject constructor(
Message_Type.Action,
Message_Type.Notice).toInt(),
Message_Flag.of(Message_Flag.Highlight).toInt()
)
) {
processMessages(session, *it.toTypedArray())
}
}
}
NotificationSettings.Level.NONE -> {
......
......@@ -51,6 +51,7 @@ import de.kuschku.libquassel.util.irc.HostmaskHelper
import de.kuschku.quasseldroid.GlideApp
import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.persistence.QuasselDatabase
import de.kuschku.quasseldroid.service.BacklogRequester
import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.AutoCompleteSettings
import de.kuschku.quasseldroid.settings.BacklogSettings
......@@ -100,6 +101,8 @@ class MessageListFragment : ServiceBoundFragment() {
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var backlogRequester: BacklogRequester
private var lastBuffer: BufferId? = null
private var previousMessageId: MsgId? = null
......@@ -207,6 +210,8 @@ class MessageListFragment : ServiceBoundFragment() {
linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.reverseLayout = true
backlogRequester = BacklogRequester(viewModel, database)
adapter.setOnClickListener { msg ->
if (actionMode != null) {
if (!viewModel.selectedMessagesToggle(msg.id, msg)) {
......@@ -481,14 +486,19 @@ class MessageListFragment : ServiceBoundFragment() {
if (bufferId > 0 && bufferId != Int.MAX_VALUE) {
if (initial) swipeRefreshLayout.isRefreshing = true
runInBackground {
viewModel.session {
it.orNull()?.backlogManager?.requestBacklog(
bufferId = bufferId,
last = lastMessageId ?: database.message().findFirstByBufferId(
bufferId
)?.messageId ?: -1,
limit = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize
)
backlogRequester.loadMore(
accountId = accountId,
buffer = bufferId,
amount = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize,
pageSize = backlogSettings.pageSize,
lastMessageId = lastMessageId
?: database.message().findFirstByBufferId(bufferId)?.messageId ?: -1,
untilVisible = initial
) {
Throwable().printStackTrace()
requireActivity().runOnUiThread {
swipeRefreshLayout.isRefreshing = false
}
}
}
}
......
......@@ -30,19 +30,8 @@ class BacklogManager(
private val notificationManager: NotificationManager?,
private val backlogStorage: BacklogStorage
) : SyncableObject(session, "BacklogManager"), IBacklogManager {
override fun receiveBacklogFiltered(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
additional: Int, type: Int, flags: Int,
messages: QVariantList) {
val actualMessages = messages.mapNotNull { it.value<Message?>(null) }
notificationManager?.processMessages(
session, *actualMessages.toTypedArray()
)
}
override fun receiveBacklogAllFiltered(first: MsgId, last: MsgId, limit: Int, additional: Int,
type: Int, flags: Int, messages: QVariantList) {
// TODO: Not implemented
}
private val loading = mutableMapOf<BufferId, (List<Message>) -> Unit>()
private val loadingFiltered = mutableMapOf<BufferId, (List<Message>) -> Unit>()
init {
initialized = true
......@@ -50,14 +39,57 @@ class BacklogManager(
fun updateIgnoreRules() = backlogStorage.updateIgnoreRules(session)
fun requestBacklog(bufferId: BufferId, first: MsgId = -1, last: MsgId = -1, limit: Int = -1,
additional: Int = 0, callback: (List<Message>) -> Unit) {
if (loading.contains(bufferId)) return
loading[bufferId] = callback
requestBacklog(bufferId, first, last, limit, additional)
}
fun requestBacklogFiltered(bufferId: BufferId, first: MsgId = -1, last: MsgId = -1,
limit: Int = -1, additional: Int = 0, type: Int = -1, flags: Int = -1,
callback: (List<Message>) -> Unit) {
if (loadingFiltered.contains(bufferId)) return
loadingFiltered[bufferId] = callback
requestBacklogFiltered(bufferId, first, last, limit, additional, type, flags)
}
fun requestBacklogAll(first: MsgId = -1, last: MsgId = -1, limit: Int = -1, additional: Int = 0,
callback: (List<Message>) -> Unit) {
if (loading.contains(-1)) return
loading[-1] = callback
requestBacklogAll(first, last, limit, additional)
}
fun requestBacklogAllFiltered(first: MsgId = -1, last: MsgId = -1, limit: Int = -1,
additional: Int = 0, type: Int = -1, flags: Int = -1,
callback: (List<Message>) -> Unit) {
if (loading.contains(-1)) return
loadingFiltered[-1] = callback
requestBacklogAllFiltered(first, last, limit, additional, type, flags)
}
override fun receiveBacklog(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
additional: Int, messages: QVariantList) {
backlogStorage.storeMessages(session, messages.mapNotNull(QVariant_::value), initialLoad = true)
loading.remove(bufferId)?.invoke(messages.mapNotNull { it.value<Message?>(null) })
}
override fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int,
messages: QVariantList) {
backlogStorage.storeMessages(session, messages.mapNotNull(QVariant_::value), initialLoad = true)
loading.remove(-1)?.invoke(messages.mapNotNull { it.value<Message?>(null) })
}
override fun receiveBacklogFiltered(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
additional: Int, type: Int, flags: Int,
messages: QVariantList) {
loadingFiltered.remove(bufferId)?.invoke(messages.mapNotNull { it.value<Message?>(null) })
}
override fun receiveBacklogAllFiltered(first: MsgId, last: MsgId, limit: Int, additional: Int,
type: Int, flags: Int, messages: QVariantList) {
loadingFiltered.remove(-1)?.invoke(messages.mapNotNull { it.value<Message?>(null) })
}
fun removeBuffer(buffer: BufferId) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment