summary refs log tree commit diff
path: root/resources/qml/voip
diff options
context:
space:
mode:
authorJoseph Donofry <joedonofry@gmail.com>2021-01-11 17:51:39 -0500
committerJoseph Donofry <joedonofry@gmail.com>2021-01-11 17:51:39 -0500
commit3ff8b3ad8c015d45a515ca381691cae43fc32a00 (patch)
treeedec1d1e7926d9c0e0beb68ca604cc6bcdc1ebf6 /resources/qml/voip
parentAdd Ripple effects to qml buttons and avatar (diff)
parentMerge pull request #372 from deepbluev7/fix-pr-CI (diff)
downloadnheko-3ff8b3ad8c015d45a515ca381691cae43fc32a00.tar.xz
Merge master and fix conflicts
Diffstat (limited to 'resources/qml/voip')
-rw-r--r--resources/qml/voip/ActiveCallBar.qml180
-rw-r--r--resources/qml/voip/CallDevices.qml78
-rw-r--r--resources/qml/voip/CallInviteBar.qml128
-rw-r--r--resources/qml/voip/DeviceError.qml32
-rw-r--r--resources/qml/voip/PlaceCall.qml154
-rw-r--r--resources/qml/voip/VideoCall.qml6
6 files changed, 578 insertions, 0 deletions
diff --git a/resources/qml/voip/ActiveCallBar.qml b/resources/qml/voip/ActiveCallBar.qml
new file mode 100644
index 00000000..85da4e3c
--- /dev/null
+++ b/resources/qml/voip/ActiveCallBar.qml
@@ -0,0 +1,180 @@
+import "../"
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+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 {
+            Layout.leftMargin: 8
+            font.pointSize: fontMetrics.font.pointSize * 1.1
+            text: CallManager.callParty
+            color: "#000000"
+        }
+
+        Image {
+            Layout.leftMargin: 4
+            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
+            color: "#000000"
+        }
+
+        Item {
+            states: [
+                State {
+                    name: "OFFERSENT"
+                    when: CallManager.callState == WebRTCState.OFFERSENT
+
+                    PropertyChanges {
+                        target: callStateLabel
+                        text: qsTr("Calling...")
+                    }
+
+                },
+                State {
+                    name: "CONNECTING"
+                    when: CallManager.callState == WebRTCState.CONNECTING
+
+                    PropertyChanges {
+                        target: callStateLabel
+                        text: qsTr("Connecting...")
+                    }
+
+                },
+                State {
+                    name: "ANSWERSENT"
+                    when: CallManager.callState == WebRTCState.ANSWERSENT
+
+                    PropertyChanges {
+                        target: callStateLabel
+                        text: qsTr("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.haveLocalVideo
+            width: 24
+            height: 24
+            buttonTextColor: "#000000"
+            image: ":/icons/icons/ui/toggle-camera-view.png"
+            hoverEnabled: true
+            ToolTip.visible: hovered
+            ToolTip.text: qsTr("Toggle camera view")
+            onClicked: CallManager.toggleCameraView()
+        }
+
+        ImageButton {
+            Layout.leftMargin: 8
+            Layout.rightMargin: 16
+            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()
+        }
+
+    }
+
+}
diff --git a/resources/qml/voip/CallDevices.qml b/resources/qml/voip/CallDevices.qml
new file mode 100644
index 00000000..8b30c540
--- /dev/null
+++ b/resources/qml/voip/CallDevices.qml
@@ -0,0 +1,78 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Popup {
+    modal: true
+    anchors.centerIn: parent
+    palette: colors
+
+    ColumnLayout {
+        spacing: 16
+
+        ColumnLayout {
+            spacing: 8
+            Layout.topMargin: 8
+            Layout.leftMargin: 8
+            Layout.rightMargin: 8
+
+            RowLayout {
+                Image {
+                    Layout.preferredWidth: 22
+                    Layout.preferredHeight: 22
+                    source: "image://colorimage/:/icons/icons/ui/microphone-unmute.png?" + colors.windowText
+                }
+
+                ComboBox {
+                    id: micCombo
+
+                    Layout.fillWidth: true
+                    model: CallManager.mics
+                }
+
+            }
+
+            RowLayout {
+                visible: CallManager.isVideo && CallManager.cameras.length > 0
+
+                Image {
+                    Layout.preferredWidth: 22
+                    Layout.preferredHeight: 22
+                    source: "image://colorimage/:/icons/icons/ui/video-call.png?" + colors.windowText
+                }
+
+                ComboBox {
+                    id: cameraCombo
+
+                    Layout.fillWidth: true
+                    model: CallManager.cameras
+                }
+
+            }
+
+        }
+
+        DialogButtonBox {
+            Layout.leftMargin: 128
+            standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
+            onAccepted: {
+                Settings.microphone = micCombo.currentText;
+                if (cameraCombo.visible)
+                    Settings.camera = cameraCombo.currentText;
+
+                close();
+            }
+            onRejected: {
+                close();
+            }
+        }
+
+    }
+
+    background: Rectangle {
+        color: colors.window
+        border.color: colors.windowText
+    }
+
+}
diff --git a/resources/qml/voip/CallInviteBar.qml b/resources/qml/voip/CallInviteBar.qml
new file mode 100644
index 00000000..e349332f
--- /dev/null
+++ b/resources/qml/voip/CallInviteBar.qml
@@ -0,0 +1,128 @@
+import "../"
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Rectangle {
+    visible: CallManager.haveCallInvite
+    color: "#2ECC71"
+    implicitHeight: visible ? rowLayout.height + 8 : 0
+
+    Component {
+        id: devicesDialog
+
+        CallDevices {
+        }
+
+    }
+
+    Component {
+        id: deviceError
+
+        DeviceError {
+        }
+
+    }
+
+    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 {
+            Layout.leftMargin: 8
+            font.pointSize: fontMetrics.font.pointSize * 1.1
+            text: CallManager.callParty
+            color: "#000000"
+        }
+
+        Image {
+            Layout.leftMargin: 4
+            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 ? qsTr("Video Call") : qsTr("Voice Call")
+            color: "#000000"
+        }
+
+        Item {
+            Layout.fillWidth: true
+        }
+
+        ImageButton {
+            Layout.rightMargin: 16
+            width: 20
+            height: 20
+            buttonTextColor: "#000000"
+            image: ":/icons/icons/ui/settings.png"
+            hoverEnabled: true
+            ToolTip.visible: hovered
+            ToolTip.text: qsTr("Devices")
+            onClicked: {
+                CallManager.refreshDevices();
+                var dialog = devicesDialog.createObject(timelineRoot);
+                dialog.open();
+            }
+        }
+
+        Button {
+            Layout.rightMargin: 4
+            icon.source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png"
+            text: qsTr(" Accept ")
+            palette: colors
+            onClicked: {
+                if (CallManager.mics.length == 0) {
+                    var dialog = deviceError.createObject(timelineRoot, {
+                        "errorString": qsTr("No microphone found."),
+                        "image": ":/icons/icons/ui/place-call.png"
+                    });
+                    dialog.open();
+                    return ;
+                } else if (!CallManager.mics.includes(Settings.microphone)) {
+                    var dialog = deviceError.createObject(timelineRoot, {
+                        "errorString": qsTr("Unknown microphone: ") + Settings.microphone,
+                        "image": ":/icons/icons/ui/place-call.png"
+                    });
+                    dialog.open();
+                    return ;
+                }
+                if (CallManager.isVideo && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) {
+                    var dialog = deviceError.createObject(timelineRoot, {
+                        "errorString": qsTr("Unknown camera: ") + Settings.camera,
+                        "image": ":/icons/icons/ui/video-call.png"
+                    });
+                    dialog.open();
+                    return ;
+                }
+                CallManager.acceptInvite();
+            }
+        }
+
+        Button {
+            Layout.rightMargin: 16
+            icon.source: "qrc:/icons/icons/ui/end-call.png"
+            text: qsTr(" Decline ")
+            palette: colors
+            onClicked: {
+                CallManager.hangUp();
+            }
+        }
+
+    }
+
+}
diff --git a/resources/qml/voip/DeviceError.qml b/resources/qml/voip/DeviceError.qml
new file mode 100644
index 00000000..81872ef7
--- /dev/null
+++ b/resources/qml/voip/DeviceError.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Popup {
+    property string errorString
+    property var image
+
+    modal: true
+    anchors.centerIn: parent
+
+    RowLayout {
+        Image {
+            Layout.preferredWidth: 16
+            Layout.preferredHeight: 16
+            source: "image://colorimage/" + image + "?" + colors.windowText
+        }
+
+        Label {
+            text: errorString
+            color: colors.windowText
+        }
+
+    }
+
+    background: Rectangle {
+        color: colors.window
+        border.color: colors.windowText
+    }
+
+}
diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml
new file mode 100644
index 00000000..65f2f350
--- /dev/null
+++ b/resources/qml/voip/PlaceCall.qml
@@ -0,0 +1,154 @@
+import "../"
+import QtQuick 2.9
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import im.nheko 1.0
+
+Popup {
+    modal: true
+    anchors.centerIn: parent
+    palette: colors
+
+    Component {
+        id: deviceError
+
+        DeviceError {
+        }
+
+    }
+
+    ColumnLayout {
+        id: columnLayout
+
+        spacing: 16
+
+        RowLayout {
+            Layout.topMargin: 8
+            Layout.leftMargin: 8
+
+            Label {
+                text: qsTr("Place a call to ") + TimelineManager.timeline.roomName + "?"
+                color: colors.windowText
+            }
+
+            Item {
+                Layout.fillWidth: true
+            }
+
+        }
+
+        RowLayout {
+            id: buttonLayout
+
+            function validateMic() {
+                if (CallManager.mics.length == 0) {
+                    var dialog = deviceError.createObject(timelineRoot, {
+                        "errorString": qsTr("No microphone found."),
+                        "image": ":/icons/icons/ui/place-call.png"
+                    });
+                    dialog.open();
+                    return false;
+                }
+                return true;
+            }
+
+            Layout.leftMargin: 8
+            Layout.rightMargin: 8
+
+            Avatar {
+                Layout.rightMargin: cameraCombo.visible ? 16 : 64
+                width: avatarSize
+                height: avatarSize
+                url: TimelineManager.timeline.roomAvatarUrl.replace("mxc://", "image://MxcImage/")
+                displayName: TimelineManager.timeline.roomName
+            }
+
+            Button {
+                text: qsTr(" Voice ")
+                icon.source: "qrc:/icons/icons/ui/place-call.png"
+                onClicked: {
+                    if (buttonLayout.validateMic()) {
+                        Settings.microphone = micCombo.currentText;
+                        CallManager.sendInvite(TimelineManager.timeline.roomId(), false);
+                        close();
+                    }
+                }
+            }
+
+            Button {
+                visible: CallManager.cameras.length > 0
+                text: qsTr(" Video ")
+                icon.source: "qrc:/icons/icons/ui/video-call.png"
+                onClicked: {
+                    if (buttonLayout.validateMic()) {
+                        Settings.microphone = micCombo.currentText;
+                        Settings.camera = cameraCombo.currentText;
+                        CallManager.sendInvite(TimelineManager.timeline.roomId(), true);
+                        close();
+                    }
+                }
+            }
+
+            Button {
+                text: qsTr("Cancel")
+                onClicked: {
+                    close();
+                }
+            }
+
+        }
+
+        ColumnLayout {
+            spacing: 8
+
+            RowLayout {
+                Layout.leftMargin: 8
+                Layout.rightMargin: 8
+                Layout.bottomMargin: cameraCombo.visible ? 0 : 8
+
+                Image {
+                    Layout.preferredWidth: 22
+                    Layout.preferredHeight: 22
+                    source: "image://colorimage/:/icons/icons/ui/microphone-unmute.png?" + colors.windowText
+                }
+
+                ComboBox {
+                    id: micCombo
+
+                    Layout.fillWidth: true
+                    model: CallManager.mics
+                }
+
+            }
+
+            RowLayout {
+                visible: CallManager.cameras.length > 0
+                Layout.leftMargin: 8
+                Layout.rightMargin: 8
+                Layout.bottomMargin: 8
+
+                Image {
+                    Layout.preferredWidth: 22
+                    Layout.preferredHeight: 22
+                    source: "image://colorimage/:/icons/icons/ui/video-call.png?" + colors.windowText
+                }
+
+                ComboBox {
+                    id: cameraCombo
+
+                    Layout.fillWidth: true
+                    model: CallManager.cameras
+                }
+
+            }
+
+        }
+
+    }
+
+    background: Rectangle {
+        color: colors.window
+        border.color: colors.windowText
+    }
+
+}
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"
+}