diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e5b4002..1bb35818 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,7 +74,8 @@ set(COMMON_SOURCES
${SRC_DIR}/moderatorlistmodel.cpp
${SRC_DIR}/screensaver.cpp
${SRC_DIR}/systemtray.cpp
- ${SRC_DIR}/appsettingsmanager.cpp)
+ ${SRC_DIR}/appsettingsmanager.cpp
+ ${SRC_DIR}/lrcinstance.cpp)
set(COMMON_HEADERS
${SRC_DIR}/avatarimageprovider.h
@@ -86,7 +87,6 @@ set(COMMON_HEADERS
${SRC_DIR}/version.h
${SRC_DIR}/accountlistmodel.h
${SRC_DIR}/runguard.h
- ${SRC_DIR}/lrcinstance.h
${SRC_DIR}/webchathelpers.h
${SRC_DIR}/rendermanager.h
${SRC_DIR}/connectivitymonitor.h
@@ -127,7 +127,8 @@ set(COMMON_HEADERS
${SRC_DIR}/moderatorlistmodel.h
${SRC_DIR}/screensaver.h
${SRC_DIR}/systemtray.h
- ${SRC_DIR}/appsettingsmanager.h)
+ ${SRC_DIR}/appsettingsmanager.h
+ ${SRC_DIR}/lrcinstance.h)
find_package(PkgConfig REQUIRED)
diff --git a/jami-qt.pro b/jami-qt.pro
index 5ad3e8ff..9f0417c6 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -104,7 +104,6 @@ HEADERS += \
src/version.h \
src/accountlistmodel.h \
src/runguard.h \
- src/lrcinstance.h \
src/webchathelpers.h \
src/rendermanager.h \
src/connectivitymonitor.h \
@@ -139,7 +138,8 @@ HEADERS += \
src/qtutils.h \
src/utilsadapter.h \
src/systemtray.h \
- src/appsettingsmanager.h
+ src/appsettingsmanager.h \
+ src/lrcinstance.h
SOURCES += \
src/bannedlistmodel.cpp \
@@ -181,7 +181,8 @@ SOURCES += \
src/qmlregister.cpp \
src/utilsadapter.cpp \
src/systemtray.cpp \
- src/appsettingsmanager.cpp
+ src/appsettingsmanager.cpp \
+ src/lrcinstance.cpp
RESOURCES += \
resources.qrc \
diff --git a/qml.qrc b/qml.qrc
index dc35418b..1f5a159b 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -1,6 +1,40 @@
+ src/MainApplicationWindow.qml
+ src/DaemonReconnectWindow.qml
+ src/constant/JamiQmlUtils.qml
src/constant/JamiStrings.qml
+ src/constant/JamiTheme.qml
+ src/commoncomponents/SettingParaCombobox.qml
+ src/commoncomponents/PreferenceItemDelegate.qml
+ src/commoncomponents/PasswordDialog.qml
+ src/commoncomponents/MaterialLineEdit.qml
+ src/commoncomponents/PhotoboothView.qml
+ src/commoncomponents/LookupStatusLabel.qml
+ src/commoncomponents/ListViewJami.qml
+ src/commoncomponents/DeleteAccountDialog.qml
+ src/commoncomponents/CustomBorder.qml
+ src/commoncomponents/PushButton.qml
+ src/commoncomponents/JamiFileDialog.qml
+ src/commoncomponents/TintedButton.qml
+ src/commoncomponents/GeneralMenuItem.qml
+ src/commoncomponents/GeneralMenuSeparator.qml
+ src/commoncomponents/AccountMigrationDialog.qml
+ src/commoncomponents/MaterialButton.qml
+ src/commoncomponents/ElidedTextLabel.qml
+ src/commoncomponents/js/contextmenugenerator.js
+ src/commoncomponents/BaseContextMenu.qml
+ src/commoncomponents/SpinnerButton.qml
+ src/commoncomponents/UsernameLineEdit.qml
+ src/commoncomponents/Scaffold.qml
+ src/commoncomponents/LineEditContextMenu.qml
+ src/commoncomponents/BaseDialog.qml
+ src/commoncomponents/ModalPopup.qml
+ src/commoncomponents/SimpleMessageDialog.qml
+ src/commoncomponents/ResponsiveImage.qml
+ src/commoncomponents/PresenceIndicator.qml
+ src/commoncomponents/AvatarImage.qml
+ src/commoncomponents/DaemonReconnectPopup.qml
src/settingsview/SettingsView.qml
src/settingsview/components/ChatviewSettings.qml
src/settingsview/components/SettingsMenu.qml
@@ -42,22 +76,13 @@
src/settingsview/components/SettingsComboBox.qml
src/settingsview/components/SettingsMaterialLineEdit.qml
src/settingsview/components/LevelMeter.qml
- src/commoncomponents/SettingParaCombobox.qml
src/settingsview/components/DeviceItemDelegate.qml
src/settingsview/components/PluginItemDelegate.qml
- src/mainview/components/PluginHandlerItemDelegate.qml
- src/commoncomponents/PreferenceItemDelegate.qml
src/settingsview/components/ContactItemDelegate.qml
src/settingsview/components/MediaCodecDelegate.qml
src/settingsview/components/NameRegistrationDialog.qml
src/settingsview/components/LinkDeviceDialog.qml
src/settingsview/components/RevokeDevicePasswordDialog.qml
- src/commoncomponents/PasswordDialog.qml
- src/commoncomponents/MaterialLineEdit.qml
- src/commoncomponents/PhotoboothView.qml
- src/commoncomponents/LookupStatusLabel.qml
- src/commoncomponents/ListViewJami.qml
- src/commoncomponents/DeleteAccountDialog.qml
src/wizardview/WizardView.qml
src/wizardview/components/WelcomePage.qml
src/wizardview/components/CreateAccountPage.qml
@@ -68,27 +93,22 @@
src/wizardview/components/ConnectToAccountManagerPage.qml
src/wizardview/components/ProfilePage.qml
src/wizardview/components/CollapsiblePasswordWidget.qml
- src/MainApplicationWindow.qml
+ src/wizardview/components/AccountCreationStepIndicator.qml
src/mainview/MainView.qml
- src/commoncomponents/CustomBorder.qml
- src/constant/JamiTheme.qml
+ src/mainview/components/PluginHandlerItemDelegate.qml
src/mainview/components/AboutPopUp.qml
src/mainview/components/SidePanel.qml
src/mainview/components/WelcomePage.qml
src/mainview/components/MessageWebView.qml
src/mainview/components/MessageWebViewHeader.qml
- src/commoncomponents/PushButton.qml
src/mainview/components/AccountComboBox.qml
src/mainview/components/ConversationSmartListView.qml
- src/commoncomponents/JamiFileDialog.qml
src/mainview/components/CallStackView.qml
src/mainview/components/IncomingCallPage.qml
src/mainview/components/OutgoingCallPage.qml
src/mainview/components/AudioCallPage.qml
src/mainview/components/CallOverlay.qml
- src/commoncomponents/TintedButton.qml
src/mainview/components/CallOverlayButtonGroup.qml
- src/mainview/js/incomingcallpagecreation.js
src/mainview/components/ContactSearchBar.qml
src/mainview/components/VideoCallPage.qml
src/mainview/components/ParticipantOverlay.qml
@@ -97,46 +117,26 @@
src/mainview/components/ConversationSmartListViewItemDelegate.qml
src/mainview/components/SidePanelTabBar.qml
src/mainview/components/WelcomePageQrDialog.qml
- src/commoncomponents/GeneralMenuItem.qml
src/mainview/components/ConversationSmartListContextMenu.qml
src/mainview/components/CallViewContextMenu.qml
- src/commoncomponents/GeneralMenuSeparator.qml
src/mainview/components/UserProfile.qml
- src/mainview/js/videodevicecontextmenuitemcreation.js
src/mainview/components/VideoCallPageContextMenuDeviceItem.qml
src/mainview/components/SelectScreen.qml
- src/mainview/js/selectscreenwindowcreation.js
src/mainview/components/ScreenRubberBand.qml
- src/mainview/js/screenrubberbandcreation.js
- src/mainview/js/callfullscreenwindowcontainercreation.js
src/mainview/components/VideoCallFullScreenWindowContainer.qml
src/mainview/components/ContactPicker.qml
src/mainview/components/PluginHandlerPicker.qml
+ src/mainview/components/ContactPickerItemDelegate.qml
+ src/mainview/components/RecordBox.qml
+ src/mainview/components/SipInputPanel.qml
+ src/mainview/components/ParticipantOverlayMenu.qml
+ src/mainview/components/UserInfoCallPage.qml
+ src/mainview/js/videodevicecontextmenuitemcreation.js
+ src/mainview/js/incomingcallpagecreation.js
+ src/mainview/js/selectscreenwindowcreation.js
+ src/mainview/js/screenrubberbandcreation.js
+ src/mainview/js/callfullscreenwindowcontainercreation.js
src/mainview/js/contactpickercreation.js
src/mainview/js/pluginhandlerpickercreation.js
- src/mainview/components/ContactPickerItemDelegate.qml
- src/commoncomponents/AccountMigrationDialog.qml
- src/commoncomponents/MaterialButton.qml
- src/mainview/components/RecordBox.qml
- src/commoncomponents/ElidedTextLabel.qml
- src/mainview/components/SipInputPanel.qml
- src/commoncomponents/js/contextmenugenerator.js
- src/commoncomponents/BaseContextMenu.qml
- src/commoncomponents/Scaffold.qml
- src/constant/JamiQmlUtils.qml
- src/wizardview/components/AccountCreationStepIndicator.qml
- src/commoncomponents/SpinnerButton.qml
- src/commoncomponents/UsernameLineEdit.qml
- src/mainview/components/UserInfoCallPage.qml
- src/commoncomponents/BaseDialog.qml
- src/commoncomponents/ModalPopup.qml
- src/commoncomponents/SimpleMessageDialog.qml
- src/commoncomponents/ResponsiveImage.qml
- src/commoncomponents/PresenceIndicator.qml
- src/commoncomponents/AvatarImage.qml
- src/mainview/components/ParticipantOverlayMenu.qml
- src/commoncomponents/DaemonReconnectPopup.qml
- src/DaemonReconnectWindow.qml
- src/commoncomponents/LineEditContextMenu.qml
diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 9a3b4495..6f5cba4f 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -28,6 +28,8 @@
#include "utils.h"
#include
+#include
+#include
CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent)
: QmlAdapterBase(instance, parent)
@@ -475,7 +477,7 @@ CallAdapter::connectCallModel(const QString& accountId)
*/
bool forceCallOnly {false};
if (!convInfo.confId.isEmpty()) {
- auto callList = lrcInstance_->getAPI().getConferenceSubcalls(convInfo.confId);
+ auto callList = lrcInstance_->getConferenceSubcalls(convInfo.confId);
if (callList.empty()) {
auto lastConference = lrcInstance_->poplastConference(convInfo.confId);
if (!lastConference.isEmpty()) {
@@ -612,7 +614,7 @@ CallAdapter::hangupCall(const QString& uri)
* so we can switch the smartlist index after termination.
*/
if (!convInfo.confId.isEmpty()) {
- auto callList = lrcInstance_->getAPI().getConferenceSubcalls(convInfo.confId);
+ auto callList = lrcInstance_->getConferenceSubcalls(convInfo.confId);
if (callList.size() == 2) {
for (const auto& cId : callList) {
if (cId != convInfo.callId) {
diff --git a/src/lrcinstance.cpp b/src/lrcinstance.cpp
new file mode 100644
index 00000000..deed9083
--- /dev/null
+++ b/src/lrcinstance.cpp
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2019-2021 by Savoir-faire Linux
+ * Author: Andreas Traczyk
+ * Author: Isa Nanic
+ * Author: Mingrui Zhang
+ *
+ * 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 .
+ */
+
+#include "lrcinstance.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+LRCInstance::LRCInstance(migrateCallback willMigrateCb,
+ migrateCallback didMigrateCb,
+ const QString& updateUrl,
+ ConnectivityMonitor* connectivityMonitor)
+ : lrc_(std::make_unique(willMigrateCb, didMigrateCb))
+ , renderer_(std::make_unique(lrc_->getAVModel()))
+ , updateManager_(std::make_unique(updateUrl, connectivityMonitor, this))
+{
+ lrc_->holdConferences = false;
+};
+
+VectorString
+LRCInstance::getConferenceSubcalls(const QString& callId)
+{
+ return lrc_->getConferenceSubcalls(callId);
+}
+
+RenderManager*
+LRCInstance::renderer()
+{
+ return renderer_.get();
+}
+
+UpdateManager*
+LRCInstance::getUpdateManager()
+{
+ return updateManager_.get();
+}
+
+void
+LRCInstance::connectivityChanged()
+{
+ lrc_->connectivityChanged();
+}
+
+NewAccountModel&
+LRCInstance::accountModel()
+{
+ return lrc_->getAccountModel();
+}
+
+BehaviorController&
+LRCInstance::behaviorController()
+{
+ return lrc_->getBehaviorController();
+}
+
+DataTransferModel&
+LRCInstance::dataTransferModel()
+{
+ return lrc_->getDataTransferModel();
+}
+
+AVModel&
+LRCInstance::avModel()
+{
+ return lrc_->getAVModel();
+}
+
+PluginModel&
+LRCInstance::pluginModel()
+{
+ return lrc_->getPluginModel();
+}
+
+bool
+LRCInstance::isConnected()
+{
+ return lrc_->isConnected();
+}
+
+VectorString
+LRCInstance::getActiveCalls()
+{
+ return lrc_->activeCalls();
+}
+
+const account::Info&
+LRCInstance::getAccountInfo(const QString& accountId)
+{
+ return accountModel().getAccountInfo(accountId);
+}
+
+const account::Info&
+LRCInstance::getCurrentAccountInfo()
+{
+ return getAccountInfo(getCurrAccId());
+}
+
+bool
+LRCInstance::hasVideoCall()
+{
+ auto activeCalls = lrc_->activeCalls();
+ auto accountList = accountModel().getAccountList();
+ bool result = false;
+ for (const auto& callId : activeCalls) {
+ for (const auto& accountId : accountList) {
+ auto& accountInfo = accountModel().getAccountInfo(accountId);
+ if (accountInfo.callModel->hasCall(callId)) {
+ auto call = accountInfo.callModel->getCall(callId);
+ result |= !(call.isAudioOnly || call.videoMuted);
+ }
+ }
+ }
+ return result;
+}
+
+QString
+LRCInstance::getCallIdForConversationUid(const QString& convUid, const QString& accountId)
+{
+ const auto& convInfo = getConversationFromConvUid(convUid, accountId);
+ if (convInfo.uid.isEmpty()) {
+ return {};
+ }
+ return convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
+}
+
+const call::Info*
+LRCInstance::getCallInfo(const QString& callId, const QString& accountId)
+{
+ try {
+ auto& accInfo = accountModel().getAccountInfo(accountId);
+ if (!accInfo.callModel->hasCall(callId)) {
+ return nullptr;
+ }
+ return &accInfo.callModel->getCall(callId);
+ } catch (...) {
+ return nullptr;
+ }
+}
+
+const call::Info*
+LRCInstance::getCallInfoForConversation(const conversation::Info& convInfo, bool forceCallOnly)
+{
+ try {
+ auto accountId = convInfo.accountId;
+ auto& accInfo = accountModel().getAccountInfo(accountId);
+ auto callId = forceCallOnly
+ ? convInfo.callId
+ : (convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId);
+ if (!accInfo.callModel->hasCall(callId)) {
+ return nullptr;
+ }
+ return &accInfo.callModel->getCall(callId);
+ } catch (...) {
+ return nullptr;
+ }
+}
+
+const conversation::Info&
+LRCInstance::getConversationFromConvUid(const QString& convUid, const QString& accountId)
+{
+ auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId : getCurrAccId());
+ auto& convModel = accInfo.conversationModel;
+ return convModel->getConversationForUid(convUid).value_or(invalid);
+}
+
+const conversation::Info&
+LRCInstance::getConversationFromPeerUri(const QString& peerUri, const QString& accountId)
+{
+ auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId : getCurrAccId());
+ auto& convModel = accInfo.conversationModel;
+ return convModel->getConversationForPeerUri(peerUri).value_or(invalid);
+}
+
+const conversation::Info&
+LRCInstance::getConversationFromCallId(const QString& callId, const QString& accountId)
+{
+ auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId : getCurrAccId());
+ auto& convModel = accInfo.conversationModel;
+ return convModel->getConversationForCallId(callId).value_or(invalid);
+}
+
+ConversationModel*
+LRCInstance::getCurrentConversationModel()
+{
+ return getCurrentAccountInfo().conversationModel.get();
+}
+
+NewCallModel*
+LRCInstance::getCurrentCallModel()
+{
+ return getCurrentAccountInfo().callModel.get();
+}
+
+const QString&
+LRCInstance::getCurrAccId()
+{
+ if (selectedAccountId_.isEmpty()) {
+ auto accountList = accountModel().getAccountList();
+ if (accountList.size())
+ selectedAccountId_ = accountList.at(0);
+ }
+ return selectedAccountId_;
+}
+
+void
+LRCInstance::setSelectedAccountId(const QString& accountId)
+{
+ if (accountId == selectedAccountId_)
+ return; // No need to select current selected account
+
+ selectedAccountId_ = accountId;
+
+ // Last selected account should be set as preferred.
+ accountModel().setTopAccount(accountId);
+
+ Q_EMIT currentAccountChanged();
+}
+
+const QString&
+LRCInstance::getCurrentConvUid()
+{
+ return selectedConvUid_;
+}
+
+void
+LRCInstance::setSelectedConvId(const QString& convUid)
+{
+ selectedConvUid_ = convUid;
+}
+
+int
+LRCInstance::getCurrentAccountIndex()
+{
+ for (int i = 0; i < accountModel().getAccountList().size(); i++) {
+ if (accountModel().getAccountList()[i] == getCurrAccId()) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void
+LRCInstance::setAvatarForAccount(const QPixmap& avatarPixmap, const QString& accountID)
+{
+ QByteArray ba;
+ QBuffer bu(&ba);
+ bu.open(QIODevice::WriteOnly);
+ avatarPixmap.save(&bu, "PNG");
+ auto str = QString::fromLocal8Bit(ba.toBase64());
+ accountModel().setAvatar(accountID, str);
+}
+
+void
+LRCInstance::setCurrAccAvatar(const QPixmap& avatarPixmap)
+{
+ QByteArray ba;
+ QBuffer bu(&ba);
+ bu.open(QIODevice::WriteOnly);
+ avatarPixmap.save(&bu, "PNG");
+ auto str = QString::fromLocal8Bit(ba.toBase64());
+ accountModel().setAvatar(getCurrAccId(), str);
+}
+
+void
+LRCInstance::setCurrAccAvatar(const QString& avatar)
+{
+ accountModel().setAvatar(getCurrAccId(), avatar);
+}
+
+void
+LRCInstance::setCurrAccDisplayName(const QString& displayName)
+{
+ auto accountId = getCurrAccId();
+ accountModel().setAlias(accountId, displayName);
+ /*
+ * Force save to .yml.
+ */
+ auto confProps = accountModel().getAccountConfig(accountId);
+ accountModel().setAccountConfig(accountId, confProps);
+}
+
+const account::ConfProperties_t&
+LRCInstance::getCurrAccConfig()
+{
+ return getCurrentAccountInfo().confProperties;
+}
+
+void
+LRCInstance::subscribeToDebugReceived()
+{
+ lrc_->subscribeToDebugReceived();
+}
+
+void
+LRCInstance::startAudioMeter(bool async)
+{
+ auto f = [this] {
+ if (!getActiveCalls().size()) {
+ avModel().startAudioDevice();
+ }
+ avModel().setAudioMeterState(true);
+ };
+ if (async) {
+ QtConcurrent::run(f);
+ } else {
+ f();
+ }
+}
+
+void
+LRCInstance::stopAudioMeter(bool async)
+{
+ auto f = [this] {
+ if (!getActiveCalls().size()) {
+ avModel().stopAudioDevice();
+ }
+ avModel().setAudioMeterState(false);
+ };
+ if (async) {
+ QtConcurrent::run(f);
+ } else {
+ f();
+ }
+}
+
+QString
+LRCInstance::getContentDraft(const QString& convUid, const QString& accountId)
+{
+ auto draftKey = accountId + "_" + convUid;
+ return contentDrafts_[draftKey];
+}
+
+void
+LRCInstance::setContentDraft(const QString& convUid,
+ const QString& accountId,
+ const QString& content)
+{
+ auto draftKey = accountId + "_" + convUid;
+ contentDrafts_[draftKey] = content;
+}
+
+void
+LRCInstance::pushlastConference(const QString& confId, const QString& callId)
+{
+ lastConferences_[confId] = callId;
+}
+
+QString
+LRCInstance::poplastConference(const QString& confId)
+{
+ QString callId = {};
+ auto iter = lastConferences_.find(confId);
+ if (iter != lastConferences_.end()) {
+ callId = iter.value();
+ lastConferences_.erase(iter);
+ }
+ return callId;
+}
+
+void
+LRCInstance::selectConversation(const QString& accountId, const QString& convUid)
+{
+ const auto& convInfo = getConversationFromConvUid(convUid, accountId);
+
+ if (getCurrentConvUid() != convInfo.uid || convInfo.participants.size() > 0) {
+ // If the account is not currently selected, do that first, then
+ // proceed to select the conversation.
+ auto selectConversation = [this, accountId, convUid = convInfo.uid] {
+ const auto& convInfo = getConversationFromConvUid(convUid, accountId);
+ if (convInfo.uid.isEmpty()) {
+ return;
+ }
+ auto& accInfo = getAccountInfo(convInfo.accountId);
+ setSelectedConvId(convInfo.uid);
+ accInfo.conversationModel->clearUnreadInteractions(convInfo.uid);
+
+ try {
+ // Set contact filter (for conversation tab selection)
+ auto& contact = accInfo.contactModel->getContact(convInfo.participants.front());
+ setProperty("currentTypeFilter", QVariant::fromValue(contact.profileInfo.type));
+ } catch (const std::out_of_range& e) {
+ qDebug() << e.what();
+ }
+ };
+ if (convInfo.accountId != getCurrAccId()) {
+ Utils::oneShotConnect(this, &LRCInstance::currentAccountChanged, [selectConversation] {
+ selectConversation();
+ });
+ setSelectedConvId();
+ setSelectedAccountId(convInfo.accountId);
+ } else {
+ selectConversation();
+ }
+ }
+ Q_EMIT conversationSelected();
+}
+
+void
+LRCInstance::finish()
+{
+ renderer_.reset();
+ lrc_.reset();
+}
diff --git a/src/lrcinstance.h b/src/lrcinstance.h
index e5d8ccdc..f50ba868 100644
--- a/src/lrcinstance.h
+++ b/src/lrcinstance.h
@@ -1,5 +1,5 @@
-/*!
- * Copyright (C) 2019-2020 by Savoir-faire Linux
+/*
+ * Copyright (C) 2019-2021 by Savoir-faire Linux
* Author: Andreas Traczyk
* Author: Isa Nanic
* Author: Mingrui Zhang
@@ -29,29 +29,18 @@
#include "qtutils.h"
#include "utils.h"
+#include "api/lrc.h"
#include "api/account.h"
#include "api/avmodel.h"
-#include "api/pluginmodel.h"
#include "api/behaviorcontroller.h"
#include "api/contact.h"
#include "api/contactmodel.h"
#include "api/conversation.h"
#include "api/conversationmodel.h"
-#include "api/datatransfermodel.h"
-#include "api/lrc.h"
#include "api/newaccountmodel.h"
#include "api/newcallmodel.h"
-#include "api/newcodecmodel.h"
-#include "api/newdevicemodel.h"
-#include "api/peerdiscoverymodel.h"
-#include
-#include
#include
-#include
-#include
-#include
-#include
#include
@@ -67,369 +56,65 @@ class LRCInstance : public QObject
Q_OBJECT
public:
- LRCInstance(migrateCallback willMigrateCb = {},
- migrateCallback didMigrateCb = {},
- const QString& updateUrl = {},
- ConnectivityMonitor* connectivityMonitor = {})
- {
- lrc_ = std::make_unique(willMigrateCb, didMigrateCb);
- renderer_ = std::make_unique(lrc_->getAVModel());
- updateManager_ = std::make_unique(updateUrl, connectivityMonitor, this);
- };
+ explicit LRCInstance(migrateCallback willMigrateCb = {},
+ migrateCallback didMigrateCb = {},
+ const QString& updateUrl = {},
+ ConnectivityMonitor* connectivityMonitor = {});
+ ~LRCInstance() = default;
- Lrc& getAPI()
- {
- return *(lrc_);
- }
+ void finish();
- RenderManager* renderer()
- {
- return renderer_.get();
- }
+ RenderManager* renderer();
+ UpdateManager* getUpdateManager();
- UpdateManager* getUpdateManager()
- {
- return updateManager_.get();
- }
+ NewAccountModel& accountModel();
+ ConversationModel* getCurrentConversationModel();
+ NewCallModel* getCurrentCallModel();
+ AVModel& avModel();
+ PluginModel& pluginModel();
+ BehaviorController& behaviorController();
+ DataTransferModel& dataTransferModel();
- void connectivityChanged()
- {
- lrc_->connectivityChanged();
- }
-
- NewAccountModel& accountModel()
- {
- return lrc_->getAccountModel();
- }
-
- BehaviorController& behaviorController()
- {
- return lrc_->getBehaviorController();
- }
-
- DataTransferModel& dataTransferModel()
- {
- return lrc_->getDataTransferModel();
- }
-
- AVModel& avModel()
- {
- return lrc_->getAVModel();
- }
-
- PluginModel& pluginModel()
- {
- return lrc_->getPluginModel();
- }
-
- bool isConnected()
- {
- return lrc_->isConnected();
- }
-
- VectorString getActiveCalls()
- {
- return lrc_->activeCalls();
- }
-
- const account::Info& getAccountInfo(const QString& accountId)
- {
- return accountModel().getAccountInfo(accountId);
- }
-
- const account::Info& getCurrentAccountInfo()
- {
- return getAccountInfo(getCurrAccId());
- }
-
- bool hasVideoCall()
- {
- auto activeCalls = lrc_->activeCalls();
- auto accountList = accountModel().getAccountList();
- bool result = false;
- for (const auto& callId : activeCalls) {
- for (const auto& accountId : accountList) {
- auto& accountInfo = accountModel().getAccountInfo(accountId);
- if (accountInfo.callModel->hasCall(callId)) {
- auto call = accountInfo.callModel->getCall(callId);
- result |= !(call.isAudioOnly || call.videoMuted);
- }
- }
- }
- return result;
- }
-
- QString getCallIdForConversationUid(const QString& convUid, const QString& accountId)
- {
- const auto& convInfo = getConversationFromConvUid(convUid, accountId);
- if (convInfo.uid.isEmpty()) {
- return {};
- }
- return convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
- }
-
- const call::Info* getCallInfo(const QString& callId, const QString& accountId)
- {
- try {
- auto& accInfo = accountModel().getAccountInfo(accountId);
- if (!accInfo.callModel->hasCall(callId)) {
- return nullptr;
- }
- return &accInfo.callModel->getCall(callId);
- } catch (...) {
- return nullptr;
- }
- }
+ void subscribeToDebugReceived();
+ bool isConnected();
+ void connectivityChanged();
+ VectorString getActiveCalls();
+ const account::Info& getAccountInfo(const QString& accountId);
+ const account::Info& getCurrentAccountInfo();
+ QString getCallIdForConversationUid(const QString& convUid, const QString& accountId);
+ const call::Info* getCallInfo(const QString& callId, const QString& accountId);
const call::Info* getCallInfoForConversation(const conversation::Info& convInfo,
- bool forceCallOnly = {})
- {
- try {
- auto accountId = convInfo.accountId;
- auto& accInfo = accountModel().getAccountInfo(accountId);
- auto callId = forceCallOnly
- ? convInfo.callId
- : (convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId);
- if (!accInfo.callModel->hasCall(callId)) {
- return nullptr;
- }
- return &accInfo.callModel->getCall(callId);
- } catch (...) {
- return nullptr;
- }
- }
-
+ bool forceCallOnly = {});
const conversation::Info& getConversationFromConvUid(const QString& convUid,
- const QString& accountId = {})
- {
- auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
- : getCurrAccId());
- auto& convModel = accInfo.conversationModel;
- return convModel->getConversationForUid(convUid).value_or(invalid);
- }
-
+ const QString& accountId = {});
const conversation::Info& getConversationFromPeerUri(const QString& peerUri,
- const QString& accountId = {})
- {
- auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
- : getCurrAccId());
- auto& convModel = accInfo.conversationModel;
- return convModel->getConversationForPeerUri(peerUri).value_or(invalid);
- }
-
+ const QString& accountId = {});
const conversation::Info& getConversationFromCallId(const QString& callId,
- const QString& accountId = {})
- {
- auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
- : getCurrAccId());
- auto& convModel = accInfo.conversationModel;
- return convModel->getConversationForCallId(callId).value_or(invalid);
- }
+ const QString& accountId = {});
- ConversationModel* getCurrentConversationModel()
- {
- return getCurrentAccountInfo().conversationModel.get();
- }
+ const QString& getCurrAccId();
+ void setSelectedAccountId(const QString& accountId = {});
+ const QString& getCurrentConvUid();
+ void selectConversation(const QString& accountId, const QString& convUid);
+ void setSelectedConvId(const QString& convUid = {});
+ int getCurrentAccountIndex();
+ void setAvatarForAccount(const QPixmap& avatarPixmap, const QString& accountID);
+ void setCurrAccAvatar(const QPixmap& avatarPixmap);
+ void setCurrAccAvatar(const QString& avatar);
+ void setCurrAccDisplayName(const QString& displayName);
+ const account::ConfProperties_t& getCurrAccConfig();
- NewCallModel* getCurrentCallModel()
- {
- return getCurrentAccountInfo().callModel.get();
- }
+ void startAudioMeter(bool async);
+ void stopAudioMeter(bool async);
- const QString& getCurrAccId()
- {
- if (selectedAccountId_.isEmpty()) {
- auto accountList = accountModel().getAccountList();
- if (accountList.size())
- selectedAccountId_ = accountList.at(0);
- }
- return selectedAccountId_;
- }
+ QString getContentDraft(const QString& convUid, const QString& accountId);
+ void setContentDraft(const QString& convUid, const QString& accountId, const QString& content);
- void setSelectedAccountId(const QString& accountId = {})
- {
- if (accountId == selectedAccountId_)
- return; // No need to select current selected account
-
- selectedAccountId_ = accountId;
-
- // Last selected account should be set as preferred.
- accountModel().setTopAccount(accountId);
-
- Q_EMIT currentAccountChanged();
- }
-
- const QString& getCurrentConvUid()
- {
- return selectedConvUid_;
- }
-
- void setSelectedConvId(const QString& convUid = {})
- {
- selectedConvUid_ = convUid;
- }
-
- void reset(bool newInstance = false)
- {
- if (newInstance) {
- renderer_.reset(new RenderManager(avModel()));
- lrc_.reset(new Lrc());
- } else {
- renderer_.reset();
- lrc_.reset();
- }
- }
-
- int getCurrentAccountIndex()
- {
- for (int i = 0; i < accountModel().getAccountList().size(); i++) {
- if (accountModel().getAccountList()[i] == getCurrAccId()) {
- return i;
- }
- }
- return -1;
- }
-
- void setAvatarForAccount(const QPixmap& avatarPixmap, const QString& accountID)
- {
- QByteArray ba;
- QBuffer bu(&ba);
- bu.open(QIODevice::WriteOnly);
- avatarPixmap.save(&bu, "PNG");
- auto str = QString::fromLocal8Bit(ba.toBase64());
- accountModel().setAvatar(accountID, str);
- }
-
- void setCurrAccAvatar(const QPixmap& avatarPixmap)
- {
- QByteArray ba;
- QBuffer bu(&ba);
- bu.open(QIODevice::WriteOnly);
- avatarPixmap.save(&bu, "PNG");
- auto str = QString::fromLocal8Bit(ba.toBase64());
- accountModel().setAvatar(getCurrAccId(), str);
- }
-
- void setCurrAccAvatar(const QString& avatar)
- {
- accountModel().setAvatar(getCurrAccId(), avatar);
- }
-
- void setCurrAccDisplayName(const QString& displayName)
- {
- auto accountId = getCurrAccId();
- accountModel().setAlias(accountId, displayName);
- /*
- * Force save to .yml.
- */
- auto confProps = accountModel().getAccountConfig(accountId);
- accountModel().setAccountConfig(accountId, confProps);
- }
-
- const account::ConfProperties_t& getCurrAccConfig()
- {
- return getCurrentAccountInfo().confProperties;
- }
-
- void subscribeToDebugReceived()
- {
- lrc_->subscribeToDebugReceived();
- }
-
- void startAudioMeter(bool async)
- {
- auto f = [this] {
- if (!getActiveCalls().size()) {
- avModel().startAudioDevice();
- }
- avModel().setAudioMeterState(true);
- };
- if (async) {
- QtConcurrent::run(f);
- } else {
- f();
- }
- }
-
- void stopAudioMeter(bool async)
- {
- auto f = [this] {
- if (!getActiveCalls().size()) {
- avModel().stopAudioDevice();
- }
- avModel().setAudioMeterState(false);
- };
- if (async) {
- QtConcurrent::run(f);
- } else {
- f();
- }
- }
-
- QString getContentDraft(const QString& convUid, const QString& accountId)
- {
- auto draftKey = accountId + "_" + convUid;
- return contentDrafts_[draftKey];
- }
-
- void setContentDraft(const QString& convUid, const QString& accountId, const QString& content)
- {
- auto draftKey = accountId + "_" + convUid;
- contentDrafts_[draftKey] = content;
- }
-
- void pushlastConference(const QString& confId, const QString& callId)
- {
- lastConferences_[confId] = callId;
- }
-
- QString poplastConference(const QString& confId)
- {
- QString callId = {};
- auto iter = lastConferences_.find(confId);
- if (iter != lastConferences_.end()) {
- callId = iter.value();
- lastConferences_.erase(iter);
- }
- return callId;
- }
-
- void selectConversation(const QString& accountId, const QString& convUid)
- {
- const auto& convInfo = getConversationFromConvUid(convUid, accountId);
-
- if (getCurrentConvUid() != convInfo.uid || convInfo.participants.size() > 0) {
- // If the account is not currently selected, do that first, then
- // proceed to select the conversation.
- auto selectConversation = [this, accountId, convUid = convInfo.uid] {
- const auto& convInfo = getConversationFromConvUid(convUid, accountId);
- if (convInfo.uid.isEmpty()) {
- return;
- }
- auto& accInfo = getAccountInfo(convInfo.accountId);
- setSelectedConvId(convInfo.uid);
- accInfo.conversationModel->clearUnreadInteractions(convInfo.uid);
-
- try {
- // Set contact filter (for conversation tab selection)
- auto& contact = accInfo.contactModel->getContact(convInfo.participants.front());
- setProperty("currentTypeFilter", QVariant::fromValue(contact.profileInfo.type));
- } catch (const std::out_of_range& e) {
- qDebug() << e.what();
- }
- };
- if (convInfo.accountId != getCurrAccId()) {
- Utils::oneShotConnect(this,
- &LRCInstance::currentAccountChanged,
- [selectConversation] { selectConversation(); });
- setSelectedConvId();
- setSelectedAccountId(convInfo.accountId);
- } else {
- selectConversation();
- }
- }
- Q_EMIT conversationSelected();
- }
+ bool hasVideoCall();
+ void pushlastConference(const QString& confId, const QString& callId);
+ QString poplastConference(const QString& confId);
+ VectorString getConferenceSubcalls(const QString& callId);
Q_SIGNALS:
void accountListChanged();
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
index 76e22e9c..7a7aebe6 100644
--- a/src/mainapplication.cpp
+++ b/src/mainapplication.cpp
@@ -46,6 +46,9 @@
#include
#include
#include
+#include
+#include
+#include
#include
#include
@@ -339,7 +342,6 @@ MainApplication::initLrc(const QString& downloadUrl, ConnectivityMonitor* cm)
downloadUrl,
cm));
lrcInstance_->subscribeToDebugReceived();
- lrcInstance_->getAPI().holdConferences = false;
}
const QVariantMap
diff --git a/src/mediacodeclistmodel.cpp b/src/mediacodeclistmodel.cpp
index 1887fba6..fb4cec22 100644
--- a/src/mediacodeclistmodel.cpp
+++ b/src/mediacodeclistmodel.cpp
@@ -23,6 +23,7 @@
#include "api/account.h"
#include "api/contact.h"
#include "api/conversation.h"
+#include "api/newcodecmodel.h"
#include "api/newdevicemodel.h"
MediaCodecListModel::MediaCodecListModel(QObject* parent)
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index 1cdf09ee..a5c6db97 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -35,6 +35,8 @@
#include
#include
#include
+#include
+#include
MessagesAdapter::MessagesAdapter(AppSettingsManager* settingsManager,
LRCInstance* instance,
diff --git a/src/pluginlistpreferencemodel.h b/src/pluginlistpreferencemodel.h
index 1ce6f6e0..614eb428 100644
--- a/src/pluginlistpreferencemodel.h
+++ b/src/pluginlistpreferencemodel.h
@@ -20,6 +20,8 @@
#include "abstractitemmodelbase.h"
+#include "api/pluginmodel.h"
+
class PluginListPreferenceModel : public AbstractListModelBase
{
Q_OBJECT
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 78adb0ce..47a2d06b 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -39,6 +39,12 @@
#include "videoformatresolutionmodel.h"
#include "videoinputdevicemodel.h"
+#include "api/peerdiscoverymodel.h"
+#include "api/newcodecmodel.h"
+#include "api/newdevicemodel.h"
+#include "api/datatransfermodel.h"
+#include "api/pluginmodel.h"
+
#include
#include
diff --git a/src/settingsadapter.cpp b/src/settingsadapter.cpp
index a2ea168b..8f770c31 100644
--- a/src/settingsadapter.cpp
+++ b/src/settingsadapter.cpp
@@ -18,6 +18,7 @@
#include "settingsadapter.h"
+#include "api/newcodecmodel.h"
#include "api/newdevicemodel.h"
SettingsAdapter::SettingsAdapter(AppSettingsManager* settingsManager,
diff --git a/src/updatemanager.cpp b/src/updatemanager.cpp
index 68f98a6a..1d5b3e92 100644
--- a/src/updatemanager.cpp
+++ b/src/updatemanager.cpp
@@ -128,7 +128,7 @@ UpdateManager::applyUpdates(bool beta)
get(
downloadUrl,
[this, downloadUrl](const QString&) {
- lrcInstance_->reset();
+ lrcInstance_->finish();
Q_EMIT lrcInstance_->quitEngineRequested();
auto args = QString(" /passive /norestart WIXNONUILAUNCH=1");
QProcess process;
diff --git a/src/utilsadapter.cpp b/src/utilsadapter.cpp
index dafd36a0..3b983086 100644
--- a/src/utilsadapter.cpp
+++ b/src/utilsadapter.cpp
@@ -27,6 +27,8 @@
#include "utils.h"
#include "version.h"
+#include "api/pluginmodel.h"
+
#include
#include
#include