diff --git a/CustomModels/channelmodel.cpp b/CustomModels/channelmodel.cpp
index 23a7d367299da492cf03d006095fc335742aae87..eb22f6939cae279ef4a5022d85bc954998a1b728 100644
--- a/CustomModels/channelmodel.cpp
+++ b/CustomModels/channelmodel.cpp
@@ -98,6 +98,35 @@ QVariant ChannelModel::data( const QModelIndex &index, int role ) const
         return currentChannel->getUsername();
     }
 
+    if ( role == userStatus ) {
+        int status = 0;
+        auto partner = currentChannel->getChatPartner();
+
+        if ( !partner.isNull() ) {
+            switch ( partner->getStatus() ) {
+                case RocketChatUser::status::ONLINE :
+                    status = 0;
+                    break;
+
+                case RocketChatUser::status::AWAY :
+                    status = 1;
+                    break;
+
+                case RocketChatUser::status::OFFLINE:
+                    status = 2;
+                    break;
+
+                case RocketChatUser::status::BUSY:
+                    status = 3;
+                    break;
+            }
+        }
+
+        return status;
+
+
+    }
+
     return QVariant();
 
 }
@@ -136,6 +165,7 @@ QHash<int, QByteArray> ChannelModel::roleNames() const
     roles[ownerId] = QByteArrayLiteral( "ownerId" );
     roles[ownerName] = QByteArrayLiteral( "ownerName" );
     roles[username] = QByteArrayLiteral( "username" );
+    roles[userStatus] = QByteArrayLiteral( "userStatus" );
 
     return roles;
 }
diff --git a/CustomModels/channelmodel.h b/CustomModels/channelmodel.h
index 681e9d330c5bf0c9780a51a01412fe8241d41e1d..cf4b5ebb7c59137cc90d10f4f9422af0763f74ed 100644
--- a/CustomModels/channelmodel.h
+++ b/CustomModels/channelmodel.h
@@ -50,7 +50,8 @@ class ChannelModel : public QAbstractListModel
             deleted,
             ownerId,
             ownerName,
-            username
+            username,
+            userStatus
         };
     public:
         ChannelModel();
diff --git a/CustomModels/usermodel.cpp b/CustomModels/usermodel.cpp
index ab4a0a846dd13f5b4ee21c55fea65fce6ed5a062..0a991d32d774cbfaffbef24e97e8d10a329c9d97 100644
--- a/CustomModels/usermodel.cpp
+++ b/CustomModels/usermodel.cpp
@@ -47,12 +47,36 @@ QVariant UserModel::data( const QModelIndex &index, int role ) const
 
     if ( role == UserRoles::UserName ) {
         return user->getUserName();
-    };
+    }
 
     if ( role == UserRoles::name ) {
         return user->getName();
     }
 
+    if ( role == UserRoles::status ) {
+        int status = 2;
+
+        switch ( user->getStatus() ) {
+            case RocketChatUser::status::ONLINE :
+                status = 0;
+                break;
+
+            case RocketChatUser::status::AWAY :
+                status = 1;
+                break;
+
+            case RocketChatUser::status::OFFLINE:
+                status = 2;
+                break;
+
+            case RocketChatUser::status::BUSY:
+                status = 3;
+                break;
+        }
+
+        return status;
+    }
+
     return QVariant();
 }
 
@@ -61,7 +85,37 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke
     beginResetModel();
 
     if ( !user.isNull() ) {
-        userMap.insert( channelId, user );
+        QSharedPointer<RocketChatUser> userToAdd;
+        mMutex.lock();
+
+        if ( mAllUsers.contains( user->getUserId() ) ) {
+            auto oldUser = mAllUsers[user->getUserId()];
+
+            if ( !user->getSurname().isEmpty() ) {
+                oldUser->setSurname( user->getSurname() );
+            }
+
+            if ( !user->getLastname().isEmpty() ) {
+                oldUser->setLastname( user->getLastname() );
+            }
+
+            if ( !user->getName().isEmpty() ) {
+                oldUser->setName( user->getName() );
+            }
+
+            if ( !user->getUserId().isEmpty() ) {
+                oldUser->setUserId( user->getUserId() );
+            }
+
+            userToAdd = oldUser;
+        } else {
+            userToAdd = user;
+            mAllUsers.insert( userToAdd->getUserId(), userToAdd );
+            connect( userToAdd.data(), &RocketChatUser::statusChanged, this, &UserModel::refreshUserList );
+        }
+
+        userMap.insert( channelId, userToAdd );
+        mMutex.unlock();
         setCurrent( getCurrent() );
     } else {
         return true;
@@ -72,6 +126,12 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke
     return true;
 }
 
+void UserModel::refreshUserList()
+{
+    beginResetModel();
+    endResetModel();
+}
+
 QString UserModel::getCurrent() const
 {
     return current;
@@ -80,13 +140,14 @@ QString UserModel::getCurrent() const
 void UserModel::setCurrent( const QString &value )
 {
     current = value;
-
+    mMutex.lock();
     userOfCurrentChannel.clear();
     beginResetModel();
     QList<QSharedPointer<RocketChatUser>> userList = userMap.values( value );
+    mMutex.unlock();
 
     for ( auto current : userList ) {
-        userOfCurrentChannel.insert( current->getUserName(), current );
+        userOfCurrentChannel.insert( current->getUserId(), current );
     }
 
     endResetModel();
@@ -97,11 +158,35 @@ void UserModel::onCurrentChannelChanged( const QString &newText )
     current = newText;
 }
 
+QSharedPointer<RocketChatUser> UserModel::getUserById( const QString &pId )
+{
+    QSharedPointer<RocketChatUser> user;
+    mMutex.lock();
+
+    if ( mAllUsers.contains( pId ) ) {
+        user = mAllUsers[pId];
+    }
+
+    mMutex.unlock();
+    return user;
+}
+
+void UserModel::addUser( QSharedPointer<RocketChatUser> pUser )
+{
+    if ( !pUser.isNull() ) {
+        mMutex.lock();
+        mAllUsers.insert( pUser->getUserId(), pUser );
+        mMutex.unlock();
+        connect( pUser.data(), &RocketChatUser::statusChanged, this, &UserModel::refreshUserList );
+    }
+}
+
 QHash<int, QByteArray> UserModel::roleNames() const
 {
     QHash<int, QByteArray> roles;
     roles[UserName] = QByteArrayLiteral( "username" );
     roles[UserId] =  QByteArrayLiteral( "userId" );
     roles[name] = QByteArrayLiteral( "name" );
+    roles[status] = QByteArrayLiteral( "status" );
     return roles;
 }
diff --git a/CustomModels/usermodel.h b/CustomModels/usermodel.h
index 0c0da919ad029d726bd09dc6ef0cc8f121cb8249..8bf6725282b314eff8f4ea5810e3530148008d86 100644
--- a/CustomModels/usermodel.h
+++ b/CustomModels/usermodel.h
@@ -29,6 +29,7 @@
 #include <QDebug>
 #include <QMap>
 #include <QList>
+#include <QMutex>
 
 #include "repos/entities/rocketchatuser.h"
 
@@ -41,25 +42,35 @@ class UserModel: public QAbstractListModel
         enum UserRoles {
             UserName = Qt::UserRole + 1,
             UserId,
-            name
+            name,
+            status
         };
     public slots:
         bool insertUser( const QString &, const QSharedPointer<RocketChatUser> & );
+        void refreshUserList();
+        void addUser( QSharedPointer<RocketChatUser> pUser );
 
     public:
-        UserModel( QObject *parent = 0 );
+        UserModel( QObject *parent = nullptr );
         int rowCount( const QModelIndex &parent = QModelIndex() ) const;
         QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
         QString getCurrent() const;
         void setCurrent( const QString &value );
         void onCurrentChannelChanged( const QString &newText );
 
+        QSharedPointer<RocketChatUser> getUserById( const QString &pId );
+
+
     protected:
         QHash<int, QByteArray> roleNames() const;
         QSet<QString> duplicateCheck;
         QMultiMap<QString, QSharedPointer<RocketChatUser>> userMap;
         QMap<QString, QSharedPointer<RocketChatUser>> userOfCurrentChannel;
+        QMap<QString, QSharedPointer<RocketChatUser>> mAllUsers;
         QString current;
+    private:
+        QMutex mMutex;
+
     signals:
         void currentChannelChanged( const QString &newText );
         void countChanged();
diff --git a/android/androidstatusbarcolor.cpp b/android/androidstatusbarcolor.cpp
index 8cba462b83e4b186fad31e0d5427a891fe5704c3..751f57e5cf979ae59490bb8498798cb6b47aabdd 100644
--- a/android/androidstatusbarcolor.cpp
+++ b/android/androidstatusbarcolor.cpp
@@ -29,10 +29,10 @@ AndroidStatusBarColor::AndroidStatusBarColor()
 void AndroidStatusBarColor::setStatusBarColor( QString pColor )
 {
     QAndroidJniObject jColor = QAndroidJniObject::fromString( pColor );
-    /* QAndroidJniObject::callStaticMethod<void>(
-                 "com/osalliance/rocketchatMobile/MainActivity",
-                 "setStatusBarColor",
-                 "(Ljava/lang/String;)V",
-                 jColor.object<jstring>());
-     */
+    QAndroidJniObject::callStaticMethod<void>(
+        "com/osalliance/rocketchatMobile/MainActivity",
+        "setStatusBarColor",
+        "(Ljava/lang/String;)V",
+        jColor.object<jstring>() );
+
 }
diff --git a/config.h b/config.h
index 849783df3df3ffabb87f337ec4e9ca2d10a15c5a..d29a64c906e6c27050caafda81ec3613e65c20be 100755
--- a/config.h
+++ b/config.h
@@ -1,7 +1,7 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
-#define DBVERSION 4
+#define DBVERSION 5
 
 
 #endif // CONFIG_H
diff --git a/ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp b/ddpRequests/rocketchatchangeuserpresencedefaultstatus.cpp
similarity index 80%
rename from ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp
rename to ddpRequests/rocketchatchangeuserpresencedefaultstatus.cpp
index 3757a5770beb426333fd2165b9b4cea8027c1310..bdea6037502bc3b104bb44d3df13d551b4d76b72 100644
--- a/ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp
+++ b/ddpRequests/rocketchatchangeuserpresencedefaultstatus.cpp
@@ -19,23 +19,27 @@
  ********************************************************************************************/
 
 
-#include "rocketchatchangeuserpresancedefaultstatus.h"
+#include "rocketchatchangeuserpresencedefaultstatus.h"
+#include "repos/entities/rocketchatuser.h"
 
-RocketChatChangeUserPresanceDefaultStatus::RocketChatChangeUserPresanceDefaultStatus( const status &pStatus )
+RocketChatChangeUserPresenceDefaultStatus::RocketChatChangeUserPresenceDefaultStatus( const RocketChatUser::status &pStatus )
 {
     QJsonArray params;
 
     QString statusText;
 
-    if ( pStatus == status::AWAY ) {
+    if ( pStatus == RocketChatUser::status::AWAY ) {
         statusText = QStringLiteral( "away" );
-    } else if ( pStatus == status::ONLINE ) {
+    } else if ( pStatus == RocketChatUser::status::ONLINE ) {
         statusText = QStringLiteral( "online" );
-    } else if ( pStatus == status::OFFLINE ) {
+    } else if ( pStatus == RocketChatUser::status::OFFLINE ) {
         statusText = QStringLiteral( "offline" );
+    } else if ( pStatus == RocketChatUser::status::BUSY ) {
+        statusText = QStringLiteral( "busy" );
     }
 
     params.append( statusText );
 
     buildRequest( QStringLiteral( "UserPresence:setDefaultStatus" ), params );
 }
+
diff --git a/ddpRequests/rocketchatchangeuserpresancedefaultstatus.h b/ddpRequests/rocketchatchangeuserpresencedefaultstatus.h
similarity index 88%
rename from ddpRequests/rocketchatchangeuserpresancedefaultstatus.h
rename to ddpRequests/rocketchatchangeuserpresencedefaultstatus.h
index a6d894be271afa8e31a1a4ea4785ad886d41d696..cef6bb35db768dce1797031875ddfc0b3948fed7 100644
--- a/ddpRequests/rocketchatchangeuserpresancedefaultstatus.h
+++ b/ddpRequests/rocketchatchangeuserpresencedefaultstatus.h
@@ -23,18 +23,14 @@
 #define ROCKETCHATCHANGEUSERPRESANCEDEFAULTSTATUS_H
 
 #include "ddpmethodrequest.h"
+#include "repos/entities/rocketchatuser.h"
 
-class RocketChatChangeUserPresanceDefaultStatus:  public DDPMethodRequest
+
+class RocketChatChangeUserPresenceDefaultStatus:  public DDPMethodRequest
 {
     public:
-        enum class status {
-            ONLINE = 1,
-            AWAY = 2,
-            BUSY = 3,
-            OFFLINE = 4
-        };
-
-        RocketChatChangeUserPresanceDefaultStatus( const status &pStatus );
+
+        RocketChatChangeUserPresenceDefaultStatus( const RocketChatUser::status &pStatus );
 
 };
 
diff --git a/ddpRequests/rocketchatchangeuserpresencestatus.cpp b/ddpRequests/rocketchatchangeuserpresencestatus.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0bc72603eb8366af830b6d275b7b2c384c5ba4df
--- /dev/null
+++ b/ddpRequests/rocketchatchangeuserpresencestatus.cpp
@@ -0,0 +1,44 @@
+/********************************************************************************************
+ *                                                                                          *
+ * Copyright (C) 2017 Armin Felder, Dennis Beier                                            *
+ * This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>.     *
+ *                                                                                          *
+ * RocketChatMobileEngine is free software: you can redistribute it and/or modify           *
+ * it under the terms of the GNU General Public License as published by                     *
+ * the Free Software Foundation, either version 3 of the License, or                        *
+ * (at your option) any later version.                                                      *
+ *                                                                                          *
+ * RocketChatMobileEngine is distributed in the hope that it will be useful,                *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of                           *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            *
+ * GNU General Public License for more details.                                             *
+ *                                                                                          *
+ * You should have received a copy of the GNU General Public License                        *
+ * along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>.           *
+ *                                                                                          *
+ ********************************************************************************************/
+
+
+#include "rocketchatchangeuserpresencestatus.h"
+#include "repos/entities/rocketchatuser.h"
+
+RocketChatChangeUserPresenceStatus::RocketChatChangeUserPresenceStatus( const RocketChatUser::status &pStatus )
+{
+    QJsonArray params;
+
+    QString statusText;
+
+    if ( pStatus == RocketChatUser::status::AWAY ) {
+        statusText = QStringLiteral( "away" );
+    } else if ( pStatus == RocketChatUser::status::ONLINE ) {
+        statusText = QStringLiteral( "online" );
+    } else if ( pStatus == RocketChatUser::status::OFFLINE ) {
+        statusText = QStringLiteral( "offline" );
+    } else if ( pStatus == RocketChatUser::status::BUSY ) {
+        statusText = QStringLiteral( "busy" );
+    }
+
+    params.append( QJsonValue::Null );
+
+    buildRequest( QStringLiteral( "UserPresence:" ) + statusText, params );
+}
diff --git a/ddpRequests/rocketchatchangeuserpresencestatus.h b/ddpRequests/rocketchatchangeuserpresencestatus.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6e356c5c674630035e37fbe5616182a0e209d30
--- /dev/null
+++ b/ddpRequests/rocketchatchangeuserpresencestatus.h
@@ -0,0 +1,37 @@
+/********************************************************************************************
+ *                                                                                          *
+ * Copyright (C) 2017 Armin Felder, Dennis Beier                                            *
+ * This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>.     *
+ *                                                                                          *
+ * RocketChatMobileEngine is free software: you can redistribute it and/or modify           *
+ * it under the terms of the GNU General Public License as published by                     *
+ * the Free Software Foundation, either version 3 of the License, or                        *
+ * (at your option) any later version.                                                      *
+ *                                                                                          *
+ * RocketChatMobileEngine is distributed in the hope that it will be useful,                *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of                           *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            *
+ * GNU General Public License for more details.                                             *
+ *                                                                                          *
+ * You should have received a copy of the GNU General Public License                        *
+ * along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>.           *
+ *                                                                                          *
+ ********************************************************************************************/
+
+
+#ifndef ROCKETCHATCHANGEUSERPRESANCESTATUS_H
+#define ROCKETCHATCHANGEUSERPRESANCESTATUS_H
+
+#include "ddpmethodrequest.h"
+#include "repos/entities/rocketchatuser.h"
+
+
+class RocketChatChangeUserPresenceStatus:  public DDPMethodRequest
+{
+    public:
+
+        RocketChatChangeUserPresenceStatus( const RocketChatUser::status &pStatus );
+
+};
+
+#endif // ROCKETCHATCHANGEUSERPRESANCEDEFAULTSTATUS_H
diff --git a/ddpRequests/rocketchatcreatechannelrequest.cpp b/ddpRequests/rocketchatcreatepublicgrouprequest.cpp
similarity index 81%
rename from ddpRequests/rocketchatcreatechannelrequest.cpp
rename to ddpRequests/rocketchatcreatepublicgrouprequest.cpp
index 36059d6f92893f33071899171a3c84290387e755..94e53d17e5442dc32bdf4daa6430703e53f551b4 100755
--- a/ddpRequests/rocketchatcreatechannelrequest.cpp
+++ b/ddpRequests/rocketchatcreatepublicgrouprequest.cpp
@@ -19,9 +19,9 @@
  ********************************************************************************************/
 
 
-#include "rocketchatcreatechannelrequest.h"
+#include "rocketchatcreatepublicgrouprequest.h"
 
-RocketChatCreateChannelRequest::RocketChatCreateChannelRequest( const QString &pChannelName, const QStringList &pUserName, bool pReadonly, const DdpCallback &pSuccess )
+RocketChatCreatePublicGroupRequest::RocketChatCreatePublicGroupRequest( const QString &pChannelName, const QStringList &pUserName, bool pReadonly, const DdpCallback &pSuccess )
 {
     QJsonArray users = QJsonArray::fromStringList( pUserName );
     QJsonArray params = {pChannelName, users, pReadonly};
@@ -29,7 +29,7 @@ RocketChatCreateChannelRequest::RocketChatCreateChannelRequest( const QString &p
     setSuccess( pSuccess );
 }
 
-RocketChatCreateChannelRequest::RocketChatCreateChannelRequest( const QString &pChannelName, const QStringList &pUserNames, const DdpCallback &pSuccess ): RocketChatCreateChannelRequest( pChannelName, pUserNames, false, pSuccess )
+RocketChatCreatePublicGroupRequest::RocketChatCreatePublicGroupRequest( const QString &pChannelName, const QStringList &pUserNames, const DdpCallback &pSuccess ): RocketChatCreatePublicGroupRequest( pChannelName, pUserNames, false, pSuccess )
 {
 
 }
diff --git a/ddpRequests/rocketchatcreatechannelrequest.h b/ddpRequests/rocketchatcreatepublicgrouprequest.h
similarity index 84%
rename from ddpRequests/rocketchatcreatechannelrequest.h
rename to ddpRequests/rocketchatcreatepublicgrouprequest.h
index 58c00467a24b9b24f2543d1e10a073cf5ef6a443..e806911a97a2ca9d2519e0ffe3a60c2f7cc222ac 100755
--- a/ddpRequests/rocketchatcreatechannelrequest.h
+++ b/ddpRequests/rocketchatcreatepublicgrouprequest.h
@@ -24,11 +24,11 @@
 
 #include "ddpmethodrequest.h"
 
-class RocketChatCreateChannelRequest : public DDPMethodRequest
+class RocketChatCreatePublicGroupRequest : public DDPMethodRequest
 {
     public:
-        RocketChatCreateChannelRequest( const QString &pChannelName, const QStringList &pUserNames, bool pReadonly, const DdpCallback &pSuccess = nullptr );
-        RocketChatCreateChannelRequest( const QString &pChannelName, const QStringList &pUserNames, const DdpCallback &pSuccess = nullptr );
+        RocketChatCreatePublicGroupRequest( const QString &pChannelName, const QStringList &pUserNames, bool pReadonly, const DdpCallback &pSuccess = nullptr );
+        RocketChatCreatePublicGroupRequest( const QString &pChannelName, const QStringList &pUserNames, const DdpCallback &pSuccess = nullptr );
 };
 
 #endif // ROCKETCHATCREATECHANNELREQUEST_H
diff --git a/ddpRequests/rocketchatsubscribeuserdata.cpp b/ddpRequests/rocketchatsubscribeuserdata.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..043dc385eba366731e013e4f57bf1e3a15d21518
--- /dev/null
+++ b/ddpRequests/rocketchatsubscribeuserdata.cpp
@@ -0,0 +1,9 @@
+#include "rocketchatsubscribeuserdata.h"
+
+#include <QJsonArray>
+
+RocketChatSubscribeUserData::RocketChatSubscribeUserData()
+{
+    QJsonArray params = {QJsonValue::Null};
+    buildRequest( QStringLiteral( "userData" ), params );
+}
diff --git a/ddpRequests/rocketchatsubscribeuserdata.h b/ddpRequests/rocketchatsubscribeuserdata.h
new file mode 100644
index 0000000000000000000000000000000000000000..100fcc122825ad0bc017fa22f4217e866996a47e
--- /dev/null
+++ b/ddpRequests/rocketchatsubscribeuserdata.h
@@ -0,0 +1,12 @@
+#ifndef ROCKETCHATSUBSCRIBEUSERDATA_H
+#define ROCKETCHATSUBSCRIBEUSERDATA_H
+
+#include "ddpsubscriptionrequest.h"
+
+class RocketChatSubscribeUserData: public DDPSubscriptionRequest
+{
+    public:
+        RocketChatSubscribeUserData();
+};
+
+#endif // ROCKETCHATSUBSCRIBEUSERDATA_H
diff --git a/engine.pro b/engine.pro
index c2192bd2ae1d0e2db74291b0bd44f20787590046..2e07cbb46290f968b69c39d962d6f857aa8f6bfa 100644
--- a/engine.pro
+++ b/engine.pro
@@ -18,7 +18,6 @@ SOURCES +=  api/meteorddp.cpp \
     ddpRequests/rocketchatnotifynoticesrequest.cpp \
     ddpRequests/rocketchatsubscriptionchangedrequest.cpp \
     ddpRequests/rocketchatmarkchannelasreadrequest.cpp \
-    ddpRequests/rocketchatcreatechannelrequest.cpp \
     ddpRequests/ddpunsubscriptionrequest.cpp \
     ddpRequests/rocketchatcreateprivategrouprequest.cpp \
     ddpRequests/rocketchatadduserstochannel.cpp \
@@ -78,7 +77,7 @@ SOURCES +=  api/meteorddp.cpp \
     container/sortedvector.cpp \
     container/observablelist.cpp \
     container/modelobserver.cpp \
-    ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp \
+    ddpRequests/rocketchatchangeuserpresencedefaultstatus.cpp \
     CustomModels/messagemodel.cpp \
     CustomModels/loginmethodsmodel.cpp \
     CustomModels/models.cpp \
@@ -100,7 +99,10 @@ SOURCES +=  api/meteorddp.cpp \
     ddpRequests/rocketchatjoinroomrequest.cpp \
     ddpRequests/rocketchatgetroomidbynameorid.cpp \
     ddpRequests/rocketchatspotlightrequest.cpp \
-    repos/entities/rocketchatreplymessage.cpp
+    repos/entities/rocketchatreplymessage.cpp \
+    ddpRequests/rocketchatcreatepublicgrouprequest.cpp \
+    ddpRequests/rocketchatchangeuserpresencestatus.cpp \
+    ddpRequests/rocketchatsubscribeuserdata.cpp
 
 
 HEADERS += \
@@ -118,7 +120,6 @@ HEADERS += \
     ddpRequests/rocketchatnotifynoticesrequest.h \
     ddpRequests/rocketchatsubscriptionchangedrequest.h \
     ddpRequests/rocketchatmarkchannelasreadrequest.h \
-    ddpRequests/rocketchatcreatechannelrequest.h \
     ddpRequests/ddpunsubscriptionrequest.h \
     ddpRequests/rocketchatcreateprivategrouprequest.h \
     ddpRequests/rocketchatadduserstochannel.h \
@@ -180,7 +181,6 @@ HEADERS += \
     container/sortedvector.h \
     container/observablelist.h \
     container/modelobserver.h \
-    ddpRequests/rocketchatchangeuserpresancedefaultstatus.h \
     config.h \
     CustomModels/messagemodel.h \
     CustomModels/loginmethodsmodel.h \
@@ -204,7 +204,11 @@ HEADERS += \
     ddpRequests/rocketchatgetroomidbynameorid.h \
     ddpRequests/rocketchatspotlightrequest.h \
     api/messagelistener.h \
-    repos/entities/rocketchatreplymessage.h
+    repos/entities/rocketchatreplymessage.h \
+    ddpRequests/rocketchatcreatepublicgrouprequest.h \
+    ddpRequests/rocketchatchangeuserpresencestatus.h \
+    ddpRequests/rocketchatchangeuserpresencedefaultstatus.h \
+    ddpRequests/rocketchatsubscribeuserdata.h
 
 linux{
 
@@ -283,6 +287,7 @@ RESOURCES += \
 
 DISTFILES += \
     sql/migrations/3.sql \
-    sql/migrations/4.sql
+    sql/migrations/4.sql \
+    sql/migrations/5.sql
 
 
diff --git a/persistancelayer.cpp b/persistancelayer.cpp
index bec51d305f2d543866710c33fbd152e1a6bfb1ba..c110672d258cc2c323f05b277d1deddc41cd79fd 100755
--- a/persistancelayer.cpp
+++ b/persistancelayer.cpp
@@ -98,7 +98,8 @@ void PersistanceLayer::initShema()
                                    "archived bool,"
                                    "joined bool, "
                                    "blocked bool DEFAULT 0, "
-                                   "username varchar(100) DEFAULT \"\")" ) );
+                                   "username varchar(100) DEFAULT \"\", "
+                                   "chat_partner_id varchar(100) DEFAULT \"\")" ) );
 
     if ( !query.exec() ) {
         qWarning() << query.lastError();
@@ -302,6 +303,9 @@ void PersistanceLayer::upgradeSchema()
             } else if ( dbVersion < 4 ) {
                 currentTarget = 4;
                 sqlFile.setFileName( QStringLiteral( ":/sql/migrations/4.sql" ) );
+            } else if ( dbVersion < 5 ) {
+                currentTarget = 5;
+                sqlFile.setFileName( QStringLiteral( ":/sql/migrations/5.sql" ) );
             }
 
             if ( !sqlFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
@@ -762,12 +766,12 @@ void PersistanceLayer::setSetting( const QString &pProperty, const QString &pVal
 
 }
 
-void PersistanceLayer::addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, bool pReadOnly, const QString &pMuted, bool pArchived, bool pBlocked, const QString &pUsername )
+void PersistanceLayer::addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, bool pReadOnly, const QString &pMuted, bool pArchived, bool pBlocked, const QString &pUsername, const QString &pMchatPartnerId )
 {
     transaction();
     QSqlQuery setChannel;
     setChannel.prepare( QStringLiteral( "REPLACE INTO rooms "
-                                        "(id,name,type,joined,read_only,muted,archived,blocked,username) VALUES(:id,:name,:type,:joined,:read_only,:muted,:archived,:blocked,:username)" ) );
+                                        "(id,name,type,joined,read_only,muted,archived,blocked,username) VALUES(:id,:name,:type,:joined,:read_only,:muted,:archived,:blocked,:username,:chat_partner_id)" ) );
     setChannel.bindValue( QStringLiteral( ":id" ), pId );
     setChannel.bindValue( QStringLiteral( ":name" ), pName );
     setChannel.bindValue( QStringLiteral( ":joined" ), pJoined );
@@ -777,6 +781,8 @@ void PersistanceLayer::addChannel( const QString &pId, const QString &pName, con
     setChannel.bindValue( QStringLiteral( ":archived" ), pArchived );
     setChannel.bindValue( QStringLiteral( ":blocked" ), pBlocked );
     setChannel.bindValue( QStringLiteral( ":username" ), pUsername );
+    setChannel.bindValue( QStringLiteral( ":chat_partner_id" ), pUsername );
+
 
     if ( !setChannel.exec() ) {
         qWarning() << setChannel.lastError();
@@ -785,13 +791,13 @@ void PersistanceLayer::addChannel( const QString &pId, const QString &pName, con
     commit();
 }
 
-void PersistanceLayer::addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, const QString &pUsername )
+void PersistanceLayer::addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, const QString &pUsername, const QString &pMchatPartnerId )
 {
     bool readOnly = false;
     QString muted = "";
     bool archived = false;
     bool blocked = false;
-    addChannel( pId, pName, pType, pJoined, readOnly, muted, archived, blocked, pUsername );
+    addChannel( pId, pName, pType, pJoined, readOnly, muted, archived, blocked, pUsername, pMchatPartnerId );
 }
 
 void PersistanceLayer::deleteChannel( const QString &pId )
@@ -1210,6 +1216,8 @@ QList<QVariantHash> PersistanceLayer::getChannels( void )
         int archivedCol = rec.indexOf( QStringLiteral( "archived" ) );
         int blocked = rec.indexOf( QStringLiteral( "blocked" ) );
         int usernameCol = rec.indexOf( QStringLiteral( "username" ) );
+        int chatPartnerIdCol = rec.indexOf( QStringLiteral( "chat_partner_id" ) );
+
 
         while ( rooms.next() ) {
             QVariantHash roomsHash;
@@ -1224,6 +1232,8 @@ QList<QVariantHash> PersistanceLayer::getChannels( void )
             roomsHash[QStringLiteral( "archived" )] = rooms.value( archivedCol ).toBool();
             roomsHash[QStringLiteral( "blocked" )] = rooms.value( blocked ).toBool();
             roomsHash[QStringLiteral( "username" )] = rooms.value( usernameCol ).toString();
+            roomsHash[QStringLiteral( "chatPartnerId" )] = rooms.value( chatPartnerIdCol ).toString();
+
             roomsList.append( roomsHash );
         }
     }
diff --git a/persistancelayer.h b/persistancelayer.h
index c9dc4df78b4657595d9331d911a704a5ad18ca85..ce4a8c5fa573b3563bfa021cca12340037aa9ed7 100755
--- a/persistancelayer.h
+++ b/persistancelayer.h
@@ -39,8 +39,8 @@ class PersistanceLayer : public QObject
         void setUserName( const QString & );
         void setPassword( const QString & );
         void setToken( const QString &, uint );
-        void addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, bool pReadOnly, const QString &pMuted, bool pArchived, bool pBlocked, const QString &pUsername );
-        void addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, const QString &pUsername );
+        void addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, bool pReadOnly, const QString &pMuted, bool pArchived, bool pBlocked, const QString &pUsername, const QString &pMchatPartnerId );
+        void addChannel( const QString &pId, const QString &pName, const QString &pType, bool pJoined, const QString &pUsername, const QString &pMchatPartnerId );
         void deleteChannel( const QString &pId );
         void addMessage( const QString &pId, const QString &pRid, const QString &pAuthor, qint64 pTs, const QString &pJson, const QString &pUserId );
         void addFileCacheEntry( const QString &pUrl, const QString &pPath );
diff --git a/repos/entities/rocketchatchannel.cpp b/repos/entities/rocketchatchannel.cpp
index f0fd26fc701ee73a04d4f8f117772ace50c2fefe..876b0220570d6723929e4c3f84406f98f8fd3edc 100755
--- a/repos/entities/rocketchatchannel.cpp
+++ b/repos/entities/rocketchatchannel.cpp
@@ -90,10 +90,10 @@ void RocketChatChannel::setName( const QString &value )
 
 bool RocketChatChannel::addUser( QSharedPointer<RocketChatUser> user )
 {
-    QString username = user->getUserName();
+    QString userId = user->getUserId();
 
-    if ( mUsers.empty() || !mUsers.contains( username ) ) {
-        mUsers[username] = user;
+    if ( mUsers.empty() || !mUsers.contains( userId ) ) {
+        mUsers[userId] = user;
         return true;
     }
 
@@ -277,6 +277,29 @@ void RocketChatChannel::setUsername( const QString &username )
 {
     mUsername = username;
 }
+
+QSharedPointer<RocketChatUser> RocketChatChannel::getChatPartner() const
+{
+    return mChatPartner;
+}
+
+void RocketChatChannel::setChatPartner( const QSharedPointer<RocketChatUser> &chatPartner )
+{
+    mChatPartner = chatPartner;
+    connect( chatPartner.data(), &RocketChatUser::statusChanged, this, [ = ]() {
+        emit dataChanged( mRoomId, "userStatus" );
+    } );
+}
+
+QString RocketChatChannel::getChatPartnerId() const
+{
+    return mChatPartnerId;
+}
+
+void RocketChatChannel::setChatPartnerId( const QString &chatPartnerId )
+{
+    mChatPartnerId = chatPartnerId;
+}
 bool RocketChatChannel::getBlocked() const
 {
     return mBlocked;
diff --git a/repos/entities/rocketchatchannel.h b/repos/entities/rocketchatchannel.h
index e006388eef7ecb64606f628d0a6aa979e56d7561..e91ce9800e5489912cc90149c0d7f4a92c6ec7b9 100755
--- a/repos/entities/rocketchatchannel.h
+++ b/repos/entities/rocketchatchannel.h
@@ -118,7 +118,13 @@ class RocketChatChannel : public QObject
         QString getUsername() const;
         void setUsername( const QString &username );
 
-    protected:
+        QSharedPointer<RocketChatUser> getChatPartner() const;
+        void setChatPartner( const QSharedPointer<RocketChatUser> &chatPartner );
+
+        QString getChatPartnerId() const;
+        void setChatPartnerId( const QString &chatPartnerId );
+
+    private:
         QString mOwnerName;
         QString mOwnerId;
         bool mDeleted;
@@ -129,8 +135,10 @@ class RocketChatChannel : public QObject
         QString mRoomId;
         QString mName;
         QString mUsername;
+        QString mChatPartnerId;
         MessageRepository mMessages;
         QMap<QString, QSharedPointer<RocketChatUser>> mUsers;
+        QSharedPointer<RocketChatUser> mChatPartner;
         bool mJoined = false;
         QString mType;
         unsigned int mUnreadMessages = 0;
@@ -141,6 +149,7 @@ class RocketChatChannel : public QObject
         void unreadMessagesChanged( QString id, int number );
         void channelDeleted( const QString &pId, bool deleted );
         void dataChanged( QString id, QString property );
+        void chatPartnerStatusChanged();
 
 };
 
diff --git a/repos/entities/rocketchatuser.cpp b/repos/entities/rocketchatuser.cpp
index b94bb87736684c2b875db5b98fb67d6447d41350..a4fc04b174de91d62e3337ae6753308ae16424fc 100755
--- a/repos/entities/rocketchatuser.cpp
+++ b/repos/entities/rocketchatuser.cpp
@@ -22,7 +22,7 @@
 
 #include "rocketchatuser.h"
 
-RocketChatUser::RocketChatUser( QString pUsername ): mUserName( pUsername )
+RocketChatUser::RocketChatUser( const QString &pId ): mUserId( pId )
 {
 
 }
@@ -74,10 +74,32 @@ RocketChatUser::status RocketChatUser::getStatus() const
 
 void RocketChatUser::setStatus( status pStatus )
 {
-    mStatus = pStatus;
+    if ( pStatus != mStatus ) {
+        mStatus = pStatus;
+        emit statusChanged();
+    }
 }
 
-bool RocketChatUser::operator==(const RocketChatUser lhs)
+void RocketChatUser::setStatus( const QString &pStatus )
+{
+    if ( !pStatus.isEmpty() ) {
+        status newStatus;
+
+        if ( pStatus == "online" ) {
+            newStatus = status::ONLINE;
+        } else if ( pStatus == "away" ) {
+            newStatus = status::AWAY;
+        } else if ( pStatus == "offline" ) {
+            newStatus = status::OFFLINE;
+        } else if ( pStatus == "busy" ) {
+            newStatus = status::BUSY;
+        }
+
+        setStatus( newStatus );
+    }
+}
+
+bool RocketChatUser::operator==( const RocketChatUser lhs )
 {
     return lhs.getUserId() == this->getUserId();
 }
@@ -87,7 +109,7 @@ QString RocketChatUser::getName() const
     return mName;
 }
 
-void RocketChatUser::setName(const QString &name)
+void RocketChatUser::setName( const QString &name )
 {
     mName = name;
 }
diff --git a/repos/entities/rocketchatuser.h b/repos/entities/rocketchatuser.h
index b3e549573c7eb0fb6d11e2dc03eb3453a2f35c2d..6f6c04b6732b8dacaa32bb8dbd09f0d23dc2e5c6 100755
--- a/repos/entities/rocketchatuser.h
+++ b/repos/entities/rocketchatuser.h
@@ -31,12 +31,13 @@ class RocketChatUser : public QObject
 
     public:
 
-        enum class status {
-            ONLINE,
-            AWAY,
-            OFFLINE
+        enum class status : int {
+            ONLINE = 0,
+            AWAY = 1,
+            OFFLINE = 2,
+            BUSY = 3
         };
-        explicit RocketChatUser( QString pUsername )                                            ;
+        explicit RocketChatUser( const QString &pId )                                            ;
 
         QString getUserName() const;
         void setUserName( const QString &pValue );
@@ -52,6 +53,8 @@ class RocketChatUser : public QObject
 
         status getStatus() const;
         void setStatus( status );
+        void setStatus( const QString &pStatus );
+        
 
         inline bool operator==( const RocketChatUser lhs );
 
@@ -66,7 +69,7 @@ class RocketChatUser : public QObject
         QString mName;
         status mStatus = status::OFFLINE;
     signals:
-
+        void statusChanged();
     public slots:
 };
 
diff --git a/rocketchat.cpp b/rocketchat.cpp
index 73175528760b3d8ccd653cd8fedf9e9fa2d22319..cba3c55f47ad4665f2955f7e9d6bfa52db37f70d 100755
--- a/rocketchat.cpp
+++ b/rocketchat.cpp
@@ -41,8 +41,6 @@
 
 /**
  * @brief RocketChat::RocketChat
- * @param restApi
- * @param ddp
  */
 RocketChat::RocketChat( QGuiApplication *app )
 {
@@ -62,7 +60,6 @@ RocketChat::RocketChat( QGuiApplication *app )
     qRegisterMetaType<ConnectionState>( "ConnectionState" );
     qRegisterMetaType<Qt::ApplicationState>( "Qt::ApplicationState" );
 
-
 }
 
 RocketChat::~RocketChat()
@@ -106,8 +103,6 @@ void RocketChat::login( const QString &pServerId, const QString &pUsername, cons
         mStorage->wipeDb();
     }
 
-    qDebug() << "login thread id: " << QThread::currentThreadId();
-
     if ( mServerStatus ) {
         QMetaObject::invokeMethod( mServerMap.first(),  "login", Q_ARG( QString, pUsername ), Q_ARG( QString, pPassword ) );
     }
@@ -266,6 +261,11 @@ void RocketChat::searchRoomByType( const QString &pTerm, const QString &pType )
     QMetaObject::invokeMethod( mServerMap.first(), "searchRoom", Q_ARG( QString, pTerm ), Q_ARG( QString, pType ) );
 }
 
+void RocketChat::setUserDefaultStatus( int pStatus )
+{
+    QMetaObject::invokeMethod( mServerMap.first(), "setUserPresenceDefaultStatus", Q_ARG( int, pStatus ) );
+}
+
 bool RocketChat::newServerByDomain( const QString &domain, bool pUnsecure = false )
 {
     newServerMutex.lock();
@@ -316,17 +316,6 @@ bool RocketChat::newServerByDomain( const QString &domain, bool pUnsecure = fals
     return 0;
 }
 
-//TODO: make asynchonous
-void RocketChat::getUserOfChannel( const QString &pServerId, const QString &pChannelId )
-{
-    Q_UNUSED( pServerId );
-
-    if ( mServerStatus ) {
-        QMetaObject::invokeMethod( mServerMap.first(), "requestUsersOfChannel", Q_ARG( QString, pChannelId ) );
-    }
-}
-
-
 void RocketChat::openPrivateChannelWith( const QString &pServerId, const QString &pUsername )
 {
     Q_UNUSED( pServerId );
@@ -614,12 +603,12 @@ void RocketChat::logout( const QString &pServerId )
     }
 }
 
-void RocketChat::createChannel( const QString &pServerId, const QString &pChannelName, const QStringList &pUsersNames, bool pReadonly )
+void RocketChat::createPublicGroup( const QString &pServerId, const QString &pChannelName, const QStringList &pUsersNames, bool pReadonly )
 {
     Q_UNUSED( pServerId );
 
     if ( mServerStatus ) {
-        QMetaObject::invokeMethod( mServerMap.first(), "createChannel", Q_ARG( QString, pChannelName ), Q_ARG( QStringList, pUsersNames ), Q_ARG( bool, pReadonly ) );
+        QMetaObject::invokeMethod( mServerMap.first(), "createPublicGroup", Q_ARG( QString, pChannelName ), Q_ARG( QStringList, pUsersNames ), Q_ARG( bool, pReadonly ) );
     }
 }
 
@@ -762,7 +751,6 @@ void RocketChat::serverReadySlot()
 
     connect( pServer, &RocketChatServerData::openUrl, this, &RocketChat::openUrl, Qt::UniqueConnection );
 
-    connect( pServer, &RocketChatServerData::usersReady, this, &RocketChat::channelUsersReady, Qt::UniqueConnection );
     connect( pServer, &RocketChatServerData::channelDetailsReady, this, &RocketChat::channelDetailsReady, Qt::UniqueConnection );
     connect( pServer, &RocketChatServerData::unreadCountChanged, this, &RocketChat::onUnreadCountChanged, Qt::UniqueConnection );
 
@@ -774,8 +762,9 @@ void RocketChat::serverReadySlot()
     connect( pServer, &RocketChatServerData::loggingIn, this, &RocketChat::loggingIn, Qt::UniqueConnection );
     connect( pServer, &RocketChatServerData::historyReady, this, &RocketChat::historyReady, Qt::UniqueConnection );
 
-    QMetaObject::invokeMethod( pServer, "init" );
+    connect( pServer, &RocketChatServerData::userStatusChanged, this, &RocketChat::userStatusChanged, Qt::UniqueConnection );
 
+    QMetaObject::invokeMethod( pServer, "init" );
 }
 
 void RocketChat::storageReadySlot()
@@ -846,6 +835,7 @@ void RocketChat::onServerSlotsReady()
 #ifdef Q_OS_ANDROID
     connect( &mNotificationsObject, &Notifications::tokenReceived, firstServer, &RocketChatServerData::sendPushToken, Qt::UniqueConnection );
     connect( &mNotificationsObject, &Notifications::messageReceived, firstServer, &RocketChatServerData::switchChannel, Qt::UniqueConnection );
+
 #endif
 #ifdef Q_OS_IOS
     connect( this, &RocketChat::pushTokenReceived, firstServer, &RocketChatServerData::sendPushToken, Qt::UniqueConnection );
diff --git a/rocketchat.h b/rocketchat.h
index 54c3136e3fc755b08e9ca6c1137e173ff9afcf6d..802d3a742afe962b3429bf5882bae18376ead4e2 100755
--- a/rocketchat.h
+++ b/rocketchat.h
@@ -22,7 +22,7 @@
 #include "ddpRequests/ddpmethodrequest.h"
 #include "ddpRequests/ddpsubscriptionrequest.h"
 #include "ddpRequests/rocketchatsubscribechannelrequest.h"
-#include "ddpRequests/rocketchatcreatechannelrequest.h"
+#include "ddpRequests/rocketchatcreatepublicgrouprequest.h"
 
 #include "CustomModels/loginmethodsmodel.h"
 
@@ -68,15 +68,14 @@ class RocketChat : public QObject
                                 const QString &pPassword );
         Q_INVOKABLE void loginWithSamlToken( const QString &pToken );
         Q_INVOKABLE void loginWithMethod( const QString &method, const QString &payload );
-        Q_INVOKABLE void getUserOfChannel( const QString &pServerId, const QString &pId );
         Q_INVOKABLE void openPrivateChannelWith( const QString &pServerId, const QString &pUsername );
         Q_INVOKABLE void sendMessage( const QString &pServerId, const QString &pChannelId,
                                       const QString &pMessage );
         Q_INVOKABLE void openFileDialog( const QString &pChannelId );
         Q_INVOKABLE void resetCurrentChannel( void );
         Q_INVOKABLE void logout( const QString &pServer );
-        Q_INVOKABLE void createChannel( const QString &pServerId, const QString &pChannelName,
-                                        const QStringList &pUsersNames, bool pReadonly = false );
+        Q_INVOKABLE void createPublicGroup( const QString &pServerId, const QString &pChannelName,
+                                            const QStringList &pUsersNames, bool pReadonly = false );
         Q_INVOKABLE void createPrivateGroup( const QString &pServerId, const QString &pChannelName,
                                              const QStringList &pUsersNames, bool pReadonly = false );
         Q_INVOKABLE void addUsersToChannel( const QString &pServerId, const QString &pChannelName,
@@ -148,6 +147,7 @@ class RocketChat : public QObject
 
         Q_INVOKABLE void searchRoomByType( const QString &pTerm, const QString &pType );
 
+        Q_INVOKABLE void setUserDefaultStatus( int pStatus );
 
         void registerServer( RocketChatServerData *pServer );
 
@@ -256,7 +256,6 @@ class RocketChat : public QObject
         void emojisReady( QVariantList emojis );
         void allChannelsReceived( QVariantList channels );
         //TODO: use QVariant...
-        void channelUsersReady( QString users, QString channel );
         void channelDetailsReady( QVariantMap details, QString channelId );
         void noJitsiMeetAvailable();
         void offlineMode( void );
@@ -264,6 +263,7 @@ class RocketChat : public QObject
         void pushMessageReceived( QString pServer, QString pRid, QString pName, QString pType );
         void loggingIn();
         void historyReady();
+        void userStatusChanged( int status );
 
 
         // iOS helper
diff --git a/rocketchatserver.cpp b/rocketchatserver.cpp
index e02cace088f6696acd948ed316b05e5595f2fb07..01face4701a79e6df3a339ce0d109c0ae9b6e3ab 100755
--- a/rocketchatserver.cpp
+++ b/rocketchatserver.cpp
@@ -84,7 +84,7 @@ void RocketChatServerData::init()
 
     QMetaObject::invokeMethod( mRestApi, "init" );
 
-    mDdpApi->registerMessageHandler(this);
+    mDdpApi->registerMessageHandler( this );
     connect( mDdpApi, &MeteorDDP::ddpConnected, this, &RocketChatServerData::onDDPConnected, Qt::UniqueConnection );
     connect( mDdpApi, &MeteorDDP::ddpDisconnected, this, &RocketChatServerData::onDDPDisonnected, Qt::UniqueConnection );
 
@@ -305,12 +305,21 @@ void RocketChatServerData::requestIsLoggedIn()
     }
 }
 
