First steps on the new idea of file up/downloading

This commit is contained in:
Blue 2021-04-18 15:49:20 +03:00
parent 8f914c02a7
commit 3a7735b192
23 changed files with 650 additions and 525 deletions

View file

@ -30,7 +30,7 @@ Models::Element::Element(Type p_type, const Models::Account* acc, const QString&
feed(new MessageFeed(this))
{
connect(feed, &MessageFeed::requestArchive, this, &Element::requestArchive);
connect(feed, &MessageFeed::fileLocalPathRequest, this, &Element::fileLocalPathRequest);
connect(feed, &MessageFeed::fileDownloadRequest, this, &Element::fileDownloadRequest);
QMap<QString, QVariant>::const_iterator itr = data.find("avatarState");
if (itr != data.end()) {
@ -156,8 +156,17 @@ bool Models::Element::isRoom() const
return type != contact;
}
void Models::Element::fileProgress(const QString& messageId, qreal value)
void Models::Element::fileProgress(const QString& messageId, qreal value, bool up)
{
feed->fileProgress(messageId, value);
feed->fileProgress(messageId, value, up);
}
void Models::Element::fileComplete(const QString& messageId, bool up)
{
feed->fileComplete(messageId, up);
}
void Models::Element::fileError(const QString& messageId, const QString& error, bool up)
{
feed->fileError(messageId, error, up);
}

View file

@ -43,11 +43,13 @@ public:
unsigned int getMessagesCount() const;
void responseArchive(const std::list<Shared::Message> list, bool last);
bool isRoom() const;
void fileProgress(const QString& messageId, qreal value);
void fileProgress(const QString& messageId, qreal value, bool up);
void fileError(const QString& messageId, const QString& error, bool up);
void fileComplete(const QString& messageId, bool up);
signals:
void requestArchive(const QString& before);
void fileLocalPathRequest(const QString& messageId, const QString& url);
void fileDownloadRequest(const QString& url);
protected:
void setJid(const QString& p_jid);

View file

@ -305,7 +305,7 @@ void Models::MessageFeed::downloadAttachment(const QString& messageId)
if (progressPair.second) { //Only to take action if we weren't already downloading it
Shared::Message* msg = static_cast<Shared::Message*>(ind.internalPointer());
emit dataChanged(ind, ind);
emit fileLocalPathRequest(messageId, msg->getOutOfBandUrl());
emit fileDownloadRequest(msg->getOutOfBandUrl());
} else {
qDebug() << "Attachment download for message with id" << messageId << "is already in progress, skipping";
}
@ -319,16 +319,34 @@ void Models::MessageFeed::uploadAttachment(const QString& messageId)
qDebug() << "request to upload attachment of the message" << messageId;
}
void Models::MessageFeed::fileProgress(const QString& messageId, qreal value)
void Models::MessageFeed::fileProgress(const QString& messageId, qreal value, bool up)
{
Progress::iterator itr = downloads.find(messageId);
if (itr != downloads.end()) {
Progress* pr = 0;
if (up) {
pr = &uploads;
} else {
pr = &downloads;
}
Progress::iterator itr = pr->find(messageId);
if (itr != pr->end()) {
itr->second = value;
QModelIndex ind = modelIndexById(messageId);
emit dataChanged(ind, ind);
}
}
void Models::MessageFeed::fileComplete(const QString& messageId, bool up)
{
//TODO
}
void Models::MessageFeed::fileError(const QString& messageId, const QString& error, bool up)
{
//TODO
}
QModelIndex Models::MessageFeed::modelIndexById(const QString& id) const
{
StorageById::const_iterator itr = indexById.find(id);

View file

@ -59,12 +59,14 @@ public:
void uploadAttachment(const QString& messageId);
unsigned int unreadMessagesCount() const;
void fileProgress(const QString& messageId, qreal value);
void fileProgress(const QString& messageId, qreal value, bool up);
void fileError(const QString& messageId, const QString& error, bool up);
void fileComplete(const QString& messageId, bool up);
signals:
void requestArchive(const QString& before);
void requestStateChange(bool requesting);
void fileLocalPathRequest(const QString& messageId, const QString& url);
void fileDownloadRequest(const QString& url);
protected:
bool sentByMe(const Shared::Message& msg) const;
@ -141,6 +143,8 @@ enum AttachmentType {
local,
downloading,
uploading,
errorDownload,
errorUpload,
ready
};

View file

@ -27,8 +27,7 @@ Models::Roster::Roster(QObject* parent):
root(new Item(Item::root, {{"name", "root"}})),
accounts(),
groups(),
contacts(),
requestedFiles()
contacts()
{
connect(accountsModel, &Accounts::dataChanged, this, &Roster::onAccountDataChanged);
connect(root, &Item::childChanged, this, &Roster::onChildChanged);
@ -448,7 +447,7 @@ void Models::Roster::addContact(const QString& account, const QString& jid, cons
if (itr == contacts.end()) {
contact = new Contact(acc, jid, data);
connect(contact, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
connect(contact, &Contact::fileLocalPathRequest, this, &Roster::onElementFileLocalPathRequest);
connect(contact, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
contacts.insert(std::make_pair(id, contact));
} else {
contact = itr->second;
@ -534,35 +533,19 @@ 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)
{
ElId id(account, jid);
std::map<ElId, Contact*>::iterator cItr = contacts.find(id);
if (cItr != contacts.end()) {
Element* el = getElement({account, jid});
if (el != NULL) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
cItr->second->update(itr.key(), itr.value());
}
} else {
std::map<ElId, Room*>::iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
for (QMap<QString, QVariant>::const_iterator itr = data.begin(), end = data.end(); itr != end; ++itr) {
rItr->second->update(itr.key(), itr.value());
}
el->update(itr.key(), itr.value());
}
}
}
void Models::Roster::changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
{
ElId elid(account, jid);
std::map<ElId, Contact*>::iterator cItr = contacts.find(elid);
if (cItr != contacts.end()) {
cItr->second->changeMessage(id, data);
} else {
std::map<ElId, Room*>::iterator rItr = rooms.find(elid);
if (rItr != rooms.end()) {
rItr->second->changeMessage(id, data);
}
Element* el = getElement({account, jid});
if (el != NULL) {
el->changeMessage(id, data);
}
}
@ -626,7 +609,6 @@ void Models::Roster::removeContact(const QString& account, const QString& jid, c
} else {
delete ref;
}
if (gr->childCount() == 0) {
removeGroup(account, group);
}
@ -707,15 +689,9 @@ void Models::Roster::removePresence(const QString& account, const QString& jid,
void Models::Roster::addMessage(const QString& account, const Shared::Message& data)
{
ElId id(account, data.getPenPalJid());
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
if (itr != contacts.end()) {
itr->second->addMessage(data);
} else {
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
rItr->second->addMessage(data);
}
Element* el = getElement({account, data.getPenPalJid()});
if (el != NULL) {
el->addMessage(data);
}
}
@ -808,7 +784,7 @@ void Models::Roster::addRoom(const QString& account, const QString jid, const QM
Room* room = new Room(acc, jid, data);
connect(room, &Contact::requestArchive, this, &Roster::onElementRequestArchive);
connect(room, &Contact::fileLocalPathRequest, this, &Roster::onElementFileLocalPathRequest);
connect(room, &Contact::fileDownloadRequest, this, &Roster::fileDownloadRequest);
rooms.insert(std::make_pair(id, room));
acc->appendChild(room);
}
@ -971,51 +947,55 @@ void Models::Roster::onElementRequestArchive(const QString& before)
void Models::Roster::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last)
{
ElId id(account, jid);
std::map<ElId, Contact*>::iterator itr = contacts.find(id);
if (itr != contacts.end()) {
itr->second->responseArchive(list, last);
Element* el = getElement(id);
if (el != NULL) {
el->responseArchive(list, last);
}
}
void Models::Roster::fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up)
{
for (const Shared::MessageInfo& info : msgs) {
Element* el = getElement({info.account, info.jid});
if (el != NULL) {
el->fileProgress(info.messageId, value, up);
}
}
}
void Models::Roster::fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up)
{
for (const Shared::MessageInfo& info : msgs) {
Element* el = getElement({info.account, info.jid});
if (el != NULL) {
el->fileComplete(info.messageId, up);
}
}
}
void Models::Roster::fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up)
{
for (const Shared::MessageInfo& info : msgs) {
Element* el = getElement({info.account, info.jid});
if (el != NULL) {
el->fileError(info.messageId, err, up);
}
}
}
Models::Element * Models::Roster::getElement(const Models::Roster::ElId& id)
{
std::map<ElId, Contact*>::iterator cItr = contacts.find(id);
if (cItr != contacts.end()) {
return cItr->second;
} else {
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
std::map<ElId, Room*>::iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
rItr->second->responseArchive(list, last);
}
}
}
void Models::Roster::onElementFileLocalPathRequest(const QString& messageId, const QString& url)
{
Element* el = static_cast<Element*>(sender());
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
bool created = false;
if (itr == requestedFiles.end()) {
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
created = true;
}
itr->second.insert(Models::Roster::ElId(el->getAccountName(), el->getJid()));
if (created) {
emit fileLocalPathRequest(messageId, url);
}
}
void Models::Roster::fileProgress(const QString& messageId, qreal value)
{
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
if (itr == requestedFiles.end()) {
qDebug() << "fileProgress in UI but there is nobody waiting for that id:" << messageId << ", skipping";
return;
} else {
const std::set<Models::Roster::ElId>& convs = itr->second;
for (const Models::Roster::ElId& id : convs) {
std::map<ElId, Contact*>::const_iterator cItr = contacts.find(id);
if (cItr != contacts.end()) {
cItr->second->fileProgress(messageId, value);
} else {
std::map<ElId, Room*>::const_iterator rItr = rooms.find(id);
if (rItr != rooms.end()) {
rItr->second->fileProgress(messageId, value);
}
}
return rItr->second;
}
}
return NULL;
}

View file

@ -26,6 +26,7 @@
#include "shared/message.h"
#include "shared/global.h"
#include "shared/messageinfo.h"
#include "accounts.h"
#include "item.h"
#include "account.h"
@ -81,21 +82,19 @@ public:
QModelIndex getAccountIndex(const QString& name);
QModelIndex getGroupIndex(const QString& account, const QString& name);
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list, bool last);
void fileProgress(const QString& messageId, qreal value);
void fileProgress(const std::list<Shared::MessageInfo>& msgs, qreal value, bool up);
void fileError(const std::list<Shared::MessageInfo>& msgs, const QString& err, bool up);
void fileComplete(const std::list<Shared::MessageInfo>& msgs, bool up);
Accounts* accountsModel;
signals:
void requestArchive(const QString& account, const QString& jid, const QString& before);
void fileLocalPathRequest(const QString& messageId, const QString& url);
void fileDownloadRequest(const QString& url);
private:
Item* root;
std::map<QString, Account*> accounts;
std::map<ElId, Group*> groups;
std::map<ElId, Contact*> contacts;
std::map<ElId, Room*> rooms;
std::map<QString, std::set<Models::Roster::ElId>> requestedFiles;
Element* getElement(const ElId& id);
private slots:
void onAccountDataChanged(const QModelIndex& tl, const QModelIndex& br, const QVector<int>& roles);
@ -107,7 +106,13 @@ private slots:
void onChildIsAboutToBeMoved(Item* source, int first, int last, Item* destination, int newIndex);
void onChildMoved();
void onElementRequestArchive(const QString& before);
void onElementFileLocalPathRequest(const QString& messageId, const QString& url);
private:
Item* root;
std::map<QString, Account*> accounts;
std::map<ElId, Group*> groups;
std::map<ElId, Contact*> contacts;
std::map<ElId, Room*> rooms;
public:
class ElId {

View file

@ -29,7 +29,6 @@ Squawk::Squawk(QWidget *parent) :
conversations(),
contextMenu(new QMenu()),
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
requestedFiles(),
vCards(),
requestedAccountsForPasswords(),
prompt(0),
@ -62,8 +61,8 @@ Squawk::Squawk(QWidget *parent) :
connect(m_ui->roster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &Squawk::onRosterSelectionChanged);
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onConversationRequestArchive);
connect(&rosterModel, &Models::Roster::fileLocalPathRequest, this, &Squawk::fileLocalPathRequest);
connect(&rosterModel, &Models::Roster::requestArchive, this, &Squawk::onRequestArchive);
connect(&rosterModel, &Models::Roster::fileDownloadRequest, this, &Squawk::fileDownloadRequest);
connect(contextMenu, &QMenu::aboutToHide, this, &Squawk::onContextAboutToHide);
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
@ -389,86 +388,24 @@ void Squawk::onConversationClosed(QObject* parent)
}
}
void Squawk::onConversationDownloadFile(const QString& messageId, const QString& url)
void Squawk::fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up)
{
Conversation* conv = static_cast<Conversation*>(sender());
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
bool created = false;
if (itr == requestedFiles.end()) {
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
created = true;
}
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
if (created) {
emit downloadFileRequest(messageId, url);
}
rosterModel.fileProgress(msgs, value, up);
}
void Squawk::fileProgress(const QString& messageId, qreal value)
void Squawk::fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path)
{
rosterModel.fileProgress(messageId, value);
rosterModel.fileComplete(msgs, false);
}
void Squawk::fileError(const QString& messageId, const QString& error)
void Squawk::fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up)
{
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
if (itr == requestedFiles.end()) {
qDebug() << "fileError in UI Squawk but there is nobody waiting for that id" << messageId << ", skipping";
return;
} else {
const std::set<Models::Roster::ElId>& convs = itr->second;
for (std::set<Models::Roster::ElId>::const_iterator cItr = convs.begin(), cEnd = convs.end(); cItr != cEnd; ++cItr) {
const Models::Roster::ElId& id = *cItr;
Conversations::const_iterator c = conversations.find(id);
if (c != conversations.end()) {
c->second->fileError(messageId, error);
}
if (currentConversation != 0 && currentConversation->getId() == id) {
currentConversation->fileError(messageId, error);
}
}
requestedFiles.erase(itr);
}
rosterModel.fileError(msgs, error, up);
}
//TODO! Need to make it look like a standard message change event!
void Squawk::fileLocalPathResponse(const QString& messageId, const QString& path)
void Squawk::fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path)
{
std::map<QString, std::set<Models::Roster::ElId>>::const_iterator itr = requestedFiles.find(messageId);
if (itr == requestedFiles.end()) {
qDebug() << "fileLocalPathResponse in UI Squawk but there is nobody waiting for that path, skipping";
return;
} else {
const std::set<Models::Roster::ElId>& convs = itr->second;
for (std::set<Models::Roster::ElId>::const_iterator cItr = convs.begin(), cEnd = convs.end(); cItr != cEnd; ++cItr) {
const Models::Roster::ElId& id = *cItr;
Conversations::const_iterator c = conversations.find(id);
if (c != conversations.end()) {
c->second->responseLocalFile(messageId, path);
}
if (currentConversation != 0 && currentConversation->getId() == id) {
currentConversation->responseLocalFile(messageId, path);
}
}
requestedFiles.erase(itr);
}
}
void Squawk::onConversationRequestLocalFile(const QString& messageId, const QString& url)
{
Conversation* conv = static_cast<Conversation*>(sender());
std::map<QString, std::set<Models::Roster::ElId>>::iterator itr = requestedFiles.find(messageId);
bool created = false;
if (itr == requestedFiles.end()) {
itr = requestedFiles.insert(std::make_pair(messageId, std::set<Models::Roster::ElId>())).first;
created = true;
}
itr->second.insert(Models::Roster::ElId(conv->getAccount(), conv->getJid()));
if (created) {
emit fileLocalPathRequest(messageId, url);
}
rosterModel.fileComplete(msgs, true);
}
void Squawk::accountMessage(const QString& account, const Shared::Message& data)
@ -565,23 +502,13 @@ void Squawk::notify(const QString& account, const Shared::Message& msg)
void Squawk::onConversationMessage(const Shared::Message& msg)
{
Conversation* conv = static_cast<Conversation*>(sender());
Models::Roster::ElId id = conv->getId();
QString acc = conv->getAccount();
rosterModel.addMessage(conv->getAccount(), msg);
QString ap = msg.getAttachPath();
QString oob = msg.getOutOfBandUrl();
if ((ap.size() > 0 && oob.size() == 0) || (ap.size() == 0 && oob.size() > 0)) {
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(id);
//TODO can also start downloading here if someone attached the message with the remote url
}
emit sendMessage(conv->getAccount(), msg);
rosterModel.addMessage(acc, msg);
emit sendMessage(acc, msg);
}
void Squawk::onConversationRequestArchive(const QString& account, const QString& jid, const QString& before)
void Squawk::onRequestArchive(const QString& account, const QString& jid, const QString& before)
{
emit requestArchive(account, jid, 20, before); //TODO amount as a settings value
}
@ -1029,8 +956,6 @@ void Squawk::subscribeConversation(Conversation* conv)
{
connect(conv, &Conversation::destroyed, this, &Squawk::onConversationClosed);
connect(conv, &Conversation::sendMessage, this, &Squawk::onConversationMessage);
connect(conv, &Conversation::requestLocalFile, this, &Squawk::onConversationRequestLocalFile);
connect(conv, &Conversation::downloadFile, this, &Squawk::onConversationDownloadFile);
}
void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous)

