I dont know some improvements on reacting calendar changes.
This commit is contained in:
@@ -166,7 +166,6 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
|||||||
base.RegisterRecipients();
|
base.RegisterRecipients();
|
||||||
|
|
||||||
Messenger.Register<LoadCalendarMessage>(this);
|
Messenger.Register<LoadCalendarMessage>(this);
|
||||||
Messenger.Register<CalendarItemDeleted>(this);
|
|
||||||
Messenger.Register<CalendarSettingsUpdatedMessage>(this);
|
Messenger.Register<CalendarSettingsUpdatedMessage>(this);
|
||||||
Messenger.Register<CalendarItemTappedMessage>(this);
|
Messenger.Register<CalendarItemTappedMessage>(this);
|
||||||
Messenger.Register<CalendarItemDoubleTappedMessage>(this);
|
Messenger.Register<CalendarItemDoubleTappedMessage>(this);
|
||||||
@@ -177,7 +176,6 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
|||||||
base.UnregisterRecipients();
|
base.UnregisterRecipients();
|
||||||
|
|
||||||
Messenger.Unregister<LoadCalendarMessage>(this);
|
Messenger.Unregister<LoadCalendarMessage>(this);
|
||||||
Messenger.Unregister<CalendarItemDeleted>(this);
|
|
||||||
Messenger.Unregister<CalendarSettingsUpdatedMessage>(this);
|
Messenger.Unregister<CalendarSettingsUpdatedMessage>(this);
|
||||||
Messenger.Unregister<CalendarItemTappedMessage>(this);
|
Messenger.Unregister<CalendarItemTappedMessage>(this);
|
||||||
Messenger.Unregister<CalendarItemDoubleTappedMessage>(this);
|
Messenger.Unregister<CalendarItemDoubleTappedMessage>(this);
|
||||||
@@ -613,30 +611,7 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnCalendarItemAdded(CalendarItem calendarItem)
|
|
||||||
{
|
|
||||||
base.OnCalendarItemAdded(calendarItem);
|
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
foreach (var calendarDay in allDaysForEvent)
|
|
||||||
{
|
|
||||||
var calendarItemViewModel = new CalendarItemViewModel(calendarItem);
|
|
||||||
|
|
||||||
await ExecuteUIThread(() =>
|
|
||||||
{
|
|
||||||
calendarDay.EventsCollection.AddCalendarItem(calendarItemViewModel);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterActiveCalendars(DayRanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task InitializeCalendarEventsForDayRangeAsync(DayRangeRenderModel dayRangeRenderModel)
|
private async Task InitializeCalendarEventsForDayRangeAsync(DayRangeRenderModel dayRangeRenderModel)
|
||||||
{
|
{
|
||||||
@@ -871,23 +846,36 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel,
|
|||||||
|
|
||||||
public void Receive(CalendarItemDoubleTappedMessage message) => NavigateEvent(message.CalendarItemViewModel, CalendarEventTargetType.Single);
|
public void Receive(CalendarItemDoubleTappedMessage message) => NavigateEvent(message.CalendarItemViewModel, CalendarEventTargetType.Single);
|
||||||
|
|
||||||
public void Receive(CalendarItemRightTappedMessage message)
|
public void Receive(CalendarItemRightTappedMessage message) { }
|
||||||
{
|
|
||||||
|
|
||||||
|
protected override void OnCalendarItemDeleted(CalendarItem calendarItem)
|
||||||
|
{
|
||||||
|
base.OnCalendarItemDeleted(calendarItem);
|
||||||
|
|
||||||
|
Debug.WriteLine($"Calendar item deleted: {calendarItem.Id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Receive(CalendarItemDeleted message)
|
protected override async void OnCalendarItemAdded(CalendarItem calendarItem)
|
||||||
{
|
{
|
||||||
// Each deleted recurrence will report for it's own.
|
base.OnCalendarItemAdded(calendarItem);
|
||||||
|
Debug.WriteLine($"Calendar item added: {calendarItem.Id}");
|
||||||
|
|
||||||
await ExecuteUIThread(() =>
|
// 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));
|
||||||
|
|
||||||
|
foreach (var calendarDay in allDaysForEvent)
|
||||||
{
|
{
|
||||||
var deletedItem = message.CalendarItem;
|
var calendarItemViewModel = new CalendarItemViewModel(calendarItem);
|
||||||
|
|
||||||
// Event might be spreaded into multiple days.
|
await ExecuteUIThread(() =>
|
||||||
// Remove from all.
|
{
|
||||||
|
calendarDay.EventsCollection.AddCalendarItem(calendarItemViewModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// var calendarItems = GetCalendarItems(deletedItem.Id);
|
FilterActiveCalendars(DayRanges);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,5 @@ public interface ICalendarService
|
|||||||
Task<CalendarItem> GetCalendarItemAsync(Guid id);
|
Task<CalendarItem> GetCalendarItemAsync(Guid id);
|
||||||
Task<List<CalendarEventAttendee>> GetAttendeesAsync(Guid calendarEventTrackingId);
|
Task<List<CalendarEventAttendee>> GetAttendeesAsync(Guid calendarEventTrackingId);
|
||||||
Task<List<CalendarEventAttendee>> ManageEventAttendeesAsync(Guid calendarItemId, List<CalendarEventAttendee> allAttendees);
|
Task<List<CalendarEventAttendee>> ManageEventAttendeesAsync(Guid calendarItemId, List<CalendarEventAttendee> allAttendees);
|
||||||
|
Task UpdateCalendarItemAsync(CalendarItem calendarItem, List<CalendarEventAttendee> attendees);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,34 @@ using Wino.Messaging.Client.Calendar;
|
|||||||
|
|
||||||
namespace Wino.Core.ViewModels;
|
namespace Wino.Core.ViewModels;
|
||||||
|
|
||||||
public class CalendarBaseViewModel : CoreBaseViewModel, IRecipient<CalendarItemAdded>
|
public class CalendarBaseViewModel : CoreBaseViewModel,
|
||||||
|
IRecipient<CalendarItemAdded>,
|
||||||
|
IRecipient<CalendarItemUpdated>,
|
||||||
|
IRecipient<CalendarItemDeleted>
|
||||||
{
|
{
|
||||||
public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem);
|
public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem);
|
||||||
|
public void Receive(CalendarItemUpdated message) => OnCalendarItemUpdated(message.CalendarItem);
|
||||||
|
public void Receive(CalendarItemDeleted message) => OnCalendarItemDeleted(message.CalendarItem);
|
||||||
|
|
||||||
protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { }
|
protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { }
|
||||||
|
protected virtual void OnCalendarItemUpdated(CalendarItem calendarItem) { }
|
||||||
|
protected virtual void OnCalendarItemDeleted(CalendarItem calendarItem) { }
|
||||||
|
|
||||||
protected override void RegisterRecipients()
|
protected override void RegisterRecipients()
|
||||||
{
|
{
|
||||||
base.RegisterRecipients();
|
base.RegisterRecipients();
|
||||||
|
|
||||||
Messenger.Register<CalendarItemAdded>(this);
|
Messenger.Register<CalendarItemAdded>(this);
|
||||||
|
Messenger.Register<CalendarItemUpdated>(this);
|
||||||
|
Messenger.Register<CalendarItemDeleted>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UnregisterRecipients()
|
protected override void UnregisterRecipients()
|
||||||
{
|
{
|
||||||
base.UnregisterRecipients();
|
base.UnregisterRecipients();
|
||||||
|
|
||||||
Messenger.Unregister<CalendarItemAdded>(this);
|
Messenger.Unregister<CalendarItemAdded>(this);
|
||||||
|
Messenger.Unregister<CalendarItemUpdated>(this);
|
||||||
|
Messenger.Unregister<CalendarItemDeleted>(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Graph.Models;
|
using Microsoft.Graph.Models;
|
||||||
@@ -49,6 +50,7 @@ public class OutlookChangeProcessor(IDatabaseService databaseService,
|
|||||||
var savingItem = await CalendarService.GetCalendarItemAsync(assignedCalendar.Id, calendarEvent.Id);
|
var savingItem = await CalendarService.GetCalendarItemAsync(assignedCalendar.Id, calendarEvent.Id);
|
||||||
|
|
||||||
Guid savingItemId = Guid.Empty;
|
Guid savingItemId = Guid.Empty;
|
||||||
|
bool isNewItem = savingItem == null;
|
||||||
|
|
||||||
if (savingItem != null)
|
if (savingItem != null)
|
||||||
savingItemId = savingItem.Id;
|
savingItemId = savingItem.Id;
|
||||||
@@ -111,7 +113,7 @@ public class OutlookChangeProcessor(IDatabaseService databaseService,
|
|||||||
// Set timestamps
|
// Set timestamps
|
||||||
if (calendarEvent.CreatedDateTime.HasValue)
|
if (calendarEvent.CreatedDateTime.HasValue)
|
||||||
savingItem.CreatedAt = calendarEvent.CreatedDateTime.Value;
|
savingItem.CreatedAt = calendarEvent.CreatedDateTime.Value;
|
||||||
|
|
||||||
if (calendarEvent.LastModifiedDateTime.HasValue)
|
if (calendarEvent.LastModifiedDateTime.HasValue)
|
||||||
savingItem.UpdatedAt = calendarEvent.LastModifiedDateTime.Value;
|
savingItem.UpdatedAt = calendarEvent.LastModifiedDateTime.Value;
|
||||||
|
|
||||||
@@ -164,15 +166,23 @@ public class OutlookChangeProcessor(IDatabaseService databaseService,
|
|||||||
savingItem.Status = CalendarItemStatus.Confirmed;
|
savingItem.Status = CalendarItemStatus.Confirmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upsert the event.
|
// Prepare attendees list
|
||||||
await Connection.InsertOrReplaceAsync(savingItem, typeof(CalendarItem));
|
List<CalendarEventAttendee> attendees = null;
|
||||||
|
|
||||||
// Manage attendees.
|
|
||||||
if (calendarEvent.Attendees != null)
|
if (calendarEvent.Attendees != null)
|
||||||
{
|
{
|
||||||
// Clear all attendees for this event.
|
attendees = calendarEvent.Attendees.Select(a => a.CreateAttendee(savingItemId)).ToList();
|
||||||
var attendees = calendarEvent.Attendees.Select(a => a.CreateAttendee(savingItemId)).ToList();
|
}
|
||||||
await CalendarService.ManageEventAttendeesAsync(savingItemId, attendees).ConfigureAwait(false);
|
|
||||||
|
// Use CalendarService to create or update the event
|
||||||
|
if (isNewItem)
|
||||||
|
{
|
||||||
|
// New item - use CreateNewCalendarItemAsync
|
||||||
|
await CalendarService.CreateNewCalendarItemAsync(savingItem, attendees).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Existing item - use UpdateCalendarItemAsync
|
||||||
|
await CalendarService.UpdateCalendarItemAsync(savingItem, attendees).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ public partial class CustomCalendarFlipView : FlipView
|
|||||||
// Hide navigation buttons
|
// Hide navigation buttons
|
||||||
PreviousButton.Opacity = NextButton.Opacity = 0;
|
PreviousButton.Opacity = NextButton.Opacity = 0;
|
||||||
PreviousButton.IsHitTestVisible = NextButton.IsHitTestVisible = false;
|
PreviousButton.IsHitTestVisible = NextButton.IsHitTestVisible = false;
|
||||||
|
|
||||||
var t = FindName("ScrollingHost");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GoPreviousFlip()
|
public void GoPreviousFlip()
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ public partial class WinoCalendarControl : Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void OnActiveVerticalScrollViewerChanged(DependencyObject calendar, DependencyPropertyChangedEventArgs e)
|
private static void OnActiveVerticalScrollViewerChanged(DependencyObject calendar, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (calendar is WinoCalendarControl calendarControl)
|
if (calendar is WinoCalendarControl calendarControl)
|
||||||
@@ -152,7 +151,6 @@ public partial class WinoCalendarControl : Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void OnActiveCanvasChanged(DependencyObject calendar, DependencyPropertyChangedEventArgs e)
|
private static void OnActiveCanvasChanged(DependencyObject calendar, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (calendar is WinoCalendarControl calendarControl)
|
if (calendar is WinoCalendarControl calendarControl)
|
||||||
@@ -189,6 +187,8 @@ public partial class WinoCalendarControl : Control
|
|||||||
canvas.SelectedDateTime = null;
|
canvas.SelectedDateTime = null;
|
||||||
canvas.TimelineCellSelected -= ActiveTimelineCellSelected;
|
canvas.TimelineCellSelected -= ActiveTimelineCellSelected;
|
||||||
canvas.TimelineCellUnselected -= ActiveTimelineCellUnselected;
|
canvas.TimelineCellUnselected -= ActiveTimelineCellUnselected;
|
||||||
|
|
||||||
|
canvas.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterCanvas(WinoDayTimelineCanvas canvas)
|
private void RegisterCanvas(WinoDayTimelineCanvas canvas)
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ using CommunityToolkit.Mvvm.Messaging;
|
|||||||
using Ical.Net.CalendarComponents;
|
using Ical.Net.CalendarComponents;
|
||||||
using Ical.Net.DataTypes;
|
using Ical.Net.DataTypes;
|
||||||
using Itenso.TimePeriod;
|
using Itenso.TimePeriod;
|
||||||
|
using Serilog;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Entities.Calendar;
|
using Wino.Core.Domain.Entities.Calendar;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Messaging.Client.Calendar;
|
using Wino.Messaging.Client.Calendar;
|
||||||
using Wino.Services.Extensions;
|
|
||||||
|
|
||||||
namespace Wino.Services;
|
namespace Wino.Services;
|
||||||
|
|
||||||
@@ -78,17 +78,49 @@ public class CalendarService : BaseDatabaseService, ICalendarService
|
|||||||
|
|
||||||
public async Task CreateNewCalendarItemAsync(CalendarItem calendarItem, List<CalendarEventAttendee> attendees)
|
public async Task CreateNewCalendarItemAsync(CalendarItem calendarItem, List<CalendarEventAttendee> attendees)
|
||||||
{
|
{
|
||||||
await Connection.RunInTransactionAsync((conn) =>
|
try
|
||||||
{
|
{
|
||||||
conn.Insert(calendarItem, typeof(CalendarItem));
|
await Connection.RunInTransactionAsync((conn) =>
|
||||||
|
{
|
||||||
|
conn.Insert(calendarItem, typeof(CalendarItem));
|
||||||
|
|
||||||
if (attendees != null)
|
if (attendees != null)
|
||||||
{
|
{
|
||||||
conn.InsertAll(attendees, typeof(CalendarEventAttendee));
|
conn.InsertAll(attendees, typeof(CalendarEventAttendee));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
WeakReferenceMessenger.Default.Send(new CalendarItemAdded(calendarItem));
|
WeakReferenceMessenger.Default.Send(new CalendarItemAdded(calendarItem));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error creating new calendar item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateCalendarItemAsync(CalendarItem calendarItem, List<CalendarEventAttendee> attendees)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Connection.RunInTransactionAsync((conn) =>
|
||||||
|
{
|
||||||
|
conn.Update(calendarItem, typeof(CalendarItem));
|
||||||
|
|
||||||
|
// Clear existing attendees and add new ones
|
||||||
|
conn.Table<CalendarEventAttendee>().Delete(a => a.CalendarItemId == calendarItem.Id);
|
||||||
|
|
||||||
|
if (attendees != null)
|
||||||
|
{
|
||||||
|
conn.InsertAll(attendees, typeof(CalendarEventAttendee));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
WeakReferenceMessenger.Default.Send(new CalendarItemUpdated(calendarItem));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error updating calendar item");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -180,7 +212,7 @@ public class CalendarService : BaseDatabaseService, ICalendarService
|
|||||||
// Compare by checking if an exception instance overlaps with this occurrence's time window.
|
// Compare by checking if an exception instance overlaps with this occurrence's time window.
|
||||||
var occurrenceStart = occurrence.Period.StartTime.Value;
|
var occurrenceStart = occurrence.Period.StartTime.Value;
|
||||||
var occurrenceEnd = occurrence.Period.EndTime?.Value ?? occurrenceStart.Add(occurrence.Period.Duration);
|
var occurrenceEnd = occurrence.Period.EndTime?.Value ?? occurrenceStart.Add(occurrence.Period.Duration);
|
||||||
|
|
||||||
var exceptionInstance = exceptionInstances.FirstOrDefault(a =>
|
var exceptionInstance = exceptionInstances.FirstOrDefault(a =>
|
||||||
a.StartDate <= occurrenceEnd && a.EndDate >= occurrenceStart);
|
a.StartDate <= occurrenceEnd && a.EndDate >= occurrenceStart);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user