Commit bc071e8c authored by LNJ's avatar LNJ Committed by GitHub

Fix lag when changing chat (#205)

This also does some clean up and restructuring of the deployment of the
`chatPartner` property to the ClientThread (MessageHandler) and MessageModel.

Before, a thread-safe function of the ClientThread was used, so the mutex of it
blocked the GUI, when the client thread was busy in this moment.
parent 205a246c
......@@ -121,6 +121,8 @@ void ClientThread::run()
// connect slots
connect(this, &ClientThread::sendMessageRequested,
messageSessionHandler->getMessageHandler(), &MessageHandler::sendMessage);
connect(this, &ClientThread::chatPartnerChanged,
messageSessionHandler->getMessageHandler(), &MessageHandler::setChatPartner);
connect(this, &ClientThread::addContactRequested,
rosterManager, &RosterManager::addContact);
connect(this, &ClientThread::removeContactRequested,
......@@ -147,12 +149,8 @@ void ClientThread::setCredentials(Credentials creds)
client->setPassword(creds.password.toStdString());
client->unbindResource(client->resource());
client->bindResource(creds.jidResource.toStdString());
}
void ClientThread::setCurrentChatPartner(QString *jid)
{
QMutexLocker locker(&mutex); // => locking mutex in this function
messageSessionHandler->getMessageHandler()->setCurrentChatPartner(jid);
emit messageModel->ownJidChanged(creds.jid);
}
void ClientThread::setConnectionState(ConnectionState state)
......
......@@ -124,11 +124,6 @@ public:
*/
void setCredentials(Credentials creds);
/**
* Applys filters to the database for showing the correct chat.
*/
void setCurrentChatPartner(QString *jid);
/**
* Returns if connection state is connected.
*/
......@@ -214,6 +209,11 @@ signals:
*/
void logInWorked();
/**
* Emitted, when a different chat was opened on the GUI
*/
void chatPartnerChanged(QString chatPartner);
private:
/**
* Emits the signal for a given connection state.
......
......@@ -84,7 +84,7 @@ Kaidan::Kaidan(QGuiApplication *app, QObject *parent) : QObject(parent)
client = new ClientThread(rosterModel, messageModel, avatarStorage, creds,
settings, app);
client->start();
connect(client, &ClientThread::connectionStateChanged, [=](ConnectionState state) {
emit this->connectionStateChanged((quint8) state);
});
......@@ -93,6 +93,7 @@ Kaidan::Kaidan(QGuiApplication *app, QObject *parent) : QObject(parent)
});
connect(client, &ClientThread::newCredentialsNeeded, this, &Kaidan::newCredentialsNeeded);
connect(client, &ClientThread::logInWorked, this, &Kaidan::logInWorked);
connect(this, &Kaidan::chatPartnerChanged, client, &ClientThread::chatPartnerChanged);
}
Kaidan::~Kaidan()
......@@ -167,14 +168,9 @@ void Kaidan::setChatPartner(QString chatPartner)
if (this->chatPartner == chatPartner)
return;
// set the new chat partner
this->chatPartner = chatPartner;
// filter message for this chat partner
messageModel->applyRecipientFilter(&chatPartner, &(creds.jid));
client->setCurrentChatPartner(&chatPartner);
emit chatPartnerChanged();
emit chatPartnerChanged(chatPartner); // -> connected to client
messageModel->applyRecipientFilter(chatPartner);
}
quint8 Kaidan::getConnectionState() const
......
......@@ -287,7 +287,7 @@ signals:
/**
* Emitted when the currently opnened chat has changed
*/
void chatPartnerChanged();
void chatPartnerChanged(QString chatPartner);
/**
* Emitted when there are no (correct) credentials and new are needed
......
......@@ -69,8 +69,7 @@ QDateTime glooxStampToQDateTime(std::string stamp_)
MessageHandler::MessageHandler(gloox::Client *client, MessageModel *messageModel,
RosterModel *rosterModel, QObject *parent):
QObject(parent), client(client),
messageModel(messageModel), rosterModel(rosterModel),
chatPartner("")
messageModel(messageModel), rosterModel(rosterModel)
{
}
......@@ -78,9 +77,9 @@ MessageHandler::~MessageHandler()
{
}
void MessageHandler::setCurrentChatPartner(QString *chatPartner)
void MessageHandler::setChatPartner(QString chatPartner)
{
this->chatPartner = *chatPartner;
this->chatPartner = chatPartner;
resetUnreadMessagesForJid(this->chatPartner);
}
......
......@@ -52,13 +52,13 @@ public:
RosterModel *rosterModel, QObject *parent = nullptr);
~MessageHandler();
void setCurrentChatPartner(QString *chatPartner);
virtual void handleMessage(const gloox::Message &message, gloox::MessageSession *session = 0);
void updateLastExchangedOfJid(const QString &jid);
void newUnreadMessageForJid(const QString &jid);
void resetUnreadMessagesForJid(const QString &jid);
public slots:
void setChatPartner(QString chatPartner);
void sendMessage(QString toJid, QString body);
private:
......
......@@ -51,16 +51,21 @@ MessageModel::MessageModel(QSqlDatabase *database, QObject *parent):
// Ensures that the model is sorted correctly after submitting a new row.
setEditStrategy(QSqlTableModel::OnManualSubmit);
connect(this, &MessageModel::chatPartnerChanged,
this, &MessageModel::applyRecipientFilter, Qt::BlockingQueuedConnection);
connect(this, &MessageModel::ownJidChanged, [=](QString &ownJid) {
this->ownJid = ownJid;
});
connect(this, &MessageModel::addMessageRequested, this, &MessageModel::addMessage);
connect(this, &MessageModel::setMessageAsSentRequested, this, &MessageModel::setMessageAsSent);
connect(this, &MessageModel::setMessageAsDeliveredRequested, this, &MessageModel::setMessageAsDelivered);
}
void MessageModel::applyRecipientFilter(QString *recipient_, QString *author_)
void MessageModel::applyRecipientFilter(QString recipient)
{
const QString filterString = QString::fromLatin1("(recipient = '%1' AND "
"author = '%2') OR (recipient = '%2' AND author = '%1')").arg(
*recipient_, *author_);
const QString filterString = QString::fromLatin1(
"(recipient = '%1' AND author = '%2') OR (recipient = '%2' AND "
"author = '%1')").arg(recipient, ownJid);
setFilter(filterString);
select();
}
......
......@@ -42,10 +42,23 @@ public:
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
void applyRecipientFilter(QString *recipient_, QString *author_);
/**
* Applies a filter to the database to only show messages of a certain chat
*/
void applyRecipientFilter(QString recipient);
signals:
void recipientChanged();
/**
* Emitted when the user opens another chat to apply a filter to the db
*/
void chatPartnerChanged(QString &jid);
/**
* Emitted, when connecting
*/
void ownJidChanged(QString &jid);
void addMessageRequested(const QString author, const QString recipient,
const QString timestamp, const QString message,
const QString msgId, bool sentByMe,
......@@ -64,6 +77,8 @@ private slots:
private:
QSqlDatabase *database;
QString ownJid;
};
#endif // MESSAGEMODEL_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment