- Fix crash and leaks on restart/quit.

- Reload conference list when current account change.
- Fix popup design (margins).
- Factorization of message banner (eg. copy text message)
- Factorization of NewConference dialog.
- Fix design on file preview in chat.
- Add participant shortcut in video conference.
- Remove old Linphone-Utils file/scripts.
- Fix avatar image in history view when clicking on username.
This commit is contained in:
Julien Wadel 2022-05-11 18:58:08 +02:00
parent 6528d2a946
commit 8c9e610107
84 changed files with 525 additions and 515 deletions

View file

@ -229,6 +229,7 @@
<file>ui/modules/Common/Menus/Menu.qml</file>
<file>ui/modules/Common/Misc/Borders.qml</file>
<file>ui/modules/Common/Misc/ForceScrollBar.qml</file>
<file>ui/modules/Common/Misc/MessageBanner.qml</file>
<file>ui/modules/Common/Misc/Paned.qml</file>
<file>ui/modules/Common/Picker/DatePicker.qml</file>
<file>ui/modules/Common/Picker/TimePicker.qml</file>
@ -276,6 +277,7 @@
<file>ui/modules/Common/Styles/Menus/MenuItemStyle.qml</file>
<file>ui/modules/Common/Styles/Menus/MenuStyle.qml</file>
<file>ui/modules/Common/Styles/Misc/ForceScrollBarStyle.qml</file>
<file>ui/modules/Common/Styles/Misc/MessageBannerStyle.qml</file>
<file>ui/modules/Common/Styles/Misc/PanedStyle.qml</file>
<file>ui/modules/Common/Styles/Picker/DatePickerStyle.qml</file>
<file>ui/modules/Common/Styles/Picker/TimePickerStyle.qml</file>
@ -398,12 +400,11 @@
<file>ui/modules/Linphone/View/ParticipantsListView.qml</file>
<file>ui/modules/Linphone/View/ParticipantsView.qml</file>
<file>ui/modules/Linphone/View/SipAddressesView.qml</file>
<file>ui/scripts/LinphoneUtils/linphone-utils.js</file>
<file>ui/scripts/LinphoneUtils/qmldir</file>
<file>ui/scripts/Utils/port-tools.js</file>
<file>ui/scripts/Utils/qmldir</file>
<file>ui/scripts/Utils/uri-tools.js</file>
<file>ui/scripts/Utils/utils.js</file>
<file>ui/views/App/qmldir</file>
<file>ui/views/App/Calls/AbstractStartingCall.qml</file>
<file>ui/views/App/Calls/CallsWindow.js</file>
<file>ui/views/App/Calls/CallsWindow.qml</file>
@ -424,6 +425,7 @@
<file>ui/views/App/Calls/OutgoingCall.qml</file>
<file>ui/views/App/Calls/WaitingRoom.qml</file>
<file>ui/views/App/Calls/ZrtpTokenAuthentication.qml</file>
<file>ui/views/App/Dialog/NewConference.qml</file>
<file>ui/views/App/Main/Assistant/ActivateAppSipAccountWithEmail.qml</file>
<file>ui/views/App/Main/Assistant/ActivateAppSipAccountWithPhoneNumber.qml</file>
<file>ui/views/App/Main/Assistant/AssistantAbstractView.qml</file>
@ -452,7 +454,6 @@
<file>ui/views/App/Main/Dialogs/ManageAccount.js</file>
<file>ui/views/App/Main/Dialogs/ManageAccounts.qml</file>
<file>ui/views/App/Main/Dialogs/NewChatRoom.qml</file>
<file>ui/views/App/Main/Dialogs/NewConference.qml</file>
<file>ui/views/App/Main/Dialogs/ParticipantsDevices.qml</file>
<file>ui/views/App/Main/Home.qml</file>
<file>ui/views/App/Main/HistoryView.qml</file>
@ -490,6 +491,7 @@
<file>ui/views/App/Styles/Calls/Dialogs/CallTransferStyle.qml</file>
<file>ui/views/App/Styles/Calls/Dialogs/ConferenceManagerStyle.qml</file>
<file>ui/views/App/Styles/Calls/Dialogs/MultimediaParametersStyle.qml</file>
<file>ui/views/App/Styles/Dialog/NewConferenceStyle.qml</file>
<file>ui/views/App/Styles/Main/Assistant/ActivateAppSipAccountWithEmailStyle.qml</file>
<file>ui/views/App/Styles/Main/Assistant/ActivateAppSipAccountWithPhoneNumberStyle.qml</file>
<file>ui/views/App/Styles/Main/Assistant/AssistantAbstractViewStyle.qml</file>
@ -507,7 +509,6 @@
<file>ui/views/App/Styles/Main/Dialogs/InfoChatRoomStyle.qml</file>
<file>ui/views/App/Styles/Main/Dialogs/InfoEncryptionStyle.qml</file>
<file>ui/views/App/Styles/Main/Dialogs/NewChatRoomStyle.qml</file>
<file>ui/views/App/Styles/Main/Dialogs/NewConferenceStyle.qml</file>
<file>ui/views/App/Styles/Main/Dialogs/ManageAccountsStyle.qml</file>
<file>ui/views/App/Styles/Main/Dialogs/ParticipantsDevicesStyle.qml</file>
<file>ui/views/App/Styles/Main/HomeStyle.qml</file>

View file

