From d02a609956160a7cc3a510ab48f5ca2a8db31ea3 Mon Sep 17 00:00:00 2001 From: Armin Felder <armin.felder@osalliance.com> Date: Tue, 13 Nov 2018 00:27:44 +0100 Subject: [PATCH] own user status now working --- CustomModels/usermodel.cpp | 18 +++++-- CustomModels/usermodel.h | 4 ++ ...ketchatchangeuserpresancedefaultstatus.cpp | 41 ---------------- ...cketchatchangeuserpresencedefaultstatus.h} | 14 ++---- ddpRequests/rocketchatsubscribeuserdata.cpp | 9 ++++ ddpRequests/rocketchatsubscribeuserdata.h | 12 +++++ engine.pro | 12 +++-- repos/entities/rocketchatuser.h | 10 ++-- rocketchat.cpp | 7 +++ rocketchat.h | 2 + rocketchatserver.cpp | 48 ++++++++++++++++--- rocketchatserver.h | 8 +++- 12 files changed, 115 insertions(+), 70 deletions(-) delete mode 100644 ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp rename ddpRequests/{rocketchatchangeuserpresancedefaultstatus.h => rocketchatchangeuserpresencedefaultstatus.h} (88%) create mode 100644 ddpRequests/rocketchatsubscribeuserdata.cpp create mode 100644 ddpRequests/rocketchatsubscribeuserdata.h diff --git a/CustomModels/usermodel.cpp b/CustomModels/usermodel.cpp index 1092392..0a991d3 100644 --- a/CustomModels/usermodel.cpp +++ b/CustomModels/usermodel.cpp @@ -86,6 +86,7 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke if ( !user.isNull() ) { QSharedPointer<RocketChatUser> userToAdd; + mMutex.lock(); if ( mAllUsers.contains( user->getUserId() ) ) { auto oldUser = mAllUsers[user->getUserId()]; @@ -114,6 +115,7 @@ bool UserModel::insertUser( const QString &channelId, const QSharedPointer<Rocke } userMap.insert( channelId, userToAdd ); + mMutex.unlock(); setCurrent( getCurrent() ); } else { return true; @@ -138,10 +140,11 @@ 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->getUserId(), current ); @@ -157,15 +160,24 @@ void UserModel::onCurrentChannelChanged( const QString &newText ) QSharedPointer<RocketChatUser> UserModel::getUserById( const QString &pId ) { - return mAllUsers.contains( pId ) ? mAllUsers[pId] : nullptr; + 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 ); - } } diff --git a/CustomModels/usermodel.h b/CustomModels/usermodel.h index 79f489f..8bf6725 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" @@ -67,6 +68,9 @@ class UserModel: public QAbstractListModel 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/ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp b/ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp deleted file mode 100644 index 3757a57..0000000 --- a/ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp +++ /dev/null @@ -1,41 +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/>. * - * * - ********************************************************************************************/ - - -#include "rocketchatchangeuserpresancedefaultstatus.h" - -RocketChatChangeUserPresanceDefaultStatus::RocketChatChangeUserPresanceDefaultStatus( const status &pStatus ) -{ - QJsonArray params; - - QString statusText; - - if ( pStatus == status::AWAY ) { - statusText = QStringLiteral( "away" ); - } else if ( pStatus == status::ONLINE ) { - statusText = QStringLiteral( "online" ); - } else if ( pStatus == status::OFFLINE ) { - statusText = QStringLiteral( "offline" ); - } - - 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 a6d894b..cef6bb3 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/rocketchatsubscribeuserdata.cpp b/ddpRequests/rocketchatsubscribeuserdata.cpp new file mode 100644 index 0000000..043dc38 --- /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 0000000..100fcc1 --- /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 064de0f..2e07cbb 100644 --- a/engine.pro +++ b/engine.pro @@ -77,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 +100,9 @@ SOURCES += api/meteorddp.cpp \ ddpRequests/rocketchatgetroomidbynameorid.cpp \ ddpRequests/rocketchatspotlightrequest.cpp \ repos/entities/rocketchatreplymessage.cpp \ - ddpRequests/rocketchatcreatepublicgrouprequest.cpp + ddpRequests/rocketchatcreatepublicgrouprequest.cpp \ + ddpRequests/rocketchatchangeuserpresencestatus.cpp \ + ddpRequests/rocketchatsubscribeuserdata.cpp HEADERS += \ @@ -179,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 +205,10 @@ HEADERS += \ ddpRequests/rocketchatspotlightrequest.h \ api/messagelistener.h \ repos/entities/rocketchatreplymessage.h \ - ddpRequests/rocketchatcreatepublicgrouprequest.h + ddpRequests/rocketchatcreatepublicgrouprequest.h \ + ddpRequests/rocketchatchangeuserpresencestatus.h \ + ddpRequests/rocketchatchangeuserpresencedefaultstatus.h \ + ddpRequests/rocketchatsubscribeuserdata.h linux{ diff --git a/repos/entities/rocketchatuser.h b/repos/entities/rocketchatuser.h index 61412d5..6f6c04b 100755 --- a/repos/entities/rocketchatuser.h +++ b/repos/entities/rocketchatuser.h @@ -31,11 +31,11 @@ class RocketChatUser : public QObject public: - enum class status { - ONLINE, - AWAY, - OFFLINE, - BUSY + enum class status : int { + ONLINE = 0, + AWAY = 1, + OFFLINE = 2, + BUSY = 3 }; explicit RocketChatUser( const QString &pId ) ; diff --git a/rocketchat.cpp b/rocketchat.cpp index c07f38b..6c8ca65 100755 --- a/rocketchat.cpp +++ b/rocketchat.cpp @@ -264,6 +264,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(); @@ -760,6 +765,8 @@ void RocketChat::serverReadySlot() connect( pServer, &RocketChatServerData::loggingIn, this, &RocketChat::loggingIn, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::historyReady, this, &RocketChat::historyReady, Qt::UniqueConnection ); + connect( pServer, &RocketChatServerData::userStatusChanged, this, &RocketChat::userStatusChanged, Qt::UniqueConnection ); + QMetaObject::invokeMethod( pServer, "init" ); } diff --git a/rocketchat.h b/rocketchat.h index a2bcc05..802d3a7 100755 --- a/rocketchat.h +++ b/rocketchat.h @@ -147,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 ); @@ -262,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 cab9219..01face4 100755 --- a/rocketchatserver.cpp +++ b/rocketchatserver.cpp @@ -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 ) ) ); - sendDdprequest( 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 ) ); } } @@ -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() @@ -626,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 ); @@ -688,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 ); @@ -767,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 ); @@ -839,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(); @@ -932,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(); @@ -1188,7 +1214,10 @@ void RocketChatServerData::onDDPMessageReceived( const QJsonObject &pMessage ) 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(); user->setStatus( msgStatus ); } @@ -1208,7 +1237,10 @@ void RocketChatServerData::onDDPMessageReceived( const QJsonObject &pMessage ) if ( pMessage.contains( "fields" ) ) { QJsonObject fields = pMessage["fields"].toObject(); - if ( fields.contains( QStringLiteral( "status" ) ) ) { + 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 ); } @@ -1714,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() ); + 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(); diff --git a/rocketchatserver.h b/rocketchatserver.h index 46508a2..2398074 100755 --- a/rocketchatserver.h +++ b/rocketchatserver.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" @@ -186,6 +188,8 @@ class RocketChatServerData : public MessageListener void requestIsLoggedIn(); + void setUserPresenceDefaultStatus( int pStatus ); + void setUserPresenceStatus( int pStatus ); void onStateChanged( const Qt::ApplicationState &pState ); @@ -257,6 +261,7 @@ class RocketChatServerData : public MessageListener uint mTokenExpire = 0; QString mResumeToken; bool mUnsecureConnection = false; + QSharedPointer<RocketChatUser> mOwnUser; MeteorDDP *mDdpApi = nullptr; RestApi *mRestApi = nullptr; @@ -346,6 +351,7 @@ class RocketChatServerData : public MessageListener void offlineMode( void ); void loggingIn(); void historyReady(); + void userStatusChanged( int status ); // MessageListener interface public: -- GitLab