aboutsummaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorfrosty <gabriel@bwaaa.monster>2026-08-25 23:07:50 -0400
committerfrosty <gabriel@bwaaa.monster>2026-08-25 23:07:50 -0400
commitb2c0c1587521b9fd47437a7a9ebba16a6136a65c (patch)
tree40caee1f2b9a2c422bc3084448b0994d10ff2ed5 /main/src
parentb19412a3d291f8cdbf037e00ac2f3641f7493de6 (diff)
feat: add in notification replies
Diffstat (limited to 'main/src')
-rw-r--r--main/src/ui/notifier_freedesktop.vala57
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;