@ -235,14 +235,19 @@ App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::U
App::~App () {
qInfo() << QStringLiteral("Destroying app...");
if( mEngine )
}
void App::stop(){
qInfo() << QStringLiteral("Stopping app...");
if( mEngine ){
delete mEngine;
processEvents(QEventLoop::AllEvents);
}
CoreManager::uninit();
processEvents(QEventLoop::AllEvents); // Process all needed events on engine deletion.
if( mParser)
delete mParser;
}
// -----------------------------------------------------------------------------
QStringList App::cleanParserKeys(QCommandLineParser * parser, QStringList keys){
@ -406,7 +411,6 @@ void App::initContentApp () {
// Enable notifications.
mNotifier = new Notifier(mEngine);
// Load main view.
qInfo() << QStringLiteral("Loading main view...");
mEngine->load(QUrl(Constants::QmlViewMainWindow));

View file

@ -56,6 +56,7 @@ public:
App (int &argc, char *argv[]);
~App ();
void stop();
void initContentApp ();
QStringList cleanParserKeys(QCommandLineParser * parser, QStringList keys);// Get all options from parser and remove the selected keys. Return the result that can be passed to parser process.
void processArguments(QHash<QString,QString> args);

View file

@ -120,6 +120,7 @@ AppController::~AppController () {
void AppController::stopApp(){
try{
mApp->stop();
delete mApp;
mApp = nullptr;
}

View file

@ -27,6 +27,10 @@ template <class T>
class SortFilterAbstractProxyModel : public SortFilterProxyModel {
public:
SortFilterAbstractProxyModel(T * model, QObject * parent = nullptr) : SortFilterProxyModel(parent){
update(model);
}
void update(T* model){
setSourceModel(model);
sort(0, Qt::DescendingOrder);
}

View file

@ -192,10 +192,6 @@ QSharedPointer<ParticipantImdnStateListModel> ChatMessageModel::getParticipantIm
return mParticipantImdnStateListModel;
}
ContentProxyModel * ChatMessageModel::getContentsProxy(){
return new ContentProxyModel(this);
}
QSharedPointer<ContentListModel> ChatMessageModel::getContents() const{
return mContentListModel;
}

View file

@ -112,7 +112,6 @@ public:
bool isOutgoing() const;
Q_INVOKABLE ParticipantImdnStateProxyModel * getProxyImdnStates();
QSharedPointer<ParticipantImdnStateListModel> getParticipantImdnStates() const;
Q_INVOKABLE ContentProxyModel * getContentsProxy();
QSharedPointer<ContentListModel> getContents() const;
bool isReply() const;

View file

@ -22,6 +22,7 @@
#include "components/call/CallModel.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "ConferenceInfoListModel.hpp"
#include "ConferenceInfoMapModel.hpp"
@ -34,8 +35,17 @@ using namespace std;
//---------------------------------------------------------------------------------------------
ConferenceInfoProxyModel::ConferenceInfoProxyModel (QObject *parent) : SortFilterAbstractProxyModel<ConferenceInfoMapModel>(new ConferenceInfoMapModel(parent), parent) {
setFilterType((int)Scheduled);
connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::primarySipAddressChanged, this, &ConferenceInfoProxyModel::update);
connect(this, &ConferenceInfoProxyModel::filterTypeChanged, qobject_cast<ConferenceInfoMapModel*>(sourceModel()), &ConferenceInfoMapModel::filterTypeChanged);
setFilterType((int)Scheduled);
}
void ConferenceInfoProxyModel::update(){
int oldFilter = getFilterType();
SortFilterAbstractProxyModel<ConferenceInfoMapModel>::update(new ConferenceInfoMapModel(parent()));
setFilterType(oldFilter+1);
connect(this, &ConferenceInfoProxyModel::filterTypeChanged, qobject_cast<ConferenceInfoMapModel*>(sourceModel()), &ConferenceInfoMapModel::filterTypeChanged);
setFilterType(oldFilter);
}
bool ConferenceInfoProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {

View file

@ -47,6 +47,8 @@ public:
Q_ENUM(ConferenceType)
ConferenceInfoProxyModel (QObject *parent = Q_NULLPTR);
Q_INVOKABLE void update();
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;

View file

@ -91,6 +91,7 @@ CoreManager::~CoreManager(){
// -----------------------------------------------------------------------------
void CoreManager::initCoreManager(){
qInfo() << "Init CoreManager";
mCallsListModel = new CallsListModel(this);
mChatModel = new ChatModel(this);
mContactsListModel = new ContactsListModel(this);
@ -144,20 +145,13 @@ void CoreManager::init (QObject *parent, const QString &configPath) {
void CoreManager::uninit () {
if (mInstance) {
connect(mInstance, &QObject::destroyed, []()mutable{
mInstance = nullptr;
qInfo() << "Core is correctly destroyed";
});
QObject::connect(mInstance->getHandlers().get(), &CoreHandlers::coreStopped, mInstance, &QObject::deleteLater); // Delete data only when the core is Off
mInstance->lockVideoRender();// Stop do iterations. We have to protect GUI.
mInstance->mCore->stop();
mInstance->mCore->stop();// This is a synchronized stop.
mInstance->unlockVideoRender();
QTest::qWaitFor([&]() {return mInstance == nullptr;},10000);
if( mInstance){
qWarning() << "Core couldn't destroy in time. It may lead to have multiple session of Core";
mInstance = nullptr;
}
if( mInstance->mCore->getGlobalState() != linphone::GlobalState::Off)
qWarning() << "Core is not off after stopping it. It may result to have multiple core instance.";
delete mInstance;
mInstance = nullptr;
}
}

View file

@ -24,6 +24,7 @@
#include "components/settings/AccountSettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/conference/ConferenceModel.hpp"
#include "components/conferenceInfo/ConferenceInfoModel.hpp"
#include "utils/Utils.hpp"
#include "ParticipantListModel.hpp"
@ -37,6 +38,7 @@
// -----------------------------------------------------------------------------
ParticipantProxyModel::ParticipantProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(new ParticipantListModel((ConferenceModel*)nullptr, this));
}
// -----------------------------------------------------------------------------
@ -116,6 +118,12 @@ void ParticipantProxyModel::setConferenceModel(ConferenceModel * conferenceModel
}
}
void ParticipantProxyModel::setAddresses(ConferenceInfoModel * conferenceInfoModel){
if(conferenceInfoModel && conferenceInfoModel->getConferenceInfo())
for(auto address : conferenceInfoModel->getConferenceInfo()->getParticipants())
addAddress(QString::fromStdString(address->asString()));
}
void ParticipantProxyModel::setShowMe(const bool& show){
if(mShowMe != show){
mShowMe = show;

View file

@ -28,57 +28,59 @@ class ParticipantModel;
class ChatRoomModel;
class ParticipantListModel;
class ConferenceModel;
class ConferenceInfoModel;
// =============================================================================
class QWindow;
class ParticipantProxyModel : public QSortFilterProxyModel {
Q_OBJECT
Q_OBJECT
public:
ParticipantProxyModel ( QObject *parent = Q_NULLPTR);
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged)
Q_PROPERTY(ConferenceModel* conferenceModel READ getConferenceModel WRITE setConferenceModel NOTIFY conferenceModelChanged)
Q_PROPERTY(ParticipantListModel * participantListModel READ getParticipantListModel NOTIFY participantListModelChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
ChatRoomModel *getChatRoomModel() const;
ConferenceModel *getConferenceModel() const;
ParticipantListModel * getParticipantListModel() const;
Q_INVOKABLE QStringList getSipAddresses() const;
Q_INVOKABLE QVariantList getParticipants() const;
Q_INVOKABLE int getCount() const;
bool getShowMe() const;
void setChatRoomModel(ChatRoomModel * chatRoomModel);
void setConferenceModel(ConferenceModel * conferenceModel);
void setShowMe(const bool& show);
Q_INVOKABLE void addAddress(const QString& address);
Q_INVOKABLE void removeModel(ParticipantModel * participant);
ParticipantProxyModel ( QObject *parent = Q_NULLPTR);
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged)
Q_PROPERTY(ConferenceModel* conferenceModel READ getConferenceModel WRITE setConferenceModel NOTIFY conferenceModelChanged)
Q_PROPERTY(ParticipantListModel * participantListModel READ getParticipantListModel NOTIFY participantListModelChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
ChatRoomModel *getChatRoomModel() const;
ConferenceModel *getConferenceModel() const;
ParticipantListModel * getParticipantListModel() const;
Q_INVOKABLE QStringList getSipAddresses() const;
Q_INVOKABLE QVariantList getParticipants() const;
Q_INVOKABLE int getCount() const;
bool getShowMe() const;
void setChatRoomModel(ChatRoomModel * chatRoomModel);
void setConferenceModel(ConferenceModel * conferenceModel);
void setShowMe(const bool& show);
Q_INVOKABLE void addAddress(const QString& address);
Q_INVOKABLE void removeModel(ParticipantModel * participant);
Q_INVOKABLE void setAddresses(ConferenceInfoModel * conferenceInfoModel);
signals:
void chatRoomModelChanged();
void conferenceModelChanged();
void participantListModelChanged();
void countChanged();
void showMeChanged();
void addressAdded(QString sipAddress);
void addressRemoved(QString sipAddress);
void chatRoomModelChanged();
void conferenceModelChanged();
void participantListModelChanged();
void countChanged();
void showMeChanged();
void addressAdded(QString sipAddress);
void addressRemoved(QString sipAddress);
private:
ChatRoomModel *mChatRoomModel = nullptr;
ConferenceModel *mConferenceModel = nullptr;
bool mShowMe = true;
ChatRoomModel *mChatRoomModel = nullptr;
ConferenceModel *mConferenceModel = nullptr;
bool mShowMe = true;
};
#endif // PARTICIPANT_PROXY_MODEL_H_

View file

@ -33,6 +33,9 @@
TunnelConfigProxyModel::TunnelConfigProxyModel (QObject *parent) : QSortFilterProxyModel(parent){
}
TunnelConfigProxyModel::~TunnelConfigProxyModel() {
}
bool TunnelConfigProxyModel::filterAcceptsRow (
int sourceRow,
const QModelIndex &sourceParent

View file

@ -37,6 +37,7 @@ class TunnelConfigProxyModel : public QSortFilterProxyModel {
public:
TunnelConfigProxyModel (QObject *parent = nullptr);
virtual ~TunnelConfigProxyModel();
void setTunnel(TunnelModel * tunnel);

View file

@ -39,6 +39,9 @@ TunnelModel::TunnelModel (shared_ptr<linphone::Tunnel> tunnel, QObject *parent)
}
}
TunnelModel::~TunnelModel(){
}
// -----------------------------------------------------------------------------
QString TunnelModel::getDomain() const{

View file

@ -38,6 +38,7 @@ class TunnelModel : public QObject {
public:
TunnelModel (std::shared_ptr<linphone::Tunnel> linphoneTunnel, QObject *parent = nullptr);
virtual ~TunnelModel();
Q_PROPERTY(QString domain READ getDomain WRITE setDomain NOTIFY domainChanged)

View file

@ -94,6 +94,7 @@ Rectangle {
Layout.fillHeight: (expandHeight ? true : !dialog.contentIsEmpty)
Layout.fillWidth: true
Layout.topMargin: (showMargins ? DialogStyle.content.topMargin : 0)
Layout.bottomMargin: (showMargins ? DialogStyle.content.bottomMargin : 0)
Layout.leftMargin: (showMargins ? DialogStyle.content.leftMargin : 0)
Layout.rightMargin: (showMargins ? DialogStyle.content.rightMargin : 0)
}

View file

@ -0,0 +1,70 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Common 1.0
import Common.Styles 1.0
import Utils 1.0
Rectangle{
id: mainItem
property int fitHeight: visible && opacity > 0 ? 32 : 0
property string noticeBannerText
property int iconMode : 1 // 0=noIcons, 1=copy
onNoticeBannerTextChanged: if(noticeBannerText!='') mainItem.state = "showed"
color: MessageBannerStyle.color
radius: 10
state: "hidden"
Timer{
id: hideNoticeBanner
interval: 4000
repeat: false
onTriggered: mainItem.state = "hidden"
}
RowLayout{
anchors.centerIn: parent
spacing: 5
Icon{
icon: if(iconMode == 1) MessageBannerStyle.copyTextIcon
overwriteColor: MessageBannerStyle.textColor
iconSize: 20
visible: iconMode != 0
}
Text{
Layout.fillHeight: true
Layout.fillWidth: true
text: mainItem.noticeBannerText
font {
pointSize: MessageBannerStyle.pointSize
}
color: MessageBannerStyle.textColor
}
}
states: [
State {
name: "hidden"
PropertyChanges { target: mainItem; opacity: 0 }
},
State {
name: "showed"
PropertyChanges { target: mainItem; opacity: 1 }
}
]
transitions: [
Transition {
from: "*"; to: "showed"
SequentialAnimation{
NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 500 }
ScriptAction{ script: hideNoticeBanner.start()}
}
},
Transition {
SequentialAnimation{
NumberAnimation{ properties: "opacity"; duration: 1000 }
ScriptAction{ script: mainItem.noticeBannerText = '' }
}
}
]
}// mainItem

View file

@ -32,6 +32,7 @@ QtObject {
property int leftMargin: 25
property int rightMargin: 25
property int topMargin: 25
property int bottomMargin: 25
}
property QtObject description: QtObject {

View file

@ -0,0 +1,15 @@
pragma Singleton
import QtQml 2.2
import Units 1.0
import ColorsList 1.0
// =============================================================================
QtObject {
property string sectionName: 'MessageBanner'
property string copyTextIcon : 'copy_custom'
property color color: ColorsList.add(sectionName+'_message_banner', '', 'Background of message banner', '#9ecd1d').color
property color textColor: ColorsList.add(sectionName+'_message_banner_text', 'q', 'Text of message banner').color
property int pointSize: Units.dp * 9
}

View file

@ -53,6 +53,7 @@ singleton MenuItemStyle 1.0 Menus/MenuItemStyle.qml
singleton MenuStyle 1.0 Menus/MenuStyle.qml
singleton ForceScrollBarStyle 1.0 Misc/ForceScrollBarStyle.qml
singleton MessageBannerStyle 1.0 Misc/MessageBannerStyle.qml
singleton PanedStyle 1.0 Misc/PanedStyle.qml
singleton DatePickerStyle 1.0 Picker/DatePickerStyle.qml

View file

@ -82,6 +82,7 @@ MenuItem 1.0 Menus/MenuItem.qml
Borders 1.0 Misc/Borders.qml
ForceScrollBar 1.0 Misc/ForceScrollBar.qml
MessageBanner 1.0 Misc/MessageBanner.qml
Paned 1.0 Misc/Paned.qml
DatePicker 1.0 Picker/DatePicker.qml

View file

@ -1,7 +1,6 @@
import QtQuick 2.7
import Linphone 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0
@ -13,12 +12,14 @@ Avatar {
id: mainItem
property var call
property var participantDeviceModel
readonly property var _sipAddressObserver: call ? SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress)
property var _sipAddressObserver: call ? SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress)
: participantDeviceModel ? SipAddressesModel.getSipAddressObserver(participantDeviceModel.address, '')
: null
readonly property var _username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
property bool isPaused: (call && (call.status === CallModel.CallStatusPaused)) || (participantDeviceModel && participantDeviceModel.isPaused)
property var _username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
property bool isPaused: (call && (call.status === CallModel.CallStatusPaused)) || (participantDeviceModel && participantDeviceModel.isPaused) || false
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
backgroundColor: CallStyle.container.avatar.backgroundColor
foregroundColor: mainItem.isPaused ? CallStyle.container.pause.color : 'transparent'

View file

@ -7,7 +7,6 @@ import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0

View file

@ -26,8 +26,6 @@
.import Linphone 1.0 as Linphone
.import UtilsCpp 1.0 as UtilsCpp
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
// =============================================================================
function initView () {

View file

@ -21,8 +21,8 @@ Rectangle {
property alias proxyModel: chat.model // ChatRoomProxyModel
property alias tryingToLoadMoreEntries : chat.tryToLoadMoreEntries
property string noticeBannerText : '' // When set, show a banner with text and hide after some time
onNoticeBannerTextChanged: if(noticeBannerText!='') messageBlock.state = "showed"
property alias noticeBannerText : messageBlock.noticeBannerText // When set, show a banner with text and hide after some time
// ---------------------------------------------------------------------------
@ -380,66 +380,15 @@ Rectangle {
ColumnLayout{
anchors.fill: parent
spacing: 0
Rectangle{
MessageBanner{
id: messageBlock
onHeightChanged: height = Layout.preferredHeight
Layout.preferredHeight: visible && opacity > 0 ? 32 : 0
Layout.fillWidth: true
Layout.preferredHeight: fitHeight
Layout.leftMargin: ChatStyle.entry.leftMargin
Layout.rightMargin: ChatStyle.entry.rightMargin
color: ChatStyle.messageBanner.color
radius: 10
state: "hidden"
Timer{
id: hideNoticeBanner
interval: 4000
repeat: false
onTriggered: messageBlock.state = "hidden"
}
RowLayout{
anchors.centerIn: parent
spacing: 5
Icon{
icon: ChatStyle.copyTextIcon
overwriteColor: ChatStyle.messageBanner.textColor
iconSize: 20
}
Text{
Layout.fillHeight: true
Layout.fillWidth: true
text: container.noticeBannerText
font {
pointSize: ChatStyle.messageBanner.pointSize
}
color: ChatStyle.messageBanner.textColor
}
}
states: [
State {
name: "hidden"
PropertyChanges { target: messageBlock; opacity: 0 }
},
State {
name: "showed"
PropertyChanges { target: messageBlock; opacity: 1 }
}
]
transitions: [
Transition {
from: "*"; to: "showed"
SequentialAnimation{
NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 500 }
ScriptAction{ script: hideNoticeBanner.start()}
}
},
Transition {
SequentialAnimation{
NumberAnimation{ properties: "opacity"; duration: 1000 }
ScriptAction{ script: container.noticeBannerText = '' }
}
}
]
}// MessageBlock
noticeBannerText: ''
}
ChatMessagePreview{
id: chatMessagePreview
Layout.fillWidth: true

View file

@ -2,6 +2,7 @@ import QtQuick 2.7
import QtQuick.Layouts 1.3
import Clipboard 1.0
import App 1.0
import Common 1.0
import Linphone 1.0
@ -16,6 +17,7 @@ import LinphoneEnums 1.0
import ColorsList 1.0
import 'Message.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@ -32,6 +34,7 @@ Loader{
property bool isExpanded : false
signal expandToggle()
signal conferenceUriCopied()
width: parent.width
height: parent.height
@ -242,6 +245,10 @@ Loader{
isCustom: true
colorSet: ChatCalendarMessageStyle.copyLinkButton
backgroundRadius: width/2
onClicked: {
Clipboard.text = uriField.text
mainItem.conferenceUriCopied()
}
}
}
RowLayout{
@ -254,6 +261,7 @@ Loader{
}
TextButtonC{
text: 'REJOINDRE'
onClicked: CallsListModel.prepareConferenceCall(mainItem.conferenceInfoModel)
}
ActionButton{
isCustom: true
@ -261,7 +269,7 @@ Loader{
backgroundRadius: width/2
onClicked: {
window.detachVirtualWindow()
window.attachVirtualWindow(Qt.resolvedUrl('../../../views/App/Main/Dialogs/NewConference.qml')
window.attachVirtualWindow(Utils.buildAppDialogUri('NewConference')
,{conferenceInfoModel: mainItem.conferenceInfoModel})
}
}

View file

@ -4,7 +4,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import Utils 1.0

View file

@ -47,7 +47,7 @@ Item{
FileView{
height:mainListView.height-ChatFilePreviewStyle.filePreview.heightMargins
width: height * ChatFilePreviewStyle.filePreview.format
anchors.verticalCenter: ScrollableListView.contentItem.verticalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 7
//anchors.horizontalCenter: parent.horizontalCenter
thumbnail: $modelData.thumbnail

View file

@ -4,7 +4,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import LinphoneUtils 1.0
// =============================================================================

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.12
import Linphone 1.0
import LinphoneUtils 1.0
import Linphone.Styles 1.0
import Common 1.0

View file

@ -4,7 +4,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import Utils 1.0

View file

@ -2,7 +2,6 @@ import QtQuick 2.7
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import Utils 1.0
@ -14,9 +13,10 @@ Row {
id: mainItem
signal entryClicked(var entry)
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '')
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '')
property QtObject iconData
property string translation
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
Component.onCompleted: {
if ($historyEntry.status == LinphoneEnums.CallStatusSuccess) {
if(!$historyEntry.isStart){
@ -166,7 +166,7 @@ Row {
pointSize: HistoryStyle.entry.event.text.pointSize
}
height: parent.height
text: UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress)
text: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
verticalAlignment: Text.AlignVCenter
MouseArea{
anchors.fill:parent

View file

@ -25,8 +25,6 @@
.import Linphone 1.0 as Linphone
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
// =============================================================================
function initView () {

View file

@ -7,7 +7,6 @@ import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
@ -24,12 +23,26 @@ Rectangle{
property ParticipantModel me: conferenceModel.localParticipant
property bool isMeAdmin: me && me.adminStatus
onIsMeAdminChanged: console.log("Is admin : " +isMeAdmin)
property bool isParticipantsMenu: false
signal close()
height: 500
width: 400
color: "white"
radius: VideoConferenceMenuStyle.radius
// List of title texts in order to allow bindings between all components
property var menuTitles: [
'Régler les périphériques'
, 'Modifier la mise en page'
, mainItem.isMeAdmin ? 'Inviter des participants' : 'Participants'
]
function showParticipantsMenu(){
contentsStack.push(participantsMenu, {title:Qt.binding(function() { return mainItem.menuTitles[2]})})
visible = true
}
ButtonGroup{id: modeGroup}
ColumnLayout{
anchors.fill: parent
@ -87,13 +100,7 @@ Rectangle{
Layout.fillHeight: true
Layout.fillWidth: true
// List of title texts in order to allow bindings between all components
property var menuTitles: [
'Régler les périphériques'
, 'Modifier la mise en page'
, mainItem.isMeAdmin ? 'Inviter des participants' : 'Participants'
]
Repeater{
model: [
@ -136,7 +143,7 @@ Rectangle{
wrapMode: Text.WordWrap
elide: Text.ElideRight
text: menuTitles[modelData.titleIndex]
text: mainItem.menuTitles[modelData.titleIndex]
font.pointSize: VideoConferenceMenuStyle.list.pointSize
color: VideoConferenceMenuStyle.list.color
}
@ -265,6 +272,8 @@ Rectangle{
Layout.fillWidth: true
Layout.fillHeight: true
}
Component.onCompleted: mainItem.isParticipantsMenu = true
Component.onDestruction: mainItem.isParticipantsMenu = false
}
}
}

View file

@ -38,6 +38,7 @@ Notification {
entry=SipAddressesModel.getSipAddressObserver(peerAddress, notification.call ? notification.call.fullLocalAddress : '')
}
entry: SipAddressesModel.getSipAddressObserver(peerAddress, notification.call ? notification.call.fullLocalAddress : '')
Component.onDestruction: entry=null// Need to set it to null because of not calling destructor if not.
}
// ---------------------------------------------------------------------

View file

@ -49,6 +49,7 @@ Notification {
securityLevel: chatRoomModel.securityLevel,
auxDataToShow: '- ' + chatRoomModel.subject+' -'
})
Component.onDestruction: sipObserver=null// Need to set it to null because of not calling destructor if not.
}
Rectangle {

View file

@ -83,11 +83,6 @@ QtObject {
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_f_p', icon, 'l_p_b_fg').color
}
}
property QtObject messageBanner: QtObject {
property color color: ColorsList.add(sectionName+'_message_banner', '', 'Background of message banner', '#9ecd1d').color
property color textColor: ColorsList.add(sectionName+'_message_banner_text', 'q', 'Text of message banner').color
property int pointSize: Units.dp * 9
}
property QtObject ephemeralTimer: QtObject{
property string icon: 'timer_custom'
property int iconSize : 25

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
@ -29,7 +28,6 @@ ColumnLayout {
onIsAdminChanged: console.log("participantsListView is admin : "+isAdmin)
onCanHandleParticipantsChanged: console.log("CanHandleParticipants:"+canHandleParticipants)
spacing: ParticipantsListViewStyle.mainLayout.spacing
Component.onCompleted: console.log("participantsListView : " +isAdmin +", "+canHandleParticipants +", " +chatRoomModel+", "+conferenceModel + ", "+conferenceModel.localParticipant +", " +conferenceModel.localParticipant.adminStatus)
SmartSearchBar {
id: smartSearchBar

View file

@ -1,123 +0,0 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// =============================================================================
// Contains linphone helpers.
// =============================================================================
.pragma library
.import Linphone 1.0 as Linphone
.import UtilsCpp 1.0 as UtilsCpp
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
// Contact/SIP address helpers.
// =============================================================================
function _getDisplayNameFromQuotedString (str) {
var start = str.indexOf('"')
if (start === -1) {
return
}
var end = str.lastIndexOf('"')
if (end === -1 || start === end) {
return
}
return str.substring(start + 1, end)
}
function _getDisplayNameFromString (str) {
var end = str.indexOf('<')
if (end === -1) {
return
}
return str.substring(0, end).trim() || undefined
}
function _getDisplayName (str) {
var name = _getDisplayNameFromQuotedString(str)
if (name != null) {
return name
}
return _getDisplayNameFromString(str)
}
// -----------------------------------------------------------------------------
function _getUsername (str) {
var start = str.indexOf('sip')
if (start === -1) {
return
}
start += 4 + Number(str.charAt(start + 4) === ':') // Deal with `sip:` and `sips:`
var end = str.indexOf('@', start + 1)
if (end === -1) {
return Utils.decode(str.substring(start))
}
return Utils.decode(str.substring(start, end))
}
// =============================================================================
// Codec helpers.
// =============================================================================
function openCodecOnlineInstallerDialog (window, codecInfo, cb) {
var VideoCodecsModel = Linphone.VideoCodecsModel
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
descriptionText: qsTr('downloadCodecDescription')
.replace('%1', codecInfo.mime)
.replace('%2', codecInfo.encoderDescription)
}, function (status) {
if (status) {
window.attachVirtualWindow(buildDialogUri('OnlineInstallerDialog'), {
downloadUrl: codecInfo.downloadUrl,
extract: true,
installFolder: VideoCodecsModel.codecsFolder,
installName: codecInfo.installName,
mime: codecInfo.mime
}, function (status) {
if (status) {
VideoCodecsModel.reload()
}
if (cb) {
cb(window)
}
})
}
else if (cb) {
cb(window)
}
})
}
// =============================================================================
// QML helpers.
// =============================================================================
function buildDialogUri (component) {
return 'qrc:/ui/modules/Linphone/Dialog/' + component + '.qml'
}

View file

@ -1,3 +0,0 @@
module LinphoneUtils
LinphoneUtils 1.0 linphone-utils.js

View file

@ -41,10 +41,18 @@ var SCHEME_REGEX = new RegExp('^[^:]+:')
// QML helpers.
// =============================================================================
function buildDialogUri (component) {
function buildCommonDialogUri (component) {
return 'qrc:/ui/modules/Common/Dialog/' + component + '.qml'
}
function buildLinphoneDialogUri (component) {
return 'qrc:/ui/modules/Linphone/Dialog/' + component + '.qml'
}
function buildAppDialogUri (component) {
return 'qrc:/ui/views/App/Dialog/' + component + '.qml'
}
// -----------------------------------------------------------------------------
// Destroy timeout.
@ -708,4 +716,35 @@ function computeAvatarSize (container, maxSize) {
var size = height < maxSize && height > 0 ? height : maxSize
return size < width ? size : width
}
// -----------------------------------------------------------------------------
function openCodecOnlineInstallerDialog (window, codecInfo, cb) {
var VideoCodecsModel = Linphone.VideoCodecsModel
window.attachVirtualWindow(buildLinphoneDialogUri('ConfirmDialog'), {
descriptionText: qsTr('downloadCodecDescription')
.replace('%1', codecInfo.mime)
.replace('%2', codecInfo.encoderDescription)
}, function (status) {
if (status) {
window.attachVirtualWindow(buildCommonDialogUri('OnlineInstallerDialog'), {
downloadUrl: codecInfo.downloadUrl,
extract: true,
installFolder: VideoCodecsModel.codecsFolder,
installName: codecInfo.installName,
mime: codecInfo.mime
}, function (status) {
if (status) {
VideoCodecsModel.reload()
}
if (cb) {
cb(window)
}
})
}
else if (cb) {
cb(window)
}
})
}

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0
@ -18,6 +17,7 @@ Rectangle {
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress)
property alias showKeypad :telKeypadButton.visible
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
// ---------------------------------------------------------------------------
color: CallStyle.backgroundColor
@ -44,7 +44,7 @@ Rectangle {
height: CallStyle.header.contactDescription.height
horizontalTextAlignment: Text.AlignHCenter
sipAddress: call.peerAddress
username: UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress)
username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
width: contentWidth
}
@ -84,7 +84,7 @@ Rectangle {
anchors.centerIn: parent
backgroundColor: CallStyle.container.avatar.backgroundColor
image: _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar
image: _sipAddressObserver && _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar
username: contactDescription.username
height: _computeAvatarSize()

View file

@ -36,7 +36,7 @@ function handleClosing (close) {
return
}
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('acceptClosingDescription')
}, function (status) {
if (status) {

View file

@ -4,7 +4,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0
@ -130,6 +129,7 @@ Rectangle {
spacing: ConferenceStyle.grid.cell.spacing
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
ContactDescription {
id: contactDescription
@ -138,7 +138,7 @@ Rectangle {
horizontalTextAlignment: Text.AlignHCenter
sipAddress: parent.sipAddress
username: UtilsCpp.getDisplayName(parent._sipAddressObserver.peerAddress)
username: parent._sipAddressObserver ? UtilsCpp.getDisplayName(parent._sipAddressObserver.peerAddress) : ''
}
IncallAvatar {

View file

@ -48,6 +48,7 @@ DialogPlus {
Layout.fillWidth: true
entry: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '')
Component.onDestruction: entry=null// Need to set it to null because of not calling destructor if not.
}
// -------------------------------------------------------------------------

View file

@ -2,7 +2,6 @@ import QtQuick 2.7
import QtQuick.Layouts 1.3
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import UtilsCpp 1.0
@ -20,6 +19,8 @@ Rectangle {
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '')
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
// ---------------------------------------------------------------------------
color: CallStyle.backgroundColor
@ -39,8 +40,8 @@ Rectangle {
Layout.preferredHeight: CallStyle.header.contactDescription.height
horizontalTextAlignment: Text.AlignHCenter
sipAddress: _sipAddressObserver.peerAddress
username: UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress)
sipAddress: _sipAddressObserver && _sipAddressObserver.peerAddress
username: _sipAddressObserver ? UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress) : ''
}
Text {
@ -66,7 +67,7 @@ Rectangle {
Avatar {
anchors.centerIn: parent
backgroundColor: CallStyle.container.avatar.backgroundColor
image: _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar
image: _sipAddressObserver && _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar
username: contactDescription.username
height: Utils.computeAvatarSize(container, CallStyle.container.avatar.maxSize)

View file

@ -90,7 +90,7 @@ function handleVideoRequested (call) {
call.statusChanged.connect(endedHandler)
console.log("D")
// Ask video to user.
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('acceptVideoDescription'),
}, function (status) {
//Utils.clearTimeout(timeout)

View file

@ -5,7 +5,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import UtilsCpp 1.0
@ -34,6 +33,8 @@ Rectangle {
property bool isFullScreen: false // Use this variable to test if we are in fullscreen. Do not test _fullscreen : we need to clean memory before having the window (see .js file)
property var _fullscreen: null
on_FullscreenChanged: if( !_fullscreen) isFullScreen = false
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
// ---------------------------------------------------------------------------
color: CallStyle.backgroundColor
@ -143,7 +144,7 @@ Rectangle {
anchors.centerIn: parent
horizontalTextAlignment: Text.AlignHCenter
sipAddress: _sipAddressObserver.peerAddress
sipAddress: _sipAddressObserver && _sipAddressObserver.peerAddress
username: UtilsCpp.getDisplayName(sipAddress)
height: parent.height

View file

@ -7,7 +7,6 @@ import Common 1.0
import Common.Styles 1.0
import DesktopTools 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import App.Styles 1.0

View file

@ -6,7 +6,6 @@ import QtGraphicalEffects 1.12
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
import UtilsCpp 1.0
@ -376,7 +375,13 @@ Rectangle {
isCustom: true
backgroundRadius: width/2
colorSet: VideoConferenceStyle.buttons.participants
visible: false // TODO
toggled: rightMenu.visible && rightMenu.isParticipantsMenu
onClicked: {
if(toggled)
rightMenu.visible = false
else
rightMenu.showParticipantsMenu()
}
}
ActionButton {
id: callQuality

View file

@ -6,7 +6,6 @@ import QtGraphicalEffects 1.12
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0

View file

@ -6,7 +6,6 @@ import QtGraphicalEffects 1.12
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import DesktopTools 1.0
import LinphoneEnums 1.0

View file

@ -6,7 +6,6 @@ import QtGraphicalEffects 1.12
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import UtilsCpp 1.0

View file

@ -4,7 +4,6 @@ import QtQuick.Controls 2.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
@ -21,6 +20,7 @@ DialogPlus {
property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{
property bool isNew: true
}
onConferenceInfoModelChanged: if( conferenceInfoModel && !conferenceInfoModel.isNew) selectedParticipants.setAddresses(conferenceInfoModel)
Connections{
target: conferenceInfoModel
onConferenceCreated: {
@ -484,7 +484,7 @@ DialogPlus {
anchors.fill: parent
showContactAddress:false
showSwitch : true
showSwitch : conferenceInfoModel.isNew
showSeparator: false
isSelectable: false
showInvitingIndicator: false
@ -512,7 +512,6 @@ DialogPlus {
model: ParticipantProxyModel {
id:selectedParticipants
chatRoomModel:null
}
onEntryClicked: actions[0].handler(entry)
}

View file

@ -2,7 +2,7 @@ import QtQuick 2.7
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import App.Styles 1.0
@ -57,7 +57,7 @@ AssistantAbstractView {
}
var codecInfo = VideoCodecsModel.getCodecInfo('H264')
if (codecInfo.downloadUrl) {
LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome)
Utils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome)
} else {
quitToHome(window)
}

View file

@ -2,7 +2,7 @@ import QtQuick 2.7
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import App.Styles 1.0
@ -69,7 +69,7 @@ AssistantAbstractView {
}
var codecInfo = VideoCodecsModel.getCodecInfo('H264')
if (codecInfo.downloadUrl) {
LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome)
Utils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome)
} else {
quitToHome(window)
}

View file

@ -25,7 +25,7 @@ Item{
onRemoteProvisioningChanged: {
requestBlock.stop('')
window.detachVirtualWindow()
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('remoteProvisioningUpdateDescription'),
}, function (status) {
if (status) {

View file

@ -2,7 +2,7 @@ import QtQuick 2.7
import Common 1.0
import Linphone 1.0
import LinphoneUtils 1.0
import Utils 1.0
import ConstantsCpp 1.0
import App.Styles 1.0
@ -112,7 +112,7 @@ AssistantAbstractView {
if (!error.length) {
var codecInfo = VideoCodecsModel.getCodecInfo('H264')
if (codecInfo.downloadUrl) {
LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, function cb (window) {
Utils.openCodecOnlineInstallerDialog(window, codecInfo, function cb (window) {
window.setView('Home')
})
} else {

View file

@ -10,190 +10,204 @@ import LinphoneEnums 1.0
import App.Styles 1.0
// =============================================================================
Item{
ColumnLayout {
id: mainItem
property int filterType: -1
spacing: 0
Component.onCompleted: filterType = ConferenceInfoProxyModel.Scheduled
// ---------------------------------------------------------------------------
// Title
// ---------------------------------------------------------------------------
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: ConferencesStyle.bar.height
ColumnLayout {
id: mainItem
property int filterType: -1
spacing: 0
Component.onCompleted: filterType = ConferenceInfoProxyModel.Scheduled
anchors.fill: parent
// ---------------------------------------------------------------------------
// Title
// ---------------------------------------------------------------------------
color: ConferencesStyle.bar.backgroundColor
Text{
anchors.fill: parent
verticalAlignment: Qt.AlignVCenter
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: ConferencesStyle.bar.height
anchors.leftMargin: 40
color: ConferencesStyle.bar.text.color
font {
bold: true
pointSize: ConferencesStyle.bar.text.pointSize
color: ConferencesStyle.bar.backgroundColor
Text{
anchors.fill: parent
verticalAlignment: Qt.AlignVCenter
anchors.leftMargin: 40
color: ConferencesStyle.bar.text.color
font {
bold: true
pointSize: ConferencesStyle.bar.text.pointSize
}
text: 'Mes conférences'
}
text: 'Mes conférences'
}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: ConferencesStyle.bar.height
color: 'white'
RowLayout {
anchors {
fill: parent
leftMargin: ConferencesStyle.bar.leftMargin
rightMargin: ConferencesStyle.bar.rightMargin
}
spacing: ConferencesStyle.spacing
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: ConferencesStyle.bar.height
ExclusiveButtons {
texts: [
'TERMINEES',
'PROGRAMMEES',
'INVITATIONS',
'TEST'
]
selectedButton: mainItem.filterType
onClicked: {
if(button <= 2)
mainItem.filterType = (button === 0 ? ConferenceInfoProxyModel.Ended : button === 1 ?ConferenceInfoProxyModel.Scheduled : ConferenceInfoProxyModel.Invitations);
else {
window.detachVirtualWindow()
window.attachVirtualWindow(Qt.resolvedUrl('../Calls/VideoConferenceMenu.qml'))
color: 'white'
RowLayout {
anchors {
fill: parent
leftMargin: ConferencesStyle.bar.leftMargin
rightMargin: ConferencesStyle.bar.rightMargin
}
spacing: ConferencesStyle.spacing
ExclusiveButtons {
texts: [
'TERMINEES',
'PROGRAMMEES',
'INVITATIONS',
'TEST'
]
selectedButton: mainItem.filterType
onClicked: {
if(button <= 2)
mainItem.filterType = (button === 0 ? ConferenceInfoProxyModel.Ended : button === 1 ?ConferenceInfoProxyModel.Scheduled : ConferenceInfoProxyModel.Invitations);
else {
window.detachVirtualWindow()
window.attachVirtualWindow(Qt.resolvedUrl('../Calls/VideoConferenceMenu.qml'))
}
//mainItem.filterType = button
}
//mainItem.filterType = button
}
}
}
}
// ---------------------------------------------------------------------------
// Conferences list.
// ---------------------------------------------------------------------------
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: ConferencesStyle.backgroundColor
ScrollableListView {
anchors.fill: parent
spacing: 10
// ---------------------------------------------------------------------------
// Conferences list.
// ---------------------------------------------------------------------------
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: ConferencesStyle.backgroundColor
highlightFollowsCurrentItem: false
section {
criteria: ViewSection.FullString
delegate: sectionHeading
property: '$modelKey'
}
model: ConferenceInfoProxyModel{
id: conferencesProxyModel
filterType: mainItem.filterType
}
// -----------------------------------------------------------------------
// Heading.
// -----------------------------------------------------------------------
Component {
id: sectionHeading
ScrollableListView {
anchors.fill: parent
spacing: 10
Item {
implicitHeight: container.height + ConferencesStyle.sectionHeading.bottomMargin
width: parent.width
highlightFollowsCurrentItem: false
section {
criteria: ViewSection.FullString
delegate: sectionHeading
property: '$modelKey'
}
model: ConferenceInfoProxyModel{
id: conferencesProxyModel
filterType: mainItem.filterType
}
// -----------------------------------------------------------------------
// Heading.
// -----------------------------------------------------------------------
Component {
id: sectionHeading
Borders {
id: container
borderColor: ConferencesStyle.sectionHeading.border.color
bottomWidth: ConferencesStyle.sectionHeading.border.width
implicitHeight: text.contentHeight +
ConferencesStyle.sectionHeading.padding * 2 +
ConferencesStyle.sectionHeading.border.width * 2
topWidth: ConferencesStyle.sectionHeading.border.width
Item {
implicitHeight: container.height + ConferencesStyle.sectionHeading.bottomMargin
width: parent.width
Text {
id: text
Borders {
id: container
anchors.fill: parent
color: ConferencesStyle.sectionHeading.text.color
font {
bold: true
pointSize: ConferencesStyle.sectionHeading.text.pointSize
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// Cast section to integer because Qt converts the
// sectionDate in string!!!
text: new Date(section).toLocaleDateString(
Qt.locale(App.locale)
)
}
}
}
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
delegate: Item {
implicitHeight: calendarGrid.height + ConferencesStyle.conference.bottomMargin
anchors {
left: parent ? parent.left : undefined
leftMargin: 10
right: parent ? parent.right : undefined
rightMargin: 10
}
GridView{
id: calendarGrid
property bool expanded : false //anchors.fill: parent
cellWidth: width/2
cellHeight: expanded ? 300 : 100
model: $modelData
height: cellHeight * ( (count+1) /2)
width: mainItem.width - 20
delegate:Rectangle {
id: entry
width: calendarGrid.cellWidth-10
height: calendarGrid.cellHeight-10
radius: 6
color: mainItem.filterType == ConferenceInfoProxyModel.Ended ? ConferencesStyle.conference.backgroundColor.ended
: ConferencesStyle.conference.backgroundColor.scheduled
border.color: calendarMessage.containsMouse || calendarMessage.isExpanded ? ConferencesStyle.conference.selectedBorder.color : 'transparent'
border.width: ConferencesStyle.conference.selectedBorder.width
ChatCalendarMessage{
id: calendarMessage
anchors.centerIn: parent
borderColor: ConferencesStyle.sectionHeading.border.color
bottomWidth: ConferencesStyle.sectionHeading.border.width
implicitHeight: text.contentHeight +
ConferencesStyle.sectionHeading.padding * 2 +
ConferencesStyle.sectionHeading.border.width * 2
topWidth: ConferencesStyle.sectionHeading.border.width
width: parent.width
height: parent.height
conferenceInfoModel: $modelData
//width: calendarGrid.cellWidth
//maxWidth: calendarGrid.cellWidth
gotoButtonMode: mainItem.filterType == ConferenceInfoProxyModel.Scheduled ? 1
: mainItem.filterType == ConferenceInfoProxyModel.Ended ? -1
: 0
onExpandToggle: calendarGrid.expanded = !calendarGrid.expanded
isExpanded: calendarGrid.expanded
Text {
id: text
anchors.fill: parent
color: ConferencesStyle.sectionHeading.text.color
font {
bold: true
pointSize: ConferencesStyle.sectionHeading.text.pointSize
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// Cast section to integer because Qt converts the
// sectionDate in string!!!
text: new Date(section).toLocaleDateString(
Qt.locale(App.locale)
)
}
}
}
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
delegate: Item {
implicitHeight: calendarGrid.height + ConferencesStyle.conference.bottomMargin
anchors {
left: parent ? parent.left : undefined
leftMargin: 10
right: parent ? parent.right : undefined
rightMargin: 10
}
GridView{
id: calendarGrid
property bool expanded : false //anchors.fill: parent
cellWidth: width/2
cellHeight: expanded ? 300 : 100
model: $modelData
height: cellHeight * ( (count+1) /2)
width: mainItem.width - 20
delegate:Rectangle {
id: entry
width: calendarGrid.cellWidth-10
height: calendarGrid.cellHeight-10
radius: 6
color: mainItem.filterType == ConferenceInfoProxyModel.Ended ? ConferencesStyle.conference.backgroundColor.ended
: ConferencesStyle.conference.backgroundColor.scheduled
border.color: calendarMessage.containsMouse || calendarMessage.isExpanded ? ConferencesStyle.conference.selectedBorder.color : 'transparent'
border.width: ConferencesStyle.conference.selectedBorder.width
ChatCalendarMessage{
id: calendarMessage
anchors.centerIn: parent
width: parent.width
height: parent.height
conferenceInfoModel: $modelData
//width: calendarGrid.cellWidth
//maxWidth: calendarGrid.cellWidth
gotoButtonMode: mainItem.filterType == ConferenceInfoProxyModel.Scheduled ? 1
: mainItem.filterType == ConferenceInfoProxyModel.Ended ? -1
: 0
onExpandToggle: calendarGrid.expanded = !calendarGrid.expanded
isExpanded: calendarGrid.expanded
onConferenceUriCopied: messageBanner.noticeBannerText = 'Conference URL has been copied'
}
}
}
}
}
}
}
MessageBanner{
id: messageBanner
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 25
height: fitHeight
}
}

View file

@ -25,7 +25,6 @@
.import UtilsCpp 1.0 as UtilsCpp
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
// =============================================================================
@ -74,7 +73,7 @@ function editContact () {
}
function removeContact () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('removeContactDescription'),
}, function (status) {
if (status) {

View file

@ -27,10 +27,12 @@ ColumnLayout {
property var _contact
property var _vcard
// ---------------------------------------------------------------------------
spacing: 0
Component.onDestruction: {_vcard=null}// Need to set it to null because of not calling destructor if not.
Component.onCompleted:{
var sipAddress = contactEdit.sipAddress
var contact = contactEdit._contact = SipAddressesModel.mapSipAddressToContact(

View file

@ -13,7 +13,7 @@ import App.Styles 1.0
ColumnLayout {
function _removeContact (contact) {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('removeContactDescription'),
}, function (status) {
if (status) {

View file

@ -24,13 +24,12 @@
.import Linphone 1.0 as Linphone
.import UtilsCpp 1.0 as UtilsCpp
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
function removeAllEntries () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('removeAllEntriesDescription'),
}, function (status) {
if (status) {
@ -40,12 +39,12 @@ function removeAllEntries () {
}
function getAvatar () {
var contact = conversation._sipAddressObserver.contact
var contact = conversation._sipAddressObserver ? conversation._sipAddressObserver.contact : null
return contact ? contact.vcard.avatar : ''
}
function getEditTooltipText() {
return conversation._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd')
return conversation._sipAddressObserver && conversation._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd')
}
function updateChatFilter (button) {

View file

@ -36,7 +36,7 @@ ColumnLayout {
property int securityLevel : chatRoomModel ? chatRoomModel.securityLevel : 1
readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), (fullLocalAddress?fullLocalAddress:localAddress))
property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), (fullLocalAddress?fullLocalAddress:localAddress))
property bool haveMoreThanOneParticipants: chatRoomModel ? chatRoomModel.participants.count > 2 : false
property bool haveLessThanMinParticipantsForCall: chatRoomModel ? chatRoomModel.participants.count <= 5 : false
@ -57,6 +57,7 @@ ColumnLayout {
spacing: 0
clip:false
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
// ---------------------------------------------------------------------------
// Contact bar.
// ---------------------------------------------------------------------------
@ -88,7 +89,7 @@ ColumnLayout {
presenceLevel: chatRoomModel.presenceStatus
//username: Logic.getUsername()
username: chatRoomModel?chatRoomModel.username:UtilsCpp.getDisplayName(conversation._sipAddressObserver.peerAddress)
username: chatRoomModel?chatRoomModel.username:( conversation._sipAddressObserver ? UtilsCpp.getDisplayName(conversation._sipAddressObserver.peerAddress) : '')
visible: !groupChat.visible
}
@ -308,7 +309,7 @@ ColumnLayout {
ActionButton {
isCustom: true
backgroundRadius: 4
colorSet: conversation._sipAddressObserver.contact ? ConversationStyle.bar.actions.edit.viewContact : ConversationStyle.bar.actions.edit.addContact
colorSet: conversation._sipAddressObserver && conversation._sipAddressObserver.contact ? ConversationStyle.bar.actions.edit.viewContact : ConversationStyle.bar.actions.edit.addContact
visible: SettingsModel.contactsEnabled && !conversation.chatRoomModel.groupEnabled
onClicked: window.setView('ContactEdit', {

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0

View file

@ -3,7 +3,6 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0

View file

@ -5,7 +5,6 @@ import Common 1.0
import Linphone 1.0
import Utils 1.0
import UtilsCpp 1.0
import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
@ -149,6 +148,7 @@ DialogPlus {
interactive: false
model: $modelData.getProxyDevices()
Component.onDestruction: {model=null}// Need to set it to null because of not calling destructor if not.
delegate: Rectangle{
id:mainRectangle

View file

@ -24,13 +24,12 @@
.import Linphone 1.0 as Linphone
.import UtilsCpp 1.0 as UtilsCpp
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
function removeAllEntries () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('removeAllEntriesDescription'),
}, function (status) {
if (status) {

View file

@ -17,13 +17,13 @@ ColumnLayout {
property string peerAddress
property string fullPeerAddress
readonly property var _sipAddressObserver: peerAddress?SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), ''):null
property var _sipAddressObserver: peerAddress?SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), ''):null
// ---------------------------------------------------------------------------
spacing: 0
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
// ---------------------------------------------------------------------------
// Contact bar.
// ---------------------------------------------------------------------------
@ -50,17 +50,13 @@ ColumnLayout {
Layout.preferredHeight: HistoryViewStyle.bar.avatarSize
Layout.preferredWidth: HistoryViewStyle.bar.avatarSize
image: peerAddress ?
(historyView._sipAddressObserver.contact
? historyView._sipAddressObserver.contact
: null)
:null
image: peerAddress && historyView._sipAddressObserver && historyView._sipAddressObserver.contact? historyView._sipAddressObserver.contact.avatar : null
presenceLevel: historyView._sipAddressObserver?Presence.getPresenceLevel(
historyView._sipAddressObserver.presenceStatus
):null
username: peerAddress? UtilsCpp.getDisplayName(historyView._sipAddressObserver.peerAddress):null
username: peerAddress && historyView._sipAddressObserver? UtilsCpp.getDisplayName(historyView._sipAddressObserver.peerAddress):null
visible:peerAddress
}

View file

@ -77,7 +77,7 @@ function setView (view, props, callback) {
apply(view, props, false, callback)
return
}
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: lockedInfo.descriptionText,
}, function (status) {
if (status) {

View file

@ -11,6 +11,7 @@ import App.Styles 1.0
import ColorsList 1.0
import 'MainWindow.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@ -226,7 +227,7 @@ ApplicationWindow {
//onClicked: Logic.openConferenceManager()
onClicked: {
window.detachVirtualWindow()
window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/NewConference.qml')
window.attachVirtualWindow(Utils.buildAppDialogUri('NewConference')
,{})
}
}

View file

@ -34,7 +34,7 @@ function editLdap (ldap) {
}
function cleanLogs () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('cleanLogsDescription'),
}, function (status) {
if (status) {

View file

@ -34,7 +34,7 @@ function editAccount (account) {
}
function deleteAccount (account) {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('deleteAccountDescription'),
}, function (status) {
if (status) {
@ -44,7 +44,7 @@ function deleteAccount (account) {
}
function eraseAllPasswords () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('eraseAllPasswordsDescription'),
}, function (status) {
if (status) {

View file

@ -183,7 +183,7 @@ TabContainer {
id: view
property TunnelModel tunnelModel : SettingsModel.getTunnel()
property TunnelConfigProxyModel tunnelConfigProxyModel: tunnelModel.getTunnelProxyConfigs()
Component.onDestruction: {tunnelConfigProxyModel=null}// Need to set it to null because of not calling destructor if not.
width: parent.width
model: tunnelConfigProxyModel
delegate:

View file

@ -28,7 +28,7 @@
// =============================================================================
function cleanAvatars () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('cleanAvatarsDescription'),
}, function (status) {
if (status) {
@ -62,7 +62,7 @@ function setLocale (locale) {
App.configLocale = locale
window.detachVirtualWindow()
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('setLocaleDescription'),
}, function (status) {
if (status) {

View file

@ -23,7 +23,7 @@
.import Linphone 1.0 as Linphone
.import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@ -46,5 +46,5 @@ function hideVideoPreview () {
}
function handleCodecDownloadRequested (codecInfo) {
LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo)
Utils.openCodecOnlineInstallerDialog(window, codecInfo)
}

View file

@ -378,9 +378,11 @@ QtObject {
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_inv_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_inv_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_inv_bg').color
property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, 'me_c_b_inv_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_inv_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_inv_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_inv_fg').color
property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 'me_c_b_inv_fg').color
}
property QtObject callQuality: QtObject {
property int iconSize: 20

View file

@ -18,6 +18,10 @@ singleton CallTransferStyle 1.0 Calls/Dialogs/CallT
singleton ConferenceManagerStyle 1.0 Calls/Dialogs/ConferenceManagerStyle.qml
singleton MultimediaParametersStyle 1.0 Calls/Dialogs/MultimediaParametersStyle.qml
# Dialog Window ------------------------------------------------------------------
singleton NewConferenceStyle 1.0 Dialog/NewConferenceStyle.qml
# Main Window ------------------------------------------------------------------
singleton ActivateAppSipAccountWithEmailStyle 1.0 Main/Assistant/ActivateAppSipAccountWithEmailStyle.qml
@ -44,7 +48,6 @@ singleton InfoChatRoomStyle 1.0 Main/Dialogs/InfoCh
singleton InfoEncryptionStyle 1.0 Main/Dialogs/InfoEncryptionStyle.qml
singleton ManageAccountsStyle 1.0 Main/Dialogs/ManageAccountsStyle.qml
singleton NewChatRoomStyle 1.0 Main/Dialogs/NewChatRoomStyle.qml
singleton NewConferenceStyle 1.0 Main/Dialogs/NewConferenceStyle.qml
singleton ParticipantsDevicesStyle 1.0 Main/Dialogs/ParticipantsDevicesStyle.qml

View file

@ -0,0 +1,10 @@
# ==============================================================================
# App's components to export.
# ==============================================================================
module App
# Components -------------------------------------------------------------------
NewConference 1.0 Dialog/NewConference.qml

@ -1 +1 @@
Subproject commit 9c69668a42189b54530a83b9263cfa2ad4149cf9
Subproject commit 0bf934b0669e77ddecfcd8298ea615bb998aa28a