From 552f9791af05530b15c60a87581687edce86d051 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Tue, 21 Jan 2025 18:27:10 +0100 Subject: [PATCH] Fix item ghost hovering and remove moving center when selecting/moving to an item in contacts/call logs. Remove refreshing meeting list on registration state changes. Fix scrolling to items in meetings, call logs, contacts. --- .../core/conference/ConferenceInfoList.cpp | 18 +------ .../core/conference/ConferenceInfoList.hpp | 1 - .../Display/Contact/AllContactListView.qml | 23 ++------ .../Display/Contact/ContactListItem.qml | 7 ++- .../Display/Contact/ContactListView.qml | 18 ++++++- .../Display/Meeting/MeetingListView.qml | 49 ++++++----------- Linphone/view/Control/Tool/Helper/utils.js | 53 +++++++++++++++++++ Linphone/view/Page/Main/Call/CallPage.qml | 41 +++++++++++--- 8 files changed, 131 insertions(+), 79 deletions(-) diff --git a/Linphone/core/conference/ConferenceInfoList.cpp b/Linphone/core/conference/ConferenceInfoList.cpp index 37d93a746..9557ad89c 100644 --- a/Linphone/core/conference/ConferenceInfoList.cpp +++ b/Linphone/core/conference/ConferenceInfoList.cpp @@ -70,7 +70,7 @@ void ConferenceInfoList::setSelf(QSharedPointer me) { items->push_back(nullptr); // Add Dummy conference for today for (auto conferenceInfo : conferenceInfos) { if (conferenceInfo->getState() == linphone::ConferenceInfo::State::Cancelled) { - auto myAddress = defaultAccount->getContactAddress(); + auto myAddress = defaultAccount->getParams()->getIdentityAddress(); if (!myAddress || myAddress->weakEqual(conferenceInfo->getOrganizer())) continue; } auto confInfoCore = build(conferenceInfo); @@ -98,9 +98,7 @@ void ConferenceInfoList::setSelf(QSharedPointer me) { // This is needed because account does not have a contact address until // it is connected, so we can't verify if it is the organizer of a deleted // conference (which must hidden) - mCoreModelConnection->makeConnectToModel(&CoreModel::defaultAccountChanged, - &ConferenceInfoList::updateCurrentAccount); - updateCurrentAccount(); + mCoreModelConnection->makeConnectToModel(&CoreModel::defaultAccountChanged, [this]() { emit lUpdate(true); }); mCoreModelConnection->makeConnectToModel( &CoreModel::conferenceInfoCreated, @@ -142,18 +140,6 @@ void ConferenceInfoList::addConference(const std::shared_ptrinvokeToModel([this]() { - if (mCurrentAccountCore) disconnect(mCurrentAccountCore.get()); - auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); - if (defaultAccount) { - mCurrentAccountCore = AccountCore::create(defaultAccount); - connect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this, - [this] { emit lUpdate(true); }); - } - }); -} - bool ConferenceInfoList::haveCurrentDate() const { return mHaveCurrentDate; } diff --git a/Linphone/core/conference/ConferenceInfoList.hpp b/Linphone/core/conference/ConferenceInfoList.hpp index a2c4d6c39..5dd10ef57 100644 --- a/Linphone/core/conference/ConferenceInfoList.hpp +++ b/Linphone/core/conference/ConferenceInfoList.hpp @@ -42,7 +42,6 @@ public: void resetData(QList> data); void addConference(const std::shared_ptr &confInfo); - void updateCurrentAccount(); bool haveCurrentDate() const; void setHaveCurrentDate(bool have); diff --git a/Linphone/view/Control/Display/Contact/AllContactListView.qml b/Linphone/view/Control/Display/Contact/AllContactListView.qml index ca998b07e..bb030a840 100644 --- a/Linphone/view/Control/Display/Contact/AllContactListView.qml +++ b/Linphone/view/Control/Display/Contact/AllContactListView.qml @@ -6,6 +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 Flickable{ id: mainItem @@ -113,27 +114,9 @@ Flickable{ if( nextItem.model.count > 0) return nextItem else return findNextList(nextItem, count+1, direction) } - + function updatePosition(list){ - var item = list.itemAtIndex(list.currentIndex) - var centerItemPos = 0 - 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) - //console.log("item pos: " +item.x + " / " +item.y) - //console.log("fav pos: " +favoriteList.x + " / " +favoriteList.y) - //console.log("fav content: " +favoriteList.contentX + " / " +favoriteList.contentY) - //console.log("main pos: " +mainItem.x + " / " +mainItem.y) - //console.log("main content: " +mainItem.contentX + " / " +mainItem.contentY) - //console.log("list pos: " +listPosition.x + " / " +listPosition.y) - //console.log("new pos: " +newPosition.x + " / " +newPosition.y) - //console.log("header pos: " +headerItem.x + " / " +headerItem.y) - //console.log("Moving to " + (headerItem.y+item.y)) - centerItemPos = item.y + list.y + list.headerHeight +item.height/2 - } - var centerPos = centerItemPos - height/2 - mainItem.contentY = Math.max(0, Math.min(centerPos, height, contentHeight-height)) + Utils.updatePosition(mainItem, list) } onHighlightedContactChanged:{ diff --git a/Linphone/view/Control/Display/Contact/ContactListItem.qml b/Linphone/view/Control/Display/Contact/ContactListItem.qml index 42968e402..4426f6e2a 100644 --- a/Linphone/view/Control/Display/Contact/ContactListItem.qml +++ b/Linphone/view/Control/Display/Contact/ContactListItem.qml @@ -24,6 +24,7 @@ FocusScope { property bool multiSelectionEnabled: false //Multiple items can be selected. property list selectedContacts // List of default address on selected contacts. property bool isSelected: false // selected in list => currentIndex == index + property bool isLastHovered: false property var previousInitial // Use directly previous initial property int itemsRightMargin: 39 * DefaultStyle.dp @@ -33,6 +34,7 @@ FocusScope { signal clicked(var mouse) signal contactDeletionRequested(FriendGui contact) + signal containsMouseChanged(bool containsMouse) Text { id: initial @@ -217,12 +219,15 @@ FocusScope { acceptedButtons: Qt.AllButtons z: -1 focus: !actionButtons.visible + onContainsMouseChanged: { + mainItem.containsMouseChanged(containsMouse) + } Rectangle { anchors.fill: contactArea radius: 8 * DefaultStyle.dp opacity: 0.7 color: mainItem.isSelected ? DefaultStyle.main2_200 : DefaultStyle.main2_100 - visible: contactArea.containsMouse || friendPopup.hovered || mainItem.isSelected || friendPopup.visible + visible: mainItem.isLastHovered || friendPopup.hovered || mainItem.isSelected || friendPopup.visible } Keys.onPressed: (event)=> { if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index 190eca8b3..f07e91d99 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -57,6 +57,16 @@ ListView { cacheBuffer: 400 implicitHeight: contentHeight spacing: expanded ? 4 * DefaultStyle.dp : 0 + + property var _currentItemY: currentItem?.y + on_CurrentItemYChanged: if(_currentItemY){ + updatePosition() + } + onYChanged: updatePosition() + + // Qt bug: sometimes, containsMouse may not be send and update on each MouseArea. + // So we need to use this variable to switch off all hovered items. + property int lastMouseContainsIndex: -1 property bool _moveToIndex: false @@ -82,7 +92,6 @@ ListView { _moveToIndex = false } } - onContactSelected: updatePosition() onExpandedChanged: if(!expanded) updatePosition() keyNavigationEnabled: false @@ -194,6 +203,7 @@ ListView { multiSelectionEnabled: mainItem.multiSelectionEnabled selectedContacts: mainItem.selectedContacts isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core + isLastHovered: mainItem.lastMouseContainsIndex == index previousInitial: mainItem.itemAtIndex(index-1)?.initial itemsRightMargin: mainItem.itemsRightMargin @@ -218,5 +228,11 @@ ListView { mainItem.contactSelected(searchResultItem) } } + onContainsMouseChanged: (containsMouse) => { + if(containsMouse) + mainItem.lastMouseContainsIndex = index + else if( mainItem.lastMouseContainsIndex == index) + mainItem.lastMouseContainsIndex = -1 + } } } diff --git a/Linphone/view/Control/Display/Meeting/MeetingListView.qml b/Linphone/view/Control/Display/Meeting/MeetingListView.qml index 8fab89df6..df4b47644 100644 --- a/Linphone/view/Control/Display/Meeting/MeetingListView.qml +++ b/Linphone/view/Control/Display/Meeting/MeetingListView.qml @@ -7,6 +7,8 @@ import Linphone import QtQml import UtilsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils + ListView { id: mainItem property string searchBarText @@ -30,18 +32,11 @@ ListView { mainItem.selectedConference = null mainItem.currentIndex = -1 } - // Issues Notes: - // positionViewAtIndex: - // - if currentItem was in cache, it will not go to it (ex: contentY=63, currentItem.y=3143) - // - Animation don't work + +//---------------------------------------------------------------- function moveToCurrentItem(){ - var centerItemPos = 0 - if( currentItem){ - centerItemPos = currentItem.y + currentItem.height/2 - } - var centerPos = centerItemPos - height/2 - moveBehaviorTimer.startAnimation() - mainItem.contentY = Math.max(0, Math.min(centerPos, contentHeight-height)) + if( mainItem.currentIndex >= 0) + Utils.updatePosition(mainItem, mainItem) } onCurrentItemChanged: { moveToCurrentItem() @@ -50,35 +45,23 @@ ListView { currentItem.forceActiveFocus() } } - // When cache is updating, contentHeight changes. Update position if we are moving the view. - onContentHeightChanged:{ - if(moveBehavior.enabled){ - moveToCurrentItem() - } + // Update position only if we are moving to current item and its position is changing. + property var _currentItemY: currentItem?.y + on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){ + moveToCurrentItem() } - onAtYEndChanged: if(atYEnd) confInfoProxy.displayMore() - - Timer{ - id: moveBehaviorTimer - interval: 501 - onTriggered: moveBehavior.enabled = false - function startAnimation(){ - moveBehavior.enabled = true - moveBehaviorTimer.restart() - } - } - Behavior on contentY{ - id: moveBehavior - enabled: false NumberAnimation { + id: moveAnimation duration: 500 easing.type: Easing.OutExpo - onFinished: {// Not call if on Behavior. Callback just in case. - moveBehavior.enabled = false - } + alwaysRunToEnd: true } } +//---------------------------------------------------------------- + onAtYEndChanged: if(atYEnd) confInfoProxy.displayMore() + + Keys.onPressed: (event)=> { if(event.key == Qt.Key_Up) { if(currentIndex > 0 ) { diff --git a/Linphone/view/Control/Tool/Helper/utils.js b/Linphone/view/Control/Tool/Helper/utils.js index 1b8ab1754..60c3eb62d 100644 --- a/Linphone/view/Control/Tool/Helper/utils.js +++ b/Linphone/view/Control/Tool/Helper/utils.js @@ -754,3 +754,56 @@ function infoDialog(window, message) { showButtonOnly: 1 }, function (status) {}) } + +// Set position of list.currentItem into the scrollItem +function updatePosition(scrollItem, list){ + if(scrollItem.height == 0) return; + var item = list.itemAtIndex(list.currentIndex) + var centerItemPos = 0 + var topItemPos = 0 + var bottomItemPos = 0 + if(!item) item = list.currentItem + if( item && (list.expanded || list.expanded == undefined)){ + // For debugging just in case + //var listPosition = item.mapToItem(favoriteList, item.x, item.y) + //var newPosition = favoriteList.mapToItem(mainItem, listPosition.x, listPosition.y) + //console.log("item pos: " +item.x + " / " +item.y) + //console.log("fav pos: " +favoriteList.x + " / " +favoriteList.y) + //console.log("fav content: " +favoriteList.contentX + " / " +favoriteList.contentY) + //console.log("main pos: " +mainItem.x + " / " +mainItem.y) + //console.log("main content: " +mainItem.contentX + " / " +mainItem.contentY) + //console.log("list pos: " +listPosition.x + " / " +listPosition.y) + //console.log("new pos: " +newPosition.x + " / " +newPosition.y) + //console.log("header pos: " +headerItem.x + " / " +headerItem.y) + //console.log("Moving to " + (headerItem.y+item.y)) + // Middle position + //centerItemPos = item.y + list.y + item.height/2 + //if( list.headerHeight) centerItemPos += list.headerHeight + topItemPos = item.y + if( list != scrollItem) topItemPos += list.y + if( list.headerHeight) topItemPos += list.headerHeight + bottomItemPos = topItemPos +item.height + } + if(item){ + // Middle position + //var centerPos = centerItemPos - scrollItem.height/2 + //scrollItem.contentY = Math.max(0, Math.min(centerPos, scrollItem.height, scrollItem.contentHeight-scrollItem.height)) + // Visible position + if( topItemPos < scrollItem.contentY){ + // Display item at the beginning + scrollItem.contentY = topItemPos + //console.debug("Set to top", scrollItem.contentY,topItemPos, item.height) + }else if(bottomItemPos > scrollItem.contentY + scrollItem.height){ + // Display item at the end + scrollItem.contentY = bottomItemPos - scrollItem.height + //console.debug("Set to bottom",scrollItem.contentY,list.y,list.headerHeight, topItemPos, bottomItemPos, scrollItem.height, bottomItemPos - scrollItem.height, item.height) + }else{ + //console.debug("Inside, do not move", topItemPos, bottomItemPos, scrollItem.contentY, (scrollItem.contentY + scrollItem.height)) + } + + }else{ + // console.debug("Item is null") + } +} + + diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 2af793251..6eb092de2 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -6,6 +6,7 @@ import Linphone import UtilsCpp import SettingsCpp import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils AbstractMainPage { id: mainItem @@ -252,10 +253,7 @@ AbstractMainPage { cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items flickDeceleration: 10000 spacing: 10 * DefaultStyle.dp - highlightFollowsCurrentItem: true - preferredHighlightBegin: height/2 - 10 - preferredHighlightEnd: height/2 + 10 - highlightRangeMode: ListView.ApplyRange + Keys.onPressed: (event) => { if(event.key == Qt.Key_Escape){ console.log("Back") @@ -292,15 +290,38 @@ AbstractMainPage { callHistoryProxy.displayMore() } } +//---------------------------------------------------------------- + function moveToCurrentItem(){ + if( historyListView.currentIndex >= 0) + Utils.updatePosition(historyListView, historyListView) + } + onCurrentItemChanged: { + moveToCurrentItem() + } + // Update position only if we are moving to current item and its position is changing. + property var _currentItemY: currentItem?.y + on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){ + moveToCurrentItem() + } + Behavior on contentY{ + NumberAnimation { + id: moveAnimation + duration: 500 + easing.type: Easing.OutExpo + alwaysRunToEnd: true + } + } +//---------------------------------------------------------------- onCurrentIndexChanged: { - if(currentIndex == 0) positionViewAtBeginning() - else positionViewAtIndex(currentIndex, ListView.Visible) mainItem.selectedRowHistoryGui = model.getAt(currentIndex) } onVisibleChanged: { if (!visible) currentIndex = -1 } + // Qt bug: sometimes, containsMouse may not be send and update on each MouseArea. + // So we need to use this variable to switch off all hovered items. + property int lastMouseContainsIndex: -1 delegate: FocusScope { width:historyListView.width height: 56 * DefaultStyle.dp @@ -402,12 +423,18 @@ AbstractMainPage { hoverEnabled: true anchors.fill: parent focus: true + onContainsMouseChanged: { + if(containsMouse) + historyListView.lastMouseContainsIndex = index + else if( historyListView.lastMouseContainsIndex == index) + historyListView.lastMouseContainsIndex = -1 + } Rectangle { anchors.fill: parent opacity: 0.7 radius: 8 * DefaultStyle.dp color: historyListView.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100 - visible: parent.containsMouse || historyListView.currentIndex === index + visible: historyListView.lastMouseContainsIndex === index || historyListView.currentIndex === index } onPressed: { historyListView.currentIndex = model.index