44#include < gtk/gtk.h>
55#include < sys/utsname.h>
66
7+ #include < algorithm>
78#include < cstring>
9+ #include < map>
10+ #include < vector>
811
912#include < libnotify/notify.h>
1013
1114#define LOCAL_NOTIFIER_PLUGIN (obj ) \
1215 (G_TYPE_CHECK_INSTANCE_CAST((obj), local_notifier_plugin_get_type(), \
1316 LocalNotifierPlugin))
1417
18+ LocalNotifierPlugin* plugin_instance;
19+ std::map<std::string, int > notification_id_map_;
20+ std::vector<NotifyNotification*> notifications_;
21+
1522struct _LocalNotifierPlugin {
1623 GObject parent_instance;
1724 FlPluginRegistrar* registrar;
25+ FlMethodChannel* channel;
1826};
1927
2028G_DEFINE_TYPE (LocalNotifierPlugin, local_notifier_plugin, g_object_get_type())
@@ -32,17 +40,113 @@ GdkWindow* get_gdk_window(LocalNotifierPlugin* self) {
3240 return gtk_widget_get_window (GTK_WIDGET (get_window (self)));
3341}
3442
43+ const char * _get_identifier (NotifyNotification* notification) {
44+ int notification_id = -1 ;
45+ g_object_get (G_OBJECT (notification), " id" , ¬ification_id, NULL );
46+
47+ auto result = std::find_if (
48+ notification_id_map_.begin (), notification_id_map_.end (),
49+ [notification_id](const auto & e) { return e.second == notification_id; });
50+
51+ if (result != notification_id_map_.end ())
52+ return result->first .c_str ();
53+
54+ return " " ;
55+ }
56+
57+ void _on_notification_close (NotifyNotification* notification,
58+ gpointer user_data) {
59+ const char * identifier = _get_identifier (notification);
60+
61+ g_autoptr (FlValue) result_data = fl_value_new_map ();
62+ fl_value_set_string_take (result_data, " notificationId" ,
63+ fl_value_new_string (identifier));
64+ fl_method_channel_invoke_method (plugin_instance->channel ,
65+ " onLocalNotificationClose" , result_data,
66+ nullptr , nullptr , nullptr );
67+ }
68+
69+ void _action_callback (NotifyNotification* notification,
70+ char * action,
71+ gpointer user_data) {
72+ const char * identifier = _get_identifier (notification);
73+
74+ gint index = GPOINTER_TO_INT (user_data);
75+
76+ g_autoptr (FlValue) result_data = fl_value_new_map ();
77+ fl_value_set_string_take (result_data, " notificationId" ,
78+ fl_value_new_string (identifier));
79+ fl_value_set_string_take (result_data, " actionIndex" , fl_value_new_int (index));
80+ fl_method_channel_invoke_method (plugin_instance->channel ,
81+ " onLocalNotificationClickAction" , result_data,
82+ nullptr , nullptr , nullptr );
83+ }
84+
3585static FlMethodResponse* notify (LocalNotifierPlugin* self, FlValue* args) {
86+ const gchar* app_name =
87+ fl_value_get_string (fl_value_lookup_string (args, " appName" ));
88+
89+ const gchar* identifier =
90+ fl_value_get_string (fl_value_lookup_string (args, " identifier" ));
3691 const gchar* title =
3792 fl_value_get_string (fl_value_lookup_string (args, " title" ));
38- const gchar* subtitle =
39- fl_value_get_string (fl_value_lookup_string (args, " subtitle" ));
40- // const gchar *body = fl_value_get_string(fl_value_lookup_string(args,
41- // "body"));
93+ const gchar* body = fl_value_get_string (fl_value_lookup_string (args, " body" ));
94+ FlValue* actions_value = fl_value_lookup_string (args, " actions" );
95+
96+ notify_init (app_name);
97+ NotifyNotification* notification = notify_notification_new (title, body, 0 );
98+ notify_notification_set_app_name (notification, app_name);
99+
100+ for (gint i = 0 ; i < fl_value_get_length (actions_value); i++) {
101+ FlValue* action_item_value = fl_value_get_list_value (actions_value, i);
102+ const char * action_text =
103+ fl_value_get_string (fl_value_lookup_string (action_item_value, " text" ));
104+
105+ notify_notification_add_action (notification, action_text, // action
106+ action_text, // label
107+ (NotifyActionCallback)_action_callback,
108+ GINT_TO_POINTER (i), // user_data,
109+ NULL );
110+ }
111+
112+ notify_notification_show (notification, 0 );
113+
114+ g_signal_connect (notification, " closed" , G_CALLBACK (_on_notification_close),
115+ NULL );
116+
117+ notifications_.push_back (notification);
42118
43- notify_init (" local_notifier" );
44- NotifyNotification* n = notify_notification_new (title, subtitle, 0 );
45- notify_notification_show (n, 0 );
119+ int notification_id = -1 ;
120+ g_object_get (G_OBJECT (notification), " id" , ¬ification_id, NULL );
121+
122+ notification_id_map_.erase (identifier);
123+ notification_id_map_.insert (
124+ std::pair<std::string, int >(identifier, notification_id));
125+
126+ g_autoptr (FlValue) result_data = fl_value_new_map ();
127+ fl_value_set_string_take (result_data, " notificationId" ,
128+ fl_value_new_string (identifier));
129+ fl_method_channel_invoke_method (plugin_instance->channel ,
130+ " onLocalNotificationShow" , result_data,
131+ nullptr , nullptr , nullptr );
132+
133+ return FL_METHOD_RESPONSE (
134+ fl_method_success_response_new (fl_value_new_bool (true )));
135+ }
136+
137+ static FlMethodResponse* close (LocalNotifierPlugin* self, FlValue* args) {
138+ const gchar* identifier =
139+ fl_value_get_string (fl_value_lookup_string (args, " identifier" ));
140+
141+ for (int i = 0 ; i < notifications_.size (); i++) {
142+ NotifyNotification* notification = notifications_[i];
143+ const char * item_identifier = _get_identifier (notification);
144+ if (strcmp (identifier, item_identifier) == 0 ) {
145+ notify_notification_close (notification, NULL );
146+ notifications_.erase (notifications_.begin () + i);
147+ break ;
148+ }
149+ }
46150
47151 return FL_METHOD_RESPONSE (
48152 fl_method_success_response_new (fl_value_new_bool (true )));
@@ -58,6 +162,8 @@ static void local_notifier_plugin_handle_method_call(
58162 FlValue* args = fl_method_call_get_args (method_call);
59163 if (strcmp (method, " notify" ) == 0 ) {
60164 response = notify (self, args);
165+ } else if (strcmp (method, " close" ) == 0 ) {
166+ response = close (self, args);
61167 } else {
62168 response = FL_METHOD_RESPONSE (fl_method_not_implemented_response_new ());
63169 }
@@ -90,11 +196,13 @@ void local_notifier_plugin_register_with_registrar(
90196 plugin->registrar = FL_PLUGIN_REGISTRAR (g_object_ref (registrar));
91197
92198 g_autoptr (FlStandardMethodCodec) codec = fl_standard_method_codec_new ();
93- g_autoptr (FlMethodChannel) channel =
199+ plugin-> channel =
94200 fl_method_channel_new (fl_plugin_registrar_get_messenger (registrar),
95201 " local_notifier" , FL_METHOD_CODEC (codec));
96202 fl_method_channel_set_method_call_handler (
97- channel, method_call_cb, g_object_ref (plugin), g_object_unref);
203+ plugin->channel , method_call_cb, g_object_ref (plugin), g_object_unref);
204+
205+ plugin_instance = plugin;
98206
99207 g_object_unref (plugin);
100208}
0 commit comments