mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-04-21 21:52:03 +02:00

In the members list, a right click allow the user to access some actions such as: + Perform a video or audio call with a member + Open a 1:1 conversation with this member + Block this contact + If allowed, kick a member from the conversation In the future, other actions can be added, such as promote a user to administrator. GitLab: #340 Change-Id: I3824ad4efa8faf89479e99c93b98d3dd9781582d
602 lines
No EOL
22 KiB
C++
602 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);
|
|
}
|
|
|
|
QVariantMap
|
|
ConversationsAdapter::getConvInfoMap(const QString& convId)
|
|
{
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
if (convInfo.participants.empty())
|
|
return {};
|
|
QString peerUri {};
|
|
QString bestId {};
|
|
if (convInfo.isCoreDialog()) {
|
|
try {
|
|
const auto& accountInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
|
|
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)},
|
|
{"uri", peerUri},
|
|
{"isSwarm", convInfo.isSwarm()},
|
|
{"isRequest", convInfo.isRequest},
|
|
{"needsSyncing", convInfo.needsSyncing},
|
|
{"isAudioOnly", isAudioOnly},
|
|
{"callState", static_cast<int>(callState)},
|
|
{"callStackViewShouldShow", callStackViewShouldShow},
|
|
{"readOnly", convInfo.readOnly}};
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::restartConversation(const QString& convId)
|
|
{
|
|
// make sure this conversation meets the criteria of a "restartable" conv
|
|
// 'readOnly' implies 'isSwarm'
|
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
|
if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog() || !convInfo.readOnly) {
|
|
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() && !convInfo.readOnly
|
|
&& 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->updateConversationInfo(convId, details);
|
|
}
|
|
|
|
void
|
|
ConversationsAdapter::updateConversationDescription(const QString& convId,
|
|
const QString& newDescription)
|
|
{
|
|
auto convModel = lrcInstance_->getCurrentConversationModel();
|
|
QMap<QString, QString> details;
|
|
details["description"] = newDescription;
|
|
convModel->updateConversationInfo(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}});
|
|
} |