Updating visibilities on calendar events on calendar activation/deactivation.
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||
using CommunityToolkit.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Serilog;
|
||||
using Wino.Calendar.ViewModels.Data;
|
||||
using Wino.Calendar.ViewModels.Interfaces;
|
||||
using Wino.Core.Domain.Collections;
|
||||
@@ -64,8 +65,26 @@ namespace Wino.Calendar.ViewModels
|
||||
_accountCalendarStateService = accountCalendarStateService;
|
||||
_preferencesService = preferencesService;
|
||||
|
||||
_accountCalendarStateService.AccountCalendarSelectionStateChanged += UpdateAccountCalendarRequested;
|
||||
_accountCalendarStateService.CollectiveAccountGroupSelectionStateChanged += AccountCalendarStateCollectivelyChanged;
|
||||
}
|
||||
|
||||
private void AccountCalendarStateCollectivelyChanged(object sender, GroupedAccountCalendarViewModel e)
|
||||
{
|
||||
// For all date ranges, update the events.
|
||||
foreach (var dayRange in DayRanges)
|
||||
{
|
||||
_ = InitializeCalendarEventsForDayRangeAsync(dayRange);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAccountCalendarRequested(object sender, AccountCalendarViewModel e)
|
||||
{
|
||||
foreach (var range in DayRanges)
|
||||
{
|
||||
_ = InitializeCalendarEventsForDayRangeAsync(range);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace when calendar settings are updated.
|
||||
// Should be a field ideally.
|
||||
@@ -125,9 +144,8 @@ namespace Wino.Calendar.ViewModels
|
||||
|
||||
if (ShouldResetDayRanges(message))
|
||||
{
|
||||
DayRanges.Clear();
|
||||
|
||||
Debug.WriteLine("Will reset day ranges.");
|
||||
await ClearDayRangeModelsAsync();
|
||||
}
|
||||
else if (ShouldScrollToItem(message))
|
||||
{
|
||||
@@ -145,6 +163,7 @@ namespace Wino.Calendar.ViewModels
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error while loading calendar.");
|
||||
Debugger.Break();
|
||||
}
|
||||
finally
|
||||
@@ -165,6 +184,47 @@ namespace Wino.Calendar.ViewModels
|
||||
return new DateRange(minimumLoadedDate, maximumLoadedDate);
|
||||
}
|
||||
|
||||
private async Task AddDayRangeModelAsync(DayRangeRenderModel dayRangeRenderModel)
|
||||
{
|
||||
dayRangeRenderModel.CalendarDayEventCollectionUpdated -= EventsUpdatedInDayHeader;
|
||||
dayRangeRenderModel.CalendarDayEventCollectionUpdated += EventsUpdatedInDayHeader;
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
DayRanges.Add(dayRangeRenderModel);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task InsertDayRangeModelAsync(DayRangeRenderModel dayRangeRenderModel, int index)
|
||||
{
|
||||
dayRangeRenderModel.CalendarDayEventCollectionUpdated -= EventsUpdatedInDayHeader;
|
||||
dayRangeRenderModel.CalendarDayEventCollectionUpdated += EventsUpdatedInDayHeader;
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
DayRanges.Insert(index, dayRangeRenderModel);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task RemoveDayRangeModelAsync(DayRangeRenderModel dayRangeRenderModel)
|
||||
{
|
||||
dayRangeRenderModel.CalendarDayEventCollectionUpdated -= EventsUpdatedInDayHeader;
|
||||
dayRangeRenderModel.UnregisterAll();
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
DayRanges.Remove(dayRangeRenderModel);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task ClearDayRangeModelsAsync()
|
||||
{
|
||||
while (DayRanges.Count > 0)
|
||||
{
|
||||
await RemoveDayRangeModelAsync(DayRanges[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RenderDatesAsync(CalendarInitInitiative calendarInitInitiative,
|
||||
DateTime? loadingDisplayDate = null,
|
||||
CalendarLoadDirection calendarLoadDirection = CalendarLoadDirection.Replace)
|
||||
@@ -232,10 +292,9 @@ namespace Wino.Calendar.ViewModels
|
||||
}
|
||||
|
||||
// Dates are loaded. Now load the events for them.
|
||||
|
||||
foreach (var renderModel in renderModels)
|
||||
{
|
||||
await InitializeCalendarEventsAsync(renderModel).ConfigureAwait(false);
|
||||
await InitializeCalendarEventsForDayRangeAsync(renderModel).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
CalendarLoadDirection animationDirection = calendarLoadDirection;
|
||||
@@ -251,11 +310,12 @@ namespace Wino.Calendar.ViewModels
|
||||
isLoadMoreBlocked = true;
|
||||
|
||||
// Remove all other dates except this one.
|
||||
var rangesToRemove = DayRanges.Where(a => a != SelectedDayRange).ToList();
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
foreach (var range in rangesToRemove)
|
||||
{
|
||||
DayRanges.RemoveRange(DayRanges.Where(a => a != SelectedDayRange).ToList());
|
||||
});
|
||||
await RemoveDayRangeModelAsync(range);
|
||||
}
|
||||
|
||||
animationDirection = displayDate <= SelectedDayRange?.CalendarRenderOptions.DateRange.StartDate ?
|
||||
CalendarLoadDirection.Previous : CalendarLoadDirection.Next;
|
||||
@@ -263,13 +323,10 @@ namespace Wino.Calendar.ViewModels
|
||||
|
||||
if (animationDirection == CalendarLoadDirection.Next)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
foreach (var item in renderModels)
|
||||
{
|
||||
foreach (var item in renderModels)
|
||||
{
|
||||
DayRanges.Add(item);
|
||||
}
|
||||
});
|
||||
await AddDayRangeModelAsync(item);
|
||||
}
|
||||
}
|
||||
else if (animationDirection == CalendarLoadDirection.Previous)
|
||||
{
|
||||
@@ -281,10 +338,7 @@ namespace Wino.Calendar.ViewModels
|
||||
// Insert each render model in reverse order.
|
||||
for (int i = renderModels.Count - 1; i >= 0; i--)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
DayRanges.Insert(0, renderModels[i]);
|
||||
});
|
||||
await InsertDayRangeModelAsync(renderModels[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,10 +351,7 @@ namespace Wino.Calendar.ViewModels
|
||||
|
||||
if (removeCurrent)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
DayRanges.Remove(SelectedDayRange);
|
||||
});
|
||||
await RemoveDayRangeModelAsync(SelectedDayRange);
|
||||
}
|
||||
|
||||
// TODO...
|
||||
@@ -320,8 +371,36 @@ namespace Wino.Calendar.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeCalendarEventsAsync(DayRangeRenderModel dayRangeRenderModel)
|
||||
// TODO...
|
||||
private async void EventsUpdatedInDayHeader(object sender, CalendarDayModel e)
|
||||
{
|
||||
// Find the day range model that contains the day model.
|
||||
// TODO: Maybe optimize by just updating the day?
|
||||
|
||||
if (sender is DayRangeRenderModel dayRangeRenderModel)
|
||||
{
|
||||
await InitializeCalendarEventsForDayRangeAsync(dayRangeRenderModel);
|
||||
}
|
||||
|
||||
|
||||
//var dayRange = DayRanges.FirstOrDefault(a => a.CalendarDays.Contains(e));
|
||||
|
||||
//if (dayRange == null) return;
|
||||
|
||||
//await InitializeCalendarEventsForDayRangeAsync(dayRange);
|
||||
}
|
||||
|
||||
private async Task InitializeCalendarEventsForDayRangeAsync(DayRangeRenderModel dayRangeRenderModel)
|
||||
{
|
||||
// Clear all events first for all days.
|
||||
foreach (var day in dayRangeRenderModel.CalendarDays)
|
||||
{
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
day.EventsCollection.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
// Load for each selected calendar from the state.
|
||||
var checkedCalendarViewModels = _accountCalendarStateService.GroupedAccountCalendars
|
||||
.SelectMany(a => a.AccountCalendars)
|
||||
@@ -352,9 +431,7 @@ namespace Wino.Calendar.ViewModels
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
// Use range-based add for performance.
|
||||
// No need to report changes since at this point nothing is rendered on the UI.
|
||||
|
||||
calendarDayModel.EventsCollection.AddCalendarItemRange(calendarItemViewModels, reportChange: false);
|
||||
calendarDayModel.EventsCollection.AddCalendarItemRange(calendarItemViewModels);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ namespace Wino.Calendar.Controls
|
||||
|
||||
collection.CalendarItemRangeAdded += CollectionOfEventsUpdated;
|
||||
collection.CalendarItemRangeRemoved += CollectionOfEventsUpdated;
|
||||
|
||||
collection.CalendarItemsCleared += EventsCleared;
|
||||
}
|
||||
|
||||
private void UnregisterEventCollectionChanged(CalendarEventCollection collection)
|
||||
@@ -87,10 +89,13 @@ namespace Wino.Calendar.Controls
|
||||
|
||||
collection.CalendarItemRangeAdded -= CollectionOfEventsUpdated;
|
||||
collection.CalendarItemRangeRemoved -= CollectionOfEventsUpdated;
|
||||
|
||||
collection.CalendarItemsCleared -= EventsCleared;
|
||||
}
|
||||
|
||||
private void SingleEventUpdated(object sender, ICalendarItem calendarItem) => UpdateCollectionVisuals();
|
||||
private void CollectionOfEventsUpdated(object sender, List<ICalendarItem> calendarItems) => UpdateCollectionVisuals();
|
||||
private void EventsCleared(object sender, System.EventArgs e) => UpdateCollectionVisuals();
|
||||
|
||||
private void UpdateCollectionVisuals()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace Wino.Calendar.Controls
|
||||
private readonly Dictionary<Guid, CalendarItemMeasurement> _measurements = new Dictionary<Guid, CalendarItemMeasurement>();
|
||||
|
||||
public static readonly DependencyProperty EventItemMarginProperty = DependencyProperty.Register(nameof(EventItemMargin), typeof(Thickness), typeof(WinoCalendarPanel), new PropertyMetadata(new Thickness(0, 0, 0, 0)));
|
||||
// public static readonly DependencyProperty RepresentingDateProperty = DependencyProperty.Register(nameof(RepresentingDate), typeof(DateTime), typeof(WinoCalendarControl), new PropertyMetadata(DateTime.MinValue));
|
||||
public static readonly DependencyProperty HourHeightProperty = DependencyProperty.Register(nameof(HourHeight), typeof(double), typeof(WinoCalendarPanel), new PropertyMetadata(0d));
|
||||
|
||||
public double HourHeight
|
||||
@@ -35,44 +34,6 @@ namespace Wino.Calendar.Controls
|
||||
set { SetValue(EventItemMarginProperty, value); }
|
||||
}
|
||||
|
||||
//private static void OnDayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
//{
|
||||
// if (d is WinoCalendarPanel control)
|
||||
// {
|
||||
// // We need to listen for new events being added or removed from the collection to reset measurements.
|
||||
// if (e.OldValue is CalendarDayModel oldDayModel)
|
||||
// {
|
||||
// control.DetachCollection(oldDayModel.EventsCollection.RegularEvents);
|
||||
// }
|
||||
|
||||
// if (e.NewValue is CalendarDayModel newDayModel)
|
||||
// {
|
||||
// control.AttachCollection(newDayModel.EventsCollection.RegularEvents);
|
||||
// }
|
||||
|
||||
// control.ResetMeasurements();
|
||||
// control.UpdateLayout();
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void AttachCollection(IEnumerable<ICalendarItem> events)
|
||||
//{
|
||||
// if (events is INotifyCollectionChanged collection)
|
||||
// {
|
||||
// // var t = new Grid();
|
||||
|
||||
// collection.CollectionChanged += EventCollectionChanged;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void DetachCollection(IEnumerable<ICalendarItem> events)
|
||||
//{
|
||||
// if (events is INotifyCollectionChanged collection)
|
||||
// {
|
||||
// collection.CollectionChanged -= EventCollectionChanged;
|
||||
// }
|
||||
//}
|
||||
|
||||
private void ResetMeasurements() => _measurements.Clear();
|
||||
|
||||
// No need to handle actions. Each action requires a full measurement update.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Domain.Collections
|
||||
@@ -13,6 +15,8 @@ namespace Wino.Core.Domain.Collections
|
||||
public event EventHandler<List<ICalendarItem>> CalendarItemRangeAdded;
|
||||
public event EventHandler<List<ICalendarItem>> CalendarItemRangeRemoved;
|
||||
|
||||
public event EventHandler CalendarItemsCleared;
|
||||
|
||||
private ObservableRangeCollection<ICalendarItem> _internalRegularEvents = [];
|
||||
private ObservableRangeCollection<ICalendarItem> _internalAllDayEvents = [];
|
||||
|
||||
@@ -25,27 +29,33 @@ namespace Wino.Core.Domain.Collections
|
||||
AllDayEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalAllDayEvents);
|
||||
}
|
||||
|
||||
public void AddCalendarItemRange(IEnumerable<ICalendarItem> calendarItems, bool reportChange = true)
|
||||
public bool HasCalendarEvent(AccountCalendar accountCalendar)
|
||||
{
|
||||
return _internalAllDayEvents.Any(x => x.AssignedCalendar.Id == accountCalendar.Id) ||
|
||||
_internalRegularEvents.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
|
||||
}
|
||||
|
||||
public void AddCalendarItemRange(IEnumerable<ICalendarItem> calendarItems)
|
||||
{
|
||||
foreach (var calendarItem in calendarItems)
|
||||
{
|
||||
AddCalendarItem(calendarItem, reportChange: false);
|
||||
AddCalendarItem(calendarItem);
|
||||
}
|
||||
|
||||
CalendarItemRangeAdded?.Invoke(this, new List<ICalendarItem>(calendarItems));
|
||||
}
|
||||
|
||||
public void RemoveCalendarItemRange(IEnumerable<ICalendarItem> calendarItems, bool reportChange = true)
|
||||
public void RemoveCalendarItemRange(IEnumerable<ICalendarItem> calendarItems)
|
||||
{
|
||||
foreach (var calendarItem in calendarItems)
|
||||
{
|
||||
RemoveCalendarItem(calendarItem, reportChange);
|
||||
RemoveCalendarItem(calendarItem);
|
||||
}
|
||||
|
||||
CalendarItemRangeRemoved?.Invoke(this, new List<ICalendarItem>(calendarItems));
|
||||
}
|
||||
|
||||
public void AddCalendarItem(ICalendarItem calendarItem, bool reportChange = true)
|
||||
public void AddCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
@@ -59,13 +69,18 @@ namespace Wino.Core.Domain.Collections
|
||||
_internalRegularEvents.Add(calendarItem);
|
||||
}
|
||||
|
||||
if (reportChange)
|
||||
{
|
||||
CalendarItemAdded?.Invoke(this, calendarItem);
|
||||
}
|
||||
CalendarItemAdded?.Invoke(this, calendarItem);
|
||||
}
|
||||
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem, bool reportChange = true)
|
||||
public void Clear()
|
||||
{
|
||||
_internalAllDayEvents.Clear();
|
||||
_internalRegularEvents.Clear();
|
||||
|
||||
CalendarItemsCleared?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
@@ -79,10 +94,7 @@ namespace Wino.Core.Domain.Collections
|
||||
_internalRegularEvents.Remove(calendarItem);
|
||||
}
|
||||
|
||||
if (reportChange)
|
||||
{
|
||||
CalendarItemRemoved?.Invoke(this, calendarItem);
|
||||
}
|
||||
CalendarItemRemoved?.Invoke(this, calendarItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Itenso.TimePeriod;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Calendar
|
||||
{
|
||||
@@ -28,6 +29,8 @@ namespace Wino.Core.Domain.Models.Calendar
|
||||
var representingDate = calendarRenderOptions.DateRange.StartDate.AddDays(i);
|
||||
var calendarDayModel = new CalendarDayModel(representingDate, calendarRenderOptions);
|
||||
|
||||
RegisterCalendarDayEvents(calendarDayModel);
|
||||
|
||||
CalendarDays.Add(calendarDayModel);
|
||||
}
|
||||
|
||||
@@ -50,38 +53,40 @@ namespace Wino.Core.Domain.Models.Calendar
|
||||
}
|
||||
}
|
||||
|
||||
//private void RegisterCalendarDayEvents(CalendarDayModel calendarDayModel)
|
||||
//{
|
||||
// calendarDayModel.EventsCollection.CalendarItemAdded += CalendarItemAdded;
|
||||
// calendarDayModel.EventsCollection.CalendarItemRangeRemoved += CalendarItemRangeRemoved;
|
||||
// calendarDayModel.EventsCollection.CalendarItemRemoved += CalendarItemRemoved;
|
||||
// calendarDayModel.EventsCollection.CalendarItemRangeAdded += CalendarItemRangeAdded;
|
||||
//}
|
||||
private void RegisterCalendarDayEvents(CalendarDayModel calendarDayModel)
|
||||
{
|
||||
calendarDayModel.EventsCollection.CalendarItemAdded += CalendarItemAdded;
|
||||
calendarDayModel.EventsCollection.CalendarItemRangeRemoved += CalendarItemRangeRemoved;
|
||||
calendarDayModel.EventsCollection.CalendarItemRemoved += CalendarItemRemoved;
|
||||
calendarDayModel.EventsCollection.CalendarItemRangeAdded += CalendarItemRangeAdded;
|
||||
}
|
||||
|
||||
//private void CalendarItemRangeAdded(object sender, List<ICalendarItem> e)
|
||||
// => CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
// TODO: These handlers have incorrect senders. They should be the CalendarDayModel.
|
||||
|
||||
//private void CalendarItemRemoved(object sender, ICalendarItem e)
|
||||
// => CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
private void CalendarItemRangeAdded(object sender, List<ICalendarItem> e)
|
||||
=> CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
|
||||
//private void CalendarItemAdded(object sender, ICalendarItem e)
|
||||
// => CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
private void CalendarItemRemoved(object sender, ICalendarItem e)
|
||||
=> CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
|
||||
//private void CalendarItemRangeRemoved(object sender, List<ICalendarItem> e)
|
||||
// => CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
private void CalendarItemAdded(object sender, ICalendarItem e)
|
||||
=> CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
|
||||
///// <summary>
|
||||
///// Unregisters all calendar item change listeners to draw the UI for calendar events.
|
||||
///// </summary>
|
||||
//public void UnregisterAll()
|
||||
//{
|
||||
// foreach (var day in CalendarDays)
|
||||
// {
|
||||
// day.EventsCollection.CalendarItemRangeRemoved -= CalendarItemRangeRemoved;
|
||||
// day.EventsCollection.CalendarItemRemoved -= CalendarItemRemoved;
|
||||
// day.EventsCollection.CalendarItemRangeAdded -= CalendarItemRangeAdded;
|
||||
// day.EventsCollection.CalendarItemAdded -= CalendarItemAdded;
|
||||
// }
|
||||
//}
|
||||
private void CalendarItemRangeRemoved(object sender, List<ICalendarItem> e)
|
||||
=> CalendarDayEventCollectionUpdated?.Invoke(this, sender as CalendarDayModel);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all calendar item change listeners to draw the UI for calendar events.
|
||||
/// </summary>
|
||||
public void UnregisterAll()
|
||||
{
|
||||
foreach (var day in CalendarDays)
|
||||
{
|
||||
day.EventsCollection.CalendarItemRangeRemoved -= CalendarItemRangeRemoved;
|
||||
day.EventsCollection.CalendarItemRemoved -= CalendarItemRemoved;
|
||||
day.EventsCollection.CalendarItemRangeAdded -= CalendarItemRangeAdded;
|
||||
day.EventsCollection.CalendarItemAdded -= CalendarItemAdded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user