2020-11-30 17:03:52 +00:00
|
|
|
import QtQuick 2.13
|
2020-05-27 22:59:17 +00:00
|
|
|
import "../../../../shared"
|
|
|
|
import "../../../../imports"
|
2020-07-15 21:04:14 +00:00
|
|
|
import "./MessageComponents"
|
2020-06-04 10:30:49 +00:00
|
|
|
import "../components"
|
2020-05-27 22:59:17 +00:00
|
|
|
|
2020-05-28 19:32:14 +00:00
|
|
|
Item {
|
2020-06-16 21:24:43 +00:00
|
|
|
property string fromAuthor: "0x0011223344556677889910"
|
2020-05-28 15:55:52 +00:00
|
|
|
property string userName: "Jotaro Kujo"
|
2020-12-08 15:45:43 +00:00
|
|
|
property string alias: ""
|
|
|
|
property string localName: ""
|
2020-05-28 15:55:52 +00:00
|
|
|
property string message: "That's right. We're friends... Of justice, that is."
|
2020-07-10 15:24:52 +00:00
|
|
|
property string plainText: "That's right. We're friends... Of justice, that is."
|
2020-07-20 17:04:33 +00:00
|
|
|
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQMAAAC6caSPAAAABlBMVEXMzMz////TjRV2AAAAAWJLR0QB/wIt3gAAACpJREFUGBntwYEAAAAAw6D7Uw/gCtUAAAAAAAAAAAAAAAAAAAAAAAAAgBNPsAABAjKCqQAAAABJRU5ErkJggg=="
|
2020-05-28 15:55:52 +00:00
|
|
|
property bool isCurrentUser: false
|
2020-06-11 17:50:36 +00:00
|
|
|
property string timestamp: "1234567"
|
2020-05-28 21:34:04 +00:00
|
|
|
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"
|
2020-07-09 17:29:19 +00:00
|
|
|
property int contentType: 2 // constants don't work in default props
|
2020-06-08 17:29:28 +00:00
|
|
|
property string chatId: "chatId"
|
2020-07-01 18:24:13 +00:00
|
|
|
property string outgoingStatus: ""
|
2020-07-09 15:50:38 +00:00
|
|
|
property string responseTo: ""
|
2020-07-09 17:47:36 +00:00
|
|
|
property string messageId: ""
|
2020-08-12 15:01:03 +00:00
|
|
|
property string emojiReactions: ""
|
2020-07-12 01:03:39 +00:00
|
|
|
property int prevMessageIndex: -1
|
2020-07-14 15:35:21 +00:00
|
|
|
property bool timeout: false
|
2021-02-01 18:40:55 +00:00
|
|
|
property bool hasMention: false
|
2020-11-25 10:43:36 +00:00
|
|
|
property string linkUrls: ""
|
2020-11-30 17:03:52 +00:00
|
|
|
property bool placeholderMessage: false
|
2020-12-11 20:38:10 +00:00
|
|
|
property string communityId: ""
|
2020-05-28 15:55:52 +00:00
|
|
|
|
2020-06-05 22:20:45 +00:00
|
|
|
property string authorCurrentMsg: "authorCurrentMsg"
|
|
|
|
property string authorPrevMsg: "authorPrevMsg"
|
2020-05-27 22:59:17 +00:00
|
|
|
|
2021-02-09 14:53:54 +00:00
|
|
|
property string prevMsgTimestamp: chatsModel.messageList.getMessageData(prevMessageIndex, "timestamp")
|
|
|
|
property bool shouldRepeatHeader: ((parseInt(timestamp, 10) - parseInt(prevMsgTimestamp, 10)) / 60 / 1000) > Constants.repeatHeaderInterval
|
|
|
|
|
2020-06-24 19:58:17 +00:00
|
|
|
property bool isEmoji: contentType === Constants.emojiType
|
2020-07-17 19:44:25 +00:00
|
|
|
property bool isImage: contentType === Constants.imageType
|
2020-07-30 16:07:41 +00:00
|
|
|
property bool isAudio: contentType === Constants.audioType
|
2020-06-24 19:58:17 +00:00
|
|
|
property bool isStatusMessage: contentType === Constants.systemMessagePrivateGroupType
|
2020-07-09 17:29:19 +00:00
|
|
|
property bool isSticker: contentType === Constants.stickerType
|
2020-07-20 17:34:20 +00:00
|
|
|
property bool isText: contentType === Constants.messageType
|
2021-02-01 18:40:55 +00:00
|
|
|
property bool isMessage: isEmoji || isImage || isSticker || isText || isAudio
|
|
|
|
|| contentType === Constants.communityInviteType || contentType === Constants.transactionType
|
2020-06-10 15:14:12 +00:00
|
|
|
|
2020-07-16 17:27:09 +00:00
|
|
|
property bool isExpired: (outgoingStatus == "sending" && (Math.floor(timestamp) + 180000) < Date.now())
|
2020-12-10 11:47:30 +00:00
|
|
|
property bool isStatusUpdate: false
|
2020-07-16 17:27:09 +00:00
|
|
|
|
2020-07-09 15:50:38 +00:00
|
|
|
property int replyMessageIndex: chatsModel.messageList.getMessageIndex(responseTo);
|
2020-07-12 01:03:39 +00:00
|
|
|
property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "userName") : "";
|
|
|
|
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "message") : "";
|
2020-07-17 19:44:25 +00:00
|
|
|
property int repliedMessageType: replyMessageIndex > -1 ? parseInt(chatsModel.messageList.getMessageData(replyMessageIndex, "contentType")) : 0;
|
|
|
|
property string repliedMessageImage: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "image") : "";
|
2020-07-09 15:50:38 +00:00
|
|
|
|
2020-09-12 18:22:07 +00:00
|
|
|
property var imageClick: function () {}
|
2020-07-10 15:37:23 +00:00
|
|
|
property var scrollToBottom: function () {}
|
2020-11-30 17:03:52 +00:00
|
|
|
property string userPubKey: {
|
|
|
|
if (contentType === Constants.chatIdentifier) {
|
|
|
|
return chatId
|
|
|
|
}
|
|
|
|
return fromAuthor
|
|
|
|
}
|
|
|
|
property bool useLargeImage: contentType === Constants.chatIdentifier
|
|
|
|
|
2020-12-21 12:08:44 +00:00
|
|
|
property string profileImageSource: !placeholderMessage && appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) || ""
|
2020-11-30 17:03:52 +00:00
|
|
|
|
2021-02-01 20:37:50 +00:00
|
|
|
property var emojiReactionsModel: {
|
|
|
|
if (!emojiReactions) {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
// group by id
|
|
|
|
var allReactions = Object.values(JSON.parse(emojiReactions))
|
|
|
|
var byEmoji = {}
|
|
|
|
allReactions.forEach(function (reaction) {
|
|
|
|
if (!byEmoji[reaction.emojiId]) {
|
|
|
|
byEmoji[reaction.emojiId] = {
|
|
|
|
emojiId: reaction.emojiId,
|
|
|
|
fromAccounts: [],
|
|
|
|
count: 0,
|
|
|
|
currentUserReacted: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
byEmoji[reaction.emojiId].count++;
|
|
|
|
byEmoji[reaction.emojiId].fromAccounts.push(chatsModel.userNameOrAlias(reaction.from));
|
|
|
|
if (!byEmoji[reaction.emojiId].currentUserReacted && reaction.from === profileModel.profile.pubKey) {
|
|
|
|
byEmoji[reaction.emojiId].currentUserReacted = true
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
return Object.values(byEmoji)
|
|
|
|
} catch (e) {
|
|
|
|
console.error('Error parsing emoji reactions', e)
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-30 17:03:52 +00:00
|
|
|
Connections {
|
|
|
|
enabled: !placeholderMessage
|
|
|
|
target: profileModel.contacts.list
|
|
|
|
onContactChanged: {
|
|
|
|
if (pubkey === fromAuthor) {
|
2021-02-08 18:46:20 +00:00
|
|
|
const img = appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage)
|
|
|
|
if (img) {
|
|
|
|
profileImageSource = img
|
|
|
|
}
|
2020-11-30 17:03:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-15 21:04:14 +00:00
|
|
|
|
2020-12-07 23:38:53 +00:00
|
|
|
id: root
|
2020-06-05 22:20:45 +00:00
|
|
|
width: parent.width
|
2020-07-10 15:37:23 +00:00
|
|
|
anchors.right: !isCurrentUser ? undefined : parent.right
|
2020-06-08 17:29:28 +00:00
|
|
|
height: {
|
2020-07-15 21:04:14 +00:00
|
|
|
switch(contentType) {
|
2020-06-08 17:29:28 +00:00
|
|
|
case Constants.chatIdentifier:
|
2020-07-15 21:04:14 +00:00
|
|
|
return childrenRect.height + 50
|
|
|
|
default: return childrenRect.height
|
2020-06-08 17:29:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-08 12:34:02 +00:00
|
|
|
function clickMessage(isProfileClick, isSticker = false, isImage = false, image = null, emojiOnly = false) {
|
2020-09-12 18:22:07 +00:00
|
|
|
if (isImage) {
|
|
|
|
imageClick(image);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-03 17:17:03 +00:00
|
|
|
if (!isProfileClick) {
|
|
|
|
SelectedMessage.set(messageId, fromAuthor);
|
|
|
|
}
|
2020-09-16 19:52:48 +00:00
|
|
|
// Get contact nickname
|
2021-01-14 16:03:00 +00:00
|
|
|
let nickname = appMain.getUserNickname(fromAuthor)
|
2020-08-03 17:17:03 +00:00
|
|
|
messageContextMenu.isProfile = !!isProfileClick
|
2020-08-27 23:26:12 +00:00
|
|
|
messageContextMenu.isSticker = isSticker
|
2020-12-08 12:34:02 +00:00
|
|
|
messageContextMenu.emojiOnly = emojiOnly
|
2021-02-01 20:37:50 +00:00
|
|
|
messageContextMenu.show(userName, fromAuthor, root.profileImageSource || identicon, "", nickname, emojiReactionsModel)
|
2020-07-20 18:46:15 +00:00
|
|
|
// Position the center of the menu where the mouse is
|
|
|
|
messageContextMenu.x = messageContextMenu.x - messageContextMenu.width / 2
|
2020-06-17 12:53:51 +00:00
|
|
|
}
|
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
Loader {
|
2020-11-30 17:03:52 +00:00
|
|
|
active: true
|
2020-07-15 21:04:14 +00:00
|
|
|
width: parent.width
|
|
|
|
sourceComponent: {
|
|
|
|
switch(contentType) {
|
|
|
|
case Constants.chatIdentifier:
|
|
|
|
return channelIdentifierComponent
|
2020-09-04 11:55:24 +00:00
|
|
|
case Constants.fetchMoreMessagesButton:
|
|
|
|
return fetchMoreMessagesButtonComponent
|
2020-07-15 21:04:14 +00:00
|
|
|
case Constants.systemMessagePrivateGroupType:
|
2020-07-22 12:23:15 +00:00
|
|
|
return privateGroupHeaderComponent
|
2020-12-11 20:38:10 +00:00
|
|
|
case Constants.communityInviteType:
|
|
|
|
return invitationBubble
|
2020-07-15 21:04:14 +00:00
|
|
|
default:
|
2021-01-25 20:13:43 +00:00
|
|
|
return isStatusUpdate ? statusUpdateComponent :
|
2021-02-10 20:41:00 +00:00
|
|
|
(appSettings.useCompactMode ? compactMessageComponent : messageComponent)
|
2021-01-25 20:13:43 +00:00
|
|
|
|
2020-06-04 10:30:49 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 11:47:00 +00:00
|
|
|
Timer {
|
|
|
|
id: timer
|
|
|
|
}
|
|
|
|
|
2020-09-04 11:55:24 +00:00
|
|
|
Component {
|
|
|
|
id: fetchMoreMessagesButtonComponent
|
|
|
|
Item {
|
2021-02-12 19:27:37 +00:00
|
|
|
property int gapNowAndOldestTimestamp: Date.now() / 1000 - chatsModel.oldestMsgTimestamp
|
|
|
|
|
|
|
|
visible: {
|
|
|
|
|
|
|
|
return gapNowAndOldestTimestamp < Constants.maxNbDaysToFetch * Constants.fetchRangeLast24Hours &&
|
|
|
|
(chatsModel.activeChannel.chatType !== Constants.chatTypePrivateGroupChat || chatsModel.activeChannel.isMember)
|
|
|
|
}
|
|
|
|
id: wrapper
|
2021-01-22 19:21:26 +00:00
|
|
|
height: wrapper.visible ? childrenRect.height + Style.current.smallPadding*2 : 0
|
2020-09-04 11:55:24 +00:00
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
|
|
|
Separator {
|
|
|
|
id: sep1
|
|
|
|
}
|
|
|
|
StyledText {
|
|
|
|
id: fetchMoreButton
|
|
|
|
font.weight: Font.Medium
|
2020-11-25 10:46:18 +00:00
|
|
|
font.pixelSize: Style.current.primaryTextFontSize
|
2020-09-04 11:55:24 +00:00
|
|
|
color: Style.current.blue
|
2020-09-14 12:12:47 +00:00
|
|
|
//% "↓ Fetch more messages"
|
|
|
|
text: qsTrId("load-more-messages")
|
2020-09-04 11:55:24 +00:00
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
anchors.top: sep1.bottom
|
|
|
|
anchors.topMargin: Style.current.smallPadding
|
|
|
|
MouseArea {
|
|
|
|
cursorShape: Qt.PointingHandCursor
|
|
|
|
anchors.fill: parent
|
|
|
|
onClicked: {
|
2021-02-01 18:01:30 +00:00
|
|
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours);
|
2020-09-07 11:47:00 +00:00
|
|
|
timer.setTimeout(function(){
|
|
|
|
chatsModel.hideLoadingIndicator()
|
|
|
|
}, 3000);
|
2020-09-04 11:55:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StyledText {
|
|
|
|
id: fetchDate
|
|
|
|
anchors.top: fetchMoreButton.bottom
|
|
|
|
anchors.topMargin: 3
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
color: Style.current.darkGrey
|
2020-09-14 12:12:47 +00:00
|
|
|
//% "before %1"
|
|
|
|
text: qsTrId("before--1").arg(new Date(chatsModel.oldestMsgTimestamp*1000).toDateString())
|
2020-09-04 11:55:24 +00:00
|
|
|
}
|
|
|
|
Separator {
|
|
|
|
anchors.top: fetchDate.bottom
|
|
|
|
anchors.topMargin: Style.current.smallPadding
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
Component {
|
|
|
|
id: channelIdentifierComponent
|
|
|
|
ChannelIdentifier {
|
2020-12-07 23:38:53 +00:00
|
|
|
authorCurrentMsg: root.authorCurrentMsg
|
2020-11-30 17:03:52 +00:00
|
|
|
profileImage: profileImageSource
|
2020-06-10 18:23:18 +00:00
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
// Private group Messages
|
|
|
|
Component {
|
|
|
|
id: privateGroupHeaderComponent
|
|
|
|
StyledText {
|
2020-06-25 20:17:42 +00:00
|
|
|
wrapMode: Text.Wrap
|
2020-11-30 17:03:52 +00:00
|
|
|
text: {
|
2020-09-21 15:47:15 +00:00
|
|
|
return `<html>`+
|
|
|
|
`<head>`+
|
|
|
|
`<style type="text/css">`+
|
|
|
|
`a {`+
|
|
|
|
`color: ${Style.current.textColor};`+
|
|
|
|
`text-decoration: none;`+
|
|
|
|
`}`+
|
|
|
|
`</style>`+
|
|
|
|
`</head>`+
|
|
|
|
`<body>`+
|
|
|
|
`${message}`+
|
|
|
|
`</body>`+
|
|
|
|
`</html>`;
|
|
|
|
}
|
2020-07-15 21:04:14 +00:00
|
|
|
visible: isStatusMessage
|
2020-09-21 15:47:15 +00:00
|
|
|
font.pixelSize: 14
|
|
|
|
color: Style.current.secondaryText
|
2020-07-15 21:04:14 +00:00
|
|
|
width: parent.width - 120
|
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
textFormat: Text.RichText
|
2020-12-07 23:38:53 +00:00
|
|
|
topPadding: root.prevMessageIndex === 1 ? Style.current.bigPadding : 0
|
2020-07-09 17:47:36 +00:00
|
|
|
}
|
2020-07-09 15:50:38 +00:00
|
|
|
}
|
2020-05-28 19:32:14 +00:00
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
Component {
|
|
|
|
id: messageComponent
|
|
|
|
NormalMessage {
|
2020-12-07 23:38:53 +00:00
|
|
|
clickMessage: root.clickMessage
|
|
|
|
linkUrls: root.linkUrls
|
|
|
|
isCurrentUser: root.isCurrentUser
|
|
|
|
contentType: root.contentType
|
2020-12-16 20:50:54 +00:00
|
|
|
container: root
|
2020-05-28 19:32:14 +00:00
|
|
|
}
|
2020-07-09 15:50:38 +00:00
|
|
|
}
|
2020-07-10 15:37:23 +00:00
|
|
|
|
2020-12-10 11:47:30 +00:00
|
|
|
Component {
|
|
|
|
id: statusUpdateComponent
|
|
|
|
StatusUpdate {
|
2020-12-16 20:50:54 +00:00
|
|
|
clickMessage: root.clickMessage
|
|
|
|
container: root
|
2020-12-10 11:47:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 21:04:14 +00:00
|
|
|
Component {
|
|
|
|
id: compactMessageComponent
|
|
|
|
CompactMessage {
|
2020-12-07 23:38:53 +00:00
|
|
|
clickMessage: root.clickMessage
|
|
|
|
linkUrls: root.linkUrls
|
feat: whitelist gifs (no url extension needed)
Fixes #1377.
Fixes #1479.
Two sites have been added to the whitelist: giphy.com and tenor.com.
`imageUrls` in its entirety has been removed and instead all links are being handle through the message `linkUrls`. This prevents double-handling of urls that may or may not be images.
The logic to automatically show links previews works like this:
1. If the setting "display chat images" is enabled, all links that *contain* ".png", ".jpg", ".jpeg", ".svg", ".gif" will be automatically shown. If the URL doesn't contain the extension, we are not downloading it. This was meant to be somewhat of a security compromise as we do not want to download each and every link posted in a message just to find out its true content type.
2. If the above setting is *disabled*, then we follow the whitelist settings for tenor and giphy. This allows us to preview gifs that do not have a file extension in their url.
feat: bump status-go to the commit that supports the new whitelist (https://github.com/status-im/status-go/pull/2094), and also lets us get link preview data from urls in the whitelist. NOTE: this commit was branched off status-go `develop`, so once it is merged, and we update this PR to the new commit, we will effectively be getting status-go develop changes. We *could* base that status-go PR off of master if it makes things easier.
fix: height on settings update issue
feat: move date/time of message below links
fix: layout issues when changing setting `neverAskAboutUnfurlingAgain`
feat: Add MessageBorder component to aid in showing rounded corners with different radius
2020-12-11 00:53:44 +00:00
|
|
|
isCurrentUser: root.isCurrentUser
|
2020-12-07 23:38:53 +00:00
|
|
|
contentType: root.contentType
|
2020-12-16 20:50:54 +00:00
|
|
|
container: root
|
2020-07-10 15:37:23 +00:00
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
2020-09-03 20:43:08 +00:00
|
|
|
|
2020-12-11 20:38:10 +00:00
|
|
|
Component {
|
|
|
|
id: invitationBubble
|
|
|
|
InvitationBubble {}
|
|
|
|
}
|
2020-05-27 22:59:17 +00:00
|
|
|
}
|
2020-05-28 15:55:52 +00:00
|
|
|
|
|
|
|
/*##^##
|
|
|
|
Designer {
|
2020-07-09 17:29:19 +00:00
|
|
|
D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.75;height:80;width:800}
|
2020-05-28 15:55:52 +00:00
|
|
|
}
|
|
|
|
##^##*/
|