From 7124024977ccb237547b88b6a96a50ac6838c354 Mon Sep 17 00:00:00 2001 From: trilene Date: Thu, 17 Dec 2020 11:25:32 -0500 Subject: Make call invites less intrusive --- resources/qml/ActiveCallBar.qml | 183 ----------------------------------- resources/qml/TimelineView.qml | 9 +- resources/qml/VideoCall.qml | 6 -- resources/qml/voip/ActiveCallBar.qml | 183 +++++++++++++++++++++++++++++++++++ resources/qml/voip/CallInviteBar.qml | 95 ++++++++++++++++++ resources/qml/voip/VideoCall.qml | 6 ++ 6 files changed, 292 insertions(+), 190 deletions(-) delete mode 100644 resources/qml/ActiveCallBar.qml delete mode 100644 resources/qml/VideoCall.qml create mode 100644 resources/qml/voip/ActiveCallBar.qml create mode 100644 resources/qml/voip/CallInviteBar.qml create mode 100644 resources/qml/voip/VideoCall.qml (limited to 'resources/qml') diff --git a/resources/qml/ActiveCallBar.qml b/resources/qml/ActiveCallBar.qml deleted file mode 100644 index 57b0877c..00000000 --- a/resources/qml/ActiveCallBar.qml +++ /dev/null @@ -1,183 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.2 -import im.nheko 1.0 - -Rectangle { - id: activeCallBar - - visible: CallManager.isOnCall - color: "#2ECC71" - implicitHeight: visible ? rowLayout.height + 8 : 0 - - MouseArea { - anchors.fill: parent - onClicked: { - if (CallManager.isOnVideoCall) - stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1; - - } - } - - RowLayout { - id: rowLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: 8 - - Avatar { - width: avatarSize - height: avatarSize - url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") - displayName: CallManager.callPartyName - } - - Label { - font.pointSize: fontMetrics.font.pointSize * 1.1 - text: " " + CallManager.callPartyName + " " - } - - Image { - Layout.preferredWidth: 24 - Layout.preferredHeight: 24 - source: CallManager.isOnVideoCall ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" - } - - Label { - id: callStateLabel - - font.pointSize: fontMetrics.font.pointSize * 1.1 - } - - Item { - states: [ - State { - name: "OFFERSENT" - when: CallManager.callState == WebRTCState.OFFERSENT - - PropertyChanges { - target: callStateLabel - text: "Calling..." - } - - }, - State { - name: "CONNECTING" - when: CallManager.callState == WebRTCState.CONNECTING - - PropertyChanges { - target: callStateLabel - text: "Connecting..." - } - - }, - State { - name: "ANSWERSENT" - when: CallManager.callState == WebRTCState.ANSWERSENT - - PropertyChanges { - target: callStateLabel - text: "Connecting..." - } - - }, - State { - name: "CONNECTED" - when: CallManager.callState == WebRTCState.CONNECTED - - PropertyChanges { - target: callStateLabel - text: "00:00" - } - - PropertyChanges { - target: callTimer - startTime: Math.floor((new Date()).getTime() / 1000) - } - - PropertyChanges { - target: stackLayout - currentIndex: CallManager.isOnVideoCall ? 1 : 0 - } - - }, - State { - name: "DISCONNECTED" - when: CallManager.callState == WebRTCState.DISCONNECTED - - PropertyChanges { - target: callStateLabel - text: "" - } - - PropertyChanges { - target: stackLayout - currentIndex: 0 - } - - } - ] - } - - Timer { - id: callTimer - - property int startTime - - function pad(n) { - return (n < 10) ? ("0" + n) : n; - } - - interval: 1000 - running: CallManager.callState == WebRTCState.CONNECTED - repeat: true - onTriggered: { - var d = new Date(); - let seconds = Math.floor(d.getTime() / 1000 - startTime); - let s = Math.floor(seconds % 60); - let m = Math.floor(seconds / 60) % 60; - let h = Math.floor(seconds / 3600); - callStateLabel.text = (h ? (pad(h) + ":") : "") + pad(m) + ":" + pad(s); - } - } - - Item { - Layout.fillWidth: true - } - - ImageButton { - visible: CallManager.isOnVideoCall - width: 24 - height: 24 - buttonTextColor: "#000000" - image: ":/icons/icons/ui/toggle-camera-view.png" - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: "Toggle camera view" - onClicked: CallManager.toggleCameraView() - } - - Item { - implicitWidth: 8 - } - - ImageButton { - width: 24 - height: 24 - buttonTextColor: "#000000" - image: CallManager.isMicMuted ? ":/icons/icons/ui/microphone-unmute.png" : ":/icons/icons/ui/microphone-mute.png" - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: CallManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic") - onClicked: CallManager.toggleMicMute() - } - - Item { - implicitWidth: 16 - } - - } - -} diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index c71eb89f..3e134b35 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -1,6 +1,7 @@ import "./delegates" import "./device-verification" import "./emoji" +import "./voip" import QtGraphicalEffects 1.0 import QtQuick 2.9 import QtQuick.Controls 2.3 @@ -210,7 +211,7 @@ Page { } Loader { - source: CallManager.isOnVideoCall ? "VideoCall.qml" : "" + source: CallManager.isOnCall && CallManager.isVideo ? "voip/VideoCall.qml" : "" onLoaded: TimelineManager.setVideoCallItem() } @@ -223,6 +224,12 @@ Page { } + CallInviteBar { + id: callInviteBar + Layout.fillWidth: true + z: 3 + } + ActiveCallBar { Layout.fillWidth: true z: 3 diff --git a/resources/qml/VideoCall.qml b/resources/qml/VideoCall.qml deleted file mode 100644 index 14408b6e..00000000 --- a/resources/qml/VideoCall.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.9 -import org.freedesktop.gstreamer.GLVideoItem 1.0 - -GstGLVideoItem { - objectName: "videoCallItem" -} diff --git a/resources/qml/voip/ActiveCallBar.qml b/resources/qml/voip/ActiveCallBar.qml new file mode 100644 index 00000000..9efdb325 --- /dev/null +++ b/resources/qml/voip/ActiveCallBar.qml @@ -0,0 +1,183 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import im.nheko 1.0 +import "../" + +Rectangle { + + visible: CallManager.isOnCall + color: callInviteBar.color + implicitHeight: visible ? rowLayout.height + 8 : 0 + + MouseArea { + anchors.fill: parent + onClicked: { + if (CallManager.isVideo) + stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1; + + } + } + + RowLayout { + id: rowLayout + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 8 + + Avatar { + width: avatarSize + height: avatarSize + url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") + displayName: CallManager.callParty + } + + Label { + font.pointSize: fontMetrics.font.pointSize * 1.1 + text: " " + CallManager.callParty + " " + } + + Image { + Layout.preferredWidth: 24 + Layout.preferredHeight: 24 + source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" + } + + Label { + id: callStateLabel + + font.pointSize: fontMetrics.font.pointSize * 1.1 + } + + Item { + states: [ + State { + name: "OFFERSENT" + when: CallManager.callState == WebRTCState.OFFERSENT + + PropertyChanges { + target: callStateLabel + text: "Calling..." + } + + }, + State { + name: "CONNECTING" + when: CallManager.callState == WebRTCState.CONNECTING + + PropertyChanges { + target: callStateLabel + text: "Connecting..." + } + + }, + State { + name: "ANSWERSENT" + when: CallManager.callState == WebRTCState.ANSWERSENT + + PropertyChanges { + target: callStateLabel + text: "Connecting..." + } + + }, + State { + name: "CONNECTED" + when: CallManager.callState == WebRTCState.CONNECTED + + PropertyChanges { + target: callStateLabel + text: "00:00" + } + + PropertyChanges { + target: callTimer + startTime: Math.floor((new Date()).getTime() / 1000) + } + + PropertyChanges { + target: stackLayout + currentIndex: CallManager.isVideo ? 1 : 0 + } + + }, + State { + name: "DISCONNECTED" + when: CallManager.callState == WebRTCState.DISCONNECTED + + PropertyChanges { + target: callStateLabel + text: "" + } + + PropertyChanges { + target: stackLayout + currentIndex: 0 + } + + } + ] + } + + Timer { + id: callTimer + + property int startTime + + function pad(n) { + return (n < 10) ? ("0" + n) : n; + } + + interval: 1000 + running: CallManager.callState == WebRTCState.CONNECTED + repeat: true + onTriggered: { + var d = new Date(); + let seconds = Math.floor(d.getTime() / 1000 - startTime); + let s = Math.floor(seconds % 60); + let m = Math.floor(seconds / 60) % 60; + let h = Math.floor(seconds / 3600); + callStateLabel.text = (h ? (pad(h) + ":") : "") + pad(m) + ":" + pad(s); + } + } + + Item { + Layout.fillWidth: true + } + + ImageButton { + visible: CallManager.isVideo + width: 24 + height: 24 + buttonTextColor: "#000000" + image: ":/icons/icons/ui/toggle-camera-view.png" + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: "Toggle camera view" + onClicked: CallManager.toggleCameraView() + } + + Item { + implicitWidth: 8 + } + + ImageButton { + width: 24 + height: 24 + buttonTextColor: "#000000" + image: CallManager.isMicMuted ? ":/icons/icons/ui/microphone-unmute.png" : ":/icons/icons/ui/microphone-mute.png" + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: CallManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic") + onClicked: CallManager.toggleMicMute() + } + + Item { + implicitWidth: 16 + } + + } + +} diff --git a/resources/qml/voip/CallInviteBar.qml b/resources/qml/voip/CallInviteBar.qml new file mode 100644 index 00000000..6d4d2ac0 --- /dev/null +++ b/resources/qml/voip/CallInviteBar.qml @@ -0,0 +1,95 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.2 +import im.nheko 1.0 +import "../" + +Rectangle { + + visible: CallManager.haveCallInvite + color: "#2ECC71" + implicitHeight: visible ? rowLayout.height + 8 : 0 + + MessageDialog { + id: warningDialog + icon: StandardIcon.Warning + } + + RowLayout { + id: rowLayout + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 8 + + Avatar { + width: avatarSize + height: avatarSize + url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") + displayName: CallManager.callParty + } + + Label { + font.pointSize: fontMetrics.font.pointSize * 1.1 + text: " " + CallManager.callParty + " " + } + + Image { + Layout.preferredWidth: 24 + Layout.preferredHeight: 24 + source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" + } + + Label { + font.pointSize: fontMetrics.font.pointSize * 1.1 + text: CallManager.isVideo ? "Video Call" : "Voice Call" + } + + Item { + Layout.fillWidth: true + } + + Button { + icon.source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" + palette: colors + text: qsTr("Accept") + onClicked: { + if (CallManager.mics.length == 0) { + warningDialog.text = "No microphone found."; + warningDialog.open(); + return; + } + else if (!CallManager.mics.includes(Settings.microphone)) { + warningDialog.text = "Unknown microphone: " + Settings.microphone; + warningDialog.open(); + return; + } + if (CallManager.isVideo && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) { + warningDialog.text = "Unknown camera: " + Settings.camera; + warningDialog.open(); + return; + } + CallManager.acceptInvite(); + } + } + + Item { + implicitWidth: 8 + } + + Button { + icon.source: "qrc:/icons/icons/ui/end-call.png" + palette: colors + text: qsTr("Decline") + onClicked: { + CallManager.hangUp(); + } + } + + Item { + implicitWidth: 16 + } + } +} diff --git a/resources/qml/voip/VideoCall.qml b/resources/qml/voip/VideoCall.qml new file mode 100644 index 00000000..14408b6e --- /dev/null +++ b/resources/qml/voip/VideoCall.qml @@ -0,0 +1,6 @@ +import QtQuick 2.9 +import org.freedesktop.gstreamer.GLVideoItem 1.0 + +GstGLVideoItem { + objectName: "videoCallItem" +} -- cgit 1.5.1