2020-06-17 19:18:31 +00:00
|
|
|
|
import QtQuick 2.13
|
2020-12-07 17:37:39 +00:00
|
|
|
|
import Qt.labs.platform 1.1
|
2020-06-17 19:18:31 +00:00
|
|
|
|
import QtQuick.Controls 2.13
|
2020-11-20 17:39:14 +00:00
|
|
|
|
import QtQuick.Window 2.13
|
2020-06-17 19:18:31 +00:00
|
|
|
|
import QtQuick.Layouts 1.13
|
|
|
|
|
import QtQml.Models 2.13
|
2020-09-24 15:05:17 +00:00
|
|
|
|
import QtGraphicalEffects 1.13
|
2020-11-30 21:24:01 +00:00
|
|
|
|
import QtQuick.Dialogs 1.3
|
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-09-24 15:05:17 +00:00
|
|
|
|
id: root
|
2020-11-19 18:30:09 +00:00
|
|
|
|
|
|
|
|
|
property alias chatLogView: chatLogView
|
2020-06-04 23:42:11 +00:00
|
|
|
|
|
2020-05-28 17:34:54 +00:00
|
|
|
|
property var messageList: MessagesData {}
|
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-09-24 15:05:17 +00:00
|
|
|
|
property int newMessages: 0
|
2020-05-28 22:22:51 +00:00
|
|
|
|
|
2021-04-21 15:22:49 +00:00
|
|
|
|
property string hoveredMessage
|
|
|
|
|
property string activeMessage
|
|
|
|
|
|
|
|
|
|
function setHovered(messageId, hovered) {
|
|
|
|
|
if (hovered) {
|
|
|
|
|
hoveredMessage = messageId
|
|
|
|
|
} else if (hoveredMessage === messageId) {
|
|
|
|
|
hoveredMessage = ""
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setMessageActive(messageId, active) {
|
|
|
|
|
if (active) {
|
|
|
|
|
activeMessage = messageId
|
|
|
|
|
} else if (activeMessage === messageId) {
|
|
|
|
|
activeMessage = ""
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-04 23:42:11 +00:00
|
|
|
|
contentItem: chatLogView
|
2020-05-27 22:59:17 +00:00
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.fillHeight: true
|
|
|
|
|
|
2021-04-07 16:28:49 +00:00
|
|
|
|
height: parent.height
|
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-12-07 17:37:39 +00:00
|
|
|
|
property string currentNotificationChatId
|
|
|
|
|
|
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
|
2021-02-10 20:41:00 +00:00
|
|
|
|
spacing: appSettings.useCompactMode ? 0 : 4
|
2020-06-15 12:51:04 +00:00
|
|
|
|
boundsBehavior: Flickable.StopAtBounds
|
2021-03-30 14:35:53 +00:00
|
|
|
|
flickDeceleration: {
|
|
|
|
|
if (utilsModel.getOs() === Constants.windows) {
|
|
|
|
|
return 5000
|
|
|
|
|
}
|
|
|
|
|
return 10000
|
|
|
|
|
}
|
2020-06-04 23:42:11 +00:00
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.fillHeight: true
|
2021-02-23 16:38:57 +00:00
|
|
|
|
verticalLayoutDirection: ListView.BottomToTop
|
2020-06-08 19:25:46 +00:00
|
|
|
|
|
2020-07-22 17:46:17 +00:00
|
|
|
|
Timer {
|
|
|
|
|
id: timer
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-24 15:05:17 +00:00
|
|
|
|
Button {
|
2020-09-28 14:21:40 +00:00
|
|
|
|
readonly property int buttonPadding: 5
|
|
|
|
|
|
2020-09-29 16:52:23 +00:00
|
|
|
|
id: scrollDownButton
|
|
|
|
|
visible: false
|
2020-09-24 15:05:17 +00:00
|
|
|
|
height: 32
|
2020-09-29 16:52:23 +00:00
|
|
|
|
width: nbMessages.width + arrowImage.width + 2 * Style.current.halfPadding + (nbMessages.visible ? scrollDownButton.buttonPadding : 0)
|
2020-07-23 20:22:45 +00:00
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.rightMargin: Style.current.padding
|
2020-09-24 15:05:17 +00:00
|
|
|
|
background: Rectangle {
|
2020-09-28 14:21:40 +00:00
|
|
|
|
color: Style.current.buttonSecondaryColor
|
2020-09-24 15:05:17 +00:00
|
|
|
|
border.width: 0
|
|
|
|
|
radius: 16
|
|
|
|
|
}
|
|
|
|
|
onClicked: {
|
|
|
|
|
root.newMessages = 0
|
2020-09-29 16:52:23 +00:00
|
|
|
|
scrollDownButton.visible = false
|
2020-09-24 15:05:17 +00:00
|
|
|
|
chatLogView.scrollToBottom(true)
|
|
|
|
|
}
|
2020-07-23 20:22:45 +00:00
|
|
|
|
|
|
|
|
|
StyledText {
|
2020-09-24 15:05:17 +00:00
|
|
|
|
id: nbMessages
|
|
|
|
|
visible: root.newMessages > 0
|
|
|
|
|
width: visible ? implicitWidth : 0
|
|
|
|
|
text: root.newMessages
|
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
2020-07-23 20:22:45 +00:00
|
|
|
|
anchors.left: parent.left
|
2020-09-24 15:05:17 +00:00
|
|
|
|
color: Style.current.pillButtonTextColor
|
2020-07-23 20:22:45 +00:00
|
|
|
|
font.pixelSize: 15
|
2020-09-24 15:05:17 +00:00
|
|
|
|
anchors.leftMargin: Style.current.halfPadding
|
2020-07-23 20:22:45 +00:00
|
|
|
|
}
|
2020-09-24 15:05:17 +00:00
|
|
|
|
|
|
|
|
|
SVGImage {
|
|
|
|
|
id: arrowImage
|
|
|
|
|
width: 24
|
|
|
|
|
height: 24
|
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
|
anchors.left: nbMessages.right
|
|
|
|
|
source: "../../../img/leave_chat.svg"
|
2020-09-29 16:52:23 +00:00
|
|
|
|
anchors.leftMargin: nbMessages.visible ? scrollDownButton.buttonPadding : 0
|
2020-09-24 15:05:17 +00:00
|
|
|
|
rotation: -90
|
|
|
|
|
|
|
|
|
|
ColorOverlay {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
source: parent
|
|
|
|
|
color: Style.current.pillButtonTextColor
|
|
|
|
|
}
|
2020-07-23 20:22:45 +00:00
|
|
|
|
}
|
2020-09-24 15:05:17 +00:00
|
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
|
cursorShape: Qt.PointingHandCursor
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onPressed: mouse.accepted = false
|
2020-09-25 19:44:40 +00:00
|
|
|
|
}
|
2020-07-23 20:22:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
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
|
2020-07-23 20:22:45 +00:00
|
|
|
|
return false
|
2020-07-22 18:37:43 +00:00
|
|
|
|
}
|
2020-10-20 14:15:04 +00:00
|
|
|
|
if (caller && caller !== chatLogView.itemAtIndex(chatLogView.count - 1)) {
|
|
|
|
|
// If we have a caller, only accept its request if it's the last message
|
|
|
|
|
return false
|
2020-07-22 18:37:43 +00:00
|
|
|
|
}
|
2020-10-20 14:15:04 +00:00
|
|
|
|
// Call this twice and with a timer since the first scroll to bottom might have happened before some stuff loads
|
|
|
|
|
// meaning that the scroll will not actually be at the bottom on switch
|
|
|
|
|
// Add a small delay because images, even though they say they say they are loaed, they aren't shown yet
|
2021-02-23 16:38:57 +00:00
|
|
|
|
Qt.callLater(chatLogView.positionViewAtBeginning)
|
2020-10-20 14:15:04 +00:00
|
|
|
|
timer.setTimeout(function() {
|
2021-02-23 16:38:57 +00:00
|
|
|
|
Qt.callLater(chatLogView.positionViewAtBeginning)
|
2020-10-20 14:15:04 +00:00
|
|
|
|
}, 100);
|
2020-07-23 20:22:45 +00:00
|
|
|
|
return true
|
2020-07-22 18:37:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 17:37:39 +00:00
|
|
|
|
function clickOnNotification(chatId) {
|
2021-02-15 16:42:25 +00:00
|
|
|
|
applicationWindow.show()
|
2020-12-07 17:37:39 +00:00
|
|
|
|
applicationWindow.raise()
|
2021-02-15 16:42:25 +00:00
|
|
|
|
applicationWindow.requestActivate()
|
2020-12-07 17:37:39 +00:00
|
|
|
|
chatsModel.setActiveChannel(chatId)
|
|
|
|
|
appMain.changeAppSection(Constants.chat)
|
|
|
|
|
}
|
2020-07-22 18:37:43 +00:00
|
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
|
Connections {
|
|
|
|
|
target: chatsModel
|
|
|
|
|
onMessagesLoaded: {
|
|
|
|
|
loadingMessages = false;
|
|
|
|
|
}
|
|
|
|
|
|
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-11-30 21:24:01 +00:00
|
|
|
|
onSendingMessageFailed: {
|
|
|
|
|
sendingMsgFailedPopup.open();
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-23 20:22:45 +00:00
|
|
|
|
onNewMessagePushed: {
|
|
|
|
|
if (!chatLogView.scrollToBottom()) {
|
2020-09-24 15:05:17 +00:00
|
|
|
|
root.newMessages++
|
2020-07-23 20:22:45 +00:00
|
|
|
|
}
|
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: {
|
2020-10-20 14:15:04 +00:00
|
|
|
|
chatLogView.scrollToBottom(true)
|
2020-07-22 17:46:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-16 19:25:46 +00:00
|
|
|
|
onMessageNotificationPushed: function(chatId, msg, messageType, chatType, timestamp, identicon, username, hasMention, isAddedContact, channelName) {
|
2020-10-15 11:53:27 +00:00
|
|
|
|
if (appSettings.notificationSetting == Constants.notifyAllMessages ||
|
|
|
|
|
(appSettings.notificationSetting == Constants.notifyJustMentions && hasMention)) {
|
2020-12-07 17:37:39 +00:00
|
|
|
|
if (chatType === Constants.chatTypeOneToOne && !appSettings.allowNotificationsFromNonContacts && !isAddedContact) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-12-28 15:45:46 +00:00
|
|
|
|
if (chatId === chatsModel.activeChannel.id && applicationWindow.active === true) {
|
|
|
|
|
// Do not show the notif if we are in the channel already and the window is active and focused
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 17:37:39 +00:00
|
|
|
|
chatLogView.currentNotificationChatId = chatId
|
|
|
|
|
|
|
|
|
|
let name;
|
|
|
|
|
if (appSettings.notificationMessagePreviewSetting === Constants.notificationPreviewAnonymous) {
|
|
|
|
|
name = "Status"
|
|
|
|
|
} else if (chatType === Constants.chatTypePublic) {
|
|
|
|
|
name = chatId
|
|
|
|
|
} else {
|
|
|
|
|
name = chatType === Constants.chatTypePrivateGroupChat ? Utils.filterXSS(channelName) : Utils.removeStatusEns(username)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let message;
|
|
|
|
|
if (appSettings.notificationMessagePreviewSetting > Constants.notificationPreviewNameOnly) {
|
|
|
|
|
switch(messageType){
|
2021-02-18 16:36:05 +00:00
|
|
|
|
//% "Image"
|
|
|
|
|
case Constants.imageType: message = qsTrId("image"); break
|
|
|
|
|
//% "Sticker"
|
|
|
|
|
case Constants.stickerType: message = qsTrId("sticker"); break
|
2021-04-20 01:10:01 +00:00
|
|
|
|
default: message = msg // don't parse emojis here as it emits HTML
|
2020-11-18 12:50:38 +00:00
|
|
|
|
}
|
2020-12-07 17:37:39 +00:00
|
|
|
|
} else {
|
2021-02-18 16:36:05 +00:00
|
|
|
|
//% "You have a new message"
|
|
|
|
|
message = qsTrId("you-have-a-new-message")
|
2020-12-07 17:37:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-15 16:29:16 +00:00
|
|
|
|
currentlyHasANotification = true
|
2020-12-07 17:37:39 +00:00
|
|
|
|
if (appSettings.useOSNotifications && systemTray.supportsMessages) {
|
|
|
|
|
systemTray.showMessage(name,
|
|
|
|
|
message,
|
|
|
|
|
SystemTrayIcon.NoIcon,
|
|
|
|
|
Constants.notificationPopupTTL)
|
|
|
|
|
} else {
|
|
|
|
|
notificationWindow.notifyUser(chatId, name, message, chatType, identicon, chatLogView.clickOnNotification)
|
|
|
|
|
}
|
2020-10-15 11:53:27 +00:00
|
|
|
|
}
|
2020-07-10 21:47:31 +00:00
|
|
|
|
}
|
2021-02-11 20:37:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
|
target: chatsModel.communities
|
2021-02-10 20:37:17 +00:00
|
|
|
|
|
2021-02-11 20:37:31 +00:00
|
|
|
|
onMembershipRequestChanged: function (communityName, accepted) {
|
2021-02-10 20:37:17 +00:00
|
|
|
|
systemTray.showMessage("Status",
|
|
|
|
|
accepted ? qsTr("You have been accepted into the ‘%1’ community").arg(communityName) :
|
|
|
|
|
qsTr("Your request to join the ‘%1’ community was declined").arg(communityName),
|
|
|
|
|
SystemTrayIcon.NoIcon,
|
|
|
|
|
Constants.notificationPopupTTL)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMembershipRequestPushed: function (communityName, pubKey) {
|
|
|
|
|
systemTray.showMessage(qsTr("New membership request"),
|
|
|
|
|
qsTr("%1 asks to join ‘%2’").arg(Utils.getDisplayName(pubKey)).arg(communityName),
|
|
|
|
|
SystemTrayIcon.NoIcon,
|
|
|
|
|
Constants.notificationPopupTTL)
|
|
|
|
|
}
|
2020-06-04 19:07:07 +00:00
|
|
|
|
}
|
2020-06-08 19:25:46 +00:00
|
|
|
|
|
2020-12-07 17:37:39 +00:00
|
|
|
|
Connections {
|
|
|
|
|
target: systemTray
|
|
|
|
|
onMessageClicked: {
|
|
|
|
|
chatLogView.clickOnNotification(chatLogView.currentNotificationChatId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-20 14:15:04 +00:00
|
|
|
|
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
2020-07-22 15:12:24 +00:00
|
|
|
|
if(loadingMessages) return;
|
|
|
|
|
loadingMessages = true;
|
|
|
|
|
chatsModel.loadMoreMessages();
|
|
|
|
|
});
|
|
|
|
|
|
2020-06-08 19:25:46 +00:00
|
|
|
|
onContentYChanged: {
|
2020-09-29 16:52:23 +00:00
|
|
|
|
scrollDownButton.visible = (contentHeight - (scrollY + height) > 400)
|
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
|
|
|
|
}
|
2020-11-30 21:24:01 +00:00
|
|
|
|
|
|
|
|
|
MessageDialog {
|
|
|
|
|
id: sendingMsgFailedPopup
|
|
|
|
|
standardButtons: StandardButton.Ok
|
2021-02-18 16:36:05 +00:00
|
|
|
|
//% "Failed to send message."
|
|
|
|
|
text: qsTrId("failed-to-send-message-")
|
2020-11-30 21:24:01 +00:00
|
|
|
|
icon: StandardIcon.Critical
|
|
|
|
|
}
|
2020-06-04 23:42:11 +00:00
|
|
|
|
|
2021-02-10 20:37:17 +00:00
|
|
|
|
DelegateModelGeneralized {
|
2020-06-04 23:42:11 +00:00
|
|
|
|
id: messageListDelegate
|
2021-03-01 19:00:51 +00:00
|
|
|
|
lessThan: [
|
2021-02-23 16:38:57 +00:00
|
|
|
|
function(left, right) { return left.clock > right.clock }
|
2020-06-05 22:20:45 +00:00
|
|
|
|
]
|
2020-05-28 22:22:51 +00:00
|
|
|
|
|
2020-06-05 22:20:45 +00:00
|
|
|
|
model: messageList
|
2020-06-08 17:29:28 +00:00
|
|
|
|
|
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
|
2020-12-08 15:45:43 +00:00
|
|
|
|
alias: model.alias
|
|
|
|
|
localName: model.localName
|
2020-06-05 22:20:45 +00:00
|
|
|
|
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
|
2021-02-24 16:37:40 +00:00
|
|
|
|
// The previous message is actually the nextSection since we reversed the list order
|
|
|
|
|
authorPrevMsg: msgDelegate.ListView.nextSection
|
2020-09-12 18:22:07 +00:00
|
|
|
|
imageClick: imagePopup.openPopup.bind(imagePopup)
|
2020-07-09 17:47:36 +00:00
|
|
|
|
messageId: model.messageId
|
2020-08-12 15:01:03 +00:00
|
|
|
|
emojiReactions: model.emojiReactions
|
2020-12-07 23:38:53 +00:00
|
|
|
|
linkUrls: model.linkUrls
|
2020-12-11 20:38:10 +00:00
|
|
|
|
communityId: model.communityId
|
2021-02-01 18:40:55 +00:00
|
|
|
|
hasMention: model.hasMention
|
2021-03-08 19:24:39 +00:00
|
|
|
|
stickerPackId: model.stickerPackId
|
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
|
2021-04-06 14:59:59 +00:00
|
|
|
|
if (msgDelegate.DelegateModel.itemsIndex < messageListDelegate.items.count - 1) {
|
|
|
|
|
return messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex + 1).model.index
|
2020-07-12 01:03:39 +00:00
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
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}
|
|
|
|
|
}
|
|
|
|
|
##^##*/
|