diff --git a/api/meteorddp.cpp b/api/meteorddp.cpp index 9b60ddbe14e0e52d25adabd9b51170a3b69d5711..8e7272025a289ec88657e588d226ce0146b420a5 100755 --- a/api/meteorddp.cpp +++ b/api/meteorddp.cpp @@ -255,6 +255,12 @@ uint MeteorDDP::diffToLastMessage() return difference; } +void MeteorDDP::disconnectFromServer() +{ + qDebug()<<"disconnect from server"; + mWsClient->close(); +} + void MeteorDDP::setResumeToken( QString pToken ) { this->mToken = pToken; diff --git a/api/meteorddp.h b/api/meteorddp.h index 0692e4b8a65a5fe218a371e24d12a66e8006fd50..5d47583ac2d51fb2d6a0d8905adf446cb0285e85 100755 --- a/api/meteorddp.h +++ b/api/meteorddp.h @@ -32,6 +32,7 @@ class MeteorDDP : public QObject bool websocketIsValid(void); uint diffToLastMessage( void ); + void disconnectFromServer( void ); void setResumeToken(QString pToken); void setUserId(QString pUserId); diff --git a/api/restapi.cpp b/api/restapi.cpp index d4efd7f2df04541f834e83177bfbdd80263ebbb0..0941031349b2430c410fe025ae39a2a6e7890b3c 100755 --- a/api/restapi.cpp +++ b/api/restapi.cpp @@ -184,6 +184,7 @@ QNetworkReply *RestApi::post( QString pUrl, QByteArray pData, QString pMimeType request.setRawHeader( QByteArray( "X-User-Id" ), QByteArray( mUserId.toLocal8Bit() ) ); request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); + request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); QNetworkReply *reply = mNam.post( request, pData ); return reply; } @@ -197,6 +198,8 @@ QNetworkReply *RestApi::get( QString pUrl, QString pMimeType ) request.setHeader( QNetworkRequest::ContentTypeHeader, QString( pMimeType ) ); request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); + request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); + QNetworkReply *reply = mNam.get( request ); return reply; } diff --git a/engine.pro b/engine.pro index 65592773f641fbc4400e31c5a441edf8c4e64a63..d50af0b127d7bb0db890d908882885dd628cc0c9 100644 --- a/engine.pro +++ b/engine.pro @@ -29,6 +29,11 @@ SOURCES += api/meteorddp.cpp \ ddpRequests/rocketchatmessagesearchrequest.cpp \ ddpRequests/rocketchatsubscribeactiveusers.cpp \ ddpRequests/rocketchatsubscriberoomrequest.cpp \ + ddpRequests/ddpsamlloginrequest.cpp \ + ddpRequests/rocketchatstatsrequest.cpp \ + ddpRequests/rocketchatspotlightrequest.cpp \ + ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp \ + ddpRequests/rocketchatupdatejitsitimeout.cpp \ repos/abstractbaserepository.cpp \ repos/messagerepository.cpp \ repos/channelrepository.cpp \ @@ -74,9 +79,7 @@ SOURCES += api/meteorddp.cpp \ container/sortedvector.cpp \ container/observablelist.cpp \ container/modelobserver.cpp \ - ddpRequests/rocketchatchangeuserpresancedefaultstatus.cpp \ - CustomModels/messagemodel.cpp \ - ddpRequests/rocketchatupdatejitsitimeout.cpp + CustomModels/messagemodel.cpp HEADERS += \ api/meteorddp.h \ diff --git a/notifications/android/googlepushnotifications.cpp b/notifications/android/googlepushnotifications.cpp index c8fea8fe775c0ac29d8e0eafc6cf69fd8c499bf9..71d2740cc2b223be9a4db19dbf2eaa0916754f2c 100755 --- a/notifications/android/googlepushnotifications.cpp +++ b/notifications/android/googlepushnotifications.cpp @@ -57,3 +57,8 @@ void GooglePushNotifications::registerWithService() { init(); } + +void GooglePushNotifications::checkForPendingMessages() +{ + +} diff --git a/notifications/android/googlepushnotifications.h b/notifications/android/googlepushnotifications.h index 01df7e3e9f44504f74979ea5379dca3d246055c3..4d47420fd27cbb493afb934cc5d4cff5f040fd6a 100755 --- a/notifications/android/googlepushnotifications.h +++ b/notifications/android/googlepushnotifications.h @@ -28,6 +28,10 @@ private: QString mGcmRegistrationId; AndroidNotificationReceiver* mReceiver; + + // NotificationAbstract interface +public: + void checkForPendingMessages(); }; #endif // GOOGLEPUSHNOTIFICATIONS_H diff --git a/notifications/ios/DelegateClass.h b/notifications/ios/DelegateClass.h index e67441fcc5508abb1303752af59a6603f7325ec0..623e49103b0a99b74878a100e9ea3381c5e5fad9 100755 --- a/notifications/ios/DelegateClass.h +++ b/notifications/ios/DelegateClass.h @@ -15,5 +15,7 @@ class IosDeviceTokenStorage; - (void) sendMessage:(NSString *)pServer : (NSString *)pRid : (NSString *)pName : (NSString *)pType; +- (void) openChannelByName:(NSString *)channelName; + @end diff --git a/notifications/ios/DelegateClass.mm b/notifications/ios/DelegateClass.mm index 598f4fe870d8dba99c80e30be0e559d9c89b02fe..9e04a12ab22d89a755509015e7017f10b38c56db 100755 --- a/notifications/ios/DelegateClass.mm +++ b/notifications/ios/DelegateClass.mm @@ -28,5 +28,13 @@ } } +- (void) openChannelByName:(NSString *)channelName{ + if(channelName != NULL){ + QString channelNameString([channelName UTF8String]); + mNotificationsInstance->sendSwitchChannelByName(channelNameString); + + } +} + @end diff --git a/notifications/ios/applepushnotifications.cpp b/notifications/ios/applepushnotifications.cpp index b9240e2c6d8999ca71cfdf55be7f2d84181c05e1..9b2f5aa0a84b2408d7bbfe705f6dfa2e998ce61d 100755 --- a/notifications/ios/applepushnotifications.cpp +++ b/notifications/ios/applepushnotifications.cpp @@ -1,4 +1,5 @@ #include "applepushnotifications.h" +#include ApplePushNotifications::ApplePushNotifications() { @@ -6,6 +7,7 @@ ApplePushNotifications::ApplePushNotifications() mNotificationInstance = IosNotificationReceiver::getInstance(); connect(mInstance, &IosDeviceTokenStorage::tokenReceived, this, &ApplePushNotifications::receiveToken); connect(mNotificationInstance, &IosNotificationReceiver::messageReceived, this, &ApplePushNotifications::receiveMessage); + connect(mNotificationInstance, &IosNotificationReceiver::switchChannelByName, this, &ApplePushNotifications::onSwitchRequest); } void ApplePushNotifications::receiveMessage(QString pServer, QString pRid, QString pName, QString pType) @@ -14,6 +16,7 @@ void ApplePushNotifications::receiveMessage(QString pServer, QString pRid, QStri } void ApplePushNotifications::receiveToken(){ + qDebug()<<"token received"; QString newToken = mInstance->getToken(); if (newToken != ""){ mToken = newToken; @@ -26,3 +29,12 @@ void ApplePushNotifications::registerWithService(){ receiveToken(); } } + +void ApplePushNotifications::checkForPendingMessages(){ + emit switchChannelByName(mRoomName); +} + +void ApplePushNotifications::onSwitchRequest(QString pName){ + mRoomName = pName; + emit switchChannelByName(pName); +} diff --git a/notifications/ios/applepushnotifications.h b/notifications/ios/applepushnotifications.h index a16ef54782415a737cd3a791da90001786c97e39..a8420bc0789e3eba21a227dd54a085ddbf3d8114 100755 --- a/notifications/ios/applepushnotifications.h +++ b/notifications/ios/applepushnotifications.h @@ -10,11 +10,17 @@ public: virtual void registerWithService(); ApplePushNotifications(); void receiveMessage(QString server, QString rid, QString name, QString type); + + void checkForPendingMessages(); + + void onSwitchRequest(QString pName); protected: void receiveToken(); IosDeviceTokenStorage* mInstance = nullptr; IosNotificationReceiver* mNotificationInstance = nullptr; + + QString mRoomName; }; #endif // APPLEPUSHNOTIFICATIONS_H diff --git a/notifications/ios/iosnotificationreceiver.cpp b/notifications/ios/iosnotificationreceiver.cpp index 068efe7a1e11b2f981b1298a40b81457af297d29..be90800abb8b72376b232b3ef3fba13f6b54c2be 100644 --- a/notifications/ios/iosnotificationreceiver.cpp +++ b/notifications/ios/iosnotificationreceiver.cpp @@ -14,3 +14,7 @@ void IosNotificationReceiver::sendMessageReceived(QString pServer, QString pRid, { emit messageReceived(pServer,pRid,pName,pType); } + +void IosNotificationReceiver::sendSwitchChannelByName(QString pName){ + emit switchChannelByName(pName); +} diff --git a/notifications/ios/iosnotificationreceiver.h b/notifications/ios/iosnotificationreceiver.h index 8d8cd2e814d768d4f05a8e0dc49db0f9aa46be35..e0e65f99422b1b4e40325922cda3de394779771a 100644 --- a/notifications/ios/iosnotificationreceiver.h +++ b/notifications/ios/iosnotificationreceiver.h @@ -10,6 +10,7 @@ public: static IosNotificationReceiver* getInstance(); void sendMessageReceived(QString pServer, QString pRid, QString pName, QString pType); + void sendSwitchChannelByName(QString pName); private: IosNotificationReceiver(){} @@ -20,6 +21,7 @@ private: signals: void messageReceived(QString pServer, QString pRid, QString pName, QString pType); + void switchChannelByName(QString channelName); }; #endif // IOSNOTIFICATIONRECEIVER_H diff --git a/notifications/notificationabstract.h b/notifications/notificationabstract.h index af40af77a7d68b9e5a52da548aa622246d328b1d..aefcf758f3cc8e08498a5b5545c97f5326ba5c9d 100755 --- a/notifications/notificationabstract.h +++ b/notifications/notificationabstract.h @@ -15,6 +15,8 @@ public: QString getToken() const; void setToken(const QString &pValue); + + virtual void checkForPendingMessages() = 0; protected: QString mToken; @@ -22,6 +24,7 @@ protected: signals: void tokenReceived(QString pToken); void messageReceived(QString pServer, QString pRid, QString pName, QString pType); + void switchChannelByName(QString pChannel); }; diff --git a/notifications/notifications.cpp b/notifications/notifications.cpp index 577c0d1fb6b3dd87f3ad7f7457ec4e088a478f65..a8c07dc7c4a4d9815a43a7479f9c9888b8f73119 100755 --- a/notifications/notifications.cpp +++ b/notifications/notifications.cpp @@ -22,6 +22,7 @@ Notifications::Notifications() if(mNotificationInstance != nullptr){ connect(mNotificationInstance,&Notifications::tokenReceived,this, &Notifications::tokenReceived); connect(mNotificationInstance,&Notifications::messageReceived,this, &Notifications::messageReceived); + connect(mNotificationInstance,&Notifications::switchChannelByName,this, &Notifications::switchChannelByName); } } @@ -32,3 +33,7 @@ void Notifications::registerWithService() mNotificationInstance->registerWithService(); } } + +void Notifications::checkForPendingMessages(){ + mNotificationInstance->checkForPendingMessages(); +} diff --git a/notifications/notifications.h b/notifications/notifications.h index fda84862b129c03a4098c69d834d78508ec12a44..f83832ae2e167a977839a1f4a30fc39b4e12ed2d 100755 --- a/notifications/notifications.h +++ b/notifications/notifications.h @@ -11,6 +11,7 @@ public: // NotificationAbstract interface public: void registerWithService(); + void checkForPendingMessages(); private: NotificationAbstract *mNotificationInstance = NULL; diff --git a/persistancelayer.cpp b/persistancelayer.cpp index 54c30f837797c81ded5a239a31a4366efbf44109..e3c5a82c972ac67b1d0673b812b937390cdfa1c9 100755 --- a/persistancelayer.cpp +++ b/persistancelayer.cpp @@ -272,6 +272,8 @@ void PersistanceLayer::wipeDb() if ( !file.remove() ) { qWarning() << file.errorString(); + }else{ + qDebug()<<"db wiped"; } init(); diff --git a/rocketchat.cpp b/rocketchat.cpp index 9dafb73ef1b8259f40b2765b95b834a645eec675..d76b65fcb691e089b607eb45930207e2977aa670 100755 --- a/rocketchat.cpp +++ b/rocketchat.cpp @@ -47,15 +47,18 @@ RocketChat::RocketChat( QGuiApplication *app, ChannelModel &channelModel, Channe #ifdef Q_OS_IOS mGalleryPicker = new IosGalleryPicker(); connect( mGalleryPicker, &IosGalleryPicker::filePicked, this, &RocketChat::openFileNameReady ); + connect( &mNotificationsObject, &Notifications::switchChannelByName, this, &RocketChat::onExternalChannelSwitchRequest, Qt::UniqueConnection ); #endif #ifdef Q_OS_WINRT //KeypadHelper *helper = new KeypadHelper(); //helper->showKeypad(); mInputMethod = QGuiApplication::inputMethod(); - connect( mInputMethod, &QInputMethod::visibleChanged, this, &RocketChat::onKeyboardVisiblityChanged ); + connect(mInputMethod,&QInputMethod::visibleChanged,this,&RocketChat::onKeyboardVisiblityChanged); #endif #ifdef Q_OS_ANDROID mAndroidStatusBarColor = new AndroidStatusBarColor; + connect( &mNotificationsObject, &Notifications::switchChannelByName, this, &RocketChat::onExternalChannelSwitchRequest, Qt::UniqueConnection ); + #endif qRegisterMetaType( "ConnectionState" ); qRegisterMetaType( "Qt::ApplicationState" ); @@ -95,6 +98,14 @@ void RocketChat::login( QString pServerId, QString pUsername, QString pPassword } } +void RocketChat::loginWithSamlToken(QString pToken){ + if(!pToken.isEmpty()){ + if(mServerStatus){ + QMetaObject::invokeMethod(mServerMap.first().data(), "loginWtihSamlToken", Q_ARG( QString, pToken )); + } + } +} + void RocketChat::loadRecentHistory( QString pChannelId ) { if ( mServerStatus ) { @@ -114,18 +125,18 @@ bool RocketChat::isStorageReady() void RocketChat::forceVirtualKeyboardShow() { - QGuiApplication::inputMethod()->setVisible( true ); + QGuiApplication::inputMethod()->setVisible(true); } void RocketChat::forceVirtualKeyboardHide() { - QGuiApplication::inputMethod()->setVisible( false ); + QGuiApplication::inputMethod()->setVisible(false); } -void RocketChat::setStatusBarColor( QString pColor ) +void RocketChat::setStatusBarColor(QString pColor) { #ifdef Q_OS_ANDROID - mAndroidStatusBarColor->setStatusBarColor( pColor ); + mAndroidStatusBarColor->setStatusBarColor(pColor); #endif } @@ -550,6 +561,7 @@ void RocketChat::registerForPush() { #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) mNotificationsObject.registerWithService(); + checkForpendingNotification(); #endif } @@ -691,15 +703,32 @@ void RocketChat::onServerSlotsReady() connect( &mNotificationsObject, &Notifications::tokenReceived, pServer.data(), &RocketChatServerData::sendPushToken, Qt::UniqueConnection ); connect( &mNotificationsObject, &Notifications::messageReceived, pServer.data(), &RocketChatServerData::switchChannel, Qt::UniqueConnection ); + #ifdef Q_OS_ANDROID checkForpendingNotification(); #endif - +#ifdef Q_OS_IOS + mNotificationsObject.checkForPendingMessages(); +#endif mServerStatus = true; + if(!mChannelToSwitchTo.isEmpty()){ + onExternalChannelSwitchRequest(mChannelToSwitchTo); + } emit serverReady(); } +void RocketChat::onExternalChannelSwitchRequest(QString pName){ + if(mServerStatus){ + auto server = mServerMap.first(); + QMetaObject::invokeMethod( server.data() , "switchChannelByRid", Q_ARG(QString, pName)); + mChannelToSwitchTo.clear(); + }else{ + qDebug()<<"room name: "<moveToThread(QThread::currentThread()); mDdpApi->moveToThread(QThread::currentThread()); @@ -46,6 +48,9 @@ void RocketChatServerData::init() mChannels = new ChannelRepository(channelsModel, channelsModel, groupsModel,mMessagesModel); + mFileService = new FileService( this ); + mEmojiService = new EmojiService( this, mFileService, mStorage ); + connect( mDdpApi, &MeteorDDP::messageReceived, this, &RocketChatServerData::onDDPMessageReceived, Qt::UniqueConnection ); connect( mDdpApi, &MeteorDDP::ddpConnected, this, &RocketChatServerData::onDDPConnected, Qt::UniqueConnection ); qDebug() << "loaded channel list from db"; @@ -162,9 +167,16 @@ void RocketChatServerData::switchChannel( QString pServer, QString pRid, QString void RocketChatServerData::switchChannelByRid(QString pName) { - if(mChannels->getChannelByName(pName)){ - auto channel = mChannels->getChannelByName(pName); - switchChannel("default", channel->getRoomId(), pName, channel->getType()); + if(mLoggedIn){ + if(mChannels->getChannelByName(pName)){ + auto channel = mChannels->getChannelByName(pName); + switchChannel("default", channel->getRoomId(), pName, channel->getType()); + mPendingSwitchRoomRequest.clear(); + }else{ + searchForRoomIdByName(pName); + } + }else{ + mPendingSwitchRoomRequest = pName; } } @@ -241,6 +253,48 @@ void RocketChatServerData::createVideoCall(QString pRid) } } +//TODO: rename, as method is not really for searching only +void RocketChatServerData::searchForRoomIdByName(QString pName) +{ + QSharedPointer request( new RocketChatSpotLightRequest( pName ) ); + std::function success = [ = ]( QJsonObject pResponse, MeteorDDP * ) { + + if ( pResponse.contains( "result" ) ) { + QJsonObject result = pResponse["result"].toObject(); + + if ( result.contains( "users" ) ) { + QJsonArray users = result["users"].toArray(); + for (QJsonValueRef user: users){ + QJsonObject userObj = user.toObject(); + if(userObj.contains("username") &&userObj.contains("_id")){ + QString username = userObj["username"].toString(); + if(!username.compare(pName,Qt::CaseInsensitive)){ + QString id = userObj["_id"].toString(); + switchChannel("default",id,pName,"d"); + } + } + } + }else if(result.contains("rooms")){ + QJsonArray rooms = result["rooms"].toArray(); + for (QJsonValueRef room: rooms){ + QJsonObject roomObj = room.toObject(); + if(roomObj.contains("name")&&roomObj.contains("_id")){ + QString roomname = roomObj["name"].toString(); + if(!roomname.compare(pName,Qt::CaseInsensitive)){ + QString id = roomObj["_id"].toString(); + switchChannel("default",id,pName,"c"); + } + } + } + } + } + mPendingSwitchRoomRequest.clear(); + + }; + request->setSuccess(success); + mDdpApi->sendRequest(request); +} + QString RocketChatServerData::getUserId() const { return mUserId; @@ -256,6 +310,11 @@ void RocketChatServerData::checkForMissedMessages() } +void RocketChatServerData::disconnectFromServer() +{ + mDdpApi->disconnectFromServer(); +} + void RocketChatServerData::loadHistories() { QStringList channelIds; @@ -489,6 +548,71 @@ void RocketChatServerData::loginWithToken( QString pUsername, QString pToken, bo } } +void RocketChatServerData::loginWtihSamlToken( QString pToken ){ + if ( !pToken.isEmpty() ) { + qDebug()<setUserName(mUsername); + onResume(); + this->onDDPAuthenticated(); + } + + }; + + QSharedPointer request( new ddpSamlLoginRequest( pToken ) ); + std::function success = [ = ]( QJsonObject pResponse, MeteorDDP * ) { + qDebug() << "authenticated"; + mConnectionState = ConnectionState::ONLINE; + + if ( pResponse.contains( "result" ) ) { + QJsonObject result = pResponse["result"].toObject(); + + if ( result.contains( "token" ) && result.contains( "id" ) ) { + this->mResumeToken = result["token"].toString(); + QJsonObject expireObject = result["tokenExpires"].toObject(); + double expireDouble = expireObject["$date"].toDouble(); + mTokenExpire = ( uint )( expireDouble / 1000 ); + + QString userId = result["id"].toString(); + mStorage->setToken( mResumeToken, mTokenExpire ); + mStorage->setUserId( userId ); + mRestApi->setToken( mResumeToken ); + mRestApi->setUserId( userId ); + this->mUserId = result["id"].toString(); + mDdpApi->setToken( mResumeToken ); + mDdpApi->unsetResponseBinding( request->getFrame() ); + + + RestApiRequest meRequest + = RestApiRequest( new restMeRequest( meCallBackSuccess ) ); + + mRestApi->sendRequest(meRequest); + + + + } + } + }; + DdpCallback error = [ = ]( QJsonObject pResponse, MeteorDDP * ) { + Q_UNUSED( pResponse ); + qDebug() << "login error"; + qWarning() << "SAML2 token rejected"; + onLoginError(); + }; + + request->setSuccess( success ); + request->setError( error ); + mDdpApi->sendRequest( request ); + } else { + qDebug() << "empty token"; + } +} + + void RocketChatServerData::onDDPConnected() { QSharedPointer request( new PingRequest() ); @@ -581,6 +705,7 @@ void RocketChatServerData::getFileRessource( QString pUrl, QString pType ) void RocketChatServerData::sendPushToken( QString pToken ) { + qDebug()<<"send push token called"; if ( !mUserId.isEmpty() && !pToken.isEmpty() ) { qDebug()<<"send push token "+pToken; QSharedPointer sendToken = QSharedPointer( new RocketChatUpdatePushTokenRequest( pToken, mUserId ) ); @@ -894,6 +1019,24 @@ void RocketChatServerData::setConnectionState( const ConnectionState &pValue ) mConnectionState = pValue; } +RocketChatServerData::~RocketChatServerData() +{ + disconnect( mDdpApi, &MeteorDDP::messageReceived, this, &RocketChatServerData::onDDPMessageReceived ); + disconnect( mDdpApi, &MeteorDDP::ddpConnected, this, &RocketChatServerData::onDDPConnected ); + disconnect( channelService, &RocketChatChannelService::channelsLoaded, this, &RocketChatServerData::onChannelsLoaded ); + disconnect( channelService, &RocketChatChannelService::usersLoaded, this, &RocketChatServerData::onUsersLoaded ); + + qDebug()<<"serverThread "<deleteLater(); + mRestApi->deleteLater(); + mMessageService->deleteLater(); + channelService->deleteLater(); + mEmojiRepo->deleteLater(); + delete mFileService; + delete mEmojiService; +} + QString RocketChatServerData::getCurrentChannel() const { return mCurrentChannel; @@ -973,6 +1116,9 @@ void RocketChatServerData::onLoggedIn() mLoggedIn = true; channelService->loadJoinedChannelsFromServer(); emit loggedIn( mServerId ); + if(!mPendingSwitchRoomRequest.isEmpty()){ + switchChannelByRid(mPendingSwitchRoomRequest); + } } void RocketChatServerData::markChannelAsRead( QString pChannelId ) @@ -1279,6 +1425,7 @@ void RocketChatServerData::logout() // setRestApi( new RestApi( "https://" + mBaseUrl, mApiUri ) ); // mRestApi->moveToThread(QThread::currentThread()); mLoggedIn = false; + mStorage->wipeDb(); emit loggedOut( this->mServerId ); } diff --git a/rocketchatserver.h b/rocketchatserver.h index 1395537ddeea199fc95d30c4855d9b0a5acf3924..13d327db0dfaffc66cf14a4c2cd11cd0c93fb85c 100755 --- a/rocketchatserver.h +++ b/rocketchatserver.h @@ -35,6 +35,8 @@ #include "ddpRequests/rocketchatsubscribeactiveusers.h" #include "ddpRequests/rocketchatchangeuserpresancedefaultstatus.h" #include "ddpRequests/rocketchatupdatejitsitimeout.h" +#include "ddpRequests/rocketchatspotlightrequest.h" +#include "ddpRequests/ddpsamlloginrequest.h" #include "restRequests/restrequest.h" #include "restRequests/restlogoutrequest.h" #include "fileuploader.h" @@ -103,6 +105,7 @@ public slots: void login( QString pUsername, QString pPassword ); void loginWithHash( QString pUsername, QString pHash ); void loginWithToken( QString pUsername, QString pToken, bool pResume = false ); + void loginWtihSamlToken( QString pToken ); void joinChannel( QString pChannelId ); void connectWithServer(); @@ -152,6 +155,11 @@ public slots: void createVideoCall(QString pRid); + void disconnectFromServer(); + + void searchForRoomIdByName(QString pName); + + public: QString getServerId() const; bool isConnected() const; @@ -174,6 +182,7 @@ public: QJsonObject formatMessageTime( QJsonObject pJsonObject ); bool initialised = 0; ConnectionState getConnectionState() const; + ~RocketChatServerData(); QString getCurrentChannel() const; @@ -231,6 +240,7 @@ protected: ChannelModel &groupsModel; MessagesModel &mMessagesModel; std::function> *messages )> historyLoaded; + QString mPendingSwitchRoomRequest; void postProcessChannelData( QVector> pVec ); void onDDPConnected(); diff --git a/services/rocketchatchannelservice.cpp b/services/rocketchatchannelservice.cpp index cf236c5baa0153d28cf91974ab3fd18b5ef703bc..0eef6deda37aaaec513e2aa4c76809dc4144f74b 100755 --- a/services/rocketchatchannelservice.cpp +++ b/services/rocketchatchannelservice.cpp @@ -7,8 +7,8 @@ RocketChatChannelService::RocketChatChannelService( RocketChatServerData *pServe this->mServer = pServer; this->mMessageService = pMessageService; mStorage = PersistanceLayer::instance(); - qRegisterMetaType("channelVector"); - qRegisterMetaType("userVector"); + qRegisterMetaType( "channelVector" ); + qRegisterMetaType( "userVector" ); } @@ -16,12 +16,13 @@ QSharedPointer RocketChatChannelService::createChannelObject( { QSharedPointer ptr( new RocketChatChannel( mServer, mMessageService, pRoomId, pName, pType ) ); - if(Q_LIKELY(mChannels)){ - mChannels->add(ptr); - }else{ - qCritical()<<"Channelsrepo not available to ChannelService"; + if ( Q_LIKELY( mChannels ) ) { + mChannels->add( ptr ); + } else { + qCritical() << "Channelsrepo not available to ChannelService"; } - fillChannelWithMessages(ptr); + + fillChannelWithMessages( ptr ); return ptr; } @@ -31,20 +32,22 @@ QVector > RocketChatChannelService::processCha { QVector > vec; - std::tuple openChannelTupel = mStorage->getCurrentChannel(); - QString openChannel = std::get<0>(openChannelTupel); + std::tuple openChannelTupel = mStorage->getCurrentChannel(); + QString openChannel = std::get<0>( openChannelTupel ); for ( QJsonValueRef currentChannel : pChannelArray ) { QJsonObject currentChannelObject = currentChannel.toObject(); - if ( Q_LIKELY((currentChannelObject.contains( "rid" ) && - currentChannelObject.contains( "name" ))||( currentChannelObject.contains( "_id" ) && - currentChannelObject.contains( "t" ) ))) { + if ( Q_LIKELY( ( currentChannelObject.contains( "rid" ) && + currentChannelObject.contains( "name" ) ) || ( currentChannelObject.contains( "_id" ) && + currentChannelObject.contains( "t" ) ) ) ) { QString id = currentChannelObject["rid"].toString(); - if(id == ""){ + + if ( id == "" ) { id = currentChannelObject["_id"].toString(); } + QString name = currentChannelObject["name"].toString(); QString type = currentChannelObject["t"].toString(); bool readonly = currentChannelObject["ro"].toBool(); @@ -55,7 +58,7 @@ QVector > RocketChatChannelService::processCha int unread = currentChannelObject["unread"].toInt(); QSharedPointer channel = createChannelObject( id, name, type ); - if(!channel.isNull()){ + if ( !channel.isNull() ) { if ( mutedUsers.contains( username ) ) { channel->setSelfMuted( true ); } @@ -65,14 +68,17 @@ QVector > RocketChatChannelService::processCha channel->setReadOnly( readonly ); channel->setArchived( archived ); channel->setJoined( pJoined ); - if(id == openChannel){ - channel->setUnreadMessages(0); - }else{ - channel->setUnreadMessages(unread); + + if ( id == openChannel ) { + channel->setUnreadMessages( 0 ); + } else { + channel->setUnreadMessages( unread ); } - if(!archived){ - subscribeChannel(channel); + + if ( !archived ) { + subscribeChannel( channel ); } + vec.append( channel ); } @@ -96,14 +102,15 @@ void RocketChatChannelService::loadJoinedChannelsFromServer( void ) { std::function subscriptionSuccess = [ = ]( QJsonObject pResponse, MeteorDDP * pDdpApi ) { Q_UNUSED( pDdpApi ); - if ( Q_LIKELY(pResponse.contains( "result" )) ) { + + if ( Q_LIKELY( pResponse.contains( "result" ) ) ) { QJsonArray channels = pResponse["result"].toArray(); auto channelsParsed = processChannelData( channels, true ); emit channelsLoaded( channelsParsed, true ); } }; - QSharedPointer subscriptions( new DDPMethodRequest( "subscriptions/get", {}, [=]( QJsonObject pResponse, MeteorDDP * pDdpApi){ - subscriptionSuccess(pResponse, pDdpApi); + QSharedPointer subscriptions( new DDPMethodRequest( "subscriptions/get", {}, [ = ]( QJsonObject pResponse, MeteorDDP * pDdpApi ) { + subscriptionSuccess( pResponse, pDdpApi ); QSharedPointer rooms( new DDPMethodRequest( "rooms/get", {}, subscriptionSuccess ) ); mServer->sendDdprequest( rooms ); } ) ); @@ -116,12 +123,13 @@ void RocketChatChannelService::loadJoinedChannelsFromDb() { QList roomsList = mStorage->getChannels(); - if(Q_LIKELY(!roomsList.isEmpty())){ + if ( Q_LIKELY( !roomsList.isEmpty() ) ) { QVector> channels; foreach ( QVariantHash roomHash , roomsList ) { QSharedPointer channelPointer = createChannelObject( roomHash["id"].toString(), roomHash["name"].toString(), roomHash["type"].toString() ); - if(!channelPointer.isNull()){ + + if ( !channelPointer.isNull() ) { channelPointer->setMuted( roomHash["list"].toStringList() ); channelPointer->setArchived( roomHash["archived"].toBool() ); channelPointer->setReadOnly( roomHash["readOnly"].toBool() ); @@ -151,26 +159,32 @@ void RocketChatChannelService::persistChannel( QSharedPointer */ void RocketChatChannelService::loadUsersOfChannel( QSharedPointer pChannel ) { - if(!pChannel.isNull()){ + if ( !pChannel.isNull() ) { QString channelId = pChannel->getRoomId(); QJsonArray params = {channelId, true}; QSharedPointer request( new DDPMethodRequest( "getUsersOfRoom", params ) ); std::function success = [ = ]( QJsonObject data, MeteorDDP * ddp ) { Q_UNUSED( ddp ); - if ( Q_LIKELY(data.contains( "result" )) ) { + if ( Q_LIKELY( data.contains( "result" ) ) ) { QJsonObject result = data["result"].toObject(); - if ( Q_LIKELY(result.contains( "records" ) && result["records"].isArray()) ) { + if ( Q_LIKELY( result.contains( "records" ) && result["records"].isArray() ) ) { QJsonArray records = result["records"].toArray(); QVector> userList; //crate new user objects and add them to the channel for ( auto current : records ) { - QJsonObject userObject = current.toObject(); - QString name =userObject["username"].toString(); - QSharedPointer user( new RocketChatUser( name ) ); - userList.append( user ); + if ( current.type() == QJsonValue::Object ) { + QJsonObject userObject = current.toObject(); + QString name = userObject["username"].toString(); + QSharedPointer user( new RocketChatUser( name ) ); + userList.append( user ); + }else if(current.type() == QJsonValue::String){ + QString name = current.toString(); + QSharedPointer user( new RocketChatUser( name ) ); + userList.append( user ); + } } emit usersLoaded( channelId, userList ); @@ -182,56 +196,59 @@ void RocketChatChannelService::loadUsersOfChannel( QSharedPointer pChannel) +void RocketChatChannelService::subscribeChannel( QSharedPointer pChannel ) { - if(!pChannel.isNull()){ + if ( !pChannel.isNull() ) { QString roomId = pChannel->getRoomId(); QSharedPointer subscription( new RocketChatSubscribeChannelRequest( pChannel->getRoomId() ) ); mServer->sendDdprequest( subscription ); } } -void RocketChatChannelService::loadMissedMessages(QSharedPointer pChannel) +void RocketChatChannelService::loadMissedMessages( QSharedPointer pChannel ) { -// auto messageRepo = pChannel->getMessageRepo(); -// if(messageRepo != nullptr){ -// auto msgPrev = messageRepo->get(messageRepo->size()-2); -// auto msgLast = messageRepo->get(messageRepo->size()-1); -// qint64 msgPrevTime = msgPrev->getTimestamp(); -// qint64 msgLastTime = msgLast->getTimestamp(); - -// std::function > *messages )> success = -// [ = ]( QMultiMap > *messages ) { -// auto messageList = messages->values( pChannelId ); -// qDebug() << "load history from gap " << messageList.size(); -// QList> newmessages = mChannels->get( pChannelId )->addMessages( messageList ); -// mMessageService->persistMessages( messageList ); -// mServer->newMessageListForGui( pChannelId, newmessages ); -// delete messages; -// }; - -// QSharedPointer pRequest = new QSharedPointer(new LoadHistoryServiceRequest); -// pRequest->setEnd(msgLastTime); -// pRequest->setStart(msgPrevTime); -// pRequest->setLimit(400); -// pRequest->setSuccess(success); -// mMessageService->loadHistoryFromServer(pRequest); -// } + // auto messageRepo = pChannel->getMessageRepo(); + // if(messageRepo != nullptr){ + // auto msgPrev = messageRepo->get(messageRepo->size()-2); + // auto msgLast = messageRepo->get(messageRepo->size()-1); + // qint64 msgPrevTime = msgPrev->getTimestamp(); + // qint64 msgLastTime = msgLast->getTimestamp(); + + // std::function > *messages )> success = + // [ = ]( QMultiMap > *messages ) { + // auto messageList = messages->values( pChannelId ); + // qDebug() << "load history from gap " << messageList.size(); + // QList> newmessages = mChannels->get( pChannelId )->addMessages( messageList ); + // mMessageService->persistMessages( messageList ); + // mServer->newMessageListForGui( pChannelId, newmessages ); + // delete messages; + // }; + + // QSharedPointer pRequest = new QSharedPointer(new LoadHistoryServiceRequest); + // pRequest->setEnd(msgLastTime); + // pRequest->setStart(msgPrevTime); + // pRequest->setLimit(400); + // pRequest->setSuccess(success); + // mMessageService->loadHistoryFromServer(pRequest); + // } } -void RocketChatChannelService::fillChannelWithMessages(QSharedPointer pChannel) +void RocketChatChannelService::fillChannelWithMessages( QSharedPointer pChannel ) { - if(!pChannel.isNull()){ + if ( !pChannel.isNull() ) { QString roomId = pChannel->getRoomId(); - auto messages = mStorage->getMessagesByRid(roomId); + auto messages = mStorage->getMessagesByRid( roomId ); MessageList list; - for(auto currentMessage : messages){ - auto newMessage = mMessageService->parseMessage(currentMessage,false); - if(Q_LIKELY(!newMessage.isNull())){ - list.append(newMessage); + + for ( auto currentMessage : messages ) { + auto newMessage = mMessageService->parseMessage( currentMessage, false ); + + if ( Q_LIKELY( !newMessage.isNull() ) ) { + list.append( newMessage ); } } - pChannel->addMessages(list); + + pChannel->addMessages( list ); } } @@ -246,7 +263,7 @@ ChannelRepository *RocketChatChannelService::getChannels() const return mChannels; } -void RocketChatChannelService::setChannels(ChannelRepository *pChannels) +void RocketChatChannelService::setChannels( ChannelRepository *pChannels ) { mChannels = pChannels; } @@ -255,19 +272,20 @@ void RocketChatChannelService::openPrivateChannelWith( QString pUsername ) QJsonArray params = {pUsername}; QSharedPointer request( new DDPMethodRequest( "createDirectMessage", params ) ); std::function success = [ = ]( QJsonObject pResponse, MeteorDDP * pDdp ) { - if ( Q_LIKELY(pResponse.contains( "result" )) ) { + if ( Q_LIKELY( pResponse.contains( "result" ) ) ) { QJsonObject result = pResponse["result"].toObject(); - if ( Q_LIKELY(result.contains( "rid" )) ) { + if ( Q_LIKELY( result.contains( "rid" ) ) ) { QString rid = result["rid"].toString(); QSharedPointer subRoom( new DDPSubscriptionRequest( "room", {"d" + pUsername} ) ); QSharedPointer subMessages( new RocketChatSubscribeChannelRequest( rid ) ); QSharedPointer channel = createChannelObject( rid, pUsername, "d" ); - if(!channel.isNull()){ + + if ( !channel.isNull() ) { emit channelsLoaded( {channel}, true ); pDdp->sendRequest( subRoom ); pDdp->sendRequest( subMessages ); - emit directChannelReady(rid); + emit directChannelReady( rid ); } } }