diff --git a/Wino.Calendar.ViewModels/CalendarAccountSettingsPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarAccountSettingsPageViewModel.cs
new file mode 100644
index 00000000..53ebbbba
--- /dev/null
+++ b/Wino.Calendar.ViewModels/CalendarAccountSettingsPageViewModel.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Messaging;
+using Wino.Core.Domain;
+using Wino.Core.Domain.Entities.Calendar;
+using Wino.Core.Domain.Entities.Shared;
+using Wino.Core.Domain.Enums;
+using Wino.Core.Domain.Interfaces;
+using Wino.Core.Domain.Models.Navigation;
+using Wino.Core.ViewModels;
+using Wino.Messaging.Client.Calendar;
+
+namespace Wino.Calendar.ViewModels;
+
+///
+/// ViewModel for managing calendar account settings.
+///
+public partial class CalendarAccountSettingsPageViewModel : CalendarBaseViewModel
+{
+ private readonly ICalendarService _calendarService;
+ private readonly IAccountService _accountService;
+
+ [ObservableProperty]
+ public partial MailAccount Account { get; set; }
+
+ [ObservableProperty]
+ public partial AccountCalendar AccountCalendar { get; set; }
+
+ [ObservableProperty]
+ public partial string AccountColorHex { get; set; } = "#0078D4";
+
+ [ObservableProperty]
+ public partial bool IsSyncEnabled { get; set; }
+
+ [ObservableProperty]
+ public partial bool IsPrimaryCalendar { get; set; }
+
+ public ObservableCollection ShowAsOptions { get; } = new ObservableCollection();
+
+ [ObservableProperty]
+ public partial ShowAsOption SelectedDefaultShowAsOption { get; set; }
+
+ public CalendarAccountSettingsPageViewModel(ICalendarService calendarService, IAccountService accountService)
+ {
+ _calendarService = calendarService;
+ _accountService = accountService;
+
+ // Initialize ShowAs options
+ ShowAsOptions.Add(new ShowAsOption(CalendarItemShowAs.Free));
+ ShowAsOptions.Add(new ShowAsOption(CalendarItemShowAs.Tentative));
+ ShowAsOptions.Add(new ShowAsOption(CalendarItemShowAs.Busy));
+ ShowAsOptions.Add(new ShowAsOption(CalendarItemShowAs.OutOfOffice));
+ ShowAsOptions.Add(new ShowAsOption(CalendarItemShowAs.WorkingElsewhere));
+ }
+
+ public override async void OnNavigatedTo(NavigationMode mode, object parameters)
+ {
+ base.OnNavigatedTo(mode, parameters);
+
+ if (parameters is not Guid accountId)
+ return;
+
+ // Load account
+ Account = await _accountService.GetAccountAsync(accountId);
+
+ if (Account == null)
+ return;
+
+ // Load first primary calendar for this account
+ var calendars = await _calendarService.GetAccountCalendarsAsync(accountId);
+ AccountCalendar = calendars.FirstOrDefault(c => c.IsPrimary) ?? calendars.FirstOrDefault();
+
+ if (AccountCalendar == null)
+ return;
+
+ // Initialize properties from AccountCalendar
+ AccountColorHex = AccountCalendar.BackgroundColorHex ?? "#0078D4";
+ IsSyncEnabled = AccountCalendar.IsExtended;
+ IsPrimaryCalendar = AccountCalendar.IsPrimary;
+
+ // TODO: Default ShowAs is not stored in AccountCalendar yet, defaulting to Busy
+ SelectedDefaultShowAsOption = ShowAsOptions[2]; // Busy
+ }
+
+ partial void OnAccountColorHexChanged(string value)
+ {
+ if (AccountCalendar != null && !string.IsNullOrEmpty(value))
+ {
+ AccountCalendar.BackgroundColorHex = value;
+ SaveChangesAsync();
+ }
+ }
+
+ partial void OnIsSyncEnabledChanged(bool value)
+ {
+ if (AccountCalendar != null)
+ {
+ AccountCalendar.IsExtended = value;
+ SaveChangesAsync();
+ }
+ }
+
+ partial void OnIsPrimaryCalendarChanged(bool value)
+ {
+ if (AccountCalendar != null)
+ {
+ AccountCalendar.IsPrimary = value;
+ SaveChangesAsync();
+ }
+ }
+
+ partial void OnSelectedDefaultShowAsOptionChanged(ShowAsOption value)
+ {
+ // TODO: Default ShowAs should be stored in AccountCalendar or account preferences
+ // For now, this is just a placeholder as the property doesn't exist yet
+ if (value != null)
+ {
+ // Future: Store value.ShowAs somewhere
+ }
+ }
+
+ private async void SaveChangesAsync()
+ {
+ if (AccountCalendar == null)
+ return;
+
+ await _calendarService.UpdateAccountCalendarAsync(AccountCalendar);
+
+ // Send message to update UI
+ Messenger.Send(new CalendarListUpdated(AccountCalendar));
+ }
+}
diff --git a/Wino.Calendar.ViewModels/CalendarSettingsPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarSettingsPageViewModel.cs
index 887249a7..801b67ed 100644
--- a/Wino.Calendar.ViewModels/CalendarSettingsPageViewModel.cs
+++ b/Wino.Calendar.ViewModels/CalendarSettingsPageViewModel.cs
@@ -1,13 +1,20 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
+using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
+using Wino.Core.Domain;
+using Wino.Core.Domain.Entities.Shared;
+using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Translations;
using Wino.Core.ViewModels;
using Wino.Messaging.Client.Calendar;
+using Wino.Messaging.Client.Navigation;
namespace Wino.Calendar.ViewModels;
@@ -45,13 +52,17 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
public IPreferencesService PreferencesService { get; }
private readonly ICalendarService _calendarService;
+ private readonly IAccountService _accountService;
+
+ public ObservableCollection Accounts { get; } = new ObservableCollection();
private readonly bool _isLoaded = false;
- public CalendarSettingsPageViewModel(IPreferencesService preferencesService, ICalendarService calendarService)
+ public CalendarSettingsPageViewModel(IPreferencesService preferencesService, ICalendarService calendarService, IAccountService accountService)
{
PreferencesService = preferencesService;
_calendarService = calendarService;
+ _accountService = accountService;
var currentLanguageLanguageCode = WinoTranslationDictionary.GetLanguageFileNameRelativePath(preferencesService.CurrentLanguage);
@@ -98,6 +109,34 @@ public partial class CalendarSettingsPageViewModel : CalendarBaseViewModel
}
_isLoaded = true;
+
+ // Load accounts with calendar support
+ LoadAccountsAsync();
+ }
+
+ private async void LoadAccountsAsync()
+ {
+ var accounts = await _accountService.GetAccountsAsync();
+
+ await Dispatcher.ExecuteOnUIThread(() =>
+ {
+ Accounts.Clear();
+ foreach (var account in accounts)
+ {
+ Accounts.Add(account);
+ }
+ });
+ }
+
+ [RelayCommand]
+ private void NavigateToAccountSettings(MailAccount account)
+ {
+ if (account == null) return;
+
+ Messenger.Send(new BreadcrumbNavigationRequested(
+ string.Format(Translator.CalendarAccountSettings_Description, account.Name),
+ WinoPage.CalendarAccountSettingsPage,
+ account.Id));
}
partial void OnCellHourHeightChanged(double oldValue, double newValue) => SaveSettings();
diff --git a/Wino.Calendar/Services/NavigationService.cs b/Wino.Calendar/Services/NavigationService.cs
index f409c4b3..a6cf340b 100644
--- a/Wino.Calendar/Services/NavigationService.cs
+++ b/Wino.Calendar/Services/NavigationService.cs
@@ -30,7 +30,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
};
}
- public void GoBack()
+ public void GoBack(Core.Domain.Enums.SlideNavigationTransitionEffect slideEffect = Core.Domain.Enums.SlideNavigationTransitionEffect.FromRight)
{
if (Window.Current.Content is Frame appFrame && appFrame.Content is AppShell shellPage)
{
diff --git a/Wino.Core.Domain/Enums/NavigationTransitionEffect.cs b/Wino.Core.Domain/Enums/NavigationTransitionEffect.cs
new file mode 100644
index 00000000..73be75f6
--- /dev/null
+++ b/Wino.Core.Domain/Enums/NavigationTransitionEffect.cs
@@ -0,0 +1,27 @@
+namespace Wino.Core.Domain.Enums;
+
+///
+/// Specifies the animation effect to use during a slide navigation transition.
+///
+public enum NavigationTransitionEffect
+{
+ ///
+ /// The navigation transition effect starts from the left edge of the frame.
+ ///
+ FromLeft,
+
+ ///
+ /// The navigation transition effect starts from the right edge of the frame.
+ ///
+ FromRight,
+
+ ///
+ /// The navigation transition effect starts from the top edge of the frame.
+ ///
+ FromTop,
+
+ ///
+ /// The navigation transition effect starts from the bottom edge of the frame.
+ ///
+ FromBottom
+}
diff --git a/Wino.Core.Domain/Enums/WinoPage.cs b/Wino.Core.Domain/Enums/WinoPage.cs
index 0b563fa5..3e34cb73 100644
--- a/Wino.Core.Domain/Enums/WinoPage.cs
+++ b/Wino.Core.Domain/Enums/WinoPage.cs
@@ -30,6 +30,7 @@ public enum WinoPage
KeyboardShortcutsPage,
CalendarPage,
CalendarSettingsPage,
+ CalendarAccountSettingsPage,
EventDetailsPage,
SignatureAndEncryptionPage
}
diff --git a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
index 43dfbd10..55653d6e 100644
--- a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
+++ b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
@@ -39,6 +39,16 @@ public interface IStatePersistanceService : INotifyPropertyChanged
///
bool IsEventDetailsVisible { get; set; }
+ ///
+ /// Whether ManageAccountsPage has navigated to a sub-page and can go back.
+ ///
+ bool IsManageAccountsNavigating { get; set; }
+
+ ///
+ /// Whether SettingsPage has navigated to a sub-page and can go back.
+ ///
+ bool IsSettingsNavigating { get; set; }
+
///
/// Setting: Opened pane length for the navigation view.
///
diff --git a/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs b/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs
index 954c8bf2..3a1b2b5a 100644
--- a/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs
+++ b/Wino.Core.Domain/Interfaces/IWinoNavigationService.cs
@@ -13,5 +13,5 @@ public interface INavigationService
Type GetPageType(WinoPage winoPage);
bool ChangeApplicationMode(WinoApplicationMode mode);
- void GoBack();
+ void GoBack(NavigationTransitionEffect slideEffect = NavigationTransitionEffect.FromRight);
}
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index c2322998..613221ac 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -26,6 +26,10 @@
"AccountDetailsPage_Description": "Change the name of the account in Wino and set desired sender name.",
"AccountDetailsPage_ColorPicker_Title": "Account color",
"AccountDetailsPage_ColorPicker_Description": "Assign a new account color to colorize its symbol in the list.",
+ "AccountDetailsPage_TabGeneral": "General",
+ "AccountDetailsPage_TabMail": "Mail",
+ "AccountDetailsPage_TabCalendar": "Calendar",
+ "AccountDetailsPage_CalendarListDescription": "Select a calendar to configure its settings",
"AddHyperlink": "Add",
"AppCloseBackgroundSynchronizationWarningTitle": "Background Synchronization",
"AppCloseStartupLaunchDisabledWarningMessageFirstLine": "Application has not been set to launch on Windows startup.",
@@ -861,5 +865,15 @@
"ContactSelection_SelectAll": "Select All",
"ContactSelection_Clear": "Clear Selection",
"ContactsPage_EmptyState": "No contacts to display",
- "ContactsPage_AddFirstContact": "Add your first contact"
+ "ContactsPage_AddFirstContact": "Add your first contact",
+ "CalendarAccountSettings_Title": "Calendar Account Settings",
+ "CalendarAccountSettings_Description": "Manage calendar settings for {0}",
+ "CalendarAccountSettings_AccountColor": "Account Color",
+ "CalendarAccountSettings_AccountColorDescription": "Change the display color for this calendar account",
+ "CalendarAccountSettings_SyncEnabled": "Enable Synchronization",
+ "CalendarAccountSettings_SyncEnabledDescription": "Enable or disable calendar synchronization for this account",
+ "CalendarAccountSettings_DefaultShowAs": "Default Show As Status",
+ "CalendarAccountSettings_DefaultShowAsDescription": "Default availability status for new events created with this account",
+ "CalendarAccountSettings_PrimaryCalendar": "Primary Calendar",
+ "CalendarAccountSettings_PrimaryCalendarDescription": "Mark this calendar as the primary calendar for the account"
}
diff --git a/Wino.Core.ViewModels/NewAccountManagementPageViewModel.cs b/Wino.Core.ViewModels/NewAccountManagementPageViewModel.cs
index 4c289889..74c40093 100644
--- a/Wino.Core.ViewModels/NewAccountManagementPageViewModel.cs
+++ b/Wino.Core.ViewModels/NewAccountManagementPageViewModel.cs
@@ -4,10 +4,12 @@ namespace Wino.Core.ViewModels;
public class ManageAccountsPagePageViewModel : CoreBaseViewModel
{
- public ManageAccountsPagePageViewModel(INavigationService navigationService)
+ public ManageAccountsPagePageViewModel(INavigationService navigationService, IStatePersistanceService statePersistenceService)
{
NavigationService = navigationService;
+ StatePersistenceService = statePersistenceService;
}
public INavigationService NavigationService { get; }
+ public IStatePersistanceService StatePersistenceService { get; }
}
diff --git a/Wino.Core.ViewModels/SettingsPageViewModel.cs b/Wino.Core.ViewModels/SettingsPageViewModel.cs
index 792eebe0..47c91308 100644
--- a/Wino.Core.ViewModels/SettingsPageViewModel.cs
+++ b/Wino.Core.ViewModels/SettingsPageViewModel.cs
@@ -4,10 +4,12 @@ namespace Wino.Core.ViewModels;
public class SettingsPageViewModel : CoreBaseViewModel
{
- public SettingsPageViewModel(INavigationService navigationService)
+ public SettingsPageViewModel(INavigationService navigationService, IStatePersistanceService statePersistenceService)
{
NavigationService = navigationService;
+ StatePersistenceService = statePersistenceService;
}
public INavigationService NavigationService { get; }
+ public IStatePersistanceService StatePersistenceService { get; }
}
diff --git a/Wino.Mail.ViewModels/AccountDetailsPageViewModel.cs b/Wino.Mail.ViewModels/AccountDetailsPageViewModel.cs
index 073b9204..ccbeb437 100644
--- a/Wino.Mail.ViewModels/AccountDetailsPageViewModel.cs
+++ b/Wino.Mail.ViewModels/AccountDetailsPageViewModel.cs
@@ -1,17 +1,21 @@
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain;
+using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Folders;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Services;
+using Wino.Messaging.Client.Calendar;
using Wino.Messaging.Client.Navigation;
namespace Wino.Mail.ViewModels;
@@ -21,11 +25,17 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
private readonly IMailDialogService _dialogService;
private readonly IAccountService _accountService;
private readonly IFolderService _folderService;
+ private readonly ICalendarService _calendarService;
private bool isLoaded = false;
public MailAccount Account { get; set; }
public ObservableCollection CurrentFolders { get; set; } = [];
+ public ObservableCollection AccountCalendars { get; set; } = [];
+ [ObservableProperty]
+ public partial int SelectedTabIndex { get; set; } = 1; // Default to Mail tab
+
+ // Mail-related properties
[ObservableProperty]
private bool isFocusedInboxEnabled;
@@ -49,11 +59,13 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
public AccountDetailsPageViewModel(IMailDialogService dialogService,
IAccountService accountService,
- IFolderService folderService)
+ IFolderService folderService,
+ ICalendarService calendarService)
{
_dialogService = dialogService;
_accountService = accountService;
_folderService = folderService;
+ _calendarService = calendarService;
}
[RelayCommand]
@@ -127,10 +139,33 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
CurrentFolders.Add(folder);
}
+ // Load calendar list
+ await LoadAccountCalendarsAsync();
+
isLoaded = true;
}
}
+ private async Task LoadAccountCalendarsAsync()
+ {
+ var calendars = await _calendarService.GetAccountCalendarsAsync(Account.Id);
+
+ AccountCalendars.Clear();
+ foreach (var calendar in calendars)
+ {
+ AccountCalendars.Add(calendar);
+ }
+ }
+
+ [RelayCommand]
+ private void CalendarItemClicked(AccountCalendar calendar)
+ {
+ if (calendar == null) return;
+
+ // Navigate to calendar settings page with breadcrumb
+ Messenger.Send(new BreadcrumbNavigationRequested(calendar.Name, WinoPage.CalendarAccountSettingsPage, calendar));
+ }
+
protected override async void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
diff --git a/Wino.Mail.WinUI/App.xaml.cs b/Wino.Mail.WinUI/App.xaml.cs
index 9561db1a..c57b2679 100644
--- a/Wino.Mail.WinUI/App.xaml.cs
+++ b/Wino.Mail.WinUI/App.xaml.cs
@@ -95,6 +95,7 @@ public partial class App : WinoApplication,
services.AddTransient(typeof(CalendarPageViewModel));
services.AddTransient(typeof(CalendarSettingsPageViewModel));
+ services.AddTransient(typeof(CalendarAccountSettingsPageViewModel));
services.AddTransient(typeof(EventDetailsPageViewModel));
}
diff --git a/Wino.Mail.WinUI/Helpers/XamlHelpers.cs b/Wino.Mail.WinUI/Helpers/XamlHelpers.cs
index e2e4cd0e..f3e2f135 100644
--- a/Wino.Mail.WinUI/Helpers/XamlHelpers.cs
+++ b/Wino.Mail.WinUI/Helpers/XamlHelpers.cs
@@ -42,6 +42,7 @@ public static class XamlHelpers
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
public static bool ReverseBoolConverter(bool value) => !value;
+ public static bool AreEqual(int value1, int value2) => value1 == value2;
public static bool ShouldDisplayPreview(string text) => text == null ? false : text.Any(x => char.IsLetter(x));
public static bool CountToBooleanConverter(int value) => value > 0;
public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2);
diff --git a/Wino.Mail.WinUI/Selectors/CalendarItemShowAsStripeTemplateSelector.cs b/Wino.Mail.WinUI/Selectors/CalendarItemShowAsStripeTemplateSelector.cs
index bbf4657d..e24fe86b 100644
--- a/Wino.Mail.WinUI/Selectors/CalendarItemShowAsStripeTemplateSelector.cs
+++ b/Wino.Mail.WinUI/Selectors/CalendarItemShowAsStripeTemplateSelector.cs
@@ -8,7 +8,7 @@ namespace Wino.Selectors;
///
/// DataTemplateSelector that selects the appropriate stripe template based on CalendarItemShowAs status.
///
-public class CalendarItemShowAsStripeTemplateSelector : DataTemplateSelector
+public partial class CalendarItemShowAsStripeTemplateSelector : DataTemplateSelector
{
public DataTemplate FreeTemplate { get; set; }
public DataTemplate TentativeTemplate { get; set; }
diff --git a/Wino.Mail.WinUI/Services/NavigationService.cs b/Wino.Mail.WinUI/Services/NavigationService.cs
index 683f0655..096ce076 100644
--- a/Wino.Mail.WinUI/Services/NavigationService.cs
+++ b/Wino.Mail.WinUI/Services/NavigationService.cs
@@ -15,6 +15,7 @@ using Wino.Mail.WinUI.Interfaces;
using Wino.Mail.WinUI.Services;
using Wino.Mail.WinUI.Views.Calendar;
using Wino.Messaging.Client.Mails;
+using Wino.Messaging.Client.Navigation;
using Wino.Views;
using Wino.Views.Account;
using Wino.Views.Mail;
@@ -68,6 +69,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.CalendarPage => typeof(CalendarPage),
WinoPage.EventDetailsPage => typeof(EventDetailsPage),
WinoPage.CalendarSettingsPage => typeof(CalendarSettingsPage),
+ WinoPage.CalendarAccountSettingsPage => typeof(CalendarAccountSettingsPage),
_ => null,
};
}
@@ -208,8 +210,17 @@ public class NavigationService : NavigationServiceBase, INavigationService
return false;
}
- public void GoBack()
+ public void GoBack(Core.Domain.Enums.NavigationTransitionEffect slideEffect = Core.Domain.Enums.NavigationTransitionEffect.FromRight)
{
+ // Check if we're navigating within ManageAccountsPage (applies to both modes)
+ // Check if we're navigating within SettingsPage (applies to both modes)
+ if (_statePersistanceService.IsManageAccountsNavigating || _statePersistanceService.IsSettingsNavigating)
+ {
+ // Send message to ManageAccountsPage to go back within its AccountPagesFrame
+ WeakReferenceMessenger.Default.Send(new BackBreadcrumNavigationRequested(slideEffect));
+ return;
+ }
+
if (_statePersistanceService.ApplicationMode == WinoApplicationMode.Calendar)
{
var innerShellFrame = GetCoreFrame(NavigationReferenceFrame.InnerShellFrame);
diff --git a/Wino.Mail.WinUI/Services/StatePersistenceService.cs b/Wino.Mail.WinUI/Services/StatePersistenceService.cs
index 742ee766..4038d7fd 100644
--- a/Wino.Mail.WinUI/Services/StatePersistenceService.cs
+++ b/Wino.Mail.WinUI/Services/StatePersistenceService.cs
@@ -32,8 +32,8 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
public bool IsBackButtonVisible =>
ApplicationMode == WinoApplicationMode.Mail
- ? IsReadingMail && IsReaderNarrowed
- : IsEventDetailsVisible;
+ ? (IsReadingMail && IsReaderNarrowed) || IsManageAccountsNavigating || IsSettingsNavigating
+ : IsEventDetailsVisible || IsManageAccountsNavigating || IsSettingsNavigating;
private WinoApplicationMode applicationMode = WinoApplicationMode.Mail;
@@ -66,6 +66,34 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
}
}
+ private bool isManageAccountsNavigating;
+
+ public bool IsManageAccountsNavigating
+ {
+ get => isManageAccountsNavigating;
+ set
+ {
+ if (SetProperty(ref isManageAccountsNavigating, value))
+ {
+ OnPropertyChanged(nameof(IsBackButtonVisible));
+ }
+ }
+ }
+
+ private bool isSettingsNavigating;
+
+ public bool IsSettingsNavigating
+ {
+ get => isSettingsNavigating;
+ set
+ {
+ if (SetProperty(ref isSettingsNavigating, value))
+ {
+ OnPropertyChanged(nameof(IsBackButtonVisible));
+ }
+ }
+ }
+
private bool isReadingMail;
public bool IsReadingMail
diff --git a/Wino.Mail.WinUI/Views/Abstract/CalendarAccountSettingsPageAbstract.cs b/Wino.Mail.WinUI/Views/Abstract/CalendarAccountSettingsPageAbstract.cs
new file mode 100644
index 00000000..33ddb038
--- /dev/null
+++ b/Wino.Mail.WinUI/Views/Abstract/CalendarAccountSettingsPageAbstract.cs
@@ -0,0 +1,6 @@
+using Wino.Calendar.ViewModels;
+using Wino.Mail.WinUI.Views.Abstract;
+
+namespace Wino.Mail.WinUI.Views.Abstract;
+
+public abstract class CalendarAccountSettingsPageAbstract : BasePage { }
diff --git a/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml b/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml
index c0d16838..8ce44c18 100644
--- a/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml
+++ b/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml
@@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:abstract="using:Wino.Views.Abstract"
+ xmlns:calendar="using:Wino.Core.Domain.Entities.Calendar"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:controls1="using:Wino.Controls"
xmlns:coreControls="using:Wino.Mail.WinUI.Controls"
@@ -15,7 +16,8 @@
xmlns:local="using:Wino.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
- x:Name="root"
+ xmlns:ui="using:CommunityToolkit.WinUI"
+ x:Name="PageRoot"
mc:Ignorable="d">
@@ -69,186 +71,294 @@
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+ Command="{x:Bind ViewModel.EditAccountDetailsCommand}"
+ Description="{x:Bind domain:Translator.SettingsEditAccountDetails_Description}"
+ Header="{x:Bind domain:Translator.SettingsEditAccountDetails_Title}"
+ IsClickEnabled="True">
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ActionIcon="{x:Null}"
+ ActionIconToolTip="{x:Bind domain:Translator.SettingsDeleteAccount_Title}"
+ Command="{x:Bind ViewModel.DeleteAccountCommand}"
+ Description="{x:Bind domain:Translator.SettingsDeleteAccount_Description}"
+ Header="{x:Bind domain:Translator.SettingsDeleteAccount_Title}">
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml.cs b/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml.cs
index 46d12c22..6baff56c 100644
--- a/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml.cs
+++ b/Wino.Mail.WinUI/Views/Account/AccountDetailsPage.xaml.cs
@@ -1,4 +1,7 @@
+using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Navigation;
+using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Models.Folders;
using Wino.Views.Abstract;
@@ -9,9 +12,16 @@ public sealed partial class AccountDetailsPage : AccountDetailsPageAbstract
public AccountDetailsPage()
{
InitializeComponent();
+
+ NavigationCacheMode = NavigationCacheMode.Enabled;
}
- private async void SyncFolderToggled(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
+ private void OnTabSelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs e)
+ {
+ ViewModel.SelectedTabIndex = TabSelector.SelectedItem == null ? 1 : TabSelector.Items.IndexOf(TabSelector.SelectedItem);
+ }
+
+ private async void SyncFolderToggled(object sender, RoutedEventArgs e)
{
if (sender is CheckBox checkBox && checkBox.Tag is IMailItemFolder folder)
{
@@ -19,11 +29,30 @@ public sealed partial class AccountDetailsPage : AccountDetailsPageAbstract
}
}
- private async void UnreadBadgeCheckboxToggled(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
+ private async void UnreadBadgeCheckboxToggled(object sender, RoutedEventArgs e)
{
if (sender is CheckBox checkBox && checkBox.Tag is IMailItemFolder folder)
{
await ViewModel.FolderShowUnreadToggled(folder, checkBox.IsChecked.GetValueOrDefault());
}
}
+
+ private void CalendarItemClicked(object sender, RoutedEventArgs e)
+ {
+ if (sender is CommunityToolkit.WinUI.Controls.SettingsCard settingsCard && settingsCard.CommandParameter is AccountCalendar calendar)
+ {
+ ViewModel.CalendarItemClickedCommand?.Execute(calendar);
+ }
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ base.OnNavigatedTo(e);
+
+ if (e.NavigationMode == NavigationMode.New)
+ {
+ // Set initial tab to Mail (index 1)
+ TabSelector.SelectedItem = TabSelector.Items[1];
+ }
+ }
}
diff --git a/Wino.Mail.WinUI/Views/Account/AccountManagementPage.xaml b/Wino.Mail.WinUI/Views/Account/AccountManagementPage.xaml
index 179c0ee7..1587bf30 100644
--- a/Wino.Mail.WinUI/Views/Account/AccountManagementPage.xaml
+++ b/Wino.Mail.WinUI/Views/Account/AccountManagementPage.xaml
@@ -230,7 +230,6 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wino.Mail.WinUI/Views/Calendar/CalendarAccountSettingsPage.xaml.cs b/Wino.Mail.WinUI/Views/Calendar/CalendarAccountSettingsPage.xaml.cs
new file mode 100644
index 00000000..0d74d993
--- /dev/null
+++ b/Wino.Mail.WinUI/Views/Calendar/CalendarAccountSettingsPage.xaml.cs
@@ -0,0 +1,11 @@
+using Wino.Mail.WinUI.Views.Abstract;
+
+namespace Wino.Mail.WinUI.Views.Calendar;
+
+public sealed partial class CalendarAccountSettingsPage : CalendarAccountSettingsPageAbstract
+{
+ public CalendarAccountSettingsPage()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/Wino.Mail.WinUI/Views/Calendar/CalendarSettingsPage.xaml b/Wino.Mail.WinUI/Views/Calendar/CalendarSettingsPage.xaml
index 35b3a574..d2990476 100644
--- a/Wino.Mail.WinUI/Views/Calendar/CalendarSettingsPage.xaml
+++ b/Wino.Mail.WinUI/Views/Calendar/CalendarSettingsPage.xaml
@@ -7,8 +7,10 @@
xmlns:controls1="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="using:Wino.Core.Domain"
+ xmlns:entities="using:Wino.Core.Domain.Entities.Shared"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkitExt="using:CommunityToolkit.WinUI"
+ x:Name="Root"
mc:Ignorable="d">
@@ -178,7 +180,52 @@
+
+
diff --git a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml
index 5079a8f7..5a15e870 100644
--- a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml
+++ b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml
@@ -43,7 +43,10 @@
-
+
diff --git a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
index e39a6a87..bbd4bb27 100644
--- a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
+++ b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
@@ -6,8 +6,8 @@ using Microsoft.UI.Xaml.Navigation;
using MoreLinq;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
-using Wino.Mail.WinUI.Views.Abstract;
using Wino.Mail.ViewModels.Data;
+using Wino.Mail.WinUI.Views.Abstract;
using Wino.Messaging.Client.Navigation;
using Wino.Messaging.UI;
@@ -37,6 +37,10 @@ public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
WeakReferenceMessenger.Default.Register(this);
WeakReferenceMessenger.Default.Register(this);
+ // Register for frame navigation events to track back button visibility
+ AccountPagesFrame.Navigated -= AccountPagesFrameNavigated;
+ AccountPagesFrame.Navigated += AccountPagesFrameNavigated;
+
var initialRequest = new BreadcrumbNavigationRequested(Translator.MenuManageAccounts, WinoPage.AccountManagementPage);
PageHistory.Add(new BreadcrumbNavigationItemViewModel(initialRequest, true));
@@ -53,6 +57,12 @@ public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
WeakReferenceMessenger.Default.Unregister(this);
WeakReferenceMessenger.Default.Unregister(this);
+ // Unregister frame navigation event
+ AccountPagesFrame.Navigated -= AccountPagesFrameNavigated;
+
+ // Reset navigation state when leaving ManageAccountsPage
+ ViewModel.StatePersistenceService.IsManageAccountsNavigating = false;
+
base.OnNavigatingFrom(e);
}
@@ -62,20 +72,42 @@ public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
if (pageType == null) return;
- AccountPagesFrame.Navigate(pageType, message.Parameter, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
+ AccountPagesFrame.Navigate(pageType, message.Parameter, new SlideNavigationTransitionInfo() { Effect = Microsoft.UI.Xaml.Media.Animation.SlideNavigationTransitionEffect.FromRight });
PageHistory.ForEach(a => a.IsActive = false);
PageHistory.Add(new BreadcrumbNavigationItemViewModel(message, true));
}
- private void GoBackFrame()
+ private void AccountPagesFrameNavigated(object sender, NavigationEventArgs e)
+ {
+ // Update back button visibility based on whether we can go back within the frame
+ ViewModel.StatePersistenceService.IsManageAccountsNavigating = AccountPagesFrame.CanGoBack;
+ }
+
+ private void GoBackFrame(Core.Domain.Enums.NavigationTransitionEffect slideEffect)
{
if (AccountPagesFrame.CanGoBack)
{
PageHistory.RemoveAt(PageHistory.Count - 1);
- AccountPagesFrame.GoBack(new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
+ var winuiEffect = slideEffect switch
+ {
+ Core.Domain.Enums.NavigationTransitionEffect.FromLeft => Microsoft.UI.Xaml.Media.Animation.SlideNavigationTransitionEffect.FromLeft,
+ _ => Microsoft.UI.Xaml.Media.Animation.SlideNavigationTransitionEffect.FromRight,
+ };
+
+ AccountPagesFrame.GoBack(new SlideNavigationTransitionInfo() { Effect = winuiEffect });
+
+ // Set the new last item as active
+ if (PageHistory.Count > 0)
+ {
+ PageHistory.ForEach(a => a.IsActive = false);
+ PageHistory[PageHistory.Count - 1].IsActive = true;
+ }
+
+ // Update back button visibility after navigation
+ ViewModel.StatePersistenceService.IsManageAccountsNavigating = AccountPagesFrame.CanGoBack;
}
}
@@ -83,17 +115,16 @@ public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
{
var clickedPageHistory = PageHistory[args.Index];
+ // Trigger GoBack repeatedly until we reach the clicked breadcrumb item
while (PageHistory.FirstOrDefault(a => a.IsActive) != clickedPageHistory)
{
- AccountPagesFrame.GoBack(new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
- PageHistory.RemoveAt(PageHistory.Count - 1);
- PageHistory[PageHistory.Count - 1].IsActive = true;
+ ViewModel.NavigationService.GoBack();
}
}
public void Receive(BackBreadcrumNavigationRequested message)
{
- GoBackFrame();
+ GoBackFrame(message.SlideEffect);
}
public void Receive(AccountUpdatedMessage message)
diff --git a/Wino.Mail.WinUI/Views/Settings/EditAccountDetailsPage.xaml b/Wino.Mail.WinUI/Views/Settings/EditAccountDetailsPage.xaml
index d163cc25..eb20b025 100644
--- a/Wino.Mail.WinUI/Views/Settings/EditAccountDetailsPage.xaml
+++ b/Wino.Mail.WinUI/Views/Settings/EditAccountDetailsPage.xaml
@@ -43,7 +43,7 @@
Text="{x:Bind ViewModel.SenderName, Mode=TwoWay}" />
-
+