From ed99447e054b357a8fd3dd826ad1db583eb442f3 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Wed, 17 Nov 2021 14:48:44 +0100 Subject: [PATCH] Fix reply mode : - avoid sending reply after removing preview - keep reply preview for the current chat room only --- .../components/chat-room/ChatRoomModel.cpp | 22 ++++++++++++------- .../components/chat-room/ChatRoomModel.hpp | 8 +++++-- .../chat-room/ChatRoomProxyModel.cpp | 2 -- .../chat-room/ChatRoomProxyModel.hpp | 3 --- .../ui/modules/Linphone/Chat/Chat.qml | 8 ++----- .../Linphone/Chat/ChatMessagePreview.qml | 3 +-- .../Linphone/Chat/ChatReplyPreview.qml | 20 ++++++++--------- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index c53fc75dc..6fe698752 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -190,7 +190,6 @@ std::shared_ptr ChatRoomModel::create(std::shared_ptr chatRoom, QObject * parent) : QAbstractListModel(parent){ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE CoreManager *coreManager = CoreManager::getInstance(); - mReply = nullptr; mCoreHandlers = coreManager->getHandlers(); mChatRoom = chatRoom; @@ -605,14 +604,20 @@ void ChatRoomModel::setEphemeralLifetime(long lifetime){ } void ChatRoomModel::setReply(ChatMessageModel * model){ - if(mReply) - clearReply(); - mReply = model->getChatMessage(); + if(model != mReplyModel.get()){ + if( model && model->getChatMessage() ) + mReplyModel = ChatMessageModel::create(model->getChatMessage(), this); + else + mReplyModel = nullptr; + emit replyChanged(); + } } -void ChatRoomModel::clearReply(){ - mReply = nullptr; + +ChatMessageModel * ChatRoomModel::getReply()const{ + return mReplyModel.get(); } + //------------------------------------------------------------------------------------------------ void ChatRoomModel::deleteChatRoom(){ @@ -652,8 +657,8 @@ void ChatRoomModel::updateParticipants(const QVariantList& participants){ void ChatRoomModel::sendMessage (const QString &message) { shared_ptr _message; - if(mReply) - _message = mChatRoom->createReplyMessage(mReply); + if(mReplyModel && mReplyModel->getChatMessage()) + _message = mChatRoom->createReplyMessage(mReplyModel->getChatMessage()); else _message= mChatRoom->createEmptyMessage(); auto recorder = CoreManager::getInstance()->getRecorderManager(); @@ -666,6 +671,7 @@ void ChatRoomModel::sendMessage (const QString &message) { _message->addUtf8TextContent(message.toUtf8().toStdString()); _message->send(); emit messageSent(_message); + setReply(nullptr); } void ChatRoomModel::sendFileMessage (const QString &path) { diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp index 3a57b7c10..2e19836f8 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp @@ -151,6 +151,8 @@ public: Q_PROPERTY(ParticipantListModel* participants READ getParticipants CONSTANT) + Q_PROPERTY(ChatMessageModel * reply READ getReply WRITE setReply NOTIFY replyChanged) + //ChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure); @@ -211,6 +213,7 @@ public: void setEphemeralLifetime(long lifetime); void setReply(ChatMessageModel * model); + ChatMessageModel * getReply()const; void clearReply(); // Tools @@ -309,7 +312,8 @@ signals: void ephemeralEnabledChanged(); void ephemeralLifetimeChanged(); void canBeEphemeralChanged(); - void chatRoomDeleted();// Must be connected with DirectConnection mode + void chatRoomDeleted();// Must be connected with DirectConnection mode + void replyChanged(); // Chat Room listener callbacks @@ -342,7 +346,7 @@ private: std::shared_ptr mChatRoom; std::shared_ptr mChatRoomModelListener; - std::shared_ptr mReply; + std::shared_ptr mReplyModel; std::weak_ptr mSelf; }; diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp index dc24563ea..504488ae0 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp @@ -121,8 +121,6 @@ CREATE_PARENT_MODEL_FUNCTION(removeAllEntries) CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendFileMessage, const QString &) CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendMessage, const QString &) CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(forwardMessage, ChatMessageModel *) -CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(setReply, ChatMessageModel*) -CREATE_PARENT_MODEL_FUNCTION(clearReply) CREATE_PARENT_MODEL_FUNCTION_WITH_ID(removeRow) diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp index 0b3f16cc7..41d1d8817 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp @@ -72,9 +72,6 @@ public: Q_INVOKABLE void setFilterText(const QString& text); - Q_INVOKABLE void setReply(ChatMessageModel* model); - Q_INVOKABLE void clearReply(); - signals: void peerAddressChanged (const QString &peerAddress); void localAddressChanged (const QString &localAddress); diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml index afaa5c112..d3a2fe6c5 100644 --- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml +++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml @@ -23,8 +23,6 @@ Rectangle { property string noticeBannerText : '' // When set, show a banner with text and hide after some time onNoticeBannerTextChanged: if(noticeBannerText!='') messageBlock.state = "showed" - property alias replyChatMessageModel: chatMessagePreview.replyChatMessageModel - // --------------------------------------------------------------------------- signal messageToSend (string text) @@ -271,8 +269,7 @@ Rectangle { //: "Selection copied to clipboard" : when a user copy a text from the menu, this message show up. onCopySelectionDone: container.noticeBannerText = qsTr("selectedTextCopied") onReplyClicked: { - proxyModel.setReply($chatEntry) - container.replyChatMessageModel = $chatEntry + proxyModel.chatRoomModel.reply = $chatEntry } onForwardClicked:{ window.attachVirtualWindow(Qt.resolvedUrl('../Dialog/SipAddressDialog.qml') @@ -314,6 +311,7 @@ Rectangle { ChatMessagePreview{ id: chatMessagePreview + replyChatRoomModel: proxyModel.chatRoomModel } Rectangle{ id: messageBlock @@ -418,12 +416,10 @@ Rectangle { chat.bindToEnd = true if(proxyModel.chatRoomModel) { proxyModel.sendMessage(text) - chatMessagePreview.hide() }else{ console.log("Peer : " +proxyModel.peerAddress+ "/"+chat.model.peerAddress) proxyModel.chatRoomModel = CallsListModel.createChat(proxyModel.peerAddress) proxyModel.sendMessage(text) - chatMessagePreview.hide() } } onAudioRecordRequest: RecorderManager.resetVocalRecorder() diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml b/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml index 39f0862da..d406d2649 100644 --- a/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml +++ b/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml @@ -14,7 +14,7 @@ import 'Chat.js' as Logic // ============================================================================= ColumnLayout{ - property alias replyChatMessageModel : replyPreview.replyChatMessageModel + property alias replyChatRoomModel : replyPreview.chatRoomModel property int maxHeight: parent.height - ( audioPreview.visible ? audioPreview.height : 0) anchors.left: parent.left anchors.right: parent.right @@ -22,7 +22,6 @@ ColumnLayout{ spacing: 0 function hide(){ - replyPreview.hide() audioPreview.hide() } ChatReplyPreview{ diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml index 72cd3f936..33b09cecf 100644 --- a/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml +++ b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml @@ -16,8 +16,7 @@ import 'Chat.js' as Logic Rectangle{ id: replyPreviewBlock - property ChatMessageModel replyChatMessageModel - onReplyChatMessageModelChanged: if(replyChatMessageModel) replyPreviewBlock.state = "showed" + property ChatRoomModel chatRoomModel Layout.preferredHeight: Math.min(replyPreviewText.implicitHeight + replyPreviewHeaderArea.implicitHeight + 10, parent.maxHeight) @@ -26,8 +25,7 @@ Rectangle{ color: ChatStyle.replyPreview.backgroundColor radius: 10 - state: "hidden" - visible: container.replyChatMessageModel + state: chatRoomModel && chatRoomModel.reply ? 'showed' : 'hidden' // Remove bottom corners clip: false function hide(){ @@ -62,7 +60,7 @@ Rectangle{ Layout.fillWidth: true Layout.preferredHeight: implicitHeight //: 'Reply to %1' : Title for a reply preview to know who said what. - text: container.replyChatMessageModel ? qsTr('titleReply').arg(container.replyChatMessageModel.fromDisplayName) : '' + text: replyPreviewBlock.chatRoomModel && replyPreviewBlock.chatRoomModel.reply ? qsTr('titleReply').arg(replyPreviewBlock.chatRoomModel.reply.fromDisplayName) : '' font.pointSize: ChatStyle.replyPreview.headerPointSize font.weight: Font.Bold color: ChatStyle.replyPreview.headerTextColor @@ -92,7 +90,7 @@ Rectangle{ selectByMouse: true font.family: customFont.family font.pointSize: Units.dp * (customFont.pointSize - 2) - text: replyChatMessageModel ? Utils.encodeTextToQmlRichFormat(replyChatMessageModel.content, { + text: chatRoomModel && chatRoomModel.reply ? Utils.encodeTextToQmlRichFormat(chatRoomModel.reply.content, { imagesHeight: ChatStyle.entry.message.images.height, imagesWidth: ChatStyle.entry.message.images.width }) @@ -113,29 +111,31 @@ Rectangle{ backgroundRadius: 90 colorSet: ChatStyle.replyPreview.closeButton - onClicked: parent.hide() + onClicked: chatRoomModel.reply = null } states: [ State { name: "hidden" - PropertyChanges { target: replyPreviewBlock; opacity: 0 } + PropertyChanges { target: replyPreviewBlock; opacity: 0 ; visible: false } }, State { name: "showed" - PropertyChanges { target: replyPreviewBlock; opacity: 1 } + PropertyChanges { target: replyPreviewBlock; opacity: 1 ; visible: true} } ] transitions: [ Transition { from: "*"; to: "showed" SequentialAnimation{ + ScriptAction{ script: replyPreviewBlock.visible = true } NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 500 } } }, Transition { + from: "*"; to: "hidden" SequentialAnimation{ NumberAnimation{ properties: "opacity"; duration: 250 } - ScriptAction{ script: container.replyChatMessageModel = null } + ScriptAction{ script: replyPreviewBlock.visible = false } } } ]