conversation model: use map to store conversation by id

GitLab: #1794
Change-Id: I559d306a9f82453e2fbad653f1fe05e6d25a1f6e
This commit is contained in:
Adrien Béraud
2025-11-26 15:22:01 -05:00
parent d714dcd31d
commit d01fec2ba8

View File

@@ -227,6 +227,8 @@ public:
ConversationModel::ConversationQueueProxy filteredConversations; ConversationModel::ConversationQueueProxy filteredConversations;
ConversationModel::ConversationQueueProxy customFilteredConversations; ConversationModel::ConversationQueueProxy customFilteredConversations;
std::map<QString, std::reference_wrapper<conversation::Info>> conversationMap;
QString currentFilter; QString currentFilter;
FilterType typeFilter; FilterType typeFilter;
FilterType customTypeFilter; FilterType customTypeFilter;
@@ -420,15 +422,16 @@ ConversationModel::allFilteredConversations() const
QMap<ConferenceableItem, ConferenceableValue> QMap<ConferenceableItem, ConferenceableValue>
ConversationModel::getConferenceableConversations(const QString& convId, const QString& filter) const ConversationModel::getConferenceableConversations(const QString& convId, const QString& filter) const
{ {
auto conversationIdx = pimpl_->indexOf(convId); auto conversationIt = pimpl_->conversationMap.find(convId);
if (conversationIdx == -1 || !owner.enabled) { if (conversationIt == pimpl_->conversationMap.end() || !owner.enabled) {
return {}; return {};
} }
auto& conversation = conversationIt->second.get();
QMap<ConferenceableItem, ConferenceableValue> result; QMap<ConferenceableItem, ConferenceableValue> result;
ConferenceableValue callsVector, contactsVector; ConferenceableValue callsVector, contactsVector;
auto currentConfId = pimpl_->conversations.at(conversationIdx).confId; auto& currentConfId = conversation.confId;
auto currentCallId = pimpl_->conversations.at(conversationIdx).callId; auto& currentCallId = conversation.callId;
auto calls = pimpl_->lrc.getCalls(); auto calls = pimpl_->lrc.getCalls();
auto conferences = pimpl_->lrc.getConferences(owner.id); auto conferences = pimpl_->lrc.getConferences(owner.id);
auto& conversations = pimpl_->conversations; auto& conversations = pimpl_->conversations;
@@ -2399,15 +2402,16 @@ ConversationModelPimpl::slotConversationReady(const QString& accountId, const QS
} }
} }
int conversationIdx = indexOf(conversationId); auto conversationIt = conversationMap.find(conversationId);
bool conversationExists = conversationIdx >= 0; bool conversationExists = conversationIt != conversationMap.end();
if (!conversationExists) if (!conversationExists) {
addSwarmConversation(conversationId); addSwarmConversation(conversationId);
auto& conversation = getConversationForUid(conversationId).get(); conversationIt = conversationMap.find(conversationId);
}
auto& conversation = conversationIt->second.get();
if (conversationExists) { if (conversationExists) {
// if swarm request already exists, update participnts // if swarm request already exists, update participnts
auto& conversation = getConversationForUid(conversationId).get();
conversation.participants = participants; conversation.participants = participants;
const MapStringString& details = ConfigurationManager::instance().conversationInfos(accountId, conversationId); const MapStringString& details = ConfigurationManager::instance().conversationInfos(accountId, conversationId);
conversation.infos = details; conversation.infos = details;
@@ -2418,7 +2422,7 @@ ConversationModelPimpl::slotConversationReady(const QString& accountId, const QS
conversation.isRequest = false; conversation.isRequest = false;
conversation.needsSyncing = false; conversation.needsSyncing = false;
Q_EMIT linked.conversationUpdated(conversationId); Q_EMIT linked.conversationUpdated(conversationId);
Q_EMIT linked.dataChanged(conversationIdx); Q_EMIT linked.dataChanged(indexOf(conversationId));
ConfigurationManager::instance().loadConversation(linked.owner.id, conversationId, "", 0); ConfigurationManager::instance().loadConversation(linked.owner.id, conversationId, "", 0);
auto& peers = peersForConversation(conversation); auto& peers = peersForConversation(conversation);
if (peers.size() == 1) if (peers.size() == 1)
@@ -2438,18 +2442,17 @@ ConversationModelPimpl::slotConversationReady(const QString& accountId, const QS
void void
ConversationModelPimpl::slotConversationRemoved(const QString& accountId, const QString& conversationId) ConversationModelPimpl::slotConversationRemoved(const QString& accountId, const QString& conversationId)
{ {
auto conversationIndex = indexOf(conversationId); if (accountId != linked.owner.id)
if (accountId != linked.owner.id || conversationIndex < 0)
return; return;
try { try {
auto& conversation = getConversationForUid(conversationId).get();
auto removeConversation = [&]() { auto removeConversation = [&]() {
// remove swarm conversation // remove swarm conversation
eraseConversation(conversationIndex); eraseConversation(conversationId);
invalidateModel(); invalidateModel();
Q_EMIT linked.conversationRemoved(conversationId); Q_EMIT linked.conversationRemoved(conversationId);
}; };
auto& conversation = getConversationForUid(conversationId).get();
auto& peers = peersForConversation(conversation); auto& peers = peersForConversation(conversation);
if (peers.isEmpty()) { if (peers.isEmpty()) {
removeConversation(); removeConversation();
@@ -2506,9 +2509,10 @@ ConversationModelPimpl::slotConversationMemberEvent(const QString& accountId,
} }
} }
// update participants // update participants
try {
auto& conversation = getConversationForUid(conversationId).get(); auto& conversation = getConversationForUid(conversationId).get();
const VectorMapStringString& members = ConfigurationManager::instance().getConversationMembers(linked.owner.id, const VectorMapStringString& members
conversationId); = ConfigurationManager::instance().getConversationMembers(linked.owner.id, conversationId);
QVector<member::Member> participants; QVector<member::Member> participants;
VectorString membersRemaining; VectorString membersRemaining;
for (auto& member : members) { for (auto& member : members) {
@@ -2518,6 +2522,8 @@ ConversationModelPimpl::slotConversationMemberEvent(const QString& accountId,
} }
conversation.participants = participants; conversation.participants = participants;
invalidateModel(); invalidateModel();
} catch (...) {
}
Q_EMIT linked.modelChanged(); Q_EMIT linked.modelChanged();
Q_EMIT linked.conversationUpdated(conversationId); Q_EMIT linked.conversationUpdated(conversationId);
Q_EMIT linked.dataChanged(indexOf(conversationId)); Q_EMIT linked.dataChanged(indexOf(conversationId));
@@ -2956,14 +2962,24 @@ ConversationModelPimpl::getConversation(const FilterPredicate& pred, const bool
} }
} }
throw std::out_of_range("Conversation out of range"); throw std::out_of_range("Conversation not found");
} }
std::reference_wrapper<conversation::Info> std::reference_wrapper<conversation::Info>
ConversationModelPimpl::getConversationForUid(const QString& uid, const bool searchResultIncluded) const ConversationModelPimpl::getConversationForUid(const QString& uid, const bool searchResultIncluded) const
{ {
return getConversation([uid](const conversation::Info& conv) -> bool { return uid == conv.uid; }, auto it = conversationMap.find(uid);
searchResultIncluded); if (it != conversationMap.end())
return it->second;
if (searchResultIncluded) {
auto sr = std::find_if(searchResults.begin(), searchResults.end(), [&](const auto& conv) {
return conv.uid == uid;
});
if (sr != searchResults.end()) {
return std::remove_const_t<conversation::Info&>(*sr);
}
}
throw std::out_of_range("Conversation not found");
} }
std::reference_wrapper<conversation::Info> std::reference_wrapper<conversation::Info>
@@ -3725,16 +3741,19 @@ ConversationModelPimpl::invalidateModel()
void void
ConversationModelPimpl::emplaceBackConversation(conversation::Info&& conversation) ConversationModelPimpl::emplaceBackConversation(conversation::Info&& conversation)
{ {
if (indexOf(conversation.uid) != -1) if (conversationMap.find(conversation.uid) != conversationMap.end())
return; return;
Q_EMIT linked.beginInsertRows(conversations.size()); Q_EMIT linked.beginInsertRows(conversations.size());
conversations.emplace_back(std::move(conversation)); conversations.emplace_back(std::move(conversation));
auto& newConv = conversations.back();
conversationMap.emplace(newConv.uid, newConv);
Q_EMIT linked.endInsertRows(); Q_EMIT linked.endInsertRows();
} }
void void
ConversationModelPimpl::eraseConversation(const QString& convId) ConversationModelPimpl::eraseConversation(const QString& convId)
{ {
conversationMap.erase(convId);
eraseConversation(indexOf(convId)); eraseConversation(indexOf(convId));
} }
@@ -3902,12 +3921,13 @@ ConversationModelPimpl::slotConversationPreferencesUpdated(const QString&,
const QString& conversationId, const QString& conversationId,
const MapStringString& preferences) const MapStringString& preferences)
{ {
auto conversationIdx = indexOf(conversationId); try {
if (conversationIdx < 0) auto& conversation = getConversationForUid(conversationId).get();
return;
auto& conversation = conversations[conversationIdx];
conversation.preferences = preferences; conversation.preferences = preferences;
Q_EMIT linked.conversationPreferencesUpdated(conversationId); Q_EMIT linked.conversationPreferencesUpdated(conversationId);
} catch (const std::out_of_range&) {
qWarning() << Q_FUNC_INFO << "Unable to find conversation" << conversationId;
}
} }
} // namespace lrc } // namespace lrc