Improve room past events loading
- Trigger when room is shown if there's not enough messages to fill the list height - Trigger whenever user is scrolling before a certain point, instead of when dragging is released/scrolling stopped and the top edge is hit - Prevent multiple load requests at same time - Keep a set of fully loaded rooms, don't request anymore history if a room is fully loaded
This commit is contained in:
parent
a0f9acddaa
commit
6ab4acdc84
4
TODO.md
4
TODO.md
|
@ -30,3 +30,7 @@
|
|||
- Push instead of replacing in stack view
|
||||
|
||||
- QQuickImageProvider, matrix preview API
|
||||
|
||||
- Spinner when loading past room events or images
|
||||
|
||||
- nio: org.matrix.room.preview\_urls, m.room.aliases
|
||||
|
|
|
@ -2,20 +2,21 @@
|
|||
# This file is part of harmonyqml, licensed under GPLv3.
|
||||
|
||||
import hashlib
|
||||
from typing import Dict
|
||||
from typing import Dict, Set
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot
|
||||
|
||||
from .client_manager import ClientManager
|
||||
from .html_filter import HtmlFilter
|
||||
from .model.items import User
|
||||
from .model.qml_models import QMLModels
|
||||
from .html_filter import HtmlFilter
|
||||
|
||||
|
||||
class Backend(QObject):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.past_tokens: Dict[str, str] = {}
|
||||
self.fully_loaded_rooms: Set[str] = set()
|
||||
|
||||
self._client_manager: ClientManager = ClientManager()
|
||||
self._models: QMLModels = QMLModels()
|
||||
|
@ -61,13 +62,19 @@ class Backend(QObject):
|
|||
|
||||
|
||||
@pyqtSlot(str)
|
||||
def loadPastEvents(self, room_id: str) -> None:
|
||||
@pyqtSlot(str, int)
|
||||
def loadPastEvents(self, room_id: str, limit: int = 100) -> None:
|
||||
if not room_id in self.past_tokens:
|
||||
return # Initial sync not done yet
|
||||
|
||||
if room_id in self.fully_loaded_rooms:
|
||||
return
|
||||
|
||||
for client in self.clientManager.clients.values():
|
||||
if room_id in client.nio.rooms:
|
||||
client.loadPastEvents(room_id, self.past_tokens[room_id])
|
||||
client.loadPastEvents(
|
||||
room_id, self.past_tokens[room_id], limit
|
||||
)
|
||||
break
|
||||
else:
|
||||
raise ValueError(f"Room not found in any client: {room_id}")
|
||||
|
|
|
@ -69,6 +69,8 @@ class Client(QObject):
|
|||
self.net = NetworkManager(self.host, self.port, self.nio)
|
||||
self.net_sync = NetworkManager(self.host, self.port, self.nio_sync)
|
||||
|
||||
self._loading: bool = False
|
||||
|
||||
self._stop_sync: Event = Event()
|
||||
|
||||
|
||||
|
@ -157,14 +159,22 @@ class Client(QObject):
|
|||
|
||||
|
||||
@futurize
|
||||
def loadPastEvents(self, room_id: str, start_token: str) -> None:
|
||||
def loadPastEvents(self, room_id: str, start_token: str, limit: int = 100
|
||||
) -> None:
|
||||
# From QML, use Backend.loastPastEvents instead
|
||||
|
||||
if self._loading:
|
||||
return
|
||||
self._loading = True
|
||||
|
||||
print("load", limit)
|
||||
self._on_past_events(
|
||||
room_id,
|
||||
self.net.talk(
|
||||
self.nio.room_messages, room_id, start=start_token, limit=100
|
||||
self.nio.room_messages, room_id, start=start_token, limit=limit
|
||||
)
|
||||
)
|
||||
self._loading = False
|
||||
|
||||
|
||||
def _on_past_events(self, room_id: str, response: nr.RoomMessagesResponse
|
||||
|
|
|
@ -93,6 +93,9 @@ class SignalManager(QObject):
|
|||
self, _: Client, room_id: str, token: str
|
||||
) -> None:
|
||||
|
||||
if self.backend.past_tokens[room_id] == token:
|
||||
self.backend.fully_loaded_rooms.add(room_id)
|
||||
|
||||
self.backend.past_tokens[room_id] = token
|
||||
|
||||
|
||||
|
|
|
@ -26,8 +26,14 @@ Rectangle {
|
|||
// reloaded from network.
|
||||
cacheBuffer: height * 6
|
||||
|
||||
onMovementEnded: if (atYBeginning) {
|
||||
// Declaring this "alias" provides the on... signal
|
||||
property real yPos: visibleArea.yPosition
|
||||
|
||||
onYPosChanged: {
|
||||
console.log(yPos)
|
||||
if (yPos <= 0.1) {
|
||||
Backend.loadPastEvents(chatPage.room.room_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user