Actualizaciones varias: mejoras en cuenta, sincronización, UI

This commit is contained in:
2026-07-05 10:45:44 +02:00
parent 8799633447
commit 4569c174f0
195 changed files with 32571 additions and 20694 deletions
+87 -52
View File
@@ -1,15 +1,13 @@
#include "mailservice.h"
#include <QFuture>
#include <QFutureWatcher>
#include <QtConcurrent/QtConcurrent>
#include <QDebug>
#include <QUuid>
#include <QSslSocket>
#include <QUrl>
#include "db/dao/accountdao.h"
static void sendViaSmtp(const MailItem &mail, const Account &account);
MailService::MailService(QObject *parent)
MailService::MailService(AccountService *accountService, QObject *parent)
: QObject(parent)
, m_composer(new EmailComposerBridge(this))
, m_accountService(accountService)
{
}
@@ -20,67 +18,104 @@ QVector<MailItem> MailService::getMails(const QString &folderId)
void MailService::sendMail(const MailItem &mail, const QString &accountId)
{
qDebug() << "[MailService] Sending mail:" << mail.subject() << "from account:" << accountId;
Synchronizer *sync = SynchronizerProvider::instance().getSynchronizer(accountId);
if (!sync) {
emit mailSendFailed(mail.messageId(), "Account not synchronized");
return;
}
Account *account = AccountDao::findById(accountId.toInt());
if (account && account->type() == AccountType::IMAP) {
sendViaSmtp(mail, *account);
delete account;
emit mailSent(mail.messageId());
return;
}
if (account) delete account;
MailItem copy = mail;
copy.setFolderId(5);
MailItemDao::insert(copy);
emit mailSent(mail.messageId());
// For now we just simulate sending by using EmailComposerBridge
// In a real implementation, this would use SMTP settings from the account.
Q_UNUSED(mail);
Q_UNUSED(accountId);
// Emit success immediately; actual sending would be asynchronous.
QMetaObject::invokeMethod(this, "mailSent", Qt::QueuedConnection,
Q_ARG(QString, QString()));
}
void MailService::fetchMails(const QString &accountId, const QString &folderId)
{
Synchronizer *sync = SynchronizerProvider::instance().getSynchronizer(accountId);
if (!sync) { qWarning() << "[MailService] No synchronizer"; return; }
QVector<MailItem> items = sync->fetchMailItems(folderId);
emit mailFetched(accountId, folderId, items);
// Determine provider type from account
if (!m_accountService) {
emit mailFetchError(accountId, folderId, tr("AccountService not available"));
return;
}
Account *acc = m_accountService->findAccountById(accountId.toLongLong());
QString providerType = QStringLiteral("imap"); // fallback
if (acc) {
switch (acc->type()) {
case AccountType::IMAP:
providerType = QStringLiteral("imap");
break;
case AccountType::POP3:
providerType = QStringLiteral("pop3");
break;
case AccountType::Gmail:
providerType = QStringLiteral("gmail");
break;
case AccountType::Outlook:
providerType = QStringLiteral("outlook");
break;
default:
providerType = QStringLiteral("imap");
break;
}
}
Synchronizer *sync = SynchronizerProvider::instance().createSynchronizer(accountId, providerType);
if (!sync) {
emit mailFetchError(accountId, folderId, tr("Failed to create synchronizer"));
return;
}
// Connect progress signals (if they exist) using string-based syntax for compatibility
QObject::connect(sync, SIGNAL(progressChanged(int)), this, SIGNAL(progressChanged(int)), Qt::QueuedConnection);
QObject::connect(sync, SIGNAL(statusMessage(const QString&)), this, SIGNAL(statusMessage(const QString&)), Qt::QueuedConnection);
QFuture<QVector<MailItem>> future = QtConcurrent::run([=]() {
// SinceUid = 0 for full sync; could be stored per folder but omitted for simplicity
return sync->fetchMailItems(folderId, 0);
});
QFutureWatcher<QVector<MailItem>> *watcher = new QFutureWatcher<QVector<MailItem>>(this);
QObject::connect(watcher, &QFutureWatcher<QVector<MailItem>>::finished, this, [=]() {
// Disconnect progress signals
QObject::disconnect(sync, SIGNAL(progressChanged(int)), this, SIGNAL(progressChanged(int)));
QObject::disconnect(sync, SIGNAL(statusMessage(const QString&)), this, SIGNAL(statusMessage(const QString&)));
QVector<MailItem> items = watcher->result();
watcher->deleteLater();
emit mailFetched(accountId, folderId, items);
});
watcher->setFuture(future);
}
void MailService::moveMail(const QString &mailItemId, const QString &targetFolderId)
{
qDebug() << "[MailService] Moving mail:" << mailItemId;
std::optional<MailItem> item = MailItemDao::findById(mailItemId.toLongLong());
if (item.has_value()) {
MailItem m = item.value();
m.setFolderId(targetFolderId.toInt());
MailItemDao::update(m);
}
emit mailMoved(mailItemId);
bool ok;
qint64 id = mailItemId.toLongLong(&ok);
if (!ok) return;
std::optional<MailItem> opt = MailItemDao::findById(id);
if (!opt) return;
MailItem item = *opt;
item.setFolderId(targetFolderId.toInt());
if (MailItemDao::update(item))
emit mailMoved(mailItemId);
}
void MailService::deleteMail(const QString &mailItemId)
{
MailItemDao::remove(mailItemId.toLongLong());
emit mailDeleted(mailItemId);
bool ok;
qint64 id = mailItemId.toLongLong(&ok);
if (!ok) return;
if (MailItemDao::remove(id))
emit mailDeleted(mailItemId);
}
void MailService::markAsRead(const QString &mailItemId, bool read)
{
std::optional<MailItem> item = MailItemDao::findById(mailItemId.toLongLong());
if (item.has_value()) {
MailItem m = item.value();
m.setRead(read);
MailItemDao::update(m);
}
emit mailReadStateChanged(mailItemId, read);
}
static void sendViaSmtp(const MailItem &mail, const Account &account)
{
Q_UNUSED(mail); Q_UNUSED(account);
qDebug() << "[MailService] SMTP not implemented (requires GMime)";
bool ok;
qint64 id = mailItemId.toLongLong(&ok);
if (!ok) return;
std::optional<MailItem> opt = MailItemDao::findById(id);
if (!opt) return;
MailItem item = *opt;
item.setRead(read);
if (MailItemDao::update(item))
emit mailReadStateChanged(mailItemId, read);
}
#include "mailservice.moc"