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