View file

@ -75,8 +75,7 @@ signals:
void setRoomAutoJoin(const QString& account, const QString& jid, bool joined);
void addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin);
void removeRoomRequest(const QString& account, const QString& jid);
void fileLocalPathRequest(const QString& messageId, const QString& url);
void downloadFileRequest(const QString& messageId, const QString& url);
void fileDownloadRequest(const QString& url);
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);
@ -103,9 +102,10 @@ public slots:
void addRoomParticipant(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 fileLocalPathResponse(const QString& messageId, const QString& path);
void fileError(const QString& messageId, const QString& error);
void fileProgress(const QString& messageId, qreal value);
void fileError(const std::list<Shared::MessageInfo> msgs, const QString& error, bool up);
void fileProgress(const std::list<Shared::MessageInfo> msgs, qreal value, bool up);
void fileDownloadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
void fileUploadComplete(const std::list<Shared::MessageInfo> msgs, const QString& path);
void responseVCard(const QString& jid, const Shared::VCard& card);
void changeMessage(const QString& account, const QString& jid, const QString& id, const QMap<QString, QVariant>& data);
void requestPassword(const QString& account);
@ -119,7 +119,6 @@ private:
Conversations conversations;
QMenu* contextMenu;
QDBusInterface dbus;
std::map<QString, std::set<Models::Roster::ElId>> requestedFiles;
std::map<QString, VCard*> vCards;
std::deque<QString> requestedAccountsForPasswords;
QInputDialog* prompt;
@ -146,10 +145,8 @@ private slots:
void onComboboxActivated(int index);
void onRosterItemDoubleClicked(const QModelIndex& item);
void onConversationMessage(const Shared::Message& msg);
void onConversationRequestArchive(const QString& account, const QString& jid, const QString& before);
void onRequestArchive(const QString& account, const QString& jid, const QString& before);
void onRosterContextMenu(const QPoint& point);
void onConversationRequestLocalFile(const QString& messageId, const QString& url);
void onConversationDownloadFile(const QString& messageId, const QString& url);
void onItemCollepsed(const QModelIndex& index);
void onPasswordPromptAccepted();
void onPasswordPromptRejected();