feat/tray_pictogram #70
@ -16,6 +16,8 @@
|
|||||||
### New features
|
### New features
|
||||||
- new "About" window with links, license, gratitudes
|
- new "About" window with links, license, gratitudes
|
||||||
- if the authentication failed Squawk will ask againg for your password and login
|
- if the authentication failed Squawk will ask againg for your password and login
|
||||||
|
- now there is an amount of unread messages showing on top of Squawk launcher icon
|
||||||
|
- notifications now have buttons to open a conversation or to mark that message as read
|
||||||
|
|
||||||
## Squawk 0.2.1 (Apr 02, 2022)
|
## Squawk 0.2.1 (Apr 02, 2022)
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
@ -26,7 +26,8 @@ Application::Application(Core::Squawk* p_core):
|
|||||||
conversations(),
|
conversations(),
|
||||||
dialogueQueue(roster),
|
dialogueQueue(roster),
|
||||||
nowQuitting(false),
|
nowQuitting(false),
|
||||||
destroyingSquawk(false)
|
destroyingSquawk(false),
|
||||||
|
storage()
|
||||||
{
|
{
|
||||||
connect(&roster, &Models::Roster::unnoticedMessage, this, &Application::notify);
|
connect(&roster, &Models::Roster::unnoticedMessage, this, &Application::notify);
|
||||||
connect(&roster, &Models::Roster::unreadMessagesCountChanged, this, &Application::unreadMessagesCountChanged);
|
connect(&roster, &Models::Roster::unreadMessagesCountChanged, this, &Application::unreadMessagesCountChanged);
|
||||||
@ -90,6 +91,23 @@ Application::Application(Core::Squawk* p_core):
|
|||||||
connect(core, &Core::Squawk::requestPassword, this, &Application::requestPassword);
|
connect(core, &Core::Squawk::requestPassword, this, &Application::requestPassword);
|
||||||
connect(core, &Core::Squawk::ready, this, &Application::readSettings);
|
connect(core, &Core::Squawk::ready, this, &Application::readSettings);
|
||||||
|
|
||||||
|
QDBusConnection sys = QDBusConnection::sessionBus();
|
||||||
|
sys.connect(
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
"/org/freedesktop/Notifications",
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
"NotificationClosed",
|
||||||
|
this,
|
||||||
|
SLOT(onNotificationClosed(quint32, quint32))
|
||||||
|
);
|
||||||
|
sys.connect(
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
"/org/freedesktop/Notifications",
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
"ActionInvoked",
|
||||||
|
this,
|
||||||
|
SLOT(onNotificationInvoked(quint32, const QString&))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {}
|
Application::~Application() {}
|
||||||
@ -188,12 +206,14 @@ void Application::onSquawkDestroyed() {
|
|||||||
|
|
||||||
void Application::notify(const QString& account, const Shared::Message& msg)
|
void Application::notify(const QString& account, const Shared::Message& msg)
|
||||||
{
|
{
|
||||||
QString name = QString(roster.getContactName(account, msg.getPenPalJid()));
|
QString jid = msg.getPenPalJid();
|
||||||
QString path = QString(roster.getContactIconPath(account, msg.getPenPalJid(), msg.getPenPalResource()));
|
QString name = QString(roster.getContactName(account, jid));
|
||||||
|
QString path = QString(roster.getContactIconPath(account, jid, msg.getPenPalResource()));
|
||||||
QVariantList args;
|
QVariantList args;
|
||||||
args << QString();
|
args << QString();
|
||||||
|
|
||||||
args << qHash(msg.getId());
|
uint32_t notificationId = qHash(msg.getId());
|
||||||
|
args << notificationId;
|
||||||
if (path.size() > 0) {
|
if (path.size() > 0) {
|
||||||
args << path;
|
args << path;
|
||||||
} else {
|
} else {
|
||||||
@ -212,7 +232,10 @@ void Application::notify(const QString& account, const Shared::Message& msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
args << body;
|
args << body;
|
||||||
args << QStringList();
|
args << QStringList({
|
||||||
|
"markAsRead", tr("Mark as Read"),
|
||||||
|
"openConversation", tr("Open conversation")
|
||||||
|
});
|
||||||
args << QVariantMap({
|
args << QVariantMap({
|
||||||
{"desktop-entry", qApp->desktopFileName()},
|
{"desktop-entry", qApp->desktopFileName()},
|
||||||
{"category", QString("message")},
|
{"category", QString("message")},
|
||||||
@ -222,11 +245,40 @@ void Application::notify(const QString& account, const Shared::Message& msg)
|
|||||||
args << -1;
|
args << -1;
|
||||||
notifications.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
|
notifications.callWithArgumentList(QDBus::AutoDetect, "Notify", args);
|
||||||
|
|
||||||
|
storage.insert(std::make_pair(notificationId, std::make_pair(Models::Roster::ElId(account, name), msg.getId())));
|
||||||
|
|
||||||
if (squawk != nullptr) {
|
if (squawk != nullptr) {
|
||||||
QApplication::alert(squawk);
|
QApplication::alert(squawk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::onNotificationClosed(quint32 id, quint32 reason)
|
||||||
|
{
|
||||||
|
Notifications::const_iterator itr = storage.find(id);
|
||||||
|
if (itr != storage.end()) {
|
||||||
|
if (reason == 2) { //dissmissed by user (https://specifications.freedesktop.org/notification-spec/latest/ar01s09.html)
|
||||||
|
//TODO may ba also mark as read?
|
||||||
|
}
|
||||||
|
if (reason != 1) { //just expired, can be activated again from history, so no removing for now
|
||||||
|
storage.erase(id);
|
||||||
|
qDebug() << "Notification" << id << "was closed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onNotificationInvoked(quint32 id, const QString& action)
|
||||||
|
{
|
||||||
|
qDebug() << "Notification" << id << action << "request";
|
||||||
|
Notifications::const_iterator itr = storage.find(id);
|
||||||
|
if (itr != storage.end()) {
|
||||||
|
if (action == "markAsRead") {
|
||||||
|
roster.markMessageAsRead(itr->second.first, itr->second.second);
|
||||||
|
} else if (action == "openConversation") {
|
||||||
|
focusConversation(itr->second.first, "", itr->second.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::unreadMessagesCountChanged(int count)
|
void Application::unreadMessagesCountChanged(int count)
|
||||||
{
|
{
|
||||||
QDBusMessage signal = QDBusMessage::createSignal("/", "com.canonical.Unity.LauncherEntry", "Update");
|
QDBusMessage signal = QDBusMessage::createSignal("/", "com.canonical.Unity.LauncherEntry", "Update");
|
||||||
@ -238,6 +290,27 @@ void Application::unreadMessagesCountChanged(int count)
|
|||||||
QDBusConnection::sessionBus().send(signal);
|
QDBusConnection::sessionBus().send(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::focusConversation(const Models::Roster::ElId& id, const QString& resource, const QString& messageId)
|
||||||
|
{
|
||||||
|
if (squawk != nullptr) {
|
||||||
|
if (squawk->currentConversationId() != id) {
|
||||||
|
QModelIndex index = roster.getContactIndex(id.account, id.name, resource);
|
||||||
|
squawk->select(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (squawk->isMinimized()) {
|
||||||
|
squawk->showNormal();
|
||||||
|
} else {
|
||||||
|
squawk->show();
|
||||||
|
}
|
||||||
|
squawk->raise();
|
||||||
|
squawk->activateWindow();
|
||||||
|
} else {
|
||||||
|
openConversation(id, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO focus messageId;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setState(Shared::Availability p_availability)
|
void Application::setState(Shared::Availability p_availability)
|
||||||
{
|
{
|
||||||
@ -343,7 +416,7 @@ void Application::openConversation(const Models::Roster::ElId& id, const QString
|
|||||||
conv = itr->second;
|
conv = itr->second;
|
||||||
} else {
|
} else {
|
||||||
Models::Element* el = roster.getElement(id);
|
Models::Element* el = roster.getElement(id);
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
if (el->type == Models::Item::room) {
|
if (el->type == Models::Item::room) {
|
||||||
created = true;
|
created = true;
|
||||||
Models::Room* room = static_cast<Models::Room*>(el);
|
Models::Room* room = static_cast<Models::Room*>(el);
|
||||||
@ -409,7 +482,7 @@ void Application::onSquawkOpenedConversation() {
|
|||||||
Models::Roster::ElId id = squawk->currentConversationId();
|
Models::Roster::ElId id = squawk->currentConversationId();
|
||||||
|
|
||||||
const Models::Element* el = roster.getElementConst(id);
|
const Models::Element* el = roster.getElementConst(id);
|
||||||
if (el != NULL && el->isRoom() && !static_cast<const Models::Room*>(el)->getJoined()) {
|
if (el != nullptr && el->isRoom() && !static_cast<const Models::Room*>(el)->getJoined()) {
|
||||||
emit setRoomJoined(id.account, id.name, true);
|
emit setRoomJoined(id.account, id.name, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,14 +89,19 @@ private slots:
|
|||||||
void stateChanged(Shared::Availability state);
|
void stateChanged(Shared::Availability state);
|
||||||
void onSquawkClosing();
|
void onSquawkClosing();
|
||||||
void onSquawkDestroyed();
|
void onSquawkDestroyed();
|
||||||
|
void onNotificationClosed(quint32 id, quint32 reason);
|
||||||
|
void onNotificationInvoked(quint32 id, const QString& action);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createMainWindow();
|
void createMainWindow();
|
||||||
void subscribeConversation(Conversation* conv);
|
void subscribeConversation(Conversation* conv);
|
||||||
void checkForTheLastWindow();
|
void checkForTheLastWindow();
|
||||||
|
void focusConversation(const Models::Roster::ElId& id, const QString& resource = "", const QString& messageId = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
|
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
|
||||||
|
typedef std::map<uint32_t, std::pair<Models::Roster::ElId, QString>> Notifications;
|
||||||
|
|
||||||
Shared::Availability availability;
|
Shared::Availability availability;
|
||||||
Core::Squawk* core;
|
Core::Squawk* core;
|
||||||
@ -107,6 +112,7 @@ private:
|
|||||||
DialogQueue dialogueQueue;
|
DialogQueue dialogueQueue;
|
||||||
bool nowQuitting;
|
bool nowQuitting;
|
||||||
bool destroyingSquawk;
|
bool destroyingSquawk;
|
||||||
|
Notifications storage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATION_H
|
#endif // APPLICATION_H
|
||||||
|
@ -155,6 +155,16 @@ void Models::Contact::removePresence(const QString& name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Models::Presence * Models::Contact::getPresence(const QString& name)
|
||||||
|
{
|
||||||
|
QMap<QString, Presence*>::iterator itr = presences.find(name);
|
||||||
|
if (itr == presences.end()) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return itr.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Contact::refresh()
|
void Models::Contact::refresh()
|
||||||
{
|
{
|
||||||
QDateTime lastActivity;
|
QDateTime lastActivity;
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
|
|
||||||
void addPresence(const QString& name, const QMap<QString, QVariant>& data);
|
void addPresence(const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removePresence(const QString& name);
|
void removePresence(const QString& name);
|
||||||
|
Presence* getPresence(const QString& name);
|
||||||
|
|
||||||
QString getContactName() const;
|
QString getContactName() const;
|
||||||
QString getStatus() const;
|
QString getStatus() const;
|
||||||
|
@ -134,6 +134,11 @@ unsigned int Models::Element::getMessagesCount() const
|
|||||||
return feed->unreadMessagesCount();
|
return feed->unreadMessagesCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Models::Element::markMessageAsRead(const QString& id) const
|
||||||
|
{
|
||||||
|
return feed->markMessageAsRead(id);
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Element::addMessage(const Shared::Message& data)
|
void Models::Element::addMessage(const Shared::Message& data)
|
||||||
{
|
{
|
||||||
feed->addMessage(data);
|
feed->addMessage(data);
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
void addMessage(const Shared::Message& data);
|
void addMessage(const Shared::Message& data);
|
||||||
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
|
void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
|
||||||
unsigned int getMessagesCount() const;
|
unsigned int getMessagesCount() const;
|
||||||
|
bool markMessageAsRead(const QString& id) const;
|
||||||
void responseArchive(const std::list<Shared::Message> list, bool last);
|
void responseArchive(const std::list<Shared::Message> list, bool last);
|
||||||
bool isRoom() const;
|
bool isRoom() const;
|
||||||
void fileProgress(const QString& messageId, qreal value, bool up);
|
void fileProgress(const QString& messageId, qreal value, bool up);
|
||||||
|
@ -264,6 +264,16 @@ void Models::Room::removeParticipant(const QString& p_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Models::Participant * Models::Room::getParticipant(const QString& p_name)
|
||||||
|
{
|
||||||
|
std::map<QString, Participant*>::const_iterator itr = participants.find(p_name);
|
||||||
|
if (itr == participants.end()) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Room::handleParticipantUpdate(std::map<QString, Participant*>::const_iterator itr, const QMap<QString, QVariant>& data)
|
void Models::Room::handleParticipantUpdate(std::map<QString, Participant*>::const_iterator itr, const QMap<QString, QVariant>& data)
|
||||||
{
|
{
|
||||||
Participant* part = itr->second;
|
Participant* part = itr->second;
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
void addParticipant(const QString& name, const QMap<QString, QVariant>& data);
|
void addParticipant(const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void changeParticipant(const QString& name, const QMap<QString, QVariant>& data);
|
void changeParticipant(const QString& name, const QMap<QString, QVariant>& data);
|
||||||
void removeParticipant(const QString& name);
|
void removeParticipant(const QString& name);
|
||||||
|
Participant* getParticipant(const QString& name);
|
||||||
|
|
||||||
void toOfflineState() override;
|
void toOfflineState() override;
|
||||||
QString getDisplayedName() const override;
|
QString getDisplayedName() const override;
|
||||||
|
@ -549,8 +549,8 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
|
|||||||
|
|
||||||
void Models::Roster::changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data)
|
void Models::Roster::changeContact(const QString& account, const QString& jid, const QMap<QString, QVariant>& data)
|
||||||
{
|
{
|
||||||
Element* el = getElement({account, jid});
|
Element* el = getElement(ElId(account, jid));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
|
||||||
el->update(itr.key(), itr.value());
|
el->update(itr.key(), itr.value());
|
||||||
}
|
}
|
||||||
@ -559,8 +559,8 @@ void Models::Roster::changeContact(const QString& account, const QString& jid, c
|
|||||||
|
|
||||||
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
||||||
{
|
{
|
||||||
Element* el = getElement({account, jid});
|
Element* el = getElement(ElId(account, jid));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->changeMessage(id, data);
|
el->changeMessage(id, data);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "A request to change a message of the contact " << jid << " in the account " << account << " but it wasn't found";
|
qDebug() << "A request to change a message of the contact " << jid << " in the account " << account << " but it wasn't found";
|
||||||
@ -707,8 +707,8 @@ void Models::Roster::removePresence(const QString& account, const QString& jid,
|
|||||||
|
|
||||||
void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
|
void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
|
||||||
{
|
{
|
||||||
Element* el = getElement({account, data.getPenPalJid()});
|
Element* el = getElement(ElId(account, data.getPenPalJid()));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->addMessage(data);
|
el->addMessage(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -948,9 +948,18 @@ const Models::Element * Models::Roster::getElementConst(const Models::Roster::El
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Models::Roster::markMessageAsRead(const Models::Roster::ElId& elementId, const QString& messageId)
|
||||||
|
{
|
||||||
|
const Element* el = getElementConst(elementId);
|
||||||
|
if (el != nullptr) {
|
||||||
|
return el->markMessageAsRead(messageId);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex Models::Roster::getAccountIndex(const QString& name)
|
QModelIndex Models::Roster::getAccountIndex(const QString& name)
|
||||||
{
|
{
|
||||||
@ -968,7 +977,7 @@ QModelIndex Models::Roster::getGroupIndex(const QString& account, const QString&
|
|||||||
if (itr == accounts.end()) {
|
if (itr == accounts.end()) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
} else {
|
} else {
|
||||||
std::map<ElId, Group*>::const_iterator gItr = groups.find({account, name});
|
std::map<ElId, Group*>::const_iterator gItr = groups.find(ElId(account, name));
|
||||||
if (gItr == groups.end()) {
|
if (gItr == groups.end()) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
} else {
|
} else {
|
||||||
@ -978,6 +987,48 @@ QModelIndex Models::Roster::getGroupIndex(const QString& account, const QString&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex Models::Roster::getContactIndex(const QString& account, const QString& jid, const QString& resource)
|
||||||
|
{
|
||||||
|
std::map<QString, Account*>::const_iterator itr = accounts.find(account);
|
||||||
|
if (itr == accounts.end()) {
|
||||||
|
return QModelIndex();
|
||||||
|
} else {
|
||||||
|
Account* acc = itr->second;
|
||||||
|
QModelIndex accIndex = index(acc->row(), 0, QModelIndex());
|
||||||
|
std::map<ElId, Contact*>::const_iterator cItr = contacts.find(ElId(account, jid));
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
QModelIndex contactIndex = index(acc->getContact(jid), 0, accIndex);
|
||||||
|
if (resource.size() == 0) {
|
||||||
|
return contactIndex;
|
||||||
|
} else {
|
||||||
|
Presence* pres = cItr->second->getPresence(resource);
|
||||||
|
if (pres != nullptr) {
|
||||||
|
return index(pres->row(), 0, contactIndex);
|
||||||
|
} else {
|
||||||
|
return contactIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::map<ElId, Room*>::const_iterator rItr = rooms.find(ElId(account, jid));
|
||||||
|
if (rItr != rooms.end()) {
|
||||||
|
QModelIndex roomIndex = index(rItr->second->row(), 0, accIndex);
|
||||||
|
if (resource.size() == 0) {
|
||||||
|
return roomIndex;
|
||||||
|
} else {
|
||||||
|
Participant* part = rItr->second->getParticipant(resource);
|
||||||
|
if (part != nullptr) {
|
||||||
|
return index(part->row(), 0, roomIndex);
|
||||||
|
} else {
|
||||||
|
return roomIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Models::Roster::onElementRequestArchive(const QString& before)
|
void Models::Roster::onElementRequestArchive(const QString& before)
|
||||||
{
|
{
|
||||||
Element* el = static_cast<Element*>(sender());
|
Element* el = static_cast<Element*>(sender());
|
||||||
@ -988,7 +1039,7 @@ void Models::Roster::responseArchive(const QString& account, const QString& jid,
|
|||||||
{
|
{
|
||||||
ElId id(account, jid);
|
ElId id(account, jid);
|
||||||
Element* el = getElement(id);
|
Element* el = getElement(id);
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->responseArchive(list, last);
|
el->responseArchive(list, last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -996,8 +1047,8 @@ void Models::Roster::responseArchive(const QString& account, const QString& jid,
|
|||||||
void Models::Roster::fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up)
|
void Models::Roster::fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up)
|
||||||
{
|
{
|
||||||
for (const Shared::MessageInfo& info : msgs) {
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
Element* el = getElement({info.account, info.jid});
|
Element* el = getElement(ElId(info.account, info.jid));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->fileProgress(info.messageId, value, up);
|
el->fileProgress(info.messageId, value, up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1006,8 +1057,8 @@ void Models::Roster::fileProgress(const std::list<Shared::MessageInfo>& msgs, qr
|
|||||||
void Models::Roster::fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up)
|
void Models::Roster::fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up)
|
||||||
{
|
{
|
||||||
for (const Shared::MessageInfo& info : msgs) {
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
Element* el = getElement({info.account, info.jid});
|
Element* el = getElement(ElId(info.account, info.jid));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->fileComplete(info.messageId, up);
|
el->fileComplete(info.messageId, up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1016,8 +1067,8 @@ void Models::Roster::fileComplete(const std::list<Shared::MessageInfo>& msgs, bo
|
|||||||
void Models::Roster::fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up)
|
void Models::Roster::fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up)
|
||||||
{
|
{
|
||||||
for (const Shared::MessageInfo& info : msgs) {
|
for (const Shared::MessageInfo& info : msgs) {
|
||||||
Element* el = getElement({info.account, info.jid});
|
Element* el = getElement(ElId(info.account, info.jid));
|
||||||
if (el != NULL) {
|
if (el != nullptr) {
|
||||||
el->fileError(info.messageId, err, up);
|
el->fileError(info.messageId, err, up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1031,7 +1082,7 @@ Models::Element * Models::Roster::getElement(const Models::Roster::ElId& id)
|
|||||||
Models::Item::Type Models::Roster::getContactType(const Models::Roster::ElId& id) const
|
Models::Item::Type Models::Roster::getContactType(const Models::Roster::ElId& id) const
|
||||||
{
|
{
|
||||||
const Models::Element* el = getElementConst(id);
|
const Models::Element* el = getElementConst(id);
|
||||||
if (el == NULL) {
|
if (el == nullptr) {
|
||||||
return Item::root;
|
return Item::root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,8 @@ public:
|
|||||||
const Account* getAccountConst(const QString& name) const;
|
const Account* getAccountConst(const QString& name) const;
|
||||||
QModelIndex getAccountIndex(const QString& name);
|
QModelIndex getAccountIndex(const QString& name);
|
||||||
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
QModelIndex getGroupIndex(const QString& account, const QString& name);
|
||||||
|
QModelIndex getContactIndex(const QString& account, const QString& jid, const QString& resource = "");
|
||||||
|
bool markMessageAsRead(const ElId& elementId, const QString& messageId);
|
||||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
|
||||||
|
|
||||||
void fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);
|
void fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);
|
||||||
@ -115,7 +117,7 @@ private slots:
|
|||||||
void onChildMoved();
|
void onChildMoved();
|
||||||
void onElementRequestArchive(const QString& before);
|
void onElementRequestArchive(const QString& before);
|
||||||
void recalculateUnreadMessages();
|
void recalculateUnreadMessages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Item* root;
|
Item* root;
|
||||||
std::map<QString, Account*> accounts;
|
std::map<QString, Account*> accounts;
|
||||||
|
@ -656,3 +656,8 @@ Models::Roster::ElId Squawk::currentConversationId() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Squawk::select(QModelIndex index)
|
||||||
|
{
|
||||||
|
m_ui->roster->scrollTo(index, QAbstractItemView::EnsureVisible);
|
||||||
|
m_ui->roster->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
|
||||||
|
}
|
||||||
|
@ -90,6 +90,7 @@ public slots:
|
|||||||
void writeSettings();
|
void writeSettings();
|
||||||
void stateChanged(Shared::Availability state);
|
void stateChanged(Shared::Availability state);
|
||||||
void responseVCard(const QString& jid, const Shared::VCard& card);
|
void responseVCard(const QString& jid, const Shared::VCard& card);
|
||||||
|
void select(QModelIndex index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<Ui::Squawk> m_ui;
|
QScopedPointer<Ui::Squawk> m_ui;
|
||||||
|
@ -318,12 +318,7 @@ QVariant Models::MessageFeed::data(const QModelIndex& index, int role) const
|
|||||||
case Bulk: {
|
case Bulk: {
|
||||||
FeedItem item;
|
FeedItem item;
|
||||||
item.id = msg->getId();
|
item.id = msg->getId();
|
||||||
|
markMessageAsRead(item.id);
|
||||||
std::set<QString>::const_iterator umi = unreadMessages->find(item.id);
|
|
||||||
if (umi != unreadMessages->end()) {
|
|
||||||
unreadMessages->erase(umi);
|
|
||||||
emit unreadMessagesCountChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
item.sentByMe = sentByMe(*msg);
|
item.sentByMe = sentByMe(*msg);
|
||||||
item.date = msg->getTime();
|
item.date = msg->getTime();
|
||||||
@ -373,6 +368,17 @@ int Models::MessageFeed::rowCount(const QModelIndex& parent) const
|
|||||||
return storage.size();
|
return storage.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Models::MessageFeed::markMessageAsRead(const QString& id) const
|
||||||
|
{
|
||||||
|
std::set<QString>::const_iterator umi = unreadMessages->find(id);
|
||||||
|
if (umi != unreadMessages->end()) {
|
||||||
|
unreadMessages->erase(umi);
|
||||||
|
emit unreadMessagesCountChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int Models::MessageFeed::unreadMessagesCount() const
|
unsigned int Models::MessageFeed::unreadMessagesCount() const
|
||||||
{
|
{
|
||||||
return unreadMessages->size();
|
return unreadMessages->size();
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
void reportLocalPathInvalid(const QString& messageId);
|
void reportLocalPathInvalid(const QString& messageId);
|
||||||
|
|
||||||
unsigned int unreadMessagesCount() const;
|
unsigned int unreadMessagesCount() const;
|
||||||
|
bool markMessageAsRead(const QString& id) const;
|
||||||
void fileProgress(const QString& messageId, qreal value, bool up);
|
void fileProgress(const QString& messageId, qreal value, bool up);
|
||||||
void fileError(const QString& messageId, const QString& error, bool up);
|
void fileError(const QString& messageId, const QString& error, bool up);
|
||||||
void fileComplete(const QString& messageId, bool up);
|
void fileComplete(const QString& messageId, bool up);
|
||||||
|
Loading…
Reference in New Issue
Block a user