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.
|
// Check if event falls into the current date range.
|
||||||
if (DayRanges.DisplayRange == null) return;
|
if (DayRanges.DisplayRange == null) return;
|
||||||
|
|
||||||
// Check whether this event falls into any of the loaded date ranges.
|
// Get all periods from the visible day ranges
|
||||||
var allDaysForEvent = DayRanges.SelectMany(a => a.CalendarDays).Where(a => a.Period.OverlapsWith(calendarItem.Period));
|
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);
|
FilterActiveCalendars(DayRanges);
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ public interface ICalendarService
|
|||||||
/// <returns>List of calendar items including regular events and recurring event occurrences.</returns>
|
/// <returns>List of calendar items including regular events and recurring event occurrences.</returns>
|
||||||
Task<List<CalendarItem>> GetCalendarEventsAsync(IAccountCalendar calendar, ITimePeriod period);
|
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<CalendarItem> GetCalendarItemAsync(Guid accountCalendarId, string remoteEventId);
|
||||||
Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken);
|
Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken);
|
||||||
|
|
||||||
|
|||||||
@@ -269,6 +269,70 @@ public class CalendarService : BaseDatabaseService, ICalendarService
|
|||||||
deltaToken, calendarId);
|
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)
|
public Task<List<CalendarEventAttendee>> GetAttendeesAsync(Guid calendarEventTrackingId)
|
||||||
=> Connection.Table<CalendarEventAttendee>().Where(x => x.CalendarItemId == calendarEventTrackingId).ToListAsync();
|
=> Connection.Table<CalendarEventAttendee>().Where(x => x.CalendarItemId == calendarEventTrackingId).ToListAsync();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user