+void RocketChatServerData::setUserPresenceDefaultStatus( int pStatus )
+{
+    if ( pStatus >= 0 && pStatus < 5 && isWebsocketValid() && diffToLastDDPPing() < 29 ) {
+
+        QSharedPointer<DDPMethodRequest> request( new RocketChatChangeUserPresenceDefaultStatus( static_cast<RocketChatUser::status>( pStatus ) ) );
+        sendDdprequest( request, true );
+    }
+}
+
 void RocketChatServerData::setUserPresenceStatus( int pStatus )
 {
-    if ( pStatus > 0 && pStatus < 5 && isWebsocketValid() && diffToLastDDPPing() < 29 ) {
+    if ( pStatus >= 0 && pStatus < 5 && isWebsocketValid() && diffToLastDDPPing() < 29 ) {
 
-        QSharedPointer<DDPMethodRequest> request( new RocketChatChangeUserPresanceDefaultStatus( static_cast<RocketChatChangeUserPresanceDefaultStatus::status>( pStatus ) ) );
-        mDdpApi->sendRequest( request );
+        QSharedPointer<DDPMethodRequest> request( new RocketChatChangeUserPresenceStatus( static_cast<RocketChatUser::status>( pStatus ) ) );
+        sendDdprequest( request, true );
     }
 }
 
@@ -322,7 +331,7 @@ void RocketChatServerData::onStateChanged( const Qt::ApplicationState &pState )
         qDebug() << "call resume";
         resume();
     } else {
-        setUserPresenceStatus( 1 );
+        setUserPresenceStatus( static_cast<int>( RocketChatUser::status::ONLINE ) );
     }
 }
 
@@ -331,7 +340,7 @@ void RocketChatServerData::createVideoCall( const QString &pRid )
     if ( !pRid.isEmpty() ) {
 
         QSharedPointer<DDPMethodRequest> request( new RocketChatUpdateJitsiTimeout( pRid ) );
-        mDdpApi->sendRequest( request );
+        sendDdprequest( request );
         joinJitsiCall( pRid );
     }
 }
@@ -397,13 +406,13 @@ void RocketChatServerData::blockUser( const QString &pChannelId )
 
         QSharedPointer<RocketChatBlockUserRequest> blockRequest1( new RocketChatBlockUserRequest( possibleRoom1, userId ) );
         QSharedPointer<RocketChatBlockUserRequest> blockRequest2( new RocketChatBlockUserRequest( possibleRoom2, userId ) );
-        mDdpApi->sendRequest( blockRequest1 );
-        mDdpApi->sendRequest( blockRequest2 );
+        sendDdprequest( blockRequest1 );
+        sendDdprequest( blockRequest2 );
 
 
     } else {
         QSharedPointer<RocketChatBlockUserRequest> blockRequest( new RocketChatBlockUserRequest( pChannelId, userId ) );
-        mDdpApi->sendRequest( blockRequest );
+        sendDdprequest( blockRequest );
     }
 }
 
@@ -417,11 +426,11 @@ void RocketChatServerData::unBlockUser( const QString &pChannelId )
         QString possibleRoom2 = mUserId + userId;
         QSharedPointer<RocketChatUnblockUserRequest> unBlockRequest1( new RocketChatUnblockUserRequest( possibleRoom1, userId ) );
         QSharedPointer<RocketChatUnblockUserRequest> unBlockRequest2( new RocketChatUnblockUserRequest( possibleRoom2, userId ) );
-        mDdpApi->sendRequest( unBlockRequest1 );
-        mDdpApi->sendRequest( unBlockRequest2 );
+        sendDdprequest( unBlockRequest1 );
+        sendDdprequest( unBlockRequest2 );
     } else {
         QSharedPointer<RocketChatUnblockUserRequest> unBlockRequest( new RocketChatUnblockUserRequest( pChannelId, userId ) );
-        mDdpApi->sendRequest( unBlockRequest );
+        sendDdprequest( unBlockRequest );
     }
 }
 
@@ -432,7 +441,20 @@ QString RocketChatServerData::getUserId() const
 
 void RocketChatServerData::setUserId( const QString &userId )
 {
+    auto users = Models::getUsersModel();
+    auto user = users->getUserById( userId );
+
+    if ( user.isNull() ) {
+        user = QSharedPointer<RocketChatUser>( new RocketChatUser( userId ) );
+        QMetaObject::invokeMethod( userModel, "addUser", Q_ARG( User, user ) );
+    }
+
+    mOwnUser = user;
     mUserId = userId;
+
+    connect( user.data(), &RocketChatUser::statusChanged, this, [ = ]() {
+        emit userStatusChanged( static_cast<int>( user->getStatus() ) );
+    } );
 }
 
 void RocketChatServerData::checkForMissedMessages()
@@ -522,10 +544,10 @@ void RocketChatServerData::onUnreadCountChanged()
     emit unreadCountChanged( QStringLiteral( "default" ), number );
 }
 
-bool RocketChatServerData::handlesMessage(QJsonObject message)
+bool RocketChatServerData::handlesMessage( QJsonObject message )
 {
     qDebug() << "RocketChatServerData message handler";
-    onDDPMessageReceived(message);
+    onDDPMessageReceived( message );
     return true;
 }
 
