diff --git a/AGENTS.md b/AGENTS.md
index f1324382..fe235e7a 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -143,7 +143,7 @@ private string searchQuery = string.Empty;
- In ViewModels, update all UI-bound properties/collections via `ExecuteUIThread(...)` (especially after awaited calls and any use of `ConfigureAwait(false)`).
- In `EventDetailsPageViewModel.LoadAttendeesAsync`, never mutate `CurrentEvent.Attendees` outside `ExecuteUIThread(...)`.
- Never create pure C# controls or controls that heavily manipulate UI structure from `.cs` files. Define controls in XAML and keep UI composition in XAML.
-- For XAML-backed controls and pages, wire framework events like `Loaded`, `Unloaded`, and input events from XAML, not by subscribing in constructors in `.xaml.cs`.
+- Never subscribe to framework events like `Loaded`, `Unloaded`, or input events from constructors in `.xaml.cs` for XAML-backed controls and pages; wire them directly in XAML instead.
diff --git a/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs b/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs
index 15609ec5..9b98cc15 100644
--- a/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs
+++ b/Wino.Calendar.ViewModels/CalendarAppShellViewModel.cs
@@ -85,7 +85,6 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
[ObservableProperty]
private bool isStoreUpdateItemVisible;
- private readonly ManageAccountsMenuItem _manageAccountsMenuItem = new();
private readonly SettingsItem _settingsItem = new();
private readonly StoreUpdateMenuItem _storeUpdateMenuItem = new();
private readonly NewCalendarEventMenuItem _newEventMenuItem = new();
@@ -378,9 +377,6 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
ForceNavigateCalendarDate();
}
- [RelayCommand]
- public void ManageAccounts() => NavigationService.Navigate(WinoPage.AccountManagementPage);
-
public async Task HandleNavigationItemInvokedAsync(IMenuItem menuItem)
{
switch (menuItem)
@@ -388,9 +384,6 @@ public partial class CalendarAppShellViewModel : CalendarBaseViewModel,
case NewMailMenuItem:
await NewEventAsync().ConfigureAwait(false);
break;
- case ManageAccountsMenuItem:
- NavigationService.Navigate(WinoPage.ManageAccountsPage);
- break;
case SettingsItem:
NavigationService.Navigate(WinoPage.SettingsPage);
break;
diff --git a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
index 2c544e59..fa10bc7e 100644
--- a/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
+++ b/Wino.Core.Domain/Interfaces/IStatePersistenceService.cs
@@ -44,11 +44,6 @@ 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.
///
diff --git a/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs b/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs
deleted file mode 100644
index 147501b2..00000000
--- a/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace Wino.Core.Domain.MenuItems;
-
-public class ManageAccountsMenuItem : MenuItemBase { }
diff --git a/Wino.Core.Domain/MenuItems/MenuItemBase.cs b/Wino.Core.Domain/MenuItems/MenuItemBase.cs
index eaf53f82..db4958de 100644
--- a/Wino.Core.Domain/MenuItems/MenuItemBase.cs
+++ b/Wino.Core.Domain/MenuItems/MenuItemBase.cs
@@ -8,10 +8,10 @@ namespace Wino.Core.Domain.MenuItems;
public partial class MenuItemBase : ObservableObject, IMenuItem
{
[ObservableProperty]
- private bool _isExpanded;
+ public partial bool IsExpanded { get; set; }
[ObservableProperty]
- private bool _isSelected;
+ public partial bool IsSelected { get; set; }
public IMenuItem ParentMenuItem { get; }
@@ -46,7 +46,7 @@ public partial class MenuItemBase : ObservableObject, IMenuItem
public partial class MenuItemBase : MenuItemBase
{
[ObservableProperty]
- private T _parameter;
+ public partial T Parameter { get; set; }
public MenuItemBase(T parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(entityId, parentMenuItem) => Parameter = parameter;
}
@@ -54,7 +54,7 @@ public partial class MenuItemBase : MenuItemBase
public partial class MenuItemBase : MenuItemBase
{
[ObservableProperty]
- private bool _isChildSelected;
+ public partial bool IsChildSelected { get; set; }
protected MenuItemBase(TValue parameter, Guid? entityId, IMenuItem parentMenuItem = null) : base(parameter, entityId, parentMenuItem) { }
diff --git a/Wino.Core.Domain/MenuItems/NewContactMenuItem.cs b/Wino.Core.Domain/MenuItems/NewContactMenuItem.cs
new file mode 100644
index 00000000..24d09bc0
--- /dev/null
+++ b/Wino.Core.Domain/MenuItems/NewContactMenuItem.cs
@@ -0,0 +1,3 @@
+namespace Wino.Core.Domain.MenuItems;
+
+public sealed class NewContactMenuItem : MenuItemBase { }
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index 8d87609c..97f7e975 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -793,7 +793,7 @@
"SettingsMailSpacing_Description": "Adjust the spacing for listing mails.",
"SettingsMailSpacing_Title": "Mail Spacing",
"SettingsManageAccountSettings_Description": "Notifications, signatures, synchronization and other settings per account.",
- "SettingsManageAccountSettings_Title": "Manage Account Settings",
+ "SettingsManageAccountSettings_Title": "Manage Accounts",
"SettingsManageAliases_Description": "See e-mail aliases assigned for this account, update or delete them.",
"SettingsManageAliases_Title": "Aliases",
"SettingsEditAccountDetails_Title": "Edit Account Details",
@@ -1060,6 +1060,9 @@
"ContactsPage_EmptyState": "No contacts to display",
"ContactsPage_AddFirstContact": "Add your first contact",
"ContactsPage_ContactsCountSuffix": "contacts",
+ "ContactsPane_NewContact": "New Contact",
+ "ContactsPane_DescriptionTitle": "Manage your contacts",
+ "ContactsPane_DescriptionBody": "Create contacts, rename them, update profile pictures, and keep saved details organized in one place.",
"ContactEditDialog_AddTitle": "Add Contact",
"ContactInfoBar_ContactAdded": "Contact added successfully.",
"ContactInfoBar_ContactUpdated": "Contact updated successfully.",
diff --git a/Wino.Mail.ViewModels/ContactsPageViewModel.cs b/Wino.Mail.ViewModels/ContactsPageViewModel.cs
index 4e883ef8..f08e4ac6 100644
--- a/Wino.Mail.ViewModels/ContactsPageViewModel.cs
+++ b/Wino.Mail.ViewModels/ContactsPageViewModel.cs
@@ -7,16 +7,19 @@ using System.Threading;
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.Models.Navigation;
using Wino.Mail.ViewModels.Data;
+using Wino.Messaging.Client.Contacts;
namespace Wino.Mail.ViewModels;
-public partial class ContactsPageViewModel : MailBaseViewModel
+public partial class ContactsPageViewModel : MailBaseViewModel,
+ IRecipient
{
private const int ContactPageSize = 50;
@@ -97,6 +100,9 @@ public partial class ContactsPageViewModel : MailBaseViewModel
private async void ContactsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
=> await ExecuteUIThread(() => { OnPropertyChanged(nameof(IsEmpty)); });
+ void IRecipient.Receive(NewContactRequested message)
+ => _ = AddContactAsync();
+
[RelayCommand]
private async Task ReloadContactsAsync()
{
@@ -219,6 +225,20 @@ public partial class ContactsPageViewModel : MailBaseViewModel
}
}
+ protected override void RegisterRecipients()
+ {
+ base.RegisterRecipients();
+
+ Messenger.Register(this);
+ }
+
+ protected override void UnregisterRecipients()
+ {
+ base.UnregisterRecipients();
+
+ Messenger.Unregister(this);
+ }
+
[RelayCommand]
private async Task EditContactAsync(AccountContactViewModel contactViewModel)
{
diff --git a/Wino.Mail.ViewModels/MailAppShellViewModel.cs b/Wino.Mail.ViewModels/MailAppShellViewModel.cs
index 20ea5ad2..fc668429 100644
--- a/Wino.Mail.ViewModels/MailAppShellViewModel.cs
+++ b/Wino.Mail.ViewModels/MailAppShellViewModel.cs
@@ -54,7 +54,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
public MenuItemCollection MenuItems { get; set; }
private readonly SettingsItem SettingsItem = new SettingsItem();
- private readonly ManageAccountsMenuItem ManageAccountsMenuItem = new ManageAccountsMenuItem();
private readonly ContactsMenuItem ContactsMenuItem = new ContactsMenuItem();
private readonly StoreUpdateMenuItem StoreUpdateMenuItem = new StoreUpdateMenuItem();
@@ -820,7 +819,7 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
if (isManageAccountClicked)
{
- SelectedMenuItem = ManageAccountsMenuItem;
+ NavigationService.Navigate(WinoPage.SettingsPage, WinoPage.ManageAccountsPage);
}
return;
diff --git a/Wino.Mail.WinUI/App.xaml.cs b/Wino.Mail.WinUI/App.xaml.cs
index fa39fb6f..06bb04cf 100644
--- a/Wino.Mail.WinUI/App.xaml.cs
+++ b/Wino.Mail.WinUI/App.xaml.cs
@@ -561,7 +561,7 @@ public partial class App : WinoApplication,
public Task OpenManageAccountsFromWelcomeAsync()
{
Services.GetRequiredService()
- .Navigate(WinoPage.ManageAccountsPage, null, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.DrillIn);
+ .Navigate(WinoPage.SettingsPage, WinoPage.ManageAccountsPage, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.DrillIn);
return Task.CompletedTask;
}
diff --git a/Wino.Mail.WinUI/Selectors/NavigationMenuTemplateSelector.cs b/Wino.Mail.WinUI/Selectors/NavigationMenuTemplateSelector.cs
index 97167fbf..030026c5 100644
--- a/Wino.Mail.WinUI/Selectors/NavigationMenuTemplateSelector.cs
+++ b/Wino.Mail.WinUI/Selectors/NavigationMenuTemplateSelector.cs
@@ -8,7 +8,6 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
{
public DataTemplate MenuItemTemplate { get; set; } = null!;
public DataTemplate ContactsMenuItemTemplate { get; set; } = null!;
- public DataTemplate AccountManagementTemplate { get; set; } = null!;
public DataTemplate ClickableAccountMenuTemplate { get; set; } = null!;
public DataTemplate MergedAccountTemplate { get; set; } = null!;
public DataTemplate MergedAccountFolderTemplate { get; set; } = null!;
@@ -21,6 +20,7 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
public DataTemplate CreateNewFolderTemplate { get; set; } = null!;
public DataTemplate SeperatorTemplate { get; set; } = null!;
public DataTemplate NewMailTemplate { get; set; } = null!;
+ public DataTemplate NewContactTemplate { get; set; } = null!;
public DataTemplate CalendarNewEventTemplate { get; set; } = null!;
public DataTemplate CategoryItemsTemplate { get; set; } = null!;
public DataTemplate FixAuthenticationIssueTemplate { get; set; } = null!;
@@ -30,6 +30,8 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
{
if (item is NewCalendarEventMenuItem)
return CalendarNewEventTemplate;
+ else if (item is NewContactMenuItem)
+ return NewContactTemplate;
else if (item is NewMailMenuItem)
return NewMailTemplate;
else if (item is ContactsMenuItem)
@@ -43,8 +45,6 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
else if (item is AccountMenuItem)
// Merged inbox account menu items must be nested.
return ClickableAccountMenuTemplate;
- else if (item is ManageAccountsMenuItem)
- return AccountManagementTemplate;
else if (item is RateMenuItem)
return RatingItemTemplate;
else if (item is MergedAccountMenuItem)
diff --git a/Wino.Mail.WinUI/Services/NavigationService.cs b/Wino.Mail.WinUI/Services/NavigationService.cs
index 1a1fde0d..10e63b43 100644
--- a/Wino.Mail.WinUI/Services/NavigationService.cs
+++ b/Wino.Mail.WinUI/Services/NavigationService.cs
@@ -106,7 +106,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.AccountDetailsPage => typeof(AccountDetailsPage),
WinoPage.MergedAccountDetailsPage => typeof(MergedAccountDetailsPage),
WinoPage.AccountManagementPage => typeof(AccountManagementPage),
- WinoPage.ManageAccountsPage => typeof(ManageAccountsPage),
+ WinoPage.ManageAccountsPage => typeof(AccountManagementPage),
WinoPage.SignatureManagementPage => typeof(SignatureManagementPage),
WinoPage.AboutPage => typeof(AboutPage),
WinoPage.PersonalizationPage => typeof(PersonalizationPage),
@@ -237,6 +237,11 @@ public class NavigationService : NavigationServiceBase, INavigationService
NavigationReferenceFrame frame = NavigationReferenceFrame.InnerShellFrame,
NavigationTransitionType transition = NavigationTransitionType.None)
{
+ if (page is WinoPage.ManageAccountsPage or WinoPage.AccountManagementPage)
+ {
+ return NavigateInternal(WinoPage.SettingsPage, WinoPage.ManageAccountsPage, frame, transition);
+ }
+
var pageType = GetPageType(page);
if (pageType == null) return false;
@@ -441,11 +446,8 @@ public class NavigationService : NavigationServiceBase, INavigationService
private void GoBackInternal(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)
+ if (_statePersistanceService.IsSettingsNavigating)
{
- // Send message to ManageAccountsPage to go back within its AccountPagesFrame
WeakReferenceMessenger.Default.Send(new BackBreadcrumNavigationRequested(slideEffect));
return;
}
diff --git a/Wino.Mail.WinUI/Services/StatePersistenceService.cs b/Wino.Mail.WinUI/Services/StatePersistenceService.cs
index 23ce4466..67db9961 100644
--- a/Wino.Mail.WinUI/Services/StatePersistenceService.cs
+++ b/Wino.Mail.WinUI/Services/StatePersistenceService.cs
@@ -34,8 +34,8 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
public bool IsBackButtonVisible =>
ApplicationMode == WinoApplicationMode.Mail
- ? (IsReadingMail && IsReaderNarrowed) || IsManageAccountsNavigating || IsSettingsNavigating
- : IsEventDetailsVisible || IsManageAccountsNavigating || IsSettingsNavigating;
+ ? (IsReadingMail && IsReaderNarrowed) || IsSettingsNavigating
+ : IsEventDetailsVisible || IsSettingsNavigating;
private WinoApplicationMode applicationMode = WinoApplicationMode.Mail;
@@ -68,20 +68,6 @@ 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
diff --git a/Wino.Mail.WinUI/Styles/DataTemplates.xaml b/Wino.Mail.WinUI/Styles/DataTemplates.xaml
index dd622a9e..d914a61a 100644
--- a/Wino.Mail.WinUI/Styles/DataTemplates.xaml
+++ b/Wino.Mail.WinUI/Styles/DataTemplates.xaml
@@ -26,15 +26,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/Wino.Mail.WinUI/ViewModels/ContactsShellClient.cs b/Wino.Mail.WinUI/ViewModels/ContactsShellClient.cs
index f17cefd0..ef73e0c3 100644
--- a/Wino.Mail.WinUI/ViewModels/ContactsShellClient.cs
+++ b/Wino.Mail.WinUI/ViewModels/ContactsShellClient.cs
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.Messaging;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
@@ -6,11 +7,14 @@ using Wino.Core.Domain.MenuItems;
using Wino.Core.Domain.Models;
using Wino.Core.Domain.Models.Navigation;
using Wino.Core.ViewModels;
+using Wino.Messaging.Client.Contacts;
namespace Wino.Mail.WinUI.ViewModels;
public sealed class ContactsShellClient(INavigationService navigationService) : CoreBaseViewModel, IShellClient
{
+ private readonly NewContactMenuItem _newContactMenuItem = new();
+
public WinoApplicationMode Mode => WinoApplicationMode.Contacts;
public MenuItemCollection? MenuItems { get; private set; }
public object? SelectedMenuItem { get; set; }
@@ -20,6 +24,11 @@ public sealed class ContactsShellClient(INavigationService navigationService) :
{
base.OnDispatcherAssigned();
MenuItems ??= new MenuItemCollection(Dispatcher);
+
+ if (MenuItems.Count == 0)
+ {
+ MenuItems.Add(_newContactMenuItem);
+ }
}
public void Activate(ShellModeActivationContext activationContext)
@@ -33,7 +42,15 @@ public sealed class ContactsShellClient(INavigationService navigationService) :
OnNavigatedFrom(NavigationMode.New, null!);
}
- public Task HandleNavigationItemInvokedAsync(IMenuItem? menuItem) => Task.CompletedTask;
+ public Task HandleNavigationItemInvokedAsync(IMenuItem? menuItem)
+ {
+ if (menuItem is NewContactMenuItem)
+ {
+ WeakReferenceMessenger.Default.Send(new NewContactRequested());
+ }
+
+ return Task.CompletedTask;
+ }
public Task HandleNavigationSelectionChangedAsync(IMenuItem? menuItem) => Task.CompletedTask;
}
diff --git a/Wino.Mail.WinUI/Views/Calendar/CalendarAppShell.xaml b/Wino.Mail.WinUI/Views/Calendar/CalendarAppShell.xaml
index 550f2b14..7335a0eb 100644
--- a/Wino.Mail.WinUI/Views/Calendar/CalendarAppShell.xaml
+++ b/Wino.Mail.WinUI/Views/Calendar/CalendarAppShell.xaml
@@ -39,15 +39,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/Wino.Mail.WinUI/Views/Contacts/ContactsAppShell.xaml b/Wino.Mail.WinUI/Views/Contacts/ContactsAppShell.xaml
index 338640f7..1c86542d 100644
--- a/Wino.Mail.WinUI/Views/Contacts/ContactsAppShell.xaml
+++ b/Wino.Mail.WinUI/Views/Contacts/ContactsAppShell.xaml
@@ -5,14 +5,16 @@
xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract"
xmlns:coreControls="using:Wino.Mail.WinUI.Controls"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
-
-
+
+ ScrollViewer.VerticalScrollBarVisibility="Hidden"
+ Style="{StaticResource CalendarShellNavigationViewStyle}">
@@ -15,38 +12,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ HorizontalAlignment="Stretch" />
diff --git a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
index 20ef8f9e..f1545fc8 100644
--- a/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
+++ b/Wino.Mail.WinUI/Views/ManageAccountsPage.xaml.cs
@@ -1,136 +1,12 @@
-using System.Collections.ObjectModel;
-using System.Linq;
-using CommunityToolkit.Mvvm.Messaging;
-using Microsoft.UI.Xaml.Media.Animation;
-using Microsoft.UI.Xaml.Navigation;
using Wino.Core.Domain;
-using Wino.Core.Domain.Enums;
-using Wino.Helpers;
-using Wino.Mail.ViewModels.Data;
using Wino.Mail.WinUI.Views.Abstract;
-using Wino.Messaging.Client.Navigation;
-using Wino.Messaging.UI;
namespace Wino.Views;
-public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract,
- IRecipient,
- IRecipient,
- IRecipient,
- IRecipient
+public sealed partial class ManageAccountsPage : ManageAccountsPageAbstract
{
- public ObservableCollection PageHistory { get; set; } = new ObservableCollection();
-
-
public ManageAccountsPage()
{
InitializeComponent();
}
-
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
-
- // Re-register message handlers after base.OnNavigatedTo unregisters all handlers
- WeakReferenceMessenger.Default.Register(this);
- WeakReferenceMessenger.Default.Register(this);
- 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, backStackDepth: AccountPagesFrame.BackStack.Count + 1));
-
- var accountManagementPageType = ViewModel.NavigationService.GetPageType(WinoPage.AccountManagementPage);
-
- AccountPagesFrame.Navigate(accountManagementPageType, null, new SuppressNavigationTransitionInfo());
- UpdateWindowTitle();
- }
-
- protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
- {
- // Explicitly unregister our message handlers before base.OnNavigatingFrom calls UnregisterAll
- WeakReferenceMessenger.Default.Unregister(this);
- WeakReferenceMessenger.Default.Unregister(this);
- 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);
- }
-
- void IRecipient.Receive(BreadcrumbNavigationRequested message)
- {
- BreadcrumbNavigationHelper.Navigate(AccountPagesFrame, PageHistory, message, ViewModel.NavigationService.GetPageType);
- UpdateWindowTitle();
- }
-
- 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 (!BreadcrumbNavigationHelper.GoBack(AccountPagesFrame, PageHistory, slideEffect))
- return;
-
- ViewModel.StatePersistenceService.IsManageAccountsNavigating = AccountPagesFrame.CanGoBack;
- UpdateWindowTitle();
- }
-
- private void BreadItemClicked(Microsoft.UI.Xaml.Controls.BreadcrumbBar sender, Microsoft.UI.Xaml.Controls.BreadcrumbBarItemClickedEventArgs args)
- {
- if (!BreadcrumbNavigationHelper.NavigateTo(AccountPagesFrame, PageHistory, args.Index))
- return;
-
- ViewModel.StatePersistenceService.IsManageAccountsNavigating = AccountPagesFrame.CanGoBack;
- UpdateWindowTitle();
- }
-
- public void Receive(BackBreadcrumNavigationRequested message)
- {
- GoBackFrame(message.SlideEffect);
- }
-
- public void Receive(AccountUpdatedMessage message)
- {
- var activePage = PageHistory.FirstOrDefault(a => a.Request.PageType == WinoPage.AccountDetailsPage);
-
- if (activePage == null) return;
-
- DispatcherQueue.TryEnqueue(() =>
- {
- activePage.Title = message.Account.Name;
- UpdateWindowTitle();
- });
- }
-
- public void Receive(MergedInboxRenamed message)
- {
- // TODO: Find better way to retrieve page history from the stack for the merged account.
- var activePage = PageHistory.LastOrDefault();
-
- if (activePage == null) return;
-
- activePage.Title = message.NewName;
- UpdateWindowTitle();
- }
-
- private void UpdateWindowTitle()
- {
- var activeTitle = PageHistory.LastOrDefault()?.Title;
- ViewModel.StatePersistenceService.CoreWindowTitle = string.IsNullOrWhiteSpace(activeTitle)
- ? Translator.MenuManageAccounts
- : activeTitle;
- }
}
diff --git a/Wino.Mail.WinUI/Views/Settings/ContactsPage.xaml b/Wino.Mail.WinUI/Views/Settings/ContactsPage.xaml
index 7ac7e478..cd4190c7 100644
--- a/Wino.Mail.WinUI/Views/Settings/ContactsPage.xaml
+++ b/Wino.Mail.WinUI/Views/Settings/ContactsPage.xaml
@@ -106,11 +106,6 @@
-
-
-
-
-
-
-
diff --git a/Wino.Mail.WinUI/Views/SettingsPage.xaml.cs b/Wino.Mail.WinUI/Views/SettingsPage.xaml.cs
index 9f861d82..4bf25b17 100644
--- a/Wino.Mail.WinUI/Views/SettingsPage.xaml.cs
+++ b/Wino.Mail.WinUI/Views/SettingsPage.xaml.cs
@@ -8,6 +8,7 @@ using Wino.Core.Domain.Enums;
using Wino.Helpers;
using Wino.Mail.ViewModels.Data;
using Wino.Messaging.Client.Navigation;
+using Wino.Messaging.UI;
using Wino.Views.Abstract;
using Wino.Views.Settings;
@@ -15,7 +16,9 @@ namespace Wino.Views;
public sealed partial class SettingsPage : SettingsPageAbstract,
IRecipient,
- IRecipient
+ IRecipient,
+ IRecipient,
+ IRecipient
{
public ObservableCollection PageHistory { get; set; } = [];
@@ -45,20 +48,20 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
switch (parameterPage)
{
case WinoPage.AppPreferencesPage:
- WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsAppPreferences_Title, WinoPage.AppPreferencesPage));
+ NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsAppPreferences_Title, WinoPage.AppPreferencesPage));
break;
case WinoPage.PersonalizationPage:
- WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsPersonalization_Title, WinoPage.PersonalizationPage));
+ NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsPersonalization_Title, WinoPage.PersonalizationPage));
break;
case WinoPage.StoragePage:
- WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
+ NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
break;
case WinoPage.EmailTemplatesPage:
- WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsEmailTemplates_Title, WinoPage.EmailTemplatesPage));
+ NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsEmailTemplates_Title, WinoPage.EmailTemplatesPage));
break;
case WinoPage.ManageAccountsPage:
case WinoPage.AccountManagementPage:
- WeakReferenceMessenger.Default.Send(new BreadcrumbNavigationRequested(Translator.SettingsManageAccountSettings_Title, WinoPage.ManageAccountsPage));
+ NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsManageAccountSettings_Title, WinoPage.ManageAccountsPage));
break;
}
}
@@ -77,6 +80,14 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
if (settingsHeader == null) return;
settingsHeader.Title = Translator.MenuSettings;
+ var manageAccountsEntry = PageHistory.FirstOrDefault(a =>
+ a.Request.PageType == WinoPage.ManageAccountsPage || a.Request.PageType == WinoPage.AccountManagementPage);
+
+ if (manageAccountsEntry != null)
+ {
+ manageAccountsEntry.Title = Translator.SettingsManageAccountSettings_Title;
+ }
+
UpdateWindowTitle();
}
@@ -97,6 +108,8 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
WeakReferenceMessenger.Default.Register(this);
WeakReferenceMessenger.Default.Register(this);
+ WeakReferenceMessenger.Default.Register(this);
+ WeakReferenceMessenger.Default.Register(this);
}
protected override void UnregisterRecipients()
@@ -105,12 +118,13 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
WeakReferenceMessenger.Default.Unregister(this);
WeakReferenceMessenger.Default.Unregister(this);
+ WeakReferenceMessenger.Default.Unregister(this);
+ WeakReferenceMessenger.Default.Unregister(this);
}
void IRecipient.Receive(BreadcrumbNavigationRequested message)
{
- BreadcrumbNavigationHelper.Navigate(SettingsFrame, PageHistory, message, ViewModel.NavigationService.GetPageType);
- UpdateWindowTitle();
+ NavigateBreadcrumb(message);
}
private void SettingsFrameNavigated(object sender, NavigationEventArgs e)
@@ -142,6 +156,42 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
GoBackFrame(message.SlideEffect);
}
+ public void Receive(AccountUpdatedMessage message)
+ {
+ var activePage = PageHistory.LastOrDefault(a => a.Request.PageType == WinoPage.AccountDetailsPage);
+
+ if (activePage == null)
+ return;
+
+ DispatcherQueue.TryEnqueue(() =>
+ {
+ activePage.Title = message.Account.Name;
+ UpdateWindowTitle();
+ });
+ }
+
+ public void Receive(MergedInboxRenamed message)
+ {
+ var activePage = PageHistory.LastOrDefault(a => a.Request.PageType == WinoPage.MergedAccountDetailsPage);
+
+ if (activePage == null)
+ return;
+
+ DispatcherQueue.TryEnqueue(() =>
+ {
+ activePage.Title = message.NewName;
+ UpdateWindowTitle();
+ });
+ }
+
+ private void NavigateBreadcrumb(BreadcrumbNavigationRequested message)
+ {
+ if (!BreadcrumbNavigationHelper.Navigate(SettingsFrame, PageHistory, message, ViewModel.NavigationService.GetPageType))
+ return;
+
+ UpdateWindowTitle();
+ }
+
private void UpdateWindowTitle()
{
var activeTitle = PageHistory.LastOrDefault()?.Title;
diff --git a/Wino.Mail.WinUI/Views/WinoAppShell.xaml b/Wino.Mail.WinUI/Views/WinoAppShell.xaml
index 2e1f78fd..32c5c10d 100644
--- a/Wino.Mail.WinUI/Views/WinoAppShell.xaml
+++ b/Wino.Mail.WinUI/Views/WinoAppShell.xaml
@@ -394,6 +394,23 @@
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs b/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs
index df834607..39dab9ea 100644
--- a/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs
+++ b/Wino.Mail.WinUI/Views/WinoAppShell.xaml.cs
@@ -157,7 +157,6 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
private void ResetShellModeNavigationState()
{
- ViewModel.StatePersistenceService.IsManageAccountsNavigating = false;
ViewModel.StatePersistenceService.IsSettingsNavigating = false;
InnerShellFrame.BackStack.Clear();
InnerShellFrame.ForwardStack.Clear();
@@ -187,7 +186,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
if (ViewModel.IsCalendarMode)
{
- ViewModel.StatePersistenceService.CoreWindowTitle = ViewModel.StatePersistenceService.AppModeTitle;
+ ViewModel.StatePersistenceService.CoreWindowTitle = string.Empty;
return;
}
@@ -490,16 +489,29 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
private void UpdateNavigationPaneLayout(NavigationViewDisplayMode displayMode)
{
- if (ViewModel.IsCalendarMode)
+ if (displayMode == NavigationViewDisplayMode.Expanded && navigationView.IsPaneOpen)
{
- PaneCustomContent.Visibility = displayMode == NavigationViewDisplayMode.Expanded && navigationView.IsPaneOpen
- ? Visibility.Visible
- : Visibility.Collapsed;
+ if (ViewModel.IsCalendarMode)
+ {
+ PaneCustomContent.Visibility = Visibility.Visible;
+ CalendarPaneContent.Visibility = Visibility.Visible;
+ ContactsPaneContent.Visibility = Visibility.Collapsed;
+ InnerShellFrame.Margin = new Thickness(0);
+ return;
+ }
- InnerShellFrame.Margin = new Thickness(0);
- return;
+ if (ViewModel.IsContactsMode)
+ {
+ PaneCustomContent.Visibility = Visibility.Visible;
+ CalendarPaneContent.Visibility = Visibility.Collapsed;
+ ContactsPaneContent.Visibility = Visibility.Visible;
+ InnerShellFrame.Margin = new Thickness(0);
+ return;
+ }
}
+ CalendarPaneContent.Visibility = Visibility.Collapsed;
+ ContactsPaneContent.Visibility = Visibility.Collapsed;
PaneCustomContent.Visibility = Visibility.Collapsed;
InnerShellFrame.Margin = displayMode == NavigationViewDisplayMode.Minimal
? new Thickness(7, 0, 0, 0)
diff --git a/Wino.Messages/Client/Contacts/NewContactRequested.cs b/Wino.Messages/Client/Contacts/NewContactRequested.cs
new file mode 100644
index 00000000..2d451cf2
--- /dev/null
+++ b/Wino.Messages/Client/Contacts/NewContactRequested.cs
@@ -0,0 +1,3 @@
+namespace Wino.Messaging.Client.Contacts;
+
+public record NewContactRequested;