Fixed the display date of the calendar items. Created test project for core library, included tests for recurring calendar events.

This commit is contained in:
Burak Kaan Köse
2025-12-29 14:10:09 +01:00
parent f79305f0a6
commit 8613e92b31
33 changed files with 1168 additions and 173 deletions
@@ -5,7 +5,6 @@ using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Calendar.ViewModels.Data;
using Wino.Calendar.ViewModels.Interfaces;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Mail.WinUI.Services;
@@ -33,16 +32,16 @@ public partial class AccountCalendarStateService : ObservableObject, IAccountCal
}
}
public IEnumerable<IGrouping<MailAccount, AccountCalendarViewModel>> GroupedAccountCalendarsEnumerable
{
get
{
return GroupedAccountCalendars
.Select(a => a.AccountCalendars)
.SelectMany(b => b)
.GroupBy(c => c.Account);
}
}
//public IEnumerable<IGrouping<MailAccount, AccountCalendarViewModel>> GroupedAccountCalendarsEnumerable
//{
// get
// {
// return GroupedAccountCalendars
// .Select(a => a.AccountCalendars)
// .SelectMany(b => b)
// .GroupBy(c => c.Account);
// }
//}
public AccountCalendarStateService()
{
+81 -47
View File
@@ -87,6 +87,9 @@ public class NavigationService : NavigationServiceBase, INavigationService
if (coreFrame == null) return false;
// Update the application mode in state persistence service
_statePersistanceService.ApplicationMode = mode;
var targetPageType = mode == WinoApplicationMode.Mail ? typeof(MailAppShell) : typeof(CalendarAppShell);
var currentPageType = coreFrame.Content?.GetType();
var transitionInfo = GetNavigationTransitionInfo(NavigationTransitionType.DrillIn);
@@ -128,73 +131,104 @@ public class NavigationService : NavigationServiceBase, INavigationService
NavigationTransitionType transition = NavigationTransitionType.None)
{
var pageType = GetPageType(page);
Frame shellFrame = GetCoreFrame(NavigationReferenceFrame.InnerShellFrame);
var currentApplicationMode = GetCoreFrame(NavigationReferenceFrame.ShellFrame)?.Content?.GetType() == typeof(MailAppShell)
? WinoApplicationMode.Mail
: WinoApplicationMode.Calendar;
_statePersistanceService.IsReadingMail = _renderingPageTypes.Contains(page);
_statePersistanceService.IsEventDetailsVisible = page == WinoPage.EventDetailsPage;
if (shellFrame != null)
Frame innerShellFrame = GetCoreFrame(NavigationReferenceFrame.InnerShellFrame);
if (innerShellFrame != null)
{
var currentFrameType = GetCurrentFrameType(ref shellFrame);
bool isCalendarShellActive = shellFrame.Content != null && shellFrame.Content.GetType() == typeof(CalendarAppShell);
if (isCalendarShellActive)
// Calendar navigations.
if (currentApplicationMode == WinoApplicationMode.Calendar)
{
return shellFrame.Navigate(pageType, parameter);
return innerShellFrame.Navigate(pageType, parameter);
}
bool isMailListingPageActive = currentFrameType != null && currentFrameType == typeof(MailListPage);
// Active page is mail list page and we are refreshing the folder.
if (isMailListingPageActive && currentFrameType == pageType && parameter is NavigateMailFolderEventArgs folderNavigationArgs)
else
{
// No need for new navigation, just refresh the folder.
WeakReferenceMessenger.Default.Send(new ActiveMailFolderChangedEvent(folderNavigationArgs.BaseFolderMenuItem, folderNavigationArgs.FolderInitLoadAwaitTask));
WeakReferenceMessenger.Default.Send(new DisposeRenderingFrameRequested());
// Mail navigations.
var currentFrameType = GetCurrentFrameType(ref innerShellFrame);
bool isMailListingPageActive = currentFrameType != null && currentFrameType == typeof(MailListPage);
return true;
}
var transitionInfo = GetNavigationTransitionInfo(transition);
// This page must be opened in the Frame placed in MailListingPage.
if (isMailListingPageActive && frame == NavigationReferenceFrame.RenderingFrame)
{
var listingFrame = GetCoreFrame(NavigationReferenceFrame.RenderingFrame);
if (listingFrame == null) return false;
// Active page is mail list page and we are opening a mail item.
// No navigation needed, just refresh the rendered mail item.
if (listingFrame.Content != null
&& listingFrame.Content.GetType() == GetPageType(WinoPage.MailRenderingPage)
&& parameter is MailItemViewModel mailItemViewModel
&& page != WinoPage.ComposePage)
// Active page is mail list page and we are refreshing the folder.
if (isMailListingPageActive && currentFrameType == pageType && parameter is NavigateMailFolderEventArgs folderNavigationArgs)
{
WeakReferenceMessenger.Default.Send(new NewMailItemRenderingRequestedEvent(mailItemViewModel));
}
else if (listingFrame.Content != null
&& listingFrame.Content.GetType() == GetPageType(WinoPage.IdlePage)
&& pageType == typeof(IdlePage))
{
// Idle -> Idle navigation. Ignore.
// No need for new navigation, just refresh the folder.
WeakReferenceMessenger.Default.Send(new ActiveMailFolderChangedEvent(folderNavigationArgs.BaseFolderMenuItem, folderNavigationArgs.FolderInitLoadAwaitTask));
WeakReferenceMessenger.Default.Send(new DisposeRenderingFrameRequested());
return true;
}
else
var transitionInfo = GetNavigationTransitionInfo(transition);
// This page must be opened in the Frame placed in MailListingPage.
if (isMailListingPageActive && frame == NavigationReferenceFrame.RenderingFrame)
{
listingFrame.Navigate(pageType, parameter, transitionInfo);
var listingFrame = GetCoreFrame(NavigationReferenceFrame.RenderingFrame);
if (listingFrame == null) return false;
// Active page is mail list page and we are opening a mail item.
// No navigation needed, just refresh the rendered mail item.
if (listingFrame.Content != null
&& listingFrame.Content.GetType() == GetPageType(WinoPage.MailRenderingPage)
&& parameter is MailItemViewModel mailItemViewModel
&& page != WinoPage.ComposePage)
{
WeakReferenceMessenger.Default.Send(new NewMailItemRenderingRequestedEvent(mailItemViewModel));
}
else if (listingFrame.Content != null
&& listingFrame.Content.GetType() == GetPageType(WinoPage.IdlePage)
&& pageType == typeof(IdlePage))
{
// Idle -> Idle navigation. Ignore.
return true;
}
else
{
listingFrame.Navigate(pageType, parameter, transitionInfo);
}
return true;
}
return true;
}
if ((currentFrameType != null && currentFrameType != pageType) || currentFrameType == null)
{
return shellFrame.Navigate(pageType, parameter, transitionInfo);
if ((currentFrameType != null && currentFrameType != pageType) || currentFrameType == null)
{
return innerShellFrame.Navigate(pageType, parameter, transitionInfo);
}
}
}
return false;
}
public void GoBack() => throw new NotImplementedException("GoBack method is not implemented in Wino Mail.");
public void GoBack()
{
if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Calendar)
{
var innerShellFrame = GetCoreFrame(NavigationReferenceFrame.InnerShellFrame);
if (innerShellFrame?.CanGoBack == true)
{
innerShellFrame.GoBack();
// Calendar mode: Navigate back from EventDetailsPage
_statePersistanceService.IsEventDetailsVisible = false;
}
}
else
{
// Mail mode: Clear selections and dispose rendering frame
_statePersistanceService.IsReadingMail = false;
WeakReferenceMessenger.Default.Send(new ClearMailSelectionsRequested());
WeakReferenceMessenger.Default.Send(new DisposeRenderingFrameRequested());
}
}
// Standalone EML viewer.
//public void NavigateRendering(MimeMessageInformation mimeMessageInformation, NavigationTransitionType transition = NavigationTransitionType.None)
@@ -9,7 +9,7 @@ namespace Wino.Services;
public class StatePersistenceService : ObservableObject, IStatePersistanceService
{
public event EventHandler<string> StatePropertyChanged;
public event EventHandler<string?>? StatePropertyChanged;
private const string OpenPaneLengthKey = nameof(OpenPaneLengthKey);
private const string MailListPaneLengthKey = nameof(MailListPaneLengthKey);
@@ -28,9 +28,40 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
PropertyChanged += ServicePropertyChanged;
}
private void ServicePropertyChanged(object sender, PropertyChangedEventArgs e) => StatePropertyChanged?.Invoke(this, e.PropertyName);
private void ServicePropertyChanged(object? sender, PropertyChangedEventArgs e) => StatePropertyChanged?.Invoke(this, e?.PropertyName ?? string.Empty);
public bool IsBackButtonVisible => IsReadingMail && IsReaderNarrowed;
public bool IsBackButtonVisible =>
ApplicationMode == WinoApplicationMode.Mail
? IsReadingMail && IsReaderNarrowed
: IsEventDetailsVisible;
private WinoApplicationMode applicationMode = WinoApplicationMode.Mail;
public WinoApplicationMode ApplicationMode
{
get => applicationMode;
set
{
if (SetProperty(ref applicationMode, value))
{
OnPropertyChanged(nameof(IsBackButtonVisible));
}
}
}
private bool isEventDetailsVisible;
public bool IsEventDetailsVisible
{
get => isEventDetailsVisible;
set
{
if (SetProperty(ref isEventDetailsVisible, value))
{
OnPropertyChanged(nameof(IsBackButtonVisible));
}
}
}
private bool isReadingMail;
@@ -68,7 +99,7 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
}
}
private string coreWindowTitle;
private string coreWindowTitle = string.Empty;
public string CoreWindowTitle
{