fix slow loading when many friends

This commit is contained in:
gaelle 2025-02-21 15:57:56 +01:00
parent b4b573a027
commit c1013baac5
14 changed files with 384 additions and 384 deletions

View file

@ -59,6 +59,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
auto itemCore = item.objectCast<FriendCore>();
return itemCore->getDefaultAddress().length() > 0 &&
itemCore->getDefaultAddress() == friendCore->getDefaultAddress() ||
itemCore->getFriendModel() && friendCore->getFriendModel() &&
itemCore->getFriendModel()->getFriend() == friendCore->getFriendModel()->getFriend();
});
if (haveContact == mList.end()) {
@ -117,8 +118,9 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
address->asString())); // linphone Friend object remove specific address.
contacts->append(contact);
} else if (!it->getPhoneNumber().empty()) {
auto phoneNumber = it->getPhoneNumber();
linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
linphoneFriend->setAddress(address);
linphoneFriend->addPhoneNumber(phoneNumber);
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber()));
contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber()));
@ -128,6 +130,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
mModelConnection->invokeToCore([this, contacts]() {
setResults(*contacts);
delete contacts;
emit resultsProcessed();
});
});
qDebug() << log().arg("Initialized");

View file

@ -72,6 +72,8 @@ signals:
void friendCreated(int index, FriendGui *data);
void friendStarredChanged();
void resultsProcessed();
void initialized();
private:

View file

@ -25,11 +25,13 @@
#include "core/friend/FriendCore.hpp"
MagicSearchProxy::MagicSearchProxy(QObject *parent) : LimitProxy(parent) {
setList(MagicSearchList::create());
auto magicSearchList = MagicSearchList::create();
setList(magicSearchList);
connect(this, &MagicSearchProxy::forceUpdate, [this] {
if (mList) emit mList->lSearch(mSearchText, getSourceFlags(), getAggregationFlag(), getMaxResults());
});
connect(App::getInstance(), &App::currentDateChanged, this, &MagicSearchProxy::forceUpdate);
connect(magicSearchList.get(), &MagicSearchList::resultsProcessed, this, &MagicSearchProxy::resultsProcessed);
}
MagicSearchProxy::~MagicSearchProxy() {

View file

@ -82,6 +82,7 @@ signals:
void parentProxyChanged();
void hideListProxyChanged();
void initialized();
void resultsProcessed();
protected:
MagicSearchProxy *mParentProxy = nullptr;

View file

@ -81,31 +81,23 @@ void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr<linphone::M
auto appFriends = ToolModel::getAppFriendList();
auto ldapFriends = ToolModel::getLdapFriendList();
std::list<std::shared_ptr<linphone::SearchResult>> finalResults;
emit searchResultsReceived(results);
for (auto result : results) {
auto f = result->getFriend();
auto fList = f ? f->getFriendList() : nullptr;
qDebug() << log().arg("") << (f ? f->getName().c_str() : "NoFriend") << ", "
<< (result->getAddress() ? result->getAddress()->asString().c_str() : "NoAddr") << " / "
<< (fList ? fList->getDisplayName().c_str() : "NoList") << result->getSourceFlags() << " / "
<< (f ? f.get() : nullptr);
// qDebug() << log().arg("") << (f ? f->getName().c_str() : "NoFriend") << ", "
// << (result->getAddress() ? result->getAddress()->asString().c_str() : "NoAddr") << " / "
// << (fList ? fList->getDisplayName().c_str() : "NoList") << result->getSourceFlags() << " / "
// << (f ? f.get() : nullptr);
bool isLdap = (result->getSourceFlags() & (int)linphone::MagicSearch::Source::LdapServers) != 0;
// Do not add it into ldap_friends if it already exists in app_friends.
if (isLdap && f && (!fList || fList->getDisplayName() != "app_friends") &&
!ToolModel::friendIsInFriendList(appFriends, f)) { // Double check because of SDK merging that lead to
if (isLdap && f && (!fList || fList->getDisplayName() != "app_friends")) { // Double check because of SDK merging that lead to
// use a ldap result as of app_friends/ldap_friends.
updateFriendListWithFriend(f, ToolModel::getLdapFriendList());
updateFriendListWithFriend(f, ldapFriends);
}
auto resultIt =
std::find_if(finalResults.begin(), finalResults.end(), [result](std::shared_ptr<linphone::SearchResult> r) {
return r->getAddress() && r->getAddress()->weakEqual(result->getAddress());
});
if (resultIt == finalResults.end()) finalResults.push_back(result);
else if (fList && fList->getDisplayName() == "app_friends") *resultIt = result; // replace if local friend
}
emit searchResultsReceived(finalResults);
}
void MagicSearchModel::onMoreResultsAvailable(const std::shared_ptr<linphone::MagicSearch> &magicSearch,

View file

@ -297,12 +297,11 @@ std::shared_ptr<linphone::FriendList> ToolModel::getLdapFriendList() {
bool ToolModel::friendIsInFriendList(const std::shared_ptr<linphone::FriendList> &friendList,
const std::shared_ptr<linphone::Friend> &f) {
for (auto contact : friendList->getFriends()) {
if (f == contact) {
return true;
}
}
return false;
auto friends = friendList->getFriends();
auto it = std::find_if(friends.begin(), friends.end(), [f] (std::shared_ptr<linphone::Friend> linFriend) {
return linFriend == f;
});
return (it != friends.end());
}
// Load downloaded codecs like OpenH264 (needs to be after core is created and has loaded its plugins, as

View file

@ -7,9 +7,10 @@ import Linphone
Control.ScrollBar {
id: mainItem
padding: 0
property color color: DefaultStyle.grey_850
contentItem: Rectangle {
implicitWidth: 6 * DefaultStyle.dp
radius: 32 * DefaultStyle.dp
color: DefaultStyle.grey_850
color: mainItem.color
}
}

View file

@ -8,9 +8,11 @@ import ConstantsCpp 1.0
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Flickable{
Flickable {
id: mainItem
flickableDirection: Flickable.VerticalFlick
property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below display name.
property bool showActions: false // Display actions layout (call buttons)
@ -44,21 +46,20 @@ Flickable{
property int sectionsPixelSize: 16 * DefaultStyle.dp
property int sectionsWeight: 800 * DefaultStyle.dp
property int sectionsSpacing: 18 * DefaultStyle.dp
property int busyIndicatorSize: 40 * DefaultStyle.dp
property int itemsRightMargin: 39 * DefaultStyle.dp
property int count: contactsList.count + suggestionsList.count + favoritesList.count
signal resultsReceived()
contentHeight: contentsLayout.height
rightMargin: itemsRightMargin
signal contactStarredChanged()
signal contactDeletionRequested(FriendGui contact)
signal contactAddedToSelection(string address)
signal contactRemovedFromSelection(string address)
signal contactSelected(FriendGui contact)
contentWidth: width
contentHeight: contentsLayout.height
function selectContact(address) {
var index = contactsProxy.loadUntil(address)// Be sure to have this address in proxy if it exists
if (index != -1) {
@ -125,12 +126,9 @@ Flickable{
suggestionsList.highlightedContact = highlightedContact
}
onResultsReceived: {
loading = false
mainItem.contentY = 0
}
onSearchBarTextChanged: {
if(!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
console.log("change search text")
searchText = searchBarText.length === 0 ? "*" : searchBarText
}
}
@ -139,17 +137,11 @@ Flickable{
searchText = searchBarText.length === 0 ? "*" : searchBarText
}
}
onSearchTextChanged: loading = true
onAtYEndChanged: if(atYEnd) {
if( (contactsProxy.haveMore && contactList.expanded ) || mainItem.hideSuggestions) contactsProxy.displayMore()
else suggestionsProxy.displayMore()
}
Behavior on contentY{
NumberAnimation {
duration: 500
easing.type: Easing.OutExpo
}
onSearchTextChanged: {
console.log("search texte changed, loading...")
loading = true
}
Keys.onPressed: (event)=> {
if(!event.accepted){
if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){
@ -189,7 +181,12 @@ Flickable{
sourceFlags: mainItem.sourceFlags
onModelReset: {
mainItem.resetSelections()
mainItem.resultsReceived()
}
onResultsProcessed: {
console.log("result processed list view")
mainItem.loading = false
mainItem.contentY = 0
}
onInitialized: {
@ -200,30 +197,40 @@ Flickable{
}
}
onAtYEndChanged: if(atYEnd) {
if( (contactsProxy.haveMore && contactList.expanded ) || mainItem.hideSuggestions) contactsProxy.displayMore()
else suggestionsProxy.displayMore()
}
Behavior on contentY{
NumberAnimation {
duration: 500
easing.type: Easing.OutExpo
}
}
Control.ScrollBar.vertical: ScrollBar {
id: scrollbar
rightPadding: 8 * DefaultStyle.dp
topPadding: mainItem.haveFavorites ? 24 * DefaultStyle.dp : 0 // Avoid to be on top of collapse button
z: 1
topPadding: 24 * DefaultStyle.dp // Avoid to be on top of collapse button
active: true
interactive: true
policy: mainItem.contentHeight > mainItem.height ? Control.ScrollBar.AlwaysOn : Control.ScrollBar.AlwaysOff
visible: mainItem.contentHeight > mainItem.height
policy: Control.ScrollBar.AsNeeded
}
ColumnLayout{
ColumnLayout {
id: contentsLayout
width: parent.width
spacing: 20 * DefaultStyle.dp
width: mainItem.width
spacing: 0//20 * DefaultStyle.dp
BusyIndicator {
Layout.alignment: Qt.AlignCenter
Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0
Layout.preferredWidth: 60 * DefaultStyle.dp
indicatorHeight: 60 * DefaultStyle.dp
indicatorWidth: 60 * DefaultStyle.dp
id: busyIndicator
visible: mainItem.loading
indicatorColor: DefaultStyle.main1_500_main
width: mainItem.busyIndicatorSize
height: mainItem.busyIndicatorSize
Layout.preferredWidth: mainItem.busyIndicatorSize
Layout.preferredHeight: mainItem.busyIndicatorSize
Layout.alignment: Qt.AlignCenter | Qt.AlignVCenter
}
ContactListView{
@ -231,6 +238,8 @@ Flickable{
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
sectionsWeight: mainItem.sectionsWeight
sectionsPixelSize: mainItem.sectionsPixelSize
interactive: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
@ -241,6 +250,7 @@ Flickable{
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
title: qsTr('Favoris')
itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: (contactGui) => {
@ -273,6 +283,7 @@ Flickable{
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
itemsRightMargin: mainItem.itemsRightMargin
title: qsTr('Contacts')
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
@ -312,6 +323,7 @@ Flickable{
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
title: qsTr('Suggestions')
itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: (contactGui) => {

View file

@ -114,7 +114,7 @@ FocusScope {
id: actionButtons
visible: mainItem.showActions
spacing: visible ? 10 * DefaultStyle.dp : 0
Button {
IconButton {
id: callButton
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
@ -128,7 +128,7 @@ FocusScope {
KeyNavigation.left: chatButton
KeyNavigation.right: videoCallButton
}
Button {
IconButton {
id: videoCallButton
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
@ -142,7 +142,7 @@ FocusScope {
KeyNavigation.left: callButton
KeyNavigation.right: chatButton
}
Button {
IconButton {
id: chatButton
visible: actionButtons.visible && !SettingsCpp.disableChatFeature
Layout.preferredWidth: 45 * DefaultStyle.dp

View file

@ -45,7 +45,6 @@ ListView {
property bool expanded: true
property int headerHeight: headerItem?.height
signal resultsReceived()
signal contactDeletionRequested(FriendGui contact)
signal contactSelected(FriendGui contact) // Click/Space/Enter
signal addContactToSelection(var address)

View file

@ -45,6 +45,7 @@ Loader {
MultiEffect {
id: effect2
enabled: effectEnabled
visible: mainItem.useColor
property bool effectEnabled: mainItem.useColor
anchors.fill: effect

View file

@ -191,14 +191,15 @@ Item {
id: listPopup
width: magicSearchBar.width
property int maxHeight: 400 * DefaultStyle.dp
property bool displayScrollbar: contactList.contentHeight + topPadding + bottomPadding> maxHeight
height: contactList.haveContacts ? Math.min(contactList.contentHeight + topPadding + bottomPadding, maxHeight) : 0
property bool displayScrollbar: contactList.height > maxHeight
height: Math.min(contactList.contentHeight, maxHeight) + topPadding + bottomPadding
y: magicSearchBar.height
// closePolicy: Popup.NoAutoClose
topPadding: contactList.haveContacts ? 20 * DefaultStyle.dp : 0
bottomPadding: contactList.haveContacts ? 20 * DefaultStyle.dp : 0
rightPadding: 10 * DefaultStyle.dp
closePolicy: Popup.CloseOnEscape
topPadding: 20 * DefaultStyle.dp
bottomPadding: contactList.haveContacts ? 20 * DefaultStyle.dp : 10 * DefaultStyle.dp
rightPadding: 8 * DefaultStyle.dp
leftPadding: 20 * DefaultStyle.dp
visible: magicSearchBar.text.length != 0
background: Item {
anchors.fill: parent
@ -219,24 +220,11 @@ Item {
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
}
ScrollBar {
id: scrollbar
Component.onCompleted: x = -10 * DefaultStyle.dp
policy: Control.ScrollBar.AsNeeded// Don't work as expected
visible: listPopup.displayScrollbar
interactive: true
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.margins: 10 * DefaultStyle.dp
}
}
}
contentItem: AllContactListView {
id: contactList
visible: !loading && magicSearchBar.text.length != 0
Layout.preferredHeight: visible ? contentHeight : 0
Layout.fillWidth: true
width: listPopup.width - listPopup.leftPadding - listPopup.rightPadding
itemsRightMargin: 5 * DefaultStyle.dp //(Actions have already 10 of margin)
showInitials: false
showContactMenu: false
@ -250,7 +238,6 @@ Item {
sectionsWeight: 700 * DefaultStyle.dp
sectionsSpacing: 5 * DefaultStyle.dp
Control.ScrollBar.vertical: scrollbar
searchBarText: magicSearchBar.text
}
}

View file

@ -227,6 +227,7 @@ AbstractMainPage {
ColumnLayout {
id: content
spacing: 15 * DefaultStyle.dp
Layout.leftMargin: 45 * DefaultStyle.dp
Text {
visible: !contactList.loading && !contactList.haveContacts
Layout.alignment: Qt.AlignHCenter
@ -241,7 +242,7 @@ AbstractMainPage {
id: contactList
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 45 * DefaultStyle.dp
Layout.rightMargin: 8 * DefaultStyle.dp
searchBarText: searchBar.text
hideSuggestions: true
showDefaultAddress: false