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
123 lines
3.7 KiB
QML
123 lines
3.7 KiB
QML
// SPDX-FileCopyrightText: 2022 Tobias Fella <fella@posteo.de>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtMultimedia 5.15
|
|
|
|
import org.kde.kirigami 2.15 as Kirigami
|
|
|
|
import org.kde.neochat 1.0
|
|
|
|
TimelineContainer {
|
|
id: audioDelegate
|
|
|
|
onReplyClicked: ListView.view.goToEvent(eventID)
|
|
|
|
onOpenContextMenu: openFileContext(model, audioDelegate)
|
|
|
|
readonly property bool downloaded: model.progressInfo && model.progressInfo.completed
|
|
onDownloadedChanged: audio.play()
|
|
|
|
hoverComponent: hoverActions
|
|
innerObject: Control {
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: audioDelegate.contentMaxWidth
|
|
|
|
Audio {
|
|
id: audio
|
|
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 {
|
|
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
|
|
|
|
Slider {
|
|
from: 0
|
|
to: audio.duration
|
|
value: audio.position
|
|
onMoved: audio.seek(value)
|
|
}
|
|
|
|
Label {
|
|
text: Controller.formatDuration(audio.position) + "/" + Controller.formatDuration(audio.duration)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|