From 7dfac8a9f7ac8cca06577d829f52b22a63813a3d Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Tue, 9 Aug 2022 21:40:00 +0200 Subject: [PATCH] Fix audio playback Since the preparation for encrypted events landed, audio playback was broken since QtMultimedia (gstreamer) doesn't use our custom QNAM. Instead of letting QtMultimedia download the media, we thus need to manually download it and point QML Audio to the local file. On the positive side, this also allows encrypted Audio files to be played and enables us to seek in the audio delegate :) It does however mean that we do need to do an annoying bit of manual state management. BUG: 457687 --- .../Component/Timeline/AudioDelegate.qml | 89 +++++++++++++++---- src/messageeventmodel.cpp | 1 + 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/imports/NeoChat/Component/Timeline/AudioDelegate.qml b/imports/NeoChat/Component/Timeline/AudioDelegate.qml index 517cd48b9..ca43fe227 100644 --- a/imports/NeoChat/Component/Timeline/AudioDelegate.qml +++ b/imports/NeoChat/Component/Timeline/AudioDelegate.qml @@ -1,18 +1,14 @@ -// SPDX-FileCopyrightText: 2019-2020 Black Hat -// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2022 Tobias Fella +// SPDX-License-Identifier: GPL-2.0-or-later import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 -import Qt.labs.platform 1.1 as Platform import QtMultimedia 5.15 import org.kde.kirigami 2.15 as Kirigami import org.kde.neochat 1.0 -import NeoChat.Component 1.0 -import NeoChat.Dialog 1.0 -import NeoChat.Menu.Timeline 1.0 TimelineContainer { id: audioDelegate @@ -21,6 +17,9 @@ TimelineContainer { onOpenContextMenu: openFileContext(model, audioDelegate) + readonly property bool downloaded: model.progressInfo && model.progressInfo.completed + onDownloadedChanged: audio.play() + hoverComponent: hoverActions innerObject: Control { Layout.fillWidth: true @@ -28,36 +27,90 @@ TimelineContainer { Audio { id: audio - source: currentRoom.urlToMxcUrl(content.url) + source: model.progressInfo.localPath autoLoad: false } + states: [ + State { + name: "notDownloaded" + when: !model.progressInfo.completed && !model.progressInfo.active + + PropertyChanges { + target: playButton + icon.name: "media-playback-start" + onClicked: currentRoom.downloadFile(model.eventId) + } + }, + State { + name: "downloading" + when: model.progressInfo.active && !model.progressInfo.completed + PropertyChanges { + target: downloadBar + visible: true + } + PropertyChanges { + target: playButton + icon.name: "media-playback-stop" + onClicked: { + currentRoom.cancelFileTransfer(model.eventId) + } + } + }, + State { + name: "paused" + when: model.progressInfo.completed && (audio.playbackState === Audio.StoppedState || audio.playbackState === Audio.PausedState) + PropertyChanges { + target: playButton + icon.name: "media-playback-start" + onClicked: { + audio.play() + } + } + }, + State { + name: "playing" + when: model.progressInfo.completed && audio.playbackState === Audio.PlayingState + + PropertyChanges { + target: playButton + + icon.name: "media-playback-pause" + + onClicked: audio.pause() + } + } + ] + contentItem: ColumnLayout { RowLayout { ToolButton { - icon.name: audio.playbackState == Audio.PlayingState ? "media-playback-pause" : "media-playback-start" - - onClicked: { - if (audio.playbackState == Audio.PlayingState) { - audio.pause() - } else { - audio.play() - } - } + id: playButton } Label { text: model.display + wrapMode: Text.Wrap + Layout.fillWidth: true } } + ProgressBar { + id: downloadBar + visible: false + Layout.fillWidth: true + from: 0 + to: model.content.info.size + value: model.progressInfo.progress + } RowLayout { visible: audio.hasAudio Layout.leftMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing - // Server doesn't support seeking, so use ProgressBar instead of Slider :( - ProgressBar { + + Slider { from: 0 to: audio.duration value: audio.position + onMoved: audio.seek(value) } Label { diff --git a/src/messageeventmodel.cpp b/src/messageeventmodel.cpp index d6601c1af..215d45f45 100644 --- a/src/messageeventmodel.cpp +++ b/src/messageeventmodel.cpp @@ -193,6 +193,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room) } refreshEventRoles(eventId, {ReactionRole, Qt::DisplayRole}); }); + connect(m_currentRoom, &Room::newFileTransfer, this, &MessageEventModel::refreshEvent); connect(m_currentRoom, &Room::fileTransferProgress, this, &MessageEventModel::refreshEvent); connect(m_currentRoom, &Room::fileTransferCompleted, this, &MessageEventModel::refreshEvent); connect(m_currentRoom, &Room::fileTransferFailed, this, &MessageEventModel::refreshEvent);