@@ -559,11 +581,13 @@ void RocketChatServerData::offlineLogin()
 
 QString RocketChatServerData::getBaseUrl() const
 {
-    QString protocol ="https://";
-    if(mDdpApi->getUnsecure()){
-        protocol ="http://";
+    QString protocol = "https://";
+
+    if ( mDdpApi->getUnsecure() ) {
+        protocol = "http://";
     }
-    return protocol+mBaseUrl;
+
+    return protocol + mBaseUrl;
 }
 
 QVariantList RocketChatServerData::getEmojisByCategory() const
@@ -624,6 +648,7 @@ void RocketChatServerData::loginWithHash( const QString &pUsername, const QStrin
                 double expireDouble = expireObject[QStringLiteral( "$date" )].toDouble();
                 self->mTokenExpire = static_cast<uint>( expireDouble / 1000 );
                 QString userId = result[QStringLiteral( "id" )].toString();
+                self->setUserId( userId );
                 self->mStorage->transaction();
                 self->mStorage->setUserData( pUsername, pPswHash );
                 self->mStorage->setToken( self->mResumeToken, self->mTokenExpire );
@@ -686,6 +711,7 @@ void RocketChatServerData::loginWithToken( const QString &pUsername, const QStri
                     self->mTokenExpire = static_cast<uint>( expireDouble / 1000 );
 
                     QString userId = result[QStringLiteral( "id" )].toString();
+                    self->setUserId( userId );
                     self->mStorage->setToken( self->mResumeToken, self->mTokenExpire );
                     self->mStorage->setUserId( userId );
                     self->mRestApi->setToken( self->mResumeToken );
@@ -765,6 +791,7 @@ void RocketChatServerData::loginWtihSamlToken( const QString &pToken )
                     mTokenExpire = static_cast<uint>( expireDouble / 1000 );
                     
                     QString userId = result[QStringLiteral( "id" )].toString();
+                    setUserId( userId );
                     mStorage->setToken( mResumeToken, mTokenExpire );
                     mStorage->setUserId( userId );
                     mRestApi->setToken( mResumeToken );
@@ -837,6 +864,7 @@ void RocketChatServerData::loginWithOpenIDToken( const QString &pToken, const QS
 
                     QString userId = result[QStringLiteral( "id" )].toString();
 
+                    self->setUserId( userId );
                     self->mRestApi->setToken( mResumeToken );
                     self->mRestApi->setUserId( userId );
                     self->mUserId = result[QStringLiteral( "id" )].toString();
@@ -930,7 +958,7 @@ void RocketChatServerData::onDDPAuthenticated()
 {
     //TODO: dirty fix!
     getCustomEmojis();
-    setUserPresenceStatus( 1 );
+    setUserPresenceStatus( static_cast<int>( RocketChatUser::status::ONLINE ) );
     mStorage->setSetting( QStringLiteral( "currentServer" ), mBaseUrl );
     getServerInfo();
 
@@ -1063,7 +1091,7 @@ void RocketChatServerData::sendPushToken( const QString &pToken )
     if ( !mUserId.isEmpty() && !pToken.isEmpty() ) {
         qDebug() << "send push token " + pToken;
         QSharedPointer<DDPRequest> sendToken = QSharedPointer<DDPRequest>( new RocketChatUpdatePushTokenRequest( pToken, mUserId ) );
-        mDdpApi->sendRequest( sendToken );
+        sendDdprequest( sendToken );
 
     }
 }
@@ -1085,22 +1113,6 @@ void RocketChatServerData::requestAllChannels()
     emit allChannelsReady( channelsMap );
 }
 
-void RocketChatServerData::requestUsersOfChannel( const QString &pChannelId )
-{
-    auto users = getUserOfChannel( pChannelId );
-    QJsonArray array;
-
-    for ( const auto &current : users ) {
-        if ( !current.isNull() ) {
-            array.append( current->getUserName() );
-        }
-    }
-
-    //TODO: use QVariant...
-    QJsonDocument doc( array );
-    emit usersReady( doc.toJson(), pChannelId );
-}
-
 void RocketChatServerData::sendUnsentMessages()
 {
     qDebug() << "send unsend ddp messages";
@@ -1194,35 +1206,58 @@ void RocketChatServerData::onDDPMessageReceived( const QJsonObject &pMessage )
         } else if ( pMessage[QStringLiteral( "collection" )] == QStringLiteral( "users" ) ) {
             QString userId = pMessage[QStringLiteral( "id" )].toString();
 
-            if ( mUsers.contains( userId ) ) {
-                QString msg = pMessage[QStringLiteral( "msg" )].toString();
+            QString msg = pMessage[QStringLiteral( "msg" )].toString();
+            QJsonObject fields = pMessage["fields"].toObject();
 
-                if ( msg == QStringLiteral( "added" ) ) {
-                    mUsers.get( userId )->setStatus( RocketChatUser::status::ONLINE );
-                } else if ( msg == QStringLiteral( "changed" ) ) {
-                    QJsonObject fields = pMessage["fields"].toObject();
+            auto user = userModel->getUserById( userId );
+
+            if ( !user.isNull() ) {
+                if ( msg == QStringLiteral( "added" ) || msg == QStringLiteral( "changed" ) ) {
 
-                    if ( fields.contains( QStringLiteral( "status" ) ) ) {
+                    if ( fields.contains( QStringLiteral( "statusDefault" ) ) && userId == mUserId ) {
+                        QString msgStatus = fields[QStringLiteral( "statusDefault" )].toString();
+                        user->setStatus( msgStatus );
+                    } else if ( fields.contains( QStringLiteral( "status" ) ) ) {
                         QString msgStatus = fields[QStringLiteral( "status" )].toString();
-                        RocketChatUser::status userStatus;
-
-                        if ( msgStatus == QStringLiteral( "online" ) ) {
-                            userStatus = RocketChatUser::status::ONLINE;
-                        } else if ( msgStatus == QStringLiteral( "away" ) ) {
-                            userStatus = RocketChatUser::status::AWAY;
-                        } else {
-                            userStatus = RocketChatUser::status::OFFLINE;
-                        }
+                        user->setStatus( msgStatus );
+                    }
 
-                        mUsers.get( userId )->setStatus( userStatus );
+                    if ( fields.contains( QStringLiteral( "name" ) ) ) {
+                        user->setUserName( fields[QStringLiteral( "name" )].toString() );
                     }
 
+
                 } else if ( msg == QStringLiteral( "removed" ) ) {
-                    mUsers.get( userId )->setStatus( RocketChatUser::status::OFFLINE );
+                    //TODO: delete user
+                    user->setStatus( RocketChatUser::status::OFFLINE );
                 }
             } else {
+                auto newUser = QSharedPointer<RocketChatUser>( new RocketChatUser( userId ) );
+
+                if ( pMessage.contains( "fields" ) ) {
+                    QJsonObject fields = pMessage["fields"].toObject();
 
+                    if ( fields.contains( QStringLiteral( "statusDefault" ) ) && userId == mUserId ) {
+                        QString msgStatus = fields[QStringLiteral( "statusDefault" )].toString();
+                        newUser->setStatus( msgStatus );
+                    } else if ( fields.contains( QStringLiteral( "status" ) ) && userId != mUserId ) {
+                        QString msgStatus = fields[QStringLiteral( "status" )].toString();
+                        newUser->setStatus( msgStatus );
+                    }
+
+                    if ( fields.contains( QStringLiteral( "name" ) ) ) {
+                        newUser->setName( fields[QStringLiteral( "name" )].toString() );
+                    }
+
+                    if ( fields.contains( QStringLiteral( "username" ) ) ) {
+                        newUser->setUserName( fields[QStringLiteral( "username" )].toString() );
+                    }
+                }
+
+                QMetaObject::invokeMethod( userModel, "addUser", Q_ARG( User, newUser ) );
             }
+
+
         } else if ( pMessage[QStringLiteral( "collection" )] == QStringLiteral( "autocompleteRecords" ) ) {
             if ( Q_LIKELY( pMessage.contains( QStringLiteral( "fields" ) ) && pMessage.contains( QStringLiteral( "msg" ) ) && pMessage.contains( QStringLiteral( "id" ) ) ) ) {
                 QJsonObject fields = pMessage[QStringLiteral( "fields" )].toObject();
@@ -1531,7 +1566,7 @@ void RocketChatServerData::markChannelAsRead( const QString &pChannelId )
 {
     if ( Q_LIKELY( mChannels->contains( pChannelId ) ) ) {
         QSharedPointer<DDPRequest> markAsRead( new RocketChatMarkChannelAsReadRequest( pChannelId ) );
-        mDdpApi->sendRequest( markAsRead );
+        sendDdprequest( markAsRead );
     }
 }
 void RocketChatServerData::joinChannel( const QString &pChannelId, bool pForce )
@@ -1711,11 +1746,13 @@ void RocketChatServerData::getCustomEmojis()
         QSharedPointer<RocketChatNotifyNoticesRequest> notifyNoticeSubSubscription( new RocketChatNotifyNoticesRequest( this->mUserId ) );
         QSharedPointer<RocketChatSubScriptionChangedRequest> noitfySubscriptionsSubscription( new RocketChatSubScriptionChangedRequest( this->mUserId ) );
         QSharedPointer<RocketChatSubscribeActiveUsers> activeUsersSubscription( new RocketChatSubscribeActiveUsers() );
-        mDdpApi->sendRequest( notifySubSubscription );
-        mDdpApi->sendRequest( notifyNoticeSubSubscription );
-        mDdpApi->sendRequest( noitfySubscriptionsSubscription );
-        mDdpApi->sendRequest( activeUsersSubscription );
-        mDdpApi->sendRequest( notifyRoomsChanged );
+        QSharedPointer<RocketChatSubscribeUserData> userData( new RocketChatSubscribeUserData() );
+        sendDdprequest( notifySubSubscription, true );
+        sendDdprequest( notifyNoticeSubSubscription, true );
+        sendDdprequest( noitfySubscriptionsSubscription, true );
+        sendDdprequest( activeUsersSubscription, true );
+        sendDdprequest( notifyRoomsChanged, true );
+        sendDdprequest( userData, true );
 
         onLoggedIn();
         sendUnsentMessages();
@@ -1824,7 +1861,7 @@ void RocketChatServerData::getUserSuggestions( const QString &pTerm, const QStri
                     emit suggestionsReady( mAutocompleteRecords );
                     mAutocompleteRecords.clear();
                     QSharedPointer<DDPUnsubscriptionRequest> unSubSuggestions( new DDPUnsubscriptionRequest( subSuggestions->getFrame() ) );
-                    mDdpApi->sendRequest( unSubSuggestions );
+                    sendDdprequest( unSubSuggestions );
                     pDdp->unsetResponseBinding( subSuggestions->getFrame() );
 
                 }
@@ -1832,7 +1869,7 @@ void RocketChatServerData::getUserSuggestions( const QString &pTerm, const QStri
         }
     };
     subSuggestions->setSuccess( success );
-    mDdpApi->sendRequest( subSuggestions );
+    sendDdprequest( subSuggestions );
 }
 
 void RocketChatServerData::getRoomInformation( const QString &pRoomName )
@@ -1842,7 +1879,7 @@ void RocketChatServerData::getRoomInformation( const QString &pRoomName )
 
     QSharedPointer<RocketChatSubscribeChannelRequest> roomSubscription( new RocketChatSubscribeChannelRequest( pRoomName ) );
 
-    mDdpApi->sendRequest( roomSubscription );
+    sendDdprequest( roomSubscription );
 }
 
 void RocketChatServerData::getLoginMethods()
@@ -1854,6 +1891,7 @@ void RocketChatServerData::getLoginMethods()
     };
     QSharedPointer<RocketChatSubscribeLoginMethods> loginMethodsSubscription( new RocketChatSubscribeLoginMethods() );
     loginMethodsSubscription->setSuccess( success );
+    // sendDdprequest( loginMethodsSubscription );
     mDdpApi->sendRequest( loginMethodsSubscription );
 }
 
@@ -1906,19 +1944,6 @@ void RocketChatServerData::searchRoom( const QString &pTerm, const QString &pTyp
     mChannelService->searchRoom( pTerm, pType );
 }
 
-QList<QSharedPointer<RocketChatUser> > RocketChatServerData::getUserOfChannel( const QString &pChannelId )
-{
-    QList<QSharedPointer<RocketChatUser>> users;
-    users.reserve( 100 );
-
-    if ( mChannels->contains( pChannelId ) && !mChannels->get( pChannelId ).isNull() ) {
-        QSharedPointer<RocketChatChannel> channel = mChannels->get( pChannelId );
-        users =  channel->getUsers().values();
-    }
-
-    return users;
-}
-
 RestApi *RocketChatServerData::getRestApi() const
 {
     return mRestApi;
@@ -1952,25 +1977,35 @@ void RocketChatServerData::logout()
     emit loggedOut( this->mServerId );
 }
 
-void RocketChatServerData::createChannel( const QString &pChannelName, const QStringList &pUsers, bool pReadonly )
+void RocketChatServerData::createPublicGroup( const QString &pChannelName, const QStringList &pUsers, bool pReadonly )
 {
     DdpCallback success = [ = ]( QJsonObject pResponse, MeteorDDP * pDdpApi ) {
         Q_UNUSED( pResponse );
         Q_UNUSED( pDdpApi );
         qDebug() << "created channel";
+
+        if ( pResponse.contains( "result" ) ) {
+            QJsonObject result = pResponse["result"].toObject();
+
+            if ( result.contains( "rid" ) && result.contains( "name" ) ) {
+                QString rid = result["rid"].toString();
+                QString name = result["name"].toString();
+                switchChannel( "default", rid, name, "c" );
+            }
+        }
     };
-    QSharedPointer<RocketChatCreateChannelRequest> request( new RocketChatCreateChannelRequest( pChannelName, pUsers, pReadonly ) );
-    mDdpApi->sendRequest( request );
+    QSharedPointer<RocketChatCreatePublicGroupRequest> request( new RocketChatCreatePublicGroupRequest( pChannelName, pUsers, pReadonly ) );
+    sendDdprequest( request );
 }
 
 void RocketChatServerData::createPrivateGroup( const QString &pChannelName, const QStringList &pUsers, bool pReadonly )
 {
-    DdpCallback success = [ = ]( QJsonObject response, MeteorDDP * ddpApi ) {
+    DdpCallback success = [ = ]( QJsonObject pResponse, MeteorDDP * ddpApi ) {
         Q_UNUSED( ddpApi );
         qDebug() << "created group";
 
-        if ( response.contains( "result" ) ) {
-            QJsonObject result = response["result"].toObject();
+        if ( pResponse.contains( "result" ) ) {
+            QJsonObject result = pResponse["result"].toObject();
 
             if ( result.contains( "rid" ) && result.contains( "name" ) ) {
                 QString rid = result["rid"].toString();
@@ -1981,7 +2016,7 @@ void RocketChatServerData::createPrivateGroup( const QString &pChannelName, cons
     };
     QSharedPointer<RocketChatCreatePrivateGroupRequest> request( new RocketChatCreatePrivateGroupRequest( pChannelName, pUsers, pReadonly ) );
     request->setSuccess( success );
-    mDdpApi->sendRequest( request );
+    sendDdprequest( request );
 }
 
 void RocketChatServerData::addUsersToChannel( const QString &pChannelId, const QStringList &pUsers )
@@ -1997,7 +2032,7 @@ void RocketChatServerData::addUsersToChannel( const QString &pChannelId, const Q
             QStringList usernames( user );
             QSharedPointer<RocketChatAddUsersToChannel > request( new RocketChatAddUsersToChannel( pChannelId, usernames ) );
             request->setSuccess( success );
-            mDdpApi->sendRequest( request );
+            sendDdprequest( request );
         }
     }
 }
diff --git a/rocketchatserver.h b/rocketchatserver.h
index a7bd8fd03ab0cd12bf9be7709c7678964e7301db..2398074f459a2c21e98a79e4b778e2c6c68470d3 100755
--- a/rocketchatserver.h
+++ b/rocketchatserver.h
@@ -49,7 +49,7 @@
 #include "ddpRequests/rocketchatnotifynoticesrequest.h"
 #include "ddpRequests/rocketchatsubscriptionchangedrequest.h"
 #include "ddpRequests/rocketchatmarkchannelasreadrequest.h"
-#include "ddpRequests/rocketchatcreatechannelrequest.h"
+#include "ddpRequests/rocketchatcreatepublicgrouprequest.h"
 #include "ddpRequests/ddpunsubscriptionrequest.h"
 #include "ddpRequests/rocketchatcreateprivategrouprequest.h"
 #include "ddpRequests/rocketchatadduserstochannel.h"
@@ -57,7 +57,9 @@
 #include "ddpRequests/rocketchatupdatepushtokenrequest.h"
 #include "ddpRequests/ddplogoutrequest.h"
 #include "ddpRequests/rocketchatsubscribeactiveusers.h"
-#include "ddpRequests/rocketchatchangeuserpresancedefaultstatus.h"
+#include "ddpRequests/rocketchatsubscribeuserdata.h"
+#include "ddpRequests/rocketchatchangeuserpresencedefaultstatus.h"
+#include "ddpRequests/rocketchatchangeuserpresencestatus.h"
 #include "ddpRequests/rocketchatupdatejitsitimeout.h"
 #include "ddpRequests/rocketchatsubscribeloginmethods.h"
 #include "ddpRequests/ddpopenidloginrequest.h"
@@ -124,7 +126,7 @@ class RocketChatServerData : public MessageListener
 
         void init();
 
-        void createChannel( const QString &pChannelName, const QStringList &pUsers, bool pReadonly );
+        void createPublicGroup( const QString &pChannelName, const QStringList &pUsers, bool pReadonly );
         void createPrivateGroup( const QString &pChannelName, const QStringList &pUsers, bool pReadonly );
         void addUsersToChannel( const QString &pChannelId, const QStringList &pUsers );
         void sendMessage( const QString &pMessage, const QString &pChannelId );
@@ -178,8 +180,6 @@ class RocketChatServerData : public MessageListener
 
         void requestAllChannels();
 
-        void requestUsersOfChannel( const QString &pChannelId );
-
         void switchChannel( const QString &pServer, const QString &pRid, const QString &pName, const QString &pType );
 
         void switchChannelByName( const QString &pRid, const QString &pType );
@@ -188,6 +188,8 @@ class RocketChatServerData : public MessageListener
 
         void requestIsLoggedIn();
 
+        void setUserPresenceDefaultStatus( int pStatus );
+
         void setUserPresenceStatus( int pStatus );
 
         void onStateChanged( const Qt::ApplicationState &pState );
@@ -218,7 +220,6 @@ class RocketChatServerData : public MessageListener
         bool isConnected() const;
         bool isWebsocketValid( void ) const;
         void getCustomEmojis();
-        QList<QSharedPointer<RocketChatUser>> getUserOfChannel( const QString &pChannelId );
         RestApi *getRestApi() const;
         ChannelRepository *getChannels() const;
         RocketChatChannelService *mChannelService;
@@ -260,6 +261,7 @@ class RocketChatServerData : public MessageListener
         uint mTokenExpire = 0;
         QString mResumeToken;
         bool mUnsecureConnection = false;
+        QSharedPointer<RocketChatUser> mOwnUser;
 
         MeteorDDP *mDdpApi = nullptr;
         RestApi *mRestApi = nullptr;
@@ -349,10 +351,11 @@ class RocketChatServerData : public MessageListener
         void offlineMode( void );
         void loggingIn();
         void historyReady();
+        void userStatusChanged( int status );
 
         // MessageListener interface
-public:
-        bool handlesMessage(QJsonObject object);
+    public:
+        bool handlesMessage( QJsonObject object );
         QString getBaseUrl() const;
 };
 
diff --git a/rocketchatserver.h.orig b/rocketchatserver.h.orig
deleted file mode 100755
index 4f7ed3c6041839e7bf49355d8a505c5761cbed65..0000000000000000000000000000000000000000
--- a/rocketchatserver.h.orig
+++ /dev/null
@@ -1,344 +0,0 @@
-/********************************************************************************************
- *                                                                                          *
- * Copyright (C) 2017 Armin Felder, Dennis Beier                                            *
- * This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>.     *
- *                                                                                          *
- * RocketChatMobileEngine is free software: you can redistribute it and/or modify           *
- * it under the terms of the GNU General Public License as published by                     *
- * the Free Software Foundation, either version 3 of the License, or                        *
- * (at your option) any later version.                                                      *
- *                                                                                          *
- * RocketChatMobileEngine is distributed in the hope that it will be useful,                *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of                           *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            *
- * GNU General Public License for more details.                                             *
- *                                                                                          *
- * You should have received a copy of the GNU General Public License                        *
- * along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>.           *
- *                                                                                          *
- ********************************************************************************************/
-
-
-
-#ifndef ROCKETCHATSERVER_H
-#define ROCKETCHATSERVER_H
-
-#include <QObject>
-#include <QVariantList>
-#include <algorithm>    // std::transform
-#include <QVariant>
-#include <QList>
-#include <QString>
-#include <QMimeType>
-#include <QCryptographicHash>
-#include <QJsonArray>
-
-#include "utils.h"
-#include "persistancelayer.h"
-#include "api/meteorddp.h"
-#include "api/restapi.h"
-#include "repos/userrepository.h"
-#include "repos/channelrepository.h"
-#include "repos/loginmethodsrepository.h"
-#include "repos/entities/loginmethod.h"
-#include "ddpRequests/pingrequest.h"
-#include "ddpRequests/ddploginrequest.h"
-#include "ddpRequests/rocketchatsubscribechannelrequest.h"
-#include "ddpRequests/ddpufscreaterequest.h"
-#include "ddpRequests/rocketchatsubscribeusernotify.h"
-#include "ddpRequests/rocketchatnotifynoticesrequest.h"
-#include "ddpRequests/rocketchatsubscriptionchangedrequest.h"
-#include "ddpRequests/rocketchatmarkchannelasreadrequest.h"
-#include "ddpRequests/rocketchatcreatechannelrequest.h"
-#include "ddpRequests/ddpunsubscriptionrequest.h"
-#include "ddpRequests/rocketchatcreateprivategrouprequest.h"
-#include "ddpRequests/rocketchatadduserstochannel.h"
-#include "ddpRequests/rocketchatsubscriberoomrequest.h"
-#include "ddpRequests/rocketchatupdatepushtokenrequest.h"
-#include "ddpRequests/ddplogoutrequest.h"
-#include "ddpRequests/rocketchatsubscribeactiveusers.h"
-#include "ddpRequests/rocketchatchangeuserpresancedefaultstatus.h"
-#include "ddpRequests/rocketchatupdatejitsitimeout.h"
-#include "ddpRequests/rocketchatsubscribeloginmethods.h"
-#include "ddpRequests/ddpopenidloginrequest.h"
-#include "ddpRequests/rocketchatspotlightrequest.h"
-#include "ddpRequests/ddpsamlloginrequest.h"
-#include "ddpRequests/rocketchatblockuserrequest.h"
-#include "ddpRequests/rocketchatunblockuserrequest.h"
-#include "restRequests/restrequest.h"
-#include "restRequests/restlogoutrequest.h"
-#include "restRequests/getserverinforequest.h"
-#include "fileuploader.h"
-#include "notifications/notifications.h"
-#include "services/rocketchatchannelservice.h"
-#include "services/messageservice.h"
-#include "services/requests/loadhistoryservicerequest.h"
-#include "services/fileservice.h"
-#include "repos/emojirepo.h"
-#include "rocketchatserverconfig.h"
-#include "repos/channelrepository.h"
-#include "services/emojiservice.h"
-#include "restRequests/getrequest.h"
-#include "segfaulthandler.h"
-#include "CustomModels/usermodel.h"
-#include "CustomModels/loginmethodsmodel.h"
-#include "restRequests/restmerequest.h"
-#include "ddpRequests/rocketchatcreateaccount.h"
-
-class RocketChatChannelService;
-class ChannelRepository;
-class FileUploader;
-class PersistanceLayer;
-typedef QSharedPointer<RestRequest> RestApiRequest;
-class MessageService;
-class EmojiService;
-class DdpLogoutRequest;
-class FileService;
-class EmojiRepo;
-class ChannelModel;
-class MessagesModel;
-
-enum class ConnectionState {
-    OFFLINE,
-    CONNECTED,
-    ONLINE
-};
-
-class RocketChatServerData : public QObject
-{
-
-        Q_OBJECT
-    public:
-        RocketChatServerData( const QString &pId,  QString pBaseUrl,
-                              QString pApiUri,
-                              UserModel &pUserModel,
-                              ChannelModel &channelModel,
-                              ChannelModel &groupsModel,
-                              ChannelModel &directModel,
-                              MessagesModel &messagesModel,
-                              LoginMethodsModel &loginMethodsModel );
-
-        ~RocketChatServerData();
-        void setServerId( const QString &pValue );
-
-        void setServerAddress( const QString &pServerAddress );
-
-    public slots:
-
-        void init();
-
-        void createChannel( const QString &pChannelName, const QStringList &pUsers, bool pReadonly );
-        void createPrivateGroup( const QString &pChannelName, const QStringList &pUsers, bool pReadonly );
-        void addUsersToChannel( const QString &pChannelName, const QStringList &pUsers );
-        void sendMessage( const QString &pChannelId, const QString &pMessage );
-
-        void uploadFile( const QString &pChannelId, const QString &pFile );
-        void cancelUpload( const QString &pFileId );
-
-        void login( const QString &pUsername, const QString &pPassword );
-        void loginWithHash( const QString &pUsername, const QString &pHash );
-        void loginWithToken( const QString &pUsername, const QString &pToken, bool pResume = false );
-        void loginWithOpenIDToken( const QString &pToken, const QString &pSecret );
-        void loginWithMethod( const QString &method, const QString &payload );
-        void loginWtihSamlToken( const QString &pToken );
-
-        void joinChannel( const QString &pChannelId );
-        void connectWithServer();
-        void loadRecentHistory( const QString &pChannelId );
-
-        void getFileRessource( const QString &pUrl );
-        void getFileRessource( const QString &pUrl, const QString &pType );
-
-
-        void getUserSuggestions( const QString &pTerm, const QString &pExceptions );
-        void getRoomInformation( const QString &pRoomName );
-        void getLoginMethods();
-
-        void getServerInfo();
-
-<<<<<<< HEAD
-        void leaveChannel( const QString &pId );
-
-=======
->>>>>>> master
-        void logout( void );
-
-        void setConnectionState( const ConnectionState &pValue );
-
-        void resume( void );
-
-        void joinJitsiCall( const QString &pRoomId );
-
-        void setUnreadMessages( const QString &pChannelId, int count );
-
-        void openPrivateChannelWith( const QString &pUsername );
-
-        void setCurrentChannel( const QString &value );
-
-        void markChannelAsRead( const QString &pChannelId );
-
-        void sendPushToken( const QString &pToken );
-
-        void requestAllChannels();
-
-        void requestUsersOfChannel( const QString &pChannelId );
-
-        void switchChannel( const QString &pServer, const QString &pRid, const QString &pName, const QString &pType );
-
-        void switchChannelByRid( const QString &pRid );
-
-        void requestGetChannelDetails( const QString &pChannelId );
-
-        void requestIsLoggedIn();
-
-        void setUserPresenceStatus( int pStatus );
-
-        void onStateChanged( const Qt::ApplicationState &pState );
-
-        void createVideoCall( const QString &pRid );
-
-        void disconnectFromServer();
-
-        void searchForRoomIdByName( const QString &pName );
-
-        void blockUser( const QString &pChannelId );
-
-        void unBlockUser( const QString &pChannelId );
-
-
-    public:
-        QString getServerId() const;
-        bool isConnected() const;
-        bool isWebsocketValid( void ) const;
-        void getCustomEmojis();
-        QList<QSharedPointer<RocketChatUser>> getUserOfChannel( const QString &pChannelId );
-        RestApi *getRestApi() const;
-        ChannelRepository *getChannels() const;
-        RocketChatChannelService *mChannelService;
-        void handleChannelMessage( const QJsonObject &pMessage );
-        uint diffToLastDDPPing();
-        QVariantList getEmojisByCategory() const;
-        QString parseMessageReceived( const QString &pMessage );
-        void sendUnsentMessages( void );
-        void sendApiRequest( const RestApiRequest &pRequest, bool pRetry = true );
-        void sendDdprequest( const QSharedPointer<DDPRequest> &pRequest, bool pRetry = true, bool pSendWhenConnected = false );
-        QJsonObject getMessageData( const QString &pChannelId, const QString &pMesssageId );
-        QJsonObject formatMessageTime( const QJsonObject &pJsonObject );
-        bool initialised = 0;
-        ConnectionState getConnectionState() const;
-
-        QString getCurrentChannel() const;
-
-        QString getUsername() const;
-        void setUsername( const QString &pUsername );
-
-        QString getUserId() const;
-        void setUserId( const QString &userId );
-
-        qint16 getCustomEmojisHash() const;
-        void setCustomEmojisHash( const qint16 &customEmojisHash );
-
-        EmojiRepo *getEmojiRepo() const;
-        void setEmojiRepo( EmojiRepo *emojiRepo );
-        void createAccount( const QString &username, const QString &email, const QString &password );
-
-        void offlineLogin();
-
-    protected:
-
-        RocketChatServerData();
-        ConnectionState mConnectionState = ConnectionState::OFFLINE;
-        QString mUsername = "";
-        QString mUserId = "";
-        QString mBaseUrl = "";
-        QString mApiUri = "";
-        QString mServerId = "";
-        uint mTokenExpire = 0;
-        QString mResumeToken;
-
-        MeteorDDP *mDdpApi = nullptr;
-        RestApi *mRestApi = nullptr;
-        UserRepository mUsers;
-        LoginMethodsRepository mLoginMethodRepo;
-        ChannelRepository *mChannels = nullptr;
-        EmojiRepo *mEmojiRepo = nullptr;
-        QVariantMap mAutocompleteRecords;
-        RocketChatServerConfig config;
-        bool mConnected = false;
-        bool mLoggedIn = false;
-        bool mResumeOperation = false;
-        MessageService *mMessageService = nullptr;
-        PersistanceLayer *mStorage = nullptr;
-        EmojiService *mEmojiService = nullptr;
-        FileService *mFileService = nullptr;
-        QHash<QString, bool> mDownloadsInProgress;
-        QLinkedList<QSharedPointer<DDPRequest>> mUnsendDdpRequests;
-        QLinkedList<RestApiRequest> mUnsendRestRequests;
-        QMap<QString, FileUploader *> mFileUploads;
-        QString mCurrentChannel;
-        QMutex mUnsentMutex;
-        UserModel &userModel;
-        ChannelModel &channelsModel;
-        ChannelModel &groupsModel;
-        ChannelModel &directModel;
-        MessagesModel &mMessagesModel;
-        LoginMethodsModel &loginMethodsModel;
-        std::function<void ( QMultiMap<QString, QSharedPointer<RocketChatMessage>> *messages )> historyLoaded;
-        QString mPendingSwitchRoomRequest;
-
-        void getServerSettings( void );
-        void onDDPConnected();
-        void onDDPAuthenticated();
-        void onDDPMessageReceived( const QJsonObject &pMessage );
-        void onChannelsLoaded( const QVector<QSharedPointer<RocketChatChannel> > &pChannels );
-        void onFileDownloaded( const QString &pUrl, const QString &pTempfile );
-        void onLoggedIn();
-        bool isStreamRoomMessage( const QJsonObject &pMessage ) const;
-        bool isUserJoinMessage( const QJsonObject &pMessage ) const;
-        void handleStreamRoomMessage( const QJsonObject &pMessage );
-        void handleUserJoinMessage( const QJsonObject &pMessage );
-        void onMessageReceived( const QString &pServerId, const QString &pChannelId, const QString &pMessage );
-        void onLoginError();
-        void onResume();
-        void setRestApi( RestApi * );
-
-        bool customEmojisDirtyFlag = false;
-
-        void loadEmojis();
-        void loadHistories( void );
-        void checkForMissedMessages( void );
-        void onUsersLoaded( const QString &pChannelId, const QVector<QSharedPointer<RocketChatUser>> &pUserList );
-
-        void onUnreadCountChanged();
-
-        qint16 mCustomEmojisHash = 0;
-
-    signals:
-        void ddpConnected( const QString &pServerId );
-        void loggedIn( const QString &pServer );
-        void onHashLoggedIn( const QString &pServer );
-        void privateChannelCreated( const QString &pServerId, const QString &pRid, const QString &pUsername );
-        void loginError( void );
-        void userJoined( const QString &pChannelId, const QString &pUsername );
-        void loggedOut( const QString &pServerId );
-        void suggestionsReady( QVariantMap );
-        void fileUploadFinished( const QString &pData );
-        void fileuploadStarted( const QString &pData );
-        void fileUploadProgressChanged( const QString &pData );
-        void error( const QString &pError );
-        void fileRessourceProcessed( const QString &pUrl, const QString &pPath, bool pShowInline );
-        void customEmojisReceived( QVariantList pEmojis );
-        void channelSwitchRequest( const QString &pServer, const QString &pRid, const QString &pName, const QString &pType, bool readonlyFlag );
-        void openUrl( const QString &url );
-        void readyToCheckForPendingNotification();
-        void registerForPush();
-        void allChannelsReady( const QVariantList &channels );
-        void usersReady( const QString &users, const QString &channel );
-        void channelDetailsReady( QVariantMap details, const QString &channelId );
-        void unreadCountChanged( const QString &pServerId, uint pUnread );
-        void newLoginMethod( const QMap<QString, QVariant> &entry );
-        void resetLoginMethods();
-
-};
-
-#endif // ROCKETCHATSERVER_H
diff --git a/services/rocketchatchannelservice.cpp b/services/rocketchatchannelservice.cpp
index 202a60ad32344d7dce30a3466470a8e2d6b7e4fc..59824c17f900a9cc6dfe0b835bb96d567625cee9 100755
--- a/services/rocketchatchannelservice.cpp
+++ b/services/rocketchatchannelservice.cpp
@@ -22,6 +22,8 @@
 
 #include "rocketchatchannelservice.h"
 
+#include <CustomModels/models.h>
+
 
 
 RocketChatChannelService::RocketChatChannelService( RocketChatServerData *pServer, MessageService *pMessageService )
@@ -74,7 +76,7 @@ QVector<QSharedPointer<RocketChatChannel> > RocketChatChannelService::processCha
     QString openChannel = std::get<0>( openChannelTupel );
     mStorage->transaction();
 
-    for ( const auto &currentChannel : pChannelArray ) {
+    for ( const auto currentChannel : pChannelArray ) {
         QJsonObject currentChannelObject = currentChannel.toObject();
 
         if ( Q_LIKELY( ( currentChannelObject.contains( "rid" ) &&
@@ -85,14 +87,19 @@ QVector<QSharedPointer<RocketChatChannel> > RocketChatChannelService::processCha
             QString name = currentChannelObject["name"].toString();
             QString type = currentChannelObject["t"].toString();
             QString username = "";
+            QString chatPartnerId ;
+
+            if ( id == "" ) {
+                id = currentChannelObject["_id"].toString();
+            }
 
             if ( type == "d" ) {
                 username = name;
                 name = currentChannelObject["fname"].toString();
-            }
 
-            if ( id == "" ) {
-                id = currentChannelObject["_id"].toString();
+                QString ownUser = mServer->getUserId();
+                chatPartnerId = id;
+                chatPartnerId.replace( ownUser, "" );
             }
 
             //TODO: refactor me please!
@@ -118,6 +125,8 @@ QVector<QSharedPointer<RocketChatChannel> > RocketChatChannelService::processCha
 
 
                 if ( type == "d" ) {
+                    channel->setChatPartnerId( chatPartnerId );
+
                     /* QString name = currentChannelObject["name"].toString();
                      QString fname = currentChannelObject["fname"].toString();
 
@@ -172,13 +181,12 @@ QVector<QSharedPointer<RocketChatChannel> > RocketChatChannelService::processCha
                 if ( id == openChannel ) {
                     channel->setUnreadMessages( 0 );
                 } else if ( currentChannelObject.contains( "unread" ) ) {
-                    channel->setUnreadMessages( currentChannelObject["unread"].toInt() );
+                    channel->setUnreadMessages( static_cast<unsigned int>( currentChannelObject["unread"].toInt() ) );
                 }
 
                 channel->setJoined( pJoined );
                 loadUsersOfChannel( channel );
 
-
                 if ( channel->getArchived() ) {
                     subscribeChannel( channel );
                 }
@@ -252,6 +260,8 @@ void RocketChatChannelService::loadJoinedChannelsFromDb()
     if ( Q_LIKELY( !roomsList.isEmpty() ) ) {
         QVector<QSharedPointer<RocketChatChannel>> channels;
 
+        auto users = Models::getUsersModel();
+
         for ( const auto &roomHash : roomsList ) {
             QSharedPointer<RocketChatChannel> channelPointer =  createChannelObject( roomHash["id"].toString(), roomHash["name"].toString(), roomHash["type"].toString(), roomHash["username"].toString() );
 
@@ -260,6 +270,18 @@ void RocketChatChannelService::loadJoinedChannelsFromDb()
                 channelPointer->setArchived( roomHash["archived"].toBool() );
                 channelPointer->setReadOnly( roomHash["readOnly"].toBool() );
                 channelPointer->setJoined( roomHash["joined"].toBool() );
+                channelPointer->setChatPartnerId( roomHash["chatPartnerId"].toString() );
+
+                if ( channelPointer->getType() == "d" ) {
+                    auto user = users->getUserById( channelPointer->getChatPartnerId() );
+
+                    if ( !user.isNull() ) {
+                        channelPointer->setChatPartner( user );
+                    } else {
+                        auto newUser = QSharedPointer<RocketChatUser>( new RocketChatUser( channelPointer->getChatPartnerId() ) );
+                        channelPointer->setChatPartner( newUser );
+                    }
+                }
 
                 if ( roomHash.contains( "blocked" ) ) {
                     channelPointer->setBlocked( roomHash["blocked"].toBool() );
@@ -275,16 +297,17 @@ void RocketChatChannelService::loadJoinedChannelsFromDb()
 
 void RocketChatChannelService::persistChannel( QSharedPointer<RocketChatChannel> pChannel )
 {
-    QString id = pChannel->getRoomId();
-    QString name  = pChannel->getName();
-    QString type = pChannel->getType();
-    QString muted = pChannel->getMuted().join( "," );
-    QString username = pChannel->getUsername();
-    bool joined = pChannel->getJoined();
-    bool archived = pChannel->getArchived();
-    bool readonly = pChannel->getReadOnly();
-    bool blocked = pChannel->getBlocked();
-    mStorage->addChannel( id, name, type, joined, readonly, muted, archived, blocked, username );
+    auto id = pChannel->getRoomId();
+    auto name  = pChannel->getName();
+    auto type = pChannel->getType();
+    auto muted = pChannel->getMuted().join( "," );
+    auto username = pChannel->getUsername();
+    auto joined = pChannel->getJoined();
+    auto archived = pChannel->getArchived();
+    auto readonly = pChannel->getReadOnly();
+    auto blocked = pChannel->getBlocked();
+    auto chatPartnerId = pChannel->getChatPartnerId();
+    mStorage->addChannel( id, name, type, joined, readonly, muted, archived, blocked, username, chatPartnerId );
 }
 /**
  * Fills the channel with users, which are loaded from the server
@@ -307,17 +330,62 @@ void RocketChatChannelService::loadUsersOfChannel( QSharedPointer<RocketChatChan
                 if ( Q_LIKELY( result.contains( "records" ) && result["records"].isArray() ) ) {
                     QJsonArray records = result["records"].toArray();
                     QVector<QSharedPointer<RocketChatUser>> userList;
+                    auto userModel = Models::getUsersModel();
 
                     //crate new user objects and add them to the channel
-                    for ( const auto &current : records ) {
+                    for ( const auto current : records ) {
                         if ( current.type() == QJsonValue::Object ) {
                             QJsonObject userObject = current.toObject();
-                            QString username = userObject["username"].toString();
-                            QString name = userObject["name"].toString();
-                            QSharedPointer<RocketChatUser> user( new RocketChatUser( username ) );
-                            user->setName( name );
+                            QString username;
+                            QString userId;
+                            QString status;
+                            QString name;
+
+                            if ( userObject.contains( "id" ) ) {
+                                userId = userObject["id"].toString();
+                            } else if ( userObject.contains( "_id" ) ) {
+                                userId = userObject["_id"].toString();
+                            }
+
+                            if ( userObject.contains( "username" ) ) {
+                                username = userObject["username"].toString();
+                            }
+
+                            if ( userObject.contains( "status" ) ) {
+                                status = userObject["status"].toString();
+                            }
+
+                            if ( userObject.contains( "name" ) ) {
+                                name = userObject["name"].toString();
+                            }
+
+                            QSharedPointer<RocketChatUser> user;
+
+
+                            auto oldUser = userModel->getUserById( userId );
+
+                            if ( !oldUser.isNull() ) {
+                                oldUser->setName( name );
+                                oldUser->setUserId( username );
+                                oldUser->setStatus( status );
+                                user = oldUser;
+
+                            } else {
+                                QSharedPointer<RocketChatUser> newUser( new RocketChatUser( userId ) );
+                                newUser->setName( name );
+                                newUser->setUserName( username );
+                                newUser->setStatus( status );
+                                user = newUser;
+                            }
+
+                            if ( userId == pChannel->getChatPartnerId() ) {
+                                pChannel->setChatPartner( user );
+                            }
+
                             userList.append( user );
+
                         } else if ( current.type() == QJsonValue::String ) {
+                            //TODO: still relevant?
                             QString name = current.toString();
                             QSharedPointer<RocketChatUser> user( new RocketChatUser( name ) );
                             userList.append( user );
diff --git a/sql.qrc b/sql.qrc
index 2efe50d77fcfd806a1878187d225f26dc30a31c8..704a7f271bd99d2db7a24b93cb13a51fbb629864 100644
--- a/sql.qrc
+++ b/sql.qrc
@@ -5,5 +5,6 @@
         <file>sql/migrations/2.sql</file>
         <file>sql/migrations/3.sql</file>
         <file>sql/migrations/4.sql</file>
+        <file>sql/migrations/5.sql</file>
     </qresource>
 </RCC>
diff --git a/sql/migrations/5.sql b/sql/migrations/5.sql
new file mode 100644
index 0000000000000000000000000000000000000000..87b997d5b223fd6338cb0bb4f5f7d4ebd42a0f5e
--- /dev/null
+++ b/sql/migrations/5.sql
@@ -0,0 +1,2 @@
+ALTER TABLE rooms ADD chat_partner_id varchar(100) DEFAULT "";
+REPLACE INTO app_info (db_ver) VALUES(5);