pal resourse sticking, notifications of unread messages, new message icons

This commit is contained in:
Blue 2021-04-27 22:29:15 +03:00
parent 4c5efad9dc
commit b44873d587
12 changed files with 119 additions and 95 deletions

View File

@ -31,6 +31,8 @@ Models::Element::Element(Type p_type, const Models::Account* acc, const QString&
{ {
connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive); connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive);
connect(feed, &MessageFeed::fileDownloadRequest, this, &Element::fileDownloadRequest); connect(feed, &MessageFeed::fileDownloadRequest, this, &Element::fileDownloadRequest);
connect(feed, &MessageFeed::unreadMessagesCountChanged, this, &Element::onFeedUnreadMessagesCountChanged);
connect(feed, &MessageFeed::unnoticedMessage, this, &Element::onFeedUnnoticedMessage);
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState"); QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
if (itr != data.end()) { if (itr != data.end()) {
@ -134,11 +136,6 @@ unsigned int Models::Element::getMessagesCount() const
void Models::Element::addMessage(const Shared::Message& data) void Models::Element::addMessage(const Shared::Message& data)
{ {
feed->addMessage(data); feed->addMessage(data);
if (type == contact) {
changed(4);
} else if (type == room) {
changed(5);
}
} }
void Models::Element::changeMessage(const QString& id, const QMap<QString, QVariant>& data) void Models::Element::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
@ -170,3 +167,17 @@ void Models::Element::fileError(const QString& messageId, const QString& error,
{ {
feed->fileError(messageId, error, up); feed->fileError(messageId, error, up);
} }
void Models::Element::onFeedUnreadMessagesCountChanged()
{
if (type == contact) {
changed(4);
} else if (type == room) {
changed(5);
}
}
void Models::Element::onFeedUnnoticedMessage(const Shared::Message& msg)
{
emit unnoticedMessage(getAccountName(), msg);
}

View File

@ -50,6 +50,7 @@ public:
signals: signals:
void requestArchive(const QString& before); void requestArchive(const QString& before);
void fileDownloadRequest(const QString& url); void fileDownloadRequest(const QString& url);
void unnoticedMessage(const QString& account, const Shared::Message& msg);
protected: protected:
void setJid(const QString& p_jid); void setJid(const QString& p_jid);
@ -59,6 +60,10 @@ protected:
bool columnInvolvedInDisplay(int col) override; bool columnInvolvedInDisplay(int col) override;
const Account* getParentAccount() const override; const Account* getParentAccount() const override;
protected slots:
void onFeedUnreadMessagesCountChanged();
void onFeedUnnoticedMessage(const Shared::Message& msg);
protected: protected:
QString jid; QString jid;
QString avatarPath; QString avatarPath;

View File

@ -44,12 +44,16 @@ Models::MessageFeed::MessageFeed(const Element* ri, QObject* parent):
rosterItem(ri), rosterItem(ri),
syncState(incomplete), syncState(incomplete),
uploads(), uploads(),
downloads() downloads(),
unreadMessages(new std::set<QString>()),
observersAmount(0)
{ {
} }
Models::MessageFeed::~MessageFeed() Models::MessageFeed::~MessageFeed()
{ {
delete unreadMessages;
for (Shared::Message* message : storage) { for (Shared::Message* message : storage) {
delete message; delete message;
} }
@ -75,6 +79,14 @@ void Models::MessageFeed::addMessage(const Shared::Message& msg)
beginInsertRows(QModelIndex(), position, position); beginInsertRows(QModelIndex(), position, position);
storage.insert(copy); storage.insert(copy);
endInsertRows(); endInsertRows();
emit newMessage(msg);
if (observersAmount == 0 && !msg.getForwarded()) { //not to notify when the message is delivered by the carbon copy
unreadMessages->insert(msg.getId()); //cuz it could be my own one or the one I read on another device
emit unreadMessagesCountChanged();
emit unnoticedMessage(msg);
}
} }
void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, QVariant>& data) void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, QVariant>& data)
@ -97,6 +109,11 @@ void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, Q
if (functor.hasIdBeenModified()) { if (functor.hasIdBeenModified()) {
changeRoles.insert(MessageRoles::Id); changeRoles.insert(MessageRoles::Id);
std::set<QString>::const_iterator umi = unreadMessages->find(id);
if (umi != unreadMessages->end()) {
unreadMessages->erase(umi);
unreadMessages->insert(msg->getId());
}
} }
//change message is a final event in download/upload event train //change message is a final event in download/upload event train
@ -258,6 +275,13 @@ 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();
std::set<QString>::const_iterator umi = unreadMessages->find(item.id);
if (umi != unreadMessages->end()) {
unreadMessages->erase(umi);
emit unreadMessagesCount();
}
item.sentByMe = sentByMe(*msg); item.sentByMe = sentByMe(*msg);
item.date = msg->getTime(); item.date = msg->getTime();
item.state = msg->getState(); item.state = msg->getState();
@ -308,7 +332,7 @@ int Models::MessageFeed::rowCount(const QModelIndex& parent) const
unsigned int Models::MessageFeed::unreadMessagesCount() const unsigned int Models::MessageFeed::unreadMessagesCount() const
{ {
return storage.size(); //let's say they are all new for now =) return unreadMessages->size();
} }
bool Models::MessageFeed::canFetchMore(const QModelIndex& parent) const bool Models::MessageFeed::canFetchMore(const QModelIndex& parent) const
@ -456,6 +480,16 @@ void Models::MessageFeed::fileError(const QString& messageId, const QString& err
//TODO //TODO
} }
void Models::MessageFeed::incrementObservers()
{
++observersAmount;
}
void Models::MessageFeed::decrementObservers()
{
--observersAmount;
}
QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const
{ {

View File

@ -66,10 +66,16 @@ public:
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);
void incrementObservers();
void decrementObservers();
signals: signals:
void requestArchive(const QString& before); void requestArchive(const QString& before);
void requestStateChange(bool requesting); void requestStateChange(bool requesting);
void fileDownloadRequest(const QString& url); void fileDownloadRequest(const QString& url);
void unreadMessagesCountChanged();
void newMessage(const Shared::Message& msg);
void unnoticedMessage(const Shared::Message& msg);
public: public:
enum MessageRoles { enum MessageRoles {
@ -140,6 +146,9 @@ private:
Progress uploads; Progress uploads;
Progress downloads; Progress downloads;
std::set<QString>* unreadMessages;
uint16_t observersAmount;
static const QHash<int, QByteArray> roles; static const QHash<int, QByteArray> roles;
}; };

View File

@ -448,6 +448,7 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons
contact = new Contact(acc, jid, data); contact = new Contact(acc, jid, data);
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive); connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
connect(contact, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest); connect(contact, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
connect(contact, &Contact::unnoticedMessage, this, &Roster::unnoticedMessage);
contacts.insert(std::make_pair(id, contact)); contacts.insert(std::make_pair(id, contact));
} else { } else {
contact = itr->second; contact = itr->second;
@ -785,6 +786,7 @@ void Models::Roster::addRoom(const QString& account, const QString jid, const QM
Room* room = new Room(acc, jid, data); Room* room = new Room(acc, jid, data);
connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive); connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
connect(room, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest); connect(room, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
connect(room, &Contact::unnoticedMessage, this, &Roster::unnoticedMessage);
rooms.insert(std::make_pair(id, room)); rooms.insert(std::make_pair(id, room));
acc->appendChild(room); acc->appendChild(room);
} }

View File

@ -92,6 +92,7 @@ public:
signals: signals:
void requestArchive(const QString& account, const QString& jid, const QString& before); void requestArchive(const QString& account, const QString& jid, const QString& before);
void fileDownloadRequest(const QString& url); void fileDownloadRequest(const QString& url);
void unnoticedMessage(const QString& account, const Shared::Message& msg);
private: private:
Element* getElement(const ElId& id); Element* getElement(const ElId& id);

View File

@ -59,6 +59,7 @@ Squawk::Squawk(QWidget *parent) :
connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu); connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu);
connect(m_ui->roster, &QTreeView::collapsed, this, &Squawk::onItemCollepsed); connect(m_ui->roster, &QTreeView::collapsed, this, &Squawk::onItemCollepsed);
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged); connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
connect(&rosterModel, &Models::Roster::unnoticedMessage, this, &Squawk::onUnnoticedMessage);
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged); connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive); connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive);
@ -410,36 +411,13 @@ void Squawk::fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const
void Squawk::accountMessage(const QString& account, const Shared::Message& data) void Squawk::accountMessage(const QString& account, const Shared::Message& data)
{ {
const QString& from = data.getPenPalJid();
Models::Roster::ElId id({account, from});
Conversations::iterator itr = conversations.find(id);
bool found = false;
rosterModel.addMessage(account, data); rosterModel.addMessage(account, data);
}
if (currentConversation != 0 && currentConversation->getId() == id) {
QApplication::alert(this); void Squawk::onUnnoticedMessage(const QString& account, const Shared::Message& msg)
if (!isVisible() && !data.getForwarded()) { {
notify(account, data); notify(account, msg); //Telegram does this way - notifies even if the app is visible
} QApplication::alert(this);
found = true;
}
if (itr != conversations.end()) {
Conversation* conv = itr->second;
QApplication::alert(conv);
if (!conv->isVisible() && !data.getForwarded()) {
notify(account, data);
}
found = true;
}
if (!found) {
if (!data.getForwarded()) {
QApplication::alert(this);
notify(account, data);
}
}
} }
void Squawk::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data) void Squawk::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
@ -935,6 +913,7 @@ void Squawk::subscribeConversation(Conversation* conv)
{ {
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed); connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage); connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage);
connect(conv, &Conversation::notifyableMessage, this, &Squawk::notify);
} }
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous) void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)

View File

@ -128,6 +128,8 @@ private:
protected: protected:
void closeEvent(QCloseEvent * event) override; void closeEvent(QCloseEvent * event) override;
protected slots:
void notify(const QString& account, const Shared::Message& msg); void notify(const QString& account, const Shared::Message& msg);
private slots: private slots:
@ -153,6 +155,8 @@ private slots:
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous); void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
void onContextAboutToHide(); void onContextAboutToHide();
void onUnnoticedMessage(const QString& account, const Shared::Message& msg);
private: private:
void checkNextAccountForPassword(); void checkNextAccountForPassword();
void onPasswordPromptDone(); void onPasswordPromptDone();

View File

@ -71,15 +71,14 @@ Shared::Message Chat::createMessage() const
return msg; return msg;
} }
// TODO void Chat::onMessage(const Shared::Message& data)
// void Chat::addMessage(const Shared::Message& data) {
// { Conversation::onMessage(data);
// Conversation::addMessage(data);
// if (!data.getOutgoing()) {
// if (!data.getOutgoing()) { //TODO need to check if that was the last message const QString& res = data.getPenPalResource();
// const QString& res = data.getPenPalResource(); if (res.size() > 0) {
// if (res.size() > 0) { setPalResource(res);
// setPalResource(res); }
// } }
// } }
// }

