/******************************************************************************************** * * * 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 <QGuiApplication> #include "rocketchat.h" #include "utils.h" #include "segfaulthandler.h" #include <QDesktopServices> #include <QClipboard> #include "CustomModels/models.h" #ifdef Q_OS_IOS #endif #ifdef Q_OS_ANDROID #include "android/androidcheckpermissions.h" #include "android/androidbadges.h" #endif #ifdef Q_OS_WINRT #include "WinRt/keypadhelper.h" #include <QInputMethod> #endif #include <QCoreApplication> /** * @brief RocketChat::RocketChat * @param restApi * @param ddp */ RocketChat::RocketChat( QGuiApplication *app ) { #ifdef Q_OS_IOS //UrlHandler *handler = new UrlHandler; // QDesktopServices::setUrlHandler("file",handler,"files"); // connect(handler,&UrlHandler::openFile,this,&RocketChat::openIosFile); #endif this->mApp = app; connect( app, &QGuiApplication::applicationStateChanged, this, &RocketChat::onApplicationStateChanged, Qt::UniqueConnection ); this->mStorage = PersistanceLayer::instance(); #ifdef Q_OS_WINRT //KeypadHelper *helper = new KeypadHelper(); //helper->showKeypad(); mInputMethod = QGuiApplication::inputMethod(); connect( mInputMethod, &QInputMethod::visibleChanged, this, &RocketChat::onKeyboardVisiblityChanged ); #endif #ifdef Q_OS_ANDROID mAndroidStatusBarColor = new AndroidStatusBarColor; #endif qRegisterMetaType<ConnectionState>( "ConnectionState" ); qRegisterMetaType<Qt::ApplicationState>( "Qt::ApplicationState" ); } RocketChat::~RocketChat() { mServerThread.quit(); mStorageThread.quit(); mServerThread.wait(); mStorageThread.wait(); } void RocketChat::joinChannel( const QString &pServerId, const QString &pChannelId ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "joinChannel", Q_ARG( QString, pChannelId ) ); if ( !mFileToShare.isEmpty() ) { uploadSharedFileToChannel( pChannelId ); } } } void RocketChat::joinChannelByNameAndType( const QString &pServerId, const QString &pChannelName, const QString &pType ) { Q_UNUSED( pServerId ) if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "joinChannelByNameAndType", Q_ARG( QString, pChannelName ), Q_ARG( QString, pType ) ); } } void RocketChat::login( const QString &pServerId, const QString &pUsername, const QString &pPassword ) { Q_UNUSED( pServerId ); if ( pUsername != mStorage->getUserName() ) { mStorage->wipeDb(); } qDebug() << "login thread id: " << QThread::currentThreadId(); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "login", Q_ARG( QString, pUsername ), Q_ARG( QString, pPassword ) ); } } void RocketChat::loginWithSamlToken( const QString &pToken ) { if ( !pToken.isEmpty() ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "loginWtihSamlToken", Q_ARG( QString, pToken ) ); } } } void RocketChat::loginWithMethod( const QString &method, const QString &payload ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "loginWithMethod", Q_ARG( QString, method ), Q_ARG( QString, payload ) ); } } void RocketChat::loadRecentHistory( const QString &pChannelId ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "loadRecentHistory", Q_ARG( QString, pChannelId ) ); } } void RocketChat::loadHistoryTill( const QString &pChannelId, qint64 pTs ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "loadHistoryTill", Q_ARG( QString, pChannelId ), Q_ARG( qint64, pTs ) ); } } bool RocketChat::isServerReady() { return mServerStatus; } bool RocketChat::isStorageReady() { return mStorageStatus; } void RocketChat::forceVirtualKeyboardShow() { QGuiApplication::inputMethod()->setVisible( true ); } void RocketChat::forceVirtualKeyboardHide() { QGuiApplication::inputMethod()->setVisible( false ); } void RocketChat::setStatusBarColor( const QString &pColor ) { #ifdef Q_OS_ANDROID mAndroidStatusBarColor->setStatusBarColor( pColor ); #else Q_UNUSED( pColor ) #endif } QVariantMap RocketChat::checkForChannelSwitchRequest() { return mChannelSwitchRequest; } void RocketChat::resetChannelSwitchRequest() { mChannelSwitchRequest.clear(); } void RocketChat::channelViewReady() { #ifdef Q_OS_IOS emit checkForLinkedFile(); #endif } bool RocketChat::customEmojisReady() { return mEmojisReady; } void RocketChat::checkLoggedIn() { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "requestIsLoggedIn" ); } } void RocketChat::getChannelDetails( const QString &pServerId, const QString &pChannelName ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "requestGetChannelDetails", Q_ARG( QString, pChannelName ) ); } } void RocketChat::createVideoCall( const QString &pServerId, const QString &pChannelId ) { Q_UNUSED( pServerId ); QMetaObject::invokeMethod( mServerMap.first(), "createVideoCall", Q_ARG( QString, pChannelId ) ); } void RocketChat::copyToClipboard( const QString &text ) { QGuiApplication::clipboard()->setText( text ); } void RocketChat::blockUser( const QString &pChannelId ) { QMetaObject::invokeMethod( mServerMap.first(), "blockUser", Q_ARG( QString, pChannelId ) ); } void RocketChat::unBlockUser( const QString &pChannelId ) { QMetaObject::invokeMethod( mServerMap.first(), "unBlockUser", Q_ARG( QString, pChannelId ) ); } void RocketChat::leaveChannel( const QString &pChannelId ) { QMetaObject::invokeMethod( mServerMap.first(), "leaveChannel", Q_ARG( QString, pChannelId ) ); } void RocketChat::hideChannel( const QString &pChannelId ) { QMetaObject::invokeMethod( mServerMap.first(), "hideChannel", Q_ARG( QString, pChannelId ) ); } void RocketChat::reportAbusiveContent( const QString &pMessageId, const QString &pAuthor ) { QMetaObject::invokeMethod( mServerMap.first(), "reportAbusiveContent", Q_ARG( QString, pMessageId ), Q_ARG( QString, pAuthor ) ); } void RocketChat::end() { QCoreApplication::quit(); } void RocketChat::searchMessage( const QString &pTerm, const QString &pChannelId ) { QMetaObject::invokeMethod( mServerMap.first(), "searchMessage", Q_ARG( QString, pTerm ), Q_ARG( QString, pChannelId ) ); } void RocketChat::searchRoom( const QString &pTerm ) { QMetaObject::invokeMethod( mServerMap.first(), "searchRoom", Q_ARG( QString, pTerm ), Q_ARG( QString, "" ) ); } void RocketChat::searchRoomByType( const QString &pTerm, const QString &pType ) { QMetaObject::invokeMethod( mServerMap.first(), "searchRoom", Q_ARG( QString, pTerm ), Q_ARG( QString, pType ) ); } bool RocketChat::newServerByDomain( const QString &domain ) { newServerMutex.lock(); mDdpConnectionEstablished = false; emit offline(); if ( !mServerMap.isEmpty() ) { auto firstServer = mServerMap.first(); mServerMap.remove( firstServer->getServerId() ); auto self = this; connect( firstServer, &RocketChatServerData::destroyed, [ &, self, domain]() { qDebug() << "domain: " << domain; QString baseUrl = domain; QString apiUri = QStringLiteral( "https://" ) + domain + QStringLiteral( "/api/v1" ); Models::resetModels(); RocketChatServerData *server = new RocketChatServerData( domain, baseUrl, apiUri ); registerServer( server ); newServerMutex.unlock(); } ); QMetaObject::invokeMethod( firstServer, "deleteLater" ); } else { QString baseUrl = domain; QString apiUri = QStringLiteral( "https://" ) + domain + QStringLiteral( "/api/v1" ); Models::resetModels(); RocketChatServerData *server = new RocketChatServerData( domain, baseUrl, apiUri ); registerServer( server ); newServerMutex.unlock(); } 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 ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "openPrivateChannelWith", Q_ARG( QString, pUsername ) ); } } void RocketChat::getFileRessource( const QString &pUrl ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "getFileRessource", Q_ARG( QString, pUrl ), Q_ARG( QString, QStringLiteral( "temp" ) ) ); } } void RocketChat::getFileRessource( const QString &pUrl, const QString &pType ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "getFileRessource", Q_ARG( QString, pUrl ), Q_ARG( QString, pType ) ); } } void RocketChat::uploadVideo( const QString &pChannelId, const QString &pPath ) { qDebug() << "video path" << pPath; if ( pPath.length() ) { QStringList split = pPath.split( Utils::getPathPrefix() ); qDebug() << "splitted string" << split; QString realpath; if ( split.count() > 1 ) { realpath = split[1]; } else { realpath = split[0]; } qDebug() << "video path" << realpath; uploadFile( pChannelId, realpath ); } } void RocketChat::uploadFile( const QString &pChannelId, const QString &pPath ) { qDebug() << "upload file called"; mCurrentChannel = pChannelId; openFileNameReady( pPath ); } void RocketChat::addUsersToChannel( const QString &pServerId, const QString &pChannelName, const QString &pUsernames ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QStringList unserList = pUsernames.split( ',' ); QMetaObject::invokeMethod( mServerMap.first(), "addUsersToChannel", Q_ARG( QString, pChannelName ), Q_ARG( QStringList, unserList ) ); } } void RocketChat::sendMessage( const QString &pServerId, const QString &pChannelId, const QString &pMessage ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { RocketChatServerData *server = mServerMap.first(); QMetaObject::invokeMethod( server, "sendMessage", Q_ARG( QString, pChannelId ), Q_ARG( QString, pMessage ) ); } } void RocketChat::openFileDialog( const QString &pChannelId ) { mCurrentChannel = pChannelId; #ifdef Q_OS_ANDROID openAndroidFileDialog( pChannelId ); #endif } void RocketChat::openFileExternally( const QString &pPath ) { #ifdef Q_OS_LINUX Q_UNUSED( pPath ); #endif #ifdef Q_OS_ANDROID Q_UNUSED( pPath ); #endif #ifdef Q_OS_IOS emit openIOSFileDialog( pPath ); #endif } void RocketChat::getSortOrderByCategory( const QString &pServerId, const QString &pType ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "requestChannelSortOrder", Q_ARG( QString, pType ) ); } } bool RocketChat::hasCameraPermission() { int granted = 1; #ifdef Q_OS_ANDROID AndroidCheckPermissions permCheck; if ( !permCheck.hasCameraAccess() ) { granted = 0; } #endif return granted; } QString RocketChat::getCleanString( const QString &pText ) { QString text = Utils::replaceUnicodeEmojis( pText, mServerMap.first()->getEmojiRepo() ); text = Utils::removeUtf8Emojis( text ); return text; } void RocketChat::getAllChannels() { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "requestAllChannels" ); } } void RocketChat::uploadSharedFileToChannel( const QString &pChannelId ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "uploadFile", Q_ARG( QString, pChannelId ), Q_ARG( QString, mFileToShare ) ); mFileToShare.clear(); } } void RocketChat::joinJitsiCall( const QString &pServer, const QString &pChannelIdm, const QString &pMessageId ) { Q_UNUSED( pServer ); Q_UNUSED( pMessageId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "joinJitsiCall", Q_ARG( QString, pChannelIdm ) ); } } //TODO: make async QString RocketChat::getUsername( const QString &pServerId ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { return mServerMap.first()->getUsername(); } else { return ""; } } //TODO: make async QString RocketChat::getPassword( const QString &pServerId ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { return mStorage->getPassword(); } else { return ""; } } void RocketChat::setUsername( const QString &pServerId, const QString &pUsername ) { Q_UNUSED( pServerId ); mStorage->setUserName( pUsername ); } void RocketChat::setPassword( const QString &pServerId, const QString &pPassword ) { Q_UNUSED( pServerId ); mStorage->setPassword( pPassword ); } void RocketChat::setCurrentChannel( const QString &pServerId, const QString &pCurrentChannel, const QString &pChannelName ) { Q_UNUSED( pServerId ); Q_UNUSED( pChannelName ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "setCurrentChannel", Q_ARG( QString, pCurrentChannel ) ); } } QString RocketChat::getNewVideoPath() { return mStorage->getNewVideoPath(); } void RocketChat::setSetting( const QString &pKey, const QString &pValue ) { mStorage->setSetting( pKey, pValue ); } QString RocketChat::getSetting( const QString &pKey ) { return mStorage->getSetting( pKey ); } void RocketChat::callGalleryPicker( const QString &pChannelId ) { #ifdef Q_OS_IOS mCurrentChannel = pChannelId; emit openGallery(); #else Q_UNUSED( pChannelId ) #endif } void RocketChat::createAccount( const QString &serverId, const QString &email, const QString &username, const QString &password ) { Q_UNUSED( serverId ) auto server = mServerMap.first(); server->createAccount( username, email, password ); } void RocketChat::markChannelAsRead( const QString &pChannelId ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "markChannelAsRead", Q_ARG( QString, pChannelId ) ); } } QString RocketChat::getCurrentChannel() { std::tuple<QString, QString> tuple = mStorage->getCurrentChannel(); QJsonObject data = {{QStringLiteral( "id" ), std::get<0>( tuple )}, {QStringLiteral( "name" ), std::get<1>( tuple )}}; QJsonDocument doc( data ); return doc.toJson(); } void RocketChat::resetCurrentChannel() { mStorage->setCurrentChannel( QStringLiteral( "none" ), QStringLiteral( "none" ) ); } void RocketChat::getUserSuggestions( const QString &pTerm, const QString &pExceptions ) { if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "getUserSuggestions", Q_ARG( QString, pTerm ), Q_ARG( QString, pExceptions ) ); } } void RocketChat::getRoomInformation( const QString &pServerId, const QString &pChannelName ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "getRoomInformation", Q_ARG( QString, pChannelName ) ); } } void RocketChat::cancelUpload( const QString &pServerId, const QString &pFileId ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "cancelUpload", Q_ARG( QString, pFileId ) ); } } void RocketChat::logout( const QString &pServerId ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "logout" ); emit loggedOut( pServerId ); } } void RocketChat::createChannel( 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 ) ); } } void RocketChat::createPrivateGroup( const QString &pServerId, const QString &pChannelName, const QStringList &pUsersNames, bool pReadonly ) { Q_UNUSED( pServerId ); if ( mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "createPrivateGroup", Q_ARG( QString, pChannelName ), Q_ARG( QStringList, pUsersNames ), Q_ARG( bool, pReadonly ) ); } } void RocketChat::registerServer( RocketChatServerData *pServer ) { qDebug() << "serverId:" << pServer->getServerId(); qDebug() << "move to thread"; pServer->moveToThread( &mServerThread ); qDebug() << "add server to map"; mServerMap[pServer->getServerId()] = pServer; connect( pServer, &RocketChatServerData::readyToCheckForPendingNotification, this, &RocketChat::onServerSlotsReady, Qt::UniqueConnection ); if ( !mServerThread.isRunning() ) { connect( &mServerThread, &QThread::started, this, &RocketChat::serverReadySlot, Qt::UniqueConnection ); qDebug() << "start thread"; mServerThread.start(); } else { serverReadySlot(); } } void RocketChat::addLoginMethod( const QMap<QString, QVariant> &pMethod ) { Models::getLoginMethodsModel()->addLoginMethod( pMethod ); } void RocketChat::resetLoginMethods() { Models::getLoginMethodsModel()->clear(); } void RocketChat::openIosFile( const QString &fileName ) { mFileToShare = fileName; openShareDialog(); } void RocketChat::openUrl( const QString url ) { if ( !QDesktopServices::openUrl( url ) ) { qDebug() << "Jitsi meet could not be opened"; emit noJitsiMeetAvailable(); } } void RocketChat::registerForPush() { #ifdef Q_OS_ANDROID mNotificationsObject.registerWithService(); #endif #ifdef Q_OS_IOS emit registerForPushIOS(); #endif } void RocketChat::onLogout( const QString &pServerId ) { emit loggedOut( pServerId ); } void RocketChat::onUnreadCountChanged( const QString &pServerId, uint pUnread ) { mUnreadSum[pServerId] = pUnread; qDebug() << "onUnreadCountChanged"; uint number = 0; if ( mServerStatus ) { for ( auto count : mUnreadSum ) { number += count; } qDebug() << "set Unread Badges to:" << number; #ifdef Q_OS_ANDROID AndroidBadges::setNumber( number ); #endif #ifdef Q_OS_IOS emit setBadge( number ); #endif } } void RocketChat::onLoggedIn( const QString &pServerId ) { #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) checkForpendingNotification(); #endif emit loggedIn( pServerId ); } void RocketChat::onChannelSwitchRequest( QSharedPointer<RocketChatChannel> pChannel ) { //TODO: fix bool readonly = pChannel->getReadOnly() && pChannel->getOwnerName() != getUsername( "default" ); emit channelSwitchRequest( "default", pChannel->getRoomId(), pChannel->getName(), pChannel->getType(), readonly ); mChannelSwitchRequest[QStringLiteral( "server" )] = "default"; mChannelSwitchRequest[QStringLiteral( "rid" )] = pChannel->getRoomId(); mChannelSwitchRequest[QStringLiteral( "name" )] = pChannel->getName(); mChannelSwitchRequest[QStringLiteral( "type" )] = pChannel->getName(); mChannelSwitchRequest[QStringLiteral( "ro" )] = readonly; } void RocketChat::serverReadySlot() { qDebug() << "server ready slot"; auto pServer = mServerMap.first(); connect( pServer, &RocketChatServerData::ddpConnected, this, &RocketChat::onDDPConnected, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::loggedIn, this, &RocketChat::onLoggedIn, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::privateChannelCreated, this, &RocketChat::onPrivateChannelCreated, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::customEmojisReceived, this, &RocketChat::onEmojisReady, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::loggedOut, this, &RocketChat::onLogout, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::suggestionsReady, this, &RocketChat::suggestionsReady, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::loginError, this, &RocketChat::loginError, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::fileuploadStarted, this, &RocketChat::fileuploadStarted, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::fileUploadProgressChanged, this, &RocketChat::fileUploadProgressChanged, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::fileUploadFinished, this, &RocketChat::fileUploadFinished, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::error, this, &RocketChat::error, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::fileRessourceProcessed, this, &RocketChat::fileRessourceProcessed, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::channelSwitchRequest, this, &RocketChat::onChannelSwitchRequest, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::onHashLoggedIn, this, &RocketChat::hashLoggedIn, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::registerForPush, this, &RocketChat::registerForPush, Qt::UniqueConnection ); 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 ); connect( &mNetworkConfiguration, &QNetworkConfigurationManager::onlineStateChanged, this, &RocketChat::onOnlineStateChanged, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::newLoginMethod, this, &RocketChat::addLoginMethod, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::resetLoginMethods, this, &RocketChat::resetLoginMethods, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::offlineMode, this, &RocketChat::offlineMode, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::loggingIn, this, &RocketChat::loggingIn, Qt::UniqueConnection ); connect( pServer, &RocketChatServerData::historyReady, this, &RocketChat::historyReady, Qt::UniqueConnection ); QMetaObject::invokeMethod( pServer, "init" ); } void RocketChat::storageReadySlot() { mStorageStatus = true; emit storageReady(); } #ifdef Q_OS_ANDROID //TODO: do this in a clean way void RocketChat::openAndroidFileDialog( QString channelId ) { currentChannel = channelId; if ( mAndroidFileDialog == nullptr ) { mAndroidFileDialog = new AndroidFileDialog(); connect( mAndroidFileDialog, &AndroidFileDialog::existingFileNameReady, this, &RocketChat::openFileNameReady, Qt::UniqueConnection ); bool success = mAndroidFileDialog->provideExistingFileName(); if ( !success ) { qWarning() << "Problem with JNI or sth like that..."; disconnect( mAndroidFileDialog, &AndroidFileDialog::existingFileNameReady, this, &RocketChat::openFileNameReady ); //or just delete fileDialog instead of disconnect mAndroidFileDialog->deleteLater(); mAndroidFileDialog = nullptr; } } } #endif #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) void RocketChat::checkForpendingNotification() { #ifdef Q_OS_ANDROID QAndroidJniObject::callStaticMethod<void>( "com/osalliance/rocketchatMobile/MainActivity", "checkForPendingIntent" ); #endif #ifdef Q_OS_IOS emit checkForpendingNotificationIOS(); #endif } #endif void RocketChat::openFileNameReady( const QString &pFile ) { #ifdef Q_OS_ANDROID mAndroidFileDialog->deleteLater(); mAndroidFileDialog = nullptr; #endif qDebug() << "file to be uploaded " << pFile; if ( pFile == "null" ) { emit error( QStringLiteral( "invalid file information" ) ); } else if ( !pFile.isEmpty() && mServerStatus ) { QMetaObject::invokeMethod( mServerMap.first(), "uploadFile", Q_ARG( QString, mCurrentChannel ), Q_ARG( QString, pFile ) ); } } void RocketChat::onKeyboardVisiblityChanged() { QRectF keyBoardRect = mInputMethod->keyboardRectangle(); float height = floor( keyBoardRect.height() / 2 ) - 5; bool visible = mInputMethod->isVisible(); emit keyboardVisibilityChanged( visible, height ); } void RocketChat::onEmojisReady( const QVariantList &pEmojiList ) { mEmojisReady = true; emit emojisReady( pEmojiList ); } void RocketChat::onServerSlotsReady() { #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) auto firstServer = mServerMap.first(); #endif #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 ); connect( this, &RocketChat::pushMessageReceived, firstServer, &RocketChatServerData::switchChannel, Qt::UniqueConnection ); #endif #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) // checkForpendingNotification(); #endif mServerStatus = true; if ( !mChannelToSwitchTo.isEmpty() && !mChannelToSwitchToType.isEmpty() ) { onExternalChannelSwitchRequest( mChannelToSwitchTo, mChannelToSwitchToType ); } emit serverReady(); } void RocketChat::onExternalChannelSwitchRequest( const QString &pName, const QString &pType ) { if ( mServerStatus ) { auto server = mServerMap.first(); QMetaObject::invokeMethod( server, "switchChannelByName", Q_ARG( QString, pName ), Q_ARG( QString, pType ) ); mChannelToSwitchTo.clear(); mChannelToSwitchToType.clear(); } else { qDebug() << "room name: " << pName; mChannelToSwitchTo = pName; mChannelToSwitchToType.clear(); } } void RocketChat::onDDPConnected( const QString &pServerId ) { mDdpConnectionEstablished = true; emit serverConnected( pServerId ); } void RocketChat::onPrivateChannelCreated( const QString &pServerId, const QString &pRid, const QString &pUsername ) { qDebug() << "sending private channel creation to gui"; emit privateChannelCreated( pServerId, pRid, pUsername ); } void RocketChat::onOnlineStateChanged( bool pOnline ) { qDebug() << "stat changed" << pOnline; connect( &mNetworkConfiguration, &QNetworkConfigurationManager::onlineStateChanged, this, &RocketChat::onOnlineStateChanged, Qt::UniqueConnection ); if ( mServerStatus ) { if ( pOnline ) { for ( const auto &server : mServerMap ) { QMetaObject::invokeMethod( server, "resume" ); } } else { for ( const auto &server : mServerMap ) { QMetaObject::invokeMethod( server, "setConnectionState", Q_ARG( ConnectionState, ConnectionState::OFFLINE ) ); } emit offline(); } } } void RocketChat::onApplicationStateChanged( const Qt::ApplicationState &pState ) { if ( pState == Qt::ApplicationActive && mServerStatus ) { QDateTime date; qDebug() << "application changed to active"; qDebug() << "time: " << date.currentDateTime(); qDebug() << "initialized: " << mInitialized; qDebug() << "networkconfig: " << mNetworkConfiguration.isOnline(); //checks if a networkconnection is available mInitialized = 1; if ( mInitialized && mNetworkConfiguration.isOnline() ) { qDebug() << "network connection active"; for ( const auto server : mServerMap ) { //check if websocket connection is still alive, and if DDP is timedout QMetaObject::invokeMethod( server, "onStateChanged", Q_ARG( Qt::ApplicationState, pState ) ); } } else { mInitialized = 1; } } else if ( ( ( pState == Qt::ApplicationInactive ) || pState == Qt::ApplicationSuspended ) && mServerStatus ) { qDebug() << "away"; if ( mNetworkConfiguration.isOnline() ) { for ( auto server : mServerMap ) { QMetaObject::invokeMethod( server, "setUserPresenceStatus", Q_ARG( int, 2 ) ); QMetaObject::invokeMethod( server, "disconnectFromServer" ); } } } } bool RocketChat::getDdpConnectionEstablished() const { return mDdpConnectionEstablished; }