1
0
forked from blue/squawk

first working prototype of file upload

This commit is contained in:
Blue 2019-11-12 16:38:01 +03:00
parent a6e48599aa
commit 166a7ac83a
13 changed files with 244 additions and 97 deletions

View File

@ -39,6 +39,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
rm(client.findExtension<QXmppRosterManager>()), rm(client.findExtension<QXmppRosterManager>()),
vm(client.findExtension<QXmppVCardManager>()), vm(client.findExtension<QXmppVCardManager>()),
um(new QXmppUploadRequestManager()), um(new QXmppUploadRequestManager()),
dm(client.findExtension<QXmppDiscoveryManager>()),
contacts(), contacts(),
conferences(), conferences(),
maxReconnectTimes(0), maxReconnectTimes(0),
@ -93,6 +94,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
QObject::connect(um, &QXmppUploadRequestManager::slotReceived, this, &Account::onUploadSlotReceived); QObject::connect(um, &QXmppUploadRequestManager::slotReceived, this, &Account::onUploadSlotReceived);
QObject::connect(um, &QXmppUploadRequestManager::requestFailed, this, &Account::onUploadSlotRequestFailed); QObject::connect(um, &QXmppUploadRequestManager::requestFailed, this, &Account::onUploadSlotRequestFailed);
QObject::connect(dm, &QXmppDiscoveryManager::itemsReceived, this, &Account::onDiscoveryItemsReceived);
QObject::connect(dm, &QXmppDiscoveryManager::infoReceived, this, &Account::onDiscoveryInfoReceived);
QObject::connect(network, &NetworkAccess::uploadFileComplete, this, &Account::onFileUploaded); QObject::connect(network, &NetworkAccess::uploadFileComplete, this, &Account::onFileUploaded);
QObject::connect(network, &NetworkAccess::uploadFileError, this, &Account::onFileUploadError); QObject::connect(network, &NetworkAccess::uploadFileError, this, &Account::onFileUploadError);
@ -196,6 +200,7 @@ void Core::Account::onClientConnected()
reconnectTimes = maxReconnectTimes; reconnectTimes = maxReconnectTimes;
state = Shared::connected; state = Shared::connected;
cm->setCarbonsEnabled(true); cm->setCarbonsEnabled(true);
dm->requestItems(getServer());
emit connectionStateChanged(state); emit connectionStateChanged(state);
} else { } else {
qDebug() << "Something weird had happened - xmpp client reported about successful connection but account wasn't in" << state << "state"; qDebug() << "Something weird had happened - xmpp client reported about successful connection but account wasn't in" << state << "state";
@ -613,6 +618,7 @@ void Core::Account::sendMessage(const Shared::Message& data)
QXmppMessage msg(data.getFrom(), data.getTo(), data.getBody(), data.getThread()); QXmppMessage msg(data.getFrom(), data.getTo(), data.getBody(), data.getThread());
msg.setId(data.getId()); msg.setId(data.getId());
msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible
msg.setOutOfBandUrl(data.getOutOfBandUrl());
RosterItem* ri = 0; RosterItem* ri = 0;
std::map<QString, Contact*>::const_iterator itr = contacts.find(data.getPenPalJid()); std::map<QString, Contact*>::const_iterator itr = contacts.find(data.getPenPalJid());
@ -671,6 +677,9 @@ void Core::Account::sendMessage(const Shared::Message& data, const QString& path
void Core::Account::sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url) void Core::Account::sendMessageWithLocalUploadedFile(Shared::Message msg, const QString& url)
{ {
msg.setOutOfBandUrl(url); msg.setOutOfBandUrl(url);
if (msg.getBody().size() == 0) {
msg.setBody(url);
}
sendMessage(msg); sendMessage(msg);
//TODO removal/progress update //TODO removal/progress update
} }
@ -1654,3 +1663,15 @@ void Core::Account::onFileUploadError(const QString& messageId, const QString& e
pendingMessages.erase(itr); pendingMessages.erase(itr);
} }
} }
void Core::Account::onDiscoveryItemsReceived(const QXmppDiscoveryIq& items)
{
for (QXmppDiscoveryIq::Item item : items.items()) {
dm->requestInfo(item.jid());
}
}
void Core::Account::onDiscoveryInfoReceived(const QXmppDiscoveryIq& info)
{
}

View File

