diff --git a/plugins/windows-notification/src/DinoWinToastLib.h b/plugins/windows-notification/src/DinoWinToastLib.h index 69723666..c7c70933 100644 --- a/plugins/windows-notification/src/DinoWinToastLib.h +++ b/plugins/windows-notification/src/DinoWinToastLib.h @@ -6,9 +6,40 @@ #ifdef __cplusplus extern "C" { #endif - typedef void(*dinoWinToastLibNotificationCallback)(int conv_id, void* userdata); - DINOWINTOASTLIB_API int dinoWinToastLibInit(); - DINOWINTOASTLIB_API int dinoWinToastLibShowMessage(dino_wintoasttemplate templ, int conv_id, dinoWinToastLibNotificationCallback click_callback, void* callback_target); + typedef enum { + Reason_Activated = 0, + Reason_ApplicationHidden, + Reason_TimedOut + } dinoWinToastLib_Notification_Reason; + + typedef void(*dinoWinToastLib_Notification_Callback_Simple)(void* userdata); + typedef void(*dinoWinToastLib_Notification_Callback_ActivatedWithActionIndex)(int action_id, void* userdata); + typedef void(*dinoWinToastLib_Notification_Callback_Dismissed)(dinoWinToastLib_Notification_Reason reason, void* userdata); + + typedef struct { + dinoWinToastLib_Notification_Callback_Simple activated; + void* activated_context; + void(*activated_free)(void*); + + dinoWinToastLib_Notification_Callback_ActivatedWithActionIndex activatedWithIndex; + void* activatedWithIndex_context; + void(*activatedWithIndex_free)(void*); + + dinoWinToastLib_Notification_Callback_Dismissed dismissed; + void* dismissed_context; + void(*dismissed_free)(void*); + + dinoWinToastLib_Notification_Callback_Simple failed; + void* failed_context; + void(*failed_free)(void*); + + } dinoWinToastLib_Notification_Callbacks; + + DINOWINTOASTLIB_API dinoWinToastLib_Notification_Callbacks* dinoWinToastLib_NewCallbacks(); + 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); #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 c508e807..190f4ca5 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/DinoWinToastTemplate.h b/plugins/windows-notification/src/DinoWinToastTemplate.h index 258335d4..b4253961 100644 --- a/plugins/windows-notification/src/DinoWinToastTemplate.h +++ b/plugins/windows-notification/src/DinoWinToastTemplate.h @@ -9,33 +9,33 @@ extern "C" { typedef void* dino_wintoasttemplate; typedef enum { - System, - Short, - Long + Duration_System, + Duration_Short, + Duration_Long } dino_wintoasttemplate_duration; typedef enum { - Default = 0, - Silent = 1, - Loop = 2 + AudioOption_Default = 0, + AudioOption_Silent = 1, + AudioOption_Loop = 2 } dino_wintoasttemplate_audiooption; typedef enum { - FirstLine = 0, - SecondLine, - ThirdLine + TextField_FirstLine = 0, + TextField_SecondLine, + TextField_ThirdLine } dino_wintoasttemplate_textfield; typedef enum { - ImageAndText01 = 0, - ImageAndText02, - ImageAndText03, - ImageAndText04, - Text01, - Text02, - Text03, - Text04, - WinToastTemplateTypeCount + TemplateType_ImageAndText01 = 0, + TemplateType_ImageAndText02, + TemplateType_ImageAndText03, + TemplateType_ImageAndText04, + TemplateType_Text01, + TemplateType_Text02, + TemplateType_Text03, + TemplateType_Text04, + TemplateType_WinToastTemplateTypeCount } dino_wintoasttemplate_wintoasttemplatetype; DINOWINTOASTLIB_API dino_wintoasttemplate dino_wintoasttemplate_new(dino_wintoasttemplate_wintoasttemplatetype templ); diff --git a/plugins/windows-notification/src/win_notification_provider.vala b/plugins/windows-notification/src/win_notification_provider.vala index 9563ee88..bb307893 100644 --- a/plugins/windows-notification/src/win_notification_provider.vala +++ b/plugins/windows-notification/src/win_notification_provider.vala @@ -2,6 +2,7 @@ using Dino; using Dino.Entities; using DinoWinToast; using Xmpp; +using Gee; namespace Dino.Plugins.WindowsNotification { public class WindowsNotificationProvider : NotificationProvider, Object { @@ -50,33 +51,37 @@ namespace Dino.Plugins.WindowsNotification { string summary = _("Subscription request"); string body = Markup.escape_text(conversation.counterpart.to_string()); - if (!show_message(summary, body, get_avatar(conversation), conversation.id, stub)) { // missing actions + DinoWinToastTemplate template; + var image_path = get_avatar(conversation); + if (image_path != null) { + template = new DinoWinToastTemplate(TemplateType.ImageAndText02); + template.setImagePath(image_path); + } else { + template = new DinoWinToastTemplate(TemplateType.Text02); + } + + template.setTextField(summary, TextField.FirstLine); + template.setTextField(body, TextField.SecondLine); + + template.addAction(_("Accept")); + template.addAction(_("Deny")); + + var callbacks = new Callbacks(); + callbacks.activated = () => { + app.activate_action("open-conversation", conversation.id); + }; + + callbacks.activatedWithIndex = (index) => { + if (index == 0) { + app.activate_action("accept-subscription", conversation.id); + } else if (index == 1) { + app.activate_action("deny-subscription", conversation.id); + } + }; + + if (!ShowMessage(template, callbacks) == 0) { warning("Failed showing subscription request notification"); } - - // HashTable hash_table = new HashTable(null, null); - // hash_table["image-data"] = yield get_conversation_icon(conversation); - // string[] actions = new string[] {"default", "Open conversation", "accept", _("Accept"), "deny", _("Deny")}; - // try { - // uint32 notification_id = dbus_notifications.notify("Dino", 0, "", summary, body, actions, hash_table, 0); - - // if (!conversation_notifications.has_key(conversation)) { - // conversation_notifications[conversation] = new ArrayList(); - // } - // conversation_notifications[conversation].add(notification_id); - - // add_action_listener(notification_id, "default", () => { - // GLib.Application.get_default().activate_action("open-conversation", new Variant.int32(conversation.id)); - // }); - // add_action_listener(notification_id, "accept", () => { - // GLib.Application.get_default().activate_action("accept-subscription", new Variant.int32(conversation.id)); - // }); - // add_action_listener(notification_id, "deny", () => { - // GLib.Application.get_default().activate_action("deny-subscription", new Variant.int32(conversation.id)); - // }); - // } catch (Error e) { - // warning("Failed showing subscription request notification: %s", e.message); - // } } public async void notify_connection_error(Account account, ConnectionManager.ConnectionError error) { @@ -97,7 +102,7 @@ namespace Dino.Plugins.WindowsNotification { break; } - if (!show_message(summary, body, null, 0, stub)) { + if (!show_message(summary, body, null, null)) { warning("Failed showing connection error notification"); } } @@ -109,15 +114,39 @@ namespace Dino.Plugins.WindowsNotification { string summary = _("Invitation to %s").printf(display_room); string body = _("%s invited you to %s").printf(inviter_display_name, display_room); + DinoWinToastTemplate template; + var image_path = get_avatar(conversation); + if (image_path != null) { + template = new DinoWinToastTemplate(TemplateType.ImageAndText02); + template.setImagePath(image_path); + } else { + template = new DinoWinToastTemplate(TemplateType.Text02); + } + + template.setTextField(summary, TextField.FirstLine); + template.setTextField(body, TextField.SecondLine); + + template.addAction(_("Accept")); + template.addAction(_("Deny")); + Conversation group_conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(room_jid, account, Conversation.Type.GROUPCHAT); - if (!show_message(summary, body, get_avatar(direct_conversation), group_conversation.id, stub)) { // action not enabled yet + var callbacks = new Callbacks(); + callbacks.activated = () => { + app.activate_action("open-muc-join", group_conversation.id); + }; + + callbacks.activatedWithIndex = (index) => { + if (index == 0) { + app.activate_action("deny-invite", group_conversation.id); + } else if (index == 1) { + app.activate_action("open-muc-join", group_conversation.id); + } + }; + + if (!ShowMessage(template, callbacks)) { warning("Failed showing muc invite notification"); } - // HashTable hash_table = new HashTable(null, null); - // hash_table["image-data"] = yield get_conversation_icon(direct_conversation); - // string[] actions = new string[] {"default", "", "reject", _("Reject"), "accept", _("Accept")}; - // try { // uint32 notification_id = dbus_notifications.notify("Dino", 0, "", summary, body, actions, hash_table, 0); @@ -137,32 +166,38 @@ namespace Dino.Plugins.WindowsNotification { } public async void notify_voice_request(Conversation conversation, Jid from_jid) { - string display_name = Dino.get_participant_display_name(stream_interactor, conversation, from_jid); string display_room = Dino.get_conversation_display_name(stream_interactor, conversation, _("%s from %s")); string summary = _("Permission request"); string body = _("%s requests the permission to write in %s").printf(display_name, display_room); - if (!show_message(summary, body, get_avatar(conversation), conversation.id, stub)) { // missing actions + DinoWinToastTemplate template; + var image_path = get_avatar(conversation); + if (image_path != null) { + template = new DinoWinToastTemplate(TemplateType.ImageAndText02); + template.setImagePath(image_path); + } else { + template = new DinoWinToastTemplate(TemplateType.Text02); + } + + template.setTextField(summary, TextField.FirstLine); + template.setTextField(body, TextField.SecondLine); + + template.addAction(_("Accept")); + template.addAction(_("Deny")); + + var callbacks = new Callbacks(); + callbacks.activatedWithIndex = (index) => { + if (index == 0) { + app.activate_action("deny-invite", conversation.id); + } else if (index == 1) { + app.activate_action("open-muc-join", conversation.id); + } + }; + + if (!ShowMessage(template, callbacks) == 0) { warning("Failed showing voice request notification"); } - - // HashTable hash_table = new HashTable(null, null); - // hash_table["image-data"] = yield get_conversation_icon(conversation); - // string[] actions = new string[] {"deny", _("Deny"), "accept", _("Accept")}; - - // try { - // uint32 notification_id = dbus_notifications.notify("Dino", 0, "", summary, body, actions, hash_table, 0); - - // add_action_listener(notification_id, "accept", () => { - // GLib.Application.get_default().activate_action("deny-invite", new Variant.int32(conversation.id)); - // }); - // add_action_listener(notification_id, "deny", () => { - // GLib.Application.get_default().activate_action("open-muc-join", new Variant.int32(conversation.id)); - // }); - // } catch (Error e) { - // warning("Failed showing voice request notification: %s", e.message); - // } } public async void retract_content_item_notifications() { @@ -185,7 +220,7 @@ namespace Dino.Plugins.WindowsNotification { // content_notifications.unset(conversation); } - private bool show_message(string sender, string message, string? image_path, int conv_id, NotificationCallback callback) { + private bool show_message(string sender, string message, string? image_path, Callbacks? callbacks = null) { DinoWinToastTemplate template; if (image_path != null) { template = new DinoWinToastTemplate(TemplateType.ImageAndText02); @@ -196,7 +231,10 @@ namespace Dino.Plugins.WindowsNotification { template.setTextField(sender, TextField.FirstLine); template.setTextField(message, TextField.SecondLine); - return ShowMessage(template, conv_id, callback) == 0; + if (callbacks != null) { + return ShowMessage(template, callbacks) == 0; + } + return ShowMessage(template, new Callbacks()) == 0; } private async void notify_content_item(Conversation conversation, string conversation_display_name, string? participant_display_name, string body_) { @@ -206,18 +244,13 @@ namespace Dino.Plugins.WindowsNotification { } var avatar = get_avatar(conversation); - if (!show_message(conversation_display_name, body, avatar, conversation.id, onclick_callback)) { + var callbacks = new Callbacks(); + callbacks.activated = () => app.activate_action("open-conversation", conversation.id); + if (!show_message(conversation_display_name, body, avatar, callbacks)) { warning("Failed showing content item notification"); } } - private void onclick_callback(int conv_id) { - this.app.activate_action("open-conversation", conv_id); - } - - private void stub(int conv_id) { - } - private string? get_avatar(Conversation conversation) { var avatar_manager = app.stream_interactor.get_module(AvatarManager.IDENTITY); return avatar_manager.get_avatar_filepath(conversation.account, conversation.counterpart); diff --git a/plugins/windows-notification/vapi/DinoWinToastLib.vapi b/plugins/windows-notification/vapi/DinoWinToastLib.vapi index a4c92057..25077d46 100644 --- a/plugins/windows-notification/vapi/DinoWinToastLib.vapi +++ b/plugins/windows-notification/vapi/DinoWinToastLib.vapi @@ -1,13 +1,45 @@ [CCode (cheader_filename = "DinoWinToastLib.h")] namespace DinoWinToast { - [CCode (cname = "dinoWinToastLibNotificationCallback", has_target = true)] - public delegate void NotificationCallback(int conv_id); + [CCode (cname = "dinoWinToastLib_Notification_Reason", cprefix = "Reason_")] + public enum Reason { + Activated, + ApplicationHidden, + TimedOut + } - [CCode (cname = "dinoWinToastLibInit")] + [CCode (cname = "dinoWinToastLib_Notification_Callback_Simple", has_target = true)] + public delegate void NotificationCallbackSimple(); + + [CCode (cname = "dinoWinToastLib_Notification_Callback_ActivatedWithActionIndex", has_target = true)] + public delegate void NotificationCallbackWithActionIndex(int actionId); + + [CCode (cname = "dinoWinToastLib_Notification_Callback_Dismissed", has_target = true)] + public delegate void NotificationCallbackDismissed(Reason reason); + + [CCode (cname = "dinoWinToastLib_Notification_Callbacks", free_function = "dinoWinToastLib_DestroyCallbacks")] + [Compact] + public class Callbacks { + [CCode (delegate_target_cname = "activated_context", destroy_notify_cname = "activated_free")] + public NotificationCallbackSimple activated; + + [CCode (delegate_target_cname = "activatedWithIndex_context", destroy_notify_cname = "activatedWithIndex_free")] + public NotificationCallbackWithActionIndex activatedWithIndex; + + [CCode (delegate_target_cname = "dismissed_context", destroy_notify_cname = "dismissed_free")] + public NotificationCallbackDismissed dismissed; + + [CCode (delegate_target_cname = "failed_context", destroy_notify_cname = "failed_free")] + public NotificationCallbackSimple failed; + + [CCode (cname = "dinoWinToastLib_NewCallbacks")] + public Callbacks(); + } + + [CCode (cname = "dinoWinToastLib_Init")] public int Init(); - [CCode (cname = "dinoWinToastLibShowMessage")] - public int ShowMessage(DinoWinToastTemplate templ, int conv_id, NotificationCallback callback); + [CCode (cname = "dinoWinToastLib_ShowMessage")] + public int ShowMessage(DinoWinToastTemplate templ, Callbacks callbacks); } diff --git a/plugins/windows-notification/vapi/DinoWinToastTemplate.vapi b/plugins/windows-notification/vapi/DinoWinToastTemplate.vapi index 59fc4740..ca5b2fc7 100644 --- a/plugins/windows-notification/vapi/DinoWinToastTemplate.vapi +++ b/plugins/windows-notification/vapi/DinoWinToastTemplate.vapi @@ -1,27 +1,27 @@ [CCode (cheader_filename = "DinoWinToastTemplate.h")] namespace DinoWinToast { - [CCode (cname = "dino_wintoasttemplate_duration", cprefix = "")] + [CCode (cname = "dino_wintoasttemplate_duration", cprefix = "Duration_")] public enum Duration { System, Short, Long } - [CCode (cname = "dino_wintoasttemplate_audiooption", cprefix = "")] + [CCode (cname = "dino_wintoasttemplate_audiooption", cprefix = "AudioOption_")] public enum AudioOption { Default, Silent, Loop } - [CCode (cname = "dino_wintoasttemplate_textfield", cprefix = "")] + [CCode (cname = "dino_wintoasttemplate_textfield", cprefix = "TextField_")] public enum TextField { FirstLine, SecondLine, ThirdLine } - [CCode (cname = "dino_wintoasttemplate_wintoasttemplatetype", cprefix = "")] + [CCode (cname = "dino_wintoasttemplate_wintoasttemplatetype", cprefix = "TemplateType_")] public enum TemplateType { ImageAndText01, ImageAndText02,