/* * gcal-sync-indicator.c * * Copyright 2023 Georges Basile Stavracas Neto * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * SPDX-License-Identifier: GPL-3.0-or-later */ #define G_LOG_DOMAIN "GcalSyncIndicator" #include "gcal-utils.h" #include "gcal-sync-indicator.h" struct _GcalSyncIndicator { AdwBin parent_instance; AdwSpinner *refreshing_spinner; GtkStack *stack; guint icon_changed_source_id; }; static gboolean icon_change_timeout_cb (gpointer data); G_DEFINE_FINAL_TYPE (GcalSyncIndicator, gcal_sync_indicator, ADW_TYPE_BIN) /* * Auxiliary methods */ static void schedule_switch_to_spinner (GcalSyncIndicator *self) { if (self->icon_changed_source_id > 0) return; g_debug ("Scheduling synchronization icon update"); self->icon_changed_source_id = g_timeout_add (500, icon_change_timeout_cb, self); } static void schedule_switch_to_success (GcalSyncIndicator *self) { g_clear_handle_id (&self->icon_changed_source_id, g_source_remove); g_debug ("Switching to success icon"); gtk_stack_set_visible_child_name (self->stack, "success"); self->icon_changed_source_id = g_timeout_add (2000, icon_change_timeout_cb, self); } /* * Callbacks */ static gboolean icon_change_timeout_cb (gpointer data) { GcalSyncIndicator *self; GcalContext *context; GcalManager *manager; gboolean synchronizing; self = GCAL_SYNC_INDICATOR (data); context = gcal_application_get_context (GCAL_DEFAULT_APPLICATION); manager = gcal_context_get_manager (context); synchronizing = gcal_manager_get_synchronizing (manager); g_debug ("Updating calendar icon to spinner"); gtk_stack_set_visible_child_name (self->stack, synchronizing ? "spinner" : "empty"); self->icon_changed_source_id = 0; return G_SOURCE_REMOVE; } static void on_manager_synchronizing_changed_cb (GcalManager *manager, GParamSpec *pspec, GcalSyncIndicator *self) { if (gcal_manager_get_synchronizing (manager)) schedule_switch_to_spinner (self); else schedule_switch_to_success (self); } /* * GObject overrides */ static void gcal_sync_indicator_finalize (GObject *object) { GcalSyncIndicator *self = (GcalSyncIndicator *)object; g_clear_handle_id (&self->icon_changed_source_id, g_source_remove); G_OBJECT_CLASS (gcal_sync_indicator_parent_class)->finalize (object); } static void gcal_sync_indicator_class_init (GcalSyncIndicatorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->finalize = gcal_sync_indicator_finalize; gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/ui/gui/gcal-sync-indicator.ui"); gtk_widget_class_bind_template_child (widget_class, GcalSyncIndicator, refreshing_spinner); gtk_widget_class_bind_template_child (widget_class, GcalSyncIndicator, stack); gtk_widget_class_set_css_name (widget_class, "syncindicator"); } static void gcal_sync_indicator_init (GcalSyncIndicator *self) { GcalContext *context = gcal_application_get_context (GCAL_DEFAULT_APPLICATION); gtk_widget_init_template (GTK_WIDGET (self)); g_signal_connect_object (gcal_context_get_manager (context), "notify::synchronizing", G_CALLBACK (on_manager_synchronizing_changed_cb), self, 0); }