2020-12-17 10:40:37 +00:00
|
|
|
import QtQuick 2.13
|
|
|
|
import QtQuick.Controls 2.13
|
|
|
|
import QtGraphicalEffects 1.13
|
|
|
|
import QtQml.Models 2.13
|
|
|
|
import QtQuick.Layouts 1.13
|
|
|
|
import "../../../imports"
|
|
|
|
import "../../../shared"
|
|
|
|
import "../../../shared/status"
|
|
|
|
import "../Chat/data"
|
|
|
|
import "../Chat/ChatColumn"
|
|
|
|
import "../Chat/components"
|
|
|
|
|
|
|
|
ScrollView {
|
|
|
|
id: root
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
2021-01-22 19:21:26 +00:00
|
|
|
contentHeight: chatLogView.contentHeight + 140
|
2020-12-17 10:40:37 +00:00
|
|
|
clip: true
|
|
|
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
2021-01-22 19:21:26 +00:00
|
|
|
|
2020-12-17 10:40:37 +00:00
|
|
|
property var onActivated: function () {
|
|
|
|
chatsModel.setActiveChannelToTimeline()
|
|
|
|
statusUpdateInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
|
|
|
}
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
|
|
|
statusUpdateInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
|
|
|
}
|
|
|
|
|
|
|
|
function openProfilePopup(userNameParam, fromAuthorParam, identiconParam, textParam, nicknameParam, parentPopup){
|
|
|
|
var popup = profilePopupComponent.createObject(root);
|
|
|
|
if(parentPopup){
|
|
|
|
popup.parentPopup = parentPopup;
|
|
|
|
}
|
|
|
|
popup.openPopup(profileModel.profile.pubKey !== fromAuthorParam, userNameParam, fromAuthorParam, identiconParam, textParam, nicknameParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MessageContextMenu {
|
|
|
|
id: messageContextMenu
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusImageModal {
|
|
|
|
id: imagePopup
|
|
|
|
}
|
|
|
|
|
|
|
|
EmojiReactions {
|
|
|
|
id: reactionModel
|
|
|
|
}
|
|
|
|
|
|
|
|
property Component profilePopupComponent: ProfilePopup {
|
|
|
|
id: profilePopup
|
|
|
|
height: 450
|
|
|
|
onClosed: {
|
|
|
|
if(profilePopup.parentPopup){
|
|
|
|
profilePopup.parentPopup.close();
|
|
|
|
}
|
|
|
|
destroy()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 20:09:07 +00:00
|
|
|
Item {
|
2020-12-17 10:40:37 +00:00
|
|
|
id: timelineContainer
|
|
|
|
width: 624
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
2021-01-14 20:09:07 +00:00
|
|
|
anchors.bottom: parent.bottom
|
2020-12-17 10:40:37 +00:00
|
|
|
|
|
|
|
StatusChatInput {
|
|
|
|
id: statusUpdateInput
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.topMargin: 40
|
|
|
|
chatType: Constants.chatTypeStatusUpdate
|
|
|
|
onSendMessage: {
|
|
|
|
if (statusUpdateInput.fileUrls.length > 0){
|
|
|
|
chatsModel.sendImage(statusUpdateInput.fileUrls[0], true);
|
|
|
|
}
|
|
|
|
var msg = chatsModel.plainText(Emoji.deparse(statusUpdateInput.textInput.text))
|
|
|
|
if (msg.length > 0){
|
|
|
|
msg = statusUpdateInput.interpretMessage(msg)
|
|
|
|
chatsModel.sendMessage(msg, "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, true);
|
|
|
|
statusUpdateInput.textInput.text = "";
|
|
|
|
if(event) event.accepted = true
|
|
|
|
statusUpdateInput.messageSound.stop()
|
|
|
|
Qt.callLater(statusUpdateInput.messageSound.play);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EmptyTimeline {
|
|
|
|
id: emptyTimeline
|
|
|
|
anchors.top: statusUpdateInput.bottom
|
|
|
|
anchors.topMargin: 40
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
visible: chatsModel.messageList.rowCount() === 0
|
|
|
|
}
|
|
|
|
|
|
|
|
ListView {
|
|
|
|
id: chatLogView
|
|
|
|
anchors.top: statusUpdateInput.bottom
|
2021-01-14 20:09:07 +00:00
|
|
|
anchors.topMargin: Style.current.bigPadding
|
2020-12-17 10:40:37 +00:00
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
2021-01-14 20:09:07 +00:00
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
spacing: Style.current.halfPadding
|
2020-12-17 10:40:37 +00:00
|
|
|
flickDeceleration: 10000
|
|
|
|
interactive: false
|
|
|
|
|
|
|
|
model: messageListDelegate
|
|
|
|
section.property: "sectionIdentifier"
|
|
|
|
section.criteria: ViewSection.FullString
|
|
|
|
}
|
|
|
|
|
|
|
|
DelegateModel {
|
|
|
|
id: messageListDelegate
|
|
|
|
property var moreThan: [
|
|
|
|
function(left, right) { return left.clock > right.clock }
|
|
|
|
]
|
|
|
|
|
|
|
|
property int sortOrder: 0
|
|
|
|
onSortOrderChanged: items.setGroups(0, items.count, "unsorted")
|
|
|
|
|
|
|
|
function insertPosition(moreThan, item) {
|
|
|
|
var lower = 0
|
|
|
|
var upper = items.count
|
|
|
|
while (lower < upper) {
|
|
|
|
var middle = Math.floor(lower + (upper - lower) / 2)
|
|
|
|
var result = moreThan(item.model, items.get(middle).model);
|
|
|
|
if (result) {
|
|
|
|
upper = middle
|
|
|
|
} else {
|
|
|
|
lower = middle + 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return lower
|
|
|
|
}
|
|
|
|
|
|
|
|
function sort(moreThan) {
|
|
|
|
while (unsortedItems.count > 0) {
|
|
|
|
var item = unsortedItems.get(0)
|
|
|
|
var index = insertPosition(moreThan, item)
|
|
|
|
item.groups = "items"
|
|
|
|
items.move(item.itemsIndex, index)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
items.includeByDefault: false
|
|
|
|
groups: DelegateModelGroup {
|
|
|
|
id: unsortedItems
|
|
|
|
name: "unsorted"
|
|
|
|
includeByDefault: true
|
|
|
|
onChanged: {
|
|
|
|
if (messageListDelegate.sortOrder == messageListDelegate.moreThan.length)
|
|
|
|
setGroups(0, count, "items")
|
|
|
|
else {
|
|
|
|
messageListDelegate.sort(messageListDelegate.moreThan[messageListDelegate.sortOrder])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
model: chatsModel.messageList
|
|
|
|
|
|
|
|
delegate: Message {
|
|
|
|
id: msgDelegate
|
|
|
|
fromAuthor: model.fromAuthor
|
|
|
|
chatId: model.chatId
|
|
|
|
userName: model.userName
|
|
|
|
localName: model.localName
|
|
|
|
alias: model.alias
|
|
|
|
message: model.message
|
|
|
|
plainText: model.plainText
|
|
|
|
identicon: model.identicon
|
|
|
|
isCurrentUser: model.isCurrentUser
|
|
|
|
timestamp: model.timestamp
|
|
|
|
sticker: model.sticker
|
|
|
|
contentType: model.contentType
|
|
|
|
outgoingStatus: model.outgoingStatus
|
|
|
|
responseTo: model.responseTo
|
|
|
|
authorCurrentMsg: msgDelegate.ListView.section
|
|
|
|
authorPrevMsg: msgDelegate.ListView.previousSection
|
|
|
|
imageClick: imagePopup.openPopup.bind(imagePopup)
|
|
|
|
messageId: model.messageId
|
|
|
|
emojiReactions: model.emojiReactions
|
|
|
|
isStatusUpdate: true
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
timeout: model.timeout
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|