forked from blue/squawk
better new message handling, subscription with adding new contact, out of roster contacts handling
This commit is contained in:
parent
bb509be29a
commit
b2699e0087
@ -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";
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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") {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user