From f847054385a47ea99e2bec611571a67c8d2ca14e Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Thu, 21 Nov 2024 09:49:01 +0100 Subject: [PATCH] Quickfixes Contacts. - losing focus after search. - sections margins. - hide magic search popup on loading instead of showing spinner. - Display complete suggestions in participants/calls/magicBar. - Limit adaptation with suggestions/contacts. - Empty list when only suggestions. - Avoid autoscroll outside lists. - ResetSelection after contact deletion. --- Linphone/core/proxy/ListProxy.hpp | 6 +++ Linphone/core/search/MagicSearchList.cpp | 1 + Linphone/model/search/MagicSearchModel.cpp | 6 +-- .../Display/Contact/AllContactListView.qml | 37 +++++++++----- .../Display/Contact/ContactListView.qml | 20 ++++---- Linphone/view/Page/Layout/Main/MainLayout.qml | 10 ++-- .../view/Page/Main/Contact/ContactPage.qml | 48 ++++++++----------- 7 files changed, 71 insertions(+), 57 deletions(-) diff --git a/Linphone/core/proxy/ListProxy.hpp b/Linphone/core/proxy/ListProxy.hpp index 41661bdf3..cab750170 100644 --- a/Linphone/core/proxy/ListProxy.hpp +++ b/Linphone/core/proxy/ListProxy.hpp @@ -87,6 +87,12 @@ public: AbstractListProxy>::prepend(items); } + virtual void resetData() { + beginResetModel(); + mList.clear(); + endResetModel(); + } + template void resetData(QList> items) { beginResetModel(); diff --git a/Linphone/core/search/MagicSearchList.cpp b/Linphone/core/search/MagicSearchList.cpp index 73a3f1c55..f41eecd5a 100644 --- a/Linphone/core/search/MagicSearchList.cpp +++ b/Linphone/core/search/MagicSearchList.cpp @@ -79,6 +79,7 @@ void MagicSearchList::setSelf(QSharedPointer me) { &MagicSearchList::lSearch, [this](QString filter, int sourceFlags, LinphoneEnums::MagicSearchAggregation aggregationFlag, int maxResults) { + resetData(); mModelConnection->invokeToModel([this, filter, sourceFlags, aggregationFlag, maxResults]() { mMagicSearch->search(filter, sourceFlags, aggregationFlag, maxResults); }); diff --git a/Linphone/model/search/MagicSearchModel.cpp b/Linphone/model/search/MagicSearchModel.cpp index b9a1c18ae..7ec1898d0 100644 --- a/Linphone/model/search/MagicSearchModel.cpp +++ b/Linphone/model/search/MagicSearchModel.cpp @@ -50,9 +50,9 @@ void MagicSearchModel::search(QString filter, !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; + // 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, diff --git a/Linphone/view/Control/Display/Contact/AllContactListView.qml b/Linphone/view/Control/Display/Contact/AllContactListView.qml index 28338a559..e1c5631d4 100644 --- a/Linphone/view/Control/Display/Contact/AllContactListView.qml +++ b/Linphone/view/Control/Display/Contact/AllContactListView.qml @@ -45,7 +45,7 @@ Flickable{ property int sectionsSpacing: 18 * DefaultStyle.dp property int itemsRightMargin: 39 * DefaultStyle.dp - property int count: contactsList.count + property int count: contactsList.count + suggestionsList.count + favoritesList.count signal resultsReceived() signal contactStarredChanged() @@ -94,6 +94,13 @@ Flickable{ return index != -1 } + function resetSelections(){ + mainItem.highlightedContact = null + favoritesList.currentIndex = -1 + contactsList.currentIndex = -1 + suggestionsList.currentIndex = -1 + } + onHighlightedContactChanged:{ favoritesList.highlightedContact = highlightedContact contactsList.highlightedContact = highlightedContact @@ -116,7 +123,7 @@ Flickable{ } onSearchTextChanged: loading = true onAtYEndChanged: if(atYEnd) { - if( contactsProxy.haveMore || mainItem.hideSuggestions) contactsProxy.displayMore() + if( (contactsProxy.haveMore && contactList.expanded ) || mainItem.hideSuggestions) contactsProxy.displayMore() else suggestionsProxy.displayMore() } function findNextList(item, count, direction){ @@ -134,7 +141,7 @@ Flickable{ function updatePosition(list){ var item = list.itemAtIndex(list.currentIndex) var centerPos = list.y - height/2 - if( item){ + if( item && list.expanded){ // For debugging just in case //var listPosition = item.mapToItem(favoriteList, item.x, item.y) //var newPosition = favoriteList.mapToItem(mainItem, listPosition.x, listPosition.y) @@ -149,7 +156,7 @@ Flickable{ //console.log("Moving to " + (headerItem.y+item.y)) centerPos += item.y } - mainItem.contentY = Math.max(0, centerPos) + mainItem.contentY = Math.min(Math.max(0, centerPos), mainItem.contentHeight - mainItem.height) } Behavior on contentY{ NumberAnimation { @@ -163,9 +170,9 @@ Flickable{ var newItem var direction = (event.key == Qt.Key_Up ? -1 : 1) if(suggestionsList.activeFocus) newItem = findNextList(suggestionsList, 0, direction) - if(contactsList.activeFocus) newItem = findNextList(contactsList, 0, direction) - if(favoritesList.activeFocus) newItem = findNextList(favoritesList, 0, direction) - + else if(contactsList.activeFocus) newItem = findNextList(contactsList, 0, direction) + else if(favoritesList.activeFocus) newItem = findNextList(favoritesList, 0, direction) + else newItem = findNextList(suggestionsList, 0, direction) if(newItem){ newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1) event.accepted = true @@ -194,7 +201,10 @@ Flickable{ searchText: mainItem.searchText aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend sourceFlags: mainItem.sourceFlags - onModelReset: mainItem.resultsReceived() + onModelReset: { + mainItem.resetSelections() + mainItem.resultsReceived() + } onInitialized: { if(mainItem.searchOnEmpty || searchText != '' ) { @@ -219,7 +229,7 @@ Flickable{ ColumnLayout{ id: contentsLayout width: parent.width - + spacing: 0 BusyIndicator { Layout.alignment: Qt.AlignCenter Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0 @@ -265,6 +275,7 @@ Flickable{ id: contactsList Layout.fillWidth: true Layout.preferredHeight: implicitHeight + Layout.topMargin: favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0 interactive: false highlightText: mainItem.highlightText showActions: mainItem.showActions @@ -284,7 +295,7 @@ Flickable{ onContactDeletionRequested: (contact) => {mainItem.contactDeletionRequested(contact)} onAddContactToSelection: (address) => {mainItem.addContactToSelection(address)} onRemoveContactFromSelection: (index) => {mainItem.removeContactFromSelection(index)} - + model:MagicSearchProxy { id: contactsProxy parentProxy: mainItem.mainModel @@ -300,6 +311,7 @@ Flickable{ id: suggestionsList Layout.fillWidth: true Layout.preferredHeight: implicitHeight + Layout.topMargin: contactsList.height + favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0 interactive: false showInitials: false highlightText: mainItem.highlightText @@ -319,13 +331,14 @@ Flickable{ onContactDeletionRequested: (contact) => {mainItem.contactDeletionRequested(contact)} onAddContactToSelection: (address) => {mainItem.addContactToSelection(address)} onRemoveContactFromSelection: (index) => {mainItem.removeContactFromSelection(index)} - model:MagicSearchProxy { id: suggestionsProxy parentProxy: mainItem.mainModel filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other - initialDisplayItems: 0 + initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : 20 + onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems displayItemsStep: 5 + onModelReset: maxDisplayItems = initialDisplayItems } } } diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index 78f8a8fc4..b1ae44334 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -6,7 +6,7 @@ import Linphone import UtilsCpp 1.0 import ConstantsCpp 1.0 import SettingsCpp - +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils ListView { id: mainItem @@ -53,8 +53,8 @@ ListView { clip: true highlightFollowsCurrentItem: false cacheBuffer: 400 - implicitHeight: contentHeight + headerItem?.height - spacing: 4 * DefaultStyle.dp + implicitHeight: contentHeight + spacing: expanded ? 4 * DefaultStyle.dp : 0 property bool _moveToIndex: false @@ -72,14 +72,17 @@ ListView { }else{ mainItem.currentIndex = -1 mainItem.highlightedContact = null - if(headerItem) headerItem.forceActiveFocus() + if(headerItem) { + headerItem.forceActiveFocus() + } } } - onCountChanged: if(_moveToIndex >= 0 && count > mainItem.currentIndex ){ + onCountChanged: if(_moveToIndex && count > mainItem.currentIndex ){ _moveToIndex = false selectIndex(mainItem.currentIndex) - } + } onContactSelected: updatePosition() + onExpandedChanged: if(!expanded) updatePosition() keyNavigationEnabled: false Keys.onPressed: (event)=> { if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){ @@ -123,10 +126,11 @@ ListView { ColumnLayout { id: headerContents width: parent.width - spacing: mainItem.count > 0 ? sectionsSpacing : 0 + spacing: 0 Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible Layout.fillWidth: true Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0 + Layout.bottomMargin: 4 * DefaultStyle.dp RowLayout { id: headerTitleLayout anchors.fill: parent @@ -182,7 +186,7 @@ ListView { onIsSelectedChanged: if(isSelected) mainItem.currentIndex = index onContactDeletionRequested: (contact) => mainItem.contactDeletionRequested(contact) - + onClicked: (mouse) => { if (mouse && mouse.button == Qt.RightButton) { friendPopup.open() diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index f11bc1993..637279e6a 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -198,11 +198,11 @@ Item { width: magicSearchBar.width property int maxHeight: 400 * DefaultStyle.dp property bool displayScrollbar: contactList.contentHeight + topPadding + bottomPadding> maxHeight - height: Math.min(contactList.contentHeight + topPadding + bottomPadding, maxHeight) + height: contactList.haveContacts ? Math.min(contactList.contentHeight + topPadding + bottomPadding, maxHeight) : 0 y: magicSearchBar.height // closePolicy: Popup.NoAutoClose - topPadding: 20 * DefaultStyle.dp - bottomPadding: 20 * DefaultStyle.dp + topPadding: contactList.haveContacts ? 20 * DefaultStyle.dp : 0 + bottomPadding: contactList.haveContacts ? 20 * DefaultStyle.dp : 0 rightPadding: 10 * DefaultStyle.dp leftPadding: 20 * DefaultStyle.dp @@ -240,8 +240,8 @@ Item { } contentItem: AllContactListView { id: contactList - visible: magicSearchBar.text.length != 0 - Layout.preferredHeight: contentHeight + visible: !loading && magicSearchBar.text.length != 0 + Layout.preferredHeight: visible ? contentHeight : 0 Layout.fillWidth: true itemsRightMargin: 5 * DefaultStyle.dp //(Actions have already 10 of margin) showInitials: false diff --git a/Linphone/view/Page/Main/Contact/ContactPage.qml b/Linphone/view/Page/Main/Contact/ContactPage.qml index e5beea57c..a7a60e74a 100644 --- a/Linphone/view/Page/Main/Contact/ContactPage.qml +++ b/Linphone/view/Page/Main/Contact/ContactPage.qml @@ -20,7 +20,7 @@ AbstractMainPage { onVisibleChanged: if (!visible) { rightPanelStackView.clear() - if(contactLoader.item) contactLoader.item.currentIndex = -1 + contactList.resetSelections() } onSelectedContactChanged: { @@ -51,7 +51,7 @@ AbstractMainPage { // rightPanelStackView.initialItem: contactDetail - showDefaultItem: rightPanelStackView.depth == 0 && contactLoader.item?.count === 0 && searchBar.text.length === 0 + showDefaultItem: rightPanelStackView.depth == 0 && !contactList.haveContacts && searchBar.text.length === 0 function deleteContact(contact) { if (!contact) return @@ -63,6 +63,7 @@ AbstractMainPage { if (confirmed) { var name = contact.core.fullName contact.core.remove() + contactList.resetSelections() UtilsCpp.showInformationPopup(qsTr("Supprimé"), qsTr("%1 a été supprimé").arg(name)) } } ) @@ -211,13 +212,13 @@ AbstractMainPage { Layout.fillWidth: true placeholderText: qsTr("Rechercher un contact") KeyNavigation.up: createContactButton - KeyNavigation.down: contactLoader.item + KeyNavigation.down: contactList } ColumnLayout { id: content spacing: 15 * DefaultStyle.dp Text { - visible: contactLoader.item && !contactLoader.item.loading && !contactLoader.item.haveContacts + visible: !contactList.loading && !contactList.haveContacts Layout.alignment: Qt.AlignHCenter Layout.topMargin: 137 * DefaultStyle.dp text: qsTr("Aucun contact%1").arg(searchBar.text.length !== 0 ? " correspondant" : "") @@ -226,35 +227,24 @@ AbstractMainPage { weight: 800 * DefaultStyle.dp } } - Loader{ - // This is a hack for an incomprehensible behavior on sections title where they doesn't match with their delegate and can be unordered after resetting models. - id: contactLoader + AllContactListView{ + id: contactList Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: 45 * DefaultStyle.dp - property string t: searchBar.text - active: leftPanel.visible - onTChanged: { - contactLoader.active = false - Qt.callLater(function(){contactLoader.active=true}) + searchBarText: searchBar.text + hideSuggestions: true + showDefaultAddress: false + sourceFlags: LinphoneEnums.MagicSearchSource.Friends | LinphoneEnums.MagicSearchSource.FavoriteFriends | LinphoneEnums.MagicSearchSource.LdapServers + onHighlightedContactChanged: mainItem.selectedContact = highlightedContact + onContactDeletionRequested: (contact) => { + mainItem.deleteContact(contact) } - //------------------------------------------------------------- - sourceComponent: AllContactListView{ - id: contactList - searchBarText: searchBar.text - hideSuggestions: true - showDefaultAddress: false - sourceFlags: LinphoneEnums.MagicSearchSource.Friends | LinphoneEnums.MagicSearchSource.FavoriteFriends | LinphoneEnums.MagicSearchSource.LdapServers - onHighlightedContactChanged: mainItem.selectedContact = highlightedContact - onContactDeletionRequested: (contact) => { - mainItem.deleteContact(contact) - } - onLoadingChanged: { - if(!loading && initialFriendToDisplay.length !== 0) { - Qt.callLater(function(){ - if (selectContact(initialFriendToDisplay) != -1) initialFriendToDisplay = "" - }) - } + onLoadingChanged: { + if(!loading && initialFriendToDisplay.length !== 0) { + Qt.callLater(function(){ + if (selectContact(initialFriendToDisplay) != -1) initialFriendToDisplay = "" + }) } } }