Recalculate recurrences when a new event added.
This commit is contained in:
@@ -863,17 +863,29 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
||||
// Check if event falls into the current date range.
|
||||
if (DayRanges.DisplayRange == null) return;
|
||||
|
||||
// Check whether this event falls into any of the loaded date ranges.
|
||||
var allDaysForEvent = DayRanges.SelectMany(a => a.CalendarDays).Where(a => a.Period.OverlapsWith(calendarItem.Period));
|
||||
// Get all periods from the visible day ranges
|
||||
var visiblePeriods = DayRanges.Select(dr => dr.Period).ToList();
|
||||
|
||||
foreach (var calendarDay in allDaysForEvent)
|
||||
// For recurring events, expand them to check if any occurrences fall within visible periods
|
||||
// For regular events, just check if they overlap with any period
|
||||
var matchingItems = await _calendarService.GetExpandedRecurringEventsForPeriodsAsync(calendarItem, visiblePeriods);
|
||||
|
||||
foreach (var item in matchingItems)
|
||||
{
|
||||
var calendarItemViewModel = new CalendarItemViewModel(calendarItem);
|
||||
// Find the days that the event falls into
|
||||
var allDaysForEvent = DayRanges
|
||||
.SelectMany(a => a.CalendarDays)
|
||||
.Where(a => a.Period.OverlapsWith(item.Period));
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
foreach (var calendarDay in allDaysForEvent)
|
||||
{
|
||||
calendarDay.EventsCollection.AddCalendarItem(calendarItemViewModel);
|
||||
});
|
||||
var calendarItemViewModel = new CalendarItemViewModel(item);
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
calendarDay.EventsCollection.AddCalendarItem(calendarItemViewModel);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
FilterActiveCalendars(DayRanges);
|
||||
|
||||
@@ -25,6 +25,14 @@ public interface ICalendarService
|
||||
/// <param name="period">The time period to query events for.</param>
|
||||
/// <returns>List of calendar items including regular events and recurring event occurrences.</returns>
|
||||
Task<List<CalendarItem>> GetCalendarEventsAsync(IAccountCalendar calendar, ITimePeriod period);
|
||||
|
||||
/// <summary>
|
||||
/// Expands a recurring calendar item to check if any of its occurrences fall within the given periods.
|
||||
/// </summary>
|
||||
/// <param name="calendarItem">The calendar item to expand (can be recurring or non-recurring).</param>
|
||||
/// <param name="periods">The list of periods to check against.</param>
|
||||
/// <returns>List of calendar items (either the original item or expanded recurrence instances) that fall within the periods.</returns>
|
||||
Task<List<CalendarItem>> GetExpandedRecurringEventsForPeriodsAsync(CalendarItem calendarItem, IEnumerable<ITimePeriod> periods);
|
||||
|
||||
Task<CalendarItem> GetCalendarItemAsync(Guid accountCalendarId, string remoteEventId);
|
||||
Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken);
|
||||
|
||||
@@ -269,6 +269,70 @@ public class CalendarService : BaseDatabaseService, ICalendarService
|
||||
deltaToken, calendarId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands a recurring calendar item to check if any of its occurrences fall within the given periods.
|
||||
/// For non-recurring events, returns the item if it overlaps with any period.
|
||||
/// For recurring events, expands occurrences and returns those that fall within any of the periods.
|
||||
/// </summary>
|
||||
/// <param name="calendarItem">The calendar item to expand (can be recurring or non-recurring).</param>
|
||||
/// <param name="periods">The list of periods to check against.</param>
|
||||
/// <returns>List of calendar items (either the original item or expanded recurrence instances) that fall within the periods.</returns>
|
||||
public async Task<List<CalendarItem>> GetExpandedRecurringEventsForPeriodsAsync(CalendarItem calendarItem, IEnumerable<ITimePeriod> periods)
|
||||
{
|
||||
var result = new List<CalendarItem>();
|
||||
|
||||
if (calendarItem == null || periods == null || !periods.Any())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Ensure AssignedCalendar is loaded
|
||||
if (calendarItem.AssignedCalendar == null)
|
||||
{
|
||||
calendarItem.AssignedCalendar = await GetAccountCalendarAsync(calendarItem.CalendarId);
|
||||
}
|
||||
|
||||
// For non-recurring events, check if it overlaps with any of the provided periods
|
||||
if (string.IsNullOrEmpty(calendarItem.Recurrence))
|
||||
{
|
||||
foreach (var period in periods)
|
||||
{
|
||||
if (calendarItem.Period.OverlapsWith(period))
|
||||
{
|
||||
result.Add(calendarItem);
|
||||
break; // Add it only once
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For recurring events, expand occurrences for the combined date range of all periods
|
||||
// Find the minimum and maximum dates across all periods
|
||||
var minDate = periods.Min(p => p.Start);
|
||||
var maxDate = periods.Max(p => p.End);
|
||||
|
||||
var combinedPeriod = new TimeRange(minDate, maxDate);
|
||||
|
||||
// Expand the recurring event for the combined period
|
||||
var expandedOccurrences = await ExpandRecurringEventAsync(calendarItem, combinedPeriod);
|
||||
|
||||
// Filter occurrences that fall within any of the individual periods
|
||||
foreach (var occurrence in expandedOccurrences)
|
||||
{
|
||||
foreach (var period in periods)
|
||||
{
|
||||
if (occurrence.Period.OverlapsWith(period))
|
||||
{
|
||||
result.Add(occurrence);
|
||||
break; // Add it only once even if it overlaps with multiple periods
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task<List<CalendarEventAttendee>> GetAttendeesAsync(Guid calendarEventTrackingId)
|
||||
=> Connection.Table<CalendarEventAttendee>().Where(x => x.CalendarItemId == calendarEventTrackingId).ToListAsync();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user