Commit 9ba820bf authored by Linus Jahn's avatar Linus Jahn 🍙

media-sharing: Display images in chat, Fix chat colour issues

Images are now displayed in the chat. For the case that they are
available locally (currently only possible by sending them), the images
are loaded directly, otherwise they're loaded via. HTTP. Of course that
still needs to be changed since those images are not cached and thus are
downloaded every time.

Fixes the `mediaLocation` attribute in the database of messages; it's
now the full file path, before it was accidently set to the folder's
path.

The colour for timestamp labels of incoming messages wasn't clearly
visible in some configurations, it is now always a bit darker (1.3
times) and well visible in all common styles.
parent 4f67917a
Pipeline #253 passed with stage
in 2 minutes and 24 seconds
......@@ -13,6 +13,7 @@
<file alias="qml/elements/RosterListItem.qml">src/qml/elements/RosterListItem.qml</file>
<file alias="qml/elements/MessageCounter.qml">src/qml/elements/MessageCounter.qml</file>
<file alias="qml/elements/ChatMessage.qml">src/qml/elements/ChatMessage.qml</file>
<file alias="qml/elements/ChatMessageImage.qml">src/qml/elements/ChatMessageImage.qml</file>
<file alias="qml/elements/RoundImage.qml">src/qml/elements/RoundImage.qml</file>
<file alias="qml/elements/IconButton.qml">src/qml/elements/IconButton.qml</file>
<file alias="qml/elements/FileChooser.qml">src/qml/elements/FileChooser.qml</file>
......
......@@ -93,7 +93,7 @@ void UploadManager::sendFile(QString jid, QString fileUrl, QString body)
msg->mediaSize = file.size();
msg->mediaContentType = mimeType.name();
msg->mediaLastModified = file.lastModified().currentMSecsSinceEpoch();
msg->mediaLocation = file.absolutePath();
msg->mediaLocation = file.filePath();
emit msgModel->addMessageRequested(*msg);
// message cache to edit on success/failure
......
......@@ -37,8 +37,6 @@ import im.kaidan.kaidan 1.0
import "elements"
Kirigami.ScrollablePage {
id: root
property string chatName
property string recipientJid
......@@ -136,8 +134,9 @@ Kirigami.ScrollablePage {
kaidan.avatarStorage.getAvatarUrl(author) :
kaidan.getResourcePath("images/fallback-avatar.svg")
}
mediaType: Enums.MessageImage
mediaUrl: model.mediaUrl
mediaType: model.type
mediaGetUrl: model.mediaUrl
mediaLocation: model.mediaLocation
}
}
......@@ -150,12 +149,13 @@ Kirigami.ScrollablePage {
color: Kirigami.Theme.disabledTextColor
samples: 20
spread: 0.3
cached: true // element is static
}
Layout.fillWidth: true
padding: 0
wheelEnabled: true
background: Rectangle {
color: Kirigami.Theme.View.backgroundColor
color: Kirigami.Theme.backgroundColor
}
RowLayout {
......
......@@ -44,14 +44,18 @@ RowLayout {
property bool isRead: false
property string recipientAvatarUrl
property int mediaType
property string mediaUrl
property string mediaGetUrl
property string mediaLocation
// 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
spacing: 8
width: parent.width
// placeholder
Item {
Layout.preferredWidth: 5
}
RoundImage {
id: avatar
......@@ -60,73 +64,86 @@ RowLayout {
fillMode: Image.PreserveAspectFit
mipmap: true
height: width
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
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
}
Rectangle {
id: box
Layout.preferredWidth: content.width + Kirigami.Units.gridUnit * 0.9
Layout.preferredHeight: content.height + Kirigami.Units.gridUnit * 0.6
color: sentByMe ? Kirigami.Theme.complementaryTextColor : Kirigami.Theme.highlightColor
radius: Kirigami.Units.smallSpacing * 2
// message bubble/box
Item {
Layout.preferredWidth: content.width + 13
Layout.preferredHeight: content.height + 8
MouseArea {
Rectangle {
id: box
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
kaidan.copyToClipboard(messageBody)
passiveNotification(qsTr("Message copied to clipboard"))
color: sentByMe ? Kirigami.Theme.complementaryTextColor
: Kirigami.Theme.highlightColor
radius: Kirigami.Units.smallSpacing * 2
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
kaidan.copyToClipboard(messageBody)
passiveNotification(qsTr("Message copied to clipboard"))
}
}
}
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
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
}
}
ColumnLayout {
id: content
spacing: 0
anchors.centerIn: box
Image {
id: image
visible: mediaType === Enums.MessageImage
source: {
mediaLocation !== "" ? "file://" + mediaLocation : mediaUrl
anchors.centerIn: parent
anchors.margins: 4
// media loader
Loader {
id: media
source: mediaType === Enums.MessageImage ? "ChatMessageImage.qml"
: ""
property string sourceUrl: {
mediaLocation === "" ? mediaGetUrl
: "file://" + mediaLocation
}
fillMode: Image.PreserveAspectFit
asynchronous: true // might be a large image
Layout.preferredHeight: paintedHeight
Layout.maximumWidth: root.width - Kirigami.Units.gridUnit * 6
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.preferredHeight: mediaType === Enums.MessageImage && loaded ?
item.paintedHeight : 0
}
// message body
Controls.Label {
visible: messageBody !== ""
text: messageBody
textFormat: Text.PlainText
wrapMode: Text.Wrap
color: sentByMe ? Kirigami.Theme.buttonTextColor : Kirigami.Theme.complementaryTextColor
color: sentByMe ? Kirigami.Theme.buttonTextColor
: Kirigami.Theme.complementaryTextColor
Layout.maximumWidth: Math.min(root.width - Kirigami.Units.gridUnit * 6, image.width)
Layout.maximumWidth: mediaType === Enums.MessageImage && media.width !== 0
? media.width
: root.width - Kirigami.Units.gridUnit * 6
}
// message meta: date, isRead
RowLayout {
Controls.Label {
id: dateLabel
text: Qt.formatDateTime(dateTime, "dd. MMM yyyy, hh:mm")
color: Kirigami.Theme.disabledTextColor
color: sentByMe ? Kirigami.Theme.disabledTextColor
: Qt.darker(Kirigami.Theme.disabledTextColor, 1.3)
font.pixelSize: Kirigami.Units.gridUnit * 0.8
}
......@@ -143,6 +160,7 @@ RowLayout {
}
}
// placeholder
Item {
Layout.fillWidth: true
}
......
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2018 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.6
Image {
id: image
source: sourceUrl
fillMode: Image.PreserveAspectFit
asynchronous: true // might be a large image
}
......@@ -87,9 +87,7 @@ Item {
if (fileIsDir) {
if (fileName === "..")
fileModel.folder = fileModel.parentFolder
else if (fileName === ".")
return
else
else if (fileName !== ".")
fileModel.folder = "file://" + filePath
} else {
root.fileUrl = filePath
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment