2020-06-17 19:18:31 +00:00
|
|
|
import QtQuick 2.13
|
|
|
|
import QtQuick.Controls 2.13
|
|
|
|
import QtQuick.Layouts 1.13
|
|
|
|
import QtQml.Models 2.13
|
2020-05-27 22:59:17 +00:00
|
|
|
import "../../../../shared"
|
|
|
|
import "../../../../imports"
|
2020-06-17 21:43:26 +00:00
|
|
|
import "../components"
|
2020-05-28 17:34:54 +00:00
|
|
|
import "./samples/"
|
2020-07-22 18:37:43 +00:00
|
|
|
import "./MessageComponents"
|
2020-05-27 22:59:17 +00:00
|
|
|
|
2020-05-28 22:22:51 +00:00
|
|
|
ScrollView {
|
2020-06-04 23:42:11 +00:00
|
|
|
id: scrollView
|
|
|
|
|
2020-05-28 17:34:54 +00:00
|
|
|
property var messageList: MessagesData {}
|
2020-07-10 15:37:23 +00:00
|
|
|
property var appSettings
|
2020-06-08 19:25:46 +00:00
|
|
|
property bool loadingMessages: false
|
2020-06-15 12:51:04 +00:00
|
|
|
property real scrollY: chatLogView.visibleArea.yPosition * chatLogView.contentHeight
|
2020-05-28 22:22:51 +00:00
|
|
|
|
2020-06-04 23:42:11 +00:00
|
|
|
contentItem: chatLogView
|
2020-05-27 22:59:17 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
|
|
|
|
2020-06-08 22:34:41 +00:00
|
|
|
ScrollBar.vertical.policy: chatLogView.contentHeight > chatLogView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
2020-05-28 22:22:51 +00:00
|
|
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
|
|
|
2020-06-04 23:42:11 +00:00
|
|
|
ListView {
|
2020-07-10 15:37:23 +00:00
|
|
|
id: chatLogView
|
2020-06-04 23:42:11 +00:00
|
|
|
anchors.fill: parent
|
2020-07-15 21:15:01 +00:00
|
|
|
anchors.bottomMargin: Style.current.bigPadding
|
2020-06-04 23:42:11 +00:00
|
|
|
spacing: 4
|
2020-06-15 12:51:04 +00:00
|
|
|
boundsBehavior: Flickable.StopAtBounds
|
2020-06-04 23:42:11 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
2020-06-08 19:25:46 +00:00
|
|
|
|
2020-07-22 17:46:17 +00:00
|
|
|
Timer {
|
|
|
|
id: timer
|
|
|
|
}
|
|
|
|
|
2020-07-22 18:37:43 +00:00
|
|
|
function scrollToBottom(force, caller) {
|
|
|
|
if (!force && !chatLogView.atYEnd) {
|
|
|
|
// User has scrolled up, we don't want to scroll back
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (caller) {
|
|
|
|
if (caller !== chatLogView.itemAtIndex(chatLogView.count - 1)) {
|
|
|
|
// If we have a caller, only accept its request if it's the last message
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Add a small delay because images, even though they say they say they are loaed, they aren't shown yet
|
|
|
|
timer.setTimeout(function() {
|
|
|
|
Qt.callLater(chatLogView.positionViewAtEnd)
|
|
|
|
}, 100);
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt.callLater(chatLogView.positionViewAtEnd)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
Connections {
|
2020-07-22 17:46:17 +00:00
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
target: chatsModel
|
|
|
|
onMessagesLoaded: {
|
|
|
|
loadingMessages = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
onActiveChannelChanged: {
|
2020-07-22 18:37:43 +00:00
|
|
|
chatLogView.scrollToBottom(true)
|
2020-06-05 22:20:45 +00:00
|
|
|
}
|
2020-06-08 19:25:46 +00:00
|
|
|
|
2020-07-22 15:12:24 +00:00
|
|
|
onSendingMessage: {
|
2020-07-23 16:23:20 +00:00
|
|
|
chatLogView.scrollToBottom(true)
|
2020-07-22 15:12:24 +00:00
|
|
|
}
|
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
onMessagePushed: {
|
2020-07-22 18:37:43 +00:00
|
|
|
chatLogView.scrollToBottom()
|
2020-06-08 19:25:46 +00:00
|
|
|
}
|
2020-07-10 21:47:31 +00:00
|
|
|
|
2020-07-22 17:46:17 +00:00
|
|
|
onAppReady: {
|
|
|
|
// Add an additionnal delay, since the app can be "ready" just milliseconds before the UI updated to show the chat
|
|
|
|
timer.setTimeout(function() {
|
2020-07-22 18:37:43 +00:00
|
|
|
chatLogView.scrollToBottom(true)
|
2020-07-22 17:46:17 +00:00
|
|
|
}, 500);
|
|
|
|
}
|
|
|
|
|
2020-07-10 21:47:31 +00:00
|
|
|
onMessageNotificationPushed: function(chatId, msg) {
|
|
|
|
notificationWindow.notifyUser(chatId, msg)
|
|
|
|
}
|
2020-06-04 19:07:07 +00:00
|
|
|
}
|
2020-06-08 19:25:46 +00:00
|
|
|
|
2020-07-22 15:12:24 +00:00
|
|
|
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
|
|
|
if(loadingMessages) return;
|
|
|
|
loadingMessages = true;
|
|
|
|
chatsModel.loadMoreMessages();
|
|
|
|
});
|
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
onContentYChanged: {
|
2020-07-22 15:12:24 +00:00
|
|
|
if(scrollY < 500){
|
|
|
|
loadMsgs();
|
2020-06-08 19:25:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-06-04 23:42:11 +00:00
|
|
|
model: messageListDelegate
|
2020-06-10 18:23:18 +00:00
|
|
|
section.property: "sectionIdentifier"
|
2020-06-05 22:20:45 +00:00
|
|
|
section.criteria: ViewSection.FullString
|
2020-06-04 23:42:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DelegateModel {
|
|
|
|
id: messageListDelegate
|
2020-06-05 22:20:45 +00:00
|
|
|
property var lessThan: [
|
2020-06-13 19:02:48 +00:00
|
|
|
function(left, right) { return left.clock < right.clock } // TODO: should be sorted by messageId
|
2020-06-05 22:20:45 +00:00
|
|
|
]
|
2020-05-28 22:22:51 +00:00
|
|
|
|
2020-06-05 22:20:45 +00:00
|
|
|
property int sortOrder: 0
|
|
|
|
onSortOrderChanged: items.setGroups(0, items.count, "unsorted")
|
2020-06-04 23:42:11 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2020-05-28 22:22:51 +00:00
|
|
|
}
|
2020-06-04 23:42:11 +00:00
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
|
2020-06-04 23:42:11 +00:00
|
|
|
items.includeByDefault: false
|
|
|
|
groups: DelegateModelGroup {
|
|
|
|
id: unsortedItems
|
|
|
|
name: "unsorted"
|
|
|
|
includeByDefault: true
|
|
|
|
onChanged: {
|
2020-06-05 22:20:45 +00:00
|
|
|
if (messageListDelegate.sortOrder == messageListDelegate.lessThan.length)
|
|
|
|
setGroups(0, count, "items")
|
|
|
|
else {
|
|
|
|
messageListDelegate.sort(messageListDelegate.lessThan[messageListDelegate.sortOrder])
|
|
|
|
}
|
2020-05-28 22:22:51 +00:00
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
2020-06-05 22:20:45 +00:00
|
|
|
model: messageList
|
2020-06-08 17:29:28 +00:00
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
ProfilePopup {
|
|
|
|
id: profilePopup
|
|
|
|
}
|
|
|
|
|
2020-07-12 01:03:39 +00:00
|
|
|
delegate: Message {
|
2020-06-05 22:20:45 +00:00
|
|
|
id: msgDelegate
|
2020-06-16 21:24:43 +00:00
|
|
|
fromAuthor: model.fromAuthor
|
2020-06-08 17:29:28 +00:00
|
|
|
chatId: model.chatId
|
2020-06-05 22:20:45 +00:00
|
|
|
userName: model.userName
|
|
|
|
message: model.message
|
2020-07-10 15:24:52 +00:00
|
|
|
plainText: model.plainText
|
2020-06-05 22:20:45 +00:00
|
|
|
identicon: model.identicon
|
|
|
|
isCurrentUser: model.isCurrentUser
|
|
|
|
timestamp: model.timestamp
|
|
|
|
sticker: model.sticker
|
|
|
|
contentType: model.contentType
|
2020-07-01 18:24:13 +00:00
|
|
|
outgoingStatus: model.outgoingStatus
|
2020-07-09 15:50:38 +00:00
|
|
|
responseTo: model.responseTo
|
2020-06-05 22:20:45 +00:00
|
|
|
authorCurrentMsg: msgDelegate.ListView.section
|
|
|
|
authorPrevMsg: msgDelegate.ListView.previousSection
|
2020-07-09 17:47:36 +00:00
|
|
|
profileClick: profilePopup.setPopupData.bind(profilePopup)
|
|
|
|
messageId: model.messageId
|
2020-07-12 01:03:39 +00:00
|
|
|
prevMessageIndex: {
|
|
|
|
// This is used in order to have access to the previous message and determine the timestamp
|
|
|
|
// we can't rely on the index because the sequence of messages is not ordered on the nim side
|
|
|
|
if(msgDelegate.DelegateModel.itemsIndex > 0){
|
|
|
|
return messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2020-07-10 15:37:23 +00:00
|
|
|
appSettings: scrollView.appSettings
|
2020-07-22 18:37:43 +00:00
|
|
|
scrollToBottom: chatLogView.scrollToBottom
|
2020-07-14 15:35:21 +00:00
|
|
|
timeout: model.timeout
|
2020-06-05 22:20:45 +00:00
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-28 15:55:52 +00:00
|
|
|
|
|
|
|
/*##^##
|
|
|
|
Designer {
|
|
|
|
D{i:0;autoSize:true;height:480;width:640}
|
|
|
|
}
|
|
|
|
##^##*/
|