diff --git a/plugins/windows-notification/src/DinoWinToastLib.h b/plugins/windows-notification/src/DinoWinToastLib.h index c7c70933..bb66ae51 100644 --- a/plugins/windows-notification/src/DinoWinToastLib.h +++ b/plugins/windows-notification/src/DinoWinToastLib.h @@ -39,7 +39,8 @@ extern "C" { DINOWINTOASTLIB_API void dinoWinToastLib_DestroyCallbacks(dinoWinToastLib_Notification_Callbacks* callbacks); DINOWINTOASTLIB_API int dinoWinToastLib_Init(); - DINOWINTOASTLIB_API int dinoWinToastLib_ShowMessage(dino_wintoasttemplate templ, dinoWinToastLib_Notification_Callbacks* callbacks); + DINOWINTOASTLIB_API int64_t dinoWinToastLib_ShowMessage(dino_wintoasttemplate templ, dinoWinToastLib_Notification_Callbacks* callbacks); + DINOWINTOASTLIB_API int dinoWinToastLib_RemoveNotification(int64_t notification_id); #ifdef __cplusplus } // extern "C" #endif \ No newline at end of file diff --git a/plugins/windows-notification/src/DinoWinToastLib_AMD64.lib b/plugins/windows-notification/src/DinoWinToastLib_AMD64.lib index 190f4ca5..cebd9481 100644 Binary files a/plugins/windows-notification/src/DinoWinToastLib_AMD64.lib and b/plugins/windows-notification/src/DinoWinToastLib_AMD64.lib differ diff --git a/plugins/windows-notification/src/DinoWinToastLib_x86.lib b/plugins/windows-notification/src/DinoWinToastLib_x86.lib index d9a35cbb..3d72e250 100644 Binary files a/plugins/windows-notification/src/DinoWinToastLib_x86.lib and b/plugins/windows-notification/src/DinoWinToastLib_x86.lib differ diff --git a/plugins/windows-notification/src/win_notification_provider.vala b/plugins/windows-notification/src/win_notification_provider.vala index bb307893..3673f07b 100644 --- a/plugins/windows-notification/src/win_notification_provider.vala +++ b/plugins/windows-notification/src/win_notification_provider.vala @@ -7,16 +7,22 @@ using Gee; namespace Dino.Plugins.WindowsNotification { public class WindowsNotificationProvider : NotificationProvider, Object { - // TODO: - // 1. Actions - // 2. Dismissed - private StreamInteractor stream_interactor; private Dino.Application app; + private GLib.Queue notifications_to_be_removed; + private HashMap content_notifications; + private HashMap> conversation_notifications; + + private class Notification { + public int64? id; + } private WindowsNotificationProvider(Dino.Application app) { this.stream_interactor = app.stream_interactor; this.app = app; + this.notifications_to_be_removed = new GLib.Queue(); + this.content_notifications = new HashMap(Conversation.hash_func, Conversation.equals_func); + this.conversation_notifications = new HashMap>(Conversation.hash_func, Conversation.equals_func); } public static WindowsNotificationProvider? try_create(Dino.Application app) { @@ -65,10 +71,12 @@ namespace Dino.Plugins.WindowsNotification { template.addAction(_("Accept")); template.addAction(_("Deny")); - + + var notification = new Notification(); var callbacks = new Callbacks(); callbacks.activated = () => { app.activate_action("open-conversation", conversation.id); + add_to_removal_queue(notification.id); }; callbacks.activatedWithIndex = (index) => { @@ -77,10 +85,20 @@ namespace Dino.Plugins.WindowsNotification { } else if (index == 1) { app.activate_action("deny-subscription", conversation.id); } + add_to_removal_queue(notification.id); }; - if (!ShowMessage(template, callbacks) == 0) { + callbacks.dismissed = (reason) => add_to_removal_queue(notification.id); + callbacks.failed = () => add_to_removal_queue(notification.id); + + notification.id = ShowMessage(template, callbacks); + if (notification.id == -1) { warning("Failed showing subscription request notification"); + } else { + if (!conversation_notifications.has_key(conversation)) { + conversation_notifications[conversation] = new ArrayList(); + } + conversation_notifications[conversation].add(notification.id); } } @@ -101,8 +119,20 @@ namespace Dino.Plugins.WindowsNotification { body = "Connection"; break; } - - if (!show_message(summary, body, null, null)) { + + var notification = new Notification(); + var callbacks = new Callbacks(); + callbacks.activated = () => add_to_removal_queue(notification.id); + callbacks.activatedWithIndex = (index) => add_to_removal_queue(notification.id); + callbacks.dismissed = (reason) => add_to_removal_queue(notification.id); + callbacks.failed = () => add_to_removal_queue(notification.id); + + DinoWinToastTemplate template = new DinoWinToastTemplate(TemplateType.Text02); + template.setTextField(summary, TextField.FirstLine); + template.setTextField(body, TextField.SecondLine); + + notification.id = ShowMessage(template, callbacks); + if (notification.id == -1) { warning("Failed showing connection error notification"); } } @@ -115,7 +145,7 @@ namespace Dino.Plugins.WindowsNotification { string body = _("%s invited you to %s").printf(inviter_display_name, display_room); DinoWinToastTemplate template; - var image_path = get_avatar(conversation); + var image_path = get_avatar(direct_conversation); if (image_path != null) { template = new DinoWinToastTemplate(TemplateType.ImageAndText02); template.setImagePath(image_path); @@ -130,9 +160,11 @@ namespace Dino.Plugins.WindowsNotification { template.addAction(_("Deny")); Conversation group_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(room_jid, account, Conversation.Type.GROUPCHAT); + var notification = new Notification(); var callbacks = new Callbacks(); callbacks.activated = () => { app.activate_action("open-muc-join", group_conversation.id); + add_to_removal_queue(notification.id); }; callbacks.activatedWithIndex = (index) => { @@ -141,28 +173,16 @@ namespace Dino.Plugins.WindowsNotification { } else if (index == 1) { app.activate_action("open-muc-join", group_conversation.id); } + add_to_removal_queue(notification.id); }; - if (!ShowMessage(template, callbacks)) { + callbacks.dismissed = (reason) => add_to_removal_queue(notification.id); + callbacks.failed = () => add_to_removal_queue(notification.id); + + notification.id = ShowMessage(template, callbacks); + if (notification.id == -1) { warning("Failed showing muc invite notification"); } - - // try { - // uint32 notification_id = dbus_notifications.notify("Dino", 0, "", summary, body, actions, hash_table, 0); - - // Conversation group_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(room_jid, account, Conversation.Type.GROUPCHAT); - // add_action_listener(notification_id, "default", () => { - // GLib.Application.get_default().activate_action("open-muc-join", new Variant.int32(group_conversation.id)); - // }); - // add_action_listener(notification_id, "accept", () => { - // GLib.Application.get_default().activate_action("deny-invite", new Variant.int32(group_conversation.id)); - // }); - // add_action_listener(notification_id, "deny", () => { - // GLib.Application.get_default().activate_action("open-muc-join", new Variant.int32(group_conversation.id)); - // }); - // } catch (Error e) { - - // } } public async void notify_voice_request(Conversation conversation, Jid from_jid) { @@ -186,6 +206,7 @@ namespace Dino.Plugins.WindowsNotification { template.addAction(_("Accept")); template.addAction(_("Deny")); + var notification = new Notification(); var callbacks = new Callbacks(); callbacks.activatedWithIndex = (index) => { if (index == 0) { @@ -193,34 +214,45 @@ namespace Dino.Plugins.WindowsNotification { } else if (index == 1) { app.activate_action("open-muc-join", conversation.id); } + add_to_removal_queue(notification.id); }; - if (!ShowMessage(template, callbacks) == 0) { + callbacks.dismissed = (reason) => add_to_removal_queue(notification.id); + callbacks.failed = () => add_to_removal_queue(notification.id); + callbacks.activated = () => add_to_removal_queue(notification.id); + + notification.id = ShowMessage(template, callbacks); + if (notification.id == -1) { warning("Failed showing voice request notification"); } } public async void retract_content_item_notifications() { - // if (content_notifications != null) { - // foreach (uint32 id in content_notifications.values) { - // try { - // dbus_notifications.close_notification(id); - // } catch (Error e) { } - // } - // content_notifications.clear(); - // } + foreach (int64 id in content_notifications.values) { + RemoveNotification(id); + } + content_notifications.clear(); } public async void retract_conversation_notifications(Conversation conversation) { - // if (content_notifications.has_key(conversation)) { - // try { - // dbus_notifications.close_notification(content_notifications[conversation]); - // } catch (Error e) { } - // } - // content_notifications.unset(conversation); + if (conversation_notifications.has_key(conversation)) { + var conversation_items = conversation_notifications[conversation]; + foreach (int64 id in conversation_items) { + RemoveNotification(id); + } + conversation_items.clear(); + } } - private bool show_message(string sender, string message, string? image_path, Callbacks? callbacks = null) { + private async void notify_content_item(Conversation conversation, string conversation_display_name, string? participant_display_name, string body_) { + clear_queue(); + + string body = body_; + if (participant_display_name != null) { + body = @"$participant_display_name: $body"; + } + + var image_path = get_avatar(conversation); DinoWinToastTemplate template; if (image_path != null) { template = new DinoWinToastTemplate(TemplateType.ImageAndText02); @@ -229,25 +261,24 @@ namespace Dino.Plugins.WindowsNotification { template = new DinoWinToastTemplate(TemplateType.Text02); } - template.setTextField(sender, TextField.FirstLine); - template.setTextField(message, TextField.SecondLine); - if (callbacks != null) { - return ShowMessage(template, callbacks) == 0; - } - return ShowMessage(template, new Callbacks()) == 0; - } + template.setTextField(conversation_display_name, TextField.FirstLine); + template.setTextField(body, TextField.SecondLine); - private async void notify_content_item(Conversation conversation, string conversation_display_name, string? participant_display_name, string body_) { - string body = body_; - if (participant_display_name != null) { - body = @"$participant_display_name: $body"; - } - - var avatar = get_avatar(conversation); + var notification = new Notification(); var callbacks = new Callbacks(); - callbacks.activated = () => app.activate_action("open-conversation", conversation.id); - if (!show_message(conversation_display_name, body, avatar, callbacks)) { + callbacks.activated = () => { + app.activate_action("open-conversation", conversation.id); + add_to_removal_queue(notification.id); + }; + callbacks.dismissed = (reason) => add_to_removal_queue(notification.id); + callbacks.failed = () => add_to_removal_queue(notification.id); + callbacks.activatedWithIndex = (index) => add_to_removal_queue(notification.id); + + notification.id = ShowMessage(template, callbacks); + if (notification.id == -1) { warning("Failed showing content item notification"); + } else { + content_notifications[conversation] = notification.id; } } @@ -255,5 +286,18 @@ namespace Dino.Plugins.WindowsNotification { var avatar_manager = app.stream_interactor.get_module(AvatarManager.IDENTITY); return avatar_manager.get_avatar_filepath(conversation.account, conversation.counterpart); } + + private void clear_queue() { + int64? id = null; + while ((id = notifications_to_be_removed.pop_head()) != null) { + RemoveNotification(id); + } + } + + private void add_to_removal_queue(int64? id) { + if (id != null && id != -1 && id != 1 && id != 0) { + notifications_to_be_removed.push_head(id); + } + } } } \ No newline at end of file diff --git a/plugins/windows-notification/vapi/DinoWinToastLib.vapi b/plugins/windows-notification/vapi/DinoWinToastLib.vapi index 25077d46..d47dfbd9 100644 --- a/plugins/windows-notification/vapi/DinoWinToastLib.vapi +++ b/plugins/windows-notification/vapi/DinoWinToastLib.vapi @@ -40,6 +40,9 @@ namespace DinoWinToast { public int Init(); [CCode (cname = "dinoWinToastLib_ShowMessage")] - public int ShowMessage(DinoWinToastTemplate templ, Callbacks callbacks); + public int64 ShowMessage(DinoWinToastTemplate templ, Callbacks callbacks); + + [CCode (cname = "dinoWinToastLib_RemoveNotification")] + public bool RemoveNotification(int64 notification_id); }