Change indentation to 4 spaces
This commit is contained in:
parent
e118f3882d
commit
cfca7157b9
165 changed files with 23146 additions and 23975 deletions
|
|
@ -11,30 +11,30 @@
|
|||
QString
|
||||
NotificationsManager::getMessageTemplate(const mtx::responses::Notification ¬ification)
|
||||
{
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
if (auto msg = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event);
|
||||
msg != nullptr) {
|
||||
return tr("%1 sent an encrypted message").arg(sender);
|
||||
}
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
if (auto msg = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event);
|
||||
msg != nullptr) {
|
||||
return tr("%1 sent an encrypted message").arg(sender);
|
||||
}
|
||||
|
||||
if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) {
|
||||
return tr("* %1 %2",
|
||||
"Format an emote message in a notification, %1 is the sender, %2 the "
|
||||
"message")
|
||||
.arg(sender);
|
||||
} else if (utils::isReply(notification.event)) {
|
||||
return tr("%1 replied: %2",
|
||||
"Format a reply in a notification. %1 is the sender, %2 the message")
|
||||
.arg(sender);
|
||||
} else {
|
||||
return tr("%1: %2",
|
||||
"Format a normal message in a notification. %1 is the sender, %2 the "
|
||||
"message")
|
||||
.arg(sender);
|
||||
}
|
||||
if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) {
|
||||
return tr("* %1 %2",
|
||||
"Format an emote message in a notification, %1 is the sender, %2 the "
|
||||
"message")
|
||||
.arg(sender);
|
||||
} else if (utils::isReply(notification.event)) {
|
||||
return tr("%1 replied: %2",
|
||||
"Format a reply in a notification. %1 is the sender, %2 the message")
|
||||
.arg(sender);
|
||||
} else {
|
||||
return tr("%1: %2",
|
||||
"Format a normal message in a notification. %1 is the sender, %2 the "
|
||||
"message")
|
||||
.arg(sender);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,83 +22,83 @@
|
|||
|
||||
struct roomEventId
|
||||
{
|
||||
QString roomId;
|
||||
QString eventId;
|
||||
QString roomId;
|
||||
QString eventId;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const roomEventId &a, const roomEventId &b)
|
||||
{
|
||||
return a.roomId == b.roomId && a.eventId == b.eventId;
|
||||
return a.roomId == b.roomId && a.eventId == b.eventId;
|
||||
}
|
||||
|
||||
class NotificationsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationsManager(QObject *parent = nullptr);
|
||||
NotificationsManager(QObject *parent = nullptr);
|
||||
|
||||
void postNotification(const mtx::responses::Notification ¬ification, const QImage &icon);
|
||||
void postNotification(const mtx::responses::Notification ¬ification, const QImage &icon);
|
||||
|
||||
signals:
|
||||
void notificationClicked(const QString roomId, const QString eventId);
|
||||
void sendNotificationReply(const QString roomId, const QString eventId, const QString body);
|
||||
void systemPostNotificationCb(const QString &room_id,
|
||||
const QString &event_id,
|
||||
const QString &roomName,
|
||||
const QString &text,
|
||||
const QImage &icon);
|
||||
void notificationClicked(const QString roomId, const QString eventId);
|
||||
void sendNotificationReply(const QString roomId, const QString eventId, const QString body);
|
||||
void systemPostNotificationCb(const QString &room_id,
|
||||
const QString &event_id,
|
||||
const QString &roomName,
|
||||
const QString &text,
|
||||
const QImage &icon);
|
||||
|
||||
public slots:
|
||||
void removeNotification(const QString &roomId, const QString &eventId);
|
||||
void removeNotification(const QString &roomId, const QString &eventId);
|
||||
|
||||
#if defined(NHEKO_DBUS_SYS)
|
||||
public:
|
||||
void closeNotifications(QString roomId);
|
||||
void closeNotifications(QString roomId);
|
||||
|
||||
private:
|
||||
QDBusInterface dbus;
|
||||
QDBusInterface dbus;
|
||||
|
||||
void systemPostNotification(const QString &room_id,
|
||||
const QString &event_id,
|
||||
const QString &roomName,
|
||||
const QString &text,
|
||||
const QImage &icon);
|
||||
void closeNotification(uint id);
|
||||
void systemPostNotification(const QString &room_id,
|
||||
const QString &event_id,
|
||||
const QString &roomName,
|
||||
const QString &text,
|
||||
const QImage &icon);
|
||||
void closeNotification(uint id);
|
||||
|
||||
// notification ID to (room ID, event ID)
|
||||
QMap<uint, roomEventId> notificationIds;
|
||||
// notification ID to (room ID, event ID)
|
||||
QMap<uint, roomEventId> notificationIds;
|
||||
|
||||
const bool hasMarkup_;
|
||||
const bool hasImages_;
|
||||
const bool hasMarkup_;
|
||||
const bool hasImages_;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
private:
|
||||
// Objective-C(++) doesn't like to do lots of regular C++, so the actual notification
|
||||
// posting is split out
|
||||
void objCxxPostNotification(const QString &title,
|
||||
const QString &subtitle,
|
||||
const QString &informativeText,
|
||||
const QImage &bodyImage);
|
||||
// Objective-C(++) doesn't like to do lots of regular C++, so the actual notification
|
||||
// posting is split out
|
||||
void objCxxPostNotification(const QString &title,
|
||||
const QString &subtitle,
|
||||
const QString &informativeText,
|
||||
const QImage &bodyImage);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
private:
|
||||
void systemPostNotification(const QString &line1,
|
||||
const QString &line2,
|
||||
const QString &iconPath);
|
||||
void systemPostNotification(const QString &line1,
|
||||
const QString &line2,
|
||||
const QString &iconPath);
|
||||
#endif
|
||||
|
||||
// these slots are platform specific (D-Bus only)
|
||||
// but Qt slot declarations can not be inside an ifdef!
|
||||
// these slots are platform specific (D-Bus only)
|
||||
// but Qt slot declarations can not be inside an ifdef!
|
||||
private slots:
|
||||
void actionInvoked(uint id, QString action);
|
||||
void notificationClosed(uint id, uint reason);
|
||||
void notificationReplied(uint id, QString reply);
|
||||
void actionInvoked(uint id, QString action);
|
||||
void notificationClosed(uint id, uint reason);
|
||||
void notificationReplied(uint id, QString reply);
|
||||
|
||||
private:
|
||||
QString getMessageTemplate(const mtx::responses::Notification ¬ification);
|
||||
QString getMessageTemplate(const mtx::responses::Notification ¬ification);
|
||||
};
|
||||
|
||||
#if defined(NHEKO_DBUS_SYS)
|
||||
|
|
|
|||
|
|
@ -34,109 +34,100 @@ NotificationsManager::NotificationsManager(QObject *parent)
|
|||
QDBusConnection::sessionBus(),
|
||||
this)
|
||||
, hasMarkup_{std::invoke([this]() -> bool {
|
||||
for (auto x : dbus.call("GetCapabilities").arguments())
|
||||
if (x.toStringList().contains("body-markup"))
|
||||
return true;
|
||||
return false;
|
||||
for (auto x : dbus.call("GetCapabilities").arguments())
|
||||
if (x.toStringList().contains("body-markup"))
|
||||
return true;
|
||||
return false;
|
||||
})}
|
||||
, hasImages_{std::invoke([this]() -> bool {
|
||||
for (auto x : dbus.call("GetCapabilities").arguments())
|
||||
if (x.toStringList().contains("body-images"))
|
||||
return true;
|
||||
return false;
|
||||
for (auto x : dbus.call("GetCapabilities").arguments())
|
||||
if (x.toStringList().contains("body-images"))
|
||||
return true;
|
||||
return false;
|
||||
})}
|
||||
{
|
||||
qDBusRegisterMetaType<QImage>();
|
||||
qDBusRegisterMetaType<QImage>();
|
||||
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"ActionInvoked",
|
||||
this,
|
||||
SLOT(actionInvoked(uint, QString)));
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"NotificationClosed",
|
||||
this,
|
||||
SLOT(notificationClosed(uint, uint)));
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"NotificationReplied",
|
||||
this,
|
||||
SLOT(notificationReplied(uint, QString)));
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"ActionInvoked",
|
||||
this,
|
||||
SLOT(actionInvoked(uint, QString)));
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"NotificationClosed",
|
||||
this,
|
||||
SLOT(notificationClosed(uint, uint)));
|
||||
QDBusConnection::sessionBus().connect("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
"NotificationReplied",
|
||||
this,
|
||||
SLOT(notificationReplied(uint, QString)));
|
||||
|
||||
connect(this,
|
||||
&NotificationsManager::systemPostNotificationCb,
|
||||
this,
|
||||
&NotificationsManager::systemPostNotification,
|
||||
Qt::QueuedConnection);
|
||||
connect(this,
|
||||
&NotificationsManager::systemPostNotificationCb,
|
||||
this,
|
||||
&NotificationsManager::systemPostNotification,
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::postNotification(const mtx::responses::Notification ¬ification,
|
||||
const QImage &icon)
|
||||
{
|
||||
const auto room_id = QString::fromStdString(notification.room_id);
|
||||
const auto event_id = QString::fromStdString(mtx::accessors::event_id(notification.event));
|
||||
const auto room_name =
|
||||
QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
const auto room_id = QString::fromStdString(notification.room_id);
|
||||
const auto event_id = QString::fromStdString(mtx::accessors::event_id(notification.event));
|
||||
const auto room_name = QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
|
||||
auto postNotif = [this, room_id, event_id, room_name, icon](QString text) {
|
||||
emit systemPostNotificationCb(room_id, event_id, room_name, text, icon);
|
||||
};
|
||||
auto postNotif = [this, room_id, event_id, room_name, icon](QString text) {
|
||||
emit systemPostNotificationCb(room_id, event_id, room_name, text, icon);
|
||||
};
|
||||
|
||||
QString template_ = getMessageTemplate(notification);
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
if (std::holds_alternative<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
notification.event)) {
|
||||
postNotif(template_);
|
||||
return;
|
||||
}
|
||||
QString template_ = getMessageTemplate(notification);
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
if (std::holds_alternative<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
notification.event)) {
|
||||
postNotif(template_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasMarkup_) {
|
||||
if (hasImages_ && mtx::accessors::msg_type(notification.event) ==
|
||||
mtx::events::MessageType::Image) {
|
||||
MxcImageProvider::download(
|
||||
QString::fromStdString(mtx::accessors::url(notification.event))
|
||||
.remove("mxc://"),
|
||||
QSize(200, 80),
|
||||
[postNotif, notification, template_](
|
||||
QString, QSize, QImage, QString imgPath) {
|
||||
if (imgPath.isEmpty())
|
||||
postNotif(template_
|
||||
.arg(utils::stripReplyFallbacks(
|
||||
notification.event, {}, {})
|
||||
.quoted_formatted_body)
|
||||
.replace("<em>", "<i>")
|
||||
.replace("</em>", "</i>")
|
||||
.replace("<strong>", "<b>")
|
||||
.replace("</strong>", "</b>"));
|
||||
else
|
||||
postNotif(template_.arg(
|
||||
QStringLiteral("<br><img src=\"file:///") % imgPath %
|
||||
"\" alt=\"" %
|
||||
mtx::accessors::formattedBodyWithFallback(
|
||||
notification.event) %
|
||||
"\">"));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
postNotif(
|
||||
template_
|
||||
.arg(
|
||||
utils::stripReplyFallbacks(notification.event, {}, {}).quoted_formatted_body)
|
||||
.replace("<em>", "<i>")
|
||||
.replace("</em>", "</i>")
|
||||
.replace("<strong>", "<b>")
|
||||
.replace("</strong>", "</b>"));
|
||||
return;
|
||||
if (hasMarkup_) {
|
||||
if (hasImages_ &&
|
||||
mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Image) {
|
||||
MxcImageProvider::download(
|
||||
QString::fromStdString(mtx::accessors::url(notification.event)).remove("mxc://"),
|
||||
QSize(200, 80),
|
||||
[postNotif, notification, template_](QString, QSize, QImage, QString imgPath) {
|
||||
if (imgPath.isEmpty())
|
||||
postNotif(template_
|
||||
.arg(utils::stripReplyFallbacks(notification.event, {}, {})
|
||||
.quoted_formatted_body)
|
||||
.replace("<em>", "<i>")
|
||||
.replace("</em>", "</i>")
|
||||
.replace("<strong>", "<b>")
|
||||
.replace("</strong>", "</b>"));
|
||||
else
|
||||
postNotif(template_.arg(
|
||||
QStringLiteral("<br><img src=\"file:///") % imgPath % "\" alt=\"" %
|
||||
mtx::accessors::formattedBodyWithFallback(notification.event) % "\">"));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
postNotif(
|
||||
template_.arg(utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body));
|
||||
template_
|
||||
.arg(utils::stripReplyFallbacks(notification.event, {}, {}).quoted_formatted_body)
|
||||
.replace("<em>", "<i>")
|
||||
.replace("</em>", "</i>")
|
||||
.replace("<strong>", "<b>")
|
||||
.replace("</strong>", "</b>"));
|
||||
return;
|
||||
}
|
||||
|
||||
postNotif(template_.arg(utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,99 +143,99 @@ NotificationsManager::systemPostNotification(const QString &room_id,
|
|||
const QString &text,
|
||||
const QImage &icon)
|
||||
{
|
||||
QVariantMap hints;
|
||||
hints["image-data"] = icon;
|
||||
hints["sound-name"] = "message-new-instant";
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << "nheko"; // app_name
|
||||
argumentList << (uint)0; // replace_id
|
||||
argumentList << ""; // app_icon
|
||||
argumentList << roomName; // summary
|
||||
argumentList << text; // body
|
||||
QVariantMap hints;
|
||||
hints["image-data"] = icon;
|
||||
hints["sound-name"] = "message-new-instant";
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << "nheko"; // app_name
|
||||
argumentList << (uint)0; // replace_id
|
||||
argumentList << ""; // app_icon
|
||||
argumentList << roomName; // summary
|
||||
argumentList << text; // body
|
||||
|
||||
// The list of actions has always the action name and then a localized version of that
|
||||
// action. Currently we just use an empty string for that.
|
||||
// TODO(Nico): Look into what to actually put there.
|
||||
argumentList << (QStringList("default") << ""
|
||||
<< "inline-reply"
|
||||
<< ""); // actions
|
||||
argumentList << hints; // hints
|
||||
argumentList << (int)-1; // timeout in ms
|
||||
// The list of actions has always the action name and then a localized version of that
|
||||
// action. Currently we just use an empty string for that.
|
||||
// TODO(Nico): Look into what to actually put there.
|
||||
argumentList << (QStringList("default") << ""
|
||||
<< "inline-reply"
|
||||
<< ""); // actions
|
||||
argumentList << hints; // hints
|
||||
argumentList << (int)-1; // timeout in ms
|
||||
|
||||
QDBusPendingCall call = dbus.asyncCallWithArgumentList("Notify", argumentList);
|
||||
auto watcher = new QDBusPendingCallWatcher{call, this};
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, room_id, event_id]() {
|
||||
if (watcher->reply().type() == QDBusMessage::ErrorMessage)
|
||||
qDebug() << "D-Bus Error:" << watcher->reply().errorMessage();
|
||||
else
|
||||
notificationIds[watcher->reply().arguments().first().toUInt()] =
|
||||
roomEventId{room_id, event_id};
|
||||
watcher->deleteLater();
|
||||
});
|
||||
QDBusPendingCall call = dbus.asyncCallWithArgumentList("Notify", argumentList);
|
||||
auto watcher = new QDBusPendingCallWatcher{call, this};
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, room_id, event_id]() {
|
||||
if (watcher->reply().type() == QDBusMessage::ErrorMessage)
|
||||
qDebug() << "D-Bus Error:" << watcher->reply().errorMessage();
|
||||
else
|
||||
notificationIds[watcher->reply().arguments().first().toUInt()] =
|
||||
roomEventId{room_id, event_id};
|
||||
watcher->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::closeNotification(uint id)
|
||||
{
|
||||
auto call = dbus.asyncCall("CloseNotification", (uint)id); // replace_id
|
||||
auto watcher = new QDBusPendingCallWatcher{call, this};
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [watcher]() {
|
||||
if (watcher->reply().type() == QDBusMessage::ErrorMessage) {
|
||||
qDebug() << "D-Bus Error:" << watcher->reply().errorMessage();
|
||||
};
|
||||
watcher->deleteLater();
|
||||
});
|
||||
auto call = dbus.asyncCall("CloseNotification", (uint)id); // replace_id
|
||||
auto watcher = new QDBusPendingCallWatcher{call, this};
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [watcher]() {
|
||||
if (watcher->reply().type() == QDBusMessage::ErrorMessage) {
|
||||
qDebug() << "D-Bus Error:" << watcher->reply().errorMessage();
|
||||
};
|
||||
watcher->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||
{
|
||||
roomEventId reId = {roomId, eventId};
|
||||
for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem) {
|
||||
if (elem.value().roomId != roomId)
|
||||
continue;
|
||||
roomEventId reId = {roomId, eventId};
|
||||
for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem) {
|
||||
if (elem.value().roomId != roomId)
|
||||
continue;
|
||||
|
||||
// close all notifications matching the eventId or having a lower
|
||||
// notificationId
|
||||
// This relies on the notificationId not wrapping around. This allows for
|
||||
// approximately 2,147,483,647 notifications, so it is a bit unlikely.
|
||||
// Otherwise we would need to store a 64bit counter instead.
|
||||
closeNotification(elem.key());
|
||||
// close all notifications matching the eventId or having a lower
|
||||
// notificationId
|
||||
// This relies on the notificationId not wrapping around. This allows for
|
||||
// approximately 2,147,483,647 notifications, so it is a bit unlikely.
|
||||
// Otherwise we would need to store a 64bit counter instead.
|
||||
closeNotification(elem.key());
|
||||
|
||||
// FIXME: compare index of event id of the read receipt and the notification instead
|
||||
// of just the id to prevent read receipts of events without notification clearing
|
||||
// all notifications in that room!
|
||||
if (elem.value() == reId)
|
||||
break;
|
||||
}
|
||||
// FIXME: compare index of event id of the read receipt and the notification instead
|
||||
// of just the id to prevent read receipts of events without notification clearing
|
||||
// all notifications in that room!
|
||||
if (elem.value() == reId)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::actionInvoked(uint id, QString action)
|
||||
{
|
||||
if (notificationIds.contains(id)) {
|
||||
roomEventId idEntry = notificationIds[id];
|
||||
if (action == "default") {
|
||||
emit notificationClicked(idEntry.roomId, idEntry.eventId);
|
||||
}
|
||||
if (notificationIds.contains(id)) {
|
||||
roomEventId idEntry = notificationIds[id];
|
||||
if (action == "default") {
|
||||
emit notificationClicked(idEntry.roomId, idEntry.eventId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::notificationReplied(uint id, QString reply)
|
||||
{
|
||||
if (notificationIds.contains(id)) {
|
||||
roomEventId idEntry = notificationIds[id];
|
||||
emit sendNotificationReply(idEntry.roomId, idEntry.eventId, reply);
|
||||
}
|
||||
if (notificationIds.contains(id)) {
|
||||
roomEventId idEntry = notificationIds[id];
|
||||
emit sendNotificationReply(idEntry.roomId, idEntry.eventId, reply);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::notificationClosed(uint id, uint reason)
|
||||
{
|
||||
Q_UNUSED(reason);
|
||||
notificationIds.remove(id);
|
||||
Q_UNUSED(reason);
|
||||
notificationIds.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -259,52 +250,52 @@ NotificationsManager::notificationClosed(uint id, uint reason)
|
|||
QDBusArgument &
|
||||
operator<<(QDBusArgument &arg, const QImage &image)
|
||||
{
|
||||
if (image.isNull()) {
|
||||
arg.beginStructure();
|
||||
arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray();
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
if (image.isNull()) {
|
||||
arg.beginStructure();
|
||||
arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray();
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
QImage scaled = image.scaledToHeight(100, Qt::SmoothTransformation);
|
||||
scaled = scaled.convertToFormat(QImage::Format_ARGB32);
|
||||
QImage scaled = image.scaledToHeight(100, Qt::SmoothTransformation);
|
||||
scaled = scaled.convertToFormat(QImage::Format_ARGB32);
|
||||
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
// ABGR -> ARGB
|
||||
QImage i = scaled.rgbSwapped();
|
||||
// ABGR -> ARGB
|
||||
QImage i = scaled.rgbSwapped();
|
||||
#else
|
||||
// ABGR -> GBAR
|
||||
QImage i(scaled.size(), scaled.format());
|
||||
for (int y = 0; y < i.height(); ++y) {
|
||||
QRgb *p = (QRgb *)scaled.scanLine(y);
|
||||
QRgb *q = (QRgb *)i.scanLine(y);
|
||||
QRgb *end = p + scaled.width();
|
||||
while (p < end) {
|
||||
*q = qRgba(qGreen(*p), qBlue(*p), qAlpha(*p), qRed(*p));
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
// ABGR -> GBAR
|
||||
QImage i(scaled.size(), scaled.format());
|
||||
for (int y = 0; y < i.height(); ++y) {
|
||||
QRgb *p = (QRgb *)scaled.scanLine(y);
|
||||
QRgb *q = (QRgb *)i.scanLine(y);
|
||||
QRgb *end = p + scaled.width();
|
||||
while (p < end) {
|
||||
*q = qRgba(qGreen(*p), qBlue(*p), qAlpha(*p), qRed(*p));
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
arg.beginStructure();
|
||||
arg << i.width();
|
||||
arg << i.height();
|
||||
arg << i.bytesPerLine();
|
||||
arg << i.hasAlphaChannel();
|
||||
int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3);
|
||||
arg << i.depth() / channels;
|
||||
arg << channels;
|
||||
arg << QByteArray(reinterpret_cast<const char *>(i.bits()), i.sizeInBytes());
|
||||
arg.endStructure();
|
||||
arg.beginStructure();
|
||||
arg << i.width();
|
||||
arg << i.height();
|
||||
arg << i.bytesPerLine();
|
||||
arg << i.hasAlphaChannel();
|
||||
int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3);
|
||||
arg << i.depth() / channels;
|
||||
arg << channels;
|
||||
arg << QByteArray(reinterpret_cast<const char *>(i.bits()), i.sizeInBytes());
|
||||
arg.endStructure();
|
||||
|
||||
return arg;
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument &
|
||||
operator>>(const QDBusArgument &arg, QImage &)
|
||||
{
|
||||
// This is needed to link but shouldn't be called.
|
||||
Q_ASSERT(0);
|
||||
return arg;
|
||||
// This is needed to link but shouldn't be called.
|
||||
Q_ASSERT(0);
|
||||
return arg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,48 +19,42 @@
|
|||
static QString
|
||||
formatNotification(const mtx::responses::Notification ¬ification)
|
||||
{
|
||||
return utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body;
|
||||
return utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body;
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::postNotification(const mtx::responses::Notification ¬ification,
|
||||
const QImage &icon)
|
||||
{
|
||||
Q_UNUSED(icon)
|
||||
Q_UNUSED(icon)
|
||||
|
||||
const auto room_name =
|
||||
QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
const auto room_name = QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
|
||||
const auto isEncrypted =
|
||||
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event) != nullptr;
|
||||
const auto isReply = utils::isReply(notification.event);
|
||||
if (isEncrypted) {
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
const QString messageInfo = (isReply ? tr("%1 replied with an encrypted message")
|
||||
: tr("%1 sent an encrypted message"))
|
||||
.arg(sender);
|
||||
objCxxPostNotification(room_name, messageInfo, "", QImage());
|
||||
} else {
|
||||
const QString messageInfo =
|
||||
(isReply ? tr("%1 replied to a message") : tr("%1 sent a message")).arg(sender);
|
||||
if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Image)
|
||||
MxcImageProvider::download(
|
||||
QString::fromStdString(mtx::accessors::url(notification.event))
|
||||
.remove("mxc://"),
|
||||
QSize(200, 80),
|
||||
[this, notification, room_name, messageInfo](
|
||||
QString, QSize, QImage image, QString) {
|
||||
objCxxPostNotification(room_name,
|
||||
messageInfo,
|
||||
formatNotification(notification),
|
||||
image);
|
||||
});
|
||||
else
|
||||
objCxxPostNotification(
|
||||
room_name, messageInfo, formatNotification(notification), QImage());
|
||||
}
|
||||
const auto isEncrypted = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event) != nullptr;
|
||||
const auto isReply = utils::isReply(notification.event);
|
||||
if (isEncrypted) {
|
||||
// TODO: decrypt this message if the decryption setting is on in the UserSettings
|
||||
const QString messageInfo = (isReply ? tr("%1 replied with an encrypted message")
|
||||
: tr("%1 sent an encrypted message"))
|
||||
.arg(sender);
|
||||
objCxxPostNotification(room_name, messageInfo, "", QImage());
|
||||
} else {
|
||||
const QString messageInfo =
|
||||
(isReply ? tr("%1 replied to a message") : tr("%1 sent a message")).arg(sender);
|
||||
if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Image)
|
||||
MxcImageProvider::download(
|
||||
QString::fromStdString(mtx::accessors::url(notification.event)).remove("mxc://"),
|
||||
QSize(200, 80),
|
||||
[this, notification, room_name, messageInfo](QString, QSize, QImage image, QString) {
|
||||
objCxxPostNotification(
|
||||
room_name, messageInfo, formatNotification(notification), image);
|
||||
});
|
||||
else
|
||||
objCxxPostNotification(
|
||||
room_name, messageInfo, formatNotification(notification), QImage());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ using namespace WinToastLib;
|
|||
class CustomHandler : public IWinToastHandler
|
||||
{
|
||||
public:
|
||||
void toastActivated() const {}
|
||||
void toastActivated(int) const {}
|
||||
void toastFailed() const { std::wcout << L"Error showing current toast" << std::endl; }
|
||||
void toastDismissed(WinToastDismissalReason) const {}
|
||||
void toastActivated() const {}
|
||||
void toastActivated(int) const {}
|
||||
void toastFailed() const { std::wcout << L"Error showing current toast" << std::endl; }
|
||||
void toastDismissed(WinToastDismissalReason) const {}
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
|
@ -32,12 +32,12 @@ bool isInitialized = false;
|
|||
void
|
||||
init()
|
||||
{
|
||||
isInitialized = true;
|
||||
isInitialized = true;
|
||||
|
||||
WinToast::instance()->setAppName(L"Nheko");
|
||||
WinToast::instance()->setAppUserModelId(WinToast::configureAUMI(L"nheko", L"nheko"));
|
||||
if (!WinToast::instance()->initialize())
|
||||
std::wcout << "Your system is not compatible with toast notifications\n";
|
||||
WinToast::instance()->setAppName(L"Nheko");
|
||||
WinToast::instance()->setAppUserModelId(WinToast::configureAUMI(L"nheko", L"nheko"));
|
||||
if (!WinToast::instance()->initialize())
|
||||
std::wcout << "Your system is not compatible with toast notifications\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,41 +49,37 @@ void
|
|||
NotificationsManager::postNotification(const mtx::responses::Notification ¬ification,
|
||||
const QImage &icon)
|
||||
{
|
||||
const auto room_name =
|
||||
QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
const auto room_name = QString::fromStdString(cache::singleRoomInfo(notification.room_id).name);
|
||||
const auto sender =
|
||||
cache::displayName(QString::fromStdString(notification.room_id),
|
||||
QString::fromStdString(mtx::accessors::sender(notification.event)));
|
||||
|
||||
const auto isEncrypted =
|
||||
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event) != nullptr;
|
||||
const auto isReply = utils::isReply(notification.event);
|
||||
const auto isEncrypted = std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
¬ification.event) != nullptr;
|
||||
const auto isReply = utils::isReply(notification.event);
|
||||
|
||||
auto formatNotification = [this, notification, sender] {
|
||||
const auto template_ = getMessageTemplate(notification);
|
||||
if (std::holds_alternative<
|
||||
mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
notification.event)) {
|
||||
return template_;
|
||||
}
|
||||
auto formatNotification = [this, notification, sender] {
|
||||
const auto template_ = getMessageTemplate(notification);
|
||||
if (std::holds_alternative<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
notification.event)) {
|
||||
return template_;
|
||||
}
|
||||
|
||||
return template_.arg(
|
||||
utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body);
|
||||
};
|
||||
return template_.arg(utils::stripReplyFallbacks(notification.event, {}, {}).quoted_body);
|
||||
};
|
||||
|
||||
const auto line1 =
|
||||
(room_name == sender) ? sender : QString("%1 - %2").arg(sender).arg(room_name);
|
||||
const auto line2 = (isEncrypted ? (isReply ? tr("%1 replied with an encrypted message")
|
||||
: tr("%1 sent an encrypted message"))
|
||||
: formatNotification());
|
||||
const auto line1 =
|
||||
(room_name == sender) ? sender : QString("%1 - %2").arg(sender).arg(room_name);
|
||||
const auto line2 = (isEncrypted ? (isReply ? tr("%1 replied with an encrypted message")
|
||||
: tr("%1 sent an encrypted message"))
|
||||
: formatNotification());
|
||||
|
||||
auto iconPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
|
||||
room_name + "-room-avatar.png";
|
||||
if (!icon.save(iconPath))
|
||||
iconPath.clear();
|
||||
auto iconPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + room_name +
|
||||
"-room-avatar.png";
|
||||
if (!icon.save(iconPath))
|
||||
iconPath.clear();
|
||||
|
||||
systemPostNotification(line1, line2, iconPath);
|
||||
systemPostNotification(line1, line2, iconPath);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -91,17 +87,17 @@ NotificationsManager::systemPostNotification(const QString &line1,
|
|||
const QString &line2,
|
||||
const QString &iconPath)
|
||||
{
|
||||
if (!isInitialized)
|
||||
init();
|
||||
if (!isInitialized)
|
||||
init();
|
||||
|
||||
auto templ = WinToastTemplate(WinToastTemplate::ImageAndText02);
|
||||
templ.setTextField(line1.toStdWString(), WinToastTemplate::FirstLine);
|
||||
templ.setTextField(line2.toStdWString(), WinToastTemplate::SecondLine);
|
||||
auto templ = WinToastTemplate(WinToastTemplate::ImageAndText02);
|
||||
templ.setTextField(line1.toStdWString(), WinToastTemplate::FirstLine);
|
||||
templ.setTextField(line2.toStdWString(), WinToastTemplate::SecondLine);
|
||||
|
||||
if (!iconPath.isNull())
|
||||
templ.setImagePath(iconPath.toStdWString());
|
||||
if (!iconPath.isNull())
|
||||
templ.setImagePath(iconPath.toStdWString());
|
||||
|
||||
WinToast::instance()->showToast(templ, new CustomHandler());
|
||||
WinToast::instance()->showToast(templ, new CustomHandler());
|
||||
}
|
||||
|
||||
void NotificationsManager::actionInvoked(uint, QString) {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue