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