From 610097c5a52cfcdcf5c562a826ae1a7d826d5425 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Thu, 20 Oct 2022 15:25:23 +0200 Subject: [PATCH] Make a cache for text to each chat rooms. Display a draft icon in timeline if a etxt has been cached. --- linphone-app/assets/images/draft_custom.svg | 49 +++++++++++++++++++ linphone-app/resources.qrc | 1 + .../components/chat-room/ChatRoomModel.cpp | 30 +++++++++++- .../components/chat-room/ChatRoomModel.hpp | 13 ++++- .../chat-room/ChatRoomProxyModel.cpp | 9 +--- .../chat-room/ChatRoomProxyModel.hpp | 5 -- .../ui/modules/Linphone/Chat/Chat.qml | 5 +- .../Styles/Timeline/TimelineStyle.qml | 7 +++ .../Linphone/Timeline/TimelineItem.qml | 19 +++++-- 9 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 linphone-app/assets/images/draft_custom.svg diff --git a/linphone-app/assets/images/draft_custom.svg b/linphone-app/assets/images/draft_custom.svg new file mode 100644 index 000000000..069924dae --- /dev/null +++ b/linphone-app/assets/images/draft_custom.svg @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc index d3d6ddeee..2c0eb933b 100644 --- a/linphone-app/resources.qrc +++ b/linphone-app/resources.qrc @@ -77,6 +77,7 @@ assets/images/declined_outgoing_call_custom.svg assets/images/delete_custom.svg assets/images/download_custom.svg + assets/images/draft_custom.svg assets/images/drop_down_custom.svg assets/images/edit_custom.svg assets/images/ended_call_custom.svg diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index dacb570dc..6eb324b52 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -523,6 +523,14 @@ int ChatRoomModel::getAllUnreadCount(){ return mUnreadMessagesCount + mMissedCallsCount; } +QString ChatRoomModel::getCachedText()const{ + return mCachedText; +} + +bool ChatRoomModel::hasDraft() const{ + return mHasDraft; +} + //------------------------------------------------------------------------------------------------ void ChatRoomModel::setSubject(QString& subject){ @@ -597,6 +605,23 @@ void ChatRoomModel::enableMarkAsRead(const bool& enable){ } } +bool ChatRoomModel::setCachedText(const QString& text){ + if(mCachedText != text){ + mCachedText = text; + emit cachedTextChanged(); + setHasDraft(!mCachedText.isEmpty()); + return true; + }else + return false; +} + +void ChatRoomModel::setHasDraft(const bool& cached){ + if(mHasDraft != cached){ + mHasDraft = cached; + emit hasDraftChanged(); + } +} + void ChatRoomModel::setReply(ChatMessageModel * model){ if(model != mReplyModel.get()){ if( model && model->getChatMessage() ) @@ -699,6 +724,7 @@ void ChatRoomModel::sendMessage (const QString &message) { if(recorder->haveVocalRecorder()) recorder->clearVocalRecorder(); CoreManager::getInstance()->getChatModel()->clear(); + setCachedText(""); } } @@ -718,8 +744,8 @@ void ChatRoomModel::forwardMessage(ChatMessageModel * model){ } // ----------------------------------------------------------------------------- -void ChatRoomModel::compose () { - if( mChatRoom) +void ChatRoomModel::compose (const QString& text) { + if( setCachedText(text) && mChatRoom)// only send a compose if text has changed mChatRoom->compose(); } diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp index ec8e82e26..bcac30bd0 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp @@ -92,6 +92,9 @@ public: Q_PROPERTY(bool entriesLoading READ isEntriesLoading WRITE setEntriesLoading NOTIFY entriesLoadingChanged) + Q_PROPERTY(QString cachedText READ getCachedText WRITE setCachedText NOTIFY cachedTextChanged) + Q_PROPERTY(bool hasDraft READ hasDraft WRITE setHasDraft NOTIFY hasDraftChanged) + static QSharedPointer create(std::shared_ptr chatRoom, const std::list>& callLogs = std::list>()); ChatRoomModel (std::shared_ptr chatRoom, const std::list>& callLogs = std::list>(), QObject * parent = nullptr); @@ -141,6 +144,8 @@ public: QList getComposers(); QString getParticipantAddress(); // return peerAddress if not secure else return the first participant SIP address. int getAllUnreadCount(); // Return unread messages and missed call. + QString getCachedText() const; + bool hasDraft() const; //---- Setters void setSubject(QString& subject); @@ -154,6 +159,8 @@ public: void setEphemeralEnabled(bool enabled); void setEphemeralLifetime(long lifetime); void enableMarkAsRead(const bool& enable); + bool setCachedText(const QString& text); // return true if cache changed + void setHasDraft(const bool& draft); void setReply(ChatMessageModel * model); ChatMessageModel * getReply()const; @@ -168,7 +175,7 @@ public: Q_INVOKABLE void updateParticipants(const QVariantList& participants); void sendMessage (const QString &message); Q_INVOKABLE void forwardMessage(ChatMessageModel * model); - void compose (); + void compose (const QString& text); Q_INVOKABLE void resetMessageCount (); void initEntries(); Q_INVOKABLE int loadMoreEntries(); // return new entries count @@ -273,6 +280,8 @@ signals: void markAsReadEnabledChanged(); void chatRoomDeleted();// Must be connected with DirectConnection mode void replyChanged(); + void cachedTextChanged(); + void hasDraftChanged(); // Chat Room listener callbacks @@ -305,6 +314,8 @@ private: QSharedPointer mReplyModel; QSharedPointer mUnreadMessageNotice; int mBindingCalls = 0; + QString mCachedText; // TODO : replace it by content to manage files/audio etc. + bool mHasDraft = false; QWeakPointer mSelf; }; diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp index ec1b15942..cc644c9bd 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp @@ -36,8 +36,6 @@ using namespace std; -QString ChatRoomProxyModel::gCachedText; - // ============================================================================= ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { @@ -101,8 +99,7 @@ CREATE_PARENT_MODEL_FUNCTION(deleteChatRoom) void ChatRoomProxyModel::compose (const QString& text) { if (mChatRoomModel) - mChatRoomModel->compose(); - gCachedText = text; + mChatRoomModel->compose(text); } int ChatRoomProxyModel::getEntryTypeFilter () { @@ -242,10 +239,6 @@ QVariant ChatRoomProxyModel::getAt(int row){ return sourceModel()->data(sourceIndex); } -QString ChatRoomProxyModel::getCachedText() const{ - return gCachedText; -} - void ChatRoomProxyModel::setIsCall(const bool& isCall){ if(mIsCall != isCall) { if(mChatRoomModel){ diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp index 39a5dc675..03758ec28 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp @@ -40,7 +40,6 @@ class ChatRoomProxyModel : public QSortFilterProxyModel { Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress WRITE setFullLocalAddress NOTIFY fullLocalAddressChanged) Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged) Q_PROPERTY(QList composers READ getComposers NOTIFY isRemoteComposingChanged) - Q_PROPERTY(QString cachedText READ getCachedText) Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged) Q_PROPERTY(bool markAsReadEnabled READ markAsReadEnabled WRITE enableMarkAsRead NOTIFY markAsReadEnabledChanged)// Focus is at end of the list. Used to reset message count if not at end @@ -120,9 +119,6 @@ private: void setChatRoomModel (ChatRoomModel *chatRoomModel); QList getComposers () const; - - QString getCachedText() const; - void reload (ChatRoomModel *chatRoomModel); void handleIsActiveChanged (QWindow *window); @@ -138,7 +134,6 @@ private: QString mLocalAddress; QString mFullPeerAddress; QString mFullLocalAddress; - static QString gCachedText; bool mMarkAsReadEnabled; bool mIsCall = false; diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml index 63adcaf1e..47c3b769b 100644 --- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml +++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml @@ -445,7 +445,10 @@ Rectangle { } } onAudioRecordRequest: RecorderManager.resetVocalRecorder() - Component.onCompleted: {text = proxyModel.cachedText; cursorPosition=text.length} + Component.onCompleted: { + text = proxyModel.chatRoomModel.cachedText + cursorPosition=text.length + } Rectangle{ anchors.fill:parent color:'white' diff --git a/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml index e21555316..1a25f90d3 100644 --- a/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml +++ b/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml @@ -17,6 +17,13 @@ QtObject { property color selectedTimerColor: ColorsList.addImageColor(sectionName+'_ephemeralTimer_c', icon, 'q').color } + property QtObject draft: QtObject{ + property string icon: 'draft_custom' + property int iconSize : 30 + property color color: ColorsList.addImageColor(sectionName+'_draft', icon, 'ad').color + property color selectedColor: ColorsList.addImageColor(sectionName+'_draft_c', icon, 'q').color + } + property QtObject contact: QtObject { property int height: 60 diff --git a/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml b/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml index 3e8f34e42..2b9db1ebc 100644 --- a/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml +++ b/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml @@ -73,14 +73,27 @@ Item { text: mainItem.timelineModel && UtilsCpp.toDateTimeString(mainItem.timelineModel.chatRoomModel.lastUpdateTime) isClickable: true } + + Icon{ + id: draft + icon: TimelineStyle.draft.icon + iconSize: visible ? TimelineStyle.draft.iconSize : 0 + overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.draft.selectedColor : TimelineStyle.draft.color + anchors.right:parent.right + anchors.bottom:parent.bottom + anchors.bottomMargin: 3 + anchors.rightMargin: 7 + visible: mainItem.timelineModel && mainItem.timelineModel.chatRoomModel.hasDraft + } + Icon{ icon: TimelineStyle.ephemeralTimer.icon iconSize: TimelineStyle.ephemeralTimer.iconSize overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.ephemeralTimer.selectedTimerColor : TimelineStyle.ephemeralTimer.timerColor - anchors.right:parent.right + anchors.right:draft.left anchors.bottom:parent.bottom - anchors.bottomMargin: 7 - anchors.rightMargin: 7 + anchors.bottomMargin: 3 + anchors.rightMargin: draft.visible ? 0 : 7 visible: mainItem.timelineModel && mainItem.timelineModel.chatRoomModel.ephemeralEnabled } MouseArea {