[gnome-shell/4592-calendar-correct-handling-of-recurring-events] calendar-server: Expand recurrences on a recurring instance change



commit f157d6ba195212e87bde24d62d82e6410972af53
Author: Milan Crha <mcrha redhat com>
Date:   Mon Jun 6 17:31:23 2022 +0200

    calendar-server: Expand recurrences on a recurring instance change
    
    When an instance of a recurring event changes, it's only that one
    being sent to the calendar view, but the calendar.js requires all
    affected events from the series, thus provide them.

 src/calendar-server/gnome-shell-calendar-server.c | 40 +++++++++++++++++++++++
 1 file changed, 40 insertions(+)
---
diff --git a/src/calendar-server/gnome-shell-calendar-server.c 
b/src/calendar-server/gnome-shell-calendar-server.c
index f1980c633c..d9921655cf 100644
--- a/src/calendar-server/gnome-shell-calendar-server.c
+++ b/src/calendar-server/gnome-shell-calendar-server.c
@@ -438,20 +438,30 @@ app_process_added_modified_objects (App *app,
                                     GSList *objects) /* ICalComponent * */
 {
   ECalClient *cal_client;
+  GHashTable *covered_uids;
   GSList *link;
   gboolean expand_recurrences;
 
   cal_client = e_cal_client_view_ref_client (view);
+  covered_uids = g_hash_table_new (g_str_hash, g_str_equal);
   expand_recurrences = e_cal_client_get_source_type (cal_client) == E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
 
   for (link = objects; link; link = g_slist_next (link))
     {
       ECalComponent *comp;
       ICalComponent *icomp = link->data;
+      const gchar *uid;
+      gboolean fallback = FALSE;
 
       if (!icomp || !i_cal_component_get_uid (icomp))
         continue;
 
+      uid = i_cal_component_get_uid (icomp);
+      if (g_hash_table_contains (covered_uids, uid))
+        continue;
+
+      g_hash_table_add (covered_uids, (gpointer) uid);
+
       if (expand_recurrences &&
           !e_cal_util_component_is_instance (icomp) &&
           e_cal_util_component_has_recurrences (icomp))
@@ -464,7 +474,36 @@ app_process_added_modified_objects (App *app,
           e_cal_client_generate_instances_for_object_sync (cal_client, icomp, app->since, app->until, NULL,
                                                            generate_instances_cb, &data);
         }
+      else if (expand_recurrences &&
+               e_cal_util_component_is_instance (icomp))
+        {
+          ICalComponent *main_comp = NULL;
+
+          /* Always pass whole series of the recurring events, because the calendar
+             removes events with the same UID first. */
+          if (e_cal_client_get_object_sync (cal_client, uid, NULL, &main_comp, NULL, NULL))
+            {
+              CollectAppointmentsData data;
+
+              data.client = cal_client;
+              data.pappointments = &app->notify_appointments;
+
+              e_cal_client_generate_instances_for_object_sync (cal_client, main_comp, app->since, 
app->until, NULL,
+                                                               generate_instances_cb, &data);
+
+              g_clear_object (&main_comp);
+            }
+          else
+            {
+               fallback = TRUE;
+            }
+        }
       else
+        {
+         fallback = TRUE;
+        }
+
+      if (fallback)
         {
           comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone (icomp));
           if (!comp)
@@ -476,6 +515,7 @@ app_process_added_modified_objects (App *app,
         }
     }
 
+  g_clear_pointer (&covered_uids, g_hash_table_unref);
   g_clear_object (&cal_client);
 
   if (app->notify_appointments)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]