using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; 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.Core.Domain.Models.Settings; 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; namespace Wino.Views; public sealed partial class SettingsPage : SettingsPageAbstract, IRecipient, IRecipient, IRecipient, IRecipient, IRecipient { public ObservableCollection PageHistory { get; set; } = []; public SettingsPage() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // Register for frame navigation events to track back button visibility SettingsFrame.Navigated -= SettingsFrameNavigated; SettingsFrame.Navigated += SettingsFrameNavigated; var initialPage = e.Parameter as WinoPage? ?? WinoPage.SettingOptionsPage; NavigateToRootPage(initialPage); } public override void OnLanguageChanged() { base.OnLanguageChanged(); // Update Settings header in breadcrumb. var settingsHeader = PageHistory.FirstOrDefault(); 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; } var winoAccountEntry = PageHistory.FirstOrDefault(a => a.Request.PageType == WinoPage.WinoAccountManagementPage); if (winoAccountEntry != null) { winoAccountEntry.Title = Translator.WinoAccount_SettingsSection_Title; } _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { // Unregister frame navigation event SettingsFrame.Navigated -= SettingsFrameNavigated; base.OnNavigatingFrom(e); } protected override void RegisterRecipients() { base.RegisterRecipients(); WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); WeakReferenceMessenger.Default.Register(this); } protected override void UnregisterRecipients() { base.UnregisterRecipients(); WeakReferenceMessenger.Default.Unregister(this); WeakReferenceMessenger.Default.Unregister(this); WeakReferenceMessenger.Default.Unregister(this); WeakReferenceMessenger.Default.Unregister(this); WeakReferenceMessenger.Default.Unregister(this); } void IRecipient.Receive(BreadcrumbNavigationRequested message) { NavigateBreadcrumb(message); } private void SettingsFrameNavigated(object sender, NavigationEventArgs e) { UpdateBackNavigationState(); _ = RefreshCurrentPageStateAsync(); } private void GoBackFrame(Core.Domain.Enums.NavigationTransitionEffect slideEffect) { if (!BreadcrumbNavigationHelper.GoBack(SettingsFrame, PageHistory, slideEffect)) return; UpdateBackNavigationState(); _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); } private void BreadItemClicked(Microsoft.UI.Xaml.Controls.BreadcrumbBar sender, Microsoft.UI.Xaml.Controls.BreadcrumbBarItemClickedEventArgs args) { if (!BreadcrumbNavigationHelper.NavigateTo(SettingsFrame, PageHistory, args.Index)) return; UpdateBackNavigationState(); _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); } public void Receive(BackBreadcrumNavigationRequested message) { GoBackFrame(message.SlideEffect); } public void Receive(SettingsRootNavigationRequested message) { var currentRootPage = SettingsNavigationInfoProvider.GetRootPage(PageHistory.LastOrDefault()?.Request.PageType ?? WinoPage.SettingOptionsPage); if (message.PageType != WinoPage.SettingOptionsPage && currentRootPage == message.PageType) return; NavigateToRootPage(message.PageType); } 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; _ = RefreshCurrentPageStateAsync(); 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; _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); }); } private void NavigateBreadcrumb(BreadcrumbNavigationRequested message) { if (!BreadcrumbNavigationHelper.Navigate(SettingsFrame, PageHistory, message, ViewModel.NavigationService.GetPageType)) return; UpdateBackNavigationState(); _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); } private void NavigateToRootPage(WinoPage targetPage) { PageHistory.Clear(); SettingsFrame.BackStack.Clear(); SettingsFrame.ForwardStack.Clear(); NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.MenuSettings, WinoPage.SettingOptionsPage)); if (targetPage != WinoPage.SettingOptionsPage) { NavigateBreadcrumb(new BreadcrumbNavigationRequested( SettingsNavigationInfoProvider.GetPageTitle(targetPage), targetPage)); return; } UpdateWindowTitle(); } public void ResetForModeSwitch() { while (PageHistory.Count > 1 && SettingsFrame.CanGoBack) { if (!BreadcrumbNavigationHelper.GoBack(SettingsFrame, PageHistory, Core.Domain.Enums.NavigationTransitionEffect.FromRight)) break; } SettingsFrame.ForwardStack.Clear(); UpdateBackNavigationState(); _ = RefreshCurrentPageStateAsync(); UpdateWindowTitle(); } private void UpdateBackNavigationState() { WeakReferenceMessenger.Default.Send(new TitleBarShellContentUpdated()); } public bool CanNavigateBack => PageHistory.Count > 1 && SettingsFrame.CanGoBack; private async Task RefreshCurrentPageStateAsync() { var activePage = PageHistory.LastOrDefault()?.Request.PageType ?? WinoPage.SettingOptionsPage; var rootPage = SettingsNavigationInfoProvider.GetRootPage(activePage); await ViewModel.UpdateActivePageAsync(rootPage); WeakReferenceMessenger.Default.Send(new ActiveSettingsPageChanged(rootPage)); } private void UpdateWindowTitle() { var activeTitle = PageHistory.LastOrDefault()?.Title; ViewModel.StatePersistenceService.CoreWindowTitle = string.IsNullOrWhiteSpace(activeTitle) ? Translator.MenuSettings : activeTitle; } }