@ -31,6 +31,7 @@
#include <QXmppRosterManager.h> #include <QXmppRosterManager.h>
#include <QXmppCarbonManager.h> #include <QXmppCarbonManager.h>
#include <QXmppDiscoveryManager.h>
#include <QXmppMamManager.h> #include <QXmppMamManager.h>
#include <QXmppMucManager.h> #include <QXmppMucManager.h>
#include <QXmppClient.h> #include <QXmppClient.h>
@ -133,6 +134,7 @@ private:
QXmppRosterManager* rm; QXmppRosterManager* rm;
QXmppVCardManager* vm; QXmppVCardManager* vm;
QXmppUploadRequestManager* um; QXmppUploadRequestManager* um;
QXmppDiscoveryManager* dm;
std::map<QString, Contact*> contacts; std::map<QString, Contact*> contacts;
std::map<QString, Conference*> conferences; std::map<QString, Conference*> conferences;
unsigned int maxReconnectTimes; unsigned int maxReconnectTimes;
@ -197,6 +199,8 @@ private slots:
void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request); void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request);
void onFileUploaded(const QString& messageId, const QString& url); void onFileUploaded(const QString& messageId, const QString& url);
void onFileUploadError(const QString& messageId, const QString& errMsg); void onFileUploadError(const QString& messageId, const QString& errMsg);
void onDiscoveryItemsReceived (const QXmppDiscoveryIq& items);
void onDiscoveryInfoReceived (const QXmppDiscoveryIq& info);
private: private:
void addedAccount(const QString &bareJid); void addedAccount(const QString &bareJid);

View File

