Proper handling of DateTimeOffset, support for Multi-Day events and reacting to adding/removing events for the days.

This commit is contained in:
Burak Kaan Köse
2024-12-30 23:10:51 +01:00
parent 8cc7d46d7b
commit 8fd09bcad4
23 changed files with 340 additions and 234 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Itenso.TimePeriod;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Interfaces;
@@ -12,9 +13,6 @@ namespace Wino.Core.Domain.Collections
public event EventHandler<ICalendarItem> CalendarItemAdded;
public event EventHandler<ICalendarItem> CalendarItemRemoved;
public event EventHandler<List<ICalendarItem>> CalendarItemRangeAdded;
public event EventHandler<List<ICalendarItem>> CalendarItemRangeRemoved;
public event EventHandler CalendarItemsCleared;
private ObservableRangeCollection<ICalendarItem> _internalRegularEvents = [];
@@ -22,79 +20,97 @@ namespace Wino.Core.Domain.Collections
public ReadOnlyObservableCollection<ICalendarItem> RegularEvents { get; }
public ReadOnlyObservableCollection<ICalendarItem> AllDayEvents { get; }
public ITimePeriod Period { get; }
public CalendarEventCollection()
private readonly List<ICalendarItem> _allItems = new List<ICalendarItem>();
public CalendarEventCollection(ITimePeriod period)
{
RegularEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalRegularEvents);
AllDayEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalAllDayEvents);
Period = period;
}
public bool HasCalendarEvent(AccountCalendar accountCalendar)
=> _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
public void FilterByCalendars(IEnumerable<Guid> visibleCalendarIds)
{
return _internalAllDayEvents.Any(x => x.AssignedCalendar.Id == accountCalendar.Id) ||
_internalRegularEvents.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
foreach (var item in _allItems)
{
var collection = GetProperCollectionForCalendarItem(item);
if (!visibleCalendarIds.Contains(item.AssignedCalendar.Id) && collection.Contains(item))
{
RemoveCalendarItemInternal(collection, item, false);
}
else if (visibleCalendarIds.Contains(item.AssignedCalendar.Id) && !collection.Contains(item))
{
AddCalendarItemInternal(collection, item, false);
}
}
}
public void AddCalendarItemRange(IEnumerable<ICalendarItem> calendarItems)
private ObservableRangeCollection<ICalendarItem> GetProperCollectionForCalendarItem(ICalendarItem calendarItem)
{
foreach (var calendarItem in calendarItems)
{
AddCalendarItem(calendarItem);
}
// Event duration is not simply enough to determine whether it's an all-day event or not.
// Event may start at 11:00 PM and end next day at 11:00 PM. It's not an all-day event.
// It's a multi-day event.
CalendarItemRangeAdded?.Invoke(this, new List<ICalendarItem>(calendarItems));
}
bool isAllDayEvent = calendarItem.Period.Duration.TotalDays == 1 && calendarItem.Period.Start.TimeOfDay == TimeSpan.Zero;
public void RemoveCalendarItemRange(IEnumerable<ICalendarItem> calendarItems)
{
foreach (var calendarItem in calendarItems)
{
RemoveCalendarItem(calendarItem);
}
CalendarItemRangeRemoved?.Invoke(this, new List<ICalendarItem>(calendarItems));
return isAllDayEvent ? _internalAllDayEvents : _internalRegularEvents;
}
public void AddCalendarItem(ICalendarItem calendarItem)
{
var collection = GetProperCollectionForCalendarItem(calendarItem);
AddCalendarItemInternal(collection, calendarItem);
}
public void RemoveCalendarItem(ICalendarItem calendarItem)
{
var collection = GetProperCollectionForCalendarItem(calendarItem);
RemoveCalendarItemInternal(collection, calendarItem);
}
private void AddCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool create = true)
{
if (calendarItem is not ICalendarItemViewModel)
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
if (calendarItem.Period.Duration.TotalMinutes == 1440)
collection.Add(calendarItem);
if (create)
{
_internalAllDayEvents.Add(calendarItem);
}
else
{
_internalRegularEvents.Add(calendarItem);
_allItems.Add(calendarItem);
}
CalendarItemAdded?.Invoke(this, calendarItem);
}
private void RemoveCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool destroy = true)
{
if (calendarItem is not ICalendarItemViewModel)
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
collection.Remove(calendarItem);
if (destroy)
{
_allItems.Remove(calendarItem);
}
CalendarItemRemoved?.Invoke(this, calendarItem);
}
public void Clear()
{
_internalAllDayEvents.Clear();
_internalRegularEvents.Clear();
_allItems.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));
if (calendarItem.Period.Duration.TotalMinutes == 1440)
{
_internalAllDayEvents.Remove(calendarItem);
}
else
{
_internalRegularEvents.Remove(calendarItem);
}
CalendarItemRemoved?.Invoke(this, calendarItem);
}
}
}