From 950665138a7a3c915bdeece3e8a137669639b340 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Tue, 19 Nov 2024 10:47:39 +0100 Subject: [PATCH] Fix contacts results specs. --- Linphone/core/friend/FriendCore.cpp | 4 +- Linphone/core/search/MagicSearchList.cpp | 12 ++- Linphone/core/search/MagicSearchProxy.cpp | 11 +-- Linphone/model/search/MagicSearchModel.cpp | 29 +++++-- .../Display/Contact/ContactListItem.qml | 3 +- .../Display/Contact/ContactListView.qml | 7 +- Linphone/view/Page/Layout/Main/MainLayout.qml | 87 ------------------- .../view/Page/Main/Contact/ContactPage.qml | 4 +- 8 files changed, 50 insertions(+), 107 deletions(-) diff --git a/Linphone/core/friend/FriendCore.cpp b/Linphone/core/friend/FriendCore.cpp index 2e3fd9b73..e4db121a5 100644 --- a/Linphone/core/friend/FriendCore.cpp +++ b/Linphone/core/friend/FriendCore.cpp @@ -128,6 +128,7 @@ FriendCore::FriendCore(const FriendCore &friendCore) { mJob = friendCore.mJob; mPictureUri = friendCore.mPictureUri; mIsSaved = friendCore.mIsSaved; + mIsStored = friendCore.mIsStored; mIsLdap = friendCore.mIsLdap; } @@ -633,10 +634,11 @@ void FriendCore::save() { // Save Values to model mCoreModelConnection->invokeToModel([this, thisCopy]() { std::shared_ptr contact; auto core = CoreModel::getInstance()->getCore(); + auto appFriends = ToolModel::getAppFriendList(); for (auto &addr : mAddressList) { auto friendAddress = addr.toMap(); auto linphoneAddr = ToolModel::interpretUrl(friendAddress["address"].toString()); - contact = core->findFriend(linphoneAddr); + contact = appFriends->findFriendByAddress(linphoneAddr); if (contact) break; } if (contact != nullptr) { diff --git a/Linphone/core/search/MagicSearchList.cpp b/Linphone/core/search/MagicSearchList.cpp index 4cf57207e..97e02f2cd 100644 --- a/Linphone/core/search/MagicSearchList.cpp +++ b/Linphone/core/search/MagicSearchList.cpp @@ -21,6 +21,7 @@ #include "MagicSearchList.hpp" #include "core/App.hpp" #include "core/friend/FriendCore.hpp" +#include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" #include #include @@ -86,13 +87,16 @@ void MagicSearchList::setSelf(QSharedPointer me) { &MagicSearchModel::searchResultsReceived, [this](const std::list> &results) { auto *contacts = new QList>(); + auto ldapContacts = ToolModel::getLdapFriendList(); + for (auto it : results) { QSharedPointer contact; auto linphoneFriend = it->getFriend(); - // Considered LDAP results as stored. - bool isStored = (it->getSourceFlags() & (int)linphone::MagicSearch::Source::LdapServers) > 0; + bool isStored = false; if (linphoneFriend) { - contact = FriendCore::create(linphoneFriend); + isStored = + (ldapContacts->findFriendByAddress(linphoneFriend->getAddress()) != linphoneFriend); + contact = FriendCore::create(linphoneFriend, isStored); contacts->append(contact); } else if (auto address = it->getAddress()) { auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); @@ -202,7 +206,7 @@ QVariant MagicSearchList::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { return QVariant::fromValue(new FriendGui(mList[row].objectCast())); } else if (role == Qt::DisplayRole + 1) { - return mList[row].objectCast()->getIsStored(); + return mList[row].objectCast()->getIsStored() || mList[row].objectCast()->isLdap(); } return QVariant(); } diff --git a/Linphone/core/search/MagicSearchProxy.cpp b/Linphone/core/search/MagicSearchProxy.cpp index af37aab7d..d275add05 100644 --- a/Linphone/core/search/MagicSearchProxy.cpp +++ b/Linphone/core/search/MagicSearchProxy.cpp @@ -193,8 +193,9 @@ bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QMo auto friendCore = getItemAtSource(sourceRow); auto toShow = false; if (friendCore) { - toShow = (!mHideSuggestions || friendCore->getIsStored()) && - (!mShowFavoritesOnly || friendCore->getStarred()) && (mShowLdapContacts || !friendCore->isLdap()); + toShow = (!mHideSuggestions || friendCore->getIsStored() || friendCore->isLdap()) && + (!mShowFavoritesOnly || friendCore->getStarred()) && + (mShowLdapContacts || (!friendCore->isLdap() || friendCore->getIsStored())); if (toShow && mHideListProxy) { for (auto &friendAddress : friendCore->getAllAddresses()) { toShow = mHideListProxy->findFriendIndexByAddress(friendAddress.toMap()["address"].toString()) == -1; @@ -211,8 +212,8 @@ bool MagicSearchProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, c auto r = getItemAtSource(sourceRight.row()); if (l && r) { - bool lIsStored = l->getIsStored(); - bool rIsStored = r->getIsStored(); + bool lIsStored = l->getIsStored() || l->isLdap(); + bool rIsStored = r->getIsStored() || r->isLdap(); if (lIsStored && !rIsStored) return true; else if (!lIsStored && rIsStored) return false; auto lName = l->getFullName().toLower(); @@ -230,6 +231,6 @@ void MagicSearchProxy::setShowLdapContacts(bool show) { auto list = dynamic_cast(sourceModel()); if (list->mShowLdapContacts != show) { list->mShowLdapContacts = show; - list->invalidate(); + list->invalidateFilter(); } } diff --git a/Linphone/model/search/MagicSearchModel.cpp b/Linphone/model/search/MagicSearchModel.cpp index 0d46a3d09..b9a1c18ae 100644 --- a/Linphone/model/search/MagicSearchModel.cpp +++ b/Linphone/model/search/MagicSearchModel.cpp @@ -26,6 +26,7 @@ #include "model/setting/SettingsModel.hpp" #include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" +#include DEFINE_ABSTRACT_OBJECT(MagicSearchModel) @@ -44,9 +45,14 @@ void MagicSearchModel::search(QString filter, int maxResults) { mLastSearch = filter; setMaxResults(maxResults); - if ((filter == "" || filter == "*") && ((sourceFlags & (int)LinphoneEnums::MagicSearchSource::LdapServers) > 0) && - !SettingsModel::getInstance()->getSyncLdapContacts()) { - sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::LdapServers; + if (filter == "" || filter == "*") { + if (((sourceFlags & (int)LinphoneEnums::MagicSearchSource::LdapServers) > 0) && + !SettingsModel::getInstance()->getSyncLdapContacts()) + sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::LdapServers; + // For complete search, we search only on local contacts. + sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::CallLogs; + sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::ChatRooms; + sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::ConferencesInfo; } qInfo() << log().arg("Searching ") << filter << " from " << sourceFlags << " with limit " << maxResults; mMonitor->getContactsListAsync(filter != "*" ? Utils::appStringToCoreString(filter) : "", "", sourceFlags, @@ -70,11 +76,24 @@ void MagicSearchModel::setMaxResults(int maxResults) { void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr &magicSearch) { qDebug() << log().arg("SDK send callback: onSearchResultsReceived"); auto results = magicSearch->getLastSearch(); + auto appFriends = ToolModel::getAppFriendList(); + std::list> finalResults; for (auto it : results) { bool isLdap = (it->getSourceFlags() & (int)LinphoneEnums::MagicSearchSource::LdapServers) != 0; - if (isLdap && it->getFriend()) updateLdapFriendListWithFriend(it->getFriend()); + bool toAdd = true; + if (isLdap && it->getFriend()) { + updateLdapFriendListWithFriend(it->getFriend()); + if (appFriends->findFriendByAddress(it->getFriend()->getAddress())) { // Already exist in app list + toAdd = false; + } + } + if (toAdd && + std::find_if(finalResults.begin(), finalResults.end(), [it](std::shared_ptr r) { + return r->getAddress()->weakEqual(it->getAddress()); + }) == finalResults.end()) + finalResults.push_back(it); } - emit searchResultsReceived(results); + emit searchResultsReceived(finalResults); } void MagicSearchModel::onLdapHaveMoreResults(const std::shared_ptr &magicSearch, diff --git a/Linphone/view/Control/Display/Contact/ContactListItem.qml b/Linphone/view/Control/Display/Contact/ContactListItem.qml index 1fed51d46..cb550758c 100644 --- a/Linphone/view/Control/Display/Contact/ContactListItem.qml +++ b/Linphone/view/Control/Display/Contact/ContactListItem.qml @@ -88,7 +88,8 @@ FocusScope { Layout.topMargin: 2 * DefaultStyle.dp Layout.fillWidth: true visible: mainItem.showDefaultAddress - text: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(searchResultItem.core.defaultAddress) : searchResultItem.core.defaultAddress + property string address: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(searchResultItem.core.defaultAddress) : searchResultItem.core.defaultAddress + text: UtilsCpp.boldTextPart(address, mainItem.highlightText) maximumLineCount: 1 elide: Text.ElideRight font { diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index 3ef7193cb..3c7fd3ff5 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -17,7 +17,7 @@ ListView { property bool showContactMenu: true // Display the dot menu for contacts. property bool showFavorites: true // Display the favorites in the header property bool hideSuggestions: false // Hide not stored contacts (not suggestions) - property string highlightText // Bold characters in Display name. + property string highlightText: searchText // Bold characters in Display name. property var sourceFlags: LinphoneEnums.MagicSearchSource.All property bool displayNameCapitalization: true // Capitalize display name. @@ -39,6 +39,7 @@ ListView { property ConferenceInfoGui confInfoGui property bool haveFavorites: false + property bool haveContacts: count > 0 || (showFavorites && headerItem.list.count > 0) property int sectionsPixelSize: 16 * DefaultStyle.dp property int sectionsWeight: 800 * DefaultStyle.dp property int sectionsSpacing: 18 * DefaultStyle.dp @@ -195,6 +196,7 @@ ListView { sourceFlags: mainItem.sourceFlags hideSuggestions: mainItem.hideSuggestions + showLdapContacts: mainItem.searchText != '*' && mainItem.searchText != '' || SettingsCpp.syncLdapContacts initialDisplayItems: 20 onLocalFriendCreated: (index) => { var item = itemAtIndex(index) @@ -438,10 +440,11 @@ ListView { focus: true searchResultItem: $modelData - showInitials: mainItem.showInitials && searchResultItem.core.isStored + showInitials: mainItem.showInitials && isStored showDefaultAddress: mainItem.showDefaultAddress showActions: mainItem.showActions showContactMenu: searchResultItem.core.isStored + highlightText: mainItem.highlightText displayNameCapitalization: mainItem.displayNameCapitalization diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index d998e3ed7..b57128f72 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -262,7 +262,6 @@ Item { showFavorites: false selectionEnabled: false showDefaultAddress: true - hideSuggestions: true sectionsPixelSize: 13 * DefaultStyle.dp sectionsWeight: 700 * DefaultStyle.dp @@ -286,92 +285,6 @@ Item { } } } - - footer: FocusScope{ - id: suggestionFocusScope - width: contactList.width - height: visible ? content.implicitHeight : 0 - onActiveFocusChanged: if(activeFocus) contactList.positionViewAtEnd() - visible: !contactList.haveAddress(suggestionText.text) - Rectangle{ - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: suggestionRow.implicitHeight - color: suggestionFocusScope.activeFocus ? DefaultStyle.numericPadPressedButtonColor : 'transparent' - } - ColumnLayout { - id: content - anchors.fill: parent - anchors.leftMargin: 5 * DefaultStyle.dp - anchors.rightMargin: 15 * DefaultStyle.dp - - spacing: 10 * DefaultStyle.dp - Text { - text: qsTr("Suggestion") - color: DefaultStyle.main2_500main - font { - pixelSize: 13 * DefaultStyle.dp - weight: 700 * DefaultStyle.dp - } - } - - Keys.onPressed: (event) => { - if(contactList.count <= 0) return; - if(event.key == Qt.Key_Down){ - contactList.currentIndex = 0 - event.accepted = true - } else if(event.key == Qt.Key_Up){ - contactList.currentIndex = contactList.count - 1 - event.accepted = true - } - } - RowLayout { - id: suggestionRow - spacing: 10 * DefaultStyle.dp - - Avatar { - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - _address: magicSearchBar.text - } - Text { - id: suggestionText - property var urlObj: UtilsCpp.interpretUrl(magicSearchBar.text) - text: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(urlObj?.value) : urlObj?.value - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } - } - Item { - Layout.fillWidth: true - } - MagicSearchButton { - id: callButton - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - icon.source: AppIcons.phone - focus: true - onClicked: { - UtilsCpp.createCall(magicSearchBar.text) - magicSearchBar.clearText() - } - KeyNavigation.right: chatButton - KeyNavigation.left: chatButton - } - MagicSearchButton { - id: chatButton - visible: !SettingsCpp.disableChatFeature - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - icon.source: AppIcons.chatTeardropText - KeyNavigation.right: callButton - KeyNavigation.left: callButton - } - } - } - } } } } diff --git a/Linphone/view/Page/Main/Contact/ContactPage.qml b/Linphone/view/Page/Main/Contact/ContactPage.qml index 280945e0c..cbc685f59 100644 --- a/Linphone/view/Page/Main/Contact/ContactPage.qml +++ b/Linphone/view/Page/Main/Contact/ContactPage.qml @@ -205,7 +205,6 @@ AbstractMainPage { spacing: 38 * DefaultStyle.dp SearchBar { id: searchBar - visible: !contactLoader.item || contactLoader.item.loading || contactLoader.item.count != 0 || text.length !== 0 Layout.leftMargin: leftPanel.leftMargin Layout.rightMargin: leftPanel.rightMargin Layout.topMargin: 18 * DefaultStyle.dp @@ -218,7 +217,7 @@ AbstractMainPage { id: content spacing: 15 * DefaultStyle.dp Text { - visible: contactLoader.item && !contactLoader.item.loading && contactLoader.item.count === 0 + visible: contactLoader.item && !contactLoader.item.loading && !contactLoader.item.haveContacts Layout.alignment: Qt.AlignHCenter Layout.topMargin: 137 * DefaultStyle.dp text: qsTr("Aucun contact%1").arg(searchBar.text.length !== 0 ? " correspondant" : "") @@ -244,6 +243,7 @@ AbstractMainPage { id: contactList searchBarText: searchBar.text hideSuggestions: true + showDefaultAddress: false sourceFlags: LinphoneEnums.MagicSearchSource.Friends | LinphoneEnums.MagicSearchSource.FavoriteFriends | LinphoneEnums.MagicSearchSource.LdapServers onSelectedContactChanged: {