Commit 2402bb2f authored by Ronan Abhamon's avatar Ronan Abhamon

feat(ui/views/App/Calls/Incall): supports set/unset video in call

parent 38b629fa
...@@ -363,6 +363,14 @@ Server url not configured.</translation> ...@@ -363,6 +363,14 @@ Server url not configured.</translation>
<source>saveScreenshotTitle</source> <source>saveScreenshotTitle</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>acceptVideoDescription</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>acceptVideoTitle</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
......
...@@ -351,6 +351,14 @@ Url du serveur non configurée.</translation> ...@@ -351,6 +351,14 @@ Url du serveur non configurée.</translation>
<source>saveScreenshotTitle</source> <source>saveScreenshotTitle</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>acceptVideoDescription</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>acceptVideoTitle</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>IncomingCall</name> <name>IncomingCall</name>
......
...@@ -36,6 +36,20 @@ CallModel::CallModel (shared_ptr<linphone::Call> linphone_call) { ...@@ -36,6 +36,20 @@ CallModel::CallModel (shared_ptr<linphone::Call> linphone_call) {
m_paused_by_user = false; m_paused_by_user = false;
break; break;
case linphone::CallStateUpdatedByRemote: {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
if (
!m_linphone_call->getCurrentParams()->videoEnabled() &&
m_linphone_call->getRemoteParams()->videoEnabled()
) {
CoreManager::getInstance()->getCore()->deferCallUpdate(m_linphone_call);
emit videoRequested();
}
}
break;
default: default:
break; break;
} }
...@@ -63,6 +77,16 @@ void CallModel::transfer () { ...@@ -63,6 +77,16 @@ void CallModel::transfer () {
// TODO // TODO
} }
void CallModel::acceptVideoRequest () {
shared_ptr<linphone::CallParams> params = m_linphone_call->getCurrentParams()->copy();
params->enableVideo(true);
CoreManager::getInstance()->getCore()->acceptCallUpdate(m_linphone_call, params);
}
void CallModel::rejectVideoRequest () {
CoreManager::getInstance()->getCore()->acceptCallUpdate(m_linphone_call, m_linphone_call->getCurrentParams());
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
QString CallModel::getSipAddress () const { QString CallModel::getSipAddress () const {
...@@ -135,6 +159,15 @@ bool CallModel::getPausedByUser () const { ...@@ -135,6 +159,15 @@ bool CallModel::getPausedByUser () const {
} }
void CallModel::setPausedByUser (bool status) { void CallModel::setPausedByUser (bool status) {
switch (m_linphone_call->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
break;
default: return;
}
if (status) { if (status) {
if (!m_paused_by_user) if (!m_paused_by_user)
CoreManager::getInstance()->getCore()->pauseCall(m_linphone_call); CoreManager::getInstance()->getCore()->pauseCall(m_linphone_call);
...@@ -146,20 +179,24 @@ void CallModel::setPausedByUser (bool status) { ...@@ -146,20 +179,24 @@ void CallModel::setPausedByUser (bool status) {
CoreManager::getInstance()->getCore()->resumeCall(m_linphone_call); CoreManager::getInstance()->getCore()->resumeCall(m_linphone_call);
} }
bool CallModel::getVideoInputEnabled () const { bool CallModel::getVideoEnabled () const {
shared_ptr<linphone::CallParams> params = m_linphone_call->getRemoteParams(); shared_ptr<linphone::CallParams> params = m_linphone_call->getCurrentParams();
return params && params->videoEnabled() && getStatus() == CallStatusConnected; return params && params->videoEnabled() && getStatus() == CallStatusConnected;
} }
void CallModel::setVideoInputEnabled (bool status) { void CallModel::setVideoEnabled (bool status) {
// TODO switch (m_linphone_call->getState()) {
} case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
break;
default: return;
}
bool CallModel::getVideoOutputEnabled () const { if (status == getVideoEnabled())
shared_ptr<linphone::CallParams> params = m_linphone_call->getCurrentParams(); return;
return params && params->videoEnabled() && getStatus() == CallStatusConnected;
}
void CallModel::setVideoOutputEnabled (bool status) { shared_ptr<linphone::CallParams> params = CoreManager::getInstance()->getCore()->createCallParams(m_linphone_call);
// TODO params->enableVideo(status);
CoreManager::getInstance()->getCore()->updateCall(m_linphone_call, params);
} }
...@@ -16,8 +16,7 @@ class CallModel : public QObject { ...@@ -16,8 +16,7 @@ class CallModel : public QObject {
Q_PROPERTY(float quality READ getQuality CONSTANT); // Same idea. Q_PROPERTY(float quality READ getQuality CONSTANT); // Same idea.
Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged); Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged);
Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged); Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged);
Q_PROPERTY(bool videoInputEnabled READ getVideoInputEnabled WRITE setVideoInputEnabled NOTIFY statusChanged); Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged);
Q_PROPERTY(bool videoOutputEnabled READ getVideoOutputEnabled WRITE setVideoOutputEnabled NOTIFY statusChanged);
public: public:
enum CallStatus { enum CallStatus {
...@@ -43,9 +42,13 @@ public: ...@@ -43,9 +42,13 @@ public:
Q_INVOKABLE void terminate (); Q_INVOKABLE void terminate ();
Q_INVOKABLE void transfer (); Q_INVOKABLE void transfer ();
Q_INVOKABLE void acceptVideoRequest ();
Q_INVOKABLE void rejectVideoRequest ();
signals: signals:
void statusChanged (CallStatus status); void statusChanged (CallStatus status);
void microMutedChanged (bool status); void microMutedChanged (bool status);
void videoRequested ();
private: private:
QString getSipAddress () const; QString getSipAddress () const;
...@@ -64,11 +67,8 @@ private: ...@@ -64,11 +67,8 @@ private:
bool getPausedByUser () const; bool getPausedByUser () const;
void setPausedByUser (bool status); void setPausedByUser (bool status);
bool getVideoInputEnabled () const; bool getVideoEnabled () const;
void setVideoInputEnabled (bool status); void setVideoEnabled (bool status);
bool getVideoOutputEnabled () const;
void setVideoOutputEnabled (bool status);
bool m_micro_muted = false; bool m_micro_muted = false;
bool m_paused_by_remote = false; bool m_paused_by_remote = false;
......
...@@ -10,6 +10,8 @@ import App.Styles 1.0 ...@@ -10,6 +10,8 @@ import App.Styles 1.0
// ============================================================================= // =============================================================================
Rectangle { Rectangle {
property var call
default property alias _actionArea: actionArea.data default property alias _actionArea: actionArea.data
property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress) property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
......
...@@ -15,11 +15,10 @@ Window { ...@@ -15,11 +15,10 @@ Window {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
property var call: calls.selectedCall
readonly property bool chatIsOpened: !rightPaned.isClosed() readonly property bool chatIsOpened: !rightPaned.isClosed()
// `{}` is a workaround to avoid `TypeError: Cannot read property...` in `Incall` component. property string sipAddress: call ? call.sipAddress : ''
property var call: calls.selectedCall || {}
property string sipAddress: call.sipAddress || ''
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -122,19 +121,28 @@ Window { ...@@ -122,19 +121,28 @@ Window {
Component { Component {
id: incomingCall id: incomingCall
IncomingCall {} IncomingCall {
call: window.call
}
} }
Component { Component {
id: outgoingCall id: outgoingCall
OutgoingCall {} OutgoingCall {
call: window.call
}
} }
Component { Component {
id: incall id: incall
Incall {} Incall {
// `{}` is a workaround to avoid `TypeError: Cannot read property...` in `Incall` component.
call: window.call || ({
videoEnabled: false
})
}
} }
Component { Component {
...@@ -151,7 +159,12 @@ Window { ...@@ -151,7 +159,12 @@ Window {
childA: Loader { childA: Loader {
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if (!window.call) {
return null
}
var status = window.call.status var status = window.call.status
if (status == null) { if (status == null) {
return null return null
......
...@@ -17,13 +17,36 @@ Rectangle { ...@@ -17,13 +17,36 @@ Rectangle {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
property var call
property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress) property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
property var _call: call
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
color: CallStyle.backgroundColor color: CallStyle.backgroundColor
// ---------------------------------------------------------------------------
// Handle video requests.
// ---------------------------------------------------------------------------
SmartConnect {
Component.onCompleted: this.connect(call, 'videoRequested', function () {
Utils.openConfirmDialog(window, {
descriptionText: qsTr('acceptVideoDescription'),
exitHandler: function (status) {
if (status) {
call.acceptVideoRequest()
} else {
call.rejectVideoRequest()
}
},
title: qsTr('acceptVideoTitle')
})
})
}
// ---------------------------------------------------------------------------
ColumnLayout { ColumnLayout {
anchors { anchors {
fill: parent fill: parent
...@@ -85,7 +108,7 @@ Rectangle { ...@@ -85,7 +108,7 @@ Rectangle {
id: cameraActions id: cameraActions
anchors.right: parent.right anchors.right: parent.right
active: Boolean(call.videoInputEnabled) && call.status !== CallModel.CallStatusEnded active: call.videoEnabled && call.status !== CallModel.CallStatusEnded
sourceComponent: ActionBar { sourceComponent: ActionBar {
iconSize: CallStyle.header.iconSize iconSize: CallStyle.header.iconSize
...@@ -200,7 +223,7 @@ Rectangle { ...@@ -200,7 +223,7 @@ Rectangle {
Camera { Camera {
height: container.height height: container.height
width: container.width width: container.width
call: incall._call call: incall.call
} }
} }
...@@ -208,7 +231,7 @@ Rectangle { ...@@ -208,7 +231,7 @@ Rectangle {
id: cameraLoader id: cameraLoader
anchors.centerIn: parent anchors.centerIn: parent
sourceComponent: call.videoInputEnabled ? camera : avatar sourceComponent: call.videoEnabled ? camera : avatar
} }
} }
...@@ -241,15 +264,11 @@ Rectangle { ...@@ -241,15 +264,11 @@ Rectangle {
} }
ActionSwitch { ActionSwitch {
icon: 'speaker' enabled: call.videoEnabled
iconSize: CallStyle.actionArea.iconSize
onClicked: enabled = !enabled
}
ActionSwitch {
icon: 'camera' icon: 'camera'
iconSize: CallStyle.actionArea.iconSize iconSize: CallStyle.actionArea.iconSize
onClicked: enabled = !enabled
onClicked: call.videoEnabled = !enabled
} }
ActionButton { ActionButton {
...@@ -266,9 +285,9 @@ Rectangle { ...@@ -266,9 +285,9 @@ Rectangle {
width: CallStyle.actionArea.userVideo.width width: CallStyle.actionArea.userVideo.width
isPreview: true isPreview: true
visible: incall.width >= CallStyle.actionArea.lowWidth && call.videoEnabled
call: incall._call Component.onCompleted: call = incall.call
visible: Boolean(incall.width >= CallStyle.actionArea.lowWidth && call.videoOutputEnabled)
} }
ActionBar { ActionBar {
......
...@@ -10,7 +10,7 @@ import App.Styles 1.0 ...@@ -10,7 +10,7 @@ import App.Styles 1.0
AbstractStartingCall { AbstractStartingCall {
GridLayout { GridLayout {
columns: parent.width < CallStyle.actionArea.lowWidth && call.videoOutputEnabled ? 1 : 2 columns: parent.width < CallStyle.actionArea.lowWidth && call.videoEnabled ? 1 : 2
rowSpacing: ActionBarStyle.spacing rowSpacing: ActionBarStyle.spacing
anchors { anchors {
...@@ -26,13 +26,6 @@ AbstractStartingCall { ...@@ -26,13 +26,6 @@ AbstractStartingCall {
onClicked: call.microMuted = enabled onClicked: call.microMuted = enabled
} }
ActionSwitch {
icon: 'speaker'
iconSize: CallStyle.actionArea.iconSize
onClicked: enabled = !enabled
}
} }
Item { Item {
...@@ -40,7 +33,7 @@ AbstractStartingCall { ...@@ -40,7 +33,7 @@ AbstractStartingCall {
height: CallStyle.actionArea.userVideo.height height: CallStyle.actionArea.userVideo.height
width: CallStyle.actionArea.userVideo.width width: CallStyle.actionArea.userVideo.width
visible: call.videoOutputEnabled visible: call.videoEnabled
} }
ActionBar { ActionBar {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment