From b8d0c8185be32e3c4c2f72dc8dc660bdf821844b Mon Sep 17 00:00:00 2001
From: Armin Felder <armin.felder@osalliance.com>
Date: Wed, 19 Dec 2018 21:05:51 +0100
Subject: [PATCH] avatar

---
 CustomModels/messagemodel.cpp           | 47 +++++++++++++++++++++++++
 CustomModels/messagemodel.h             |  5 ++-
 repos/entities/rocketchatattachment.h   |  3 +-
 repos/entities/rocketchatmessage.cpp    | 13 +++++++
 repos/entities/rocketchatmessage.h      |  9 ++++-
 repos/entities/rocketchatreplymessage.h |  6 +---
 rocketchatserver.cpp                    |  2 +-
 services/fileservice.h                  |  2 ++
 services/messageservice.cpp             | 17 ++++++---
 services/messageservice.h               |  7 ++--
 10 files changed, 95 insertions(+), 16 deletions(-)

diff --git a/CustomModels/messagemodel.cpp b/CustomModels/messagemodel.cpp
index 94e7c47..cb48a5a 100644
--- a/CustomModels/messagemodel.cpp
+++ b/CustomModels/messagemodel.cpp
@@ -162,6 +162,21 @@ QVariant MessagesModel::data( const QModelIndex &index, int role ) const
         case MessageRoles::replyDate:
             //TODO: implement or remove!
             break;
+
+        case MessageRoles::avatarImg: {
+                if ( messageAtIndex.isNull() ) {
+                    return "";
+                } else {
+                    auto avatarImg = messageAtIndex->getAvatarImg();
+
+                    if ( !avatarImg.isNull() ) {
+                        return messageAtIndex->getAvatarImg()->getFilePath();
+                    } else {
+                        return "";
+                    }
+                }
+            }
+            break;
     }
 
     qWarning() << "MessagesModel data not found for row";
@@ -243,6 +258,10 @@ bool MessagesModel::addChannel( const QSharedPointer<RocketChatChannel> &channel
         return false;
     }
 
+    for ( auto message : channel->getMessageRepo()->getElements() ) {
+        connect( message.data(), &RocketChatMessage::dataChanged, this, &MessagesModel::onDataChanged, Qt::UniqueConnection );
+    }
+
     mChannelMap.insert( id, channel );
     connect( channel.data(), &RocketChatChannel::messageAdded, this, [ = ]( const QString & id, qint64 timestamp ) {
         Q_UNUSED( id )
@@ -280,6 +299,8 @@ QHash<int, QByteArray> MessagesModel::roleNames() const
     roles[static_cast<int>( MessageRoles::replyAutor )] = QByteArrayLiteral( "replyAutor" );
     roles[static_cast<int>( MessageRoles::replyDate )] = QByteArrayLiteral( "replyDate" );
     roles[static_cast<int>( MessageRoles::replyUrl )] = QByteArrayLiteral( "replyUrl" );
+    roles[static_cast<int>( MessageRoles::avatarImg )] = QByteArrayLiteral( "avatarImg" );
+
     return roles;
 }
 
@@ -304,6 +325,7 @@ void MessagesModel::onNewMessage( const QSharedPointer<RocketChatChannel> &chann
             beginInsertRows( QModelIndex(), row, row );
             messagesOfCurrentChannel.insert( row, message );
             mInsertCount++;
+            connect( message.data(), &RocketChatMessage::dataChanged, this, &MessagesModel::onDataChanged, Qt::UniqueConnection );
             endInsertRows();
             duplicateCheck.insert( message->getId() );
         }
@@ -335,6 +357,31 @@ void MessagesModel::onEndInsertList( const QString &pChannelId )
     }
 }
 
+void MessagesModel::onDataChanged( const QString &id, const QString &property )
+{
+    int pos = 0;
+    bool found = false;
+
+    for ( const auto &current : messagesOfCurrentChannel ) {
+        if ( current->getId() == id ) {
+            found = true;
+            break;
+        }
+
+        pos++;
+    }
+
+    if ( found ) {
+        auto roles = roleNames();
+
+        for ( auto it = roles.begin(); it != roles.end(); it++ ) {
+            if ( roles[it.key()] == property ) {
+                emit dataChanged( index( pos ), index( pos ), {it.key()} );
+            }
+        }
+    }
+}
+
 void MessagesModel::addChannelSlot( const QSharedPointer<RocketChatChannel> &channel )
 {
     addChannel( channel );
diff --git a/CustomModels/messagemodel.h b/CustomModels/messagemodel.h
index 953709e..412d3ac 100644
--- a/CustomModels/messagemodel.h
+++ b/CustomModels/messagemodel.h
@@ -56,7 +56,8 @@ class MessagesModel : public QAbstractListModel
             replyMessage,
             replyAutor,
             replyDate,
-            replyUrl
+            replyUrl,
+            avatarImg
         };
         MessagesModel();
         QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
@@ -86,6 +87,8 @@ class MessagesModel : public QAbstractListModel
         QMutex mutex;
         QSet<QString> mBlockedUsers;
 
+        void onDataChanged( const QString &id, const QString &property );
+
     signals:
         void currentChannelChanged( void );
         void countChanged();
diff --git a/repos/entities/rocketchatattachment.h b/repos/entities/rocketchatattachment.h
index 97d6d11..035e971 100644
--- a/repos/entities/rocketchatattachment.h
+++ b/repos/entities/rocketchatattachment.h
@@ -24,9 +24,8 @@
 #include <QString>
 #include <QObject>
 
-class RocketChatAttachment : public QObject
+class RocketChatAttachment
 {
-        Q_OBJECT
     public:
         RocketChatAttachment( const QString &pFileUrl, const QString &pType, const QString &pTitle );
 
diff --git a/repos/entities/rocketchatmessage.cpp b/repos/entities/rocketchatmessage.cpp
index 2f68f0d..0799a6f 100755
--- a/repos/entities/rocketchatmessage.cpp
+++ b/repos/entities/rocketchatmessage.cpp
@@ -197,3 +197,16 @@ void RocketChatMessage::setRoomeTyp( const QString &value )
 {
     roomeTyp = value;
 }
+
+QSharedPointer<TempFile> RocketChatMessage::getAvatarImg() const
+{
+    return mAvatarImg;
+}
+
+void RocketChatMessage::setAvatarImg( const QSharedPointer<TempFile> &avatarImg )
+{
+    if ( mAvatarImg != avatarImg ) {
+        mAvatarImg = avatarImg;
+        emit dataChanged( id, "avatarImg" );
+    }
+}
diff --git a/repos/entities/rocketchatmessage.h b/repos/entities/rocketchatmessage.h
index 0016844..acf2792 100755
--- a/repos/entities/rocketchatmessage.h
+++ b/repos/entities/rocketchatmessage.h
@@ -32,8 +32,9 @@
 
 class EmojiRepo;
 
-class RocketChatMessage
+class RocketChatMessage: public QObject
 {
+        Q_OBJECT
     public:
         enum class Type {
             textmessage,
@@ -97,7 +98,11 @@ class RocketChatMessage
         const QString &getRoomeTyp() const;
         void setRoomeTyp( const QString &value );
 
+        QSharedPointer<TempFile> getAvatarImg() const;
+        void setAvatarImg( const QSharedPointer<TempFile> &avatarImg );
+
     protected:
+        QSharedPointer<TempFile> mAvatarImg;
         bool empty = false;
         qint64 timestamp = 0;
         QJsonObject data;
@@ -117,6 +122,8 @@ class RocketChatMessage
         QString roomeTyp;
         QList<QSharedPointer<RocketChatAttachment>> attachments;
         qint64 mEmojiHash = 0;
+    signals:
+        void dataChanged( const QString &id, const QString &property );
 };
 
 #endif // ROCKETCHATMESSAGE_H
diff --git a/repos/entities/rocketchatreplymessage.h b/repos/entities/rocketchatreplymessage.h
index 417ea45..3c05bea 100644
--- a/repos/entities/rocketchatreplymessage.h
+++ b/repos/entities/rocketchatreplymessage.h
@@ -6,16 +6,12 @@
 
 #include <QObject>
 
-class RocketChatReplyMessage :  public RocketChatAttachment, RocketChatMessage
+class RocketChatReplyMessage : public RocketChatAttachment, public RocketChatMessage
 {
-        Q_OBJECT
     public:
         RocketChatReplyMessage( const QString &pText, const QString &pAuthor, const QString &pUrl = "" );
         using RocketChatMessage::getMessageString;
         using RocketChatMessage::getAuthor;
-    signals:
-
-    public slots:
 };
 
 #endif // ROCKETCHATREPLYMESSAGE_H
diff --git a/rocketchatserver.cpp b/rocketchatserver.cpp
index f1cb425..e1d2197 100755
--- a/rocketchatserver.cpp
+++ b/rocketchatserver.cpp
@@ -142,7 +142,7 @@ void RocketChatServerData::initConnections()
 
     loadEmojis();
 
-    mMessageService = new MessageService( this, mStorage, this, mEmojiRepo );
+    mMessageService = new MessageService( this, mStorage, this, mEmojiRepo, mFileService );
     mChannelService = new RocketChatChannelService( this, this, mMessageService );
     mChannelService->setDdp( mDdpApi );
     mChannelService->setChannels( mChannels );
diff --git a/services/fileservice.h b/services/fileservice.h
index 85ce563..09b4eda 100644
--- a/services/fileservice.h
+++ b/services/fileservice.h
@@ -28,7 +28,9 @@
 #include <QMimeDatabase>
 #include "repos/entities/tempfile.h"
 #include "rocketchatserver.h"
+#include "persistancelayer.h"
 class RocketChatServerData;
+class PersistanceLayer;
 
 class FileRequest
 {
diff --git a/services/messageservice.cpp b/services/messageservice.cpp
index 8abd3bc..4ad15fd 100644
--- a/services/messageservice.cpp
+++ b/services/messageservice.cpp
@@ -22,8 +22,8 @@
 #include <algorithm>
 #include "messageservice.h"
 
-#include <repos/entities/rocketchatreplymessage.h>
-
+#include "repos/entities/rocketchatreplymessage.h"
+#include "services/fileservice.h"
 
 
 //MessageService::MessageService( PersistanceLayer *pPersistanceLayer,
@@ -36,8 +36,9 @@
 
 MessageService::MessageService( QObject *parent, PersistanceLayer *pPersistanceLayer,
                                 RocketChatServerData *pServer,
-                                EmojiRepo *pEmojiRepo ): QObject( parent ), mReplyRegeEx( "\\[ \\]\\(.*\\)</a>" ), mEmojiRepo( pEmojiRepo ), mMessagesModel( Models::getMessagesModel() ),
-    mReplyReplyRegeEx( "\\[ \\]\\(.*\\)" ), mSearchResults( Models::getMessagesSearchModel() )
+                                EmojiRepo *pEmojiRepo, FileService *pFileService ): QObject( parent ),
+    mReplyRegeEx( "\\[ \\]\\(.*\\)</a>" ), mEmojiRepo( pEmojiRepo ), mMessagesModel( Models::getMessagesModel() ),
+    mReplyReplyRegeEx( "\\[ \\]\\(.*\\)" ), mSearchResults( Models::getMessagesSearchModel() ), mFileService( pFileService )
 {
     this->mPersistanceLayer = pPersistanceLayer;
     this->mServer = pServer;
@@ -210,6 +211,14 @@ QSharedPointer<RocketChatMessage> MessageService::parseMessage( const QJsonObjec
             }
         }
 
+        auto then = [ message ]( QSharedPointer<TempFile> tempfile, bool showInline ) {
+            message->setAvatarImg( tempfile );
+        };
+        auto baseUrl = mServer->getBaseUrl();
+        auto avatarUrl = baseUrl + "/avatar/" + author + ".jpg";
+        auto avatarRequest = QSharedPointer<FileRequest>::create( avatarUrl, "temp", then, true );
+        mFileService->getFileRessource( avatarRequest );
+
         message->setAuthor( author );
         message->setFormattedDate( formattedDate );
         message->setFormattedTime( formattedTime );
diff --git a/services/messageservice.h b/services/messageservice.h
index 3b5192c..f4c00a2 100644
--- a/services/messageservice.h
+++ b/services/messageservice.h
@@ -40,18 +40,20 @@
 #include "services/requests/loadmissedmessageservicerequest.h"
 #include "CustomModels/messagemodel.h"
 #include "CustomModels/messagesearchresultsmodel.h"
+#include "services/fileservice.h"
 
 typedef QList<QSharedPointer<RocketChatMessage>> MessageList;
 typedef QSharedPointer<RocketChatMessage> ChatMessage;
 class PersistanceLayer;
 class RocketChatServerData;
+class FileService;
 
 class MessageService : public QObject
 {
         Q_OBJECT
     public:
-        // MessageService(PersistanceLayer *pPersistanceLayer, RocketChatServerData* pServer, const QHash<QString, QString> &pEmojisMap);
-        MessageService( QObject *parent, PersistanceLayer *pPersistanceLayer, RocketChatServerData *pServer, EmojiRepo *mEmojiRepo );
+        // MessageService(PersistanceLayer *pPersistanceLayer, RocketChatServerData* pServer, const QHash<QString, QString> &pEmojisMap, FileService &pFileService);
+        MessageService( QObject *parent, PersistanceLayer *pPersistanceLayer, RocketChatServerData *pServer, EmojiRepo *mEmojiRepo, FileService *pFileService );
         void loadHistory( const QSharedPointer<LoadHistoryServiceRequest> & );
         void checkForMissingMessages( const QSharedPointer<LoadMissedMessageServiceRequest> &pRequest );
         void sendMessage( const QSharedPointer<RocketChatMessage> &pMessage );
@@ -71,6 +73,7 @@ class MessageService : public QObject
         PersistanceLayer *mPersistanceLayer;
         RocketChatServerData *mServer;
         MessageSearchResultsModel *mSearchResults;
+        FileService *mFileService;
 
         void loadHistoryFromServer( const QSharedPointer<LoadHistoryRequestContainer> &pContainer );
         void loadHistoryFromServer( const QSharedPointer<LoadHistoryServiceRequest> &pContainer );
-- 
GitLab