diff --git a/Linphone/core/chat/message/ChatMessageCore.cpp b/Linphone/core/chat/message/ChatMessageCore.cpp index bbb04676f..e6b0d103e 100644 --- a/Linphone/core/chat/message/ChatMessageCore.cpp +++ b/Linphone/core/chat/message/ChatMessageCore.cpp @@ -382,13 +382,6 @@ QDateTime ChatMessageCore::getTimestamp() const { return mTimestamp; } -void ChatMessageCore::setTimestamp(QDateTime timestamp) { - if (mTimestamp != timestamp) { - mTimestamp = timestamp; - emit timestampChanged(timestamp); - } -} - QString ChatMessageCore::getText() const { return mText; } diff --git a/Linphone/core/chat/message/ChatMessageCore.hpp b/Linphone/core/chat/message/ChatMessageCore.hpp index 44deb1904..b09804aa6 100644 --- a/Linphone/core/chat/message/ChatMessageCore.hpp +++ b/Linphone/core/chat/message/ChatMessageCore.hpp @@ -77,7 +77,7 @@ class EventLogCore; class ChatMessageCore : public QObject, public AbstractObject { Q_OBJECT - Q_PROPERTY(QDateTime timestamp READ getTimestamp WRITE setTimestamp NOTIFY timestampChanged) + Q_PROPERTY(QDateTime timestamp READ getTimestamp CONSTANT) Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged) Q_PROPERTY(QString utf8Text MEMBER mUtf8Text CONSTANT) Q_PROPERTY(bool hasTextContent MEMBER mHasTextContent CONSTANT) @@ -119,9 +119,6 @@ public: QList computeDeliveryStatus(const std::shared_ptr &message); - QDateTime getTimestamp() const; - void setTimestamp(QDateTime timestamp); - QString getText() const; void setText(QString text); @@ -138,6 +135,7 @@ public: bool isEphemeral() const; int getEphemeralDuration() const; void setEphemeralDuration(int duration); + QDateTime getTimestamp() const; bool hasFileContent() const; @@ -168,7 +166,6 @@ public: Q_INVOKABLE ChatMessageContentGui *getVoiceRecordingContent() const; signals: - void timestampChanged(QDateTime timestamp); void textChanged(QString text); void utf8TextChanged(QString text); void isReadChanged(bool read); diff --git a/Linphone/core/chat/message/EventLogCore.cpp b/Linphone/core/chat/message/EventLogCore.cpp index 920333486..30fee03bc 100644 --- a/Linphone/core/chat/message/EventLogCore.cpp +++ b/Linphone/core/chat/message/EventLogCore.cpp @@ -37,9 +37,11 @@ EventLogCore::EventLogCore(const std::shared_ptr &even App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); mEventLogType = LinphoneEnums::fromLinphone(eventLog->getType()); mTimestamp = QDateTime::fromMSecsSinceEpoch(eventLog->getCreationTime() * 1000); - if (eventLog->getChatMessage()) { - mChatMessageCore = ChatMessageCore::create(eventLog->getChatMessage()); - mEventId = Utils::coreStringToAppString(eventLog->getChatMessage()->getMessageId()); + auto chatmessage = eventLog->getChatMessage(); + if (chatmessage) { + mChatMessageCore = ChatMessageCore::create(chatmessage); + mEventId = Utils::coreStringToAppString(chatmessage->getMessageId()); + mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime()); } else if (eventLog->getCallLog()) { mCallHistoryCore = CallHistoryCore::create(eventLog->getCallLog()); mEventId = Utils::coreStringToAppString(eventLog->getCallLog()->getCallId()); @@ -80,6 +82,10 @@ CallHistoryCore *EventLogCore::getCallHistoryCorePointer() { return mCallHistoryCore.get(); } +QDateTime EventLogCore::getTimestamp() const { + return mTimestamp; +} + // Events (other than ChatMessage and CallLog which are handled in their respective Core) void EventLogCore::computeEvent(const std::shared_ptr &eventLog) { diff --git a/Linphone/core/chat/message/EventLogCore.hpp b/Linphone/core/chat/message/EventLogCore.hpp index aea5cb80e..bb5121389 100644 --- a/Linphone/core/chat/message/EventLogCore.hpp +++ b/Linphone/core/chat/message/EventLogCore.hpp @@ -47,7 +47,7 @@ class EventLogCore : public QObject, public AbstractObject { Q_PROPERTY(bool important MEMBER mImportant CONSTANT) Q_PROPERTY(bool handled MEMBER mHandled CONSTANT) Q_PROPERTY(QString eventDetails MEMBER mEventDetails CONSTANT) - Q_PROPERTY(QDateTime timestamp MEMBER mTimestamp CONSTANT) + Q_PROPERTY(QDateTime timestamp READ getTimestamp CONSTANT) public: static QSharedPointer create(const std::shared_ptr &eventLog); @@ -58,6 +58,9 @@ public: QSharedPointer getChatMessageCore(); ChatMessageGui *getChatMessageGui(); QSharedPointer getCallHistoryCore(); + + QDateTime getTimestamp() const; + bool isHandled() const { return mHandled; } diff --git a/Linphone/core/chat/message/EventLogList.cpp b/Linphone/core/chat/message/EventLogList.cpp index a8de6d118..4dc787989 100644 --- a/Linphone/core/chat/message/EventLogList.cpp +++ b/Linphone/core/chat/message/EventLogList.cpp @@ -141,14 +141,14 @@ QVariant EventLogList::data(const QModelIndex &index, int role) const { if (core->getChatMessageCore()) { switch (role) { case Qt::DisplayRole: - return QVariant::fromValue(new ChatMessageGui(core->getChatMessageCore())); + return QVariant::fromValue(new EventLogGui(core)); case Qt::DisplayRole + 1: return "chatMessage"; } } else if (core->getCallHistoryCore()) { switch (role) { case Qt::DisplayRole: - return QVariant::fromValue(new CallHistoryGui(core->getCallHistoryCore())); + return QVariant::fromValue(new EventLogGui(core)); case Qt::DisplayRole + 1: return "callLog"; } diff --git a/Linphone/core/chat/message/EventLogProxy.cpp b/Linphone/core/chat/message/EventLogProxy.cpp index cca0a677d..26d69fa53 100644 --- a/Linphone/core/chat/message/EventLogProxy.cpp +++ b/Linphone/core/chat/message/EventLogProxy.cpp @@ -53,7 +53,7 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) { emit eventInserted(index, event); }); } - setSourceModels(new SortFilterList(model)); + setSourceModels(new SortFilterList(model, Qt::AscendingOrder)); sort(0); } @@ -94,6 +94,11 @@ int EventLogProxy::findFirstUnreadIndex() { return std::max(0, getCount() - 1); } +void EventLogProxy::markIndexAsRead(int proxyIndex) { + auto event = getItemAt(proxyIndex); + if (event && event->getChatMessageCore()) event->getChatMessageCore()->lMarkAsRead(); +} + int EventLogProxy::findIndexCorrespondingToFilter(int startIndex, bool goingBackward) { auto filter = getFilterText(); if (filter.isEmpty()) return startIndex; @@ -117,8 +122,8 @@ bool EventLogProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModel } bool EventLogProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { - auto l = getItemAtSource(sourceLeft.row()); - auto r = getItemAtSource(sourceRight.row()); + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); if (l && r) return l->getTimestamp() <= r->getTimestamp(); else return true; } diff --git a/Linphone/core/chat/message/EventLogProxy.hpp b/Linphone/core/chat/message/EventLogProxy.hpp index 5ca463524..316efc7c0 100644 --- a/Linphone/core/chat/message/EventLogProxy.hpp +++ b/Linphone/core/chat/message/EventLogProxy.hpp @@ -46,6 +46,7 @@ public: Q_INVOKABLE EventLogGui *getEventAtIndex(int index); Q_INVOKABLE int findFirstUnreadIndex(); + Q_INVOKABLE void markIndexAsRead(int proxyIndex); Q_INVOKABLE int findIndexCorrespondingToFilter(int startIndex, bool goingBackward = false); signals: diff --git a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml index 26204d78a..519eba1de 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml @@ -5,6 +5,7 @@ import QtQuick.Controls.Basic as Control import Qt.labs.qmlmodels import Linphone import UtilsCpp +import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle ListView { id: mainItem @@ -57,6 +58,7 @@ ListView { Qt.callLater(function() { var index = eventLogProxy.findFirstUnreadIndex() positionViewAtIndex(index, ListView.End) + eventLogProxy.markIndexAsRead(index) }) } @@ -73,18 +75,21 @@ ListView { topPadding: Math.round(16 * DefaultStyle.dp) bottomPadding: Math.round(16 * DefaultStyle.dp) anchors.bottom: parent.bottom + style: ButtonStyle.main anchors.right: parent.right anchors.bottomMargin: Math.round(18 * DefaultStyle.dp) anchors.rightMargin: Math.round(18 * DefaultStyle.dp) onClicked: { var index = eventLogProxy.findFirstUnreadIndex() mainItem.positionViewAtIndex(index, ListView.End) + eventLogProxy.markIndexAsRead(index) } } onAtYEndChanged: if (atYEnd) { if (eventLogProxy.haveMore) eventLogProxy.displayMore() + else chat.core.lMarkAsRead() } model: EventLogProxy { @@ -94,11 +99,12 @@ ListView { filterText: mainItem.filterText onEventInserted: (index, gui) => { if (!mainItem.visible) return - mainItem.positionViewAtIndex(index, ListView.End) + if(mainItem.lastItemVisible) mainItem.positionViewAtIndex(index, ListView.End) } onModelReset: Qt.callLater(function() { var index = eventLogProxy.findFirstUnreadIndex() positionViewAtIndex(index, ListView.End) + eventLogProxy.markIndexAsRead(index) }) } @@ -162,23 +168,16 @@ ListView { id: chatMessageDelegate property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) + chatMessage: modelData.core.chatMessageGui onIsFullyVisibleChanged: { if (index === mainItem.count - 1) { mainItem.lastItemVisible = isFullyVisible } - if (isFullyVisible) - modelData.core.lMarkAsRead() } Component.onCompleted: if (index === mainItem.count - 1) mainItem.lastItemVisible = isFullyVisible - chatMessage: modelData chat: mainItem.chat searchedTextPart: mainItem.filterText maxWidth: Math.round(mainItem.width * (3/4)) - onVisibleChanged: { - if (visible) { - modelData.core.lMarkAsRead() - } - } width: mainItem.width property var previousIndex: index - 1 property ChatMessageGui nextChatMessage: index >= (mainItem.count - 1) @@ -188,16 +187,16 @@ ListView { : null property var previousFromAddress: eventLogProxy.getEventAtIndex(index-1)?.core.chatMessage?.fromAddress backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100 - isFirstMessage: !previousFromAddress || previousFromAddress !== modelData.core.fromAddress + isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress anchors.right: !isRemoteMessage && parent ? parent.right : undefined - onMessageDeletionRequested: modelData.core.lDelete() - onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(modelData) - onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(modelData) - onReplyToMessageRequested: mainItem.replyToMessageRequested(modelData) - onForwardMessageRequested: mainItem.forwardMessageRequested(modelData) + onMessageDeletionRequested: chatMessage.core.lDelete() + onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage) + onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage) + onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage) + onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage) onEndOfVoiceRecordingReached: { if (nextChatMessage && nextChatMessage.core.isVoiceRecording) mainItem.requestAutoPlayVoiceRecording(index + 1) }