Commit 3d2622c9 authored by scuq's avatar scuq

basic network disconnect/connect error handling

parent ea2b8e19
......@@ -3,8 +3,10 @@
ImSession::ImSession(QObject *parent, account *account) : QObject(parent)
{
qInfo() << "ImSession created";
this->setNetworkConnection(true);
this->setNetworkConnection(false);
this->m_configured = false;
this->m_connectionLostCounter = 0;
this->m_connectionDownCounter = 0;
this->m_authenticated = false;
this->m_authenticate_processed = false;
this->m_rawUserProperties = QJsonDocument();
......@@ -80,8 +82,8 @@ void ImSession::authenticateWs()
void ImSession::requestUserList()
{
if (this->getNetworkConnection()) {
qDebug() << QString("%1: refreshing status of roster items.").arg(this->metaObject()->className());
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
qDebug() << QString("%1: refreshing status of roster items, networkConnection %2").arg(this->metaObject()->className(),QString::number(this->getNetworkConnection()));
QUrl url ( this->m_account->getServer() + "/api/v4/users" );
......@@ -98,10 +100,30 @@ void ImSession::requestUserList()
}
void ImSession::requestRemoteSystemPing()
{
qDebug() << QString("%1: request remote system ping, networkConnection %2").arg(this->metaObject()->className(),QString::number(this->getNetworkConnection()));
QUrl url ( this->m_account->getServer() + "/api/v4/system/ping" );
QNetworkRequest req ( url );
req.setRawHeader("Content-Type", "application/json");
req.setRawHeader("X-Requested-With", "XMLHttpRequest");
QNetworkReply *reply = m_WebCtrl.get(req);
netReplies[reply] = "mmapi::requestRemoteSystemPing";
}
void ImSession::requestUnreadCount()
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
qDebug() << QString("%1: refreshing unread.").arg(this->metaObject()->className());
QMapIterator<QString, ImContact*> cntcts(this->iMContacts);
......@@ -128,7 +150,7 @@ void ImSession::requestUnreadCount()
void ImSession::requestUserStatus(QString userid)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/users/%1/status").arg(userid) );
......@@ -147,7 +169,7 @@ void ImSession::requestUserStatus(QString userid)
void ImSession::setRemoteSelfStatus(ImContact::presenceStatus status)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/users/%1/status").arg(this->m_account->getUserid()) );
......@@ -172,7 +194,7 @@ void ImSession::setRemoteSelfStatus(ImContact::presenceStatus status)
void ImSession::getRemoteTeams()
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/users/%1/teams").arg(this->m_account->getUserid()) );
......@@ -192,7 +214,7 @@ void ImSession::getRemoteTeams()
void ImSession::getChannelsForUser()
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/users/%1/teams/%2/channels").arg(this->m_account->getUserid(), this->m_account->getTeamsIds().at(0)) );
QNetworkRequest req ( url );
......@@ -210,7 +232,7 @@ void ImSession::getChannelsForUser()
void ImSession::getChannelPosts(QString channelid)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/channels/%1/posts?page=0&per_page=60").arg( channelid ) );
......@@ -230,7 +252,7 @@ void ImSession::getChannelPosts(QString channelid)
void ImSession::newChannelPost(QString channelid, QString message)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/posts").arg( channelid ) );
......@@ -256,7 +278,7 @@ void ImSession::newChannelPost(QString channelid, QString message)
void ImSession::requestRemoteViewChannel(QString channelid)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/channels/members/%1/view").arg( this->m_account->getUserid() ) );
......@@ -277,7 +299,7 @@ void ImSession::requestRemoteViewChannel(QString channelid)
void ImSession::getRemoteFile(QString fileid, bool preview)
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer() + QString("/api/v4/files/%1/preview").arg( fileid ) );
......@@ -309,7 +331,7 @@ bool ImSession::isAuthenticated()
void ImSession::openWebsocket()
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && this->isAuthenticated() ) {
QUrl url ( this->m_account->getServer().replace("https://","wss://") + QString("/api/v4/websocket"));
qDebug() << url;
this->m_webSocket.open(QUrl(url));
......@@ -412,6 +434,14 @@ void ImSession::setupSignals()
this, SLOT (slOnReturned())
);
connect( this, SIGNAL (siOnConnected()),
this, SLOT (slOnConnected())
);
connect( this, SIGNAL (siOnDisconnected()),
this, SLOT (slOnDisconnected())
);
connect( &this->m_webSocket, SIGNAL (connected() ),
this, SLOT (slOnWebsocketConnected() )
);
......@@ -426,10 +456,12 @@ void ImSession::setupSignals()
connect( &this->m_webSocket, QOverload<const QList<QSslError>&>::of(&QWebSocket::sslErrors),
this, &ImSession::slOnWebsocketSslError );
}
bool ImSession::getNetworkConnection() const
{
if (m_networkConnection == false) {
qDebug() << QString("%1: connection to network or server lost, supressing request.").arg(this->metaObject()->className());
}
......@@ -438,7 +470,18 @@ bool ImSession::getNetworkConnection() const
void ImSession::setNetworkConnection(bool networkConnection)
{
m_networkConnection = networkConnection;
if ( (m_networkConnection == true) && (networkConnection == false)) {
emit (siOnDisconnected());
}
if ( (m_networkConnection == false) && (networkConnection == true)) {
emit (siOnConnected());
}
m_networkConnection = networkConnection;
}
qint64 ImSession::getSelfStatusRefreshInterval() const
......@@ -462,19 +505,19 @@ void ImSession::setupTimers()
this->m_statusRefreshTimer = new QTimer(this);
this->m_unreadRefreshTimer = new QTimer(this);
this->m_NetworkRefreshTimer = new QTimer(this);
connect( this->m_statusRefreshTimer, SIGNAL (timeout()),
this, SLOT (slOnTimeoutTimerStatusRefresh())
);
connect( this->m_unreadRefreshTimer, SIGNAL (timeout()),
this, SLOT (slOnTimeoutTimerUnreadRefresh())
connect( this->m_NetworkRefreshTimer, SIGNAL (timeout()),
this, SLOT (slOnTimeoutTimerNetworkRefresh())
);
this->m_statusRefreshTimer->start((int)this->m_statusRefreshInterval);
//this->m_unreadRefreshTimer->start(this->m_unreadRefreshInterval);
this->m_NetworkRefreshTimer->start((int)this->m_networkRefreshInterval);
this->m_selfStatusRefreshTimer = new QTimer(this);
......@@ -605,16 +648,34 @@ void ImSession::parseNetworkResponse(QNetworkReply *pReply)
if ( pReply->error() == QNetworkReply::NoError ) {
if (callingFuncName == "mmapi::authenticate") {
this->setAuthtoken(pReply->rawHeader("Token"));
emit siMmAuthenticationSuccessful( QJsonDocument::fromJson(pReply->readAll()) );
if (this->getAuthtoken().length() > 0) {
emit siMmAuthenticationSuccessful( QJsonDocument::fromJson(pReply->readAll()) );
}
}
if (callingFuncName == "mmapi::requestUserList") {
this->m_connectionDownCounter = 0;
emit siReplyUserListReceived( QJsonDocument::fromJson(pReply->readAll()) );
}
if (callingFuncName == "mmapi::requestUserStatus") {
//bug needs fixing
emit siUserStatusReceived( QJsonDocument::fromJson(pReply->readAll()) );
}
if (callingFuncName == "mmapi::requestRemoteSystemPing") {
QJsonObject ping_data = QJsonDocument::fromJson(pReply->readAll()).object();
if (ping_data.keys().contains("status")) {
if (ping_data["status"].toString() == "OK") {
this->setNetworkConnection(true);
} else {
this->setNetworkConnection(false);
}
} else {
this->setNetworkConnection(false);
}
}
if (callingFuncName == "mmapi::setSelfStatus") {
qDebug() << "getRemoteTeams: " << pReply->readAll();
}
......@@ -672,6 +733,10 @@ void ImSession::parseNetworkResponse(QNetworkReply *pReply)
if (callingFuncName == "mmapi::requestUserStatus") {
qWarning() << pReply->readAll();
}
if (callingFuncName == "mmapi::requestRemoteSystemPing") {
this->setNetworkConnection(false);
//qWarning() << pReply->readAll();
}
if (callingFuncName == "mmapi::getRemoteTeams") {
qWarning() << pReply->readAll();
}
......@@ -883,15 +948,17 @@ void ImSession::slOnTimeoutTimerStatusRefresh()
this->requestUserList();
}
void ImSession::slOnTimeoutTimerUnreadRefresh()
void ImSession::slOnTimeoutTimerNetworkRefresh()
{
this->requestUnreadCount();
this->requestRemoteSystemPing();
}
void ImSession::slOnTimeoutTimerSelfStatusRefresh()
{
if (this->getNetworkConnection()) {
if ( (this->getNetworkConnection()) && (this->isAuthenticated()) ) {
if (this->m_suppressSelfKeepOnline == false) {
qDebug() << QString("%1: refreshing my status.").arg(this->metaObject()->className());
this->setCurrentStatus(ImContact::presenceStatus::online);
......@@ -914,6 +981,7 @@ void ImSession::slOnWebsocketConnected()
void ImSession::slOnWebsocketDisconnected()
{
qDebug() << "slOnWebsocketDisconnected";
emit( siOnDisconnected() );
}
void ImSession::slOnWebsocketError(QAbstractSocket::SocketError error)
......@@ -1020,9 +1088,21 @@ void ImSession::slNetworkReplyTimeout(QString url)
{
if (url.endsWith("/api/v4/users/login")) {
this->setNetworkConnection(false);
this->m_authenticate_processed = true;
emit siMmServerConnectionFail( QString("Server connection timeout requesting %1").arg(url) );
//this->setNetworkConnection(false);
//this->m_authenticate_processed = true;
//emit siMmServerConnectionFail( QString("Server connection timeout requesting %1").arg(url) );
emit ( siOnDisconnected() );
}
}
void ImSession::slOnConnected()
{
qDebug() << "slOnConnected";
this->authenticate();
}
void ImSession::slOnDisconnected()
{
qDebug() << "slOnDisconnected";
}
......@@ -34,6 +34,7 @@ public:
void authenticate();
void authenticateWs();
void requestUserList();
void requestRemoteSystemPing();
void requestUnreadCount();
void requestUserStatus(QString userid);
void setRemoteSelfStatus(ImContact::presenceStatus status);
......@@ -80,12 +81,14 @@ private:
bool m_authenticate_processed;
bool m_networkConnection;
QMap<QString, ImContact*> iMContacts;
qint64 m_unreadRefreshInterval = 2000;
QTimer *m_unreadRefreshTimer;
qint64 m_networkRefreshInterval = 2000;
QTimer *m_NetworkRefreshTimer;
qint64 m_statusRefreshInterval = 5000;
QTimer *m_statusRefreshTimer;
qint64 m_selfStatusRefreshInterval = 30000;
QTimer *m_selfStatusRefreshTimer;
int m_connectionLostCounter;
int m_connectionDownCounter;
bool m_suppressSelfKeepOnline = false;
IdleDetector *idled;
ImContact::presenceStatus m_currentStatus;
......@@ -113,6 +116,9 @@ signals:
void siMessageReceived(QDateTime timestamp, QString message, bool hasAttachment, bool hasImage, QMap<QString, QVariant> imageProperties, QString channelid, QString sendername, bool historic, int msgcounthint, int longestsendernamelen);
void siMessageReceived(QString channelid, QString senderid);
void siGlobalSettingsChanged(QMap<QString, QVariant>);
void siOnDisconnected();
void siOnConnected();
......@@ -125,7 +131,7 @@ private slots:
void slReplyUserStatusReceived(const QJsonDocument &replyJson);
void slOnMmAuthenticationFail(const QJsonDocument &replyJson);
void slOnTimeoutTimerStatusRefresh();
void slOnTimeoutTimerUnreadRefresh();
void slOnTimeoutTimerNetworkRefresh();
void slOnTimeoutTimerSelfStatusRefresh();
void slOnWebsocketConnected();
void slOnWebsocketDisconnected();
......@@ -137,6 +143,8 @@ private slots:
void slOnReturned();
void slGlobalSettingsChanged(QMap<QString, QVariant> globalSettings);
void slNetworkReplyTimeout(QString url);
void slOnConnected();
void slOnDisconnected();
};
#endif // IMSESSION_H
......@@ -120,6 +120,8 @@ void qmMainWindow::loadConfig()
ImSession *_session = new ImSession(this, _account);
connect( _session, SIGNAL(siOnDisconnected()), this, SLOT(slOnDisconnected()) );
connect( this->m_mp, SIGNAL(siGlobalSettingsChanged(QMap<QString, QVariant>)), _session, SLOT(slGlobalSettingsChanged(QMap<QString, QVariant>)) );
this->m_mp->apply();
......@@ -132,7 +134,7 @@ void qmMainWindow::loadConfig()
);
_session->authenticate();
//_session->authenticate();
qDebug() << "is_auth" << _session->isAuthenticated();
......@@ -257,7 +259,7 @@ accntviews.value()->setModel(fsModel);
this->labelMyStatus->setCurrentStatus(ImContact::presenceStatus::online);
this->labelMyStatus->setCurrentStatus(ImContact::presenceStatus::unknown);
selfLayout->addWidget( labelMyStatus );
selfLayout->addWidget( pushButtonMe );
......@@ -336,6 +338,16 @@ void qmMainWindow::setCloseToTray(bool value)
closeToTray = value;
}
bool qmMainWindow::getNetworkConnection() const
{
return networkConnection;
}
void qmMainWindow::setNetworkConnection(bool value)
{
networkConnection = value;
}
void qmMainWindow::setupTrayIcon()
......@@ -372,6 +384,7 @@ void qmMainWindow::on_actionPreferences_triggered()
void qmMainWindow::slUpdateRecommended(bool updaterecommended)
{
if (updaterecommended == true) {
if (this->updateQuestionShown == false) {
......@@ -379,10 +392,12 @@ void qmMainWindow::slUpdateRecommended(bool updaterecommended)
QString _latestversion = uc->getLatestVersionName();
QMessageBox::StandardButton reply;
if (_latestversion.length() >= 1) {
reply = QMessageBox::question(this, appname,
"New version ("+_latestversion+") available, do you want to update?",
QMessageBox::Yes|QMessageBox::No);
}
updaterecommended = false;
......@@ -417,13 +432,17 @@ void qmMainWindow::on_action_Close_triggered()
void qmMainWindow::slOnMmAuthenticationFail(const QJsonDocument &replyJson)
{
QString _message = QJsonValue(replyJson.object()).toObject()["message"].toString();
QMessageBox::warning(this, appname, _message, QMessageBox::Ok);
if (_message.length() >= 1) {
QMessageBox::warning(this, appname, _message, QMessageBox::Ok);
}
}
void qmMainWindow::slMmServerConnectionFail(QString message)
{
QString _message = message;
QMessageBox::warning(this, appname, _message, QMessageBox::Ok);
if (_message.length() >= 1) {
QMessageBox::warning(this, appname, _message, QMessageBox::Ok);
}
}
......@@ -440,6 +459,7 @@ void qmMainWindow::slOnPushButtonMeClicked(QString accountname)
void qmMainWindow::slOnRosterClicked(const QModelIndex &index)
{
QTableView *tv = qobject_cast<QTableView *>( sender() );
RosterSortFilterProxyModel *sfm = qobject_cast< RosterSortFilterProxyModel *>( tv->model() );
RosterModel *rm = qobject_cast< RosterModel *>(sfm->sourceModel());
......@@ -465,41 +485,35 @@ void qmMainWindow::slOnRosterClicked(const QModelIndex &index)
}
if ( !( chatDialogs.keys().contains(_contact->getId()) ) ) {
dialogChat *diaChat = new dialogChat(0,rm->getSession(), this->m_mp, _contact, rm->getSession()->getAccount(), this->m_chatSettings);
connect( this->m_mp, SIGNAL(siChatSettingsChanged(QMap<QString, QVariant>)), diaChat, SLOT(slChatSettingsChanged(QMap<QString, QVariant>)) );
connect( this->m_mp, SIGNAL(siGlobalSettingsChanged(QMap<QString, QVariant>)), diaChat, SLOT(slGlobalSettingsChanged(QMap<QString, QVariant>)) );
this->m_mp->apply();
connect(diaChat, SIGNAL(siOnRead(QString)), rm, SLOT(slOnRead(QString)));
Qt::WindowFlags flags = Qt::Dialog | Qt::WindowSystemMenuHint
| Qt::WindowMinimizeButtonHint
| Qt::WindowCloseButtonHint;
diaChat->setWindowFlags(flags);
if ( !( chatDialogs.keys().contains(_contact->getId()) ) ) {
dialogChat *diaChat = new dialogChat(0,rm->getSession(), this->m_mp, _contact, rm->getSession()->getAccount(), this->m_chatSettings);
diaChat->show();
connect( this->m_mp, SIGNAL(siChatSettingsChanged(QMap<QString, QVariant>)), diaChat, SLOT(slChatSettingsChanged(QMap<QString, QVariant>)) );
connect( this->m_mp, SIGNAL(siGlobalSettingsChanged(QMap<QString, QVariant>)), diaChat, SLOT(slGlobalSettingsChanged(QMap<QString, QVariant>)) );
this->m_mp->apply();
chatDialogs.insert(_contact->getId(), diaChat);
} else {
chatDialogs.value(_contact->getId())->show();
}
connect(diaChat, SIGNAL(siOnRead(QString)), rm, SLOT(slOnRead(QString)));
Qt::WindowFlags flags = Qt::Dialog | Qt::WindowSystemMenuHint
| Qt::WindowMinimizeButtonHint
| Qt::WindowCloseButtonHint;
diaChat->setWindowFlags(flags);
diaChat->show();
chatDialogs.insert(_contact->getId(), diaChat);
} else {
chatDialogs.value(_contact->getId())->show();
}
......@@ -528,6 +542,18 @@ void qmMainWindow::slRosterLoaded()
}
}
void qmMainWindow::slOnDisconnected()
{
this->labelMyStatus->setCurrentStatus(ImContact::presenceStatus::offline);
this->setNetworkConnection(false);
}
void qmMainWindow::slOnConnected()
{
this->labelMyStatus->setCurrentStatus(ImContact::presenceStatus::unknown);
this->setNetworkConnection(true);
}
void qmMainWindow::slExit()
{
qApp->quit();
......
......@@ -43,6 +43,9 @@ public:
~qmMainWindow();
bool getNetworkConnection() const;
void setNetworkConnection(bool value);
private:
void printDebugSslLib();
void setupDialogs();
......@@ -76,6 +79,7 @@ private:
QMap<QString, QVariant> m_chatSettings;
bool updateQuestionShown;
bool closeToTray;
bool networkConnection;
void setupUpdateCheck();
......@@ -108,6 +112,9 @@ private slots:
void slRosterLoaded();
void slOnDisconnected();
void slOnConnected();
void slExit();
void slShow();
void slUnreadsPending();
......
......@@ -163,6 +163,32 @@ void RosterItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
break;
}
case ImContact::presenceStatus::unknown:
{
if (_model->getChannelShape() == "Ellipse" ) {
painter->setBrush(QBrush( QColor(Qt::blue) ));
painter->drawEllipse(QPoint(myOption.rect.left()+10, myOption.rect.center().ry()), channelBaseSize, channelBaseSize);
}
if (_model->getChannelShape() == "Rectangle" ) {
painter->setBrush(QBrush( QColor(Qt::blue) ));
QRectF rect = QRectF(myOption.rect.left()+leftOffset, myOption.rect.top()+5, channelBaseSize*2, channelBaseSize*2);
painter->drawRect(rect);
}
if (_model->getChannelShape() == "Triangle" ) {
QRectF rect = QRectF(myOption.rect.left()+leftOffset, myOption.rect.top()+5, channelBaseSize*2, channelBaseSize*2);
QPainterPath path;
path.moveTo(rect.left() + (rect.width() / 2), rect.top());
path.lineTo(rect.bottomLeft());
path.lineTo(rect.bottomRight());
path.lineTo(rect.left() + (rect.width() / 2), rect.top());
painter->fillPath(path, QBrush( QColor(Qt::blue) ));
}
break;
}
default:
{
painter->setBrush(Qt::blue);
......
......@@ -6,6 +6,8 @@ RosterModel::RosterModel(QObject* parent, ImSession *session) :
QScreen *srn = QApplication::screens().at(0);
this->dotsPerInch = (qreal)srn->logicalDotsPerInch();
selfLastStatus = "";
this->session = session;
this->setupSignals();
......@@ -19,12 +21,28 @@ RosterModel::RosterModel(QObject* parent, ImSession *session) :
this->m_unreadBlinkTimer->start((int)this->m_unreadBlinkInterval);
}
void RosterModel::loadIMContacts()
{
}
void RosterModel::slOnDisconnected()
{
QMapIterator<QString, ImContact*> cntcts(this->iMContacts);
while (cntcts.hasNext()) {
cntcts.next();
if (cntcts.value()->getIsMuc() == false) {
cntcts.value()->setPresencestatus(ImContact::presenceStatus::unknown);
} else {
cntcts.value()->setPresencestatus(ImContact::presenceStatus::muc);
}
}
}