Commit b50542ba authored by kaniini's avatar kaniini

implement notifications

parent 0f86c8b3
......@@ -35,7 +35,8 @@ SOURCES += \
ui/mainwindow.cc \
ui/onboardingwidget.cc \
ui/timelineselectorwidget.cc \
ui/timelinewidget.cc
ui/timelinewidget.cc \
ui/notificationimpl.cc
HEADERS += \
core/account.h \
......@@ -50,7 +51,8 @@ HEADERS += \
ui/mainwindow.h \
ui/onboardingwidget.h \
ui/timelineselectorwidget.h \
ui/timelinewidget.h
ui/timelinewidget.h \
ui/notificationimpl.h
FORMS +=
......@@ -58,3 +60,8 @@ RESOURCES += \
resources.qrc
ICON = Michabo.icns
unix:!macx {
QT += dbus
DBUS_ADAPTORS = org.freedesktop.Notifications.xml
}
#include "mainwindow.h"
#include "notificationimpl.h"
#include "core/account.h"
#include "core/accountmanager.h"
#include <QApplication>
......@@ -20,6 +21,8 @@ int main(int argc, char *argv[])
a.setWindowIcon(QIcon::fromTheme("michabo", QIcon(":/embedded-assets/icons/michabo-64.png")));
Michabo::AccountManager manager;
NotificationImpl notifications;
QObject::connect(&manager, &Michabo::AccountManager::notification, &notifications, &NotificationImpl::showNotification);
MainWindow w (nullptr, &manager);
w.show();
......
#include "notificationimpl.h"
#include <QCoreApplication>
NotificationImpl::NotificationImpl(QObject *parent) : QObject(parent)
{
#ifdef USE_DBUS_NOTIFICATIONS
if (! QDBusConnection::sessionBus ().isConnected ())
{
qDebug() << "D-Bus session bus not present.";
}
#endif
}
static QString notification_action (Michabo::Notification::Type type)
{
switch (type)
{
case Michabo::Notification::Favorite:
return QObject::tr ("favourited your post");
case Michabo::Notification::Follow:
return QObject::tr ("followed you");
case Michabo::Notification::Mention:
return QObject::tr ("mentioned you");
case Michabo::Notification::Repeat:
return QObject::tr ("repeated your post");
default:
return "???";
}
}
static QString notification_message (std::shared_ptr<Michabo::Notification> n)
{
switch (n->m_type)
{
case Michabo::Notification::Favorite:
case Michabo::Notification::Mention:
case Michabo::Notification::Repeat:
if (! n->m_post->m_subject.isEmpty ())
return n->m_post->m_subject;
return n->m_post->m_content;
case Michabo::Notification::Follow:
return n->m_identity->m_acct;
default:
return "???";
}
}
#if defined(USE_DBUS_NOTIFICATIONS)
int DBusImageHint::imageHintID = qDBusRegisterMetaType<DBusImageHint>();
DBusImageHint::DBusImageHint(const QImage &img)
{
QImage image (img.convertToFormat (QImage::Format_ARGB32).rgbSwapped ());
imageData = QByteArray ((char *) image.bits (), image.byteCount ());
width = image.width ();
height = image.height ();
rowstride = image.bytesPerLine ();
hasAlpha = image.hasAlphaChannel ();
channels = hasAlpha ? 4 : 3;
bitsPerSample = image.depth () / channels;
}
QImage DBusImageHint::toQImage() const
{
return QImage ((uchar *) imageData.data (), width, height, QImage::Format_ARGB32).rgbSwapped ();
}
QDBusArgument &operator<< (QDBusArgument &a, const DBusImageHint &i)
{
a.beginStructure ();
a <<
i.width <<
i.height <<
i.rowstride <<
i.hasAlpha <<
i.bitsPerSample <<
i.channels <<
i.imageData;
a.endStructure ();
return a;
}
const QDBusArgument &operator>> (const QDBusArgument &a, DBusImageHint &i)
{
a.beginStructure ();
a >>
i.width >>
i.height >>
i.rowstride >>
i.hasAlpha >>
i.bitsPerSample >>
i.channels >>
i.imageData;
a.endStructure ();
return a;
}
void NotificationImpl::showNotification(Michabo::Account *a, std::shared_ptr<Michabo::Notification> n)
{
QVariantMap hints;
QDBusInterface iface ("org.freedesktop.Notifications",
"/org/freedesktop/Notifications",
"org.freedesktop.Notifications",
QDBusConnection::sessionBus ());
if (! iface.isValid())
{
qDebug() << "D-Bus interface is not valid.";
return;
}
// prepare our message
QString action = notification_action (n->m_type);
QString message = notification_message (n);
QString topic = QString ("%1 %2 (%3)").arg(n->m_identity->m_display_name, action, qApp->applicationName ());
// prepare the avatar
DBusImageHint image (n->m_identity->m_avatar);
hints.insert (QStringLiteral ("image_data"), QVariant::fromValue (image));
QDBusReply<uint> reply;
reply = iface.call ("Notify",
qApp->applicationName (),
(uint) 0,
"michabo",
topic,
message,
QStringList (),
hints,
-1);
}
#else
void NotificationImpl::showNotification(Michabo::Account *, std::shared_ptr<Michabo::Notification>)
{
qDebug() << "Notification support is unimplemented!";
}
#endif
#ifndef NOTIFICATIONIMPL_H
#define NOTIFICATIONIMPL_H
#include <memory>
#include <QObject>
#include "core/account.h"
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
# define USE_DBUS_NOTIFICATIONS
# include <QtDBus>
#endif
class NotificationImpl : public QObject
{
Q_OBJECT
public:
explicit NotificationImpl(QObject *parent = nullptr);
signals:
public slots:
void showNotification(Michabo::Account *a, std::shared_ptr<Michabo::Notification> n);
private:
};
#ifdef USE_DBUS_NOTIFICATIONS
// derived from Snorenotify
struct DBusImageHint
{
DBusImageHint() = default;
DBusImageHint(const QImage &img);
QImage toQImage() const;
int width;
int height;
int rowstride;
bool hasAlpha;
int bitsPerSample;
int channels;
QByteArray imageData;
QString _hash;
private:
static int imageHintID;
};
Q_DECLARE_METATYPE(DBusImageHint)
QDBusArgument &operator<< (QDBusArgument &a, const DBusImageHint &i);
const QDBusArgument &operator>> (const QDBusArgument &a, DBusImageHint &i);
#endif
#endif // NOTIFICATIONXDGIMPL_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