diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro index 9cdc842..3e22d53 100644 --- a/harbour-fernschreiber.pro +++ b/harbour-fernschreiber.pro @@ -40,6 +40,8 @@ DISTFILES += qml/harbour-fernschreiber.qml \ qml/components/ImagePreview.qml \ qml/components/InReplyToRow.qml \ qml/components/LocationPreview.qml \ + qml/components/MessageListViewItem.qml \ + qml/components/MessageListViewItemSimple.qml \ qml/components/PollPreview.qml \ qml/components/StickerPicker.qml \ qml/components/PhotoTextsListItem.qml \ diff --git a/qml/components/MessageListViewItem.qml b/qml/components/MessageListViewItem.qml new file mode 100644 index 0000000..caf33f6 --- /dev/null +++ b/qml/components/MessageListViewItem.qml @@ -0,0 +1,391 @@ +/* + Copyright (C) 2020 Sebastian J. Wolf and other contributors + + This file is part of Fernschreiber. + + Fernschreiber is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Fernschreiber is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fernschreiber. If not, see . +*/ +import QtQuick 2.6 +import Sailfish.Silica 1.0 +import "../js/twemoji.js" as Emoji +import "../js/functions.js" as Functions + +ListItem { + id: messageListItem + contentHeight: messageBackground.height + Theme.paddingMedium + property variant myMessage: display + property variant userInformation: tdLibWrapper.getUserInformation(display.sender_user_id) + property Page page: chatPage + + property bool isOwnMessage: chatPage.myUserId === display.sender_user_id + property string extraContentComponentName: typeof display.content !== "undefined" + && chatView.contentComponentNames.hasOwnProperty(display.content['@type']) ? + chatView.contentComponentNames[display.content['@type']] : "" + menu: ContextMenu { + MenuItem { + onClicked: { + newMessageInReplyToRow.inReplyToMessage = display; + newMessageTextField.focus = true; + } + text: qsTr("Reply to Message") + } + MenuItem { + onClicked: { + newMessageColumn.editMessageId = display.id; + newMessageTextField.text = Functions.getMessageText(display, false, false); + newMessageTextField.focus = true; + } + text: qsTr("Edit Message") + visible: display.can_be_edited + } + MenuItem { + onClicked: { + Clipboard.text = Functions.getMessageText(display, true, false); + } + text: qsTr("Copy Message to Clipboard") + } + MenuItem { + onClicked: { + var chatId = chatInformation.id; + var messageId = display.id; + Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() { tdLibWrapper.deleteMessages(chatId, [ messageId]); }) + } + text: qsTr("Delete Message") + visible: display.can_be_deleted_for_all_users || (display.can_be_deleted_only_for_self && display.chat_id === chatPage.myUserId) + } + } + + Connections { + target: chatModel + onUnreadCountUpdated: { + messageBackground.color = index > ( chatView.count - unreadCount - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor; + messageBackground.opacity = index > ( chatView.count - unreadCount - 1 ) ? 0.5 : 0.2; + } + onNewMessageReceived: { + messageBackground.color = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor; + messageBackground.opacity = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? 0.5 : 0.2; + } + + onLastReadSentMessageUpdated: { + console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex)); + messageDateText.text = getMessageStatusText(display, index, lastReadSentIndex, messageDateText.useElapsed); + } + onMessageUpdated: { + if (index === modelIndex) { + console.log("[ChatModel] This message was updated, index " + index + ", updating content..."); + messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); + messageText.text = Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), messageText.font.pixelSize); + if(locationPreviewLoader.active && locationPreviewLoader.status === Loader.Ready) { + locationPreviewLoader.item.locationData = display.content.location; + locationPreviewLoader.item.updatePicture() + } + } + } + } + + Connections { + target: tdLibWrapper + onReceivedMessage: { + if (messageId === display.reply_to_message_id.toString()) { + messageInReplyToRow.inReplyToMessage = message; + messageInReplyToRow.visible = true; + } + } + } + + Component.onCompleted: { + delegateComponentLoadingTimer.start(); + } + + Timer { + id: delegateComponentLoadingTimer + interval: 500 + repeat: false + running: false + onTriggered: { + if (typeof display.content !== "undefined") { + if (messageListItem.extraContentComponentName !== "") { + extraContentLoader.setSource( + "../components/" +messageListItem.extraContentComponentName +".qml", + { + messageListItem: messageListItem + }) + } else { + if (typeof display.content.web_page !== "undefined") { // only in messageText + webPagePreviewLoader.active = true; + } + } + } + } + } + + Row { + id: messageTextRow + spacing: Theme.paddingSmall + width: parent.width - ( 2 * Theme.horizontalPageMargin ) + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + Loader { + id: profileThumbnailLoader + active: (( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel) + asynchronous: true + width: active ? Theme.itemSizeSmall : 0 + height: active ? Theme.itemSizeSmall : 0 + anchors.bottom: parent.bottom + anchors.bottomMargin: Theme.paddingSmall + sourceComponent: Component { + ProfileThumbnail { + id: messagePictureThumbnail + photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : "" + replacementStringHint: userText.text + width: visible ? Theme.itemSizeSmall : 0 + height: visible ? Theme.itemSizeSmall : 0 + visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel + MouseArea { + anchors.fill: parent + onClicked: { + tdLibWrapper.createPrivateChat(messageListItem.userInformation.id); + } + } + } + } + } + + Item { + id: messageTextItem + + width: parent.width - profileThumbnailLoader.width - Theme.paddingSmall + height: messageBackground.height + + Rectangle { + id: messageBackground + anchors { + left: parent.left + leftMargin: messageListItem.isOwnMessage ? 2 * Theme.horizontalPageMargin : 0 + right: parent.right + rightMargin: messageListItem.isOwnMessage ? 0 : 2 * Theme.horizontalPageMargin + verticalCenter: parent.verticalCenter + } + height: messageTextColumn.height + ( 2 * Theme.paddingMedium ) + + color: index > ( chatView.count - chatInformation.unread_count - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor + radius: parent.width / 50 + opacity: index > ( chatView.count - chatInformation.unread_count - 1 ) ? 0.5 : 0.2 + visible: appSettings.showStickersAsImages || display.content['@type'] !== "messageSticker" + Behavior on color { ColorAnimation { duration: 200 } } + Behavior on opacity { FadeAnimation {} } + } + + Column { + id: messageTextColumn + + spacing: Theme.paddingSmall + + width: messageBackground.width - Theme.horizontalPageMargin + anchors.centerIn: messageBackground + + Component.onCompleted: { + if (display.reply_to_message_id !== 0) { + tdLibWrapper.getMessage(chatInformation.id, display.reply_to_message_id); + } + } + + + Text { + id: userText + + width: parent.width + text: !messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You") + font.pixelSize: Theme.fontSizeExtraSmall + font.weight: Font.ExtraBold + color: messageListItem.isOwnMessage ? Theme.highlightColor : Theme.primaryColor + maximumLineCount: 1 + elide: Text.ElideRight + textFormat: Text.StyledText + horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft + visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel + MouseArea { + anchors.fill: parent + onClicked: { + tdLibWrapper.createPrivateChat(messageListItem.userInformation.id); + } + } + } + + InReplyToRow { + id: messageInReplyToRow + myUserId: chatPage.myUserId + visible: false + } + + Loader { + id: forwardedInformationLoader + active: typeof display.forward_info !== "undefined" + asynchronous: true + width: parent.width + // height: active ? ( item ? item.height : Theme.itemSizeExtraSmall ) : 0 + sourceComponent: Component { + Row { + id: forwardedMessageInformationRow + spacing: Theme.paddingSmall + width: parent.width + + Component.onCompleted: { + if (display.forward_info.origin["@type"] === "messageForwardOriginChannel") { + var otherChatInformation = tdLibWrapper.getChat(display.forward_info.origin.chat_id); + forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : ""; + forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall); + } else if (display.forward_info.origin["@type"] === "messageForwardOriginUser") { + var otherUserInformation = tdLibWrapper.getUserInformation(display.forward_info.origin.sender_user_id); + forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : ""; + forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall); + } else { + forwardedThumbnail.photoData = ""; + forwardedChannelText.text = Emoji.emojify(display.forward_info.origin.sender_user_name, Theme.fontSizeExtraSmall); + } + } + + ProfileThumbnail { + id: forwardedThumbnail + replacementStringHint: forwardedChannelText.text + width: Theme.itemSizeExtraSmall + height: Theme.itemSizeExtraSmall + } + + Column { + spacing: Theme.paddingSmall + width: parent.width + Text { + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.primaryColor + width: parent.width + font.italic: true + elide: Text.ElideRight + textFormat: Text.StyledText + text: qsTr("Forwarded Message") + onTruncatedChanged: { + // There is obviously a bug in QML in truncating text with images. + // We simply remove Emojis then... + if (truncated) { + text = text.replace(/\]+\/\>/g, ""); + } + } + } + Text { + id: forwardedChannelText + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.primaryColor + width: parent.width + font.bold: true + elide: Text.ElideRight + textFormat: Text.StyledText + text: Emoji.emojify(forwardedMessageInformationRow.otherChatInformation.title, font.pixelSize) + onTruncatedChanged: { + // There is obviously a bug in QML in truncating text with images. + // We simply remove Emojis then... + if (truncated) { + text = text.replace(/\]+\/\>/g, ""); + } + } + } + } + + + } + } + } + + Text { + id: messageText + width: parent.width + text: Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), font.pixelSize) + font.pixelSize: Theme.fontSizeSmall + color: messageListItem.isOwnMessage ? Theme.highlightColor : Theme.primaryColor + wrapMode: Text.Wrap + textFormat: Text.StyledText + onLinkActivated: { + Functions.handleLink(link); + } + horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft + linkColor: Theme.highlightColor + visible: (text !== "") + } + + Loader { + id: webPagePreviewLoader + active: false + asynchronous: true + width: parent.width + height: typeof display.content.web_page !== "undefined" ? ( (parent.width * 2 / 3) + (6 * Theme.fontSizeExtraSmall) + ( 7 * Theme.paddingSmall) ) : 0 + + sourceComponent: Component { + id: webPagePreviewComponent + WebPagePreview { + id: webPagePreview + + onImplicitHeightChanged: { + webPagePreviewLoader.height = webPagePreview.implicitHeight; + } + + webPageData: display.content.web_page + width: parent.width + } + } + } + Loader { + id: extraContentLoader + width: parent.width + asynchronous: true + property int heightPreset: messageListItem.extraContentComponentName !== "" ? chatView.getContentComponentHeight(messageListItem.extraContentComponentName, display.content, width) : 0 + height: item ? item.height : heightPreset + } + + Timer { + id: messageDateUpdater + interval: 60000 + running: true + repeat: true + onTriggered: { + messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); + } + } + + + Text { + width: parent.width + + property bool useElapsed: true + + id: messageDateText + font.pixelSize: Theme.fontSizeTiny + color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor + horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft + text: getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed) + MouseArea { + anchors.fill: parent + onClicked: { + messageDateText.useElapsed = !messageDateText.useElapsed; + messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); + } + } + } + + } + + } + + } + +} diff --git a/qml/components/MessageListViewItemSimple.qml b/qml/components/MessageListViewItemSimple.qml new file mode 100644 index 0000000..5d86162 --- /dev/null +++ b/qml/components/MessageListViewItemSimple.qml @@ -0,0 +1,53 @@ +/* + Copyright (C) 2020 Sebastian J. Wolf and other contributors + + This file is part of Fernschreiber. + + Fernschreiber is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Fernschreiber is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fernschreiber. If not, see . +*/ +import QtQuick 2.6 +import Sailfish.Silica 1.0 +import "../js/twemoji.js" as Emoji +import "../js/functions.js" as Functions + +Item { + id: messageListItem + property variant myMessage: display + property variant userInformation: tdLibWrapper.getUserInformation(myMessage.sender_user_id) + property bool isOwnMessage: chatPage.myUserId === myMessage.sender_user_id + height: backgroundRectangle.height + Theme.paddingMedium + + Rectangle { + id: backgroundRectangle + anchors.centerIn: parent + height: messageText.height + Theme.paddingMedium * 2 + width: Math.min(messageText.implicitWidth, messageText.contentWidth) + Theme.paddingMedium * 2 + color: Theme.rgba(Theme.secondaryColor, 0.1) + radius: parent.width / 50 + } + Text { + id: messageText + width: parent.width - Theme.paddingMedium * 4 - Theme.horizontalPageMargin * 2 + anchors.centerIn: parent + color: Theme.highlightColor + horizontalAlignment: Text.AlignHCenter + font.pixelSize: Theme.fontSizeExtraSmall + text: "" + (!messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You")) + " " + Emoji.emojify(Functions.getMessageText(messageListItem.myMessage, false, messageListItem.isOwnMessage), font.pixelSize) + textFormat: Text.RichText + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + onLinkActivated: { + Functions.handleLink(link); + } + } +} diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index 41f7901..ca84b30 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -572,379 +572,19 @@ Page { } } - delegate: ListItem { - id: messageListItem - contentHeight: messageBackground.height + Theme.paddingMedium - contentWidth: parent.width - - property variant myMessage: display - property variant userInformation: tdLibWrapper.getUserInformation(display.sender_user_id) - property Page page: chatPage - - property bool isOwnMessage: chatPage.myUserId === display.sender_user_id - property string extraContentComponentName: typeof display.content !== "undefined" - && chatView.contentComponentNames.hasOwnProperty(display.content['@type']) ? - chatView.contentComponentNames[display.content['@type']] : "" - menu: ContextMenu { - MenuItem { - onClicked: { - newMessageInReplyToRow.inReplyToMessage = display; - newMessageTextField.focus = true; - } - text: qsTr("Reply to Message") - } - MenuItem { - onClicked: { - newMessageColumn.editMessageId = display.id; - newMessageTextField.text = Functions.getMessageText(display, false, false); - newMessageTextField.focus = true; - } - text: qsTr("Edit Message") - visible: display.can_be_edited - } - MenuItem { - onClicked: { - Clipboard.text = Functions.getMessageText(display, true, false); - } - text: qsTr("Copy Message to Clipboard") - } - MenuItem { - onClicked: { - var chatId = chatInformation.id; - var messageId = display.id; - Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() { tdLibWrapper.deleteMessages(chatId, [ messageId]); }) - } - text: qsTr("Delete Message") - visible: display.can_be_deleted_for_all_users || (display.can_be_deleted_only_for_self && display.chat_id === chatPage.myUserId) - } + property var simpleDelegateMessages: ["messageBasicGroupChatCreate", "messageChatAddMembers", "messageChatChangePhoto", "messageChatChangeTitle", "messageChatDeleteMember", "messageChatDeletePhoto", "messageChatJoinByLink", "messageChatSetTtl", "messageChatUpgradeFrom", "messageChatUpgradeTo", "messageCustomServiceAction", "messagePinMessage", "messageScreenshotTaken", "messageSupergroupChatCreate", "messageUnsupported"] + delegate: Loader { + width: chatView.width + Component { + id: messageListViewItemComponent + MessageListViewItem {} } - - Connections { - target: chatModel - onUnreadCountUpdated: { - messageBackground.color = index > ( chatView.count - unreadCount - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor; - messageBackground.opacity = index > ( chatView.count - unreadCount - 1 ) ? 0.5 : 0.2; - } - onNewMessageReceived: { - messageBackground.color = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor; - messageBackground.opacity = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? 0.5 : 0.2; - } - - onLastReadSentMessageUpdated: { - console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex)); - messageDateText.text = getMessageStatusText(display, index, lastReadSentIndex, messageDateText.useElapsed); - } - onMessageUpdated: { - if (index === modelIndex) { - console.log("[ChatModel] This message was updated, index " + index + ", updating content..."); - messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); - messageText.text = Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), messageText.font.pixelSize); - if(locationPreviewLoader.active && locationPreviewLoader.status === Loader.Ready) { - locationPreviewLoader.item.locationData = display.content.location; - locationPreviewLoader.item.updatePicture() - } - } - } + Component { + id: messageListViewItemSimpleComponent + MessageListViewItemSimple {} } - - Connections { - target: tdLibWrapper - onReceivedMessage: { - if (messageId === display.reply_to_message_id.toString()) { - messageInReplyToRow.inReplyToMessage = message; - messageInReplyToRow.visible = true; - } - } - } - - Component.onCompleted: { - delegateComponentLoadingTimer.start(); - } - - Timer { - id: delegateComponentLoadingTimer - interval: 500 - repeat: false - running: false - onTriggered: { - if (typeof display.content !== "undefined") { - if (messageListItem.extraContentComponentName !== "") { - extraContentLoader.setSource( - "../components/" +messageListItem.extraContentComponentName +".qml", - { - messageListItem: messageListItem - }) - } else { - if (typeof display.content.web_page !== "undefined") { // only in messageText - webPagePreviewLoader.active = true; - } - } - } - } - } - - - Row { - id: messageTextRow - spacing: Theme.paddingSmall - width: parent.width - ( 2 * Theme.horizontalPageMargin ) - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - - Loader { - id: profileThumbnailLoader - active: (( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel) - asynchronous: true - width: active ? Theme.itemSizeSmall : 0 - height: active ? Theme.itemSizeSmall : 0 - anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.paddingSmall - sourceComponent: Component { - ProfileThumbnail { - id: messagePictureThumbnail - photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : "" - replacementStringHint: userText.text - width: visible ? Theme.itemSizeSmall : 0 - height: visible ? Theme.itemSizeSmall : 0 - visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel - MouseArea { - anchors.fill: parent - onClicked: { - tdLibWrapper.createPrivateChat(messageListItem.userInformation.id); - } - } - } - } - } - - Item { - id: messageTextItem - - width: parent.width - profileThumbnailLoader.width - Theme.paddingSmall - height: messageBackground.height - - Rectangle { - id: messageBackground - anchors { - left: parent.left - leftMargin: messageListItem.isOwnMessage ? 2 * Theme.horizontalPageMargin : 0 - right: parent.right - rightMargin: messageListItem.isOwnMessage ? 0 : 2 * Theme.horizontalPageMargin - verticalCenter: parent.verticalCenter - } - height: messageTextColumn.height + ( 2 * Theme.paddingMedium ) - - color: index > ( chatView.count - chatInformation.unread_count - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor - Behavior on color { ColorAnimation { duration: 200 } } - Behavior on opacity { FadeAnimation {} } - radius: parent.width / 50 - opacity: index > ( chatView.count - chatInformation.unread_count - 1 ) ? 0.5 : 0.2 - visible: appSettings.showStickersAsImages || display.content['@type'] !== "messageSticker" - } - - Column { - id: messageTextColumn - - spacing: Theme.paddingSmall - - width: messageBackground.width - Theme.horizontalPageMargin - anchors.centerIn: messageBackground - - Component.onCompleted: { - if (display.reply_to_message_id !== 0) { - tdLibWrapper.getMessage(chatInformation.id, display.reply_to_message_id); - } - } - - - Text { - id: userText - - width: parent.width - text: !messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You") - font.pixelSize: Theme.fontSizeExtraSmall - font.weight: Font.ExtraBold - color: messageListItem.isOwnMessage ? Theme.highlightColor : Theme.primaryColor - maximumLineCount: 1 - elide: Text.ElideRight - textFormat: Text.StyledText - horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft - visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel - MouseArea { - anchors.fill: parent - onClicked: { - tdLibWrapper.createPrivateChat(messageListItem.userInformation.id); - } - } - } - - InReplyToRow { - id: messageInReplyToRow - myUserId: chatPage.myUserId - visible: false - } - - Loader { - id: forwardedInformationLoader - active: typeof display.forward_info !== "undefined" - asynchronous: true - width: parent.width -// height: active ? ( item ? item.height : Theme.itemSizeExtraSmall ) : 0 - sourceComponent: Component { - Row { - id: forwardedMessageInformationRow - spacing: Theme.paddingSmall - width: parent.width - - Component.onCompleted: { - if (display.forward_info.origin["@type"] === "messageForwardOriginChannel") { - var otherChatInformation = tdLibWrapper.getChat(display.forward_info.origin.chat_id); - forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : ""; - forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall); - } else if (display.forward_info.origin["@type"] === "messageForwardOriginUser") { - var otherUserInformation = tdLibWrapper.getUserInformation(display.forward_info.origin.sender_user_id); - forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : ""; - forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall); - } else { - forwardedThumbnail.photoData = ""; - forwardedChannelText.text = Emoji.emojify(display.forward_info.origin.sender_user_name, Theme.fontSizeExtraSmall); - } - } - - ProfileThumbnail { - id: forwardedThumbnail - replacementStringHint: forwardedChannelText.text - width: Theme.itemSizeExtraSmall - height: Theme.itemSizeExtraSmall - } - - Column { - spacing: Theme.paddingSmall - width: parent.width - Text { - font.pixelSize: Theme.fontSizeExtraSmall - color: Theme.primaryColor - width: parent.width - font.italic: true - elide: Text.ElideRight - textFormat: Text.StyledText - text: qsTr("Forwarded Message") - onTruncatedChanged: { - // There is obviously a bug in QML in truncating text with images. - // We simply remove Emojis then... - if (truncated) { - text = text.replace(/\]+\/\>/g, ""); - } - } - } - Text { - id: forwardedChannelText - font.pixelSize: Theme.fontSizeExtraSmall - color: Theme.primaryColor - width: parent.width - font.bold: true - elide: Text.ElideRight - textFormat: Text.StyledText - text: Emoji.emojify(forwardedMessageInformationRow.otherChatInformation.title, font.pixelSize) - onTruncatedChanged: { - // There is obviously a bug in QML in truncating text with images. - // We simply remove Emojis then... - if (truncated) { - text = text.replace(/\]+\/\>/g, ""); - } - } - } - } - - - } - } - } - - Text { - id: messageText - - width: parent.width - text: Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), font.pixelSize) - font.pixelSize: Theme.fontSizeSmall - color: messageListItem.isOwnMessage ? Theme.highlightColor : Theme.primaryColor - wrapMode: Text.Wrap - textFormat: Text.StyledText - onLinkActivated: { - Functions.handleLink(link); - } - horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft - linkColor: Theme.highlightColor - visible: (text !== "") - } - - Loader { - id: webPagePreviewLoader - active: false - asynchronous: true - width: parent.width - height: typeof display.content.web_page !== "undefined" ? ( (parent.width * 2 / 3) + (6 * Theme.fontSizeExtraSmall) + ( 7 * Theme.paddingSmall) ) : 0 - - sourceComponent: Component { - id: webPagePreviewComponent - WebPagePreview { - id: webPagePreview - - onImplicitHeightChanged: { - webPagePreviewLoader.height = webPagePreview.implicitHeight; - } - - webPageData: display.content.web_page - width: parent.width - } - } - } - Loader { - id: extraContentLoader - width: parent.width - asynchronous: true - property int heightPreset: messageListItem.extraContentComponentName !== "" ? chatView.getContentComponentHeight(messageListItem.extraContentComponentName, display.content, width) : 0 - height: item ? item.height : heightPreset - } - - Timer { - id: messageDateUpdater - interval: 60000 - running: true - repeat: true - onTriggered: { - messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); - } - } - - - Text { - width: parent.width - - property bool useElapsed: true - - id: messageDateText - font.pixelSize: Theme.fontSizeTiny - color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor - horizontalAlignment: messageListItem.isOwnMessage ? Text.AlignRight : Text.AlignLeft - text: getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed) - MouseArea { - anchors.fill: parent - onClicked: { - messageDateText.useElapsed = !messageDateText.useElapsed; - messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex, messageDateText.useElapsed); - } - } - } - - } - - } - - } - + sourceComponent: chatView.simpleDelegateMessages.indexOf(display.content['@type']) > -1 ? messageListViewItemSimpleComponent : messageListViewItemComponent } - VerticalScrollDecorator {} ViewPlaceholder {