@ -478,12 +478,12 @@ bool Core::NetworkAccess::isUploading(const QString& path, const QString& messag
void Core::NetworkAccess::uploadFile(const QString& messageId, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers) void Core::NetworkAccess::uploadFile(const QString& messageId, const QString& path, const QUrl& put, const QUrl& get, const QMap<QString, QString> headers)
{ {
Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, get.toString(), 0}); QFile* file = new QFile(path);
Transfer* upl = new Transfer({{messageId}, 0, 0, true, path, get.toString(), file});
QNetworkRequest req(put); QNetworkRequest req(put);
for (QMap<QString, QString>::const_iterator itr = headers.begin(), end = headers.end(); itr != end; itr++) { for (QMap<QString, QString>::const_iterator itr = headers.begin(), end = headers.end(); itr != end; itr++) {
req.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8()); req.setRawHeader(itr.key().toUtf8(), itr.value().toUtf8());
} }
QFile* file = new QFile(path);
if (file->open(QIODevice::ReadOnly)) { if (file->open(QIODevice::ReadOnly)) {
upl->reply = manager->put(req, file); upl->reply = manager->put(req, file);

2
external/qxmpp vendored

@ -1 +1 @@
Subproject commit b18a57daa33f0fefa5f4c63aa7f448b48d302e0d Subproject commit f8c546c5b701c53d708a38a951fcc734eaee7940

View File

@ -79,6 +79,11 @@ int main(int argc, char *argv[])
QThread* coreThread = new QThread(); QThread* coreThread = new QThread();
squawk->moveToThread(coreThread); squawk->moveToThread(coreThread);
QObject::connect(coreThread, &QThread::started, squawk, &Core::Squawk::start);
QObject::connect(&app, &QApplication::aboutToQuit, squawk, &Core::Squawk::stop);
QObject::connect(squawk, &Core::Squawk::quit, coreThread, &QThread::quit);
QObject::connect(coreThread, &QThread::finished, squawk, &Core::Squawk::deleteLater);
QObject::connect(&w, &Squawk::newAccountRequest, squawk, &Core::Squawk::newAccountRequest); QObject::connect(&w, &Squawk::newAccountRequest, squawk, &Core::Squawk::newAccountRequest);
QObject::connect(&w, &Squawk::modifyAccountRequest, squawk, &Core::Squawk::modifyAccountRequest); QObject::connect(&w, &Squawk::modifyAccountRequest, squawk, &Core::Squawk::modifyAccountRequest);
QObject::connect(&w, &Squawk::removeAccountRequest, squawk, &Core::Squawk::removeAccountRequest); QObject::connect(&w, &Squawk::removeAccountRequest, squawk, &Core::Squawk::removeAccountRequest);
@ -129,10 +134,10 @@ int main(int argc, char *argv[])
QObject::connect(squawk, &Core::Squawk::changeRoomParticipant, &w, &Squawk::changeRoomParticipant); QObject::connect(squawk, &Core::Squawk::changeRoomParticipant, &w, &Squawk::changeRoomParticipant);
QObject::connect(squawk, &Core::Squawk::removeRoomParticipant, &w, &Squawk::removeRoomParticipant); QObject::connect(squawk, &Core::Squawk::removeRoomParticipant, &w, &Squawk::removeRoomParticipant);
QObject::connect(squawk, &Core::Squawk::fileLocalPathResponse, &w, &Squawk::fileLocalPathResponse); QObject::connect(squawk, &Core::Squawk::fileLocalPathResponse, &w, &Squawk::fileLocalPathResponse);
QObject::connect(squawk, &Core::Squawk::downloadFileProgress, &w, &Squawk::downloadFileProgress); QObject::connect(squawk, &Core::Squawk::downloadFileProgress, &w, &Squawk::fileProgress);
QObject::connect(squawk, &Core::Squawk::downloadFileError, &w, &Squawk::downloadFileError); QObject::connect(squawk, &Core::Squawk::downloadFileError, &w, &Squawk::fileError);
QObject::connect(squawk, &Core::Squawk::uploadFileProgress, &w, &Squawk::uploadFileProgress); QObject::connect(squawk, &Core::Squawk::uploadFileProgress, &w, &Squawk::fileProgress);
QObject::connect(squawk, &Core::Squawk::uploadFileError, &w, &Squawk::uploadFileError); QObject::connect(squawk, &Core::Squawk::uploadFileError, &w, &Squawk::fileError);
QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard); QObject::connect(squawk, &Core::Squawk::responseVCard, &w, &Squawk::responseVCard);
coreThread->start(); coreThread->start();

View File

@ -369,11 +369,11 @@ void Squawk::onConversationDownloadFile(const QString& messageId, const QString&
} }
} }
void Squawk::downloadFileProgress(const QString& messageId, qreal value) void Squawk::fileProgress(const QString& messageId, qreal value)
{ {
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId); std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
if (itr == requestedFiles.end()) { if (itr == requestedFiles.end()) {
qDebug() << "downloadFileProgress in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping"; qDebug() << "fileProgress in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping";
return; return;
} else { } else {
const std::set<Models::Roster::ElId>& convs = itr->second; const std::set<Models::Roster::ElId>& convs = itr->second;
@ -381,17 +381,17 @@ void Squawk::downloadFileProgress(const QString& messageId, qreal value)
const Models::Roster::ElId& id = *cItr; const Models::Roster::ElId& id = *cItr;
Conversations::const_iterator c = conversations.find(id); Conversations::const_iterator c = conversations.find(id);
if (c != conversations.end()) { if (c != conversations.end()) {
c->second->responseDownloadProgress(messageId, value); c->second->responseFileProgress(messageId, value);
} }
} }
} }
} }
void Squawk::downloadFileError(const QString& messageId, const QString& error) void Squawk::fileError(const QString& messageId, const QString& error)
{ {
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId); std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
if (itr == requestedFiles.end()) { if (itr == requestedFiles.end()) {
qDebug() << "downloadFileError in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping"; qDebug() << "fileError in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping";
return; return;
} else { } else {
const std::set<Models::Roster::ElId>& convs = itr->second; const std::set<Models::Roster::ElId>& convs = itr->second;
@ -399,7 +399,7 @@ void Squawk::downloadFileError(const QString& messageId, const QString& error)
const Models::Roster::ElId& id = *cItr; const Models::Roster::ElId& id = *cItr;
Conversations::const_iterator c = conversations.find(id); Conversations::const_iterator c = conversations.find(id);
if (c != conversations.end()) { if (c != conversations.end()) {
c->second->downloadError(messageId, error); c->second->fileError(messageId, error);
} }
} }
requestedFiles.erase(itr); requestedFiles.erase(itr);
@ -497,6 +497,9 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path) void Squawk::onConversationMessage(const Shared::Message& msg, const QString& path)
{ {
Conversation* conv = static_cast<Conversation*>(sender()); Conversation* conv = static_cast<Conversation*>(sender());
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.insert(std::make_pair(msg.getId(), std::set<Models::Roster::ElId>())).first;
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
emit sendMessage(conv->getAccount(), msg, path); emit sendMessage(conv->getAccount(), msg, path);
} }

View File

@ -98,10 +98,8 @@ public slots:
void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data); void changeRoomParticipant(const QString& account, const QString& jid, const QString& name, const QMap<QString, QVariant>& data);
void removeRoomParticipant(const QString& account, const QString& jid, const QString& name); void removeRoomParticipant(const QString& account, const QString& jid, const QString& name);
void fileLocalPathResponse(const QString& messageId, const QString& path); void fileLocalPathResponse(const QString& messageId, const QString& path);
void downloadFileError(const QString& messageId, const QString& error); void fileError(const QString& messageId, const QString& error);
void downloadFileProgress(const QString& messageId, qreal value); void fileProgress(const QString& messageId, qreal value);
void uploadFileError(const QString& messageId, const QString& error);
void uploadFileProgress(const QString& messageId, qreal value);
void responseVCard(const QString& jid, const Shared::VCard& card); void responseVCard(const QString& jid, const Shared::VCard& card);
private: private:

View File

@ -34,11 +34,11 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
sender(new QLabel(p_sender)), sender(new QLabel(p_sender)),
text(new QLabel()), text(new QLabel()),
shadow(new QGraphicsDropShadowEffect()), shadow(new QGraphicsDropShadowEffect()),
downloadButton(0), button(0),
file(0), file(0),
progress(0), progress(0),
fileComment(new QLabel()), fileComment(new QLabel()),
hasDownloadButton(false), hasButton(false),
hasProgress(false), hasProgress(false),
hasFile(false), hasFile(false),
commentAdded(false) commentAdded(false)
@ -77,13 +77,13 @@ Message::Message(const Shared::Message& source, bool outgoing, const QString& p_
body->setGraphicsEffect(shadow); body->setGraphicsEffect(shadow);
if (outgoing) { if (outgoing) {
addWidget(body);
addStretch();
} else {
sender->setAlignment(Qt::AlignRight); sender->setAlignment(Qt::AlignRight);
date->setAlignment(Qt::AlignRight); date->setAlignment(Qt::AlignRight);
addStretch(); addStretch();
addWidget(body); addWidget(body);
} else {
addWidget(body);
addStretch();
} }
} }
@ -109,35 +109,28 @@ void Message::setSender(const QString& p_sender)
sender->setText(p_sender); sender->setText(p_sender);
} }
void Message::addButton(const QIcon& icon, const QString& buttonText, const QString& comment) void Message::addButton(const QIcon& icon, const QString& buttonText)
{ {
hideFile(); hideFile();
hideProgress(); hideProgress();
if (!hasDownloadButton) { if (!hasButton) {
hideComment(); hideComment();
if (msg.getBody() == msg.getOutOfBandUrl()) { if (msg.getBody() == msg.getOutOfBandUrl()) {
text->setText(""); text->setText("");
text->hide(); text->hide();
} }
downloadButton = new QPushButton(icon, buttonText); button = new QPushButton(icon, buttonText);
downloadButton->setToolTip("<a href=\"" + msg.getOutOfBandUrl() + "\">" + msg.getOutOfBandUrl() + "</a>"); button->setToolTip("<a href=\"" + msg.getOutOfBandUrl() + "\">" + msg.getOutOfBandUrl() + "</a>");
if (comment.size() != 0) { connect(button, &QPushButton::clicked, this, &Message::buttonClicked);
fileComment->setWordWrap(true); bodyLayout->insertWidget(2, button);
fileComment->setText(comment); hasButton = true;
fileComment->show();
}
connect(downloadButton, &QPushButton::clicked, this, &Message::downloadFile);
bodyLayout->insertWidget(2, fileComment);
bodyLayout->insertWidget(3, downloadButton);
hasDownloadButton = true;
commentAdded = true;
} }
} }
void Message::setProgress(qreal value, const QString& label) void Message::setProgress(qreal value)
{ {
hideFile(); hideFile();
hideDownload(); hideButton();
if (!hasProgress) { if (!hasProgress) {
hideComment(); hideComment();
if (msg.getBody() == msg.getOutOfBandUrl()) { if (msg.getBody() == msg.getOutOfBandUrl()) {
@ -146,21 +139,15 @@ void Message::setProgress(qreal value, const QString& label)
} }
progress = new QProgressBar(); progress = new QProgressBar();
progress->setRange(0, 100); progress->setRange(0, 100);
if (label.size() != 0) {
fileComment->setText(label);
}
fileComment->show();
bodyLayout->insertWidget(2, progress); bodyLayout->insertWidget(2, progress);
bodyLayout->insertWidget(3, fileComment);
hasProgress = true; hasProgress = true;
commentAdded = true;
} }
progress->setValue(value * 100); progress->setValue(value * 100);
} }
void Message::showFile(const QString& path) void Message::showFile(const QString& path)
{ {
hideDownload(); hideButton();
hideProgress(); hideProgress();
if (!hasFile) { if (!hasFile) {
hideComment(); hideComment();
@ -173,16 +160,13 @@ void Message::showFile(const QString& path)
QStringList parts = type.name().split("/"); QStringList parts = type.name().split("/");
QString big = parts.front(); QString big = parts.front();
QFileInfo info(path); QFileInfo info(path);
fileComment = new QLabel();
if (big == "image") { if (big == "image") {
file = new Image(path); file = new Image(path);
} else { } else {
file = new QLabel(); file = new QLabel();
file->setPixmap(QIcon::fromTheme(type.iconName()).pixmap(50)); file->setPixmap(QIcon::fromTheme(type.iconName()).pixmap(50));
file->setAlignment(Qt::AlignCenter); file->setAlignment(Qt::AlignCenter);
fileComment->setText(info.fileName()); showComment(info.fileName(), true);
fileComment->setWordWrap(true);
fileComment->show();
} }
file->setContextMenuPolicy(Qt::ActionsContextMenu); file->setContextMenuPolicy(Qt::ActionsContextMenu);
QAction* openAction = new QAction(QIcon::fromTheme("document-new-from-template"), tr("Open"), file); QAction* openAction = new QAction(QIcon::fromTheme("document-new-from-template"), tr("Open"), file);
@ -191,9 +175,7 @@ void Message::showFile(const QString& path)
}); });
file->addAction(openAction); file->addAction(openAction);
bodyLayout->insertWidget(2, file); bodyLayout->insertWidget(2, file);
bodyLayout->insertWidget(3, fileComment);
hasFile = true; hasFile = true;
commentAdded = true;
} }
} }
@ -206,12 +188,12 @@ void Message::hideComment()
} }
} }
void Message::hideDownload() void Message::hideButton()
{ {
if (hasDownloadButton) { if (hasButton) {
downloadButton->deleteLater(); button->deleteLater();
downloadButton = 0; button = 0;
hasDownloadButton = false; hasButton = false;
} }
} }
@ -232,3 +214,29 @@ void Message::hideProgress()
hasProgress = false;; hasProgress = false;;
} }
} }
void Message::showComment(const QString& comment, bool wordWrap)
{
if (!commentAdded) {
int index = 2;
if (hasFile) {
index++;
}
if (hasButton) {
index++;
}
if (hasProgress) {
index++;
}
bodyLayout->insertWidget(index, fileComment);
fileComment->show();
commentAdded = true;
}
fileComment->setWordWrap(wordWrap);
fileComment->setText(comment);
}
const Shared::Message & Message::getMessage() const
{
return msg;
}

View File

@ -47,13 +47,16 @@ public:
void setSender(const QString& sender); void setSender(const QString& sender);
QString getId() const; QString getId() const;
QString getFileUrl() const; QString getFileUrl() const;
const Shared::Message& getMessage() const;
void addButton(const QIcon& icon, const QString& buttonText, const QString& comment = ""); void addButton(const QIcon& icon, const QString& buttonText);
void showComment(const QString& comment, bool wordWrap = false);
void hideComment();
void showFile(const QString& path); void showFile(const QString& path);
void setProgress(qreal value, const QString& label = ""); void setProgress(qreal value);
signals: signals:
void downloadFile(); void buttonClicked();
private: private:
Shared::Message msg; Shared::Message msg;
@ -63,20 +66,19 @@ private:
QLabel* sender; QLabel* sender;
QLabel* text; QLabel* text;
QGraphicsDropShadowEffect* shadow; QGraphicsDropShadowEffect* shadow;
QPushButton* downloadButton; QPushButton* button;
QLabel* file; QLabel* file;
QProgressBar* progress; QProgressBar* progress;
QLabel* fileComment; QLabel* fileComment;
bool hasDownloadButton; bool hasButton;
bool hasProgress; bool hasProgress;
bool hasFile; bool hasFile;
bool commentAdded; bool commentAdded;
private: private:
void hideDownload(); void hideButton();
void hideProgress(); void hideProgress();
void hideFile(); void hideFile();
void hideComment();
}; };
#endif // MESSAGE_H #endif // MESSAGE_H

View File

@ -30,7 +30,6 @@ MessageLine::MessageLine(bool p_room, QWidget* parent):
layout(new QVBoxLayout(this)), layout(new QVBoxLayout(this)),
myName(), myName(),
palNames(), palNames(),
views(),
uploading(), uploading(),
downloading(), downloading(),
room(p_room), room(p_room),
@ -63,15 +62,15 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
if (room) { if (room) {
if (msg.getFromResource() == myName) { if (msg.getFromResource() == myName) {
sender = myName; sender = myName;
outgoing = false; outgoing = true;
} else { } else {
sender = msg.getFromResource(); sender = msg.getFromResource();
outgoing = true; outgoing = false;
} }
} else { } else {
if (msg.getOutgoing()) { if (msg.getOutgoing()) {
sender = myName; sender = myName;
outgoing = false; outgoing = true;
} else { } else {
QString jid = msg.getFromJid(); QString jid = msg.getFromJid();
std::map<QString, QString>::iterator itr = palNames.find(jid); std::map<QString, QString>::iterator itr = palNames.find(jid);
@ -80,7 +79,7 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
} else { } else {
sender = jid; sender = jid;
} }
outgoing = true; outgoing = false;
} }
} }
@ -93,6 +92,8 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
return invalid; return invalid;
} }
if (outgoing) { if (outgoing) {
myMessages.insert(std::make_pair(id, message));
} else {
if (room) { if (room) {
} else { } else {
@ -103,8 +104,6 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
} }
pItr->second.insert(std::make_pair(id, message)); pItr->second.insert(std::make_pair(id, message));
} }
} else {
myMessages.insert(std::make_pair(id, message));
} }
messageIndex.insert(std::make_pair(id, message)); messageIndex.insert(std::make_pair(id, message));
int index = std::distance<Order::const_iterator>(messageOrder.begin(), result.first); //need to make with binary indexed tree int index = std::distance<Order::const_iterator>(messageOrder.begin(), result.first); //need to make with binary indexed tree
@ -130,7 +129,7 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
if (msg.hasOutOfBandUrl()) { if (msg.hasOutOfBandUrl()) {
emit requestLocalFile(msg.getId(), msg.getOutOfBandUrl()); emit requestLocalFile(msg.getId(), msg.getOutOfBandUrl());
connect(message, &Message::downloadFile, this, &MessageLine::onDownload); connect(message, &Message::buttonClicked, this, &MessageLine::onDownload);
} }
return res; return res;
@ -143,6 +142,8 @@ void MessageLine::onDownload()
Index::const_iterator itr = downloading.find(messageId); Index::const_iterator itr = downloading.find(messageId);
if (itr == downloading.end()) { if (itr == downloading.end()) {
downloading.insert(std::make_pair(messageId, msg)); downloading.insert(std::make_pair(messageId, msg));
msg->setProgress(0);
msg->showComment(tr("Downloading..."));
emit downloadFile(messageId, msg->getFileUrl()); emit downloadFile(messageId, msg->getFileUrl());
} else { } else {
qDebug() << "An attempt to initiate download for already downloading file" << msg->getFileUrl() << ", skipping"; qDebug() << "An attempt to initiate download for already downloading file" << msg->getFileUrl() << ", skipping";
@ -210,16 +211,11 @@ void MessageLine::hideBusyIndicator()
void MessageLine::fileProgress(const QString& messageId, qreal progress) void MessageLine::fileProgress(const QString& messageId, qreal progress)
{ {
Index::const_iterator itr = downloading.find(messageId); Index::const_iterator itr = messageIndex.find(messageId);
if (itr == downloading.end()) { if (itr == messageIndex.end()) {
Index::const_iterator itr = uploading.find(messageId); //TODO may be some logging, that's not normal
if (itr == uploading.end()) {
//TODO may be some logging, that's not normal
} else {
itr->second->setProgress(progress, tr("Uploading..."));
}
} else { } else {
itr->second->setProgress(progress, tr("Downloading...")); itr->second->setProgress(progress);
} }
} }
@ -229,14 +225,88 @@ void MessageLine::responseLocalFile(const QString& messageId, const QString& pat
if (itr == messageIndex.end()) { if (itr == messageIndex.end()) {
} else { } else {
Index::const_iterator uItr = uploading.find(messageId);
if (path.size() > 0) { if (path.size() > 0) {
itr->second->showFile(path); Index::const_iterator dItr = downloading.find(messageId);
if (dItr != downloading.end()) {
downloading.erase(dItr);
itr->second->showFile(path);
} else {
if (uItr != uploading.end()) {
uploading.erase(uItr);
std::map<QString, QString>::const_iterator muItr = uploadPaths.find(messageId);
if (muItr != uploadPaths.end()) {
uploadPaths.erase(muItr);
}
if (room) {
removeMessage(messageId);
} else {
Shared::Message msg = itr->second->getMessage();
removeMessage(messageId);
msg.setCurrentTime();
message(msg);
itr = messageIndex.find(messageId);
itr->second->showFile(path);
}
} else {
itr->second->showFile(path); //then it is already cached file
}
}
} else { } else {
itr->second->addButton(QIcon::fromTheme("download"), tr("Download"), tr("Push the button to daownload the file")); if (uItr != uploading.end()) {
itr->second->addButton(QIcon::fromTheme("download"), tr("Download"));
itr->second->showComment(tr("Push the button to daownload the file"));
} else {
qDebug() << "An unhandled state for file uploading - empty path";
}
} }
} }
} }
void MessageLine::removeMessage(const QString& messageId)
{
Index::const_iterator itr = messageIndex.find(messageId);
if (itr != messageIndex.end()) {
Message* ui = itr->second;
const Shared::Message& msg = ui->getMessage();
messageIndex.erase(itr);
Order::const_iterator oItr = messageOrder.find(msg.getTime());
if (oItr != messageOrder.end()) {
messageOrder.erase(oItr);
} else {
qDebug() << "An attempt to remove message from messageLine, but it wasn't found in order";
}
if (msg.getOutgoing()) {
Index::const_iterator mItr = myMessages.find(messageId);
if (mItr != myMessages.end()) {
myMessages.erase(mItr);
} else {
qDebug() << "Error removing message: it seems to be outgoing yet it wasn't found in outgoing messages";
}
} else {
if (room) {
} else {
QString jid = msg.getFromJid();
std::map<QString, Index>::iterator pItr = palMessages.find(jid);
if (pItr != palMessages.end()) {
Index& pMsgs = pItr->second;
Index::const_iterator pmitr = pMsgs.find(messageId);
if (pmitr != pMsgs.end()) {
pMsgs.erase(pmitr);
} else {
qDebug() << "Error removing message: it seems to be incoming yet it wasn't found among messages from that penpal";
}
}
}
}
ui->deleteLater();
qDebug() << "message" << messageId << "has been removed";
} else {
qDebug() << "An attempt to remove non existing message from messageLine";
}
}
void MessageLine::fileError(const QString& messageId, const QString& error) void MessageLine::fileError(const QString& messageId, const QString& error)
{ {
Index::const_iterator itr = downloading.find(messageId); Index::const_iterator itr = downloading.find(messageId);
@ -245,18 +315,29 @@ void MessageLine::fileError(const QString& messageId, const QString& error)
if (itr == uploading.end()) { if (itr == uploading.end()) {
//TODO may be some logging, that's not normal //TODO may be some logging, that's not normal
} else { } else {
//itr->second->showError(error); itr->second->showComment(tr("Error uploading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", error.toLatin1())), true);
//itr->second->addDownloadDialog(); itr->second->addButton(QIcon::fromTheme("upload"), tr("Upload"));
} }
} else { } else {
itr->second->addButton(QIcon::fromTheme("download"), tr("Download"), itr->second->addButton(QIcon::fromTheme("download"), tr("Download"));
tr("Error downloading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", error.toLatin1()))); itr->second->showComment(tr("Error downloading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", error.toLatin1())), true);
} }
} }
void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QString& path) void MessageLine::appendMessageWithUpload(const Shared::Message& msg, const QString& path)
{ {
message(msg); message(msg);
QString id = msg.getId();
Message* ui = messageIndex.find(id)->second;
connect(ui, &Message::buttonClicked, this, &MessageLine::onUpload); //this is in case of retry;
ui->setProgress(0);
ui->showComment("Uploading...");
uploading.insert(std::make_pair(id, ui));
uploadPaths.insert(std::make_pair(id, path));
emit uploadFile(msg, path);
} }
void MessageLine::onUpload()
{
//TODO retry
}

View File

@ -53,6 +53,7 @@ public:
void fileError(const QString& messageId, const QString& error); void fileError(const QString& messageId, const QString& error);
void fileProgress(const QString& messageId, qreal progress); void fileProgress(const QString& messageId, qreal progress);
void appendMessageWithUpload(const Shared::Message& message, const QString& path); void appendMessageWithUpload(const Shared::Message& message, const QString& path);
void removeMessage(const QString& messageId);
signals: signals:
void resize(int amount); void resize(int amount);
@ -65,6 +66,7 @@ protected:
protected: protected:
void onDownload(); void onDownload();
void onUpload();
private: private:
struct Comparator { struct Comparator {
@ -86,7 +88,6 @@ private:
QString myName; QString myName;
std::map<QString, QString> palNames; std::map<QString, QString> palNames;
std::deque<QHBoxLayout*> views;
Index uploading; Index uploading;
Index downloading; Index downloading;
bool room; bool room;

View File

@ -66,6 +66,7 @@ Conversation::Conversation(bool muc, const QString& mJid, const QString mRes, co
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed); connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize); connect(line, &MessageLine::resize, this, &Conversation::onMessagesResize);
connect(line, &MessageLine::downloadFile, this, &Conversation::downloadFile); 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(line, &MessageLine::requestLocalFile, this, &Conversation::requestLocalFile);
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach); connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
@ -180,9 +181,32 @@ void Conversation::onEnterPressed()
{ {
QString body(m_ui->messageEditor->toPlainText()); QString body(m_ui->messageEditor->toPlainText());
if (body.size() > 0) { if (filesToAttach.size() > 0) {
m_ui->messageEditor->clear(); for (Badge* badge : filesToAttach) {
handleSendMessage(body); Shared::Message msg;
if (isMuc) {
msg.setType(Shared::Message::groupChat);
} else {
msg.setType(Shared::Message::chat);
msg.setToResource(activePalResource);
}
msg.setFromJid(myJid);
msg.setFromResource(myResource);
msg.setToJid(palJid);
msg.setOutgoing(true);
msg.generateRandomId();
msg.setCurrentTime();
if (body.size() > 0) {
msg.setBody(body);
}
line->appendMessageWithUpload(msg, badge->id);
}
clearAttachedFiles();
} else {
if (body.size() > 0) {
m_ui->messageEditor->clear();
handleSendMessage(body);
}
} }
} }
@ -294,14 +318,14 @@ void Conversation::onScrollResize()
} }
} }
void Conversation::responseDownloadProgress(const QString& messageId, qreal progress) void Conversation::responseFileProgress(const QString& messageId, qreal progress)
{ {
line->responseDownloadProgress(messageId, progress); line->fileProgress(messageId, progress);
} }
void Conversation::downloadError(const QString& messageId, const QString& error) void Conversation::fileError(const QString& messageId, const QString& error)
{ {
line->downloadError(messageId, error); line->fileError(messageId, error);
} }
void Conversation::responseLocalFile(const QString& messageId, const QString& path) void Conversation::responseLocalFile(const QString& messageId, const QString& path)

View File

@ -75,8 +75,8 @@ public:
void responseArchive(const std::list<Shared::Message> list); void responseArchive(const std::list<Shared::Message> list);
void showEvent(QShowEvent * event) override; void showEvent(QShowEvent * event) override;
void responseLocalFile(const QString& messageId, const QString& path); void responseLocalFile(const QString& messageId, const QString& path);
void downloadError(const QString& messageId, const QString& error); void fileError(const QString& messageId, const QString& error);
void responseDownloadProgress(const QString& messageId, qreal progress); void responseFileProgress(const QString& messageId, qreal progress);
signals: signals:
void sendMessage(const Shared::Message& message); void sendMessage(const Shared::Message& message);