1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-09-10 12:03:18 +02:00

conversations: refactor list reselection when making permanent

This should fix a race condition preventing the right conversation
from being selected after an outgoing interaction and, more rarely,
accepting an invitation.

Change-Id: Iccd1f91ba4d46285c2f1e4594122a736824b752f
This commit is contained in:
Andreas Traczyk 2021-06-22 14:31:42 -04:00
parent 392c423bc1
commit 83bb6fb082
15 changed files with 58 additions and 131 deletions

View file

@ -350,7 +350,6 @@ AccountAdapter::connectAccount(const QString& accountId)
QObject::disconnect(accountStatusChangedConnection_);
QObject::disconnect(accountProfileUpdatedConnection_);
QObject::disconnect(contactAddedConnection_);
QObject::disconnect(addedToConferenceConnection_);
QObject::disconnect(bannedStatusChangedConnection_);
@ -368,23 +367,6 @@ AccountAdapter::connectAccount(const QString& accountId)
Q_EMIT accountStatusChanged(accountId);
});
contactAddedConnection_ = QObject::connect(
accInfo.contactModel.get(),
&lrc::api::ContactModel::contactAdded,
[this, accountId](const QString& contactUri) {
const auto& convInfo = lrcInstance_->getConversationFromConvUid(
lrcInstance_->get_selectedConvUid());
if (convInfo.uid.isEmpty()) {
return;
}
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
auto selectedContactUri
= accInfo.contactModel->getContact(convInfo.participants.at(0)).profileInfo.uri;
if (contactUri == selectedContactUri) {
Q_EMIT selectedContactAdded(convInfo.uid);
}
});
addedToConferenceConnection_
= QObject::connect(accInfo.callModel.get(),
&NewCallModel::callAddedToConference,

View file

@ -96,7 +96,6 @@ public:
Q_SIGNALS:
// Trigger other components to reconnect account related signals.
void accountStatusChanged(QString accountId);
void selectedContactAdded(QString convId);
// Send report failure to QML to make it show the right UI state .
void reportFailure();
@ -115,7 +114,6 @@ private:
QMetaObject::Connection accountStatusChangedConnection_;
QMetaObject::Connection accountProfileUpdatedConnection_;
QMetaObject::Connection contactAddedConnection_;
QMetaObject::Connection addedToConferenceConnection_;
QMetaObject::Connection bannedStatusChangedConnection_;
QMetaObject::Connection registeredNameSavedConnection_;

View file

@ -332,22 +332,14 @@ void
CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
{
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
if (!convInfo.uid.isEmpty()) {
lrcInstance_->getAccountInfo(accountId).callModel->accept(convInfo.callId);
auto& accInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
accInfo.callModel->setCurrentCall(convInfo.callId);
if (convInfo.uid.isEmpty())
return;
auto contactUri = convInfo.participants.front();
if (contactUri.isEmpty()) {
return;
}
try {
auto& contact = accInfo.contactModel->getContact(contactUri);
if (contact.profileInfo.type == lrc::api::profile::Type::PENDING) {
lrcInstance_->getCurrentConversationModel()->makePermanent(convInfo.uid);
}
} catch (...) {
}
lrcInstance_->getAccountInfo(accountId).callModel->accept(convInfo.callId);
auto& accInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
accInfo.callModel->setCurrentCall(convInfo.callId);
if (convInfo.isRequest) {
lrcInstance_->makeConversationPermanent(convInfo.uid, accountId);
}
}

View file

@ -116,8 +116,7 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray,
auto& convInfo = lrcInstance_->getConversationFromPeerUri(peerUri, accountId);
if (convInfo.uid.isEmpty())
return;
lrcInstance_->getAccountInfo(accountId).conversationModel->makePermanent(
convInfo.uid);
lrcInstance_->makeConversationPermanent(convInfo.uid, accountId);
});
connect(systemTray_,
&SystemTray::refusePendingActivated,
@ -301,12 +300,6 @@ ConversationsAdapter::onFilterChanged()
Q_EMIT indexRepositionRequested();
}
void
ConversationsAdapter::onNewConversation(const QString& convUid)
{
updateConversationForNewContact(convUid);
}
void
ConversationsAdapter::onConversationCleared(const QString& convUid)
{
@ -330,6 +323,17 @@ ConversationsAdapter::onSearchResultUpdated()
searchSrcModel_->onSearchResultsUpdated();
}
void
ConversationsAdapter::onConversationReady(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
lrcInstance_->selectConversation(convId);
Q_EMIT conversationReady(convId);
}
void
ConversationsAdapter::updateConversationFilterData()
{
@ -438,12 +442,6 @@ ConversationsAdapter::connectConversationModel()
&ConversationsAdapter::onFilterChanged,
Qt::UniqueConnection);
QObject::connect(currentConversationModel,
&lrc::api::ConversationModel::newConversation,
this,
&ConversationsAdapter::onNewConversation,
Qt::UniqueConnection);
QObject::connect(currentConversationModel,
&lrc::api::ConversationModel::conversationCleared,
this,
@ -462,6 +460,12 @@ ConversationsAdapter::connectConversationModel()
&ConversationsAdapter::onSearchResultUpdated,
Qt::UniqueConnection);
QObject::connect(currentConversationModel,
&lrc::api::ConversationModel::conversationReady,
this,
&ConversationsAdapter::onConversationReady,
Qt::UniqueConnection);
convSrcModel_.reset(new ConversationListModel(lrcInstance_));
convModel_->bindSourceModel(convSrcModel_.get());
searchSrcModel_.reset(new SearchResultsListModel(lrcInstance_));
@ -471,26 +475,3 @@ ConversationsAdapter::connectConversationModel()
return true;
}
void
ConversationsAdapter::updateConversationForNewContact(const QString& convUid)
{
auto* convModel = lrcInstance_->getCurrentConversationModel();
if (convModel == nullptr) {
return;
}
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid);
if (!convInfo.uid.isEmpty() && !convInfo.participants.isEmpty()) {
try {
const auto contact = convModel->owner.contactModel->getContact(convInfo.participants[0]);
if (!contact.profileInfo.uri.isEmpty()
&& contact.profileInfo.uri == lrcInstance_->get_selectedConvUid()) {
lrcInstance_->selectConversation(convUid, convInfo.accountId);
convModel_->selectSourceRow(lrcInstance_->indexOf(convUid));
}
} catch (...) {
return;
}
}
}

