1
0
forked from blue/squawk

handled a case when user removes downloaded file, minor optimizations on message changing

This commit is contained in:
Blue 2021-04-28 23:26:19 +03:00
parent b44873d587
commit 50190f3eac
23 changed files with 136 additions and 40 deletions

View File

@ -920,3 +920,6 @@ void Core::Account::onContactHistoryResponse(const std::list<Shared::Message>& l
}
emit responseArchive(contact->jid, list, last);
}
void Core::Account::requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data){
mh->requestChangeMessage(jid, messageId, data);}

View File

@ -96,6 +96,7 @@ public:
void addContactToGroupRequest(const QString& jid, const QString& groupName);
void removeContactFromGroupRequest(const QString& jid, const QString& groupName);
void renameContactRequest(const QString& jid, const QString& newName);
void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data);
void setRoomJoined(const QString& jid, bool joined);
void setRoomAutoJoin(const QString& jid, bool joined);

View File

@ -429,3 +429,18 @@ void Core::MessageHandler::sendMessageWithLocalUploadedFile(Shared::Message msg,
performSending(msg);
//TODO removal/progress update
}
void Core::MessageHandler::requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data)
{
RosterItem* cnt = acc->rh->getRosterItem(jid);
if (cnt != 0) {
QMap<QString, QVariant>::const_iterator itr = data.find("attachPath");
if (data.size() == 1 && itr != data.end()) {
cnt->changeMessage(messageId, data);
emit acc->changeMessage(jid, messageId, data);
} else {
qDebug() << "A request to change message" << messageId << "of conversation" << jid << "with following data" << data;
qDebug() << "nothing but the changing of the local path is supported yet in this method, skipping";
}
}
}

View File

@ -58,6 +58,7 @@ public slots:
void onDownloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
void onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
void onLoadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& path, bool up);
void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data);
private:
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);

View File

@ -493,3 +493,8 @@ QString Core::NetworkAccess::addMessageAndCheckForPath(const QString& url, const
{
return storage.addMessageAndCheckForPath(url, account, jid, id);
}
std::list<Shared::MessageInfo> Core::NetworkAccess::reportPathInvalid(const QString& path)
{
return storage.deletedFile(path);
}

View File

@ -53,6 +53,7 @@ public:
QString addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id);
void uploadFile(const Shared::MessageInfo& info, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers);
bool checkAndAddToUploading(const QString& acc, const QString& jid, const QString id, const QString path);
std::list<Shared::MessageInfo> reportPathInvalid(const QString& path);
signals:
void loadFileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);

View File

@ -751,3 +751,20 @@ void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id
Account* acc = static_cast<Account*>(sender());
emit fileError({{acc->getName(), jid, id}}, errorText, true);
}
void Core::Squawk::onLocalPathInvalid(const QString& path)
{
std::list<Shared::MessageInfo> list = network.reportPathInvalid(path);
QMap<QString, QVariant> data({
{"attachPath", ""}
});
for (const Shared::MessageInfo& info : list) {
AccountsMap::const_iterator itr = amap.find(info.account);
if (itr != amap.end()) {
itr->second->requestChangeMessage(info.jid, info.messageId, data);
} else {
qDebug() << "Reacting on failure to reach file" << path << "there was an attempt to change message in account" << info.account << "which doesn't exist, skipping";
}
}
}

View File

@ -121,6 +121,7 @@ public slots:
void requestVCard(const QString& account, const QString& jid);
void uploadVCard(const QString& account, const Shared::VCard& card);
void responsePassword(const QString& account, const QString& password);
void onLocalPathInvalid(const QString& path);
private:
typedef std::deque<Account*> Accounts;

View File

@ -348,6 +348,7 @@ std::list<Shared::MessageInfo> Core::UrlStorage::deletedFile(const QString& path
url = QString(surl.c_str());
} else if (rc == MDB_NOTFOUND) {
qDebug() << "Have been asked to remove file" << path << ", which isn't in the database, skipping";
mdb_txn_abort(txn);
return list;
} else {
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));

View File

@ -116,6 +116,7 @@ int main(int argc, char *argv[])
QObject::connect(&w, &Squawk::requestVCard, squawk, &Core::Squawk::requestVCard);
QObject::connect(&w, &Squawk::uploadVCard, squawk, &Core::Squawk::uploadVCard);
QObject::connect(&w, &Squawk::responsePassword, squawk, &Core::Squawk::responsePassword);
QObject::connect(&w, &Squawk::localPathInvalid, squawk, &Core::Squawk::onLocalPathInvalid);
QObject::connect(squawk, &Core::Squawk::newAccount, &w, &Squawk::newAccount);
QObject::connect(squawk, &Core::Squawk::addContact, &w, &Squawk::addContact);

View File

@ -394,18 +394,21 @@ bool Shared::Message::change(const QMap<QString, QVariant>& data)
itr = data.find("body");
if (itr != data.end()) {
QMap<QString, QVariant>::const_iterator dItr = data.find("stamp");
QDateTime correctionDate;
if (dItr != data.end()) {
correctionDate = dItr.value().toDateTime();
} else {
correctionDate = QDateTime::currentDateTimeUtc(); //in case there is no information about time of this correction it's applied
}
if (!edited || lastModified < correctionDate) {
originalMessage = body;
lastModified = correctionDate;
setBody(itr.value().toString());
setEdited(true);
QString b = itr.value().toString();
if (body != b) {
QMap<QString, QVariant>::const_iterator dItr = data.find("stamp");
QDateTime correctionDate;
if (dItr != data.end()) {
correctionDate = dItr.value().toDateTime();
} else {
correctionDate = QDateTime::currentDateTimeUtc(); //in case there is no information about time of this correction it's applied
}
if (!edited || lastModified < correctionDate) {
originalMessage = body;
lastModified = correctionDate;
setBody(body);
setEdited(true);
}
}
}

View File

@ -33,6 +33,7 @@ Models::Element::Element(Type p_type, const Models::Account* acc, const QString&
connect(feed, &MessageFeed::fileDownloadRequest, this, &Element::fileDownloadRequest);
connect(feed, &MessageFeed::unreadMessagesCountChanged, this, &Element::onFeedUnreadMessagesCountChanged);
connect(feed, &MessageFeed::unnoticedMessage, this, &Element::onFeedUnnoticedMessage);
connect(feed, &MessageFeed::localPathInvalid, this, &Element::localPathInvalid);
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
if (itr != data.end()) {

View File

@ -51,6 +51,7 @@ signals:
void requestArchive(const QString& before);
void fileDownloadRequest(const QString& url);
void unnoticedMessage(const QString& account, const Shared::Message& msg);
void localPathInvalid(const QString& path);
protected:
void setJid(const QString& p_jid);

View File

@ -116,37 +116,39 @@ void Models::MessageFeed::changeMessage(const QString& id, const QMap<QString, Q
}
}
//change message is a final event in download/upload event train
//only after changeMessage we can consider the download is done
Progress::const_iterator dItr = downloads.find(id);
bool attachOrError = changeRoles.count(MessageRoles::Attach) > 0 || changeRoles.count(MessageRoles::Error);
if (dItr != downloads.end()) {
if (attachOrError) {
downloads.erase(dItr);
} else if (changeRoles.count(MessageRoles::Id) > 0) {
qreal progress = dItr->second;
downloads.erase(dItr);
downloads.insert(std::make_pair(msg->getId(), progress));
}
} else {
dItr = uploads.find(id);
if (dItr != uploads.end()) {
if (changeRoles.size() > 0) {
//change message is a final event in download/upload event train
//only after changeMessage we can consider the download is done
Progress::const_iterator dItr = downloads.find(id);
bool attachOrError = changeRoles.count(MessageRoles::Attach) > 0 || changeRoles.count(MessageRoles::Error);
if (dItr != downloads.end()) {
if (attachOrError) {
uploads.erase(dItr);
downloads.erase(dItr);
} else if (changeRoles.count(MessageRoles::Id) > 0) {
qreal progress = dItr->second;
uploads.erase(dItr);
uploads.insert(std::make_pair(msg->getId(), progress));
downloads.erase(dItr);
downloads.insert(std::make_pair(msg->getId(), progress));
}
} else {
dItr = uploads.find(id);
if (dItr != uploads.end()) {
if (attachOrError) {
uploads.erase(dItr);
} else if (changeRoles.count(MessageRoles::Id) > 0) {
qreal progress = dItr->second;
uploads.erase(dItr);
uploads.insert(std::make_pair(msg->getId(), progress));
}
}
}
QVector<int> cr;
for (MessageRoles role : changeRoles) {
cr.push_back(role);
}
emit dataChanged(index, index, cr);
}
QVector<int> cr;
for (MessageRoles role : changeRoles) {
cr.push_back(role);
}
emit dataChanged(index, index, cr);
}
std::set<Models::MessageFeed::MessageRoles> Models::MessageFeed::detectChanges(const Shared::Message& msg, const QMap<QString, QVariant>& data) const
@ -174,13 +176,13 @@ std::set<Models::MessageFeed::MessageRoles> Models::MessageFeed::detectChanges(c
if (state == Shared::Message::State::error) {
itr = data.find("errorText");
if (itr != data.end()) {
if (itr != data.end() && itr.value().toString() != msg.getErrorText()) {
roles.insert(MessageRoles::Error);
}
}
itr = data.find("body");
if (itr != data.end()) {
if (itr != data.end() && itr.value().toString() != msg.getBody()) {
QMap<QString, QVariant>::const_iterator dItr = data.find("stamp");
QDateTime correctionDate;
if (dItr != data.end()) {
@ -522,3 +524,22 @@ QModelIndex Models::MessageFeed::modelIndexByTime(const QString& id, const QDate
return QModelIndex();
}
void Models::MessageFeed::reportLocalPathInvalid(const QString& messageId)
{
StorageById::iterator itr = indexById.find(messageId);
if (itr == indexById.end()) {
qDebug() << "received a command to change a message, but the message couldn't be found, skipping";
return;
}
Shared::Message* msg = *itr;
emit localPathInvalid(msg->getAttachPath());
//gonna change the message in current model right away, to prevent spam on each attemt to draw element
QModelIndex index = modelIndexByTime(messageId, msg->getTime());
msg->setAttachPath("");
emit dataChanged(index, index, {MessageRoles::Attach});
}

View File

@ -60,6 +60,7 @@ public:
void downloadAttachment(const QString& messageId);
void uploadAttachment(const QString& messageId);
bool registerUpload(const QString& messageId);
void reportLocalPathInvalid(const QString& messageId);
unsigned int unreadMessagesCount() const;
void fileProgress(const QString& messageId, qreal value, bool up);
@ -76,6 +77,7 @@ signals:
void unreadMessagesCountChanged();
void newMessage(const Shared::Message& msg);
void unnoticedMessage(const Shared::Message& msg);
void localPathInvalid(const QString& path);
public:
enum MessageRoles {

View File

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

View File

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

View File

@ -64,6 +64,7 @@ Squawk::Squawk(QWidget *parent) :
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive);
connect(&rosterModel, &Models::Roster::fileDownloadRequest, this, &Squawk::fileDownloadRequest);
connect(&rosterModel, &Models::Roster::localPathInvalid, this, &Squawk::localPathInvalid);
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
//m_ui->mainToolBar->addWidget(m_ui->comboBox);

View File

@ -79,6 +79,7 @@ signals:
void requestVCard(const QString& account, const QString& jid);
void uploadVCard(const QString& account, const Shared::VCard& card);
void responsePassword(const QString& account, const QString& password);
void localPathInvalid(const QString& path);
public slots:
void readSettings();

View File

@ -304,6 +304,7 @@ void FeedView::setItemDelegate(QAbstractItemDelegate* delegate)
if (specialDelegate) {
MessageDelegate* del = static_cast<MessageDelegate*>(itemDelegate());
disconnect(del, &MessageDelegate::buttonPushed, this, &FeedView::onMessageButtonPushed);
disconnect(del, &MessageDelegate::invalidPath, this, &FeedView::onMessageInvalidPath);
}
QAbstractItemView::setItemDelegate(delegate);
@ -312,6 +313,7 @@ void FeedView::setItemDelegate(QAbstractItemDelegate* delegate)
if (del) {
specialDelegate = true;
connect(del, &MessageDelegate::buttonPushed, this, &FeedView::onMessageButtonPushed);
connect(del, &MessageDelegate::invalidPath, this, &FeedView::onMessageInvalidPath);
} else {
specialDelegate = false;
}
@ -341,3 +343,12 @@ void FeedView::onMessageButtonPushed(const QString& messageId, bool download)
}
}
}
void FeedView::onMessageInvalidPath(const QString& messageId)
{
if (specialModel) {
Models::MessageFeed* feed = static_cast<Models::MessageFeed*>(model());
feed->reportLocalPathInvalid(messageId);
}
}

View File

@ -55,6 +55,7 @@ protected slots:
void verticalScrollbarValueChanged(int value) override;
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles) override;
void onMessageButtonPushed(const QString& messageId, bool download);
void onMessageInvalidPath(const QString& messageId);
protected:
int verticalOffset() const override;

View File

@ -310,7 +310,11 @@ void MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* paint
start = option.rect.topLeft();
}
QImage img(data.attach.localPath);
painter->drawImage(QRect(start, size), img);
if (img.isNull()) {
emit invalidPath(data.id);
} else {
painter->drawImage(QRect(start, size), img);
}
option.rect.adjust(0, size.height() + textMargin, 0, 0);
}

View File

@ -55,6 +55,7 @@ public:
signals:
void buttonPushed(const QString& messageId, bool download) const;
void invalidPath(const QString& messageId) const;
protected:
void paintButton(QPushButton* btn, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const;