diff --git a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs index 261b06d1..d75a1f31 100644 --- a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs +++ b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs @@ -44,12 +44,12 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, #region Quick Event Creation [ObservableProperty] - private bool _isQuickEventDialogOpen; + public partial bool IsQuickEventDialogOpen { get; set; } [ObservableProperty] [NotifyPropertyChangedFor(nameof(SelectedQuickEventAccountCalendarName))] [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] - private AccountCalendarViewModel _selectedQuickEventAccountCalendar; + public partial AccountCalendarViewModel SelectedQuickEventAccountCalendar { get; set; } public string SelectedQuickEventAccountCalendarName { @@ -60,41 +60,62 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, } [ObservableProperty] - private List _hourSelectionStrings; + public partial List HourSelectionStrings { get; set; } // To be able to revert the values when the user enters an invalid time. private string _previousSelectedStartTimeString; private string _previousSelectedEndTimeString; [ObservableProperty] - private DateTime? _selectedQuickEventDate; - - [ObservableProperty] - private bool _isAllDay; + [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] + public partial DateTime? SelectedQuickEventDate { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] - private string _selectedStartTimeString; + public partial bool IsAllDay { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] - private string _selectedEndTimeString; - - [ObservableProperty] - private string _location; + public partial string SelectedStartTimeString { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] - private string _eventName; + public partial string SelectedEndTimeString { get; set; } + + [ObservableProperty] + public partial string Location { get; set; } + + [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SaveQuickEventCommand))] + public partial string EventName { get; set; } public DateTime QuickEventStartTime => SelectedQuickEventDate.Value.Date.Add(CurrentSettings.GetTimeSpan(SelectedStartTimeString).Value); public DateTime QuickEventEndTime => SelectedQuickEventDate.Value.Date.Add(CurrentSettings.GetTimeSpan(SelectedEndTimeString).Value); - public bool CanSaveQuickEvent => SelectedQuickEventAccountCalendar != null && - !string.IsNullOrWhiteSpace(EventName) && - !string.IsNullOrWhiteSpace(SelectedStartTimeString) && - !string.IsNullOrWhiteSpace(SelectedEndTimeString) && - QuickEventEndTime > QuickEventStartTime; + public bool CanSaveQuickEvent + { + get + { + if (SelectedQuickEventAccountCalendar == null || + SelectedQuickEventDate == null || + string.IsNullOrWhiteSpace(EventName) || + string.IsNullOrWhiteSpace(SelectedStartTimeString) || + string.IsNullOrWhiteSpace(SelectedEndTimeString)) + { + return false; + } + + var startTime = CurrentSettings.GetTimeSpan(SelectedStartTimeString); + var endTime = CurrentSettings.GetTimeSpan(SelectedEndTimeString); + + if (!startTime.HasValue || !endTime.HasValue) + { + return false; + } + + return IsAllDay || endTime > startTime; + } + } #endregion @@ -152,7 +173,7 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, private long _pageLifetimeVersion; [ObservableProperty] - private CalendarSettings _currentSettings; + public partial CalendarSettings CurrentSettings { get; set; } public IStatePersistanceService StatePersistanceService { get; } public IAccountCalendarStateService AccountCalendarStateService { get; } @@ -1129,6 +1150,8 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, { if (value) { + _previousSelectedStartTimeString = SelectedStartTimeString; + _previousSelectedEndTimeString = SelectedEndTimeString; SelectedStartTimeString = HourSelectionStrings.FirstOrDefault(); SelectedEndTimeString = HourSelectionStrings.FirstOrDefault(); } @@ -1147,7 +1170,7 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, { SelectedStartTimeString = _previousSelectedStartTimeString; } - else if (IsAllDay) + else if (!IsAllDay) { _previousSelectedStartTimeString = newValue; } @@ -1159,9 +1182,9 @@ public partial class CalendarPageViewModel : CalendarBaseViewModel, if (parsedTime == null) { - SelectedEndTimeString = _previousSelectedStartTimeString; + SelectedEndTimeString = _previousSelectedEndTimeString; } - else if (IsAllDay) + else if (!IsAllDay) { _previousSelectedEndTimeString = newValue; } diff --git a/Wino.Mail.WinUI/Services/NavigationService.cs b/Wino.Mail.WinUI/Services/NavigationService.cs index 7995e4ec..2f533165 100644 --- a/Wino.Mail.WinUI/Services/NavigationService.cs +++ b/Wino.Mail.WinUI/Services/NavigationService.cs @@ -303,6 +303,8 @@ public class NavigationService : NavigationServiceBase, INavigationService if (innerShellFrame != null) { + PruneInnerShellBackStackForMode(innerShellFrame, currentApplicationMode); + // Calendar navigations. if (currentApplicationMode == WinoApplicationMode.Calendar) { @@ -514,29 +516,42 @@ public class NavigationService : NavigationServiceBase, INavigationService private void GoBackInternal(Core.Domain.Enums.NavigationTransitionEffect slideEffect = Core.Domain.Enums.NavigationTransitionEffect.FromRight) { var innerShellFrame = GetCoreFrameInternal(NavigationReferenceFrame.InnerShellFrame); + var currentApplicationMode = _statePersistanceService.ApplicationMode; - if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Settings && + if (currentApplicationMode == WinoApplicationMode.Settings && _statePersistanceService.HasCurrentModeBackStack) { WeakReferenceMessenger.Default.Send(new BackBreadcrumNavigationRequested(slideEffect)); return; } - if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Settings && + if (currentApplicationMode == WinoApplicationMode.Settings && innerShellFrame?.Content is SettingsPage) { return; } - if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Calendar && innerShellFrame?.CanGoBack == true) + if (innerShellFrame != null) { - innerShellFrame.GoBack(); - UpdateCurrentModeBackStackState(innerShellFrame); + PruneInnerShellBackStackForMode(innerShellFrame, currentApplicationMode); + } + + if (currentApplicationMode == WinoApplicationMode.Calendar) + { + if (innerShellFrame?.CanGoBack == true) + { + innerShellFrame.GoBack(); + UpdateCurrentModeBackStackState(innerShellFrame); + } + else if (innerShellFrame != null && innerShellFrame.Content?.GetType() != typeof(CalendarPage)) + { + NavigateToCalendarRoot(innerShellFrame); + } // Calendar mode: Navigate back from EventDetailsPage _statePersistanceService.IsEventDetailsVisible = false; } - else if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Mail) + else if (currentApplicationMode == WinoApplicationMode.Mail) { if (_statePersistanceService.IsReadingMail && _statePersistanceService.IsReaderNarrowed) { @@ -576,6 +591,51 @@ public class NavigationService : NavigationServiceBase, INavigationService innerShellFrame?.CanGoBack == true; } + private void PruneInnerShellBackStackForMode(Frame frame, WinoApplicationMode mode) + { + for (int i = frame.BackStack.Count - 1; i >= 0; i--) + { + var backStackEntry = frame.BackStack[i]; + + if (!IsPageTypeAllowedInMode(mode, backStackEntry.SourcePageType)) + { + frame.BackStack.RemoveAt(i); + } + } + } + + private bool IsPageTypeAllowedInMode(WinoApplicationMode mode, Type? pageType) + { + if (pageType == null) + return false; + + foreach (var page in Enum.GetValues()) + { + if (page == WinoPage.None) + continue; + + if (GetPageType(page) == pageType) + return IsPageAllowedInMode(mode, page); + } + + return false; + } + + private void NavigateToCalendarRoot(Frame frame) + { + if (!frame.Navigate(typeof(CalendarPage), new CalendarPageNavigationArgs + { + RequestDefaultNavigation = true + }, GetNavigationTransitionInfo(NavigationTransitionType.None))) + { + return; + } + + frame.BackStack.Clear(); + frame.ForwardStack.Clear(); + UpdateCurrentModeBackStackState(frame); + } + // Standalone EML viewer. //public void NavigateRendering(MimeMessageInformation mimeMessageInformation, NavigationTransitionType transition = NavigationTransitionType.None) //{