mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 03:53:23 +02:00
contactmodel: cache profiles for non contacts profile
If we're a member of a group swarm, we will receive profiles from non contact (the other members of a conversation). This patch try to get from cache before calling getContact() to be able to retrieve profiles from non contacts if stored by the daemon Change-Id: I864f1d5dd9f65232751e170b930606d23241d283
This commit is contained in:
parent
77e019b02b
commit
c5e15d26a0
2 changed files with 41 additions and 30 deletions
|
@ -420,8 +420,14 @@ Utils::contactPhoto(LRCInstance* instance,
|
|||
try {
|
||||
auto& accInfo = instance->accountModel().getAccountInfo(
|
||||
accountId.isEmpty() ? instance->get_currentAccountId() : accountId);
|
||||
auto contactInfo = accInfo.contactModel->getContact(contactUri);
|
||||
auto contactPhoto = accInfo.contactModel->avatar(contactUri);
|
||||
if (!contactPhoto.isEmpty()) {
|
||||
photo = imageFromBase64String(contactPhoto);
|
||||
if (!photo.isNull())
|
||||
return Utils::scaleAndFrame(photo, size);
|
||||
}
|
||||
// If no avatar is found, generate one
|
||||
auto contactInfo = accInfo.contactModel->getContact(contactUri);
|
||||
auto bestName = accInfo.contactModel->bestNameForContact(contactUri);
|
||||
if (accInfo.profileInfo.type == profile::Type::SIP
|
||||
&& contactInfo.profileInfo.type == profile::Type::TEMPORARY) {
|
||||
|
@ -429,12 +435,6 @@ Utils::contactPhoto(LRCInstance* instance,
|
|||
} else if (contactInfo.profileInfo.type == profile::Type::TEMPORARY
|
||||
&& contactInfo.profileInfo.uri.isEmpty()) {
|
||||
photo = Utils::fallbackAvatar(QString(), QString());
|
||||
} else if (!contactPhoto.isEmpty()) {
|
||||
photo = imageFromBase64String(contactPhoto);
|
||||
if (photo.isNull()) {
|
||||
auto avatarName = contactInfo.profileInfo.uri == bestName ? QString() : bestName;
|
||||
photo = Utils::fallbackAvatar("jami:" + contactInfo.profileInfo.uri, avatarName);
|
||||
}
|
||||
} else {
|
||||
auto avatarName = contactInfo.profileInfo.uri == bestName ? QString() : bestName;
|
||||
photo = Utils::fallbackAvatar("jami:" + contactInfo.profileInfo.uri, avatarName);
|
||||
|
|
|
@ -133,6 +133,8 @@ public:
|
|||
|
||||
// Store if a profile is cached for a given URI.
|
||||
QSet<QString> cachedProfiles;
|
||||
// For non contacts (such as members of a group)
|
||||
QMap<QString, profile::Info> cachedProfilesInfo;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
|
@ -557,10 +559,9 @@ ContactModel::bestNameForContact(const QString& contactUri) const
|
|||
return owner.accountModel->bestNameForAccount(owner.id);
|
||||
QString res = contactUri;
|
||||
try {
|
||||
auto contact = getContact(contactUri);
|
||||
auto alias = displayName(contactUri).simplified();
|
||||
if (alias.isEmpty()) {
|
||||
return bestIdFromContactInfo(contact);
|
||||
return bestIdFromContactInfo(getContact(contactUri));
|
||||
}
|
||||
return alias;
|
||||
} catch (const std::out_of_range&) {
|
||||
|
@ -1184,16 +1185,11 @@ ContactModelPimpl::slotProfileReceived(const QString& accountId,
|
|||
return;
|
||||
}
|
||||
|
||||
// Make sure this is for a contact and not the linked account,
|
||||
// then just remove the URI from the cache list and notify.
|
||||
std::lock_guard<std::mutex> lk(contactsMtx_);
|
||||
if (contacts.find(peer) != contacts.end()) {
|
||||
// Remove the URI from the cache list and notify.
|
||||
cachedProfiles.remove(peer);
|
||||
// This signal should be listened to in order to update contact display names
|
||||
// and avatars in the client.
|
||||
Q_EMIT linked.profileUpdated(peer);
|
||||
}
|
||||
// Remove the URI from the cache list and notify.
|
||||
cachedProfiles.remove(peer);
|
||||
// This signal should be listened to in order to update contact display names
|
||||
// and avatars in the client.
|
||||
Q_EMIT linked.profileUpdated(peer);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1236,30 +1232,45 @@ ContactModelPimpl::slotUserSearchEnded(const QString& accountId,
|
|||
|
||||
template<typename Func>
|
||||
QString
|
||||
ContactModelPimpl::getCachedProfileProperty(const QString& contactUri, Func extractor)
|
||||
ContactModelPimpl::getCachedProfileProperty(const QString& peerUri, Func extractor)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(contactsMtx_);
|
||||
// For search results it's loaded and not in storage yet.
|
||||
if (searchResult.contains(contactUri)) {
|
||||
auto contact = searchResult.value(contactUri);
|
||||
if (searchResult.contains(peerUri)) {
|
||||
auto contact = searchResult.value(peerUri);
|
||||
return extractor(contact.profileInfo);
|
||||
}
|
||||
|
||||
// Try to find the contact.
|
||||
auto it = contacts.find(contactUri);
|
||||
if (it == contacts.end()) {
|
||||
return {};
|
||||
}
|
||||
auto it = contacts.find(peerUri);
|
||||
auto isContact = it != contacts.end();
|
||||
auto getPInfo = [&]() -> profile::Info& {
|
||||
if (!isContact) {
|
||||
auto itNonContact = cachedProfilesInfo.find(peerUri);
|
||||
if (itNonContact != cachedProfilesInfo.end()) {
|
||||
return *itNonContact;
|
||||
} else {
|
||||
profile::Info pInfo;
|
||||
pInfo.uri = peerUri;
|
||||
pInfo.type = profile::Type::TEMPORARY;
|
||||
cachedProfilesInfo.insert(peerUri, pInfo);
|
||||
return cachedProfilesInfo[peerUri];
|
||||
}
|
||||
} else {
|
||||
return it->profileInfo;
|
||||
}
|
||||
};
|
||||
profile::Info& pInfo = getPInfo();
|
||||
|
||||
// If we have a profile that appears to be recently cached, return the extracted property.
|
||||
if (cachedProfiles.contains(contactUri)) {
|
||||
return extractor(it->profileInfo);
|
||||
if (cachedProfiles.contains(peerUri)) {
|
||||
return extractor(pInfo);
|
||||
}
|
||||
|
||||
// Otherwise, update the profile info and return the extracted property.
|
||||
updateCachedProfile(it->profileInfo);
|
||||
updateCachedProfile(pInfo);
|
||||
|
||||
return extractor(it->profileInfo);
|
||||
return extractor(pInfo);
|
||||
}
|
||||
|
||||
} // namespace lrc
|
||||
|
|
Loading…
Add table
Reference in a new issue