fix: show new messages at the bottom
This commit is contained in:
parent
722ab36bf1
commit
1b086b006d
|
@ -1,27 +1,45 @@
|
|||
import QtQuick 2.14
|
||||
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Controls 2.14 as QQC2
|
||||
import QtQuick.Layouts 1.3
|
||||
import Qt.labs.platform 1.1
|
||||
import QtQml.Models 2.3
|
||||
import "../../../../shared"
|
||||
import "../../../../imports"
|
||||
import "./samples/"
|
||||
|
||||
ScrollView {
|
||||
id: scrollView
|
||||
|
||||
property var messageList: MessagesData {}
|
||||
|
||||
contentItem: chatLogView
|
||||
anchors.fill: parent
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
ScrollBar.vertical.policy: chatLogView.contentHeight > chatLogView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
|
||||
SortFilterModel {
|
||||
id: messageListDelegate
|
||||
lessThan: function(left, right) {
|
||||
return left.clock < right.clock;
|
||||
function scrollToBottom(goToBottom) {
|
||||
chatLogView.positionViewAtEnd();
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
id: chatLogView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
onCountChanged: {
|
||||
scrollToBottom();
|
||||
}
|
||||
model: messageListDelegate
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: messageListDelegate
|
||||
model: messageList
|
||||
delegate: Message {
|
||||
userName: model.userName
|
||||
|
@ -33,29 +51,47 @@ ScrollView {
|
|||
sticker: model.sticker
|
||||
contentType: model.contentType
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
id: chatLogView
|
||||
model: messageListDelegate
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightFollowsCurrentItem: true
|
||||
onCountChanged: {
|
||||
if (!this.atYEnd) {
|
||||
// User has scrolled up, we don't want to scroll back
|
||||
return
|
||||
property var lessThan: function(left, right) { return left.clock < right.clock }
|
||||
|
||||
function insertPosition(lessThan, item) {
|
||||
var lower = 0
|
||||
var upper = items.count
|
||||
while (lower < upper) {
|
||||
var middle = Math.floor(lower + (upper - lower) / 2)
|
||||
var result = lessThan(item.model, items.get(middle).model);
|
||||
if (result) {
|
||||
upper = middle
|
||||
} else {
|
||||
lower = middle + 1
|
||||
}
|
||||
}
|
||||
return lower
|
||||
}
|
||||
|
||||
// positionViewAtEnd doesn't work well. Instead, we use highlightFollowsCurrentItem
|
||||
// and set the current Item/Index to the latest item
|
||||
while (this.currentIndex < this.count - 1) {
|
||||
this.incrementCurrentIndex()
|
||||
function sort(lessThan) {
|
||||
while (unsortedItems.count > 0) {
|
||||
var item = unsortedItems.get(0)
|
||||
var index = insertPosition(lessThan, item)
|
||||
|
||||
item.groups = "items"
|
||||
items.move(item.itemsIndex, index)
|
||||
}
|
||||
}
|
||||
|
||||
items.includeByDefault: false
|
||||
|
||||
groups: DelegateModelGroup {
|
||||
id: unsortedItems
|
||||
name: "unsorted"
|
||||
includeByDefault: true
|
||||
onChanged: {
|
||||
messageListDelegate.sort(messageListDelegate.lessThan)
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*##^##
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
import QtQuick 2.9
|
||||
import QtQml.Models 2.3
|
||||
|
||||
// https://martin.rpdev.net/2019/01/15/using-delegatemodel-in-qml-for-sorting-and-filtering.html
|
||||
|
||||
DelegateModel {
|
||||
id: delegateModel
|
||||
|
||||
property var lessThan: function(left, right) { return true; }
|
||||
property var filterAcceptsItem: function(item) { return true; }
|
||||
|
||||
function update() {
|
||||
if (items.count > 0) {
|
||||
items.setGroups(0, items.count, "items");
|
||||
}
|
||||
|
||||
// Step 1: Filter items
|
||||
var visible = [];
|
||||
for (var i = 0; i < items.count; ++i) {
|
||||
var item = items.get(i);
|
||||
if (filterAcceptsItem(item.model)) {
|
||||
visible.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Sort the list of visible items
|
||||
visible.sort(function(a, b) {
|
||||
return lessThan(a.model, b.model) ? -1 : 1;
|
||||
});
|
||||
|
||||
// Step 3: Add all items to the visible group:
|
||||
for (i = 0; i < visible.length; ++i) {
|
||||
item = visible[i];
|
||||
item.inVisible = true;
|
||||
if (item.visibleIndex !== i) {
|
||||
visibleItems.move(item.visibleIndex, i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items.onChanged: update()
|
||||
onLessThanChanged: update()
|
||||
onFilterAcceptsItemChanged: update()
|
||||
|
||||
groups: DelegateModelGroup {
|
||||
id: visibleItems
|
||||
|
||||
name: "visible"
|
||||
includeByDefault: false
|
||||
}
|
||||
|
||||
filterOnGroup: "visible"
|
||||
}
|
Loading…
Reference in New Issue