From fedf26a65d851163295cd0dc31283ba3a795fde5 Mon Sep 17 00:00:00 2001
From: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Date: Tue, 19 Jan 2016 13:33:54 -0500
Subject: [PATCH] chat: track unread message count

Each TextRecording object tracks the number of unread messages and report it to
the RecordingModel. It allows to display a global notice on how many text
messages are unread in the app.

Change-Id: I5053466ffa9b678cf35c67a62adc3a5849a06e4f
Tuleap: #202
---
 src/media/recordingmodel.cpp  | 18 ++++++++++++++++++
 src/media/recordingmodel.h    |  3 ++-
 src/media/textrecording.cpp   | 10 +++++++++-
 src/media/textrecording.h     |  1 +
 src/private/textrecording_p.h |  1 +
 5 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/media/recordingmodel.cpp b/src/media/recordingmodel.cpp
index b0eaf407..4218898b 100644
--- a/src/media/recordingmodel.cpp
+++ b/src/media/recordingmodel.cpp
@@ -63,9 +63,12 @@ public:
    RecordingNode*                 m_pText                   ;
    RecordingNode*                 m_pAudioVideo             ;
    LocalTextRecordingCollection*  m_pTextRecordingCollection;
+   int                            m_UnreadCount             ;
+
    //RecordingNode*                 m_pFiles     ; //TODO uncomment when implemented in DRing
 
    void forwardInsertion(const QMap<QString,QString>& message, ContactMethod* cm, Media::Media::Direction direction);
+   void updateUnreadCount(const int count);
 
 private:
    Media::RecordingModel* q_ptr;
@@ -90,6 +93,15 @@ void RecordingModelPrivate::forwardInsertion(const QMap<QString,QString>& messag
    emit q_ptr->newTextMessage(static_cast<Media::TextRecording*>(sender()), cm);
 }
 
+void RecordingModelPrivate::updateUnreadCount(const int count)
+{
+    m_UnreadCount += count;
+    if (m_UnreadCount <= 0) {
+        m_UnreadCount = 0;
+    }
+    emit q_ptr->unreadMessagesCountChanged(m_UnreadCount);
+}
+
 Media::RecordingModel::~RecordingModel()
 {
    delete d_ptr;
@@ -264,6 +276,7 @@ bool Media::RecordingModel::addItemCallback(const Recording* item)
       if (item->type() == Recording::Type::TEXT) {
          const TextRecording* r = static_cast<const TextRecording*>(item);
          connect(r, &TextRecording::messageInserted, d_ptr, &RecordingModelPrivate::forwardInsertion);
+         connect(r, &TextRecording::unreadCountChange, d_ptr, &RecordingModelPrivate::updateUnreadCount);
       }
 
       return true;
@@ -321,6 +334,11 @@ void Media::RecordingModel::setAlwaysRecording(bool record)
    configurationManager.setIsAlwaysRecording   ( record );
 }
 
+int  Media::RecordingModel::unreadCount() const
+{
+    return d_ptr->m_UnreadCount;
+}
+
 ///Create or load the recording associated with the ContactMethod cm
 Media::TextRecording* Media::RecordingModel::createTextRecording(const ContactMethod* cm)
 {
diff --git a/src/media/recordingmodel.h b/src/media/recordingmodel.h
index d39d5aa1..b5289098 100644
--- a/src/media/recordingmodel.h
+++ b/src/media/recordingmodel.h
@@ -73,6 +73,7 @@ public:
    //Getter
    bool isAlwaysRecording() const;
    QUrl recordPath       () const;
+   int  unreadCount      () const;
 
    //Setter
    void setAlwaysRecording( bool        record );
@@ -86,6 +87,7 @@ public:
 
 Q_SIGNALS:
    void newTextMessage(TextRecording* t, ContactMethod* cm);
+   void unreadMessagesCountChanged(int unreadCount);
 
 private:
    RecordingModelPrivate* d_ptr;
@@ -98,4 +100,3 @@ private:
 };
 
 }
-
diff --git a/src/media/textrecording.cpp b/src/media/textrecording.cpp
index da7317bd..c1d192ac 100644
--- a/src/media/textrecording.cpp
+++ b/src/media/textrecording.cpp
@@ -147,7 +147,7 @@ Serializable::Peers* SerializableEntityManager::fromJson(const QJsonObject& json
    return p;
 }
 
-Media::TextRecordingPrivate::TextRecordingPrivate(TextRecording* r) : q_ptr(r),m_pImModel(nullptr),m_pCurrentGroup(nullptr)
+Media::TextRecordingPrivate::TextRecordingPrivate(TextRecording* r) : q_ptr(r),m_pImModel(nullptr),m_pCurrentGroup(nullptr),m_UnreadCount(0)
 {
 
 }
@@ -198,6 +198,9 @@ void Media::TextRecording::setAllRead()
     if (changed) {
         // TODO: we assume that the CM is the same for now, and that at least some of the messages
         //       are text
+        int oldVal = d_ptr->m_UnreadCount;
+        d_ptr->m_UnreadCount = 0;
+        emit unreadCountChange(-oldVal);
         emit d_ptr->m_lNodes[0]->m_pContactMethod->unreadTextMessageCountChanged();
         emit d_ptr->m_lNodes[0]->m_pContactMethod->changed();
         save();
@@ -415,6 +418,8 @@ void Media::TextRecordingPrivate::insertNewMessage(const QMap<QString,QString>&
    cm->setLastUsed(currentTime);
    emit q_ptr->messageInserted(message, const_cast<ContactMethod*>(cm), direction);
    if (!m->isRead) {
+      m_UnreadCount += 1;
+      emit q_ptr->unreadCountChange(1);
       emit cm->unreadTextMessageCountChanged();
       emit cm->changed();
    }
@@ -705,6 +710,9 @@ bool InstantMessagingModel::setData(const QModelIndex& idx, const QVariant &valu
             if (n->m_pMessage->isRead != value.toBool()) {
                 n->m_pMessage->isRead = value.toBool();
                 if (n->m_pMessage->m_HasText) {
+                    int val = value.toBool() ? -1 : +1;
+                    m_pRecording->d_ptr->m_UnreadCount += val;
+                    emit m_pRecording->unreadCountChange(val);
                     emit n->m_pContactMethod->unreadTextMessageCountChanged();
                     emit n->m_pContactMethod->changed();
                 }
diff --git a/src/media/textrecording.h b/src/media/textrecording.h
index 1f37b509..bbe2338f 100644
--- a/src/media/textrecording.h
+++ b/src/media/textrecording.h
@@ -79,6 +79,7 @@ public:
 
 Q_SIGNALS:
    void messageInserted(const QMap<QString,QString>& message, ContactMethod* cm, Media::Media::Direction direction);
+   void unreadCountChange(int count);
 
 private:
    TextRecordingPrivate* d_ptr;
diff --git a/src/private/textrecording_p.h b/src/private/textrecording_p.h
index c2d55fc2..68ab19e4 100644
--- a/src/private/textrecording_p.h
+++ b/src/private/textrecording_p.h
@@ -157,6 +157,7 @@ public:
    Serializable::Group*        m_pCurrentGroup      ;
    QList<Serializable::Peers*> m_lAssociatedPeers   ;
    QHash<QString,bool>         m_hMimeTypes         ;
+   int                         m_UnreadCount        ;
    QStringList                 m_lMimeTypes         ;
    QAbstractItemModel*         m_pTextMessagesModel {nullptr};
    QAbstractItemModel*         m_pUnreadTextMessagesModel {nullptr};
-- 
GitLab