Update ConversationMessage.qml to latest version used in Kaidan
This commit is contained in:
parent
ea29574c93
commit
91765a354d
8 changed files with 377 additions and 91 deletions
|
@ -20,6 +20,9 @@
|
|||
*/
|
||||
|
||||
#include "conversationmodel.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QGuiApplication>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
@ -95,10 +98,17 @@ void ConversationModel::requestMoreMessages(const quint32& howMany)
|
|||
m_conversationsInterface->requestConversation(m_threadId, numMessages, numMessages + howMany);
|
||||
}
|
||||
|
||||
QString ConversationModel::getTitleForAddresses(const QList<ConversationAddress>& addresses) {
|
||||
QString ConversationModel::getTitleForAddresses(const QList<ConversationAddress>& addresses)
|
||||
{
|
||||
return SmsHelper::getTitleForAddresses(addresses);
|
||||
}
|
||||
|
||||
void ConversationModel::copyToClipboard(const QString& message) const
|
||||
{
|
||||
// TODO: Remove this method as part of abstracting GUI elements to library
|
||||
QGuiApplication::clipboard()->setText(message);
|
||||
}
|
||||
|
||||
void ConversationModel::createRowFromMessage(const ConversationMessage& message, int pos)
|
||||
{
|
||||
if (message.threadID() != m_threadId) {
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
Q_INVOKABLE void sendReplyToConversation(const QString& message);
|
||||
Q_INVOKABLE void requestMoreMessages(const quint32& howMany = 10);
|
||||
Q_INVOKABLE QString getTitleForAddresses(const QList<ConversationAddress>& addresses);
|
||||
Q_INVOKABLE void copyToClipboard(const QString& message) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleConversationUpdate(const QDBusVariant &message);
|
||||
|
|
58
smsapp/qml/Avatar.qml
Normal file
58
smsapp/qml/Avatar.qml
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Kaidan - A user-friendly XMPP client for every device!
|
||||
*
|
||||
* Copyright (C) 2016-2019 Kaidan developers and contributors
|
||||
* (see the LICENSE file for a full list of copyright authors)
|
||||
*
|
||||
* Kaidan 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.
|
||||
*
|
||||
* In addition, as a special exception, the author of Kaidan gives
|
||||
* permission to link the code of its release with the OpenSSL
|
||||
* project's "OpenSSL" library (or with modified versions of it that
|
||||
* use the same license as the "OpenSSL" library), and distribute the
|
||||
* linked executables. You must obey the GNU General Public License in
|
||||
* all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify this file, you may extend this exception to your version of
|
||||
* the file, but you are not obligated to do so. If you do not wish to
|
||||
* do so, delete this exception statement from your version.
|
||||
*
|
||||
* Kaidan 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 Kaidan. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import org.kde.kirigami 2.2 as Kirigami
|
||||
|
||||
Item {
|
||||
id: avatar
|
||||
property string avatarUrl
|
||||
property string name
|
||||
|
||||
RoundImage {
|
||||
id: imageAvatar
|
||||
visible: avatarUrl
|
||||
source: avatarUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
height: width
|
||||
anchors.fill: parent
|
||||
isRound: true
|
||||
}
|
||||
|
||||
TextAvatar {
|
||||
id: textAvatar
|
||||
visible: !avatarUrl
|
||||
name: avatar.name
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Kaidan - A user-friendly XMPP client for every device!
|
||||
*
|
||||
* Copyright (C) 2016-2018 Kaidan developers and contributors
|
||||
* Copyright (C) 2016-2019 Kaidan developers and contributors
|
||||
* (see the LICENSE file for a full list of copyright authors)
|
||||
*
|
||||
* Kaidan is free software: you can redistribute it and/or modify
|
||||
|
@ -25,93 +25,226 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kaidan. If not, see <https://www.gnu.org/licenses/>.
|
||||
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.0 as Controls
|
||||
import QtQuick.Controls 2.2 as Controls
|
||||
import org.kde.kirigami 2.0 as Kirigami
|
||||
//import im.kaidan.kaidan 1.0
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property bool sentByMe: true
|
||||
property string messageBody
|
||||
property date dateTime
|
||||
property bool isRead: false
|
||||
property string recipientAvatarUrl
|
||||
property string senderName
|
||||
property string msgId
|
||||
property string sender
|
||||
property bool sentByMe: true
|
||||
property string messageBody
|
||||
property date dateTime
|
||||
property bool isRead: false
|
||||
property int mediaType
|
||||
property string mediaGetUrl
|
||||
property string mediaLocation
|
||||
property bool edited
|
||||
// property bool isLoading: kaidan.transferCache.hasUpload(msgId)
|
||||
property string name
|
||||
// property TransferJob upload: {
|
||||
// if (mediaType !== Enums.MessageType.MessageText && isLoading) {
|
||||
// return kaidan.transferCache.jobByMessageId(model.id)
|
||||
// }
|
||||
//
|
||||
// return null
|
||||
// }
|
||||
property bool isSpoiler
|
||||
property string spoilerHint
|
||||
property bool isShowingSpoiler: false
|
||||
property string avatarUrl: null//kaidan.avatarStorage.getAvatarUrl(sender)
|
||||
|
||||
// own messages are on the right, others on the left
|
||||
layoutDirection: sentByMe ? Qt.RightToLeft : Qt.LeftToRight
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
width: parent.width - Kirigami.Units.largeSpacing * 4
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
signal messageCopyRequested(string message)
|
||||
|
||||
RoundImage {
|
||||
id: avatar
|
||||
visible: !sentByMe
|
||||
source: recipientAvatarUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
height: width
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.2
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 2.2
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
sourceSize.height: Kirigami.Units.gridUnit * 2.2
|
||||
sourceSize.width: Kirigami.Units.gridUnit * 2.2
|
||||
}
|
||||
// own messages are on the right, others on the left
|
||||
layoutDirection: sentByMe ? Qt.RightToLeft : Qt.LeftToRight
|
||||
spacing: 8
|
||||
width: ListView.view.width
|
||||
|
||||
Rectangle {
|
||||
id: box
|
||||
Layout.preferredWidth: content.width + Kirigami.Units.gridUnit * 0.9
|
||||
Layout.preferredHeight: content.height + Kirigami.Units.gridUnit * 0.6
|
||||
// placeholder
|
||||
Item {
|
||||
Layout.preferredWidth: root.layoutDirection === Qt.LeftToRight ? 5 : 10
|
||||
}
|
||||
|
||||
color: sentByMe ? Kirigami.Theme.complementaryTextColor : Kirigami.Theme.highlightColor
|
||||
radius: Kirigami.Units.smallSpacing * 2
|
||||
Avatar {
|
||||
id: avatar
|
||||
visible: !sentByMe
|
||||
avatarUrl: root.avatarUrl
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
name: root.name
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.2
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 2.2
|
||||
}
|
||||
|
||||
layer.enabled: box.visible
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: Kirigami.Units.gridUnit * 0.08
|
||||
horizontalOffset: Kirigami.Units.gridUnit * 0.08
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
samples: 10
|
||||
spread: 0.1
|
||||
}
|
||||
// message bubble/box
|
||||
Item {
|
||||
Layout.preferredWidth: content.width + 13
|
||||
Layout.preferredHeight: content.height + 8
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
spacing: 0
|
||||
anchors.centerIn: box
|
||||
Rectangle {
|
||||
id: box
|
||||
anchors.fill: parent
|
||||
color: sentByMe ? Kirigami.Theme.complementaryTextColor
|
||||
: Kirigami.Theme.highlightColor
|
||||
radius: Kirigami.Units.smallSpacing * 2
|
||||
layer.enabled: box.visible
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: Kirigami.Units.gridUnit * 0.08
|
||||
horizontalOffset: Kirigami.Units.gridUnit * 0.08
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
samples: 10
|
||||
spread: 0.1
|
||||
}
|
||||
|
||||
Controls.Label {
|
||||
id: senderNameLabel
|
||||
visible: !sentByMe && senderName != ""
|
||||
text: senderName
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton)
|
||||
contextMenu.popup()
|
||||
}
|
||||
onPressAndHold: {
|
||||
contextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
Controls.Label {
|
||||
text: messageBody
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
color: sentByMe ? Kirigami.Theme.viewTextColor : Kirigami.Theme.complementaryTextColor
|
||||
Layout.maximumWidth: root.width - Kirigami.Units.gridUnit * 6
|
||||
}
|
||||
Controls.Menu {
|
||||
id: contextMenu
|
||||
Controls.MenuItem {
|
||||
text: i18n("Copy Message")
|
||||
enabled: bodyLabel.visible
|
||||
onTriggered: {
|
||||
root.messageCopyRequested(messageBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Controls.Label {
|
||||
id: dateLabel
|
||||
text: Qt.formatDateTime(dateTime, "dd. MMM yyyy, hh:mm")
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: content
|
||||
spacing: 0
|
||||
anchors.centerIn: parent
|
||||
anchors.margins: 4
|
||||
RowLayout {
|
||||
id: spoilerHintRow
|
||||
visible: isSpoiler
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
isShowingSpoiler = !isShowingSpoiler
|
||||
}
|
||||
}
|
||||
}
|
||||
Controls.Label {
|
||||
id: dateLabeltest
|
||||
text: spoilerHint == "" ? qsTr("Spoiler") : spoilerHint
|
||||
color: sentByMe ? Kirigami.Theme.textColor
|
||||
: Kirigami.Theme.complementaryTextColor
|
||||
font.pixelSize: Kirigami.Units.gridUnit * 0.8
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
height: 28
|
||||
width: 28
|
||||
source: isShowingSpoiler ? "password-show-off" : "password-show-on"
|
||||
color: sentByMe ? Kirigami.Theme.textColor : Kirigami.Theme.complementaryTextColor
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
visible: isSpoiler
|
||||
Layout.fillWidth: true
|
||||
color: {
|
||||
var bgColor = sentByMe ? Kirigami.Theme.backgroundColor : Kirigami.Theme.highlightColor
|
||||
var textColor = sentByMe ? Kirigami.Theme.textColor : Kirigami.Theme.highlightedTextColor
|
||||
return Qt.tint(textColor, Qt.rgba(bgColor.r, bgColor.g, bgColor.b, 0.7))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: isSpoiler && isShowingSpoiler || !isSpoiler
|
||||
|
||||
|
||||
Controls.ToolButton {
|
||||
visible: {
|
||||
false
|
||||
// mediaType !== Enums.MessageText &&
|
||||
// !isLoading &&
|
||||
// mediaLocation === "" &&
|
||||
// mediaGetUrl !== ""
|
||||
}
|
||||
text: qsTr("Download")
|
||||
onClicked: {
|
||||
print("Downloading " + mediaGetUrl + "...")
|
||||
kaidan.downloadMedia(msgId, mediaGetUrl)
|
||||
}
|
||||
}
|
||||
|
||||
// message body
|
||||
Controls.Label {
|
||||
id: bodyLabel
|
||||
visible: messageBody !== "" && messageBody !== mediaGetUrl
|
||||
text: messageBody//kaidan.utils.formatMessage(messageBody)
|
||||
textFormat: Text.StyledText
|
||||
wrapMode: Text.Wrap
|
||||
color: sentByMe ? Kirigami.Theme.textColor
|
||||
: Kirigami.Theme.complementaryTextColor
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
|
||||
Layout.maximumWidth: root.width - Kirigami.Units.gridUnit * 6
|
||||
}
|
||||
Kirigami.Separator {
|
||||
visible: isSpoiler && isShowingSpoiler
|
||||
Layout.fillWidth: true
|
||||
color: {
|
||||
var bgColor = sentByMe ? Kirigami.Theme.backgroundColor : Kirigami.Theme.highlightColor
|
||||
var textColor = sentByMe ? Kirigami.Theme.textColor : Kirigami.Theme.highlightedTextColor
|
||||
return Qt.tint(textColor, Qt.rgba(bgColor.r, bgColor.g, bgColor.b, 0.7))
|
||||
}
|
||||
}
|
||||
}
|
||||
// message meta: date, isRead
|
||||
RowLayout {
|
||||
|
||||
Controls.Label {
|
||||
id: dateLabel
|
||||
text: Qt.formatDateTime(dateTime, "dd. MMM yyyy, hh:mm")
|
||||
color: sentByMe ? Kirigami.Theme.disabledTextColor
|
||||
: Qt.darker(Kirigami.Theme.disabledTextColor, 1.3)
|
||||
font.pixelSize: Kirigami.Units.gridUnit * 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// placeholder
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
function updateIsLoading() {
|
||||
isLoading = false
|
||||
// isLoading = kaidan.transferCache.hasUpload(msgId)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// kaidan.transferCache.jobsChanged.connect(updateIsLoading)
|
||||
}
|
||||
Component.onDestruction: {
|
||||
// kaidan.transferCache.jobsChanged.disconnect(updateIsLoading)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ Kirigami.ScrollablePage
|
|||
*/
|
||||
ChatMessage {
|
||||
id: genericMessage
|
||||
senderName: "Generic Sender"
|
||||
name: "Generic Sender"
|
||||
messageBody: "Generic Message Body"
|
||||
dateTime: new Date('2000-0-0')
|
||||
visible: false
|
||||
|
@ -110,7 +110,7 @@ Kirigami.ScrollablePage
|
|||
}
|
||||
|
||||
delegate: ChatMessage {
|
||||
senderName: model.sender
|
||||
name: model.sender
|
||||
messageBody: model.display
|
||||
sentByMe: model.fromMe
|
||||
dateTime: new Date(model.date)
|
||||
|
@ -139,6 +139,10 @@ Kirigami.ScrollablePage
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMessageCopyRequested: {
|
||||
conversationModel.copyToClipboard(message)
|
||||
}
|
||||
}
|
||||
|
||||
onMovementEnded: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Kaidan - A user-friendly XMPP client for every device!
|
||||
*
|
||||
* Copyright (C) 2017-2018 Kaidan developers and contributors
|
||||
* Copyright (C) 2016-2019 Kaidan developers and contributors
|
||||
* (see the LICENSE file for a full list of copyright authors)
|
||||
*
|
||||
* Kaidan is free software: you can redistribute it and/or modify
|
||||
|
@ -25,28 +25,28 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kaidan. If not, see <https://www.gnu.org/licenses/>.
|
||||
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Image {
|
||||
id: img
|
||||
property bool isRound: true
|
||||
id: img
|
||||
property bool isRound: true
|
||||
|
||||
layer.enabled: isRound
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Item {
|
||||
width: img.paintedWidth
|
||||
height: img.paintedHeight
|
||||
layer.enabled: isRound
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Item {
|
||||
width: img.paintedWidth
|
||||
height: img.paintedHeight
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(img.width, img.height)
|
||||
height: width
|
||||
radius: Math.min(width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(img.width, img.height)
|
||||
height: width
|
||||
radius: Math.min(width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
78
smsapp/qml/TextAvatar.qml
Normal file
78
smsapp/qml/TextAvatar.qml
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Kaidan - A user-friendly XMPP client for every device!
|
||||
*
|
||||
* Copyright (C) 2016-2019 Kaidan developers and contributors
|
||||
* (see the LICENSE file for a full list of copyright authors)
|
||||
*
|
||||
* Kaidan 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.
|
||||
*
|
||||
* In addition, as a special exception, the author of Kaidan gives
|
||||
* permission to link the code of its release with the OpenSSL
|
||||
* project's "OpenSSL" library (or with modified versions of it that
|
||||
* use the same license as the "OpenSSL" library), and distribute the
|
||||
* linked executables. You must obey the GNU General Public License in
|
||||
* all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify this file, you may extend this exception to your version of
|
||||
* the file, but you are not obligated to do so. If you do not wish to
|
||||
* do so, delete this exception statement from your version.
|
||||
*
|
||||
* Kaidan 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 Kaidan. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.kde.kirigami 2.2 as Kirigami
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.2
|
||||
|
||||
Rectangle {
|
||||
id: avatar
|
||||
|
||||
property string name
|
||||
|
||||
color: Kirigami.Theme.highlightColor//Qt.lighter(kaidan.utils.getUserColor(name))
|
||||
radius: width * 0.5
|
||||
|
||||
Text {
|
||||
id: text
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.devicePixelRatio * 5
|
||||
|
||||
property var model
|
||||
|
||||
renderType: Text.QtRendering
|
||||
color: Kirigami.Theme.textColor
|
||||
|
||||
font.weight: Font.Bold
|
||||
font.pointSize: 100
|
||||
minimumPointSize: Kirigami.Theme.defaultFont.pointSize
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
text: {
|
||||
if (!name) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// WIPQTQUICK HACK TODO Probably doesn't work with non-latin1.
|
||||
var match = name.match(/([a-zA-Z0-9])([a-zA-Z0-9])/);
|
||||
var abbrev = match[1].toUpperCase();
|
||||
|
||||
if (match.length > 2) {
|
||||
abbrev += match[2].toLowerCase();
|
||||
}
|
||||
|
||||
return abbrev;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,5 +5,7 @@
|
|||
<file>qml/ConversationDisplay.qml</file>
|
||||
<file>qml/ChatMessage.qml</file>
|
||||
<file>qml/RoundImage.qml</file>
|
||||
<file>qml/Avatar.qml</file>
|
||||
<file>qml/TextAvatar.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in a new issue