From ac410f46f2900bdab5a5619529a1c91f002c48c4 Mon Sep 17 00:00:00 2001 From: trilene Date: Wed, 9 Dec 2020 20:49:48 -0500 Subject: [PATCH] Move call-related properties to CallManager --- resources/qml/ActiveCallBar.qml | 37 +++++++++++----------- resources/qml/MessageInput.qml | 8 ++--- resources/qml/TimelineView.qml | 2 +- src/CallManager.cpp | 35 ++++++++++++++------- src/CallManager.h | 21 +++++++++++-- src/timeline/InputBar.cpp | 2 +- src/timeline/TimelineViewManager.cpp | 47 +++------------------------- src/timeline/TimelineViewManager.h | 23 +------------- 8 files changed, 70 insertions(+), 105 deletions(-) diff --git a/resources/qml/ActiveCallBar.qml b/resources/qml/ActiveCallBar.qml index 3059e213..57b0877c 100644 --- a/resources/qml/ActiveCallBar.qml +++ b/resources/qml/ActiveCallBar.qml @@ -6,14 +6,14 @@ import im.nheko 1.0 Rectangle { id: activeCallBar - visible: TimelineManager.callState != WebRTCState.DISCONNECTED + visible: CallManager.isOnCall color: "#2ECC71" implicitHeight: visible ? rowLayout.height + 8 : 0 MouseArea { anchors.fill: parent onClicked: { - if (TimelineManager.onVideoCall) + if (CallManager.isOnVideoCall) stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1; } @@ -30,19 +30,19 @@ 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.callPartyName } Label { font.pointSize: fontMetrics.font.pointSize * 1.1 - text: " " + TimelineManager.callPartyName + " " + text: " " + CallManager.callPartyName + " " } Image { 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.isOnVideoCall ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" } Label { @@ -52,11 +52,10 @@ Rectangle { } Item { - state: TimelineManager.callState states: [ State { name: "OFFERSENT" - when: state == WebRTCState.OFFERSENT + when: CallManager.callState == WebRTCState.OFFERSENT PropertyChanges { target: callStateLabel @@ -66,7 +65,7 @@ Rectangle { }, State { name: "CONNECTING" - when: state == WebRTCState.CONNECTING + when: CallManager.callState == WebRTCState.CONNECTING PropertyChanges { target: callStateLabel @@ -76,7 +75,7 @@ Rectangle { }, State { name: "ANSWERSENT" - when: state == WebRTCState.ANSWERSENT + when: CallManager.callState == WebRTCState.ANSWERSENT PropertyChanges { target: callStateLabel @@ -86,7 +85,7 @@ Rectangle { }, State { name: "CONNECTED" - when: state == WebRTCState.CONNECTED + when: CallManager.callState == WebRTCState.CONNECTED PropertyChanges { target: callStateLabel @@ -100,13 +99,13 @@ Rectangle { PropertyChanges { target: stackLayout - currentIndex: TimelineManager.onVideoCall ? 1 : 0 + currentIndex: CallManager.isOnVideoCall ? 1 : 0 } }, State { name: "DISCONNECTED" - when: state == WebRTCState.DISCONNECTED + when: CallManager.callState == WebRTCState.DISCONNECTED PropertyChanges { target: callStateLabel @@ -132,7 +131,7 @@ Rectangle { } interval: 1000 - running: TimelineManager.callState == WebRTCState.CONNECTED + running: CallManager.callState == WebRTCState.CONNECTED repeat: true onTriggered: { var d = new Date(); @@ -149,7 +148,7 @@ Rectangle { } ImageButton { - visible: TimelineManager.onVideoCall + visible: CallManager.isOnVideoCall width: 24 height: 24 buttonTextColor: "#000000" @@ -157,7 +156,7 @@ Rectangle { hoverEnabled: true ToolTip.visible: hovered ToolTip.text: "Toggle camera view" - onClicked: TimelineManager.toggleCameraView() + onClicked: CallManager.toggleCameraView() } Item { @@ -168,11 +167,11 @@ Rectangle { 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() + ToolTip.text: CallManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic") + onClicked: CallManager.toggleMicMute() } Item { diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index e8ebd5fc..2847d51d 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -17,14 +17,14 @@ Rectangle { spacing: 16 ImageButton { - visible: TimelineManager.callsSupported + visible: CallManager.callsSupported 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 @@ -39,7 +39,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..c71eb89f 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -210,7 +210,7 @@ Page { } Loader { - source: TimelineManager.onVideoCall ? "VideoCall.qml" : "" + source: CallManager.isOnVideoCall ? "VideoCall.qml" : "" onLoaded: TimelineManager.setVideoCallItem() } diff --git a/src/CallManager.cpp b/src/CallManager.cpp index 89cfeaf9..cb523bc2 100644 --- a/src/CallManager.cpp +++ b/src/CallManager.cpp @@ -13,7 +13,6 @@ #include "MainWindow.h" #include "MatrixClient.h" #include "Utils.h" -#include "WebRTCSession.h" #include "dialogs/AcceptCall.h" #include "mtx/responses/turn_server.hpp" @@ -112,6 +111,7 @@ CallManager::CallManager(QObject *parent) default: break; } + emit newCallState(); }); connect(&player_, @@ -144,7 +144,7 @@ CallManager::CallManager(QObject *parent) void CallManager::sendInvite(const QString &roomid, bool isVideo) { - if (onActiveCall()) + if (isOnCall()) return; auto roomInfo = cache::singleRoomInfo(roomid.toStdString()); @@ -206,12 +206,6 @@ CallManager::hangUp(CallHangUp::Reason reason) } } -bool -CallManager::onActiveCall() const -{ - return session_.state() != webrtc::State::DISCONNECTED; -} - void CallManager::syncEvent(const mtx::events::collections::TimelineEvents &event) { @@ -257,7 +251,7 @@ CallManager::handleEvent(const RoomEvent &callInviteEvent) return; auto roomInfo = cache::singleRoomInfo(callInviteEvent.room_id); - if (onActiveCall() || roomInfo.member_count != 2) { + if (isOnCall() || roomInfo.member_count != 2) { emit newMessage(QString::fromStdString(callInviteEvent.room_id), CallHangUp{callInviteEvent.content.call_id, 0, @@ -332,7 +326,7 @@ CallManager::handleEvent(const RoomEvent &callCandidatesEvent) callCandidatesEvent.sender); if (callid_ == callCandidatesEvent.content.call_id) { - if (onActiveCall()) + if (isOnCall()) session_.acceptICECandidates(callCandidatesEvent.content.candidates); else { // CallInvite has been received and we're awaiting localUser to accept or @@ -350,7 +344,7 @@ CallManager::handleEvent(const RoomEvent &callAnswerEvent) callAnswerEvent.content.call_id, callAnswerEvent.sender); - if (!onActiveCall() && callAnswerEvent.sender == utils::localUser().toStdString() && + if (!isOnCall() && callAnswerEvent.sender == utils::localUser().toStdString() && callid_ == callAnswerEvent.content.call_id) { emit ChatPage::instance()->showNotification("Call answered on another device."); stopRingtone(); @@ -358,7 +352,7 @@ CallManager::handleEvent(const RoomEvent &callAnswerEvent) return; } - if (onActiveCall() && callid_ == callAnswerEvent.content.call_id) { + if (isOnCall() && callid_ == callAnswerEvent.content.call_id) { stopRingtone(); if (!session_.acceptAnswer(callAnswerEvent.content.sdp)) { emit ChatPage::instance()->showNotification("Problem setting up call."); @@ -381,6 +375,23 @@ CallManager::handleEvent(const RoomEvent &callHangUpEvent) } } +void +CallManager::toggleMicMute() +{ + session_.toggleMicMute(); + emit micMuteChanged(); +} + +bool +CallManager::callsSupported() const +{ +#ifdef GSTREAMER_AVAILABLE + return true; +#else + return false; +#endif +} + void CallManager::generateCallID() { diff --git a/src/CallManager.h b/src/CallManager.h index 8004e838..d59a6249 100644 --- a/src/CallManager.h +++ b/src/CallManager.h @@ -8,6 +8,7 @@ #include #include +#include "WebRTCSession.h" #include "mtx/events/collections.hpp" #include "mtx/events/voip.hpp" @@ -16,11 +17,17 @@ struct TurnServer; } class QUrl; -class WebRTCSession; class CallManager : public QObject { Q_OBJECT + Q_PROPERTY(bool isOnCall READ isOnCall NOTIFY newCallState) + Q_PROPERTY(bool isOnVideoCall READ isOnVideoCall NOTIFY newVideoCallState) + Q_PROPERTY(webrtc::State callState READ callState NOTIFY newCallState) + Q_PROPERTY(QString callPartyName READ callPartyName NOTIFY newCallParty) + Q_PROPERTY(QString callPartyAvatarUrl READ callPartyAvatarUrl NOTIFY newCallParty) + Q_PROPERTY(bool isMicMuted READ isMicMuted NOTIFY micMuteChanged) + Q_PROPERTY(bool callsSupported READ callsSupported CONSTANT) public: CallManager(QObject *); @@ -28,21 +35,29 @@ public: void sendInvite(const QString &roomid, bool isVideo); void hangUp( mtx::events::msg::CallHangUp::Reason = mtx::events::msg::CallHangUp::Reason::User); - bool onActiveCall() const; + bool isOnCall() const { return session_.state() != webrtc::State::DISCONNECTED; } + bool isOnVideoCall() const { return session_.isVideo(); } + webrtc::State callState() const { return session_.state(); } QString callPartyName() const { return callPartyName_; } QString callPartyAvatarUrl() const { return callPartyAvatarUrl_; } + bool isMicMuted() const { return session_.isMicMuted(); } + bool callsSupported() const; void refreshTurnServer(); public slots: void syncEvent(const mtx::events::collections::TimelineEvents &event); + void toggleMicMute(); + void toggleCameraView() { session_.toggleCameraView(); } signals: void newMessage(const QString &roomid, const mtx::events::msg::CallInvite &); void newMessage(const QString &roomid, const mtx::events::msg::CallCandidates &); void newMessage(const QString &roomid, const mtx::events::msg::CallAnswer &); void newMessage(const QString &roomid, const mtx::events::msg::CallHangUp &); - void newCallParty(); + void newCallState(); void newVideoCallState(); + void newCallParty(); + void micMuteChanged(); void turnServerRetrieved(const mtx::responses::TurnServer &); private slots: diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index 5cbc33e0..2f50a7cc 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -597,7 +597,7 @@ void InputBar::callButton() { auto callManager_ = ChatPage::instance()->callManager(); - if (callManager_->onActiveCall()) { + if (callManager_->isOnCall()) { callManager_->hangUp(); } else { auto current_room_ = room->roomId(); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index f10c2c0d..97af0065 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -136,6 +136,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { return ChatPage::instance()->userSettings().data(); }); + qmlRegisterSingletonType( + "im.nheko", 1, 0, "CallManager", [](QQmlEngine *, QJSEngine *) -> QObject * { + return ChatPage::instance()->callManager(); + }); qRegisterMetaType(); qRegisterMetaType>(); @@ -237,36 +241,6 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par isInitialSync_ = true; emit initialSyncChanged(true); }); - connect(&WebRTCSession::instance(), - &WebRTCSession::stateChanged, - this, - &TimelineViewManager::callStateChanged); - connect( - callManager_, &CallManager::newCallParty, this, &TimelineViewManager::callPartyChanged); - connect(callManager_, - &CallManager::newVideoCallState, - this, - &TimelineViewManager::videoCallChanged); - - connect(&WebRTCSession::instance(), - &WebRTCSession::stateChanged, - this, - &TimelineViewManager::onCallChanged); -} - -bool -TimelineViewManager::isOnCall() const -{ - return callManager_->onActiveCall(); -} -bool -TimelineViewManager::callsSupported() const -{ -#ifdef GSTREAMER_AVAILABLE - return true; -#else - return false; -#endif } void @@ -354,19 +328,6 @@ TimelineViewManager::escapeEmoji(QString str) const return utils::replaceEmoji(str); } -void -TimelineViewManager::toggleMicMute() -{ - WebRTCSession::instance().toggleMicMute(); - emit micMuteChanged(); -} - -void -TimelineViewManager::toggleCameraView() -{ - WebRTCSession::instance().toggleCameraView(); -} - void TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const { diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 1cec0939..23a960b8 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -36,13 +36,6 @@ class TimelineViewManager : public QObject bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) Q_PROPERTY( bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged) - Q_PROPERTY(webrtc::State callState READ callState NOTIFY callStateChanged) - Q_PROPERTY(bool onVideoCall READ onVideoCall NOTIFY videoCallChanged) - Q_PROPERTY(QString callPartyName READ callPartyName NOTIFY callPartyChanged) - Q_PROPERTY(QString callPartyAvatarUrl READ callPartyAvatarUrl NOTIFY callPartyChanged) - Q_PROPERTY(bool isMicMuted READ isMicMuted NOTIFY micMuteChanged) - Q_PROPERTY(bool isOnCall READ isOnCall NOTIFY onCallChanged) - Q_PROPERTY(bool callsSupported READ callsSupported CONSTANT) public: TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr); @@ -61,14 +54,6 @@ public: Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } bool isNarrowView() const { return isNarrowView_; } - webrtc::State callState() const { return WebRTCSession::instance().state(); } - bool onVideoCall() const { return WebRTCSession::instance().isVideo(); } - Q_INVOKABLE void setVideoCallItem(); - QString callPartyName() const { return callManager_->callPartyName(); } - QString callPartyAvatarUrl() const { return callManager_->callPartyAvatarUrl(); } - bool isMicMuted() const { return WebRTCSession::instance().isMicMuted(); } - Q_INVOKABLE void toggleMicMute(); - Q_INVOKABLE void toggleCameraView(); Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const; Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QString escapeEmoji(QString str) const; @@ -98,11 +83,6 @@ signals: void inviteUsers(QStringList users); void showRoomList(); void narrowViewChanged(); - void callStateChanged(webrtc::State); - void videoCallChanged(); - void callPartyChanged(); - void micMuteChanged(); - void onCallChanged(); public slots: void updateReadReceipts(const QString &room_id, const std::vector &event_ids); @@ -130,8 +110,7 @@ public slots: void queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &); void updateEncryptedDescriptions(); - bool isOnCall() const; - bool callsSupported() const; + void setVideoCallItem(); void enableBackButton() {