in call ui fixes + custom app window for information popups
This commit is contained in:
parent
eb5b3b5141
commit
62cad4b214
15 changed files with 278 additions and 199 deletions
|
|
@ -58,6 +58,18 @@ void ConferenceCore::setSelf(QSharedPointer<ConferenceCore> me) {
|
||||||
auto device = ParticipantDeviceCore::create(participantDevice);
|
auto device = ParticipantDeviceCore::create(participantDevice);
|
||||||
mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); });
|
mConferenceModelConnection->invokeToCore([this, device]() { setActiveSpeaker(device); });
|
||||||
});
|
});
|
||||||
|
mConferenceModelConnection->makeConnectToModel(
|
||||||
|
&ConferenceModel::participantDeviceAdded,
|
||||||
|
[this](const std::shared_ptr<linphone::ParticipantDevice> &participantDevice) {
|
||||||
|
int count = mConferenceModel->getParticipantDeviceCount();
|
||||||
|
mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); });
|
||||||
|
});
|
||||||
|
mConferenceModelConnection->makeConnectToModel(
|
||||||
|
&ConferenceModel::participantDeviceRemoved,
|
||||||
|
[this](const std::shared_ptr<const linphone::ParticipantDevice> &participantDevice) {
|
||||||
|
int count = mConferenceModel->getParticipantDeviceCount();
|
||||||
|
mConferenceModelConnection->invokeToCore([this, count]() { setParticipantDeviceCount(count); });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConferenceCore::updateLocalParticipant() { // true if changed
|
bool ConferenceCore::updateLocalParticipant() { // true if changed
|
||||||
|
|
@ -75,15 +87,22 @@ Q_INVOKABLE qint64 ConferenceCore::getElapsedSeconds() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConferenceCore::setParticipantDeviceCount(int count) {
|
||||||
|
if (mParticipantDeviceCount != count) {
|
||||||
|
mParticipantDeviceCount = count;
|
||||||
|
emit participantDeviceCountChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ConferenceCore::getParticipantDeviceCount() const {
|
int ConferenceCore::getParticipantDeviceCount() const {
|
||||||
return mParticipantDeviceCount + 1;
|
return mParticipantDeviceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConferenceCore::setIsReady(bool state) {
|
void ConferenceCore::setIsReady(bool state) {
|
||||||
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
mustBeInMainThread(log().arg(Q_FUNC_INFO));
|
||||||
if (mIsReady != state) {
|
if (mIsReady != state) {
|
||||||
mIsReady = state;
|
mIsReady = state;
|
||||||
isReadyChanged();
|
emit isReadyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ public:
|
||||||
QDateTime getStartDate() const;
|
QDateTime getStartDate() const;
|
||||||
Q_INVOKABLE qint64 getElapsedSeconds() const;
|
Q_INVOKABLE qint64 getElapsedSeconds() const;
|
||||||
int getParticipantDeviceCount() const;
|
int getParticipantDeviceCount() const;
|
||||||
|
void setParticipantDeviceCount(int count);
|
||||||
|
|
||||||
ParticipantDeviceCore *getActiveSpeaker() const;
|
ParticipantDeviceCore *getActiveSpeaker() const;
|
||||||
ParticipantDeviceGui *getActiveSpeakerGui() const;
|
ParticipantDeviceGui *getActiveSpeakerGui() const;
|
||||||
ParticipantGui *getMeGui() const;
|
ParticipantGui *getMeGui() const;
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,7 @@ void CallModel::updateConferenceVideoLayout() {
|
||||||
// auto settings = CoreManager::getInstance()->getSettingsModel();
|
// auto settings = CoreManager::getInstance()->getSettingsModel();
|
||||||
auto newLayout = LinphoneEnums::fromLinphone(callParams->getConferenceVideoLayout());
|
auto newLayout = LinphoneEnums::fromLinphone(callParams->getConferenceVideoLayout());
|
||||||
if (!callParams->videoEnabled()) newLayout = LinphoneEnums::ConferenceLayout::AudioOnly;
|
if (!callParams->videoEnabled()) newLayout = LinphoneEnums::ConferenceLayout::AudioOnly;
|
||||||
|
if (!mConference) newLayout = LinphoneEnums::ConferenceLayout::ActiveSpeaker;
|
||||||
if (mConferenceVideoLayout != newLayout) { // && !getPausedByUser()) { // Only update if not in pause.
|
if (mConferenceVideoLayout != newLayout) { // && !getPausedByUser()) { // Only update if not in pause.
|
||||||
// if (mMonitor->getConference()) {
|
// if (mMonitor->getConference()) {
|
||||||
// if (callParams->getConferenceVideoLayout() == linphone::Conference::Layout::Grid)
|
// if (callParams->getConferenceVideoLayout() == linphone::Conference::Layout::Grid)
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,11 @@ void ConferenceModel::addParticipant(const std::shared_ptr<linphone::Address> &a
|
||||||
mMonitor->addParticipant(address);
|
mMonitor->addParticipant(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ConferenceModel::getParticipantDeviceCount() const {
|
||||||
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
|
return mMonitor->getParticipantDeviceList().size();
|
||||||
|
}
|
||||||
|
|
||||||
void ConferenceModel::setMicrophoneMuted(bool isMuted) {
|
void ConferenceModel::setMicrophoneMuted(bool isMuted) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
mMonitor->setMicrophoneMuted(isMuted);
|
mMonitor->setMicrophoneMuted(isMuted);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ public:
|
||||||
void removeParticipant(const std::shared_ptr<linphone::Address> &address);
|
void removeParticipant(const std::shared_ptr<linphone::Address> &address);
|
||||||
void addParticipant(const std::shared_ptr<linphone::Address> &address);
|
void addParticipant(const std::shared_ptr<linphone::Address> &address);
|
||||||
|
|
||||||
|
int getParticipantDeviceCount() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void microphoneMutedChanged(bool isMuted);
|
void microphoneMutedChanged(bool isMuted);
|
||||||
void speakerMutedChanged(bool isMuted);
|
void speakerMutedChanged(bool isMuted);
|
||||||
|
|
|
||||||
60
Linphone/view/App/AppWindow.qml
Normal file
60
Linphone/view/App/AppWindow.qml
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp 1.0
|
||||||
|
import SettingsCpp 1.0
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: mainWindow
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: popupComp
|
||||||
|
InformationPopup{}
|
||||||
|
}
|
||||||
|
function removeFromPopupLayout(index) {
|
||||||
|
popupLayout.popupList.splice(index, 1)
|
||||||
|
}
|
||||||
|
function showInformationPopup(title, description, isSuccess) {
|
||||||
|
var infoPopup = popupComp.createObject(popupLayout, {"title": title, "description": description, "isSuccess": isSuccess})
|
||||||
|
infoPopup.index = popupLayout.popupList.length
|
||||||
|
popupLayout.popupList.push(infoPopup)
|
||||||
|
infoPopup.open()
|
||||||
|
infoPopup.closePopup.connect(removeFromPopupLayout)
|
||||||
|
}
|
||||||
|
function showLoadingPopup(text) {
|
||||||
|
loadingPopup.text = text
|
||||||
|
loadingPopup.open()
|
||||||
|
}
|
||||||
|
function closeLoadingPopup() {
|
||||||
|
loadingPopup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: popupLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
Layout.alignment: Qt.AlignBottom
|
||||||
|
property int nextY: mainWindow.height
|
||||||
|
property list<InformationPopup> popupList
|
||||||
|
property int popupCount: popupList.length
|
||||||
|
spacing: 15 * DefaultStyle.dp
|
||||||
|
onPopupCountChanged: {
|
||||||
|
nextY = mainWindow.height
|
||||||
|
for(var i = 0; i < popupCount; ++i) {
|
||||||
|
popupList[i].y = nextY - popupList[i].height
|
||||||
|
popupList[i].index = i
|
||||||
|
nextY = nextY - popupList[i].height - 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadingPopup {
|
||||||
|
id: loadingPopup
|
||||||
|
modal: true
|
||||||
|
closePolicy: Popup.NoAutoClose
|
||||||
|
anchors.centerIn: parent
|
||||||
|
padding: 20 * DefaultStyle.dp
|
||||||
|
underlineColor: DefaultStyle.main1_500_main
|
||||||
|
radius: 15 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ import EnumsToStringCpp 1.0
|
||||||
import UtilsCpp 1.0
|
import UtilsCpp 1.0
|
||||||
import SettingsCpp 1.0
|
import SettingsCpp 1.0
|
||||||
|
|
||||||
Window {
|
AppWindow {
|
||||||
id: mainWindow
|
id: mainWindow
|
||||||
width: 1512 * DefaultStyle.dp
|
width: 1512 * DefaultStyle.dp
|
||||||
height: 982 * DefaultStyle.dp
|
height: 982 * DefaultStyle.dp
|
||||||
|
|
@ -38,33 +38,9 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
function shareInvitation() {
|
||||||
id: popupComp
|
UtilsCpp.copyToClipboard(conference.core.uri)
|
||||||
InformationPopup{}
|
showInformationPopup(qsTr("Copié"), qsTr("Le lien de la réunion a été copié dans le presse-papier"), true)
|
||||||
}
|
|
||||||
|
|
||||||
function showInformationPopup(title, description, isSuccess) {
|
|
||||||
var infoPopup = popupComp.createObject(popupLayout, {"title": title, "description": description, "isSuccess": isSuccess})
|
|
||||||
infoPopup.index = popupLayout.popupList.length
|
|
||||||
popupLayout.popupList.push(infoPopup)
|
|
||||||
infoPopup.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: popupLayout
|
|
||||||
anchors.fill: parent
|
|
||||||
Layout.alignment: Qt.AlignBottom
|
|
||||||
property int nextY: mainWindow.height
|
|
||||||
property list<Popup> popupList
|
|
||||||
property int popupCount: popupList.length
|
|
||||||
spacing: 15 * DefaultStyle.dp
|
|
||||||
onPopupCountChanged: {
|
|
||||||
nextY = mainWindow.height
|
|
||||||
for(var i = 0; i < popupCount; ++i) {
|
|
||||||
popupList[i].y = nextY - popupList[i].height
|
|
||||||
nextY = nextY - popupList[i].height - 15 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeLayout(layoutIndex) {
|
function changeLayout(layoutIndex) {
|
||||||
|
|
@ -141,10 +117,13 @@ Window {
|
||||||
function endCall(callToFinish) {
|
function endCall(callToFinish) {
|
||||||
if (callToFinish) callToFinish.core.lTerminate()
|
if (callToFinish) callToFinish.core.lTerminate()
|
||||||
}
|
}
|
||||||
function callEnded(){
|
function callEnded(call){
|
||||||
if (!callsModel.haveCall) {
|
if (!callsModel.haveCall) {
|
||||||
bottomButtonsLayout.setButtonsEnabled(false)
|
if (call.core.conference) UtilsCpp.closeCallsWindow()
|
||||||
autoCloseWindow.restart()
|
else {
|
||||||
|
bottomButtonsLayout.setButtonsEnabled(false)
|
||||||
|
autoCloseWindow.restart()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mainWindow.call = callsModel.currentCall
|
mainWindow.call = callsModel.currentCall
|
||||||
}
|
}
|
||||||
|
|
@ -707,8 +686,7 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
UtilsCpp.copyToClipboard(mainWindow.conference.core.uri)
|
mainItem.shareInvitation()
|
||||||
UtilsCpp.showInformationPopup(qsTr("Copié"), qsTr("Le lien de la réunion a été copié dans le presse-papier"), true, mainWindow)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -741,6 +719,8 @@ Window {
|
||||||
id: addParticipantComp
|
id: addParticipantComp
|
||||||
AddParticipantsLayout {
|
AddParticipantsLayout {
|
||||||
id: addParticipantLayout
|
id: addParticipantLayout
|
||||||
|
searchBarColor: DefaultStyle.grey_0
|
||||||
|
searchBarBorderColor: DefaultStyle.grey_200
|
||||||
onSelectedParticipantsCountChanged: {
|
onSelectedParticipantsCountChanged: {
|
||||||
if (participantsStack.Control.StackView.status === Control.StackView.Active && Control.StackView.visible) {
|
if (participantsStack.Control.StackView.status === Control.StackView.Active && Control.StackView.visible) {
|
||||||
rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné").arg(selectedParticipants.length).arg(selectedParticipants.length > 1 ? "s" : "")
|
rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné").arg(selectedParticipants.length).arg(selectedParticipants.length > 1 ? "s" : "")
|
||||||
|
|
@ -755,13 +735,6 @@ Window {
|
||||||
rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "")
|
rightPanel.headerSubtitleText = qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onParticipantAdded: {
|
|
||||||
addParticipantLayout.clearSelectedParticipants()
|
|
||||||
}
|
|
||||||
onValidateRequested: {
|
|
||||||
conferenceInfoGui.core.resetParticipants(contactList.selectedContacts)
|
|
||||||
returnRequested()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -799,6 +772,7 @@ Window {
|
||||||
anchors.topMargin: 10 * DefaultStyle.dp
|
anchors.topMargin: 10 * DefaultStyle.dp
|
||||||
call: mainWindow.call
|
call: mainWindow.call
|
||||||
callTerminatedByUser: mainWindow.callTerminatedByUser
|
callTerminatedByUser: mainWindow.callTerminatedByUser
|
||||||
|
onShareInvitationRequested: mainWindow.shareInvitation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import Linphone
|
||||||
import UtilsCpp 1.0
|
import UtilsCpp 1.0
|
||||||
import SettingsCpp 1.0
|
import SettingsCpp 1.0
|
||||||
|
|
||||||
ApplicationWindow {
|
AppWindow {
|
||||||
id: mainWindow
|
id: mainWindow
|
||||||
width: 1512 * DefaultStyle.dp
|
width: 1512 * DefaultStyle.dp
|
||||||
height: 982 * DefaultStyle.dp
|
height: 982 * DefaultStyle.dp
|
||||||
|
|
@ -33,57 +33,6 @@ ApplicationWindow {
|
||||||
mainWindowStackView.currentItem.transferCallSucceed()
|
mainWindowStackView.currentItem.transferCallSucceed()
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFromPopupLayout(index) {
|
|
||||||
popupLayout.popupList.splice(index, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: popupComp
|
|
||||||
InformationPopup{}
|
|
||||||
}
|
|
||||||
function showInformationPopup(title, description, isSuccess) {
|
|
||||||
var infoPopup = popupComp.createObject(popupLayout, {"title": title, "description": description, "isSuccess": isSuccess})
|
|
||||||
infoPopup.index = popupLayout.popupList.length
|
|
||||||
popupLayout.popupList.push(infoPopup)
|
|
||||||
infoPopup.open()
|
|
||||||
infoPopup.closePopup.connect(removeFromPopupLayout)
|
|
||||||
}
|
|
||||||
function showLoadingPopup(text) {
|
|
||||||
loadingPopup.text = text
|
|
||||||
loadingPopup.open()
|
|
||||||
}
|
|
||||||
function closeLoadingPopup() {
|
|
||||||
loadingPopup.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: popupLayout
|
|
||||||
anchors.fill: parent
|
|
||||||
Layout.alignment: Qt.AlignBottom
|
|
||||||
property int nextY: mainWindow.height
|
|
||||||
property list<InformationPopup> popupList
|
|
||||||
property int popupCount: popupList.length
|
|
||||||
spacing: 15 * DefaultStyle.dp
|
|
||||||
onPopupCountChanged: {
|
|
||||||
nextY = mainWindow.height
|
|
||||||
for(var i = 0; i < popupCount; ++i) {
|
|
||||||
popupList[i].y = nextY - popupList[i].height
|
|
||||||
popupList[i].index = i
|
|
||||||
nextY = nextY - popupList[i].height - 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingPopup {
|
|
||||||
id: loadingPopup
|
|
||||||
modal: true
|
|
||||||
closePolicy: Popup.NoAutoClose
|
|
||||||
anchors.centerIn: parent
|
|
||||||
padding: 20 * DefaultStyle.dp
|
|
||||||
underlineColor: DefaultStyle.main1_500_main
|
|
||||||
radius: 15 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountProxy {
|
AccountProxy {
|
||||||
// TODO : change this so it does not display the main page for one second
|
// TODO : change this so it does not display the main page for one second
|
||||||
// when we fail trying to connect the first account (account is added and
|
// when we fail trying to connect the first account (account is added and
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
list(APPEND _LINPHONEAPP_QML_FILES
|
list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/App/Main.qml
|
view/App/Main.qml
|
||||||
view/App/CallsWindow.qml
|
view/App/CallsWindow.qml
|
||||||
|
view/App/AppWindow.qml
|
||||||
view/App/Layout/LoginLayout.qml
|
view/App/Layout/LoginLayout.qml
|
||||||
view/App/Layout/MainLayout.qml
|
view/App/Layout/MainLayout.qml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ StackView {
|
||||||
|| (contact && contact.core.pictureUri)
|
|| (contact && contact.core.pictureUri)
|
||||||
|| computedAvatarUri.length != 0
|
|| computedAvatarUri.length != 0
|
||||||
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(address)
|
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(address)
|
||||||
|
|
||||||
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
||||||
|
|
||||||
property bool secured: false
|
property bool secured: false
|
||||||
|
|
|
||||||
|
|
@ -236,12 +236,13 @@ RightPanelLayout {
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
|
id: phoneNumberInput
|
||||||
label: qsTr("Phone")
|
label: qsTr("Phone")
|
||||||
contentItem: TextField {
|
contentItem: TextField {
|
||||||
backgroundColor: DefaultStyle.grey_0
|
backgroundColor: DefaultStyle.grey_0
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(label, text)
|
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(phoneNumberInput.label, text)
|
||||||
setText("")
|
text = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ Item {
|
||||||
width: 200
|
width: 200
|
||||||
property bool previewEnabled
|
property bool previewEnabled
|
||||||
property CallGui call: null
|
property CallGui call: null
|
||||||
|
property ConferenceGui conference: call && call.core.conference || null
|
||||||
|
property var callState: call && call.core.state || undefined
|
||||||
property AccountGui account: null
|
property AccountGui account: null
|
||||||
property ParticipantDeviceGui participantDevice: null
|
property ParticipantDeviceGui participantDevice: null
|
||||||
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false
|
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false
|
||||||
|
|
@ -38,7 +40,10 @@ Item {
|
||||||
property bool displayAll : !!mainItem.call
|
property bool displayAll : !!mainItem.call
|
||||||
property bool bigBottomAddress: displayAll
|
property bool bigBottomAddress: displayAll
|
||||||
property bool mutedStatus: participantDevice ? participantDevice.core.isMuted : false
|
property bool mutedStatus: participantDevice ? participantDevice.core.isMuted : false
|
||||||
|
onCallChanged: {
|
||||||
|
waitingTime.seconds = 0
|
||||||
|
waitingTimer.restart()
|
||||||
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
color: noCameraLayout.visible ? mainItem.color : 'transparent'
|
color: noCameraLayout.visible ? mainItem.color : 'transparent'
|
||||||
|
|
@ -47,19 +52,60 @@ Item {
|
||||||
border.color: DefaultStyle.main2_200
|
border.color: DefaultStyle.main2_200
|
||||||
border.width: mainItem.displayBorder ? 3 * DefaultStyle.dp : 0
|
border.width: mainItem.displayBorder ? 3 * DefaultStyle.dp : 0
|
||||||
property int minSize: Math.min(height, width)
|
property int minSize: Math.min(height, width)
|
||||||
ColumnLayout {
|
Item {
|
||||||
id: noCameraLayout
|
id: noCameraLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
|
||||||
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
|
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 81 * DefaultStyle.dp
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
// Layout.alignment: Qt.AlignHCenter |Qt.AlignTop
|
||||||
|
spacing: 0
|
||||||
|
visible: !mainItem.account && (mainItem.callState === LinphoneEnums.CallState.OutgoingInit
|
||||||
|
|| mainItem.callState === LinphoneEnums.CallState.OutgoingProgress
|
||||||
|
|| mainItem.callState === LinphoneEnums.CallState.OutgoingRinging
|
||||||
|
|| mainItem.callState === LinphoneEnums.CallState.OutgoingEarlyMedia
|
||||||
|
|| mainItem.callState === LinphoneEnums.CallState.IncomingReceived)
|
||||||
|
BusyIndicator {
|
||||||
|
indicatorColor: DefaultStyle.main2_100
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
indicatorHeight: 27 * DefaultStyle.dp
|
||||||
|
indicatorWidth: 27 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: waitingTimer
|
||||||
|
interval: 1000
|
||||||
|
repeat: true
|
||||||
|
onTriggered: waitingTime.seconds += 1
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: waitingTime
|
||||||
|
property int seconds
|
||||||
|
text: UtilsCpp.formatElapsedTime(seconds)
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.topMargin: 25 * DefaultStyle.dp
|
||||||
|
font {
|
||||||
|
pixelSize: 30 * DefaultStyle.dp
|
||||||
|
weight: 300 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
waitingTimer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Item{
|
Item{
|
||||||
Layout.alignment: Qt.AlignHCenter
|
anchors.centerIn: parent
|
||||||
// minSize = 372 => avatar = 142
|
height: mainItem.conference
|
||||||
Layout.preferredHeight: background.minSize * 142 / 372
|
? background.minSize * 142 / 372
|
||||||
Layout.preferredWidth: height
|
: 120 * DefaultStyle.dp
|
||||||
|
width: height
|
||||||
|
id: centerItem
|
||||||
Avatar{
|
Avatar{
|
||||||
id: avatar
|
id: avatar
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: !joiningView.visible
|
visible: !joiningView.visible
|
||||||
account: mainItem.account
|
account: mainItem.account
|
||||||
call: !mainItem.previewEnabled ? mainItem.call : null
|
call: !mainItem.previewEnabled ? mainItem.call : null
|
||||||
|
|
@ -67,15 +113,11 @@ Item {
|
||||||
}
|
}
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
id: joiningView
|
id: joiningView
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
visible: mainItem.participantDevice && (mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Alerting) || false
|
visible: mainItem.participantDevice && (mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Alerting) || false
|
||||||
Item{
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
Layout.preferredHeight: 27 * DefaultStyle.dp
|
Layout.preferredHeight: 42 * DefaultStyle.dp
|
||||||
indicatorColor: DefaultStyle.main2_100
|
indicatorColor: DefaultStyle.main2_100
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
indicatorHeight: 42 * DefaultStyle.dp
|
indicatorHeight: 42 * DefaultStyle.dp
|
||||||
|
|
@ -93,34 +135,34 @@ Item {
|
||||||
weight: 500 * DefaultStyle.dp
|
weight: 500 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item{
|
}
|
||||||
Layout.fillHeight: true
|
}
|
||||||
Layout.fillWidth: true
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
visible: mainItem.displayAll
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: centerItem.bottom
|
||||||
|
anchors.topMargin: 21 * DefaultStyle.dp
|
||||||
|
Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: mainItem.peerAddress
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
font {
|
||||||
|
pixelSize: 22 * DefaultStyle.dp
|
||||||
|
weight: 300 * DefaultStyle.dp
|
||||||
|
capitalization: Font.Capitalize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Text {
|
||||||
Text {
|
Layout.fillWidth: true
|
||||||
Layout.fillWidth: true
|
horizontalAlignment: Text.AlignHCenter
|
||||||
Layout.topMargin: 15 * DefaultStyle.dp
|
text: mainItem.call && mainItem.call.core.peerAddress
|
||||||
horizontalAlignment: Text.AlignHCenter
|
color: DefaultStyle.grey_0
|
||||||
visible: mainItem.displayAll
|
font {
|
||||||
text: mainItem.peerAddress
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
color: DefaultStyle.grey_0
|
weight: 300 * DefaultStyle.dp
|
||||||
font {
|
}
|
||||||
pixelSize: 22 * DefaultStyle.dp
|
|
||||||
weight: 300 * DefaultStyle.dp
|
|
||||||
capitalization: Font.Capitalize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
visible: mainItem.displayAll
|
|
||||||
text: mainItem.call && mainItem.call.core.peerAddress
|
|
||||||
color: DefaultStyle.grey_0
|
|
||||||
font {
|
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
|
||||||
weight: 300 * DefaultStyle.dp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +176,7 @@ Item {
|
||||||
triggeredOnStart: true
|
triggeredOnStart: true
|
||||||
onTriggered: {cameraLoader.reset = !cameraLoader.reset}
|
onTriggered: {cameraLoader.reset = !cameraLoader.reset}
|
||||||
}
|
}
|
||||||
active: mainItem.visible && mainItem.videoEnabled && !cameraLoader.reset
|
active: mainItem.visible && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released && mainItem.videoEnabled && !cameraLoader.reset
|
||||||
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active +", visible="+mainItem.visible +", videoEnabled="+mainItem.videoEnabled +", reset="+cameraLoader.reset)
|
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active +", visible="+mainItem.visible +", videoEnabled="+mainItem.videoEnabled +", reset="+cameraLoader.reset)
|
||||||
sourceComponent: cameraComponent
|
sourceComponent: cameraComponent
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,7 @@ Item{
|
||||||
onCountChanged: console.log("Device count changed : " +count)
|
onCountChanged: console.log("Device count changed : " +count)
|
||||||
Component.onCompleted: console.log("Loaded : " +allDevices)
|
Component.onCompleted: console.log("Loaded : " +allDevices)
|
||||||
}
|
}
|
||||||
onCallChanged: {
|
onCallStateChanged: if (callState === LinphoneEnums.CallState.End || callState === LinphoneEnums.CallState.Released) preview.visible = false
|
||||||
waitingTime.seconds = 0
|
|
||||||
waitingTimer.restart()
|
|
||||||
console.log("call changed", call, waitingTime.seconds)
|
|
||||||
}
|
|
||||||
RowLayout{
|
RowLayout{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||||
|
|
@ -42,46 +38,6 @@ Item{
|
||||||
videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled)
|
videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled)
|
||||||
qmlName: 'AS'
|
qmlName: 'AS'
|
||||||
displayPresence: false
|
displayPresence: false
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: waitingTimer
|
|
||||||
interval: 1000
|
|
||||||
repeat: true
|
|
||||||
onTriggered: waitingTime.seconds += 1
|
|
||||||
}
|
|
||||||
ColumnLayout {
|
|
||||||
id: waitingConnection
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 30 * DefaultStyle.dp
|
|
||||||
spacing: 0
|
|
||||||
visible: mainItem.callState === LinphoneEnums.CallState.OutgoingInit
|
|
||||||
|| mainItem.callState === LinphoneEnums.CallState.OutgoingProgress
|
|
||||||
|| mainItem.callState === LinphoneEnums.CallState.OutgoingRinging
|
|
||||||
|| mainItem.callState === LinphoneEnums.CallState.OutgoingEarlyMedia
|
|
||||||
|| mainItem.callState === LinphoneEnums.CallState.IncomingReceived
|
|
||||||
BusyIndicator {
|
|
||||||
indicatorColor: DefaultStyle.main2_100
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
indicatorHeight: 30 * DefaultStyle.dp
|
|
||||||
indicatorWidth: 30 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: waitingTime
|
|
||||||
property int seconds
|
|
||||||
text: UtilsCpp.formatElapsedTime(seconds)
|
|
||||||
color: DefaultStyle.grey_0
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font {
|
|
||||||
pixelSize: 30 * DefaultStyle.dp
|
|
||||||
weight: 300 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
waitingTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ListView{
|
ListView{
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
@ -116,7 +72,7 @@ Item{
|
||||||
id: preview
|
id: preview
|
||||||
qmlName: 'P'
|
qmlName: 'P'
|
||||||
previewEnabled: true
|
previewEnabled: true
|
||||||
visible: mainItem.call && allDevices.count <= 2 && !waitingConnection.visible
|
visible: mainItem.call && allDevices.count <= 2
|
||||||
onVisibleChanged: console.log(visible + " : " +allDevices.count)
|
onVisibleChanged: console.log(visible + " : " +allDevices.count)
|
||||||
height: 180 * DefaultStyle.dp
|
height: 180 * DefaultStyle.dp
|
||||||
width: 300 * DefaultStyle.dp
|
width: 300 * DefaultStyle.dp
|
||||||
|
|
|
||||||
|
|
@ -12,36 +12,54 @@ import SettingsCpp 1.0
|
||||||
Item {
|
Item {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
property CallGui call
|
property CallGui call
|
||||||
|
property ConferenceGui conference: call && call.core.conference
|
||||||
property bool callTerminatedByUser: false
|
property bool callTerminatedByUser: false
|
||||||
readonly property var callState: call && call.core.state || undefined
|
readonly property var callState: call && call.core.state || undefined
|
||||||
property int conferenceLayout: call && call.core.conferenceVideoLayout || 0
|
property int conferenceLayout: call && call.core.conferenceVideoLayout || 0
|
||||||
|
property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
|
||||||
|
Component.onCompleted: setConferenceLayout()
|
||||||
onConferenceLayoutChanged: {
|
onConferenceLayoutChanged: {
|
||||||
console.log("CallLayout change : " +conferenceLayout)
|
console.log("CallLayout change : " +conferenceLayout)
|
||||||
|
setConferenceLayout()
|
||||||
|
}
|
||||||
|
onCallStateChanged: {
|
||||||
|
if( callState === LinphoneEnums.CallState.Error) {
|
||||||
|
centerLayout.currentIndex = 1
|
||||||
|
} else if( callState === LinphoneEnums.CallState.End) {
|
||||||
|
callTerminatedText.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signal shareInvitationRequested()
|
||||||
|
function setConferenceLayout() {
|
||||||
|
if (mainItem.participantDeviceCount < 2 ) {
|
||||||
|
return
|
||||||
|
}
|
||||||
callLayout.sourceComponent = undefined // unload old view before opening the new view to avoid conflicts in Video UI.
|
callLayout.sourceComponent = undefined // unload old view before opening the new view to avoid conflicts in Video UI.
|
||||||
callLayout.sourceComponent = mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker
|
callLayout.sourceComponent = mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker
|
||||||
? activeSpeakerComponent
|
? activeSpeakerComponent
|
||||||
: gridComponent
|
: gridComponent
|
||||||
}
|
}
|
||||||
onCallStateChanged: if (callState === LinphoneEnums.CallState.End) {
|
|
||||||
callTerminatedText.visible = true
|
|
||||||
}else if( callState === LinphoneEnums.CallState.Error) {
|
|
||||||
centerLayout.currentIndex = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: callTerminatedText
|
id: callTerminatedText
|
||||||
visible: false
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 25 * DefaultStyle.dp
|
anchors.topMargin: 25 * DefaultStyle.dp
|
||||||
text: mainItem.callTerminatedByUser ? qsTr("Vous avez terminé l'appel") : qsTr("Votre correspondant a terminé l'appel")
|
|
||||||
color: DefaultStyle.grey_0
|
|
||||||
z: 1
|
z: 1
|
||||||
|
visible: false
|
||||||
|
text: mainItem.conference
|
||||||
|
? qsTr("Vous avez quitté la conférence")
|
||||||
|
: mainItem.callTerminatedByUser
|
||||||
|
? qsTr("Vous avez terminé l'appel")
|
||||||
|
: qsTr("Votre correspondant a terminé l'appel")
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
font {
|
font {
|
||||||
pixelSize: 22 * DefaultStyle.dp
|
pixelSize: 22 * DefaultStyle.dp
|
||||||
weight: 300 * DefaultStyle.dp
|
weight: 300 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.StackLayout {
|
Layout.StackLayout {
|
||||||
id: centerLayout
|
id: centerLayout
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
|
|
@ -50,7 +68,9 @@ Item {
|
||||||
id: callLayout
|
id: callLayout
|
||||||
Layout.Layout.fillWidth: true
|
Layout.Layout.fillWidth: true
|
||||||
Layout.Layout.fillHeight: true
|
Layout.Layout.fillHeight: true
|
||||||
sourceComponent: gridComponent
|
sourceComponent: mainItem.conference && mainItem.participantDeviceCount < 2
|
||||||
|
? waitingForOthersComponent
|
||||||
|
: activeSpeakerComponent
|
||||||
}
|
}
|
||||||
Layout.ColumnLayout {
|
Layout.ColumnLayout {
|
||||||
id: userNotFoundLayout
|
id: userNotFoundLayout
|
||||||
|
|
@ -81,6 +101,50 @@ Item {
|
||||||
call: mainItem.call
|
call: mainItem.call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component {
|
||||||
|
id: waitingForOthersComponent
|
||||||
|
Rectangle {
|
||||||
|
color: DefaultStyle.grey_600
|
||||||
|
radius: 15 * DefaultStyle.dp
|
||||||
|
Layout.Layout.fillWidth: true
|
||||||
|
Layout.Layout.fillHeight: true
|
||||||
|
Layout.ColumnLayout {
|
||||||
|
id: waitingForOthersLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 22 * DefaultStyle.dp
|
||||||
|
Text {
|
||||||
|
text: qsTr("Waiting for other participants...")
|
||||||
|
Layout.Layout.preferredHeight: 67 * DefaultStyle.dp
|
||||||
|
Layout.Layout.alignment: Qt.AlignHCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
font {
|
||||||
|
pixelSize: 30 * DefaultStyle.dp
|
||||||
|
weight: 300 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
color: "transparent"
|
||||||
|
borderColor: DefaultStyle.main2_400
|
||||||
|
pressedColor: DefaultStyle.main2_500main
|
||||||
|
icon.source: AppIcons.shareNetwork
|
||||||
|
contentImageColor: DefaultStyle.main2_400
|
||||||
|
text: qsTr("Share invitation")
|
||||||
|
topPadding: 11 * DefaultStyle.dp
|
||||||
|
bottomPadding: 11 * DefaultStyle.dp
|
||||||
|
leftPadding: 20 * DefaultStyle.dp
|
||||||
|
rightPadding: 20 * DefaultStyle.dp
|
||||||
|
Layout.Layout.alignment: Qt.AlignHCenter
|
||||||
|
textColor: DefaultStyle.main2_400
|
||||||
|
onClicked: {
|
||||||
|
if (mainItem.conference) {
|
||||||
|
mainItem.shareInvitationRequested()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO : waitingForParticipant
|
// TODO : waitingForParticipant
|
||||||
// ColumnLayout {
|
// ColumnLayout {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ ColumnLayout {
|
||||||
property ConferenceInfoGui conferenceInfoGui
|
property ConferenceInfoGui conferenceInfoGui
|
||||||
property bool nameGroupCall: false
|
property bool nameGroupCall: false
|
||||||
readonly property string groupName: groupCallName.text
|
readonly property string groupName: groupCallName.text
|
||||||
|
property color searchBarColor: DefaultStyle.grey_100
|
||||||
|
property color searchBarBorderColor: "transparent"
|
||||||
|
|
||||||
function clearSelectedParticipants() {
|
function clearSelectedParticipants() {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
@ -47,7 +49,6 @@ ColumnLayout {
|
||||||
ListView {
|
ListView {
|
||||||
id: participantList
|
id: participantList
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 15 * DefaultStyle.dp
|
|
||||||
Layout.preferredHeight: contentHeight
|
Layout.preferredHeight: contentHeight
|
||||||
Layout.maximumHeight: mainItem.height / 3
|
Layout.maximumHeight: mainItem.height / 3
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
|
|
@ -99,12 +100,14 @@ ColumnLayout {
|
||||||
SearchBar {
|
SearchBar {
|
||||||
id: searchbar
|
id: searchbar
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 21 * DefaultStyle.dp
|
Layout.topMargin: 6 * DefaultStyle.dp
|
||||||
Layout.rightMargin: 28 * DefaultStyle.dp
|
Layout.rightMargin: 28 * DefaultStyle.dp
|
||||||
placeholderText: mainItem.placeHolderText
|
placeholderText: mainItem.placeHolderText
|
||||||
|
color: mainItem.searchBarColor
|
||||||
|
borderColor: mainItem.searchBarColor
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
Layout.topMargin: 21 * DefaultStyle.dp
|
Layout.topMargin: 6 * DefaultStyle.dp
|
||||||
text: qsTr("Contacts")
|
text: qsTr("Contacts")
|
||||||
font {
|
font {
|
||||||
pixelSize: 16 * DefaultStyle.dp
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue