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

Demo: Allow jumping to arbitrary points in the chat history, and load

properly in both directions
parent b9b43664
No related branches found
No related tags found
1 merge request!2Draft: Jetpack compose rewrite
Pipeline #564 passed
...@@ -29,6 +29,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG ...@@ -29,6 +29,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
import de.kuschku.libquassel.util.helper.value import de.kuschku.libquassel.util.helper.value
import de.kuschku.quasseldroid.persistence.dao.findById import de.kuschku.quasseldroid.persistence.dao.findById
import de.kuschku.quasseldroid.persistence.dao.findFirstByBufferId import de.kuschku.quasseldroid.persistence.dao.findFirstByBufferId
import de.kuschku.quasseldroid.persistence.dao.findLastByBufferId
import de.kuschku.quasseldroid.persistence.dao.get import de.kuschku.quasseldroid.persistence.dao.get
import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.AccountDatabase
import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase
...@@ -41,13 +42,13 @@ class BacklogRequester( ...@@ -41,13 +42,13 @@ class BacklogRequester(
private val database: QuasselDatabase, private val database: QuasselDatabase,
private val accountDatabase: AccountDatabase private val accountDatabase: AccountDatabase
) { ) {
fun loadMore(accountId: AccountId, buffer: BufferId, amount: Int, pageSize: Int, fun loadMoreBefore(accountId: AccountId, buffer: BufferId, amount: Int, pageSize: Int,
lastMessageId: MsgId? = null, lastMessageId: MsgId? = null,
untilAllVisible: Boolean = false, untilAllVisible: Boolean = false,
finishCallback: () -> Unit) { finishCallback: () -> Unit) {
log(DEBUG, log(DEBUG,
"BacklogRequester", "BacklogRequester",
"requested(bufferId: $buffer, amount: $amount, pageSize: $pageSize, lastMessageId: $lastMessageId, untilAllVisible: $untilAllVisible)") "requestedBefore(bufferId: $buffer, amount: $amount, pageSize: $pageSize, lastMessageId: $lastMessageId, untilAllVisible: $untilAllVisible)")
var missing = amount var missing = amount
session.value?.orNull()?.let { session: ISession -> session.value?.orNull()?.let { session: ISession ->
session.backlogManager.let { session.backlogManager.let {
...@@ -56,14 +57,26 @@ class BacklogRequester( ...@@ -56,14 +57,26 @@ class BacklogRequester(
buffer, buffer,
accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0 accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0
) )
val msgId = lastMessageId
?: database.message().findFirstByBufferId(buffer)?.messageId
?: MsgId(-1)
log(DEBUG,
"BacklogRequester",
"requestBefore(bufferId: $buffer, first: -1, last: $msgId, limit: $amount)")
it.requestBacklog( it.requestBacklog(
bufferId = buffer, bufferId = buffer,
last = lastMessageId last = msgId,
?: database.message().findFirstByBufferId(buffer)?.messageId
?: MsgId(-1),
limit = amount limit = amount
) { ) {
if (it.isNotEmpty()) { val min = it.asSequence().map(Message::messageId).min()
val max = it.asSequence().map(Message::messageId).max()
log(DEBUG,
"BacklogRequester",
"receivedBefore(bufferId: $buffer, [$min-$max])")
if (min == max) {
// Do not change stored messages if we only got back one message
false
} else if (it.isNotEmpty()) {
missing -= it.count { missing -= it.count {
(it.type.value and filtered.toUInt().inv()) != 0u && (it.type.value and filtered.toUInt().inv()) != 0u &&
!QuasselBacklogStorage.isIgnored(session, it) !QuasselBacklogStorage.isIgnored(session, it)
...@@ -72,7 +85,70 @@ class BacklogRequester( ...@@ -72,7 +85,70 @@ class BacklogRequester(
val hasLoadedAny = missing < amount val hasLoadedAny = missing < amount
if (untilAllVisible && !hasLoadedAll || !untilAllVisible && !hasLoadedAny) { if (untilAllVisible && !hasLoadedAll || !untilAllVisible && !hasLoadedAny) {
val messageId = it.map(Message::messageId).min() val messageId = it.map(Message::messageId).min()
loadMore(accountId, loadMoreBefore(accountId,
buffer,
missing,
pageSize,
messageId,
untilAllVisible,
finishCallback)
true
} else {
finishCallback()
true
}
} else {
finishCallback()
true
}
}
}
}
}
fun loadMoreAfter(accountId: AccountId, buffer: BufferId, amount: Int, pageSize: Int,
lastMessageId: MsgId? = null,
untilAllVisible: Boolean = false,
finishCallback: () -> Unit) {
log(DEBUG,
"BacklogRequester",
"loadMoreAfter(bufferId: $buffer, amount: $amount, pageSize: $pageSize, lastMessageId: $lastMessageId, untilAllVisible: $untilAllVisible)")
var missing = amount
session.value?.orNull()?.let { session: ISession ->
session.backlogManager.let {
val filtered = database.filtered().get(
accountId,
buffer,
accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0
)
val msgId = lastMessageId
?: database.message().findLastByBufferId(buffer)?.messageId
?: MsgId(0)
log(DEBUG,
"BacklogRequester",
"requestAfter(bufferId: $buffer, first: $msgId, last: -1, limit: $amount)")
it.requestBacklogForward(
bufferId = buffer,
first = msgId,
limit = amount
) {
val min = it.asSequence().map(Message::messageId).min()
val max = it.asSequence().map(Message::messageId).max()
log(DEBUG,
"BacklogRequester",
"receivedAfter(bufferId: $buffer, [$min-$max])")
if (min == max) {
// Do not change stored messages if we only got back one message
false
} else if (it.isNotEmpty()) {
missing -= it.count {
(it.type.value and filtered.toUInt().inv()) != 0u &&
!QuasselBacklogStorage.isIgnored(session, it)
}
val hasLoadedAll = missing == 0
val hasLoadedAny = missing < amount
if (untilAllVisible && !hasLoadedAll || !untilAllVisible && !hasLoadedAny) {
val messageId = it.map(Message::messageId).max()
loadMoreAfter(accountId,
buffer, buffer,
missing, missing,
pageSize, pageSize,
......
...@@ -45,6 +45,8 @@ import de.kuschku.libquassel.protocol.* ...@@ -45,6 +45,8 @@ import de.kuschku.libquassel.protocol.*
import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.BufferInfo
import de.kuschku.libquassel.quassel.syncables.BufferSyncer import de.kuschku.libquassel.quassel.syncables.BufferSyncer
import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.session.SessionManager
import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.flag.hasFlag
import de.kuschku.libquassel.util.helper.* import de.kuschku.libquassel.util.helper.*
import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.libquassel.util.irc.HostmaskHelper
...@@ -77,6 +79,9 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -77,6 +79,9 @@ class MessageListFragment : ServiceBoundFragment() {
@BindView(R.id.messages) @BindView(R.id.messages)
lateinit var messageList: RecyclerView lateinit var messageList: RecyclerView
@BindView(R.id.scrollUp)
lateinit var scrollUp: FloatingActionButton
@BindView(R.id.scrollDown) @BindView(R.id.scrollDown)
lateinit var scrollDown: FloatingActionButton lateinit var scrollDown: FloatingActionButton
...@@ -119,7 +124,8 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -119,7 +124,8 @@ class MessageListFragment : ServiceBoundFragment() {
private var lastBuffer: BufferId? = null private var lastBuffer: BufferId? = null
private var previousMessageId: MsgId? = null private var previousMessageId: MsgId? = null
private var previousLoadKey: Int? = null private var previousLoadKey: MsgId_Type? = null
private var reverse: Boolean = false
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
...@@ -230,9 +236,15 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -230,9 +236,15 @@ class MessageListFragment : ServiceBoundFragment() {
} }
private val boundaryCallback = object : PagedList.BoundaryCallback<DisplayMessage>() { private val boundaryCallback = object : PagedList.BoundaryCallback<DisplayMessage>() {
override fun onItemAtFrontLoaded(itemAtFront: DisplayMessage) = Unit override fun onItemAtFrontLoaded(itemAtFront: DisplayMessage) {
val id = itemAtFront.tag.id
log(DEBUG, "MessageListFragment", "onItemAtFrontLoaded: $id")
loadMore(reverse = true, lastMessageId = id)
}
override fun onItemAtEndLoaded(itemAtEnd: DisplayMessage) { override fun onItemAtEndLoaded(itemAtEnd: DisplayMessage) {
loadMore() val id = itemAtEnd.tag.id
log(DEBUG, "MessageListFragment", "onItemAtEndLoaded: $id")
loadMore(reverse = false, lastMessageId = id)
} }
} }
...@@ -327,6 +339,11 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -327,6 +339,11 @@ class MessageListFragment : ServiceBoundFragment() {
val isScrollingDown = dy > 0 val isScrollingDown = dy > 0
scrollDown.toggle(canScrollDown && isScrollingDown) scrollDown.toggle(canScrollDown && isScrollingDown)
val canScrollUp = recyclerView.canScrollVertically(-1)
val isScrollingUp = dy < 0
scrollUp.toggle(canScrollUp && isScrollingUp)
} }
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
...@@ -396,7 +413,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -396,7 +413,7 @@ class MessageListFragment : ServiceBoundFragment() {
.setEnablePlaceholders(true) .setEnablePlaceholders(true)
.build() .build()
).setBoundaryCallback(boundaryCallback) ).setBoundaryCallback(boundaryCallback)
.setInitialLoadKey(previousLoadKey) .setInitialLoadKey(previousLoadKey?.toInt())
.build() .build()
} }
} }
...@@ -461,7 +478,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -461,7 +478,7 @@ class MessageListFragment : ServiceBoundFragment() {
var hasLoaded = false var hasLoaded = false
fun checkScroll() { fun checkScroll() {
if (hasLoaded) { if (hasLoaded) {
if (linearLayoutManager.findFirstVisibleItemPosition() < 2 && !isScrolling) { if (!reverse && linearLayoutManager.findFirstVisibleItemPosition() < 2 && !isScrolling) {
messageList.scrollToPosition(0) messageList.scrollToPosition(0)
} }
} else { } else {
...@@ -483,7 +500,12 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -483,7 +500,12 @@ class MessageListFragment : ServiceBoundFragment() {
(fab as View).visibility = View.VISIBLE (fab as View).visibility = View.VISIBLE
} }
}) })
scrollDown.setOnClickListener { messageList.scrollToPosition(0) } scrollDown.setOnClickListener {
jumpTo(false)
}
scrollUp.setOnClickListener {
jumpTo(true)
}
val avatarSize = TypedValue.applyDimension( val avatarSize = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, TypedValue.COMPLEX_UNIT_SP,
...@@ -512,12 +534,12 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -512,12 +534,12 @@ class MessageListFragment : ServiceBoundFragment() {
savedInstanceState?.run { savedInstanceState?.run {
(messageList.layoutManager as RecyclerView.LayoutManager).onRestoreInstanceState(getParcelable( (messageList.layoutManager as RecyclerView.LayoutManager).onRestoreInstanceState(getParcelable(
KEY_STATE_LIST)) KEY_STATE_LIST))
previousLoadKey = getInt(KEY_STATE_PAGING).nullIf { it == -1 } previousLoadKey = getLong(KEY_STATE_PAGING).nullIf { it == -1L }
lastBuffer = BufferId(getInt(KEY_STATE_BUFFER)).nullIf { !it.isValidId() } lastBuffer = BufferId(getInt(KEY_STATE_BUFFER)).nullIf { !it.isValidId() }
} }
data.observe(viewLifecycleOwner, Observer { list -> data.observe(viewLifecycleOwner, Observer { list ->
previousLoadKey = list?.lastKey as? Int previousLoadKey = (list?.lastKey as? Int)?.toLong()
val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
val firstVisibleMessageId = adapter[firstVisibleItemPosition]?.content?.messageId val firstVisibleMessageId = adapter[firstVisibleItemPosition]?.content?.messageId
runInBackground { runInBackground {
...@@ -534,6 +556,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -534,6 +556,7 @@ class MessageListFragment : ServiceBoundFragment() {
type = Buffer_Type.of(Buffer_Type.StatusBuffer) type = Buffer_Type.of(Buffer_Type.StatusBuffer)
)?.bufferId ?: BufferId(0) )?.bufferId ?: BufferId(0)
if (buffer != lastBuffer) { if (buffer != lastBuffer) {
reverse = false
adapter.clearCache() adapter.clearCache()
modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer ->
onBufferChange(lastBuffer, onBufferChange(lastBuffer,
...@@ -552,10 +575,26 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -552,10 +575,26 @@ class MessageListFragment : ServiceBoundFragment() {
return view return view
} }
private fun jumpTo(start: Boolean) {
reverse = start
runInBackground {
modelHelper.chat.bufferId { bufferId ->
//if (database.message().find(msg.id) == null) {
database.message().clearMessages(bufferId.id)
//}
if (start) {
loadMore(initial = true, reverse = true, lastMessageId = MsgId(0L))
} else {
loadMore(initial = true, reverse = false, lastMessageId = MsgId(-1L))
}
}
}
}
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
outState.putParcelable(KEY_STATE_LIST, messageList.layoutManager?.onSaveInstanceState()) outState.putParcelable(KEY_STATE_LIST, messageList.layoutManager?.onSaveInstanceState())
outState.putInt(KEY_STATE_PAGING, previousLoadKey ?: -1) outState.putLong(KEY_STATE_PAGING, previousLoadKey ?: -1L)
outState.putInt(KEY_STATE_BUFFER, lastBuffer?.id ?: -1) outState.putInt(KEY_STATE_BUFFER, lastBuffer?.id ?: -1)
} }
...@@ -607,14 +646,30 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -607,14 +646,30 @@ class MessageListFragment : ServiceBoundFragment() {
super.onPause() super.onPause()
} }
private fun loadMore(initial: Boolean = false, lastMessageId: MsgId? = null) { private fun loadMore(initial: Boolean = false, lastMessageId: MsgId? = null, reverse: Boolean = this.reverse) {
// This can be called *after* we’re already detached from the activity // This can be called *after* we’re already detached from the activity
activity?.runOnUiThread { activity?.runOnUiThread {
modelHelper.chat.bufferId { bufferId -> modelHelper.chat.bufferId { bufferId ->
if (bufferId.isValidId() && bufferId != BufferId.MAX_VALUE) { if (bufferId.isValidId() && bufferId != BufferId.MAX_VALUE) {
if (initial) swipeRefreshLayout.isRefreshing = true if (initial) swipeRefreshLayout.isRefreshing = true
runInBackground { runInBackground {
backlogRequester.loadMore( if (reverse) {
backlogRequester.loadMoreAfter(
accountId = accountId,
buffer = bufferId,
amount = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize,
pageSize = backlogSettings.pageSize,
lastMessageId = lastMessageId
?: database.message().findLastByBufferId(bufferId)?.messageId
?: MsgId(0),
untilAllVisible = initial
) {
activity?.runOnUiThread {
swipeRefreshLayout.isRefreshing = false
}
}
} else {
backlogRequester.loadMoreBefore(
accountId = accountId, accountId = accountId,
buffer = bufferId, buffer = bufferId,
amount = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize, amount = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize,
...@@ -633,6 +688,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -633,6 +688,7 @@ class MessageListFragment : ServiceBoundFragment() {
} }
} }
} }
}
companion object { companion object {
private const val KEY_STATE_LIST = "KEY_STATE_LIST" private const val KEY_STATE_LIST = "KEY_STATE_LIST"
......
<!--
Quasseldroid - Quassel client for Android
Copyright (c) 2020 Janne Mareike Koschinski
Copyright (c) 2020 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/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M7.41,18.41L6,17L12,11L18,17L16.59,18.41L12,13.83L7.41,18.41M7.41,12.41L6,11L12,5L18,11L16.59,12.41L12,7.83L7.41,12.41Z" />
</vector>
...@@ -39,14 +39,30 @@ ...@@ -39,14 +39,30 @@
tools:listitem="@layout/widget_chatmessage_plain" /> tools:listitem="@layout/widget_chatmessage_plain" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="end|bottom"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/scrollUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="@color/colorFillDark"
android:visibility="gone"
app:backgroundTint="#8A808080"
app:elevation="0dip"
app:fabSize="mini"
app:pressedTranslationZ="0dip"
app:srcCompat="@drawable/ic_scroll_up" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/scrollDown" android:id="@+id/scrollDown"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:tint="@color/colorFillDark" android:tint="@color/colorFillDark"
android:visibility="gone" android:visibility="gone"
app:backgroundTint="#8A808080" app:backgroundTint="#8A808080"
...@@ -55,4 +71,6 @@ ...@@ -55,4 +71,6 @@
app:pressedTranslationZ="0dip" app:pressedTranslationZ="0dip"
app:srcCompat="@drawable/ic_scroll_down" /> app:srcCompat="@drawable/ic_scroll_down" />
</LinearLayout>
</FrameLayout> </FrameLayout>
...@@ -32,6 +32,7 @@ class BacklogManager( ...@@ -32,6 +32,7 @@ class BacklogManager(
) : SyncableObject(session.proxy, "BacklogManager"), IBacklogManager { ) : SyncableObject(session.proxy, "BacklogManager"), IBacklogManager {
private val loading = mutableMapOf<BufferId, (List<Message>) -> Boolean>() private val loading = mutableMapOf<BufferId, (List<Message>) -> Boolean>()
private val loadingFiltered = mutableMapOf<BufferId, (List<Message>) -> Boolean>() private val loadingFiltered = mutableMapOf<BufferId, (List<Message>) -> Boolean>()
private val loadingForward = mutableMapOf<BufferId, (List<Message>) -> Boolean>()
override fun deinit() { override fun deinit() {
super.deinit() super.deinit()
...@@ -60,6 +61,15 @@ class BacklogManager( ...@@ -60,6 +61,15 @@ class BacklogManager(
requestBacklogFiltered(bufferId, first, last, limit, additional, type, flags) requestBacklogFiltered(bufferId, first, last, limit, additional, type, flags)
} }
fun requestBacklogForward(bufferId: BufferId, first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1), limit: Int = -1,
type: Int = 0, flags: Int = 0,
callback: (List<Message>) -> Boolean) {
if (loadingForward.contains(bufferId)) return
loadingForward[bufferId] = callback
requestBacklogForward(bufferId, first, last, limit, type, flags)
}
fun requestBacklogAll(first: MsgId = MsgId(-1), last: MsgId = MsgId(-1), limit: Int = -1, fun requestBacklogAll(first: MsgId = MsgId(-1), last: MsgId = MsgId(-1), limit: Int = -1,
additional: Int = 0, callback: (List<Message>) -> Boolean) { additional: Int = 0, callback: (List<Message>) -> Boolean) {
if (loading.contains(BufferId(-1))) return if (loading.contains(BufferId(-1))) return
...@@ -103,6 +113,16 @@ class BacklogManager( ...@@ -103,6 +113,16 @@ class BacklogManager(
} }
} }
override fun receiveBacklogForward(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
type: Int, flags: Int,
messages: QVariantList) {
val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
if (loadingForward.remove(bufferId)?.invoke(list) != false) {
log(DEBUG, "BacklogManager", "storeMessages(${list.size})")
backlogStorage?.storeMessages(session, list)
}
}
override fun receiveBacklogAllFiltered(first: MsgId, last: MsgId, limit: Int, additional: Int, override fun receiveBacklogAllFiltered(first: MsgId, last: MsgId, limit: Int, additional: Int,
type: Int, flags: Int, messages: QVariantList) { type: Int, flags: Int, messages: QVariantList) {
val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value) val list = messages.mapNotNull<QVariant_, Message>(QVariant_::value)
......
...@@ -46,6 +46,17 @@ interface IBacklogManager : ISyncableObject { ...@@ -46,6 +46,17 @@ interface IBacklogManager : ISyncableObject {
) )
} }
@Slot
fun requestBacklogForward(bufferId: BufferId, first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1), limit: Int = -1,
type: Int = -1, flags: Int = -1) {
REQUEST(
"requestBacklogForward", ARG(bufferId, QType.BufferId), ARG(first, QType.MsgId),
ARG(last, QType.MsgId), ARG(limit, Type.Int), ARG(type, Type.Int),
ARG(flags, Type.Int)
)
}
@Slot @Slot
fun requestBacklogAll(first: MsgId = MsgId(-1), last: MsgId = MsgId(-1), limit: Int = -1, fun requestBacklogAll(first: MsgId = MsgId(-1), last: MsgId = MsgId(-1), limit: Int = -1,
additional: Int = 0) { additional: Int = 0) {
...@@ -73,6 +84,10 @@ interface IBacklogManager : ISyncableObject { ...@@ -73,6 +84,10 @@ interface IBacklogManager : ISyncableObject {
fun receiveBacklogFiltered(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int, fun receiveBacklogFiltered(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
additional: Int, type: Int, flags: Int, messages: QVariantList) additional: Int, type: Int, flags: Int, messages: QVariantList)
@Slot
fun receiveBacklogForward(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int,
type: Int, flags: Int, messages: QVariantList)
@Slot @Slot
fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int, fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int,
messages: QVariantList) messages: QVariantList)
......
...@@ -48,6 +48,8 @@ open class ChatViewModel : QuasselViewModel() { ...@@ -48,6 +48,8 @@ open class ChatViewModel : QuasselViewModel() {
val stateReset = BehaviorSubject.create<Unit>() val stateReset = BehaviorSubject.create<Unit>()
val bufferOpened = PublishSubject.create<Unit>() val bufferOpened = PublishSubject.create<Unit>()
val loadKey = BehaviorSubject.create<MsgId>()
fun onSaveInstanceState(outState: Bundle) { fun onSaveInstanceState(outState: Bundle) {
/* /*
outState.putSerializable( outState.putSerializable(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment