From 90603c2420dc830fe120d9888895d97ff68fffb8 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 14 Oct 2022 11:48:12 +0200 Subject: [PATCH] Rework timeline selection managment to keep only one selection (algorithm was buggy) Fix setting wrong duration on vocal messages. Vocal message optimization by openning the file only for playing. Read its informations from content without opening it. --- .../src/components/content/ContentModel.cpp | 4 ++ .../src/components/content/ContentModel.hpp | 2 + .../src/components/recorder/RecorderModel.cpp | 4 +- .../components/timeline/TimelineListModel.cpp | 40 +++++++++++-------- .../Linphone/Chat/ChatAudioMessage.qml | 26 +++++++----- .../Styles/Chat/ChatAudioMessageStyle.qml | 8 ++-- 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/linphone-app/src/components/content/ContentModel.cpp b/linphone-app/src/components/content/ContentModel.cpp index 1a5ce8531..105bd2c2a 100644 --- a/linphone-app/src/components/content/ContentModel.cpp +++ b/linphone-app/src/components/content/ContentModel.cpp @@ -146,6 +146,10 @@ bool ContentModel::isVoiceRecording()const{ return mContent->isVoiceRecording(); } +int ContentModel::getFileDuration() const { + return mContent->getFileDuration(); +} + // Create a thumbnail from the first content that have a file and store it in Appdata void ContentModel::createThumbnail (const bool& force) { if(force || isFile() || isFileEncrypted() || isFileTransfer()){ diff --git a/linphone-app/src/components/content/ContentModel.hpp b/linphone-app/src/components/content/ContentModel.hpp index dbe51c544..7431680a3 100644 --- a/linphone-app/src/components/content/ContentModel.hpp +++ b/linphone-app/src/components/content/ContentModel.hpp @@ -73,6 +73,8 @@ public: Q_INVOKABLE bool isText() const; Q_INVOKABLE bool isVoiceRecording()const; + Q_INVOKABLE int getFileDuration() const; + void createThumbnail (const bool& force = false); void removeThumbnail (); void removeDownloadedFile(); diff --git a/linphone-app/src/components/recorder/RecorderModel.cpp b/linphone-app/src/components/recorder/RecorderModel.cpp index 74d04d1da..a6ce2258a 100644 --- a/linphone-app/src/components/recorder/RecorderModel.cpp +++ b/linphone-app/src/components/recorder/RecorderModel.cpp @@ -91,7 +91,9 @@ void RecorderModel::pause(){ } void RecorderModel::stop(){ - if(mRecorder->pause() == 0) + if(mRecorder->getState() == linphone::RecorderState::Running) // Remove these tests when the SDK do them. + mRecorder->pause(); + if(mRecorder->getState() == linphone::RecorderState::Paused) mRecorder->close(); emit stateChanged(); } diff --git a/linphone-app/src/components/timeline/TimelineListModel.cpp b/linphone-app/src/components/timeline/TimelineListModel.cpp index 75839ce77..39a3ff584 100644 --- a/linphone-app/src/components/timeline/TimelineListModel.cpp +++ b/linphone-app/src/components/timeline/TimelineListModel.cpp @@ -111,7 +111,6 @@ bool TimelineListModel::removeRows (int row, int count, const QModelIndex &paren for (int i = 0; i < count; ++i){ auto timeline = mList.takeAt(row).objectCast(); - timeline->setSelected(false); timeline->disconnectChatRoomListener(); oldTimelines.push_back(timeline); } @@ -119,8 +118,11 @@ bool TimelineListModel::removeRows (int row, int count, const QModelIndex &paren endRemoveRows(); for(auto timeline : oldTimelines) - if(timeline->mSelected) + if(timeline->mSelected) { + qWarning() << "Unselecting timemodel " << timeline; timeline->setSelected(false); + + } emit countChanged(); return true; } @@ -217,21 +219,27 @@ void TimelineListModel::setSelectedCount(int selectedCount){ } void TimelineListModel::onSelectedHasChanged(bool selected){ - if(selected) { - if(mSelectedCount >= 1){// We have more selection than wanted : count select first and unselect after : the final signal will be send only on limit - setSelectedCount(mSelectedCount+1);// It will not send a change signal - for(auto it = mList.begin() ; it != mList.end() ; ++it) - if(it->get() != sender()) - it->objectCast()->setSelected(false); - }else - setSelectedCount(mSelectedCount+1); - emit selectedChanged(qobject_cast(sender())); - } else { - if( this == CoreManager::getInstance()->getTimelineListModel()) {// Clean memory only if the selection is about the main list. - auto timeline = qobject_cast(sender()); - timeline->getChatRoomModel()->resetData();// Cleanup leaving chat room + if( mSelectedCount == 1){//swap + setSelectedCount(0); + for(auto it = mList.begin() ; it != mList.end() ; ++it) + if(it->get() != sender()) + it->objectCast()->setSelected(false); + if(!selected){ + if( this == CoreManager::getInstance()->getTimelineListModel()) {// Clean memory only if the selection is about the main list. + auto timeline = qobject_cast(sender()); + timeline->getChatRoomModel()->resetData();// Cleanup leaving chat room + } + }else{ + setSelectedCount(1); + emit selectedChanged(qobject_cast(sender())); } - setSelectedCount(mSelectedCount-1); + }else if( mSelectedCount <1){//Select + if(selected){ + setSelectedCount(1); + emit selectedChanged(qobject_cast(sender())); + } + }else{// Do nothing + qWarning() << "Timeline selection (selected=" << selected << ") is more than 1 : " << mSelectedCount; } } diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml index 05fd3d44c..50c8ebfdf 100644 --- a/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml +++ b/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml @@ -46,7 +46,18 @@ Loader{ Loader { id: vocalPlayer - active: true + active: false + function play(){ + if(!vocalPlayer.active) + vocalPlayer.active = true + else { + if(loadedItem.isPlaying){// Pause the play + vocalPlayer.item.pause() + }else{// Play the audio + vocalPlayer.item.play() + } + } + } sourceComponent: SoundPlayer { source: mainItem.contentModel && mainItem.contentModel.filePath onStopped:{ @@ -59,6 +70,7 @@ Loader{ mediaProgressBar.refresh() } } + onStatusChanged: if (loader.status == Loader.Ready) play() } RowLayout{ id: lineLayout @@ -76,11 +88,7 @@ Loader{ colorSet: (loadedItem.isPlaying ? ChatAudioMessageStyle.pauseAction : ChatAudioMessageStyle.playAction) onClicked:{ - if(loadedItem.isPlaying){// Pause the play - vocalPlayer.item.pause() - }else{// Play the audio - vocalPlayer.item.play() - } + vocalPlayer.play() } } Item{ @@ -93,9 +101,9 @@ Loader{ MediaProgressBar{ id: mediaProgressBar anchors.fill: parent - progressDuration: vocalPlayer.item ? vocalPlayer.item.duration : 0 - progressPosition: !vocalPlayer.item ? progressDuration : 0 - value: !vocalPlayer.item ? 0.01 * progressDuration / 5 : 100 + progressDuration: vocalPlayer.item ? vocalPlayer.item.duration : contentModel.getFileDuration() + progressPosition: 0 + value: 0 stopAtEnd: true resetAtEnd: false backgroundColor: ChatAudioMessageStyle.backgroundColor diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatAudioMessageStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatAudioMessageStyle.qml index 585733b78..2aba28306 100644 --- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatAudioMessageStyle.qml +++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatAudioMessageStyle.qml @@ -50,12 +50,12 @@ QtObject { property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'w_h_b_fg').color property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'w_p_b_fg').color - property color backgroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_n', icon, 'l_h_b_bg').color - property color backgroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_h', icon, 'l_n_b_bg').color + property color backgroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_n', icon, 'l_n_b_bg').color + property color backgroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_h', icon, 'l_h_b_bg').color property color backgroundHiddenPartPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_bg_p', icon, 'l_p_b_bg').color - property color foregroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_n', icon, 'l_h_b_fg').color - property color foregroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_h', icon, 'l_n_b_fg').color + property color foregroundHiddenPartNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_n', icon, 'l_n_b_fg').color + property color foregroundHiddenPartHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_h', icon, 'l_h_b_fg').color property color foregroundHiddenPartPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_hidden_fg_p', icon, 'l_p_b_fg').color }