Commit ed53593e authored by Ronan Abhamon's avatar Ronan Abhamon

feat(Notifier): refactoring, more user friendly for coders

parent 6945259b
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* Author: Ronan Abhamon * Author: Ronan Abhamon
*/ */
#include <QMutex>
#include <QQmlComponent> #include <QQmlComponent>
#include <QQuickWindow> #include <QQuickWindow>
#include <QScreen> #include <QScreen>
...@@ -32,6 +33,8 @@ ...@@ -32,6 +33,8 @@
#include "Notifier.hpp" #include "Notifier.hpp"
#define NOTIFICATIONS_PATH "qrc:/ui/modules/Linphone/Notifications/"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Notifications QML properties/methods. // Notifications QML properties/methods.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -47,24 +50,6 @@ ...@@ -47,24 +50,6 @@
#define NOTIFICATION_PROPERTY_TIMER "__timer" #define NOTIFICATION_PROPERTY_TIMER "__timer"
// -----------------------------------------------------------------------------
// Paths.
// -----------------------------------------------------------------------------
#define QML_NOTIFICATION_PATH_RECEIVED_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml"
#define QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml"
#define QML_NOTIFICATION_PATH_RECEIVED_CALL "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml"
#define QML_NOTIFICATION_PATH_NEW_VERSION_AVAILABLE "qrc:/ui/modules/Linphone/Notifications/NotificationNewVersionAvailable.qml"
// -----------------------------------------------------------------------------
// Timeouts.
// -----------------------------------------------------------------------------
#define NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE 10000
#define NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE 10000
#define NOTIFICATION_TIMEOUT_RECEIVED_CALL 30000
#define NOTIFICATION_TIMEOUT_NEW_VERSION_AVAILABLE 30000
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Arbitrary hardcoded values. // Arbitrary hardcoded values.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -85,44 +70,60 @@ void setProperty (QObject &object, const char *property, const T &value) { ...@@ -85,44 +70,60 @@ void setProperty (QObject &object, const char *property, const T &value) {
} }
} }
// ----------------------------------------------------------------------------- // =============================================================================
// Available notifications.
// =============================================================================
Notifier::Notifier (QObject *parent) : const QHash<int, Notifier::Notification> Notifier::mNotifications = {
QObject(parent) { { Notifier::ReceivedMessage, { "NotificationReceivedMessage.qml", 10000 } },
QQmlEngine *engine = App::getInstance()->getEngine(); { Notifier::ReceivedFileMessage, { "NotificationReceivedFileMessage.qml", 10000 } },
{ Notifier::ReceivedCall, { "NotificationReceivedCall.qml", 30000 } },
{ Notifier::NewVersionAvailable, { "NotificationNewVersionAvailable.qml", 30000 } }
};
// -----------------------------------------------------------------------------
Notifier::Notifier (QObject *parent) : QObject(parent) {
// Build components. // Build components.
mComponents[Notifier::MessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_MESSAGE)); const int nComponents = mNotifications.size();
mComponents[Notifier::FileMessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE)); mComponents = new QQmlComponent *[nComponents];
mComponents[Notifier::CallReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_CALL));
mComponents[Notifier::NewVersionAvailable] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_NEW_VERSION_AVAILABLE)); QQmlEngine *engine = App::getInstance()->getEngine();
for (const auto &key : mNotifications.keys())
mComponents[key] = new QQmlComponent(engine, QUrl(NOTIFICATIONS_PATH + Notifier::mNotifications[key].filename));
// Check errors. // Check errors.
for (int i = 0; i < Notifier::MaxNbTypes; ++i) { for (int i = 0; i < nComponents; ++i) {
QQmlComponent *component = mComponents[i]; QQmlComponent *component = mComponents[i];
if (component->isError()) { if (component->isError()) {
qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(i) << component->errors(); qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(i) << component->errors();
abort(); abort();
} }
} }
mMutex = new QMutex();
} }
Notifier::~Notifier () { Notifier::~Notifier () {
for (int i = 0; i < Notifier::MaxNbTypes; ++i) delete mMutex;
const int nComponents = mNotifications.size();
for (int i = 0; i < nComponents; ++i)
delete mComponents[i]; delete mComponents[i];
delete[] mComponents;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
QObject *Notifier::createNotification (Notifier::NotificationType type) { QObject *Notifier::createNotification (Notifier::NotificationType type) {
mMutex.lock(); mMutex->lock();
Q_ASSERT(mInstancesNumber <= N_MAX_NOTIFICATIONS); Q_ASSERT(mInstancesNumber <= N_MAX_NOTIFICATIONS);
// Check existing instances. // Check existing instances.
if (mInstancesNumber == N_MAX_NOTIFICATIONS) { if (mInstancesNumber == N_MAX_NOTIFICATIONS) {
qWarning() << QStringLiteral("Unable to create another notification."); qWarning() << QStringLiteral("Unable to create another notification.");
mMutex.unlock(); mMutex->unlock();
return nullptr; return nullptr;
} }
...@@ -154,7 +155,7 @@ QObject *Notifier::createNotification (Notifier::NotificationType type) { ...@@ -154,7 +155,7 @@ QObject *Notifier::createNotification (Notifier::NotificationType type) {
mOffset = 0; mOffset = 0;
} }
mMutex.unlock(); mMutex->unlock();
return instance; return instance;
} }
...@@ -184,13 +185,13 @@ void Notifier::showNotification (QObject *notification, int timeout) { ...@@ -184,13 +185,13 @@ void Notifier::showNotification (QObject *notification, int timeout) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void Notifier::deleteNotification (QVariant notification) { void Notifier::deleteNotification (QVariant notification) {
mMutex.lock(); mMutex->lock();
QObject *instance = notification.value<QObject *>(); QObject *instance = notification.value<QObject *>();
// Notification marked destroyed. // Notification marked destroyed.
if (instance->property("__valid").isValid()) { if (instance->property("__valid").isValid()) {
mMutex.unlock(); mMutex->unlock();
return; return;
} }
...@@ -205,17 +206,29 @@ void Notifier::deleteNotification (QVariant notification) { ...@@ -205,17 +206,29 @@ void Notifier::deleteNotification (QVariant notification) {
if (mInstancesNumber == 0) if (mInstancesNumber == 0)
mOffset = 0; mOffset = 0;
mMutex.unlock(); mMutex->unlock();
instance->deleteLater(); instance->deleteLater();
} }
// ============================================================================= // =============================================================================
#define CREATE_NOTIFICATION(TYPE) \
QObject * notification = createNotification(TYPE); \
if (!notification) \
return; \
const int timeout = mNotifications[TYPE].timeout;
#define SHOW_NOTIFICATION(DATA) \
::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, DATA); \
showNotification(notification, timeout);
// -----------------------------------------------------------------------------
// Notification functions.
// -----------------------------------------------------------------------------
void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &message) { void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &message) {
QObject *notification = createNotification(Notifier::MessageReceived); CREATE_NOTIFICATION(Notifier::ReceivedMessage);
if (!notification)
return;
QVariantMap map; QVariantMap map;
map["message"] = message->getFileTransferInformation() map["message"] = message->getFileTransferInformation()
...@@ -225,27 +238,21 @@ void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &m ...@@ -225,27 +238,21 @@ void Notifier::notifyReceivedMessage (const shared_ptr<linphone::ChatMessage> &m
map["sipAddress"] = ::Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly()); map["sipAddress"] = ::Utils::coreStringToAppString(message->getFromAddress()->asStringUriOnly());
map["window"].setValue(App::getInstance()->getMainWindow()); map["window"].setValue(App::getInstance()->getMainWindow());
::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); SHOW_NOTIFICATION(map);
showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE);
} }
void Notifier::notifyReceivedFileMessage (const shared_ptr<linphone::ChatMessage> &message) { void Notifier::notifyReceivedFileMessage (const shared_ptr<linphone::ChatMessage> &message) {
QObject *notification = createNotification(Notifier::FileMessageReceived); CREATE_NOTIFICATION(Notifier::ReceivedFileMessage);
if (!notification)
return;
QVariantMap map; QVariantMap map;
map["fileUri"] = ::Utils::coreStringToAppString(message->getFileTransferFilepath()); map["fileUri"] = ::Utils::coreStringToAppString(message->getFileTransferFilepath());
map["fileSize"] = static_cast<quint64>(message->getFileTransferInformation()->getSize()); map["fileSize"] = static_cast<quint64>(message->getFileTransferInformation()->getSize());
::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); SHOW_NOTIFICATION(map);
showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE);
} }
void Notifier::notifyReceivedCall (const shared_ptr<linphone::Call> &call) { void Notifier::notifyReceivedCall (const shared_ptr<linphone::Call> &call) {
QObject *notification = createNotification(Notifier::CallReceived); CREATE_NOTIFICATION(Notifier::ReceivedCall);
if (!notification)
return;
CallModel *callModel = &call->getData<CallModel>("call-model"); CallModel *callModel = &call->getData<CallModel>("call-model");
...@@ -257,19 +264,18 @@ void Notifier::notifyReceivedCall (const shared_ptr<linphone::Call> &call) { ...@@ -257,19 +264,18 @@ void Notifier::notifyReceivedCall (const shared_ptr<linphone::Call> &call) {
QVariantMap map; QVariantMap map;
map["call"].setValue(callModel); map["call"].setValue(callModel);
::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); SHOW_NOTIFICATION(map);
showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_CALL);
} }
void Notifier::notifyNewVersionAvailable (const QString &version, const QString &url) { void Notifier::notifyNewVersionAvailable (const QString &version, const QString &url) {
QObject *notification = createNotification(Notifier::NewVersionAvailable); CREATE_NOTIFICATION(Notifier::NewVersionAvailable);
if (!notification)
return;
QVariantMap map; QVariantMap map;
map["message"] = tr("newVersionAvailable").arg(version); map["message"] = tr("newVersionAvailable").arg(version);
map["url"] = url; map["url"] = url;
::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); SHOW_NOTIFICATION(map);
showNotification(notification, NOTIFICATION_TIMEOUT_NEW_VERSION_AVAILABLE);
} }
#undef SHOW_NOTIFICATION
#undef CREATE_NOTIFICATION
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
#define NOTIFIER_H_ #define NOTIFIER_H_
#include <linphone++/linphone.hh> #include <linphone++/linphone.hh>
#include <QMutex>
#include <QObject> #include <QObject>
// ============================================================================= // =============================================================================
class QMutex;
class QQmlComponent; class QQmlComponent;
class Notifier : public QObject { class Notifier : public QObject {
...@@ -39,11 +39,10 @@ public: ...@@ -39,11 +39,10 @@ public:
~Notifier (); ~Notifier ();
enum NotificationType { enum NotificationType {
MessageReceived, ReceivedMessage,
FileMessageReceived, ReceivedFileMessage,
CallReceived, ReceivedCall,
NewVersionAvailable, NewVersionAvailable
MaxNbTypes
}; };
void notifyReceivedMessage (const std::shared_ptr<linphone::ChatMessage> &message); void notifyReceivedMessage (const std::shared_ptr<linphone::ChatMessage> &message);
...@@ -55,14 +54,26 @@ public slots: ...@@ -55,14 +54,26 @@ public slots:
void deleteNotification (QVariant notification); void deleteNotification (QVariant notification);
private: private:
struct Notification {
Notification (const QString &filename = QString(""), int timeout = 0) {
this->filename = filename;
this->timeout = timeout;
}
QString filename;
int timeout;
};
QObject *createNotification (NotificationType type); QObject *createNotification (NotificationType type);
void showNotification (QObject *notification, int timeout); void showNotification (QObject *notification, int timeout);
QQmlComponent *mComponents[MaxNbTypes];
int mOffset = 0; int mOffset = 0;
int mInstancesNumber = 0; int mInstancesNumber = 0;
QMutex mMutex;
QMutex *mMutex = nullptr;
QQmlComponent **mComponents = nullptr;
static const QHash<int, Notification> mNotifications;
}; };
#endif // NOTIFIER_H_ #endif // NOTIFIER_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment