better new message handling, subscription with adding new contact, out of roster contacts handling

This commit is contained in:
Blue 2019-06-18 18:08:03 +03:00
parent bb509be29a
commit b2699e0087
11 changed files with 100 additions and 23 deletions

View File

@ -18,7 +18,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
am(new QXmppMamManager()),
contacts(),
maxReconnectTimes(0),
reconnectTimes(0)
reconnectTimes(0),
queuedContacts(),
outOfRosterContacts()
{
config.setUser(p_login);
config.setDomain(p_server);
@ -166,6 +168,12 @@ void Core::Account::setReconnectTimes(unsigned int times)
void Core::Account::onRosterItemAdded(const QString& bareJid)
{
addedAccount(bareJid);
std::map<QString, QString>::const_iterator itr = queuedContacts.find(bareJid);
if (itr != queuedContacts.end()) {
QXmppRosterManager& rm = client.rosterManager();
rm.subscribe(bareJid, itr->second);
queuedContacts.erase(itr);
}
}
void Core::Account::onRosterItemChanged(const QString& bareJid)
@ -447,6 +455,7 @@ bool Core::Account::handleChatMessage(const QXmppMessage& msg, bool outgoing, bo
} else {
cnt = new Contact(jid, name);
contacts.insert(std::make_pair(jid, cnt));
outOfRosterContacts.insert(jid);
cnt->setSubscriptionState(Shared::unknown);
emit addContact(jid, "", QMap<QString, QVariant>({
{"state", Shared::unknown}
@ -785,8 +794,14 @@ void Core::Account::unsubscribeFromContact(const QString& jid, const QString& re
void Core::Account::removeContactRequest(const QString& jid)
{
if (state == Shared::connected) {
QXmppRosterManager& rm = client.rosterManager();
rm.removeItem(jid);
std::set<QString>::const_iterator itr = outOfRosterContacts.find(jid);
if (itr != outOfRosterContacts.end()) {
outOfRosterContacts.erase(itr);
onRosterItemRemoved(jid);
} else {
QXmppRosterManager& rm = client.rosterManager();
rm.removeItem(jid);
}
} else {
qDebug() << "An attempt to remove contact " << jid << " from account " << name << " but the account is not in the connected state, skipping";
}
@ -796,8 +811,14 @@ void Core::Account::removeContactRequest(const QString& jid)
void Core::Account::addContactRequest(const QString& jid, const QString& name, const QSet<QString>& groups)
{
if (state == Shared::connected) {
QXmppRosterManager& rm = client.rosterManager();
rm.addItem(jid, name, groups);
std::map<QString, QString>::const_iterator itr = queuedContacts.find(jid);
if (itr != queuedContacts.end()) {
qDebug() << "An attempt to add contact " << jid << " to account " << name << " but the account is already queued for adding, skipping";
} else {
queuedContacts.insert(std::make_pair(jid, "")); //TODO need to add reason here;
QXmppRosterManager& rm = client.rosterManager();
rm.addItem(jid, name, groups);
}
} else {
qDebug() << "An attempt to add contact " << jid << " to account " << name << " but the account is not in the connected state, skipping";
}

View File

@ -78,6 +78,9 @@ private:
unsigned int maxReconnectTimes;
unsigned int reconnectTimes;
std::map<QString, QString> queuedContacts;
std::set<QString> outOfRosterContacts;
private slots:
void onClientConnected();
void onClientDisconnected();

View File

@ -8,6 +8,7 @@ set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets CONFIG REQUIRED)
find_package(Qt5DBus CONFIG REQUIRED)
set(squawkUI_SRC
squawk.cpp
@ -29,6 +30,7 @@ add_library(squawkUI ${squawkUI_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(squawkUI Qt5::Widgets)
target_link_libraries(squawkUI Qt5::DBus)
# Install the executable
install(TARGETS squawkUI DESTINATION lib)

View File

@ -39,7 +39,7 @@ Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
m_ui->splitter->setSizes({300, 0});
m_ui->splitter->setStretchFactor(1, 0);
setName(p_contact->getName());
setName(p_contact->getContactName());
setState(p_contact->getAvailability());
connect(contact, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onContactChanged(Models::Item*, int, int)));
@ -71,12 +71,8 @@ Conversation::~Conversation()
void Conversation::setName(const QString& name)
{
if (name == "") {
m_ui->nameLabel->setText(getJid());
} else {
m_ui->nameLabel->setText(name);
line->setPalName(getJid(), name);
}
m_ui->nameLabel->setText(name);
line->setPalName(getJid(), name);
}
void Conversation::setState(Shared::Availability state)
@ -105,7 +101,7 @@ void Conversation::onContactChanged(Models::Item* item, int row, int col)
if (item == contact) {
switch (col) {
case 0:
setName(contact->getName());
setName(contact->getContactName());
break;
case 3:
setState(contact->getAvailability());
@ -252,6 +248,7 @@ void Conversation::showEvent(QShowEvent* event)
requestingHistory = true;
emit requestArchive(line->firstMessageId());
}
emit shown();
QWidget::showEvent(event);
}

View File

@ -62,6 +62,7 @@ public:
signals:
void sendMessage(const Shared::Message& message);
void requestArchive(const QString& before);
void shown();
protected:
void setState(Shared::Availability state);

View File

@ -76,11 +76,7 @@ QVariant Models::Contact::data(int column) const
{
switch (column) {
case 0:
if (name == "") {
return jid;
} else {
return Item::data(column);
}
return getContactName();
case 1:
return jid;
case 2:
@ -94,6 +90,15 @@ QVariant Models::Contact::data(int column) const
}
}
QString Models::Contact::getContactName() const
{
if (name == "") {
return jid;
} else {
return name;
}
}
void Models::Contact::update(const QString& field, const QVariant& value)
{
if (field == "name") {

View File

@ -36,6 +36,7 @@ public:
QString getAccountName() const;
QString getAccountJid() const;
QString getAccountResource() const;
QString getContactName() const;
void addMessage(const Shared::Message& data);
unsigned int getMessagesCount() const;

View File

@ -556,3 +556,13 @@ void Models::Roster::removeAccount(const QString& account)
acc->deleteLater();
}
QString Models::Roster::getContactName(const QString& account, const QString& jid)
{
std::multimap<ElId, Contact*>::const_iterator cItr = contacts.find({account, jid});
if (cItr == contacts.end()) {
qDebug() << "An attempt to get a name of non existing contact " << account << ":" << jid << ", skipping";
return "";
}
return cItr->second->getContactName();
}

View File

@ -35,6 +35,7 @@ public:
void removePresence(const QString& account, const QString& jid, const QString& name);
void addMessage(const QString& account, const Shared::Message& data);
void dropMessages(const QString& account, const QString& jid);
QString getContactName(const QString& account, const QString& jid);
QVariant data ( const QModelIndex& index, int role ) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;

View File

@ -9,7 +9,8 @@ Squawk::Squawk(QWidget *parent) :
accounts(0),
rosterModel(),
conversations(),
contextMenu(new QMenu())
contextMenu(new QMenu()),
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus())
{
m_ui->setupUi(this);
m_ui->roster->setModel(&rosterModel);
@ -227,9 +228,9 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
connect(conv, SIGNAL(shown()), this, SLOT(onConversationShown()));
conversations.insert(std::make_pair(id, conv));
rosterModel.dropMessages(account, jid);
conv->show();
@ -241,6 +242,12 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
}
}
void Squawk::onConversationShown()
{
Conversation* conv = static_cast<Conversation*>(sender());
rosterModel.dropMessages(conv->getAccount(), conv->getJid());
}
void Squawk::onConversationClosed(QObject* parent)
{
Conversation* conv = static_cast<Conversation*>(sender());
@ -257,14 +264,38 @@ void Squawk::accountMessage(const QString& account, const Shared::Message& data)
const QString& from = data.getPenPalJid();
Conversations::iterator itr = conversations.find({account, from});
if (itr != conversations.end()) {
itr->second->addMessage(data);
} else {
if (!data.getForwarded()) {
Conversation* conv = itr->second;
conv->addMessage(data);
QApplication::alert(conv);
if (conv->isMinimized()) {
rosterModel.addMessage(account, data);
if (!data.getForwarded()) {
notify(account, data);
}
}
} else {
rosterModel.addMessage(account, data);
if (!data.getForwarded()) {
QApplication::alert(this);
notify(account, data);
}
}
}
void Squawk::notify(const QString& account, const Shared::Message& msg)
{
QVariantList args;
args << QString(QCoreApplication::applicationName());
args << QVariant(QVariant::UInt); //TODO some normal id
args << QString("mail-message"); //TODO icon
args << QString(rosterModel.getContactName(account, msg.getPenPalJid()));
args << QString(msg.getBody());
args << QStringList();
args << QVariantMap();
args << 3000;
dbus.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
}
void Squawk::onConversationMessage(const Shared::Message& msg)
{
Conversation* conv = static_cast<Conversation*>(sender());
@ -299,6 +330,7 @@ void Squawk::removeAccount(const QString& account)
disconnect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
disconnect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
disconnect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
disconnect(conv, SIGNAL(shown()), this, SLOT(onConversationShown()));
conv->close();
conversations.erase(lItr);
} else {

View File

@ -4,6 +4,7 @@
#include <QMainWindow>
#include <QScopedPointer>
#include <QCloseEvent>
#include <QtDBus/QDBusInterface>
#include <deque>
#include <map>
#include <list>
@ -65,9 +66,11 @@ private:
Models::Roster rosterModel;
Conversations conversations;
QMenu* contextMenu;
QDBusInterface dbus;
protected:
void closeEvent(QCloseEvent * event) override;
void notify(const QString& account, const Shared::Message& msg);
private slots:
void onAccounts();
@ -81,6 +84,7 @@ private slots:
void onConversationMessage(const Shared::Message& msg);
void onConversationRequestArchive(const QString& before);
void onRosterContextMenu(const QPoint& point);
void onConversationShown();
};