From 5f2e636868d5699f0710b6887e53a012f1290635 Mon Sep 17 00:00:00 2001 From: LAGonauta Date: Thu, 26 Nov 2020 20:48:59 -0300 Subject: [PATCH] Add notification retraction --- .../src/DinoWinToastLib.h | 3 +- .../src/DinoWinToastLib_AMD64.lib | Bin 6038 -> 6068 bytes .../src/DinoWinToastLib_x86.lib | Bin 5238 -> 6132 bytes .../src/win_notification_provider.vala | 162 +++++++++++------- .../vapi/DinoWinToastLib.vapi | 5 +- 5 files changed, 109 insertions(+), 61 deletions(-) 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 190f4ca5c53352a1f21259efda2abe4cca8f076c..cebd9481fb60aeac72bed91911fb9578a029d06e 100644 GIT binary patch delta 526 zcmZ|Lze~eV5C`yYT9cY$YkoF}723f;5Zj{SkEx5Bh=|}IX#I&%nm`TGLF(ckpdNH} zadV8g3a&c2x#-%h=+Hq2y=O!aG4RRbF85yUUbApjIGH}08q0k>l_Y>Xkn8}dGLUWn z`tG+^UYX`adRu^?eamD4!EQ#ZV?Z!!5tGjp>~th^!S&1;hACb!_@iLfh12_Bd||8V zA8gI}fxGQ)tOc&`Vbk^eCD&W@*Y<;1cYXD53C$}Gm8ENHcMq^sScy6DozddYhz8Ht z;X%tOpux@T>cA`WG@#YXc+F;jrVSihK#ezaOuh_`FE~H!aLl_(rVoNcLtA0v+w+-RKghME3-B;6Q&)V4}tmvJV40>M9n AApigX delta 455 zcmX|-J4*vW6ot=jb~n#WW_Rsi7x_a5=ou|xw=5DLAky~=taR|UN5E=n`8i>{a zW8lGtfFRcQU`5IaBkz%z04^nA8+lWdZ+;RQQ^d zhS2+XeH}z(jZ2=0UCJdTeVI z@*8n<|BEy=J)*WbLby?WF~vlxP3a7O2uP|8yRcu z-xW-EB6==4eT1eoi+lE_mB*ZD%S9r8T$jmqO$3;A0j#+J@)AHZkqcgcItGfz{Q#Rj zfOWEKk#ZWX!xZljp9%o9DFDj^8Xs^_0S>T36;uKb)gXZkE)c;DP7uHYUdq-Vm9}9> z?8hnIFIg;M8|Di}vM1M}tusdX=P*|C{3@5TG_-nLeoCb-S~dT3N-kVCrdQIApZ0<7 zqV>TbJMsqy03+Pz7c<|x$UGq1ECu(0*%S3}rguyt{^! z;l7Yn*cyDguaU5#+$WUoAI;Yfw&rJkY@8&8t(@YJC-_pXHNUvW`r?j>xp!e|Q(3MJ zIz2&L@@RP3qX_p0nzlNrlE*vVTAXt@@sVdtSh{j=J3_3z!0z%@*ytS-9)3H!)lRH~ z*lA&OY5QY8MODa2cZGHAd)rHqKv4relM`}kCs{RHuh+8ZG delta 670 zcmZvZO=uHQ6ot>^XC`kZX_A>F#r~wJpxCH1!I&mmT%;PPq^pLS3L0BYH6Y0%g@_IeO;;5}5f`PQ#Z5tpZi_;z73oT-H9{ap9?$s`y80TX7 z{PYZ^gBvOw(4atu z6R!VyE5D$N@*J(pgWBx9a&@LqsVv+raN!`i4V4>KvyzCl2LUJlY*~ zDAXDD(Gif5p0x+Qj&TL>NAq`zrSi36DO+BsEN6;~-5Kb9I%`CwI34(mq1o!^4gL|_ z_}@4^)&t 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); }