summary refs log tree commit diff
path: root/resources
diff options
context:
space:
mode:
authorDeepBlueV7.X <nicolas.werner@hotmail.de>2021-01-07 15:56:46 +0100
committerGitHub <noreply@github.com>2021-01-07 15:56:46 +0100
commit49abcb24b5b243bed96a8961a2614233cda23afb (patch)
tree151078e9f4dbe15141e09a1d31ad59eab78843ce /resources
parentFix notification reply build on other platforms (diff)
parentFix device discovery under GStreamer 1.16 (diff)
downloadnheko-49abcb24b5b243bed96a8961a2614233cda23afb.tar.xz
Merge pull request #356 from trilene/call-dialogs-qml
Port call dialogs to Qml
Diffstat (limited to 'resources')
-rw-r--r--resources/qml/MessageInput.qml33
-rw-r--r--resources/qml/TimelineView.qml9
-rw-r--r--resources/qml/voip/ActiveCallBar.qml (renamed from resources/qml/ActiveCallBar.qml)65
-rw-r--r--resources/qml/voip/CallDevices.qml79
-rw-r--r--resources/qml/voip/CallInviteBar.qml126
-rw-r--r--resources/qml/voip/DeviceError.qml31
-rw-r--r--resources/qml/voip/PlaceCall.qml146
-rw-r--r--resources/qml/voip/VideoCall.qml (renamed from resources/qml/VideoCall.qml)0
-rw-r--r--resources/res.qrc8
9 files changed, 454 insertions, 43 deletions
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml

index e8ebd5fc..00edb7e5 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml
@@ -1,3 +1,4 @@ +import "./voip" import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 @@ -10,6 +11,13 @@ Rectangle { Layout.preferredHeight: textInput.height Layout.minimumHeight: 40 + Component { + id: placeCallDialog + + PlaceCall { + } + } + RowLayout { id: inputBar @@ -17,18 +25,33 @@ Rectangle { spacing: 16 ImageButton { - visible: TimelineManager.callsSupported + visible: CallManager.callsSupported + opacity: CallManager.haveCallInvite ? 0.3 : 1.0 Layout.alignment: Qt.AlignBottom hoverEnabled: true width: 22 height: 22 - image: TimelineManager.isOnCall ? ":/icons/icons/ui/end-call.png" : ":/icons/icons/ui/place-call.png" + image: CallManager.isOnCall ? ":/icons/icons/ui/end-call.png" : ":/icons/icons/ui/place-call.png" ToolTip.visible: hovered - ToolTip.text: TimelineManager.isOnCall ? qsTr("Hang up") : qsTr("Place a call") + ToolTip.text: CallManager.isOnCall ? qsTr("Hang up") : qsTr("Place a call") Layout.topMargin: 8 Layout.bottomMargin: 8 Layout.leftMargin: 16 - onClicked: TimelineManager.timeline.input.callButton() + onClicked: { + if (TimelineManager.timeline) { + if (CallManager.haveCallInvite) { + return; + } + else if (CallManager.isOnCall) { + CallManager.hangUp(); + } + else { + CallManager.refreshDevices(); + var dialog = placeCallDialog.createObject(timelineRoot); + dialog.open(); + } + } + } } ImageButton { @@ -39,7 +62,7 @@ Rectangle { image: ":/icons/icons/ui/paper-clip-outline.png" Layout.topMargin: 8 Layout.bottomMargin: 8 - Layout.leftMargin: TimelineManager.callsSupported ? 0 : 16 + Layout.leftMargin: CallManager.callsSupported ? 0 : 16 onClicked: TimelineManager.timeline.input.openFileSelection() ToolTip.visible: hovered ToolTip.text: qsTr("Send a file") diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 6e9cd665..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: TimelineManager.onVideoCall ? "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/ActiveCallBar.qml b/resources/qml/voip/ActiveCallBar.qml
index 3059e213..0e932e13 100644 --- a/resources/qml/ActiveCallBar.qml +++ b/resources/qml/voip/ActiveCallBar.qml
@@ -1,19 +1,19 @@ +import "../" import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 import im.nheko 1.0 Rectangle { - id: activeCallBar - visible: TimelineManager.callState != WebRTCState.DISCONNECTED - color: "#2ECC71" + visible: CallManager.isOnCall + color: callInviteBar.color implicitHeight: visible ? rowLayout.height + 8 : 0 MouseArea { anchors.fill: parent onClicked: { - if (TimelineManager.onVideoCall) + if (CallManager.isVideo) stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1; } @@ -30,63 +30,66 @@ Rectangle { Avatar { width: avatarSize height: avatarSize - url: TimelineManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") - displayName: TimelineManager.callPartyName + url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") + displayName: CallManager.callParty } Label { + Layout.leftMargin: 8 font.pointSize: fontMetrics.font.pointSize * 1.1 - text: " " + TimelineManager.callPartyName + " " + text: CallManager.callParty + color: "#000000" } Image { + Layout.leftMargin: 4 Layout.preferredWidth: 24 Layout.preferredHeight: 24 - source: TimelineManager.onVideoCall ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" + 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 { - state: TimelineManager.callState states: [ State { name: "OFFERSENT" - when: state == WebRTCState.OFFERSENT + when: CallManager.callState == WebRTCState.OFFERSENT PropertyChanges { target: callStateLabel - text: "Calling..." + text: qsTr("Calling...") } }, State { name: "CONNECTING" - when: state == WebRTCState.CONNECTING + when: CallManager.callState == WebRTCState.CONNECTING PropertyChanges { target: callStateLabel - text: "Connecting..." + text: qsTr("Connecting...") } }, State { name: "ANSWERSENT" - when: state == WebRTCState.ANSWERSENT + when: CallManager.callState == WebRTCState.ANSWERSENT PropertyChanges { target: callStateLabel - text: "Connecting..." + text: qsTr("Connecting...") } }, State { name: "CONNECTED" - when: state == WebRTCState.CONNECTED + when: CallManager.callState == WebRTCState.CONNECTED PropertyChanges { target: callStateLabel @@ -100,13 +103,13 @@ Rectangle { PropertyChanges { target: stackLayout - currentIndex: TimelineManager.onVideoCall ? 1 : 0 + currentIndex: CallManager.isVideo ? 1 : 0 } }, State { name: "DISCONNECTED" - when: state == WebRTCState.DISCONNECTED + when: CallManager.callState == WebRTCState.DISCONNECTED PropertyChanges { target: callStateLabel @@ -132,7 +135,7 @@ Rectangle { } interval: 1000 - running: TimelineManager.callState == WebRTCState.CONNECTED + running: CallManager.callState == WebRTCState.CONNECTED repeat: true onTriggered: { var d = new Date(); @@ -149,36 +152,28 @@ Rectangle { } ImageButton { - visible: TimelineManager.onVideoCall + visible: CallManager.haveLocalVideo 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: TimelineManager.toggleCameraView() - } - - Item { - implicitWidth: 8 + ToolTip.text: qsTr("Toggle camera view") + onClicked: CallManager.toggleCameraView() } ImageButton { + Layout.leftMargin: 8 + Layout.rightMargin: 16 width: 24 height: 24 buttonTextColor: "#000000" - image: TimelineManager.isMicMuted ? ":/icons/icons/ui/microphone-unmute.png" : ":/icons/icons/ui/microphone-mute.png" + image: CallManager.isMicMuted ? ":/icons/icons/ui/microphone-unmute.png" : ":/icons/icons/ui/microphone-mute.png" hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: TimelineManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic") - onClicked: TimelineManager.toggleMicMute() - } - - Item { - implicitWidth: 16 + 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..f0847b14 --- /dev/null +++ b/resources/qml/voip/CallDevices.qml
@@ -0,0 +1,79 @@ +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 + background: Rectangle { + color: colors.window + border.color: colors.windowText + } + + 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(); + } + } + } +} diff --git a/resources/qml/voip/CallInviteBar.qml b/resources/qml/voip/CallInviteBar.qml new file mode 100644
index 00000000..5021949a --- /dev/null +++ b/resources/qml/voip/CallInviteBar.qml
@@ -0,0 +1,126 @@ +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..a6411b95 --- /dev/null +++ b/resources/qml/voip/DeviceError.qml
@@ -0,0 +1,31 @@ +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 + background: Rectangle { + color: colors.window + border.color: colors.windowText + } + + RowLayout { + + Image { + Layout.preferredWidth: 16 + Layout.preferredHeight: 16 + source: "image://colorimage/" + image + "?" + colors.windowText + } + + Label { + text: errorString + color: colors.windowText + } + } +} diff --git a/resources/qml/voip/PlaceCall.qml b/resources/qml/voip/PlaceCall.qml new file mode 100644
index 00000000..95383d95 --- /dev/null +++ b/resources/qml/voip/PlaceCall.qml
@@ -0,0 +1,146 @@ +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 + background: Rectangle { + color: colors.window + border.color: colors.windowText + } + + 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 + + Layout.leftMargin: 8 + Layout.rightMargin: 8 + + 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; + } + + 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 + } + } + } + } +} diff --git a/resources/qml/VideoCall.qml b/resources/qml/voip/VideoCall.qml
index 14408b6e..14408b6e 100644 --- a/resources/qml/VideoCall.qml +++ b/resources/qml/voip/VideoCall.qml
diff --git a/resources/res.qrc b/resources/res.qrc
index a01907ec..bceeb298 100644 --- a/resources/res.qrc +++ b/resources/res.qrc
@@ -123,7 +123,6 @@ <file>qtquickcontrols2.conf</file> <file>qml/TimelineView.qml</file> - <file>qml/ActiveCallBar.qml</file> <file>qml/Avatar.qml</file> <file>qml/Completer.qml</file> <file>qml/EncryptionIndicator.qml</file> @@ -139,7 +138,6 @@ <file>qml/TimelineRow.qml</file> <file>qml/TopBar.qml</file> <file>qml/TypingIndicator.qml</file> - <file>qml/VideoCall.qml</file> <file>qml/emoji/EmojiButton.qml</file> <file>qml/emoji/EmojiPicker.qml</file> <file>qml/UserProfile.qml</file> @@ -159,6 +157,12 @@ <file>qml/device-verification/NewVerificationRequest.qml</file> <file>qml/device-verification/Failed.qml</file> <file>qml/device-verification/Success.qml</file> + <file>qml/voip/ActiveCallBar.qml</file> + <file>qml/voip/CallDevices.qml</file> + <file>qml/voip/CallInviteBar.qml</file> + <file>qml/voip/DeviceError.qml</file> + <file>qml/voip/PlaceCall.qml</file> + <file>qml/voip/VideoCall.qml</file> </qresource> <qresource prefix="/media"> <file>media/ring.ogg</file>