diff --git a/Wino.Core.Domain/Models/Calendar/CalendarRangeTextFormatter.cs b/Wino.Core.Domain/Models/Calendar/CalendarRangeTextFormatter.cs index 055c8ffc..8d0bade7 100644 --- a/Wino.Core.Domain/Models/Calendar/CalendarRangeTextFormatter.cs +++ b/Wino.Core.Domain/Models/Calendar/CalendarRangeTextFormatter.cs @@ -9,16 +9,23 @@ public sealed class CalendarRangeTextFormatter : ICalendarRangeTextFormatter public string Format(VisibleDateRange range, IDateContextProvider dateContextProvider) { var culture = dateContextProvider.Culture; - var startText = FormatDate(range.StartDate, culture); - if (range.DisplayType == CalendarDisplayType.Day) + if (range.DayCount >= 28) { - return startText; + return FormatMonth(range.PrimaryDate, culture); } - return $"{startText} - {FormatDate(range.EndDate, culture)}"; + if (range.DayCount == 1 || range.DisplayType == CalendarDisplayType.Day) + { + return FormatDate(range.StartDate, culture); + } + + return $"{FormatDate(range.StartDate, culture)} - {FormatDate(range.EndDate, culture)}"; } private static string FormatDate(DateOnly date, CultureInfo culture) - => date.ToString(culture.DateTimeFormat.ShortDatePattern, culture); + => date.ToString(culture.DateTimeFormat.MonthDayPattern, culture); + + private static string FormatMonth(DateOnly date, CultureInfo culture) + => date.ToString(culture.DateTimeFormat.YearMonthPattern, culture); } diff --git a/Wino.Core.Tests/CalendarPageViewModelTests.cs b/Wino.Core.Tests/CalendarPageViewModelTests.cs index ce765593..f656c137 100644 --- a/Wino.Core.Tests/CalendarPageViewModelTests.cs +++ b/Wino.Core.Tests/CalendarPageViewModelTests.cs @@ -42,7 +42,7 @@ public class CalendarPageViewModelTests viewModel.CurrentVisibleRange.EndDate.Should().Be(new DateOnly(2026, 3, 22)); viewModel.LoadedDateWindow.StartDate.Should().Be(new DateTime(2026, 3, 9)); viewModel.LoadedDateWindow.EndDate.Should().Be(new DateTime(2026, 3, 30)); - viewModel.VisibleDateRangeText.Should().Be("3/16/2026 - 3/22/2026"); + viewModel.VisibleDateRangeText.Should().Be("March 16 - March 22"); requestedPeriod.Should().NotBeNull(); requestedPeriod!.Start.Should().Be(new DateTime(2026, 3, 9)); diff --git a/Wino.Core.Tests/CalendarRangeResolverTests.cs b/Wino.Core.Tests/CalendarRangeResolverTests.cs index ada2b715..20b8e3fe 100644 --- a/Wino.Core.Tests/CalendarRangeResolverTests.cs +++ b/Wino.Core.Tests/CalendarRangeResolverTests.cs @@ -115,7 +115,7 @@ public class CalendarRangeResolverTests } [Fact] - public void Formatter_Day_UsesSingleDate() + public void Formatter_Day_UsesMonthDayPattern() { var formatter = new CalendarRangeTextFormatter(); var range = new VisibleDateRange( @@ -131,11 +131,11 @@ public class CalendarRangeResolverTests var text = formatter.Format(range, new TestDateContextProvider("en-US", today: new DateOnly(2026, 3, 20))); - text.Should().Be("3/20/2026"); + text.Should().Be("March 20"); } [Fact] - public void Formatter_Range_UsesCultureShortDatePattern() + public void Formatter_Range_UsesCultureMonthDayPattern() { var formatter = new CalendarRangeTextFormatter(); var range = new VisibleDateRange( @@ -159,7 +159,7 @@ public class CalendarRangeResolverTests var text = formatter.Format(range, new TestDateContextProvider("de-DE", today: new DateOnly(2026, 3, 20))); - text.Should().Be("16.03.2026 - 22.03.2026"); + text.Should().Be("16. März - 22. März"); } private static CalendarSettings CreateSettings( diff --git a/Wino.Core.Tests/CalendarRangeTextFormatterTests.cs b/Wino.Core.Tests/CalendarRangeTextFormatterTests.cs new file mode 100644 index 00000000..d98b9427 --- /dev/null +++ b/Wino.Core.Tests/CalendarRangeTextFormatterTests.cs @@ -0,0 +1,103 @@ +using System.Linq; +using FluentAssertions; +using Wino.Core.Domain.Enums; +using Wino.Core.Domain.Models.Calendar; +using Xunit; + +namespace Wino.Core.Tests; + +public class CalendarRangeTextFormatterTests +{ + private static readonly CalendarRangeTextFormatter Formatter = new(); + private static readonly TestDateContextProvider DateContextProvider = new("en-US", new DateOnly(2026, 3, 24)); + + [Fact] + public void Format_ReturnsMonthDay_ForSingleDate() + { + var range = CreateRange( + CalendarDisplayType.Day, + anchorDate: new DateOnly(2026, 3, 6), + startDate: new DateOnly(2026, 3, 6), + endDate: new DateOnly(2026, 3, 6)); + + Formatter.Format(range, DateContextProvider).Should().Be("March 6"); + } + + [Fact] + public void Format_ReturnsFullRange_ForDatesInSameMonth() + { + var range = CreateRange( + CalendarDisplayType.Week, + anchorDate: new DateOnly(2026, 3, 6), + startDate: new DateOnly(2026, 3, 3), + endDate: new DateOnly(2026, 3, 10)); + + Formatter.Format(range, DateContextProvider).Should().Be("March 3 - March 10"); + } + + [Fact] + public void Format_ReturnsFullRange_ForDatesInDifferentMonths() + { + var range = CreateRange( + CalendarDisplayType.Week, + anchorDate: new DateOnly(2026, 4, 2), + startDate: new DateOnly(2026, 3, 30), + endDate: new DateOnly(2026, 4, 7)); + + Formatter.Format(range, DateContextProvider).Should().Be("March 30 - April 7"); + } + + [Fact] + public void Format_ReturnsAnchorMonth_WhenVisibleRangeSpansMonthGrid() + { + var range = CreateRange( + CalendarDisplayType.Month, + anchorDate: new DateOnly(2026, 3, 12), + startDate: new DateOnly(2026, 2, 23), + endDate: new DateOnly(2026, 4, 5)); + + Formatter.Format(range, DateContextProvider).Should().Be("March 2026"); + } + + [Fact] + public void Format_ReturnsAnchorMonth_WhenVisibleRangeHasExactlyTwentyEightDays() + { + var range = CreateRange( + CalendarDisplayType.Month, + anchorDate: new DateOnly(2026, 2, 14), + startDate: new DateOnly(2026, 2, 1), + endDate: new DateOnly(2026, 2, 28)); + + Formatter.Format(range, DateContextProvider).Should().Be("February 2026"); + } + + private static VisibleDateRange CreateRange( + CalendarDisplayType displayType, + DateOnly anchorDate, + DateOnly startDate, + DateOnly endDate) + { + var dayCount = endDate.DayNumber - startDate.DayNumber + 1; + var dates = Enumerable.Range(0, dayCount) + .Select(offset => startDate.AddDays(offset)) + .ToArray(); + + return new VisibleDateRange( + displayType, + anchorDate, + startDate, + endDate, + anchorDate, + dayCount, + ContainsToday: false, + SpansSingleMonth: startDate.Month == endDate.Month && startDate.Year == endDate.Year, + Dates: dates); + } + + private sealed class TestDateContextProvider(string cultureName, DateOnly today) : IDateContextProvider + { + public System.Globalization.CultureInfo Culture => System.Globalization.CultureInfo.GetCultureInfo(cultureName); + public TimeZoneInfo TimeZone => TimeZoneInfo.Utc; + public DateOnly GetToday() => today; + } +} diff --git a/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml b/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml new file mode 100644 index 00000000..589de558 --- /dev/null +++ b/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml.cs b/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml.cs new file mode 100644 index 00000000..df356b84 --- /dev/null +++ b/Wino.Mail.WinUI/Controls/CalendarTitleBarContent.xaml.cs @@ -0,0 +1,55 @@ +using System; +using System.Windows.Input; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Wino.Calendar.Controls; +using Wino.Core.Domain.Enums; + +namespace Wino.Mail.WinUI.Controls; + +public sealed partial class CalendarTitleBarContent : UserControl +{ + public event EventHandler? PreviousDateRequested; + public event EventHandler? NextDateRequested; + + public CalendarTitleBarContent() + { + InitializeComponent(); + } + + public string VisibleDateRangeText + { + get => VisibleDateRangeTextBlock.Text; + set => VisibleDateRangeTextBlock.Text = value; + } + + public ICommand? TodayClickedCommand + { + get => CalendarTypeSelector.TodayClickedCommand; + set => CalendarTypeSelector.TodayClickedCommand = value; + } + + public int DisplayDayCount + { + get => CalendarTypeSelector.DisplayDayCount; + set => CalendarTypeSelector.DisplayDayCount = value; + } + + public CalendarDisplayType SelectedType + { + get => CalendarTypeSelector.SelectedType; + set => CalendarTypeSelector.SelectedType = value; + } + + public long RegisterSelectedTypeChanged(DependencyPropertyChangedCallback callback) + => CalendarTypeSelector.RegisterPropertyChangedCallback(WinoCalendarTypeSelectorControl.SelectedTypeProperty, callback); + + public void UnregisterSelectedTypeChanged(long token) + => CalendarTypeSelector.UnregisterPropertyChangedCallback(WinoCalendarTypeSelectorControl.SelectedTypeProperty, token); + + private void PreviousDateClicked(object sender, RoutedEventArgs e) + => PreviousDateRequested?.Invoke(this, EventArgs.Empty); + + private void NextDateClicked(object sender, RoutedEventArgs e) + => NextDateRequested?.Invoke(this, EventArgs.Empty); +} diff --git a/Wino.Mail.WinUI/ShellWindow.xaml b/Wino.Mail.WinUI/ShellWindow.xaml index 4690cce7..0c4945f0 100644 --- a/Wino.Mail.WinUI/ShellWindow.xaml +++ b/Wino.Mail.WinUI/ShellWindow.xaml @@ -92,14 +92,10 @@ BorderBrush="Transparent" Visibility="{x:Bind helpers:XamlHelpers.ReverseBoolToVisibilityConverter(PreferencesService.IsWinoAccountButtonHidden), Mode=OneWay}"> - + - + SyncActionItems { get; } = new(); private bool _calendarReminderServerStartAttempted; + private ICalendarShellClient? _activeCalendarClient; + private readonly CalendarTitleBarContent _calendarTitleBarContent = new(); + private long _calendarTypeSelectorChangedToken; public ShellWindow() { @@ -51,6 +56,9 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, MinWidth = 420; MinHeight = 420; ConfigureTitleBar(); + _calendarTypeSelectorChangedToken = _calendarTitleBarContent.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged); + _calendarTitleBarContent.PreviousDateRequested += CalendarTitleBarContentPreviousDateRequested; + _calendarTitleBarContent.NextDateRequested += CalendarTitleBarContentNextDateRequested; // Handle window closing event to minimize to tray instead of closing Closed += OnWindowClosed; @@ -130,8 +138,7 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, _ = StartCalendarReminderServerAsync(); } - if (e.Content is BasePage basePage) - ShellTitleBar.Content = basePage.ShellContent; + ApplyTitleBarContent(); } private async Task StartCalendarReminderServerAsync() @@ -158,10 +165,7 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, public void Receive(TitleBarShellContentUpdated message) { - if (MainShellFrame.Content is WinoAppShell shellPage) - { - ShellTitleBar.Content = shellPage.ShellContent; - } + ApplyTitleBarContent(); } public void Receive(ApplicationThemeChanged message) @@ -257,6 +261,121 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, }); } + private void CalendarTypeSelectorSelectedTypeChanged(DependencyObject sender, DependencyProperty dp) + { + if (_activeCalendarClient == null) + return; + + var selectedType = _calendarTitleBarContent.SelectedType; + if (_activeCalendarClient.StatePersistenceService.CalendarDisplayType != selectedType) + { + _activeCalendarClient.StatePersistenceService.CalendarDisplayType = selectedType; + } + } + + private void ApplyTitleBarContent() + { + if (MainShellFrame.Content is not WinoAppShell shellPage) + { + AttachCalendarClient(null); + ShellTitleBar.Content = MainShellFrame.Content is BasePage basePage ? basePage.ShellContent : null; + return; + } + + AttachCalendarClient(shellPage.ViewModel.CalendarClient); + + if (shellPage.ViewModel.IsCalendarMode && !shellPage.ViewModel.StatePersistenceService.IsEventDetailsVisible) + { + RefreshCalendarSelector(); + ShellTitleBar.Content = _calendarTitleBarContent; + return; + } + + ShellTitleBar.Content = shellPage.GetShellFrame().Content is BasePage page ? page.ShellContent : null; + } + + private void AttachCalendarClient(ICalendarShellClient? calendarClient) + { + if (ReferenceEquals(_activeCalendarClient, calendarClient)) + return; + + if (_activeCalendarClient != null) + { + _activeCalendarClient.PropertyChanged -= CalendarClientPropertyChanged; + _activeCalendarClient.StatePersistenceService.StatePropertyChanged -= CalendarStatePersistenceServiceChanged; + } + + _activeCalendarClient = calendarClient; + + if (_activeCalendarClient != null) + { + _activeCalendarClient.PropertyChanged += CalendarClientPropertyChanged; + _activeCalendarClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged; + } + } + + private void CalendarClientPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (!DispatcherQueue.HasThreadAccess) + { + var enqueued = DispatcherQueue.TryEnqueue(() => CalendarClientPropertyChanged(sender, e)); + if (!enqueued) + throw new InvalidOperationException("Could not marshal calendar client changes onto the UI thread."); + + return; + } + + if (e.PropertyName == nameof(ICalendarShellClient.VisibleDateRangeText)) + { + RefreshCalendarSelector(); + } + } + + private void CalendarStatePersistenceServiceChanged(object? sender, string propertyName) + { + if (!DispatcherQueue.HasThreadAccess) + { + var enqueued = DispatcherQueue.TryEnqueue(() => CalendarStatePersistenceServiceChanged(sender, propertyName)); + if (!enqueued) + throw new InvalidOperationException("Could not marshal title bar state changes onto the UI thread."); + + return; + } + + if (propertyName == nameof(IStatePersistanceService.CalendarDisplayType) || + propertyName == nameof(IStatePersistanceService.DayDisplayCount)) + { + RefreshCalendarSelector(); + return; + } + + if (propertyName == nameof(IStatePersistanceService.IsEventDetailsVisible)) + { + ApplyTitleBarContent(); + } + } + + private void RefreshCalendarSelector() + { + if (_activeCalendarClient == null) + return; + + _calendarTitleBarContent.VisibleDateRangeText = _activeCalendarClient.VisibleDateRangeText; + _calendarTitleBarContent.TodayClickedCommand = _activeCalendarClient.TodayClickedCommand; + _calendarTitleBarContent.DisplayDayCount = _activeCalendarClient.StatePersistenceService.DayDisplayCount; + + if (_calendarTitleBarContent.SelectedType != _activeCalendarClient.StatePersistenceService.CalendarDisplayType) + { + _calendarTitleBarContent.SelectedType = _activeCalendarClient.StatePersistenceService.CalendarDisplayType; + } + } + + private void CalendarTitleBarContentPreviousDateRequested(object? sender, EventArgs e) + => _activeCalendarClient?.PreviousDateRangeCommand.Execute(null); + + private void CalendarTitleBarContentNextDateRequested(object? sender, EventArgs e) + => _activeCalendarClient?.NextDateRangeCommand.Execute(null); + private void OnAppWindowClosing(object sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs e) { if ((Application.Current as App)?.IsExiting == true) @@ -270,6 +389,10 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, private void OnWindowClosed(object sender, WindowEventArgs e) { AppWindow.Closing -= OnAppWindowClosing; + AttachCalendarClient(null); + _calendarTitleBarContent.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken); + _calendarTitleBarContent.PreviousDateRequested -= CalendarTitleBarContentPreviousDateRequested; + _calendarTitleBarContent.NextDateRequested -= CalendarTitleBarContentNextDateRequested; UnregisterRecipients(); } diff --git a/Wino.Mail.WinUI/Views/WinoAppShell.xaml b/Wino.Mail.WinUI/Views/WinoAppShell.xaml index 73a7fe79..4cef468b 100644 --- a/Wino.Mail.WinUI/Views/WinoAppShell.xaml +++ b/Wino.Mail.WinUI/Views/WinoAppShell.xaml @@ -4,7 +4,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract" xmlns:animations="using:CommunityToolkit.WinUI.Animations" - xmlns:calendarControls="using:Wino.Calendar.Controls" xmlns:communityControls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:Wino.Controls" xmlns:controls1="using:CommunityToolkit.WinUI.Controls" @@ -409,98 +408,11 @@ SeperatorTemplate="{StaticResource SeperatorTemplate}" SettingsShellPageItemTemplate="{StaticResource SettingsShellPageItemTemplate}" SettingsShellSectionItemTemplate="{StaticResource SettingsShellSectionItemTemplate}" - WinoAccountSettingsShellPageItemTemplate="{StaticResource SettingsShellWinoAccountItemTemplate}" - StoreUpdateItemTemplate="{StaticResource StoreUpdateItemTemplate}" /> + StoreUpdateItemTemplate="{StaticResource StoreUpdateItemTemplate}" + WinoAccountSettingsShellPageItemTemplate="{StaticResource SettingsShellWinoAccountItemTemplate}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs b/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs index 921854d3..4366adb0 100644 --- a/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs +++ b/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs @@ -13,7 +13,6 @@ using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Navigation; using Windows.Foundation; using Windows.System; -using Wino.Calendar.Controls; using Wino.Core.Domain; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; @@ -45,8 +44,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, IRecipient, IRecipient { - private const string StateHorizontalCalendar = "HorizontalCalendar"; - private const string StateVerticalCalendar = "VerticalCalendar"; private const string StateDefaultShellContent = "DefaultShellContentState"; private const string StateEventDetailsContent = "EventDetailsContentState"; private WinoApplicationMode? _activeMode; @@ -68,12 +65,9 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, ViewModel.PropertyChanged += ViewModelPropertyChanged; ViewModel.PreferencesService.PreferenceChanged += PreferencesServiceChanged; ViewModel.StatePersistenceService.StatePropertyChanged += StatePersistenceServiceChanged; - CalendarTypeSelector.RegisterPropertyChangedCallback(WinoCalendarTypeSelectorControl.SelectedTypeProperty, CalendarTypeSelectorSelectedTypeChanged); InitializeCalendarControls(); - ManageCalendarDisplayType(ViewModel.CalendarClient.StatePersistenceService.CalendarDisplayType); UpdateEventDetailsVisualState(); - ApplyTitleBarContent(); } public bool HasShellContent => InnerShellFrame.Content != null; @@ -98,8 +92,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, ViewModel.CurrentClient.Activate(activationContext); ResetShellModeNavigationState(); - - ApplyTitleBarContent(); + NotifyTitleBarContentChanged(); } protected override void OnNavigatedFrom(NavigationEventArgs e) @@ -126,17 +119,11 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, private void ApplyModeLayout() { - var isCalendarMode = ViewModel.IsCalendarMode; - - CalendarShellContentRoot.Visibility = isCalendarMode ? Visibility.Visible : Visibility.Collapsed; - DynamicPageShellContentPresenter.Visibility = isCalendarMode ? Visibility.Collapsed : Visibility.Visible; - RefreshCalendarControls(); - ManageCalendarDisplayType(ViewModel.CalendarClient.StatePersistenceService.CalendarDisplayType); UpdateEventDetailsVisualState(); UpdateTitleBarSubtitle(); UpdateNavigationPaneLayout(navigationView.DisplayMode); - ApplyTitleBarContent(); + NotifyTitleBarContentChanged(); } private void DeactivateCurrentMode() @@ -166,8 +153,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, ViewModel.CurrentClient.Deactivate(); } - - DynamicPageShellContentPresenter.Content = null; } private void ResetShellModeNavigationState() @@ -177,20 +162,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, InnerShellFrame.ForwardStack.Clear(); } - private void ApplyTitleBarContent() - { - if (ViewModel.IsCalendarMode) - { - CalendarShellContentRoot.Visibility = Visibility.Visible; - DynamicPageShellContentPresenter.Visibility = Visibility.Collapsed; - return; - } - - CalendarShellContentRoot.Visibility = Visibility.Collapsed; - DynamicPageShellContentPresenter.Visibility = Visibility.Visible; - DynamicPageShellContentPresenter.Content = InnerShellFrame.Content is BasePage page ? page.ShellContent : null; - } - private void UpdateTitleBarSubtitle() { if (ViewModel.IsContactsMode) @@ -208,24 +179,8 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, ViewModel.StatePersistenceService.CoreWindowTitle = string.Empty; } - private void ManageCalendarDisplayType(Core.Domain.Enums.CalendarDisplayType displayType) - { - DayHeaderNavigationItemsFlipView.DisplayType = displayType; - - if (CalendarTypeSelector.SelectedType != displayType) - { - CalendarTypeSelector.SelectedType = displayType; - } - - VisualStateManager.GoToState(this, displayType == Core.Domain.Enums.CalendarDisplayType.Month - ? StateVerticalCalendar - : StateHorizontalCalendar, false); - } - private void InitializeCalendarControls() { - CalendarTypeSelector.TodayClickedCommand = ViewModel.CalendarClient.TodayClickedCommand; - DayHeaderNavigationItemsFlipView.ItemsSource = ViewModel.CalendarClient.DateNavigationHeaderItems; CalendarHostListView.ItemsSource = ViewModel.CalendarClient.GroupedAccountCalendars; RefreshCalendarControls(); @@ -233,9 +188,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, private void RefreshCalendarControls() { - DayHeaderNavigationItemsFlipView.ItemsSource = ViewModel.CalendarClient.DateNavigationHeaderItems; - DayHeaderNavigationItemsFlipView.SelectedIndex = ViewModel.CalendarClient.SelectedDateNavigationHeaderIndex; - CalendarTypeSelector.DisplayDayCount = ViewModel.CalendarClient.StatePersistenceService.DayDisplayCount; CalendarHostListView.ItemsSource = ViewModel.CalendarClient.GroupedAccountCalendars; SynchronizeVisibleDateRangeCalendar(); } @@ -255,16 +207,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, false); } - private void CalendarTypeSelectorSelectedTypeChanged(DependencyObject sender, DependencyProperty dp) - { - var selectedType = CalendarTypeSelector.SelectedType; - - if (ViewModel.CalendarClient.StatePersistenceService.CalendarDisplayType != selectedType) - { - ViewModel.CalendarClient.StatePersistenceService.CalendarDisplayType = selectedType; - } - } - private async void NewCalendarEventNavigationItemTapped(object sender, TappedRoutedEventArgs e) { e.Handled = true; @@ -280,16 +222,10 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, await InvokeNewCalendarEventAsync(); } - private void PreviousDateClicked(object sender, RoutedEventArgs e) - => ViewModel.CalendarClient.PreviousDateRangeCommand.Execute(null); - - private void NextDateClicked(object sender, RoutedEventArgs e) - => ViewModel.CalendarClient.NextDateRangeCommand.Execute(null); - private Task InvokeNewCalendarEventAsync() => ViewModel.CalendarClient.HandleNavigationItemInvokedAsync(new NewCalendarEventMenuItem()); - public void Receive(CalendarDisplayTypeChangedMessage message) => ManageCalendarDisplayType(message.NewDisplayType); + public void Receive(CalendarDisplayTypeChangedMessage message) => NotifyTitleBarContentChanged(); public void Receive(AccountCreatedMessage message) { @@ -404,7 +340,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, private void ShellFrameContentNavigated(object sender, NavigationEventArgs e) { - ApplyTitleBarContent(); + NotifyTitleBarContentChanged(); if (ViewModel.IsMailMode) { @@ -499,18 +435,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, return; } - if (e.PropertyName == nameof(ICalendarShellClient.DateNavigationHeaderItems)) - { - DayHeaderNavigationItemsFlipView.ItemsSource = ViewModel.CalendarClient.DateNavigationHeaderItems; - return; - } - - if (e.PropertyName == nameof(ICalendarShellClient.SelectedDateNavigationHeaderIndex)) - { - DayHeaderNavigationItemsFlipView.SelectedIndex = ViewModel.CalendarClient.SelectedDateNavigationHeaderIndex; - return; - } - if (e.PropertyName == nameof(ICalendarShellClient.CurrentVisibleRange) || e.PropertyName == nameof(ICalendarShellClient.VisibleDateRangeText)) { @@ -631,22 +555,26 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract, { if (propertyName == nameof(IStatePersistanceService.CalendarDisplayType)) { - ManageCalendarDisplayType(ViewModel.CalendarClient.StatePersistenceService.CalendarDisplayType); + NotifyTitleBarContentChanged(); return; } if (propertyName == nameof(IStatePersistanceService.DayDisplayCount)) { - CalendarTypeSelector.DisplayDayCount = ViewModel.CalendarClient.StatePersistenceService.DayDisplayCount; + NotifyTitleBarContentChanged(); return; } if (propertyName == nameof(IStatePersistanceService.IsEventDetailsVisible)) { UpdateEventDetailsVisualState(); + NotifyTitleBarContentChanged(); } } + private static void NotifyTitleBarContentChanged() + => WeakReferenceMessenger.Default.Send(new TitleBarShellContentUpdated()); + private void UpdateNavigationPaneLayout(NavigationViewDisplayMode displayMode) { if (displayMode == NavigationViewDisplayMode.Expanded && navigationView.IsPaneOpen)