diff --git a/qml/component/AvatarContainer.qml b/qml/component/AvatarContainer.qml new file mode 100644 index 0000000..00df03b --- /dev/null +++ b/qml/component/AvatarContainer.qml @@ -0,0 +1,32 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 + +Row { + spacing: 6 + + ImageStatus { + id: avatar + + width: height + height: 40 + round: false + visible: !sentByMe && aboveAuthor !== author + source: author.avatarUrl != "" ? "image://mxc/" + author.avatarUrl : null + displayText: author.displayName + + MouseArea { + anchors.fill: parent + + hoverEnabled: true + ToolTip.visible: containsMouse + ToolTip.text: author.displayName + } + } + + Rectangle { + width: height + height: 40 + color: "transparent" + visible: !sentByMe && aboveAuthor === author + } +} diff --git a/qml/component/DownloadableContent.qml b/qml/component/DownloadableContent.qml new file mode 100644 index 0000000..98153a9 --- /dev/null +++ b/qml/component/DownloadableContent.qml @@ -0,0 +1,35 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 + +Item { + width: parent.width + height: visible ? childrenRect.height : 0 + + property bool openOnFinished: false + readonly property bool downloaded: progressInfo && progressInfo.completed + + onDownloadedChanged: { + if (downloaded && openOnFinished) + openSavedFile() + } + + function downloadAndOpen() + { + if (downloaded) + openSavedFile() + else + { + openOnFinished = true + currentRoom.downloadFile(eventId) + } + } + + function openSavedFile() + { + if (Qt.openUrlExternally(progressInfo.localPath)) + return; + + if (Qt.openUrlExternally(progressInfo.localDir)) + return; + } +} diff --git a/qml/component/FileBubble.qml b/qml/component/FileBubble.qml new file mode 100644 index 0000000..302bff8 --- /dev/null +++ b/qml/component/FileBubble.qml @@ -0,0 +1,22 @@ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.4 + +AvatarContainer { + DownloadableContent { + id: downloadable + + width: downloadButton.width + height: downloadButton.height + + Button { + id: downloadButton + + text: content.body + + highlighted: !sentByMe + + onClicked: downloadable.downloadAndOpen() + } + } +} diff --git a/qml/component/ImageBubble.qml b/qml/component/ImageBubble.qml index 14e67ae..699dddf 100644 --- a/qml/component/ImageBubble.qml +++ b/qml/component/ImageBubble.qml @@ -2,30 +2,7 @@ import QtQuick 2.11 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.4 -Row { - id: messageRow - - spacing: 6 - - ImageStatus { - id: avatar - - width: height - height: 40 - round: false - visible: !sentByMe - source: author.avatarUrl != "" ? "image://mxc/" + author.avatarUrl : null - displayText: author.displayName - - MouseArea { - anchors.fill: parent - - hoverEnabled: true - ToolTip.visible: containsMouse - ToolTip.text: author.displayName - } - } - +AvatarContainer { Rectangle { id: messageRect @@ -34,18 +11,27 @@ Row { color: sentByMe ? "lightgrey" : Material.accent - Image { - id: messageImage + DownloadableContent { + id: downloadable + + width: messageImage.width + height: messageImage.height anchors.centerIn: parent - source: "image://mxc/" + content.url - MouseArea { - anchors.fill: parent + Image { + id: messageImage + source: "image://mxc/" + content.url - hoverEnabled: true - propagateComposedEvents: true - ToolTip.visible: containsMouse - ToolTip.text: content.body + MouseArea { + anchors.fill: parent + + hoverEnabled: true + propagateComposedEvents: true + ToolTip.visible: containsMouse + ToolTip.text: content.body + + onClicked: downloadable.downloadAndOpen() + } } } } diff --git a/qml/component/MessageBubble.qml b/qml/component/MessageBubble.qml index f8c0806..ec2a67a 100644 --- a/qml/component/MessageBubble.qml +++ b/qml/component/MessageBubble.qml @@ -2,43 +2,15 @@ import QtQuick 2.11 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.4 -Row { +AvatarContainer { readonly property bool isNotice: eventType === "notice" id: messageRow - spacing: 6 - - ImageStatus { - id: avatar - - width: height - height: 40 - round: false - visible: !sentByMe && aboveAuthor !== author - source: author.avatarUrl != "" ? "image://mxc/" + author.avatarUrl : null - displayText: author.displayName - - MouseArea { - anchors.fill: parent - - hoverEnabled: true - ToolTip.visible: containsMouse - ToolTip.text: author.displayName - } - } - - Rectangle { - width: height - height: 40 - color: "transparent" - visible: !sentByMe && aboveAuthor === author - } - Rectangle { id: messageRect - width: Math.min(messageText.implicitWidth + 24, messageListView.width - (!sentByMe ? avatar.width + messageRow.spacing : 0)) + width: Math.min(messageText.implicitWidth + 24, messageListView.width - (!sentByMe ? 40 + messageRow.spacing : 0)) height: messageText.implicitHeight + 24 color: isNotice ? "transparent" : sentByMe ? "lightgrey" : Material.accent diff --git a/qml/component/MessageDelegate.qml b/qml/component/MessageDelegate.qml index aa1a106..7a0d2a7 100644 --- a/qml/component/MessageDelegate.qml +++ b/qml/component/MessageDelegate.qml @@ -10,7 +10,7 @@ Item { width: delegateLoader.width height: delegateLoader.height - anchors.right: (eventType === "message" || eventType === "image") && sentByMe ? parent.right : undefined + anchors.right: (eventType === "message" || eventType === "image" || eventType === "file" || eventType === "video" || eventType === "audio") && sentByMe ? parent.right : undefined anchors.horizontalCenter: (eventType === "state" || eventType === "emote") ? parent.horizontalCenter : undefined MouseArea { @@ -34,7 +34,12 @@ Item { case "emote": case "state": return "StateBubble.qml" + case "video": + case "audio": + case "file": + return "FileBubble.qml" } + return "" } } } diff --git a/qml/form/RoomForm.qml b/qml/form/RoomForm.qml index c106305..dd375e4 100644 --- a/qml/form/RoomForm.qml +++ b/qml/form/RoomForm.qml @@ -1,5 +1,6 @@ import QtQuick 2.11 import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 import QtQuick.Layouts 1.11 import QtQuick.Controls.Material 2.4 import QtGraphicalEffects 1.0 @@ -151,6 +152,18 @@ Item { Layout.fillHeight: true contentItem: MaterialIcon { icon: "\ue226" } + + onClicked: fileDialog.visible = true + + FileDialog { + id: fileDialog + title: "Please choose a file" + folder: shortcuts.home + onAccepted: { + console.log("You chose: " + fileDialog.fileUrls) + matriqueController.uploadFile(fileDialog.fileUrls) + } + } } TextField { diff --git a/res.qrc b/res.qrc index 6ecdb60..ec127a4 100644 --- a/res.qrc +++ b/res.qrc @@ -21,5 +21,8 @@ qml/component/MessageBubble.qml qml/component/ImageBubble.qml qml/component/StateBubble.qml + qml/component/DownloadableContent.qml + qml/component/FileBubble.qml + qml/component/AvatarContainer.qml