nheko/resources/qml/delegates/PlayableMediaMessage.qml

219 lines
7.7 KiB
QML
Raw Normal View History

2021-03-05 00:35:15 +01:00
// SPDX-FileCopyrightText: 2021 Nheko Contributors
//
2021-03-05 00:35:15 +01:00
// SPDX-License-Identifier: GPL-3.0-or-later
2021-03-27 01:17:58 +01:00
import "../"
import "../ui/media"
import QtMultimedia 5.15
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.2
import im.nheko 1.0
2021-07-19 20:11:03 +02:00
ColumnLayout {
2021-11-10 04:17:00 +01:00
id: content
required property double proportionalHeight
required property int type
required property int originalWidth
required property string thumbnailUrl
required property string eventId
required property string url
required property string body
required property string filesize
2021-07-19 20:11:03 +02:00
function durationToString(duration) {
function maybeZeroPrepend(time) {
2021-11-10 04:17:00 +01:00
return (time < 10) ? "0" + time.toString() : time.toString();
}
2021-11-10 04:17:00 +01:00
var totalSeconds = Math.floor(duration / 1000);
var seconds = totalSeconds % 60;
var minutes = (Math.floor(totalSeconds / 60)) % 60;
var hours = (Math.floor(totalSeconds / (60 * 24))) % 24;
// Always show minutes and don't prepend zero into the leftmost element
2021-11-10 04:17:00 +01:00
var ss = maybeZeroPrepend(seconds);
var mm = (hours > 0) ? maybeZeroPrepend(minutes) : minutes.toString();
var hh = hours.toString();
if (hours < 1)
return mm + ":" + ss;
2021-07-19 20:11:03 +02:00
2021-11-10 04:17:00 +01:00
return hh + ":" + mm + ":" + ss;
}
2021-11-09 01:18:11 +01:00
Layout.fillWidth: true
2021-11-10 04:17:00 +01:00
MxcMedia {
id: mxcmedia
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
// TODO: Show error in overlay or so?
onError: console.log(error)
roomm: room
2021-11-10 04:17:00 +01:00
// desiredVolume is a float from 0.0 -> 1.0, MediaPlayer volume is an int from 0 to 100
// this value automatically gets clamped for us between these two values.
volume: mediaControls.desiredVolume * 100
muted: mediaControls.muted
2021-07-19 20:11:03 +02:00
}
2021-07-19 20:11:03 +02:00
Rectangle {
id: videoContainer
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
//property double tempWidth: Math.min(parent ? parent.width : undefined, model.data.width < 1 ? 400 : /////model.data.width)
// property double tempWidth: (model.data.width < 1) ? 400 : model.data.width
// property double tempHeight: tempWidth * model.data.proportionalHeight
//property double tempWidth: Math.min(parent ? parent.width : undefined, originalWidth < 1 ? 400 : originalWidth)
2021-11-10 04:17:00 +01:00
property double tempWidth: Math.min(parent ? parent.width : undefined, originalWidth < 1 ? 400 : originalWidth)
2021-07-19 20:11:03 +02:00
property double tempHeight: tempWidth * proportionalHeight
property double divisor: isReply ? 4 : 2
property bool tooHigh: tempHeight > timelineRoot.height / divisor
2021-11-10 04:17:00 +01:00
color: Nheko.colors.window
2021-07-19 20:11:03 +02:00
Layout.preferredHeight: tooHigh ? timelineRoot.height / divisor : tempHeight
Layout.preferredWidth: tooHigh ? (timelineRoot.height / divisor) / proportionalHeight : tempWidth
2021-11-09 01:18:11 +01:00
Layout.maximumWidth: Layout.preferredWidth
2021-07-19 20:11:03 +02:00
Image {
anchors.fill: parent
source: thumbnailUrl.replace("mxc://", "image://MxcImage/")
asynchronous: true
fillMode: Image.PreserveAspectFit
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
// Button and window colored overlay to cache media
Item {
2021-07-19 20:11:03 +02:00
// Display over video controls
z: videoOutput.z + 1
visible: !mxcmedia.loaded
2021-07-19 20:11:03 +02:00
anchors.fill: parent
2021-11-10 04:17:00 +01:00
//color: Nheko.colors.window
//opacity: 0.5
2021-07-19 20:11:03 +02:00
Image {
2021-11-10 04:17:00 +01:00
property color buttonColor: (cacheVideoArea.containsMouse) ? Nheko.colors.highlight : Nheko.colors.text
2021-07-19 20:11:03 +02:00
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
2021-11-10 04:17:00 +01:00
source: "image://colorimage/:/icons/icons/ui/arrow-pointing-down.png?" + buttonColor
2021-03-27 01:17:58 +01:00
}
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
MouseArea {
id: cacheVideoArea
2021-11-10 04:17:00 +01:00
2021-02-14 01:28:28 +01:00
anchors.fill: parent
2021-07-19 20:11:03 +02:00
hoverEnabled: true
enabled: !mxcmedia.loaded
onClicked: mxcmedia.eventId = eventId
2020-10-08 21:11:21 +02:00
}
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
}
2021-11-10 04:17:00 +01:00
2021-07-19 20:11:03 +02:00
VideoOutput {
id: videoOutput
visible: type == MtxEvent.VideoMessage
2021-07-19 20:11:03 +02:00
clip: true
anchors.fill: parent
fillMode: VideoOutput.PreserveAspectFit
source: mxcmedia
flushMode: VideoOutput.FirstFrame
}
MediaControls {
id: mediaControls
2021-11-10 04:17:00 +01:00
anchors.fill: parent
x: type == MtxEvent.VideoMessage ? videoOutput.contentRect.x : videoContainer.x
y: type == MtxEvent.VideoMessage ? videoOutput.contentRect.y : videoContainer.y
width: type == MtxEvent.VideoMessage ? videoOutput.contentRect.width : videoContainer.width
height: type == MtxEvent.VideoMessage ? videoOutput.contentRect.height : videoContainer.height
positionValue: mxcmedia.position
duration: mxcmedia.duration
mediaLoaded: mxcmedia.loaded
mediaState: mxcmedia.state
volumeOrientation: Qt.Vertical
onPositionChanged: mxcmedia.position = position
onActivated: mxcmedia.state == MediaPlayer.PlayingState ? mxcmedia.pause() : mxcmedia.play()
2021-11-10 04:17:00 +01:00
}
}
}
// Audio player
// TODO: share code with the video player
// Rectangle {
// id: audioControlRect
// property int controlHeight: 25
// visible: type != MtxEvent.VideoMessage
// Layout.preferredHeight: 40
// RowLayout {
// anchors.fill: parent
// width: parent.width
// // Play/pause button
// Image {
// id: audioPlaybackStateImage
// property color controlColor: (audioPlaybackStateArea.containsMouse) ? Nheko.colors.highlight : Nheko.colors.text
// fillMode: Image.PreserveAspectFit
// Layout.preferredHeight: controlRect.controlHeight
// Layout.alignment: Qt.AlignVCenter
// source: {
// if (!mxcmedia.loaded)
// return "image://colorimage/:/icons/icons/ui/arrow-pointing-down.png?" + controlColor;
// return (mxcmedia.state == MediaPlayer.PlayingState) ? "image://colorimage/:/icons/icons/ui/pause-symbol.png?" + controlColor : "image://colorimage/:/icons/icons/ui/play-sign.png?" + controlColor;
// }
// MouseArea {
// id: audioPlaybackStateArea
// anchors.fill: parent
// hoverEnabled: true
// onClicked: {
// if (!mxcmedia.loaded) {
// mxcmedia.eventId = eventId;
// return ;
// }
// (mxcmedia.state == MediaPlayer.PlayingState) ? mxcmedia.pause() : mxcmedia.play();
// }
// }
// }
// Label {
// text: (!mxcmedia.loaded) ? "-/-" : durationToString(mxcmedia.position) + "/" + durationToString(mxcmedia.duration)
// }
// Slider {
// Layout.fillWidth: true
// Layout.minimumWidth: 50
// height: controlRect.controlHeight
// value: mxcmedia.position
// onMoved: mxcmedia.position = value
// from: 0
// to: mxcmedia.duration
// }
// }
// }
2021-11-10 04:17:00 +01:00
Label {
id: fileInfoLabel
Layout.fillWidth: true
text: body + " [" + filesize + "]"
textFormat: Text.PlainText
elide: Text.ElideRight
color: Nheko.colors.text
background: Rectangle {
color: Nheko.colors.base
}
}
2021-07-19 20:11:03 +02:00
2021-11-10 04:17:00 +01:00
}