aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdino/src/dbus/notifications.vala4
-rw-r--r--main/src/ui/notifier_freedesktop.vala57
2 files changed, 56 insertions, 5 deletions
diff --git a/libdino/src/dbus/notifications.vala b/libdino/src/dbus/notifications.vala
index 400d1da0..fd07b570 100644
--- a/libdino/src/dbus/notifications.vala
+++ b/libdino/src/dbus/notifications.vala
@@ -7,6 +7,8 @@ namespace Dino {
public signal void notification_closed (uint32 id, uint32 reason);
+ public signal void notification_replied(uint32 id, string text);
+
public abstract async uint32 notify(string app_name, uint32 replaces_id, string app_icon, string summary,
string body, string[] actions, HashTable<string, Variant> hints, int32 expire_timeout) throws DBusError, IOError;
@@ -51,4 +53,4 @@ namespace Dino {
return ret;
}
-} \ No newline at end of file
+}
diff --git a/main/src/ui/notifier_freedesktop.vala b/main/src/ui/notifier_freedesktop.vala
index 99428315..3c8bee1c 100644
--- a/main/src/ui/notifier_freedesktop.vala
+++ b/main/src/ui/notifier_freedesktop.vala
@@ -11,10 +11,12 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
private DBusNotifications dbus_notifications;
private bool supports_body_markup = false;
private bool supports_body_hyperlinks = false;
+ private bool supports_inline_reply = false;
private HashMap<Conversation, uint32> content_notifications = new HashMap<Conversation, uint32>(Conversation.hash_func, Conversation.equals_func);
private HashMap<Conversation, Gee.List<uint32>> conversation_notifications = new HashMap<Conversation, Gee.List<uint32>>(Conversation.hash_func, Conversation.equals_func);
private HashMap<uint32, HashMap<string, ListenerFuncWrapper>> action_listeners = new HashMap<uint32, HashMap<string, ListenerFuncWrapper>>();
+ private HashMap<uint32, NotificationReplyTarget> reply_targets = new HashMap<uint32, NotificationReplyTarget>();
private HashMap<Call, uint32> call_notifications = new HashMap<Call, uint32>(Call.hash_func, Call.equals_func);
public FreeDesktopNotifier(StreamInteractor stream_interactor, DBusNotifications dbus_notifications) {
@@ -35,6 +37,9 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
case "body-hyperlinks":
supports_body_hyperlinks = true;
break;
+ case "inline-reply":
+ supports_inline_reply = true;
+ break;
}
}
@@ -46,6 +51,22 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
dbus_notifications.notification_closed.connect((id) => {
action_listeners.unset(id);
+ reply_targets.unset(id);
+ });
+
+ dbus_notifications.notification_replied.connect((id, text) => {
+ if (!reply_targets.has_key(id)) return;
+
+ NotificationReplyTarget target = reply_targets[id];
+ if (text.strip() != "") {
+ Dino.send_message(target.conversation, text, target.content_item_id, null, new ArrayList<Xep.MessageMarkup.Span>());
+ }
+
+ reply_targets.unset(id);
+ if (content_notifications.has_key(target.conversation) && content_notifications[target.conversation] == id) {
+ content_notifications.unset(target.conversation);
+ }
+ dbus_notifications.close_notification.begin(id);
});
}
@@ -62,7 +83,9 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
} else {
body = message.body;
}
- yield notify_content_item(conversation, conversation_display_name, participant_display_name, body);
+ ContentItem? reply_to_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_content_item_for_message(conversation, message);
+ int reply_to_id = reply_to_item != null ? reply_to_item.id : 0;
+ yield notify_content_item(conversation, conversation_display_name, participant_display_name, body, reply_to_id);
}
public async void notify_file(FileTransfer file_transfer, Conversation conversation, bool is_image, string conversation_display_name, string? participant_display_name) {
@@ -77,10 +100,10 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
text = "<i>" + text + "</i>";
}
- yield notify_content_item(conversation, conversation_display_name, participant_display_name, text);
+ yield notify_content_item(conversation, conversation_display_name, participant_display_name, text, 0);
}
- private async void notify_content_item(Conversation conversation, string conversation_display_name, string? participant_display_name, string body_) {
+ private async void notify_content_item(Conversation conversation, string conversation_display_name, string? participant_display_name, string body_, int reply_to_id) {
string body = body_;
if (participant_display_name != null) {
if (supports_body_markup) {
@@ -96,10 +119,22 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
hash_table["desktop-entry"] = new Variant.string(Dino.Application.get_default().get_application_id());
hash_table["category"] = new Variant.string("im.received");
string[] actions = new string[] {"default", "Open conversation"};
+ if (reply_to_id != 0 && supports_inline_reply) {
+ actions += "inline-reply";
+ actions += _("Reply");
+ hash_table["x-kde-reply-placeholder-text"] = new Variant.string(_("Reply"));
+ hash_table["x-kde-reply-submit-button-text"] = new Variant.string(_("Send"));
+ }
try {
uint32 notification_id = yield dbus_notifications.notify("Dino", replace_id, "", conversation_display_name, body, actions, hash_table, -1);
content_notifications[conversation] = notification_id;
+ if (reply_to_id != 0 && supports_inline_reply) {
+ reply_targets[notification_id] = new NotificationReplyTarget(conversation, reply_to_id);
+ } else {
+ reply_targets.unset(notification_id);
+ }
+
add_action_listener(notification_id, "default", () => {
GLib.Application.get_default().activate_action("open-conversation", new Variant.int32(conversation.id));
});
@@ -284,12 +319,15 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
} catch (Error e) { }
}
content_notifications.clear();
+ reply_targets.clear();
}
public async void retract_conversation_notifications(Conversation conversation) {
try {
if (content_notifications.has_key(conversation)) {
- dbus_notifications.close_notification.begin(content_notifications[conversation]);
+ uint32 notification_id = content_notifications[conversation];
+ dbus_notifications.close_notification.begin(notification_id);
+ reply_targets.unset(notification_id);
content_notifications.unset(conversation);
}
@@ -323,6 +361,17 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
}
delegate void ListenerFunc();
+
+ class NotificationReplyTarget {
+ public Conversation conversation;
+ public int content_item_id;
+
+ public NotificationReplyTarget(Conversation conversation, int content_item_id) {
+ this.conversation = conversation;
+ this.content_item_id = content_item_id;
+ }
+ }
+
class ListenerFuncWrapper {
public ListenerFunc func;