diff --git a/client/src/activities_view.vala b/client/src/activities_view.vala index fe276e4..8f23d60 100644 --- a/client/src/activities_view.vala +++ b/client/src/activities_view.vala @@ -1,8 +1,9 @@ namespace StudySystemClient { - public class ActivitiesView : ListView, IRefreshable { + public class ActivitiesView : ListView { private const uint REFRESH_PERIOD_MS = 30000; private Client client; + private Updater updater; private Refresher refresher; private bool pending_sort; @@ -10,31 +11,42 @@ namespace StudySystemClient { base(); add_css_class("card-container"); this.client = client; - refresher = new Refresher(this, REFRESH_PERIOD_MS); + updater = new Updater(this, client); + refresher = new Refresher(updater, REFRESH_PERIOD_MS); pending_sort = false; this.map.connect(() => { + updater.refresh.begin(); refresher.start(); - refresh.begin(); }); } - private async void refresh() { - if (!client.connected) - return; - try { - var activities = yield client.list_activities(); - update_cards(activities); - } catch (ClientError e) { - stderr.printf("Error refreshing activities: %s\n", - e.message); - } + internal IterableBox.Iterator iterator() { + return container.iterator(); + } + + internal void new_card(Activity activity) { + var card = new ActivityCard(activity); + card.session_logged.connect(log_session); + card.log_closed.connect(handle_pending_sort); + container.append(card); + } + + internal void remove_card(ActivityCard card) { + container.remove(card); + } + + internal void sort() { + if (log_in_progress()) + pending_sort = true; + else + container.sort(compare_cards); } private async void log_session(string subject, ActivityType type, int minutes) { try { yield client.log_session(subject, type, minutes); - yield refresh(); + yield updater.refresh(); } catch (ClientError e) { stderr.printf("Error logging session: %s\n", e.message); } @@ -47,54 +59,6 @@ namespace StudySystemClient { } } - private void update_cards(Array activities) { - update_existing_cards(activities); - for (uint i = 0; i < activities.length; ++i) - create_card(activities.index(i)); - if (log_in_progress()) - pending_sort = true; - else - container.sort(compare_cards); - } - - private void update_existing_cards(Array activities) { - var to_remove = new List(); - foreach (var card in container) { - if (!update_existing_card(card, activities)) - to_remove.append(card); - } - foreach (var card in to_remove) - container.remove(card); - } - - private bool update_existing_card(ActivityCard card, - Array activities) { - var activity_index = find_activity(card, activities); - if (activity_index == null) - return false; - var priority = activities.index(activity_index).priority; - card.update_priority(priority); - activities._remove_index_fast(activity_index); - return true; - } - - private uint? find_activity(ActivityCard card, - Array activities) { - for (uint i = 0; i < activities.length; ++i) { - if (activities.index(i).subject == card.activity.subject - && activities.index(i).type == card.activity.type) - return i; - } - return null; - } - - private void create_card(Activity activity) { - var card = new ActivityCard(activity); - card.session_logged.connect(log_session); - card.log_closed.connect(handle_pending_sort); - container.append(card); - } - private bool log_in_progress() { foreach (var card in container) { if (card.logging) @@ -113,4 +77,64 @@ namespace StudySystemClient { return 0; } } + + private class Updater : IRefreshable { + private weak ActivitiesView target; + private Client client; + + public Updater(ActivitiesView target, Client client) { + this.target = target; + this.client = client; + } + + public async void refresh() { + if (!client.connected || target == null) + return; + try { + var activities = yield client.list_activities(); + apply_update(activities); + target.sort(); + } catch (ClientError e) { + stderr.printf("Error refreshing activities: %s\n", + e.message); + } + } + + private void apply_update(Array activities) { + update_existing(activities); + for (uint i = 0; i < activities.length; ++i) + target.new_card(activities.index(i)); + } + + private void update_existing(Array activities) { + var to_remove = new List(); + foreach (var card in target) { + if (!update_card(card, activities)) + to_remove.append(card); + } + foreach (var card in to_remove) + target.remove_card(card); + } + + private bool update_card(ActivityCard card, + Array activities) { + var activity_index = find_activity(card, activities); + if (activity_index == null) + return false; + var priority = activities.index(activity_index).priority; + card.update_priority(priority); + activities._remove_index_fast(activity_index); + return true; + } + + private static uint? find_activity(ActivityCard card, + Array activities) { + for (uint i = 0; i < activities.length; ++i) { + if (activities.index(i).subject == card.activity.subject + && activities.index(i).type == card.activity.type) + return i; + } + return null; + } + } }