View file

@ -58,6 +58,7 @@ Q_SIGNALS:
void navigateToWelcomePageRequested();
void indexRepositionRequested();
void conversationReady(const QString& convId);
private Q_SLOTS:
void onCurrentAccountIdChanged();
@ -78,10 +79,10 @@ private Q_SLOTS:
void onProfileUpdated(const QString&);
void onConversationUpdated(const QString&);
void onFilterChanged();
void onNewConversation(const QString&);
void onConversationCleared(const QString&);
void onSearchStatusChanged(const QString&);
void onSearchResultUpdated();
void onConversationReady(const QString&);
void updateConversationFilterData();

View file

@ -433,6 +433,19 @@ LRCInstance::deselectConversation()
set_selectedConvUid();
}
void
LRCInstance::makeConversationPermanent(const QString& convId, const QString& accountId)
{
auto aId = accountId.isEmpty() ? currentAccountId_ : accountId;
const auto& accInfo = accountModel().getAccountInfo(aId);
auto cId = convId.isEmpty() ? selectedConvUid_ : convId;
if (cId.isEmpty()) {
qWarning() << Q_FUNC_INFO << "no Id provided";
return;
}
accInfo.conversationModel.get()->makePermanent(cId);
}
void
LRCInstance::finish()
{

View file

@ -102,6 +102,8 @@ public:
Q_INVOKABLE void selectConversation(const QString& convId, const QString& accountId = {});
Q_INVOKABLE void deselectConversation();
Q_INVOKABLE void makeConversationPermanent(const QString& convId = {},
const QString& accountId = {});
const QString& getCurrentAccountId();
void setCurrentAccountId(const QString& accountId = {});

View file

@ -416,14 +416,6 @@ Rectangle {
visible: false
Connections {
target: MessagesAdapter
function onInvitationAccepted() {
mainViewSidePanel.selectTab(SidePanelTabBar.Conversations)
}
}
Component.onCompleted: {
recordBox.x = Qt.binding(function() {
var i = ((mainViewStack.visible && mainViewStack.width > 1000) ?
@ -586,7 +578,7 @@ Rectangle {
sequence: "Ctrl+Shift+A"
context: Qt.ApplicationShortcut
onActivated: {
UtilsAdapter.makePermanentCurrentConv()
LRCInstance.makeConversationPermanent()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
}

View file

@ -115,14 +115,6 @@ Rectangle {
}
}
Connections {
target: AccountAdapter
function onSelectedContactAdded(convId) {
MessagesAdapter.updateConversationForAddedContact()
}
}
JamiFileDialog {
id: jamiFileDialog

View file

@ -154,7 +154,7 @@ Rectangle {
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
MessagesAdapter.sendContactRequest()
MessagesAdapter.sendConversationRequest()
CallAdapter.placeAudioOnlyCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
@ -177,7 +177,7 @@ Rectangle {
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
MessagesAdapter.sendContactRequest()
MessagesAdapter.sendConversationRequest()
CallAdapter.placeCall()
communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
}
@ -217,7 +217,7 @@ Rectangle {
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
MessagesAdapter.sendContactRequest()
MessagesAdapter.sendConversationRequest()
visible = false
}
}

View file

@ -36,18 +36,18 @@ Rectangle {
anchors.fill: parent
Connections {
target: AccountAdapter
target: LRCInstance
function onSelectedContactAdded(convId) {
function onCurrentAccountIdChanged() {
clearContactSearchBar()
LRCInstance.selectConversation(convId)
}
}
Connections {
target: LRCInstance
target: ConversationsAdapter
function onCurrentAccountIdChanged() {
function onConversationReady() {
selectTab(SidePanelTabBar.Conversations)
clearContactSearchBar()
}
}

View file

@ -200,24 +200,9 @@ MessagesAdapter::connectConversationModel()
}
void
MessagesAdapter::sendContactRequest()
MessagesAdapter::sendConversationRequest()
{
const auto convUid = lrcInstance_->get_selectedConvUid();
if (!convUid.isEmpty()) {
lrcInstance_->getCurrentConversationModel()->makePermanent(convUid);
}
}
void
MessagesAdapter::updateConversationForAddedContact()
{
auto convModel = lrcInstance_->getCurrentConversationModel();
const auto& convInfo = lrcInstance_->getConversationFromConvUid(
lrcInstance_->get_selectedConvUid());
clear();
setConversationProfileData(convInfo);
// printHistory(*convModel, convInfo.interactions);
lrcInstance_->makeConversationPermanent();
}
void
@ -231,7 +216,7 @@ MessagesAdapter::slotSendMessageContentSaved(const QString& content)
Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared()));
setInvitation(false);
clear();
clearChatView();
auto restoredContent = lrcInstance_->getContentDraft(lrcInstance_->get_selectedConvUid(),
lrcInstance_->getCurrentAccountId());
setSendMessageContent(restoredContent);
@ -586,7 +571,7 @@ MessagesAdapter::setIsSwarm(bool isSwarm)
}
void
MessagesAdapter::clear()
MessagesAdapter::clearChatView()
{
QString s = QString::fromLatin1("clearMessages();");
QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s));
@ -733,11 +718,9 @@ MessagesAdapter::contactIsComposing(const QString& uid, const QString& contactUr
void
MessagesAdapter::acceptInvitation(const QString& convUid)
{
const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid;
lrcInstance_->getCurrentConversationModel()->makePermanent(currentConvUid);
lrcInstance_->makeConversationPermanent(convUid);
if (convUid == currentConvUid_)
currentConvUid_.clear();
Q_EMIT invitationAccepted();
}
void

View file

@ -43,8 +43,7 @@ protected:
Q_INVOKABLE void setupChatView(const QString& convUid);
Q_INVOKABLE void connectConversationModel();
Q_INVOKABLE void sendContactRequest();
Q_INVOKABLE void updateConversationForAddedContact();
Q_INVOKABLE void sendConversationRequest();
Q_INVOKABLE void removeConversation(const QString& accountId,
const QString& convUid,
bool banContact = false);
@ -81,7 +80,7 @@ protected:
bool isSwarm = false,
bool needsSyncing = false);
void setIsSwarm(bool isSwarm);
void clear();
void clearChatView();
void printHistory(ConversationModel& conversationModel, MessagesList interactions);
void updateHistory(ConversationModel& conversationModel,
MessagesList interactions,
@ -101,7 +100,6 @@ protected:
Q_SIGNALS:
void contactBanned();
void invitationAccepted();
void newInteraction(int type);
public Q_SLOTS:

View file

@ -156,12 +156,6 @@ UtilsAdapter::getCurrConvId()
return lrcInstance_->get_selectedConvUid();
}
void
UtilsAdapter::makePermanentCurrentConv()
{
lrcInstance_->getCurrentConversationModel()->makePermanent(lrcInstance_->get_selectedConvUid());
}
const QStringList
UtilsAdapter::getCurrAccList()
{

View file

@ -54,7 +54,6 @@ public:
Q_INVOKABLE QString getBestId(const QString& accountId);
Q_INVOKABLE const QString getBestId(const QString& accountId, const QString& uid);
Q_INVOKABLE const QString getCurrConvId();
Q_INVOKABLE void makePermanentCurrentConv();
Q_INVOKABLE const QStringList getCurrAccList();
Q_INVOKABLE int getAccountListSize();
Q_INVOKABLE bool hasCall(const QString& accountId);