mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-29 17:59:21 +00:00
feat(ui/views/App/Calls/ConferenceManager): in progress
This commit is contained in:
parent
ce03c3f1d8
commit
13e4822e2c
7 changed files with 331 additions and 9 deletions
|
|
@ -357,6 +357,17 @@ Server url not configured.</translation>
|
|||
<translation>Status</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Conference</name>
|
||||
<message>
|
||||
<source>conferenceTitle</source>
|
||||
<translation>CONFERENCE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>pendingRequestLabel</source>
|
||||
<translation>Please to wait, a request is pending.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConferenceManager</name>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -357,6 +357,17 @@ Url du serveur non configurée.</translation>
|
|||
<translation>Status</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Conference</name>
|
||||
<message>
|
||||
<source>conferenceTitle</source>
|
||||
<translation>CONFÉRENCE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>pendingRequestLabel</source>
|
||||
<translation>Merci de patienter, une requête est en attente.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConferenceManager</name>
|
||||
<message>
|
||||
|
|
|
|||
|
|
@ -355,6 +355,7 @@
|
|||
<file>ui/views/App/Calls/CallsWindow.js</file>
|
||||
<file>ui/views/App/Calls/CallsWindow.qml</file>
|
||||
<file>ui/views/App/Calls/ConferenceManager.qml</file>
|
||||
<file>ui/views/App/Calls/Conference.qml</file>
|
||||
<file>ui/views/App/Calls/EndedCall.qml</file>
|
||||
<file>ui/views/App/Calls/IncallFullscreenWindow.qml</file>
|
||||
<file>ui/views/App/Calls/Incall.js</file>
|
||||
|
|
|
|||
|
|
@ -79,9 +79,10 @@ QString CallModel::getSipAddress () const {
|
|||
void CallModel::setRecordFile (shared_ptr<linphone::CallParams> &callParams) {
|
||||
callParams->setRecordFile(
|
||||
::Utils::qStringToLinphoneString(
|
||||
CoreManager::getInstance()->getSettingsModel()->getSavedVideosFolder() +
|
||||
QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss")
|
||||
) + ".mkv"
|
||||
QStringLiteral("%1%2.mkv")
|
||||
.arg(CoreManager::getInstance()->getSettingsModel()->getSavedVideosFolder())
|
||||
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss"))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -183,14 +184,15 @@ void CallModel::startRecording () {
|
|||
}
|
||||
|
||||
void CallModel::stopRecording () {
|
||||
if (mRecording) {
|
||||
qInfo() << QStringLiteral("Stop recording call:") << this;
|
||||
if (!mRecording)
|
||||
return;
|
||||
|
||||
mRecording = false;
|
||||
mCall->stopRecording();
|
||||
qInfo() << QStringLiteral("Stop recording call:") << this;
|
||||
|
||||
emit recordingChanged(false);
|
||||
}
|
||||
mRecording = false;
|
||||
mCall->stopRecording();
|
||||
|
||||
emit recordingChanged(false);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -20,8 +20,15 @@
|
|||
* Author: Ronan Abhamon
|
||||
*/
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include "../../Utils.hpp"
|
||||
#include "../core/CoreManager.hpp"
|
||||
|
||||
#include "ConferenceModel.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ConferenceModel::ConferenceModel (QObject *parent) : QAbstractListModel(parent) {}
|
||||
|
|
@ -47,3 +54,57 @@ QVariant ConferenceModel::data (const QModelIndex &index, int role) const {
|
|||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ConferenceModel::startRecording () {
|
||||
if (mRecording)
|
||||
return;
|
||||
|
||||
qInfo() << QStringLiteral("Start recording conference:") << this;
|
||||
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
coreManager->getCore()->startConferenceRecording(
|
||||
::Utils::qStringToLinphoneString(
|
||||
QStringLiteral("%1%2.mkv")
|
||||
.arg(coreManager->getSettingsModel()->getSavedVideosFolder())
|
||||
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh:mm:ss"))
|
||||
)
|
||||
);
|
||||
mRecording = true;
|
||||
|
||||
emit recordingChanged(true);
|
||||
}
|
||||
|
||||
void ConferenceModel::stopRecording () {
|
||||
if (!mRecording)
|
||||
return;
|
||||
|
||||
qInfo() << QStringLiteral("Stop recording conference:") << this;
|
||||
|
||||
mRecording = false;
|
||||
CoreManager::getInstance()->getCore()->stopConferenceRecording();
|
||||
|
||||
emit recordingChanged(false);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ConferenceModel::getMicroMuted () const {
|
||||
return !CoreManager::getInstance()->getCore()->micEnabled();
|
||||
}
|
||||
|
||||
void ConferenceModel::setMicroMuted (bool status) {
|
||||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
|
||||
if (status == core->micEnabled()) {
|
||||
core->enableMic(!status);
|
||||
emit microMutedChanged(status);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ConferenceModel::getRecording () const {
|
||||
return mRecording;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@
|
|||
// =============================================================================
|
||||
|
||||
class ConferenceModel : public QAbstractListModel {
|
||||
Q_OBJECT;
|
||||
|
||||
Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged);
|
||||
|
||||
Q_PROPERTY(bool recording READ getRecording NOTIFY recordingChanged);
|
||||
|
||||
public:
|
||||
ConferenceModel (QObject *parent = Q_NULLPTR);
|
||||
~ConferenceModel () = default;
|
||||
|
|
@ -37,7 +43,21 @@ public:
|
|||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Q_INVOKABLE void startRecording ();
|
||||
Q_INVOKABLE void stopRecording ();
|
||||
|
||||
signals:
|
||||
void microMutedChanged (bool status);
|
||||
void recordingChanged (bool status);
|
||||
|
||||
private:
|
||||
bool getMicroMuted () const;
|
||||
void setMicroMuted (bool status);
|
||||
|
||||
bool getRecording () const;
|
||||
|
||||
bool mRecording = false;
|
||||
|
||||
QStringList mSipAddresses;
|
||||
};
|
||||
|
||||
|
|
|
|||
216
linphone-desktop/ui/views/App/Calls/Conference.qml
Normal file
216
linphone-desktop/ui/views/App/Calls/Conference.qml
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
import LinphoneUtils 1.0
|
||||
import Utils 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
//import 'Conference.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Rectangle {
|
||||
property var call: null // TODO: Remove me
|
||||
|
||||
color: CallStyle.backgroundColor
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
ConferenceModel {
|
||||
id: conference
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: CallStyle.header.topMargin
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Call info.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Item {
|
||||
id: info
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: CallStyle.header.leftMargin
|
||||
Layout.rightMargin: CallStyle.header.rightMargin
|
||||
Layout.preferredHeight: CallStyle.header.conferenceDescription.height
|
||||
|
||||
ActionBar {
|
||||
id: leftActions
|
||||
|
||||
anchors.left: parent.left
|
||||
iconSize: CallStyle.header.iconSize
|
||||
}
|
||||
|
||||
Text {
|
||||
id: conferenceDescription
|
||||
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr('conferenceTitle')
|
||||
|
||||
height: parent.height
|
||||
width: parent.width - rightActions.width - leftActions.width - CallStyle.header.conferenceDescription.width
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Video actions.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
ActionBar {
|
||||
id: rightActions
|
||||
|
||||
anchors.right: parent.right
|
||||
iconSize: CallStyle.header.iconSize
|
||||
|
||||
ActionSwitch {
|
||||
enabled: conference.recording
|
||||
icon: 'record'
|
||||
useStates: false
|
||||
|
||||
onClicked: !enabled
|
||||
? conference.startRecording()
|
||||
: conference.stopRecording()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: elapsedTime
|
||||
|
||||
Layout.fillWidth: true
|
||||
color: CallStyle.header.elapsedTime.color
|
||||
font.pointSize: CallStyle.header.elapsedTime.fontSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
repeat: true
|
||||
running: true
|
||||
triggeredOnStart: true
|
||||
|
||||
onTriggered: elapsedTime.text = Utils.formatElapsedTime(conference.duration)
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Contacts visual.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Item {
|
||||
id: container
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: CallStyle.container.margins
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Action Buttons.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: CallStyle.actionArea.height
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: CallStyle.actionArea.leftButtonsGroupMargin
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
spacing: ActionBarStyle.spacing
|
||||
|
||||
Row {
|
||||
spacing: CallStyle.actionArea.vu.spacing
|
||||
|
||||
VuMeter {
|
||||
Timer {
|
||||
interval: 50
|
||||
repeat: true
|
||||
running: micro.enabled
|
||||
|
||||
onTriggered: parent.value = conference.microVu
|
||||
}
|
||||
|
||||
enabled: micro.enabled
|
||||
}
|
||||
|
||||
ActionSwitch {
|
||||
id: micro
|
||||
|
||||
enabled: !conference.microMuted
|
||||
icon: 'micro'
|
||||
iconSize: CallStyle.actionArea.iconSize
|
||||
|
||||
onClicked: conference.microMuted = enabled
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: CallStyle.actionArea.vu.spacing
|
||||
|
||||
VuMeter {
|
||||
Timer {
|
||||
interval: 50
|
||||
repeat: true
|
||||
running: speaker.enabled
|
||||
|
||||
onTriggered: parent.value = conference.speakerVu
|
||||
}
|
||||
|
||||
enabled: speaker.enabled
|
||||
}
|
||||
|
||||
ActionSwitch {
|
||||
id: speaker
|
||||
|
||||
enabled: true
|
||||
icon: 'speaker'
|
||||
iconSize: CallStyle.actionArea.iconSize
|
||||
|
||||
onClicked: console.log('TODO')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionBar {
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: CallStyle.actionArea.rightButtonsGroupMargin
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
iconSize: CallStyle.actionArea.iconSize
|
||||
|
||||
ActionSwitch {
|
||||
enabled: !conference.pausedByUser
|
||||
icon: 'pause'
|
||||
updating: conference.updating
|
||||
|
||||
onClicked: conference.pausedByUser = enabled
|
||||
|
||||
TooltipArea {
|
||||
text: qsTr('pendingRequestLabel')
|
||||
visible: parent.updating
|
||||
}
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon: 'hangup'
|
||||
|
||||
onClicked: conference.terminate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue