From 67d255a2de7ca85b35a67bff25ef9b6770b453a0 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 6 Oct 2019 01:05:32 +0200 Subject: Add basic video messages Size is fixed for now, otherwise the Video output ends up somewhere... --- resources/qml/TimelineView.qml | 4 +- resources/qml/delegates/AudioMessage.qml | 140 --------------------- resources/qml/delegates/PlayableMediaMessage.qml | 152 +++++++++++++++++++++++ resources/res.qrc | 2 +- 4 files changed, 155 insertions(+), 143 deletions(-) delete mode 100644 resources/qml/delegates/AudioMessage.qml create mode 100644 resources/qml/delegates/PlayableMediaMessage.qml diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index c25e6543..4d8c22b8 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -112,8 +112,8 @@ Rectangle { case MtxEvent.TextMessage: return "delegates/TextMessage.qml" case MtxEvent.ImageMessage: return "delegates/ImageMessage.qml" case MtxEvent.FileMessage: return "delegates/FileMessage.qml" - //case MtxEvent.VideoMessage: return "delegates/VideoMessage.qml" - case MtxEvent.AudioMessage: return "delegates/AudioMessage.qml" + case MtxEvent.VideoMessage: return "delegates/PlayableMediaMessage.qml" + case MtxEvent.AudioMessage: return "delegates/PlayableMediaMessage.qml" case MtxEvent.Redacted: return "delegates/Redacted.qml" default: return "delegates/placeholder.qml" } diff --git a/resources/qml/delegates/AudioMessage.qml b/resources/qml/delegates/AudioMessage.qml deleted file mode 100644 index f4fa8f54..00000000 --- a/resources/qml/delegates/AudioMessage.qml +++ /dev/null @@ -1,140 +0,0 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.6 -import QtQuick.Controls 2.5 -import QtMultimedia 5.6 - -Rectangle { - radius: 10 - color: colors.dark - height: content.height + 24 - width: parent.width - - ColumnLayout { - id: content - width: parent.width - 24 - anchors.centerIn: parent - - RowLayout { - Text { - id: positionText - text: "--:--:--" - color: colors.text - } - Slider { - Layout.fillWidth: true - id: progress - value: media.position - from: 0 - to: media.duration - - onMoved: media.seek(value) - //indeterminate: true - function updatePositionTexts() { - function formatTime(date) { - var hh = date.getUTCHours(); - var mm = date.getUTCMinutes(); - var ss = date.getSeconds(); - if (hh < 10) {hh = "0"+hh;} - if (mm < 10) {mm = "0"+mm;} - if (ss < 10) {ss = "0"+ss;} - return hh+":"+mm+":"+ss; - } - positionText.text = formatTime(new Date(media.position)) - durationText.text = formatTime(new Date(media.duration)) - } - onValueChanged: updatePositionTexts() - } - Text { - id: durationText - text: "--:--:--" - color: colors.text - } - } - - RowLayout { - width: parent.width - - spacing: 15 - - Rectangle { - id: button - color: colors.light - radius: 22 - height: 44 - width: 44 - Image { - id: img - anchors.centerIn: parent - - source: "qrc:/icons/icons/ui/arrow-pointing-down.png" - fillMode: Image.Pad - - } - MouseArea { - anchors.fill: parent - onClicked: { - switch (button.state) { - case "": timelineManager.cacheMedia(eventData.url, eventData.mimetype); break; - case "stopped": - media.play(); console.log("play"); - button.state = "playing" - break - case "playing": - media.pause(); console.log("pause"); - button.state = "stopped" - break - } - } - cursorShape: Qt.PointingHandCursor - } - MediaPlayer { - id: media - onError: console.log(errorString) - onStatusChanged: if(status == MediaPlayer.Loaded) progress.updatePositionTexts() - } - - Connections { - target: timelineManager - onMediaCached: { - if (mxcUrl == eventData.url) { - media.source = "file://" + cacheUrl - button.state = "stopped" - console.log("media loaded: " + mxcUrl + " at " + cacheUrl) - } - console.log("media cached: " + mxcUrl + " at " + cacheUrl) - } - } - - states: [ - State { - name: "stopped" - PropertyChanges { target: img; source: "qrc:/icons/icons/ui/play-sign.png" } - }, - State { - name: "playing" - PropertyChanges { target: img; source: "qrc:/icons/icons/ui/pause-symbol.png" } - } - ] - } - ColumnLayout { - id: col - - Text { - Layout.fillWidth: true - text: eventData.body - textFormat: Text.PlainText - elide: Text.ElideRight - color: colors.text - } - Text { - Layout.fillWidth: true - text: eventData.filesize - textFormat: Text.PlainText - elide: Text.ElideRight - color: colors.text - } - } - } - } -} - diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml new file mode 100644 index 00000000..7498d5b2 --- /dev/null +++ b/resources/qml/delegates/PlayableMediaMessage.qml @@ -0,0 +1,152 @@ +import QtQuick 2.6 +import QtQuick.Layouts 1.6 +import QtQuick.Controls 2.5 +import QtMultimedia 5.6 + +import com.github.nheko 1.0 + +Rectangle { + radius: 10 + color: colors.dark + height: content.height + 24 + width: parent.width + + ColumnLayout { + id: content + width: parent.width - 24 + anchors.centerIn: parent + + VideoOutput { + visible: eventData.type == MtxEvent.VideoMessage + Layout.maximumHeight: 300 + Layout.minimumHeight: 300 + Layout.maximumWidth: 500 + fillMode: VideoOutput.PreserveAspectFit + source: media + } + + RowLayout { + Text { + id: positionText + text: "--:--:--" + color: colors.text + } + Slider { + Layout.fillWidth: true + id: progress + value: media.position + from: 0 + to: media.duration + + onMoved: media.seek(value) + //indeterminate: true + function updatePositionTexts() { + function formatTime(date) { + var hh = date.getUTCHours(); + var mm = date.getUTCMinutes(); + var ss = date.getSeconds(); + if (hh < 10) {hh = "0"+hh;} + if (mm < 10) {mm = "0"+mm;} + if (ss < 10) {ss = "0"+ss;} + return hh+":"+mm+":"+ss; + } + positionText.text = formatTime(new Date(media.position)) + durationText.text = formatTime(new Date(media.duration)) + } + onValueChanged: updatePositionTexts() + } + Text { + id: durationText + text: "--:--:--" + color: colors.text + } + } + + RowLayout { + width: parent.width + + spacing: 15 + + Rectangle { + id: button + color: colors.light + radius: 22 + height: 44 + width: 44 + Image { + id: img + anchors.centerIn: parent + + source: "qrc:/icons/icons/ui/arrow-pointing-down.png" + fillMode: Image.Pad + + } + MouseArea { + anchors.fill: parent + onClicked: { + switch (button.state) { + case "": timelineManager.cacheMedia(eventData.url, eventData.mimetype); break; + case "stopped": + media.play(); console.log("play"); + button.state = "playing" + break + case "playing": + media.pause(); console.log("pause"); + button.state = "stopped" + break + } + } + cursorShape: Qt.PointingHandCursor + } + MediaPlayer { + id: media + onError: console.log(errorString) + onStatusChanged: if(status == MediaPlayer.Loaded) progress.updatePositionTexts() + autoPlay: true + } + + Connections { + target: timelineManager + onMediaCached: { + if (mxcUrl == eventData.url) { + media.source = "file://" + cacheUrl + button.state = "stopped" + console.log("media loaded: " + mxcUrl + " at " + cacheUrl) + } + console.log("media cached: " + mxcUrl + " at " + cacheUrl) + } + } + + states: [ + State { + name: "stopped" + PropertyChanges { target: img; source: "qrc:/icons/icons/ui/play-sign.png" } + }, + State { + name: "playing" + PropertyChanges { target: img; source: "qrc:/icons/icons/ui/pause-symbol.png" } + } + ] + } + ColumnLayout { + id: col + + Text { + Layout.fillWidth: true + text: eventData.body + textFormat: Text.PlainText + elide: Text.ElideRight + color: colors.text + } + Text { + Layout.fillWidth: true + text: eventData.filesize + textFormat: Text.PlainText + elide: Text.ElideRight + color: colors.text + } + } + } + } +} + diff --git a/resources/res.qrc b/resources/res.qrc index 1caf378e..16bab4e4 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -122,7 +122,7 @@ qml/delegates/TextMessage.qml qml/delegates/NoticeMessage.qml qml/delegates/ImageMessage.qml - qml/delegates/AudioMessage.qml + qml/delegates/PlayableMediaMessage.qml qml/delegates/FileMessage.qml qml/delegates/Redacted.qml qml/delegates/placeholder.qml -- cgit 1.5.1