mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-11 23:05:17 +00:00
90dfa94805
Prior to this commit, the function was expected on a `chatView` QML object. This has worked out so far because the places where the API is used were always living inside `ChatLayout`. With the new timeline however, this is no longer the case so we have to make sure that the API is available to other views as well.
266 lines
9.7 KiB
QML
266 lines
9.7 KiB
QML
import QtQuick 2.13
|
|
import "../../../../shared"
|
|
import "../../../../imports"
|
|
import "./MessageComponents"
|
|
import "../components"
|
|
|
|
Item {
|
|
property string fromAuthor: "0x0011223344556677889910"
|
|
property string userName: "Jotaro Kujo"
|
|
property string alias: ""
|
|
property string localName: ""
|
|
property string message: "That's right. We're friends... Of justice, that is."
|
|
property string plainText: "That's right. We're friends... Of justice, that is."
|
|
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQMAAAC6caSPAAAABlBMVEXMzMz////TjRV2AAAAAWJLR0QB/wIt3gAAACpJREFUGBntwYEAAAAAw6D7Uw/gCtUAAAAAAAAAAAAAAAAAAAAAAAAAgBNPsAABAjKCqQAAAABJRU5ErkJggg=="
|
|
property bool isCurrentUser: false
|
|
property string timestamp: "1234567"
|
|
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"
|
|
property int contentType: 2 // constants don't work in default props
|
|
property string chatId: "chatId"
|
|
property string outgoingStatus: ""
|
|
property string responseTo: ""
|
|
property string messageId: ""
|
|
property string emojiReactions: ""
|
|
property int prevMessageIndex: -1
|
|
property bool timeout: false
|
|
property string linkUrls: ""
|
|
property bool placeholderMessage: false
|
|
|
|
property string authorCurrentMsg: "authorCurrentMsg"
|
|
property string authorPrevMsg: "authorPrevMsg"
|
|
|
|
property bool isEmoji: contentType === Constants.emojiType
|
|
property bool isImage: contentType === Constants.imageType
|
|
property bool isAudio: contentType === Constants.audioType
|
|
property bool isStatusMessage: contentType === Constants.systemMessagePrivateGroupType
|
|
property bool isSticker: contentType === Constants.stickerType
|
|
property bool isText: contentType === Constants.messageType
|
|
property bool isMessage: isEmoji || isImage || isSticker || isText || isAudio
|
|
|
|
property bool isExpired: (outgoingStatus == "sending" && (Math.floor(timestamp) + 180000) < Date.now())
|
|
property bool isStatusUpdate: false
|
|
|
|
property int replyMessageIndex: chatsModel.messageList.getMessageIndex(responseTo);
|
|
property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "userName") : "";
|
|
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "message") : "";
|
|
property int repliedMessageType: replyMessageIndex > -1 ? parseInt(chatsModel.messageList.getMessageData(replyMessageIndex, "contentType")) : 0;
|
|
property string repliedMessageImage: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "image") : "";
|
|
|
|
property var imageClick: function () {}
|
|
property var scrollToBottom: function () {}
|
|
property string userPubKey: {
|
|
if (contentType === Constants.chatIdentifier) {
|
|
return chatId
|
|
}
|
|
return fromAuthor
|
|
}
|
|
property bool useLargeImage: contentType === Constants.chatIdentifier
|
|
|
|
property string profileImageSource: !placeholderMessage && appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) || ""
|
|
|
|
Connections {
|
|
enabled: !placeholderMessage
|
|
target: profileModel.contacts.list
|
|
onContactChanged: {
|
|
if (pubkey === fromAuthor) {
|
|
profileImageSource = appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage)
|
|
}
|
|
}
|
|
}
|
|
|
|
id: root
|
|
width: parent.width
|
|
anchors.right: !isCurrentUser ? undefined : parent.right
|
|
height: {
|
|
switch(contentType) {
|
|
case Constants.chatIdentifier:
|
|
return childrenRect.height + 50
|
|
default: return childrenRect.height
|
|
}
|
|
}
|
|
|
|
function clickMessage(isProfileClick, isSticker = false, isImage = false, image = null, emojiOnly = false) {
|
|
if (isImage) {
|
|
imageClick(image);
|
|
return;
|
|
}
|
|
|
|
if (!isProfileClick) {
|
|
SelectedMessage.set(messageId, fromAuthor);
|
|
}
|
|
// Get contact nickname
|
|
const contactList = profileModel.contacts.list
|
|
const contactCount = contactList.rowCount()
|
|
let nickname = ""
|
|
for (let i = 0; i < contactCount; i++) {
|
|
if (contactList.rowData(i, 'pubKey') === fromAuthor) {
|
|
nickname = contactList.rowData(i, 'localNickname')
|
|
break;
|
|
}
|
|
}
|
|
messageContextMenu.isProfile = !!isProfileClick
|
|
messageContextMenu.isSticker = isSticker
|
|
messageContextMenu.emojiOnly = emojiOnly
|
|
messageContextMenu.show(userName, fromAuthor, root.profileImageSource || identicon, "", nickname)
|
|
// Position the center of the menu where the mouse is
|
|
messageContextMenu.x = messageContextMenu.x - messageContextMenu.width / 2
|
|
}
|
|
|
|
Loader {
|
|
active: true
|
|
width: parent.width
|
|
sourceComponent: {
|
|
switch(contentType) {
|
|
case Constants.chatIdentifier:
|
|
return channelIdentifierComponent
|
|
case Constants.fetchMoreMessagesButton:
|
|
return fetchMoreMessagesButtonComponent
|
|
case Constants.systemMessagePrivateGroupType:
|
|
return privateGroupHeaderComponent
|
|
case Constants.transactionType:
|
|
return transactionBubble
|
|
default:
|
|
return appSettings.compactMode ? compactMessageComponent :
|
|
isStatusUpdate ? statusUpdateComponent : messageComponent
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: timer
|
|
}
|
|
|
|
Component {
|
|
id: fetchMoreMessagesButtonComponent
|
|
Item {
|
|
visible: chatsModel.activeChannel.chatType !== Constants.chatTypePrivateGroupChat || chatsModel.activeChannel.isMember
|
|
id: wrapper
|
|
height: wrapper.visible ? fetchMoreButton.height + fetchDate.height + 3 + Style.current.smallPadding*2 : 0
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
Separator {
|
|
id: sep1
|
|
}
|
|
StyledText {
|
|
id: fetchMoreButton
|
|
font.weight: Font.Medium
|
|
font.pixelSize: Style.current.primaryTextFontSize
|
|
color: Style.current.blue
|
|
//% "↓ Fetch more messages"
|
|
text: qsTrId("load-more-messages")
|
|
horizontalAlignment: Text.AlignHCenter
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.top: sep1.bottom
|
|
anchors.topMargin: Style.current.smallPadding
|
|
MouseArea {
|
|
cursorShape: Qt.PointingHandCursor
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours)
|
|
timer.setTimeout(function(){
|
|
chatsModel.hideLoadingIndicator()
|
|
}, 3000);
|
|
}
|
|
}
|
|
}
|
|
StyledText {
|
|
id: fetchDate
|
|
anchors.top: fetchMoreButton.bottom
|
|
anchors.topMargin: 3
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
horizontalAlignment: Text.AlignHCenter
|
|
color: Style.current.darkGrey
|
|
//% "before %1"
|
|
text: qsTrId("before--1").arg(new Date(chatsModel.oldestMsgTimestamp*1000).toDateString())
|
|
}
|
|
Separator {
|
|
anchors.top: fetchDate.bottom
|
|
anchors.topMargin: Style.current.smallPadding
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: channelIdentifierComponent
|
|
ChannelIdentifier {
|
|
authorCurrentMsg: root.authorCurrentMsg
|
|
profileImage: profileImageSource
|
|
}
|
|
}
|
|
|
|
// Private group Messages
|
|
Component {
|
|
id: privateGroupHeaderComponent
|
|
StyledText {
|
|
wrapMode: Text.Wrap
|
|
text: {
|
|
return `<html>`+
|
|
`<head>`+
|
|
`<style type="text/css">`+
|
|
`a {`+
|
|
`color: ${Style.current.textColor};`+
|
|
`text-decoration: none;`+
|
|
`}`+
|
|
`</style>`+
|
|
`</head>`+
|
|
`<body>`+
|
|
`${message}`+
|
|
`</body>`+
|
|
`</html>`;
|
|
}
|
|
visible: isStatusMessage
|
|
font.pixelSize: 14
|
|
color: Style.current.secondaryText
|
|
width: parent.width - 120
|
|
horizontalAlignment: Text.AlignHCenter
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
textFormat: Text.RichText
|
|
topPadding: root.prevMessageIndex === 1 ? Style.current.bigPadding : 0
|
|
}
|
|
}
|
|
|
|
// Normal message
|
|
Component {
|
|
id: messageComponent
|
|
NormalMessage {
|
|
clickMessage: root.clickMessage
|
|
linkUrls: root.linkUrls
|
|
isCurrentUser: root.isCurrentUser
|
|
contentType: root.contentType
|
|
container: root
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: statusUpdateComponent
|
|
StatusUpdate {
|
|
clickMessage: root.clickMessage
|
|
container: root
|
|
}
|
|
}
|
|
|
|
// Compact Messages
|
|
Component {
|
|
id: compactMessageComponent
|
|
CompactMessage {
|
|
clickMessage: root.clickMessage
|
|
linkUrls: root.linkUrls
|
|
isCurrentUser: root.isCurrentUser
|
|
contentType: root.contentType
|
|
container: root
|
|
}
|
|
}
|
|
|
|
// Transaction bubble
|
|
Component {
|
|
id: transactionBubble
|
|
TransactionBubble {}
|
|
}
|
|
}
|
|
|
|
/*##^##
|
|
Designer {
|
|
D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.75;height:80;width:800}
|
|
}
|
|
##^##*/
|