I dont know some improvements on reacting calendar changes.

This commit is contained in:
Burak Kaan Köse
2025-12-29 23:13:32 +01:00
parent 6ba2f1f3e2
commit 0519bf86b3
7 changed files with 101 additions and 61 deletions
@@ -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);
} }
+14 -3
View File
@@ -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)
+43 -11
View File
@@ -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);