diff options
| author | frosty <gabriel@bwaaa.monster> | 2026-08-25 23:07:50 -0400 |
|---|---|---|
| committer | frosty <gabriel@bwaaa.monster> | 2026-08-25 23:07:50 -0400 |
| commit | b2c0c1587521b9fd47437a7a9ebba16a6136a65c (patch) | |
| tree | 40caee1f2b9a2c422bc3084448b0994d10ff2ed5 /main/src/ui | |
| parent | b19412a3d291f8cdbf037e00ac2f3641f7493de6 (diff) | |
feat: add in notification replies
Diffstat (limited to 'main/src/ui')
| -rw-r--r-- | main/src/ui/notifier_freedesktop.vala | 57 |
1 files changed, 53 insertions, 4 deletions
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; |
