Complete phases 6 and 7: Notifications & System Tray, Background Sync & Scheduling

This commit is contained in:
Padrino
2026-05-29 22:53:57 +02:00
parent 4fdd95c979
commit acaf741eb9
8 changed files with 293 additions and 38 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ bool Translator::loadLanguage(const QString& langCode)
QMutexLocker locker(&m_mutex);
m_translations.clear();
QString filePath = QStringLiteral("resources/translations/%1/resources.json").arg(langCode);
QString filePath = QStringLiteral(":/resources/translations/%1/resources.json").arg(langCode);
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open translation file:" << filePath;
+21 -1
View File
@@ -6,6 +6,7 @@
#include "core/emailmanager.h"
#include "syncscheduler.h"
#include "utils/notificationmanager.h"
#include "core/accountsetupdialoglauncher.h"
int main(int argc, char *argv[])
{
@@ -31,13 +32,17 @@ int main(int argc, char *argv[])
NotificationManager notificationManager(&app);
notificationManager.initialize(); // Initialize Qt components after QApplication is ready
// Create AccountSetupDialogLauncher to expose to QML
AccountSetupDialogLauncher accountSetupDialogLauncher(&app);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("translator", static_cast<QObject*>(&translator));
engine.rootContext()->setContextProperty("emailManager", &emailManager);
engine.rootContext()->setContextProperty("syncScheduler", &syncScheduler);
engine.rootContext()->setContextProperty("notificationManager", &notificationManager);
engine.rootContext()->setContextProperty("accountSetupDialogLauncher", &accountSetupDialogLauncher);
const QUrl url(QStringLiteral("qrc:/main.qml"));
const QUrl url(QStringLiteral("qrc:/resources/qml/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
@@ -45,5 +50,20 @@ int main(int argc, char *argv[])
}, Qt::QueuedConnection);
engine.load(url);
// After loading QML, get the root object to connect the notificationManager's showHideRequested signal
QObject *rootObject = nullptr;
if (!engine.rootObjects().isEmpty()) {
rootObject = engine.rootObjects().first();
}
// Connect the notificationManager's showHideRequested signal to toggle the root object's visibility
QObject::connect(&notificationManager, &NotificationManager::showHideRequested,
[rootObject]() {
if (rootObject) {
bool visible = rootObject->property("visible").toBool();
rootObject->setProperty("visible", !visible);
}
});
return app.exec();
}
+2 -2
View File
@@ -11,8 +11,8 @@
#include <QDateTime>
#include <QTimer>
#include <QEventLoop>
#include "../core/events.h"
#include "../core/eventbus.h"
#include "../../core/events.h"
#include "../../core/eventbus.h"
GmailSynchronizer::GmailSynchronizer(QObject* parent)
: Synchronizer(parent),
+2 -2
View File
@@ -11,8 +11,8 @@
#include <QDateTime>
#include <QTimer>
#include <QEventLoop>
#include "../core/events.h"
#include "../core/eventbus.h"
#include "../../core/events.h"
#include "../../core/eventbus.h"
OutlookSynchronizer::OutlookSynchronizer(QObject* parent)
: Synchronizer(parent),
+46 -21
View File
@@ -2,9 +2,10 @@
#include <QDebug>
#include <QSettings>
#include "db/dao/accountdao.h"
#include "../services/synchronizer.h"
#include "../core/eventbus.h"
#include "../core/events.h"
#include "core/synchronizerprovider.h"
#include "services/synchronizer.h"
#include "core/eventbus.h"
#include "core/events.h"
SyncScheduler::SyncScheduler(QObject *parent)
: QObject(parent)
@@ -52,21 +53,45 @@ void SyncScheduler::onTimerTick()
void SyncScheduler::performSync()
{
qDebug() << "SyncScheduler: Performing synchronization...";
// Trigger a manual sync by publishing a SyncRequestedEvent or calling synchronizers directly.
// For now, we'll publish a generic event that synchronizers can listen to.
// We'll create a simple event; but we don't have a specific event for manual sync trigger.
// Instead, we can invoke each synchronizer's syncFolder for all folders? That would be heavy.
// Following the plan, we want to trigger sync for all accounts.
// We'll create a SyncRequestedEvent and publish it.
// However, we don't have such event defined. We can extend events.h, but to keep it simple,
// we can just call the synchronizers via a central place? Not ideal.
// Given time, we'll just log and later implement.
qDebug() << "SyncScheduler: Sync trigger would happen here.";
// Update last sync timestamp
QSettings settings;
qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
settings.setValue("lastSyncTimestamp", now);
qDebug() << "SyncScheduler: Updated last sync timestamp to" << now;
bool syncPerformed = false;
// Get all accounts
QVector<Account> accounts = AccountDao::findAll();
for (const Account& account : accounts) {
// Get the synchronizer for this account
Synchronizer* synchronizer = SynchronizerProvider::instance().getSynchronizer(QString::number(account.id()));
if (!synchronizer) {
qWarning() << "SyncScheduler: No synchronizer found for account ID" << account.id();
continue;
}
// Optionally, we could initialize the synchronizer if not already initialized.
// However, we assume it's already initialized and registered (e.g., when account was added).
// If we want to be safe, we can try to initialize it here.
// But note: the synchronizer might have been initialized with a different account instance?
// We'll skip initialization for now and rely on the synchronizer being ready.
// Get folders for this account and sync each one
QVector<Folder> folders = synchronizer->getFolders();
for (const Folder& folder : folders) {
qDebug() << "SyncScheduler: Syncing folder" << folder.name() << "for account ID" << account.id();
bool success = synchronizer->syncFolder(folder);
if (!success) {
qWarning() << "SyncScheduler: Failed to sync folder" << folder.name() << "for account ID" << account.id();
}
syncPerformed = true;
}
}
if (syncPerformed) {
// Update last sync timestamp only if we actually performed a sync
QSettings settings;
qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
settings.setValue("lastSyncTimestamp", now);
qDebug() << "SyncScheduler: Updated last sync timestamp to" << now;
} else {
qDebug() << "SyncScheduler: No accounts found or no synchronizers available.";
}
}
bool SyncScheduler::shouldRunSync() const
@@ -80,9 +105,9 @@ bool SyncScheduler::shouldRunSync() const
return false;
}
// Check if current hour >= m_runHour (UTC? we'll use local time for simplicity)
QDateTime nowLocal = QDateTime::currentDateTime();
if (nowLocal.time().hour() < m_runHour) {
qDebug() << "SyncScheduler: Current hour" << nowLocal.time().hour() << "is less than run hour" << m_runHour;
QDateTime nowUtc = QDateTime::currentDateTimeUtc();
if (nowUtc.time().hour() < m_runHour) {
qDebug() << "SyncScheduler: Current UTC hour" << nowUtc.time().hour() << "is less than run hour" << m_runHour;
return false;
}
return true;