Order the roomEvents models from newest to oldest

Qt somehow handles scrolling on new messages on its own when the
ListView direction is bottom to top.
In normal top to bottom, manual scrolling is completly buggy.
This commit is contained in:
miruka 2019-04-17 16:43:18 -04:00
parent 7e62da8733
commit f0dab1801a
6 changed files with 48 additions and 32 deletions

View File

@ -96,19 +96,17 @@ class SignalManager(QObject):
date_time = QDateTime.fromMSecsSinceEpoch(edict["server_timestamp"])
new_event = RoomEvent(type=etype, date_time=date_time, dict=edict)
# Insert event in model at the right position, based on timestamps
# to keep them sorted by date of arrival.
# Iterate in reverse, since a new event is more likely to be appended,
# but events can arrive out of order.
if not model or model[-1].date_time < new_event.date_time:
# Model is sorted from newest to oldest message
insert_at = None
for i, event in enumerate(model):
if new_event.date_time > event.date_time:
insert_at = i
break
if insert_at is None:
model.append(new_event)
else:
for i, event in enumerate(reversed(model)):
if event.date_time < new_event.date_time:
model.insert(-i, new_event)
break
else:
model.insert(0, new_event)
model.insert(insert_at, new_event)
def onRoomTypingUsersUpdated(

View File

@ -5,8 +5,8 @@ Base.HLabel {
text: date_time.toLocaleDateString()
width: rootCol.width
horizontalAlignment: Text.AlignHCenter
topPadding: rootCol.isFirstMessage ? 0 : rootCol.verticalPadding * 4
bottomPadding: rootCol.verticalPadding * 2
topPadding: rootCol.isFirstMessage ? 0 : rootCol.standardSpacing
bottomPadding: rootCol.standardSpacing
font.pixelSize: normalSize * 1.1
color: "darkolivegreen"
}

View File

@ -50,6 +50,7 @@ Row {
leftPadding: horizontalPadding
rightPadding: horizontalPadding
topPadding: nameLabel.visible ? 0 : verticalPadding
bottomPadding: verticalPadding
Layout.minimumWidth: nameLabel.implicitWidth

View File

@ -4,13 +4,20 @@ import QtQuick.Layouts 1.4
import "../base" as Base
Column {
id: rootCol
id: "rootCol"
function mins_between(date1, date2) {
console.log(Math.round((((date2 - date1) % 86400000) % 3600000) / 60000))
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
}
readonly property bool isMessage: type.startsWith("RoomMessage")
function is_message(type_) { return type_.startsWith("RoomMessage") }
readonly property var previousItem:
index < messageListView.model.count - 1 ?
messageListView.model.get(index + 1) : null
readonly property bool isMessage: is_message(type)
readonly property bool isUndecryptableEvent:
type === "OlmEvent" || type === "MegolmEvent"
@ -21,37 +28,38 @@ Column {
readonly property bool isOwn:
chatPage.user_id === dict.sender
readonly property var previousData:
index > 0 ? messageListView.model.get(index - 1) : null
readonly property bool isFirstMessage: ! previousData
readonly property bool isFirstMessage: ! previousItem
readonly property bool combine:
! isFirstMessage &&
previousData.isMessage === isMessage &&
previousData.dict.sender === dict.sender &&
mins_between(previousData.date_time, date_time) <= 5
! talkBreak &&
! dayBreak &&
is_message(previousItem.type) === isMessage &&
previousItem.dict.sender === dict.sender &&
mins_between(previousItem.date_time, date_time) <= 5
readonly property bool dayBreak:
isFirstMessage ||
previousData.date_time.getDay() != date_time.getDay()
date_time.getDay() != previousItem.date_time.getDay()
readonly property bool talkBreak:
! isFirstMessage &&
! dayBreak &&
mins_between(previousData.date_time, date_time) >= 20
mins_between(previousItem.date_time, date_time) >= 20
property int standardSpacing: 8
property int standardSpacing: 16
property int horizontalPadding: 7
property int verticalPadding: 5
width: parent.width
topPadding:
previousData === null ? 0 :
talkBreak ? standardSpacing * 6 :
combine ? standardSpacing / 2 :
standardSpacing * 1.2
! previousItem ? 0 :
talkBreak ? standardSpacing * 3 :
combine ? standardSpacing / 4 :
standardSpacing
//Text { text: rootCol.topPadding }
Daybreak { visible: dayBreak }

View File

@ -13,18 +13,27 @@ Rectangle {
ListView {
id: messageListView
anchors.fill: parent
model: Backend.models.roomEvents.get(chatPage.room.room_id)
delegate: MessageDelegate {}
model: Backend.models.roomEvents.get(chatPage.room.room_id)
//highlight: Rectangle {color: "lightsteelblue"; radius: 5}
clip: true
topMargin: space
bottomMargin: space
verticalLayoutDirection: ListView.BottomToTop
// Keep x scroll pages cached, to limit images having to be
// reloaded from network.
cacheBuffer: height * 6
//Component.onCompleted: positionViewAtEnd()
function goToEnd() {
messageListView.positionViewAtEnd()
//messageListView.flick(0, -messageListView.bottomMargin * 100)
}
//Connections {
//target: messageListView.model
//onChanged: goToEnd()
//}
}
}

View File

@ -4,7 +4,7 @@
function get_last_room_event_text(room_id) {
var eventsModel = Backend.models.roomEvents.get(room_id)
for (var i = -1; i >= -eventsModel.count; i--) {
for (var i = 0; i < eventsModel.count; i++) {
var ev = eventsModel.get(i)
if (ev.type !== "RoomMemberEvent") {