From 0a776b8e94065d6bd3a3e31cf0cea85d2c896452 Mon Sep 17 00:00:00 2001 From: Armin Felder <armin.felder@osalliance.com> Date: Sun, 11 Nov 2018 22:51:45 +0100 Subject: [PATCH] user status --- CustomModels/channelmodel.cpp | 30 ++++++++++++ CustomModels/channelmodel.h | 3 +- CustomModels/usermodel.cpp | 28 ++++++++--- CustomModels/usermodel.h | 3 +- repos/entities/rocketchatchannel.cpp | 29 ++++++++++-- repos/entities/rocketchatchannel.h | 11 ++++- repos/entities/rocketchatuser.cpp | 30 ++++++++++-- repos/entities/rocketchatuser.h | 9 ++-- rocketchatserver.cpp | 67 ++++++++++++++------------- services/rocketchatchannelservice.cpp | 60 ++++++++++++++++++++---- 10 files changed, 208 insertions(+), 62 deletions(-) diff --git a/CustomModels/channelmodel.cpp b/CustomModels/channelmodel.cpp index 23a7d36..eb22f69 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 681e9d3..cf4b5eb 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 eb969f7..198c1de 100644 --- a/CustomModels/usermodel.cpp +++ b/CustomModels/usermodel.cpp @@ -67,6 +67,11 @@ QVariant UserModel::data( const QModelIndex &index, int role ) const case RocketChatUser::status::OFFLINE: status = 2; + break; + + case RocketChatUser::status::BUSY: + status = 3; + break; } return status; @@ -82,8 +87,8 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke if ( !user.isNull() ) { QSharedPointer<RocketChatUser> userToAdd; - if ( mAllUsers.contains( user->getUserName() ) ) { - auto oldUser = mAllUsers[user->getUserName()]; + if ( mAllUsers.contains( user->getUserId() ) ) { + auto oldUser = mAllUsers[user->getUserId()]; if ( !user->getSurname().isEmpty() ) { oldUser->setSurname( user->getSurname() ); @@ -104,7 +109,8 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke userToAdd = oldUser; } else { userToAdd = user; - mAllUsers.insert( userToAdd->getUserName(), userToAdd ); + mAllUsers.insert( userToAdd->getUserId(), userToAdd ); + connect( userToAdd.data(), &RocketChatUser::statusChanged, this, &UserModel::refreshUserList ); } userMap.insert( channelId, userToAdd ); @@ -118,6 +124,12 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke return true; } +void UserModel::refreshUserList() +{ + beginResetModel(); + endResetModel(); +} + QString UserModel::getCurrent() const { return current; @@ -132,7 +144,7 @@ void UserModel::setCurrent( const QString &value ) QList<QSharedPointer<RocketChatUser>> userList = userMap.values( value ); for ( auto current : userList ) { - userOfCurrentChannel.insert( current->getUserName(), current ); + userOfCurrentChannel.insert( current->getUserId(), current ); } endResetModel(); @@ -143,15 +155,17 @@ void UserModel::onCurrentChannelChanged( const QString &newText ) current = newText; } -QSharedPointer<RocketChatUser> UserModel::getUserByUsername( const QString &pUserName ) +QSharedPointer<RocketChatUser> UserModel::getUserById( const QString &pId ) { - return mAllUsers.contains( pUserName ) ? mAllUsers[pUserName] : nullptr; + return mAllUsers.contains( pId ) ? mAllUsers[pId] : nullptr; } void UserModel::addUser( QSharedPointer<RocketChatUser> pUser ) { if ( !pUser.isNull() ) { - mAllUsers.insert( pUser->getUserName(), pUser ); + mAllUsers.insert( pUser->getUserId(), pUser ); + connect( pUser.data(), &RocketChatUser::statusChanged, this, &UserModel::refreshUserList ); + } } diff --git a/CustomModels/usermodel.h b/CustomModels/usermodel.h index 4aec7ee..233bed6 100644 --- a/CustomModels/usermodel.h +++ b/CustomModels/usermodel.h @@ -46,6 +46,7 @@ class UserModel: public QAbstractListModel }; public slots: bool insertUser( const QString &, const QSharedPointer<RocketChatUser> & ); + void refreshUserList(); public: UserModel( QObject *parent = nullptr ); @@ -55,7 +56,7 @@ class UserModel: public QAbstractListModel void setCurrent( const QString &value ); void onCurrentChannelChanged( const QString &newText ); - QSharedPointer<RocketChatUser> getUserByUsername( const QString &pUserName ); + QSharedPointer<RocketChatUser> getUserById( const QString &pId ); void addUser( QSharedPointer<RocketChatUser> pUser ); diff --git a/repos/entities/rocketchatchannel.cpp b/repos/entities/rocketchatchannel.cpp index f0fd26f..876b022 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 e006388..e91ce98 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 b94bb87..a4fc04b 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 b3e5495..61412d5 100755 --- a/repos/entities/rocketchatuser.h +++ b/repos/entities/rocketchatuser.h @@ -34,9 +34,10 @@ class RocketChatUser : public QObject enum class status { ONLINE, AWAY, - OFFLINE + OFFLINE, + BUSY }; - 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/rocketchatserver.cpp b/rocketchatserver.cpp index 4b2e6f0..bcf16bd 100755 --- a/rocketchatserver.cpp +++ b/rocketchatserver.cpp @@ -1183,49 +1183,49 @@ void RocketChatServerData::onDDPMessageReceived( const QJsonObject &pMessage ) QString msg = pMessage[QStringLiteral( "msg" )].toString(); QJsonObject fields = pMessage["fields"].toObject(); - if ( fields.contains( QStringLiteral( "username" ) ) ) { - auto username = fields["username"].toString(); - auto user = userModel->getUserByUsername( username ); + auto user = userModel->getUserById( userId ); - if ( !user.isNull() ) { - if ( msg == QStringLiteral( "added" ) ) { - - } else if ( msg == QStringLiteral( "changed" ) ) { - 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; - } + if ( !user.isNull() ) { + if ( msg == QStringLiteral( "added" ) || msg == QStringLiteral( "changed" ) ) { - user->setStatus( userStatus ); - } + if ( fields.contains( QStringLiteral( "status" ) ) ) { + QString msgStatus = fields[QStringLiteral( "status" )].toString(); + user->setStatus( msgStatus ); + } - } else if ( msg == QStringLiteral( "removed" ) ) { - //TODO: delete user - user->setStatus( RocketChatUser::status::OFFLINE ); + if ( fields.contains( QStringLiteral( "name" ) ) ) { + user->setUserName( fields[QStringLiteral( "name" )].toString() ); } - } else { - auto newUser = QSharedPointer<RocketChatUser>( new RocketChatUser( username ) ); - newUser->setUserId( userId ); - if ( pMessage.contains( "fields" ) ) { - QJsonObject fields = pMessage["fields"].toObject(); - if ( fields.contains( "username" ) ) { - newUser->setUserName( username ); - } + } else if ( msg == QStringLiteral( "removed" ) ) { + //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( "status" ) ) ) { + QString msgStatus = fields[QStringLiteral( "status" )].toString(); + newUser->setStatus( msgStatus ); + } + + if ( fields.contains( QStringLiteral( "name" ) ) ) { + newUser->setName( fields[QStringLiteral( "name" )].toString() ); } - QMetaObject::invokeMethod( userModel, "addUser", Q_ARG( User, newUser ) ); + 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(); @@ -1857,7 +1857,8 @@ void RocketChatServerData::getLoginMethods() }; QSharedPointer<RocketChatSubscribeLoginMethods> loginMethodsSubscription( new RocketChatSubscribeLoginMethods() ); loginMethodsSubscription->setSuccess( success ); - sendDdprequest( loginMethodsSubscription ); + // sendDdprequest( loginMethodsSubscription ); + mDdpApi->sendRequest( loginMethodsSubscription ); } void RocketChatServerData::getServerInfo() diff --git a/services/rocketchatchannelservice.cpp b/services/rocketchatchannelservice.cpp index 202a60a..1258f8f 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 ¤tChannel : 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 ); } @@ -307,17 +315,51 @@ 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 ¤t : records ) { + for ( const auto current : records ) { if ( current.type() == QJsonValue::Object ) { QJsonObject userObject = current.toObject(); QString username = userObject["username"].toString(); + QString userId = userObject["id"].toString(); + QString status; + + if ( userObject.contains( "status" ) ) { + status = userObject["status"].toString(); + } + + if ( userId.isEmpty() && userObject.contains( "_id" ) ) { + userId = userObject["_id"].toString(); + } + + QSharedPointer<RocketChatUser> user; + QString name = userObject["name"].toString(); - QSharedPointer<RocketChatUser> user( new RocketChatUser( username ) ); - user->setName( name ); + 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 ); -- GitLab