mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-08-12 18:55:39 +02:00

A signal exists for showing errors to the user to make failing cases more explicit. With this patch, errors detected are displayed to the end user so that they know that an error occured and what kind of error occured. Change-Id: Ib2d4d4fdb171235e0598de0f1c190b8fd0fcc336
614 lines
No EOL
22 KiB
C++
614 lines
No EOL
22 KiB
C++
/*
|
|
* Copyright (C) 2020-2022 Savoir-faire Linux Inc.
|
|
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
|
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
|
*
|
|
* 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/>.
|
|
*/
|
|
|
|
#include "conversationsadapter.h"
|
|
|
|
#include "utils.h"
|
|
#include "qtutils.h"
|
|
#include "systemtray.h"
|
|
#include "qmlregister.h"
|
|
|
|
#include <QApplication>
|
|
#include <QJsonObject>
|
|
|
|
using namespace lrc::api;
|
|
|
|
ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray,
|
|
LRCInstance* instance,
|
|
QObject* parent)
|
|
: QmlAdapterBase(instance, parent)
|
|
, systemTray_(systemTray)
|
|
, convSrcModel_(new ConversationListModel(lrcInstance_))
|
|
, convModel_(new ConversationListProxyModel(convSrcModel_.get()))
|
|
, searchSrcModel_(new SearchResultsListModel(lrcInstance_))
|
|
, searchModel_(new SelectableListProxyModel(searchSrcModel_.get()))
|
|
{
|
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, convModel_.get(), "ConversationListModel");
|
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, searchModel_.get(), "SearchResultsListModel");
|
|
|
|
new SelectableListProxyGroupModel({convModel_.data(), searchModel_.data()}, this);
|
|
|
|
// this will trigger when the invite filter tab is selected
|
|
connect(this, &ConversationsAdapter::filterRequestsChanged, [this]() {
|
|
convModel_->setFilterRequests(filterRequests_);
|
|
});
|
|
|
|
connect(lrcInstance_, &LRCInstance::selectedConvUidChanged, [this]() {
|
|
auto convId = lrcInstance_->get_selectedConvUid();
|
|
if (convId.isEmpty()) {
|
|
// deselected
|
|
convModel_->deselect();
|
|
searchModel_->deselect();
|
|
Q_EMIT navigateToWelcomePageRequested();
|
|
} else {
|
|
// selected
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
if (convInfo.uid.isEmpty())
|
|
return;
|
|
|
|
auto& accInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
|
|
accInfo.conversationModel->selectConversation(convInfo.uid);
|
|
accInfo.conversationModel->clearUnreadInteractions(convInfo.uid);
|
|
|
|
// this may be a request, so adjust that filter also
|
|
set_filterRequests(convInfo.isRequest);
|
|
|
|
// reposition index in case of programmatic selection
|
|
// currently, this may only occur for the conversation list
|
|
// and not the search list
|
|
convModel_->selectSourceRow(lrcInstance_->indexOf(convId));
|
|
}
|
|
});
|
|
|
|
connect(lrcInstance_, &LRCInstance::draftSaved, [this](const QString& convId) {
|
|
auto row = lrcInstance_->indexOf(convId);
|
|
const auto index = convSrcModel_->index(row, 0);
|
|
Q_EMIT convSrcModel_->dataChanged(index, index);
|
|
});
|
|
|
|
#ifdef Q_OS_LINUX
|
|
// notification responses
|
|
connect(systemTray_,
|
|
&SystemTray::openConversationActivated,
|
|
[this](const QString& accountId, const QString& convUid) {
|
|
Q_EMIT lrcInstance_->notificationClicked();
|
|
lrcInstance_->selectConversation(convUid, accountId);
|
|
});
|
|
connect(systemTray_,
|
|
&SystemTray::acceptPendingActivated,
|
|
[this](const QString& accountId, const QString& convUid) {
|
|
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
|
accInfo.conversationModel->acceptConversationRequest(convUid);
|
|
});
|
|
connect(systemTray_,
|
|
&SystemTray::refusePendingActivated,
|
|
[this](const QString& accountId, const QString& convUid) {
|
|
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
|
accInfo.conversationModel->removeConversation(convUid);
|
|
});
|
|
#endif
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::safeInit()
|
|
{
|
|
// TODO: remove these safeInits, they are possibly called
|
|
// multiple times during qml component inits
|
|
connect(&lrcInstance_->behaviorController(),
|
|
&BehaviorController::newUnreadInteraction,
|
|
this,
|
|
&ConversationsAdapter::onNewUnreadInteraction,
|
|
Qt::UniqueConnection);
|
|
|
|
connect(&lrcInstance_->behaviorController(),
|
|
&BehaviorController::newReadInteraction,
|
|
this,
|
|
&ConversationsAdapter::onNewReadInteraction,
|
|
Qt::UniqueConnection);
|
|
|
|
connect(&lrcInstance_->behaviorController(),
|
|
&BehaviorController::newTrustRequest,
|
|
this,
|
|
&ConversationsAdapter::onNewTrustRequest,
|
|
Qt::UniqueConnection);
|
|
|
|
connect(&lrcInstance_->behaviorController(),
|
|
&BehaviorController::trustRequestTreated,
|
|
this,
|
|
&ConversationsAdapter::onTrustRequestTreated,
|
|
Qt::UniqueConnection);
|
|
|
|
connect(lrcInstance_,
|
|
&LRCInstance::currentAccountIdChanged,
|
|
this,
|
|
&ConversationsAdapter::onCurrentAccountIdChanged,
|
|
Qt::UniqueConnection);
|
|
|
|
connectConversationModel();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onCurrentAccountIdChanged()
|
|
{
|
|
lrcInstance_->deselectConversation();
|
|
|
|
connectConversationModel();
|
|
|
|
// Always turn the requests filter off when switching account.
|
|
// Conversation selection will manage the filter state in the
|
|
// case of programmatic selection(incoming call, notification
|
|
// activation, etc.).
|
|
set_filterRequests(false);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onNewUnreadInteraction(const QString& accountId,
|
|
const QString& convUid,
|
|
const QString& interactionId,
|
|
const interaction::Info& interaction)
|
|
{
|
|
if (!interaction.authorUri.isEmpty()
|
|
&& (!QApplication::focusWindow() || accountId != lrcInstance_->get_currentAccountId()
|
|
|| convUid != lrcInstance_->get_selectedConvUid())) {
|
|
auto& accountInfo = lrcInstance_->getAccountInfo(accountId);
|
|
auto from = accountInfo.contactModel->bestNameForContact(interaction.authorUri);
|
|
#ifdef Q_OS_LINUX
|
|
auto contactPhoto = Utils::contactPhoto(lrcInstance_,
|
|
interaction.authorUri,
|
|
QSize(50, 50),
|
|
accountId);
|
|
auto notifId = QString("%1;%2;%3").arg(accountId).arg(convUid).arg(interactionId);
|
|
systemTray_->showNotification(notifId,
|
|
tr("New message"),
|
|
from + ": " + interaction.body,
|
|
NotificationType::CHAT,
|
|
Utils::QImageToByteArray(contactPhoto));
|
|
|
|
#else
|
|
Q_UNUSED(interactionId)
|
|
auto onClicked = [this, accountId, convUid, uri = interaction.authorUri] {
|
|
Q_EMIT lrcInstance_->notificationClicked();
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
|
|
if (convInfo.uid.isEmpty())
|
|
return;
|
|
lrcInstance_->selectConversation(convInfo.uid, accountId);
|
|
};
|
|
systemTray_->showNotification(interaction.body, from, onClicked);
|
|
#endif
|
|
updateConversationFilterData();
|
|
}
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onNewReadInteraction(const QString& accountId,
|
|
const QString& convUid,
|
|
const QString& interactionId)
|
|
{
|
|
#ifdef Q_OS_LINUX
|
|
// hide notification
|
|
auto notifId = QString("%1;%2;%3").arg(accountId).arg(convUid).arg(interactionId);
|
|
systemTray_->hideNotification(notifId);
|
|
#else
|
|
Q_UNUSED(accountId)
|
|
Q_UNUSED(convUid)
|
|
Q_UNUSED(interactionId)
|
|
#endif
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onNewTrustRequest(const QString& accountId,
|
|
const QString& convId,
|
|
const QString& peerUri)
|
|
{
|
|
#ifdef Q_OS_LINUX
|
|
if (!QApplication::focusWindow() || accountId != lrcInstance_->get_currentAccountId()) {
|
|
auto conv = convId;
|
|
if (conv.isEmpty()) {
|
|
auto& convInfo = lrcInstance_->getConversationFromPeerUri(peerUri);
|
|
if (convInfo.uid.isEmpty())
|
|
return;
|
|
}
|
|
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
|
auto from = accInfo.contactModel->bestNameForContact(peerUri);
|
|
auto contactPhoto = Utils::contactPhoto(lrcInstance_, peerUri, QSize(50, 50), accountId);
|
|
auto notifId = QString("%1;%2").arg(accountId).arg(conv);
|
|
systemTray_->showNotification(notifId,
|
|
tr("Trust request"),
|
|
"New request from " + from,
|
|
NotificationType::REQUEST,
|
|
Utils::QImageToByteArray(contactPhoto));
|
|
}
|
|
#else
|
|
Q_UNUSED(accountId)
|
|
Q_UNUSED(peerUri)
|
|
#endif
|
|
updateConversationFilterData();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onTrustRequestTreated(const QString& accountId, const QString& peerUri)
|
|
{
|
|
#ifdef Q_OS_LINUX
|
|
// hide notification
|
|
auto notifId = QString("%1;%2").arg(accountId).arg(peerUri);
|
|
systemTray_->hideNotification(notifId);
|
|
#else
|
|
Q_UNUSED(accountId)
|
|
Q_UNUSED(peerUri)
|
|
#endif
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onModelChanged()
|
|
{
|
|
updateConversationFilterData();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onProfileUpdated(const QString& contactUri)
|
|
{
|
|
auto& convInfo = lrcInstance_->getConversationFromPeerUri(contactUri);
|
|
if (convInfo.uid.isEmpty())
|
|
return;
|
|
|
|
// notify UI elements
|
|
auto row = lrcInstance_->indexOf(convInfo.uid);
|
|
const auto index = convSrcModel_->index(row, 0);
|
|
Q_EMIT convSrcModel_->dataChanged(index, index);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onConversationUpdated(const QString& convId)
|
|
{
|
|
updateConversationFilterData();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onFilterChanged()
|
|
{
|
|
updateConversationFilterData();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onConversationCleared(const QString& convUid)
|
|
{
|
|
// If currently selected, switch to welcome screen (deselecting
|
|
// current smartlist item).
|
|
if (convUid == lrcInstance_->get_selectedConvUid()) {
|
|
lrcInstance_->deselectConversation();
|
|
}
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onSearchStatusChanged(const QString& status)
|
|
{
|
|
Q_EMIT showSearchStatus(status);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onSearchResultUpdated()
|
|
{
|
|
// smartlist search results
|
|
searchSrcModel_->onSearchResultsUpdated();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onConversationReady(const QString& convId)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
auto selectedConvId = lrcInstance_->get_selectedConvUid();
|
|
|
|
// for one to one conversations including legacy mode, we can prevent
|
|
// undesired selection by filtering for a conversation peer match,
|
|
// and for all other swarm convs, we can match the conv's id
|
|
if (convInfo.isCoreDialog()) {
|
|
auto peers = convModel->peersForConversation(convId);
|
|
auto selectedPeers = convModel->peersForConversation(selectedConvId);
|
|
if (peers != selectedPeers)
|
|
return;
|
|
} else if (convId != selectedConvId)
|
|
return;
|
|
|
|
updateConversation(convId);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::onBannedStatusChanged(const QString& uri, bool banned)
|
|
{
|
|
Q_UNUSED(banned)
|
|
auto& convInfo = lrcInstance_->getConversationFromPeerUri(uri);
|
|
if (convInfo.uid.isEmpty())
|
|
return;
|
|
auto row = lrcInstance_->indexOf(convInfo.uid);
|
|
const auto index = convSrcModel_->index(row, 0);
|
|
Q_EMIT convSrcModel_->dataChanged(index, index);
|
|
lrcInstance_->set_selectedConvUid();
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::updateConversation(const QString& convId)
|
|
{
|
|
// a conversation request has been accepted or a contact has
|
|
// been added, so select the conversation and notify the UI to:
|
|
// - switch tabs to the conversation filter tab
|
|
// - clear search bar
|
|
Q_EMIT conversationReady(convId);
|
|
lrcInstance_->selectConversation(convId);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::updateConversationFilterData()
|
|
{
|
|
// TODO: this may be further spliced to respond separately to
|
|
// incoming messages and invites
|
|
// total unread message and pending invite counts, and tab selection
|
|
auto& accountInfo = lrcInstance_->getCurrentAccountInfo();
|
|
int totalUnreadMessages {0};
|
|
if (accountInfo.profileInfo.type != profile::Type::SIP) {
|
|
auto& convModel = accountInfo.conversationModel;
|
|
auto conversations = convModel->getFilteredConversations(FilterType::JAMI, false);
|
|
conversations.for_each([&totalUnreadMessages](const conversation::Info& conversation) {
|
|
totalUnreadMessages += conversation.unreadMessages;
|
|
});
|
|
}
|
|
set_totalUnreadMessageCount(totalUnreadMessages);
|
|
set_pendingRequestCount(accountInfo.conversationModel->pendingRequestCount());
|
|
systemTray_->setCount(lrcInstance_->notificationsCount());
|
|
|
|
if (get_pendingRequestCount() == 0 && get_filterRequests())
|
|
set_filterRequests(false);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::setFilter(const QString& filterString)
|
|
{
|
|
convModel_->setFilter(filterString);
|
|
searchSrcModel_->setFilter(filterString);
|
|
Q_EMIT textFilterChanged(filterString);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::ignoreFiltering(const QVariant& hightlighted)
|
|
{
|
|
convModel_->ignoreFiltering(hightlighted.toStringList());
|
|
}
|
|
|
|
QVariantMap
|
|
ConversationsAdapter::getConvInfoMap(const QString& convId)
|
|
{
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
if (convInfo.participants.empty())
|
|
return {};
|
|
QString peerUri {};
|
|
QString bestId {};
|
|
const auto& accountInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
|
|
if (convInfo.isCoreDialog()) {
|
|
try {
|
|
peerUri = accountInfo.conversationModel->peersForConversation(convId).at(0);
|
|
bestId = accountInfo.contactModel->bestIdForContact(peerUri);
|
|
} catch (...) {
|
|
}
|
|
}
|
|
|
|
bool isAudioOnly {false};
|
|
if (!convInfo.uid.isEmpty()) {
|
|
auto* call = lrcInstance_->getCallInfoForConversation(convInfo);
|
|
if (call) {
|
|
isAudioOnly = call->isAudioOnly;
|
|
}
|
|
}
|
|
bool callStackViewShouldShow {false};
|
|
call::Status callState {};
|
|
if (!convInfo.callId.isEmpty()) {
|
|
auto* callModel = lrcInstance_->getCurrentCallModel();
|
|
const auto& call = callModel->getCall(convInfo.callId);
|
|
callStackViewShouldShow = callModel->hasCall(convInfo.callId)
|
|
&& ((!call.isOutgoing
|
|
&& (call.status == call::Status::IN_PROGRESS
|
|
|| call.status == call::Status::PAUSED
|
|
|| call.status == call::Status::INCOMING_RINGING))
|
|
|| (call.isOutgoing && call.status != call::Status::ENDED));
|
|
callState = call.status;
|
|
}
|
|
return {{"convId", convId},
|
|
{"bestId", bestId},
|
|
{"title", lrcInstance_->getCurrentConversationModel()->title(convId)},
|
|
{"description", lrcInstance_->getCurrentConversationModel()->description(convId)},
|
|
{"uri", peerUri},
|
|
{"uris", accountInfo.conversationModel->peersForConversation(convId)},
|
|
{"isSwarm", convInfo.isSwarm()},
|
|
{"isRequest", convInfo.isRequest},
|
|
{"needsSyncing", convInfo.needsSyncing},
|
|
{"isAudioOnly", isAudioOnly},
|
|
{"callState", static_cast<int>(callState)},
|
|
{"callStackViewShouldShow", callStackViewShouldShow}};
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::restartConversation(const QString& convId)
|
|
{
|
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog()) {
|
|
return;
|
|
}
|
|
|
|
// get the ONE_TO_ONE conv's peer uri
|
|
auto peerUri = accInfo.conversationModel->peersForConversation(convId).at(0);
|
|
|
|
// store a copy of the original contact so we can re-add them
|
|
// Note: we set the profile::Type to TEMPORARY to invoke a full add
|
|
// when calling ContactModel::addContact
|
|
auto contactInfo = accInfo.contactModel->getContact(peerUri);
|
|
contactInfo.profileInfo.type = profile::Type::TEMPORARY;
|
|
|
|
Utils::oneShotConnect(
|
|
accInfo.contactModel.get(),
|
|
&ContactModel::contactRemoved,
|
|
[this, &accInfo, contactInfo](const QString& peerUri) {
|
|
// setup a callback to select another ONE_TO_ONE conversation for this peer
|
|
// once the new conversation becomes ready
|
|
Utils::oneShotConnect(
|
|
accInfo.conversationModel.get(),
|
|
&ConversationModel::conversationReady,
|
|
[this, peerUri, &accInfo](const QString& convId) {
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
// 3. filter for the correct contact-conversation and select it
|
|
if (!convInfo.uid.isEmpty() && convInfo.isCoreDialog()
|
|
&& peerUri
|
|
== accInfo.conversationModel->peersForConversation(convId).at(0)) {
|
|
lrcInstance_->selectConversation(convId);
|
|
}
|
|
});
|
|
|
|
// 2. add the contact and await the conversationReady signal
|
|
accInfo.contactModel->addContact(contactInfo);
|
|
});
|
|
|
|
// 1. remove the contact and await the contactRemoved signal
|
|
accInfo.contactModel->removeContact(peerUri);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::updateConversationTitle(const QString& convId, const QString& newTitle)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
QMap<QString, QString> details;
|
|
details["title"] = newTitle;
|
|
convModel->updateConversationInfos(convId, details);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::popFrontError(const QString& convId)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
convModel->popFrontError(convId);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::updateConversationDescription(const QString& convId,
|
|
const QString& newDescription)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
QMap<QString, QString> details;
|
|
details["description"] = newDescription;
|
|
convModel->updateConversationInfos(convId, details);
|
|
}
|
|
|
|
QString
|
|
ConversationsAdapter::dialogId(const QString& peerUri)
|
|
{
|
|
auto& convInfo = lrcInstance_->getConversationFromPeerUri(peerUri);
|
|
if (!convInfo.uid.isEmpty() && convInfo.isCoreDialog())
|
|
return convInfo.uid;
|
|
return {};
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::openDialogConversationWith(const QString& peerUri)
|
|
{
|
|
auto& convInfo = lrcInstance_->getConversationFromPeerUri(peerUri);
|
|
if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog())
|
|
return;
|
|
lrcInstance_->selectConversation(convInfo.uid);
|
|
}
|
|
|
|
bool
|
|
ConversationsAdapter::connectConversationModel()
|
|
{
|
|
// Signal connections
|
|
auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::modelChanged,
|
|
this,
|
|
&ConversationsAdapter::onModelChanged,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(lrcInstance_->getCurrentContactModel(),
|
|
&ContactModel::profileUpdated,
|
|
this,
|
|
&ConversationsAdapter::onProfileUpdated,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::conversationUpdated,
|
|
this,
|
|
&ConversationsAdapter::onConversationUpdated,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::filterChanged,
|
|
this,
|
|
&ConversationsAdapter::onFilterChanged,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::conversationCleared,
|
|
this,
|
|
&ConversationsAdapter::onConversationCleared,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::searchStatusChanged,
|
|
this,
|
|
&ConversationsAdapter::onSearchStatusChanged,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::searchResultUpdated,
|
|
this,
|
|
&ConversationsAdapter::onSearchResultUpdated,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(currentConversationModel,
|
|
&ConversationModel::conversationReady,
|
|
this,
|
|
&ConversationsAdapter::onConversationReady,
|
|
Qt::UniqueConnection);
|
|
|
|
QObject::connect(lrcInstance_->getCurrentContactModel(),
|
|
&ContactModel::bannedStatusChanged,
|
|
this,
|
|
&ConversationsAdapter::onBannedStatusChanged,
|
|
Qt::UniqueConnection);
|
|
|
|
convSrcModel_.reset(new ConversationListModel(lrcInstance_));
|
|
convModel_->bindSourceModel(convSrcModel_.get());
|
|
searchSrcModel_.reset(new SearchResultsListModel(lrcInstance_));
|
|
searchModel_->bindSourceModel(searchSrcModel_.get());
|
|
|
|
updateConversationFilterData();
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::createSwarm(const QString& title,
|
|
const QString& description,
|
|
const QString& avatar,
|
|
const VectorString& participants)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
convModel->createConversation(participants,
|
|
{{"title", title},
|
|
{"description", description},
|
|
{"avatar", avatar}});
|
|
} |