View File

@ -34,14 +34,13 @@ class Chat : public Conversation
public: public:
Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0); Chat(Models::Account* acc, Models::Contact* p_contact, QWidget* parent = 0);
~Chat(); ~Chat();
//void addMessage(const Shared::Message & data) override;
protected slots: protected slots:
void onContactChanged(Models::Item* item, int row, int col); void onContactChanged(Models::Item* item, int row, int col);
protected: protected:
Shared::Message createMessage() const override; Shared::Message createMessage() const override;
void onMessage(const Shared::Message& msg) override;
private: private:
void updateState(); void updateState();

View File

@ -48,8 +48,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
delegate(new MessageDelegate(this)), delegate(new MessageDelegate(this)),
scroll(down), scroll(down),
manualSliderChange(false), manualSliderChange(false),
requestingHistory(false),
everShown(false),
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1) tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -57,8 +55,11 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
feed->setItemDelegate(delegate); feed->setItemDelegate(delegate);
delegate->initializeFonts(feed->getFont()); delegate->initializeFonts(feed->getFont());
feed->setModel(el->feed); feed->setModel(el->feed);
el->feed->incrementObservers();
m_ui->widget->layout()->addWidget(feed); m_ui->widget->layout()->addWidget(feed);
connect(el->feed, &Models::MessageFeed::newMessage, this, &Conversation::onFeedMessage);
connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged); connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged);
filesLayout = new FlowLayout(m_ui->filesPanel, 0); filesLayout = new FlowLayout(m_ui->filesPanel, 0);
@ -69,9 +70,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed); connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed);
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed); connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
//connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile);
//connect(line, &MessageLine::uploadFile, this, qOverload<const Shared::Message&, const QString&>(&Conversation::sendMessage));
//connect(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach); connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton); connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, connect(m_ui->messageEditor->document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
@ -121,18 +119,19 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
Conversation::~Conversation() Conversation::~Conversation()
{ {
element->feed->decrementObservers();
} }
void Conversation::onAccountChanged(Models::Item* item, int row, int col) void Conversation::onAccountChanged(Models::Item* item, int row, int col)
{ {
if (item == account) { if (item == account) {
if (col == 2 && account->getState() == Shared::ConnectionState::connected) { if (col == 2 && account->getState() == Shared::ConnectionState::connected) { //to request the history when we're back online after reconnect
if (!requestingHistory) { //if (!requestingHistory) {
requestingHistory = true; //requestingHistory = true;
//line->showBusyIndicator(); //line->showBusyIndicator();
//emit requestArchive(""); //emit requestArchive("");
//scroll = down; //scroll = down;
} //}
} }
} }
} }
@ -223,21 +222,6 @@ void Conversation::onEnterPressed()
} }
} }
void Conversation::showEvent(QShowEvent* event)
{
if (!everShown) {
everShown = true;
// line->showBusyIndicator();
requestingHistory = true;
scroll = keep;
emit requestArchive("");
}
emit shown();
QWidget::showEvent(event);
}
void Conversation::onAttach() void Conversation::onAttach()
{ {
QFileDialog* d = new QFileDialog(this, tr("Chose a file to send")); QFileDialog* d = new QFileDialog(this, tr("Chose a file to send"));
@ -265,21 +249,6 @@ void Conversation::setStatus(const QString& status)
statusLabel->setText(Shared::processMessageBody(status)); statusLabel->setText(Shared::processMessageBody(status));
} }
void Conversation::responseFileProgress(const QString& messageId, qreal progress)
{
// line->fileProgress(messageId, progress);
}
void Conversation::fileError(const QString& messageId, const QString& error)
{
// line->fileError(messageId, error);
}
void Conversation::responseLocalFile(const QString& messageId, const QString& path)
{
// line->responseLocalFile(messageId, path);
}
Models::Roster::ElId Conversation::getId() const Models::Roster::ElId Conversation::getId() const
{ {
return {getAccount(), getJid()}; return {getAccount(), getJid()};
@ -416,3 +385,18 @@ Shared::Message Conversation::createMessage() const
return msg; return msg;
} }
void Conversation::onFeedMessage(const Shared::Message& msg)
{
this->onMessage(msg);
}
void Conversation::onMessage(const Shared::Message& msg)
{
qDebug() << window()->windowState();
if (!msg.getForwarded()) {
QApplication::alert(this);
if (window()->windowState().testFlag(Qt::WindowMinimized)) {
emit notifyableMessage(getAccount(), msg);
}
}
}

View File

@ -68,10 +68,6 @@ public:
Models::Roster::ElId getId() const; Models::Roster::ElId getId() const;
void setPalResource(const QString& res); void setPalResource(const QString& res);
void showEvent(QShowEvent * event) override;
void responseLocalFile(const QString& messageId, const QString& path);
void fileError(const QString& messageId, const QString& error);
void responseFileProgress(const QString& messageId, qreal progress);
virtual void setAvatar(const QString& path); virtual void setAvatar(const QString& path);
void setFeedFrames(bool top, bool right, bool bottom, bool left); void setFeedFrames(bool top, bool right, bool bottom, bool left);
@ -81,6 +77,7 @@ signals:
void shown(); void shown();
void requestLocalFile(const QString& messageId, const QString& url); void requestLocalFile(const QString& messageId, const QString& url);
void downloadFile(const QString& messageId, const QString& url); void downloadFile(const QString& messageId, const QString& url);
void notifyableMessage(const QString& account, const Shared::Message& msg);
protected: protected:
virtual void setName(const QString& name); virtual void setName(const QString& name);
@ -93,6 +90,7 @@ protected:
void dragEnterEvent(QDragEnterEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override;
void dragLeaveEvent(QDragLeaveEvent* event) override; void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override; void dropEvent(QDropEvent* event) override;
virtual void onMessage(const Shared::Message& msg);
protected slots: protected slots:
void onEnterPressed(); void onEnterPressed();
@ -102,6 +100,7 @@ protected slots:
void onClearButton(); void onClearButton();
void onTextEditDocSizeChanged(const QSizeF& size); void onTextEditDocSizeChanged(const QSizeF& size);
void onAccountChanged(Models::Item* item, int row, int col); void onAccountChanged(Models::Item* item, int row, int col);
void onFeedMessage(const Shared::Message& msg);
public: public:
const bool isMuc; const bool isMuc;
@ -128,8 +127,6 @@ protected:
MessageDelegate* delegate; MessageDelegate* delegate;
Scroll scroll; Scroll scroll;
bool manualSliderChange; bool manualSliderChange;
bool requestingHistory;
bool everShown;
bool tsb; //transient scroll bars bool tsb; //transient scroll bars
}; };