Newer
Older
/*
* Copyright (C) 2020 by Savoir-faire Linux
* Author: Albert Babí <albert.babi@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import QtQuick.Shapes 1.15
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
Rectangle {
id: root
enum States {
INIT,
RECORDING,
REC_SUCCESS
}
property string pathRecorder: ""
property string timeText: "00:00"
property int duration: 0
property int state: RecordBox.States.INIT
property bool isVideo: false
property int preferredWidth: 320
property int preferredHeight: 240
property int btnSize: 40
property int offset: 3
property int curveRadius: 6
property int spikeHeight: 10 + offset
function openRecorder(vid) {
if (isVideo) {
previewWidget.deviceId = VideoDevices.getDefaultDevice()
previewWidget.rendererId = VideoDevices.startDevice(previewWidget.deviceId)
function scaleHeight() {
height = preferredHeight
if (isVideo) {
var resolution = VideoDevices.defaultRes
var resVec = resolution.split("x")
var aspectRatio = resVec[1] / resVec[0]
height = preferredWidth * aspectRatio
} else {
console.error("Could not scale recording video preview")
}
}
}
if (isVideo) {
VideoDevices.stopDevice(previewWidget.deviceId)
}
stopRecording()
visible = false
}
function updateState(new_state) {
state = new_state
recordButton.visible = (state === RecordBox.States.INIT)
btnStop.visible = (state === RecordBox.States.RECORDING)
btnRestart.visible = (state === RecordBox.States.REC_SUCCESS)
btnSend.visible = (state === RecordBox.States.REC_SUCCESS)
if (state === RecordBox.States.INIT) {
duration = 0
time.text = "00:00"
timer.stop()
} else if (state === RecordBox.States.REC_SUCCESS) {
timer.stop()
}
}
function startRecording() {
timer.start()
pathRecorder = AVModel.startLocalMediaRecorder(isVideo? VideoDevices.getDefaultDevice() : "")
if (pathRecorder == "") {
timer.stop()
}
}
function stopRecording() {
if (pathRecorder !== "") {
AVModel.stopLocalRecorder(pathRecorder)
if (pathRecorder !== "") {
MessagesAdapter.sendFile(pathRecorder)
}
}
function updateTimer() {
duration += 1
var m = Math.trunc(duration / 60)
var s = (duration % 60)
var min = (m < 10) ? "0" + String(m) : String(m)
var sec = (s < 10) ? "0" + String(s) : String(s)
time.text = min + ":" + sec
}
width: 320
height: 240
radius: 5
border.color: JamiTheme.tabbarBorderColor
color: JamiTheme.backgroundColor
onActiveFocusChanged: {
if (visible) {
closeRecorder()
}
}
onVisibleChanged: {
if (!visible) {
closeRecorder()
}
width: root.width
height: root.height
fillColor: JamiTheme.backgroundColor
strokeWidth: 1
strokeColor: JamiTheme.tabbarBorderColor
startX: -offset + curveRadius
startY: -offset
PathLine {
x: width + offset - curveRadius
y: -offset
}
x: width + offset
y: -offset + curveRadius
radiusX: curveRadius
radiusY: curveRadius
PathLine {
x: width + offset
y: height + offset - curveRadius
}
x: width + offset - curveRadius
y: height + offset
radiusX: curveRadius
radiusY: curveRadius
PathLine {
x: width / 2 + 10
y: height + offset
}
PathLine {
x: width / 2
y: height + spikeHeight
}
PathLine {
x: width / 2 - 10
y: height + offset
}
PathLine {
x: -offset + curveRadius
y: height + offset
}
x: -offset
y: height + offset - curveRadius
radiusX: curveRadius
radiusY: curveRadius
PathLine {
x: -offset
y: -offset + curveRadius
}
x: -offset + curveRadius
y: -offset
radiusX: curveRadius
radiusY: curveRadius
visible: (isVideo && VideoDevices.listSize !== 0)
color: JamiTheme.blackColor
PreviewRenderer {
anchors.fill: rectBox
anchors.centerIn: rectBox
property string deviceId: VideoDevices.getDefaultDevice()
rendererId: VideoDevices.getDefaultDevice()
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
}
onVisibleChanged: {
if (visible) {
previewWidget.deviceId = VideoDevices.getDefaultDevice()
previewWidget.rendererId = VideoDevices.startDevice(previewWidget.deviceId)
} else
VideoDevices.stopDevice(previewWidget.deviceId)
}
anchors.centerIn: parent
width: root.width
visible: (isVideo && VideoDevices.listSize === 0)
onVisibleChanged: {
if (visible) {
closeRecorder()
}
}
text: JamiStrings.previewUnavailable
font.pointSize: JamiTheme.settingsFontSize
color: JamiTheme.primaryForegroundColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
interval: 1000
running: false
onTriggered: updateTimer()
}
Text {
id: time
anchors.horizontalCenterOffset: (isVideo ? 100 : 0)
anchors.verticalCenterOffset: (isVideo ? 0 : -100)
visible: true
text: "00:00"
color: (isVideo ? JamiTheme.whiteColor : JamiTheme.textColor)
font.pointSize: (isVideo ? 12 : 20)
anchors.horizontalCenter: root.horizontalCenter
anchors.bottom: root.bottom
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.fiber_manual_record_24dp_svg
imageColor: JamiTheme.recordIconColor
onClicked: {
updateState(RecordBox.States.RECORDING)
startRecording()
}
}
anchors.horizontalCenter: root.horizontalCenter
anchors.bottom: root.bottom
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.stop_24dp_red_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
onClicked: {
stopRecording()
updateState(RecordBox.States.REC_SUCCESS)
}
}
anchors.horizontalCenter: root.horizontalCenter
anchors.bottom: root.bottom
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.re_record_24dp_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
onClicked: {
stopRecording()
updateState(RecordBox.States.INIT)
}
}
anchors.horizontalCenter: root.horizontalCenter
anchors.horizontalCenterOffset: 25
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.send_24dp_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor