diff options
author | Joseph Donofry <joedonofry@gmail.com> | 2021-01-11 17:51:39 -0500 |
---|---|---|
committer | Joseph Donofry <joedonofry@gmail.com> | 2021-01-11 17:51:39 -0500 |
commit | 3ff8b3ad8c015d45a515ca381691cae43fc32a00 (patch) | |
tree | edec1d1e7926d9c0e0beb68ca604cc6bcdc1ebf6 /resources | |
parent | Add Ripple effects to qml buttons and avatar (diff) | |
parent | Merge pull request #372 from deepbluev7/fix-pr-CI (diff) | |
download | nheko-3ff8b3ad8c015d45a515ca381691cae43fc32a00.tar.xz |
Merge master and fix conflicts
Diffstat (limited to 'resources')
-rw-r--r-- | resources/nheko.desktop | 1 | ||||
-rw-r--r-- | resources/qml/MessageInput.qml | 32 | ||||
-rw-r--r-- | resources/qml/MessageView.qml | 9 | ||||
-rw-r--r-- | resources/qml/TimelineView.qml | 10 | ||||
-rw-r--r-- | resources/qml/ui/Ripple.qml | 6 | ||||
-rw-r--r-- | resources/qml/voip/ActiveCallBar.qml (renamed from resources/qml/ActiveCallBar.qml) | 64 | ||||
-rw-r--r-- | resources/qml/voip/CallDevices.qml | 78 | ||||
-rw-r--r-- | resources/qml/voip/CallInviteBar.qml | 128 | ||||
-rw-r--r-- | resources/qml/voip/DeviceError.qml | 32 | ||||
-rw-r--r-- | resources/qml/voip/PlaceCall.qml | 154 | ||||
-rw-r--r-- | resources/qml/voip/VideoCall.qml (renamed from resources/qml/VideoCall.qml) | 0 | ||||
-rw-r--r-- | resources/res.qrc | 11 |
12 files changed, 480 insertions, 45 deletions
diff --git a/resources/nheko.desktop b/resources/nheko.desktop index 16e04926..4404e460 100644 --- a/resources/nheko.desktop +++ b/resources/nheko.desktop @@ -8,3 +8,4 @@ Type=Application Categories=Network;InstantMessaging;Qt; StartupWMClass=nheko Terminal=false +MimeType=x-scheme-handler/matrix; diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index e8ebd5fc..0090ea95 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,14 @@ Rectangle { Layout.preferredHeight: textInput.height Layout.minimumHeight: 40 + Component { + id: placeCallDialog + + PlaceCall { + } + + } + RowLayout { id: inputBar @@ -17,18 +26,31 @@ Rectangle { spacing: 16 ImageButton { - visible: TimelineManager.callsSupported + visible: CallManager.callsSupported + opacity: CallManager.haveCallInvite ? 0.3 : 1 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 +61,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/MessageView.qml b/resources/qml/MessageView.qml index 679c1f50..aa222ac5 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -140,6 +140,15 @@ ListView { } + Label { + color: colors.buttonText + text: TimelineManager.userStatus(modelData.userId) + textFormat: Text.PlainText + elide: Text.ElideRight + width: chat.delegateMaxWidth - parent.spacing * 2 - userName.implicitWidth - avatarSize + font.italic: true + } + } } diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 6e9cd665..e596d8e2 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,13 @@ Page { } + CallInviteBar { + id: callInviteBar + + Layout.fillWidth: true + z: 3 + } + ActiveCallBar { Layout.fillWidth: true z: 3 diff --git a/resources/qml/ui/Ripple.qml b/resources/qml/ui/Ripple.qml index 9b404a68..93380f77 100644 --- a/resources/qml/ui/Ripple.qml +++ b/resources/qml/ui/Ripple.qml @@ -116,10 +116,10 @@ Item { ] Connections { - function onPressed(mouse) { - // Button - // Default to center + // Button + // Default to center + function onPressed(mouse) { // MouseArea if (mouse) { ripple.centerX = mouse.x; diff --git a/resources/qml/ActiveCallBar.qml b/resources/qml/voip/ActiveCallBar.qml index 3059e213..85da4e3c 100644 --- a/resources/qml/ActiveCallBar.qml +++ b/resources/qml/voip/ActiveCallBar.qml @@ -1,19 +1,18 @@ +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 +29,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 +102,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 +134,7 @@ Rectangle { } interval: 1000 - running: TimelineManager.callState == WebRTCState.CONNECTED + running: CallManager.callState == WebRTCState.CONNECTED repeat: true onTriggered: { var d = new Date(); @@ -149,34 +151,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..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/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 9b05575e..0603d19c 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,7 +157,16 @@ <file>qml/device-verification/NewVerificationRequest.qml</file> <file>qml/device-verification/Failed.qml</file> <file>qml/device-verification/Success.qml</file> +<<<<<<< HEAD <file>qml/ui/Ripple.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> +>>>>>>> b8b642219db37b1bf46ae47c01a446a7a4e24317 </qresource> <qresource prefix="/media"> <file>media/ring.ogg</file> |