Move call-related properties to CallManager

This commit is contained in:
trilene 2020-12-09 20:49:48 -05:00 committed by Nicolas Werner
parent 4e6df2edcb
commit ac410f46f2
8 changed files with 70 additions and 105 deletions

View File

@ -6,14 +6,14 @@ import im.nheko 1.0
Rectangle { Rectangle {
id: activeCallBar id: activeCallBar
visible: TimelineManager.callState != WebRTCState.DISCONNECTED visible: CallManager.isOnCall
color: "#2ECC71" color: "#2ECC71"
implicitHeight: visible ? rowLayout.height + 8 : 0 implicitHeight: visible ? rowLayout.height + 8 : 0
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
if (TimelineManager.onVideoCall) if (CallManager.isOnVideoCall)
stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1; stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1;
} }
@ -30,19 +30,19 @@ Rectangle {
Avatar { Avatar {
width: avatarSize width: avatarSize
height: avatarSize height: avatarSize
url: TimelineManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/")
displayName: TimelineManager.callPartyName displayName: CallManager.callPartyName
} }
Label { Label {
font.pointSize: fontMetrics.font.pointSize * 1.1 font.pointSize: fontMetrics.font.pointSize * 1.1
text: " " + TimelineManager.callPartyName + " " text: " " + CallManager.callPartyName + " "
} }
Image { Image {
Layout.preferredWidth: 24 Layout.preferredWidth: 24
Layout.preferredHeight: 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 { Label {
@ -52,11 +52,10 @@ Rectangle {
} }
Item { Item {
state: TimelineManager.callState
states: [ states: [
State { State {
name: "OFFERSENT" name: "OFFERSENT"
when: state == WebRTCState.OFFERSENT when: CallManager.callState == WebRTCState.OFFERSENT
PropertyChanges { PropertyChanges {
target: callStateLabel target: callStateLabel
@ -66,7 +65,7 @@ Rectangle {
}, },
State { State {
name: "CONNECTING" name: "CONNECTING"
when: state == WebRTCState.CONNECTING when: CallManager.callState == WebRTCState.CONNECTING
PropertyChanges { PropertyChanges {
target: callStateLabel target: callStateLabel
@ -76,7 +75,7 @@ Rectangle {
}, },
State { State {
name: "ANSWERSENT" name: "ANSWERSENT"
when: state == WebRTCState.ANSWERSENT when: CallManager.callState == WebRTCState.ANSWERSENT
PropertyChanges { PropertyChanges {
target: callStateLabel target: callStateLabel
@ -86,7 +85,7 @@ Rectangle {
}, },
State { State {
name: "CONNECTED" name: "CONNECTED"
when: state == WebRTCState.CONNECTED when: CallManager.callState == WebRTCState.CONNECTED
PropertyChanges { PropertyChanges {
target: callStateLabel target: callStateLabel
@ -100,13 +99,13 @@ Rectangle {
PropertyChanges { PropertyChanges {
target: stackLayout target: stackLayout
currentIndex: TimelineManager.onVideoCall ? 1 : 0 currentIndex: CallManager.isOnVideoCall ? 1 : 0
} }
}, },
State { State {
name: "DISCONNECTED" name: "DISCONNECTED"
when: state == WebRTCState.DISCONNECTED when: CallManager.callState == WebRTCState.DISCONNECTED
PropertyChanges { PropertyChanges {
target: callStateLabel target: callStateLabel
@ -132,7 +131,7 @@ Rectangle {
} }
interval: 1000 interval: 1000
running: TimelineManager.callState == WebRTCState.CONNECTED running: CallManager.callState == WebRTCState.CONNECTED
repeat: true repeat: true
onTriggered: { onTriggered: {
var d = new Date(); var d = new Date();
@ -149,7 +148,7 @@ Rectangle {
} }
ImageButton { ImageButton {
visible: TimelineManager.onVideoCall visible: CallManager.isOnVideoCall
width: 24 width: 24
height: 24 height: 24
buttonTextColor: "#000000" buttonTextColor: "#000000"
@ -157,7 +156,7 @@ Rectangle {
hoverEnabled: true hoverEnabled: true
ToolTip.visible: hovered ToolTip.visible: hovered
ToolTip.text: "Toggle camera view" ToolTip.text: "Toggle camera view"
onClicked: TimelineManager.toggleCameraView() onClicked: CallManager.toggleCameraView()
} }
Item { Item {
@ -168,11 +167,11 @@ Rectangle {
width: 24 width: 24
height: 24 height: 24
buttonTextColor: "#000000" 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 hoverEnabled: true
ToolTip.visible: hovered ToolTip.visible: hovered
ToolTip.text: TimelineManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic") ToolTip.text: CallManager.isMicMuted ? qsTr("Unmute Mic") : qsTr("Mute Mic")
onClicked: TimelineManager.toggleMicMute() onClicked: CallManager.toggleMicMute()
} }
Item { Item {

View File

@ -17,14 +17,14 @@ Rectangle {
spacing: 16 spacing: 16
ImageButton { ImageButton {
visible: TimelineManager.callsSupported visible: CallManager.callsSupported
Layout.alignment: Qt.AlignBottom Layout.alignment: Qt.AlignBottom
hoverEnabled: true hoverEnabled: true
width: 22 width: 22
height: 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.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.topMargin: 8
Layout.bottomMargin: 8 Layout.bottomMargin: 8
Layout.leftMargin: 16 Layout.leftMargin: 16
@ -39,7 +39,7 @@ Rectangle {
image: ":/icons/icons/ui/paper-clip-outline.png" image: ":/icons/icons/ui/paper-clip-outline.png"
Layout.topMargin: 8 Layout.topMargin: 8
Layout.bottomMargin: 8 Layout.bottomMargin: 8
Layout.leftMargin: TimelineManager.callsSupported ? 0 : 16 Layout.leftMargin: CallManager.callsSupported ? 0 : 16
onClicked: TimelineManager.timeline.input.openFileSelection() onClicked: TimelineManager.timeline.input.openFileSelection()
ToolTip.visible: hovered ToolTip.visible: hovered
ToolTip.text: qsTr("Send a file") ToolTip.text: qsTr("Send a file")

View File

@ -210,7 +210,7 @@ Page {
} }
Loader { Loader {
source: TimelineManager.onVideoCall ? "VideoCall.qml" : "" source: CallManager.isOnVideoCall ? "VideoCall.qml" : ""
onLoaded: TimelineManager.setVideoCallItem() onLoaded: TimelineManager.setVideoCallItem()
} }

View File

@ -13,7 +13,6 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "MatrixClient.h" #include "MatrixClient.h"
#include "Utils.h" #include "Utils.h"
#include "WebRTCSession.h"
#include "dialogs/AcceptCall.h" #include "dialogs/AcceptCall.h"
#include "mtx/responses/turn_server.hpp" #include "mtx/responses/turn_server.hpp"
@ -112,6 +111,7 @@ CallManager::CallManager(QObject *parent)
default: default:
break; break;
} }
emit newCallState();
}); });
connect(&player_, connect(&player_,
@ -144,7 +144,7 @@ CallManager::CallManager(QObject *parent)
void void
CallManager::sendInvite(const QString &roomid, bool isVideo) CallManager::sendInvite(const QString &roomid, bool isVideo)
{ {
if (onActiveCall()) if (isOnCall())
return; return;
auto roomInfo = cache::singleRoomInfo(roomid.toStdString()); 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 void
CallManager::syncEvent(const mtx::events::collections::TimelineEvents &event) CallManager::syncEvent(const mtx::events::collections::TimelineEvents &event)
{ {
@ -257,7 +251,7 @@ CallManager::handleEvent(const RoomEvent<CallInvite> &callInviteEvent)
return; return;
auto roomInfo = cache::singleRoomInfo(callInviteEvent.room_id); 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), emit newMessage(QString::fromStdString(callInviteEvent.room_id),
CallHangUp{callInviteEvent.content.call_id, CallHangUp{callInviteEvent.content.call_id,
0, 0,
@ -332,7 +326,7 @@ CallManager::handleEvent(const RoomEvent<CallCandidates> &callCandidatesEvent)
callCandidatesEvent.sender); callCandidatesEvent.sender);
if (callid_ == callCandidatesEvent.content.call_id) { if (callid_ == callCandidatesEvent.content.call_id) {
if (onActiveCall()) if (isOnCall())
session_.acceptICECandidates(callCandidatesEvent.content.candidates); session_.acceptICECandidates(callCandidatesEvent.content.candidates);
else { else {
// CallInvite has been received and we're awaiting localUser to accept or // CallInvite has been received and we're awaiting localUser to accept or
@ -350,7 +344,7 @@ CallManager::handleEvent(const RoomEvent<CallAnswer> &callAnswerEvent)
callAnswerEvent.content.call_id, callAnswerEvent.content.call_id,
callAnswerEvent.sender); callAnswerEvent.sender);
if (!onActiveCall() && callAnswerEvent.sender == utils::localUser().toStdString() && if (!isOnCall() && callAnswerEvent.sender == utils::localUser().toStdString() &&
callid_ == callAnswerEvent.content.call_id) { callid_ == callAnswerEvent.content.call_id) {
emit ChatPage::instance()->showNotification("Call answered on another device."); emit ChatPage::instance()->showNotification("Call answered on another device.");
stopRingtone(); stopRingtone();
@ -358,7 +352,7 @@ CallManager::handleEvent(const RoomEvent<CallAnswer> &callAnswerEvent)
return; return;
} }
if (onActiveCall() && callid_ == callAnswerEvent.content.call_id) { if (isOnCall() && callid_ == callAnswerEvent.content.call_id) {
stopRingtone(); stopRingtone();
if (!session_.acceptAnswer(callAnswerEvent.content.sdp)) { if (!session_.acceptAnswer(callAnswerEvent.content.sdp)) {
emit ChatPage::instance()->showNotification("Problem setting up call."); emit ChatPage::instance()->showNotification("Problem setting up call.");
@ -381,6 +375,23 @@ CallManager::handleEvent(const RoomEvent<CallHangUp> &callHangUpEvent)
} }
} }
void
CallManager::toggleMicMute()
{
session_.toggleMicMute();
emit micMuteChanged();
}
bool
CallManager::callsSupported() const
{
#ifdef GSTREAMER_AVAILABLE
return true;
#else
return false;
#endif
}
void void
CallManager::generateCallID() CallManager::generateCallID()
{ {

View File

@ -8,6 +8,7 @@
#include <QString> #include <QString>
#include <QTimer> #include <QTimer>
#include "WebRTCSession.h"
#include "mtx/events/collections.hpp" #include "mtx/events/collections.hpp"
#include "mtx/events/voip.hpp" #include "mtx/events/voip.hpp"
@ -16,11 +17,17 @@ struct TurnServer;
} }
class QUrl; class QUrl;
class WebRTCSession;
class CallManager : public QObject class CallManager : public QObject
{ {
Q_OBJECT 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: public:
CallManager(QObject *); CallManager(QObject *);
@ -28,21 +35,29 @@ public:
void sendInvite(const QString &roomid, bool isVideo); void sendInvite(const QString &roomid, bool isVideo);
void hangUp( void hangUp(
mtx::events::msg::CallHangUp::Reason = mtx::events::msg::CallHangUp::Reason::User); 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 callPartyName() const { return callPartyName_; }
QString callPartyAvatarUrl() const { return callPartyAvatarUrl_; } QString callPartyAvatarUrl() const { return callPartyAvatarUrl_; }
bool isMicMuted() const { return session_.isMicMuted(); }
bool callsSupported() const;
void refreshTurnServer(); void refreshTurnServer();
public slots: public slots:
void syncEvent(const mtx::events::collections::TimelineEvents &event); void syncEvent(const mtx::events::collections::TimelineEvents &event);
void toggleMicMute();
void toggleCameraView() { session_.toggleCameraView(); }
signals: signals:
void newMessage(const QString &roomid, const mtx::events::msg::CallInvite &); 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::CallCandidates &);
void newMessage(const QString &roomid, const mtx::events::msg::CallAnswer &); void newMessage(const QString &roomid, const mtx::events::msg::CallAnswer &);
void newMessage(const QString &roomid, const mtx::events::msg::CallHangUp &); void newMessage(const QString &roomid, const mtx::events::msg::CallHangUp &);
void newCallParty(); void newCallState();
void newVideoCallState(); void newVideoCallState();
void newCallParty();
void micMuteChanged();
void turnServerRetrieved(const mtx::responses::TurnServer &); void turnServerRetrieved(const mtx::responses::TurnServer &);
private slots: private slots:

View File

@ -597,7 +597,7 @@ void
InputBar::callButton() InputBar::callButton()
{ {
auto callManager_ = ChatPage::instance()->callManager(); auto callManager_ = ChatPage::instance()->callManager();
if (callManager_->onActiveCall()) { if (callManager_->isOnCall()) {
callManager_->hangUp(); callManager_->hangUp();
} else { } else {
auto current_room_ = room->roomId(); auto current_room_ = room->roomId();

View File

@ -136,6 +136,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
"im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * {
return ChatPage::instance()->userSettings().data(); return ChatPage::instance()->userSettings().data();
}); });
qmlRegisterSingletonType<CallManager>(
"im.nheko", 1, 0, "CallManager", [](QQmlEngine *, QJSEngine *) -> QObject * {
return ChatPage::instance()->callManager();
});
qRegisterMetaType<mtx::events::collections::TimelineEvents>(); qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qRegisterMetaType<std::vector<DeviceInfo>>(); qRegisterMetaType<std::vector<DeviceInfo>>();
@ -237,36 +241,6 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
isInitialSync_ = true; isInitialSync_ = true;
emit initialSyncChanged(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 void
@ -354,19 +328,6 @@ TimelineViewManager::escapeEmoji(QString str) const
return utils::replaceEmoji(str); return utils::replaceEmoji(str);
} }
void
TimelineViewManager::toggleMicMute()
{
WebRTCSession::instance().toggleMicMute();
emit micMuteChanged();
}
void
TimelineViewManager::toggleCameraView()
{
WebRTCSession::instance().toggleCameraView();
}
void void
TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId) const
{ {

View File

@ -36,13 +36,6 @@ class TimelineViewManager : public QObject
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
Q_PROPERTY( Q_PROPERTY(
bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged) 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: public:
TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr); TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
@ -61,14 +54,6 @@ public:
Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; }
Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
bool isNarrowView() const { return isNarrowView_; } 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 void openImageOverlay(QString mxcUrl, QString eventId) const;
Q_INVOKABLE QColor userColor(QString id, QColor background); Q_INVOKABLE QColor userColor(QString id, QColor background);
Q_INVOKABLE QString escapeEmoji(QString str) const; Q_INVOKABLE QString escapeEmoji(QString str) const;
@ -98,11 +83,6 @@ signals:
void inviteUsers(QStringList users); void inviteUsers(QStringList users);
void showRoomList(); void showRoomList();
void narrowViewChanged(); void narrowViewChanged();
void callStateChanged(webrtc::State);
void videoCallChanged();
void callPartyChanged();
void micMuteChanged();
void onCallChanged();
public slots: public slots:
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids); void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
@ -130,8 +110,7 @@ public slots:
void queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &);
void updateEncryptedDescriptions(); void updateEncryptedDescriptions();
bool isOnCall() const; void setVideoCallItem();
bool callsSupported() const;
void enableBackButton() void enableBackButton()
{ {