Settings shell.
This commit is contained in:
@@ -4,5 +4,6 @@ public enum WinoApplicationMode
|
||||
{
|
||||
Mail,
|
||||
Calendar,
|
||||
Contacts
|
||||
Contacts,
|
||||
Settings
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.MenuItems;
|
||||
|
||||
public partial class SettingsShellPageMenuItem(
|
||||
WinoPage pageType,
|
||||
string title,
|
||||
string description,
|
||||
string glyph) : MenuItemBase
|
||||
{
|
||||
public WinoPage PageType { get; } = pageType;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = title;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Description { get; set; } = description;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Glyph { get; set; } = glyph;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Wino.Core.Domain.MenuItems;
|
||||
|
||||
public partial class SettingsShellSectionMenuItem(string title, string glyph) : MenuItemBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = title;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Glyph { get; set; } = glyph;
|
||||
}
|
||||
@@ -3,4 +3,5 @@ namespace Wino.Core.Domain.Models.Navigation;
|
||||
public sealed class ShellModeActivationContext
|
||||
{
|
||||
public bool IsInitialActivation { get; init; }
|
||||
public object Parameter { get; init; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Models.Settings;
|
||||
|
||||
public sealed class SettingsNavigationItemInfo(
|
||||
WinoPage? pageType,
|
||||
string title,
|
||||
string description,
|
||||
string glyph = "",
|
||||
bool isSeparator = false)
|
||||
{
|
||||
public WinoPage? PageType { get; } = pageType;
|
||||
public string Title { get; } = title;
|
||||
public string Description { get; } = description;
|
||||
public string Glyph { get; } = glyph;
|
||||
public bool IsSeparator { get; } = isSeparator;
|
||||
}
|
||||
|
||||
public static class SettingsNavigationInfoProvider
|
||||
{
|
||||
public static IReadOnlyList<SettingsNavigationItemInfo> GetNavigationItems(string manageAccountsDescription = "")
|
||||
{
|
||||
return
|
||||
[
|
||||
new(WinoPage.SettingOptionsPage,
|
||||
Translator.SettingsHome_Title,
|
||||
Translator.SettingsOptions_HeroDescription,
|
||||
"\uE80F"),
|
||||
new(WinoPage.ManageAccountsPage,
|
||||
Translator.SettingsManageAccountSettings_Title,
|
||||
manageAccountsDescription,
|
||||
"\uE77B"),
|
||||
new(null, Translator.SettingsOptions_GeneralSection, string.Empty, "\uE713", isSeparator: true),
|
||||
new(WinoPage.AppPreferencesPage,
|
||||
Translator.SettingsAppPreferences_Title,
|
||||
Translator.SettingsAppPreferences_Description,
|
||||
"\uE770"),
|
||||
new(WinoPage.LanguageTimePage,
|
||||
Translator.SettingsLanguageTime_Title,
|
||||
Translator.SettingsLanguageTime_Description,
|
||||
"\uE775"),
|
||||
new(WinoPage.PersonalizationPage,
|
||||
Translator.SettingsPersonalization_Title,
|
||||
Translator.SettingsPersonalization_Description,
|
||||
"\uE771"),
|
||||
new(WinoPage.AboutPage,
|
||||
Translator.SettingsAbout_Title,
|
||||
Translator.SettingsAbout_Description,
|
||||
"\uE946"),
|
||||
new(null, Translator.SettingsOptions_MailSection, string.Empty, "\uE715", isSeparator: true),
|
||||
new(WinoPage.KeyboardShortcutsPage,
|
||||
Translator.Settings_KeyboardShortcuts_Title,
|
||||
Translator.Settings_KeyboardShortcuts_Description,
|
||||
"\uE765"),
|
||||
new(WinoPage.MessageListPage,
|
||||
Translator.SettingsMessageList_Title,
|
||||
Translator.SettingsMessageList_Description,
|
||||
"\uE8C4"),
|
||||
new(WinoPage.ReadComposePanePage,
|
||||
Translator.SettingsReadComposePane_Title,
|
||||
Translator.SettingsReadComposePane_Description,
|
||||
"\uE8BD"),
|
||||
new(WinoPage.SignatureAndEncryptionPage,
|
||||
Translator.SettingsSignatureAndEncryption_Title,
|
||||
Translator.SettingsSignatureAndEncryption_Description,
|
||||
"\uE8D7"),
|
||||
new(WinoPage.StoragePage,
|
||||
Translator.SettingsStorage_Title,
|
||||
Translator.SettingsStorage_Description,
|
||||
"\uE81C"),
|
||||
new(null, Translator.SettingsOptions_CalendarSection, string.Empty, "\uE787", isSeparator: true),
|
||||
new(WinoPage.CalendarSettingsPage,
|
||||
Translator.SettingsCalendarSettings_Title,
|
||||
Translator.SettingsCalendarSettings_Description,
|
||||
"\uE787")
|
||||
];
|
||||
}
|
||||
|
||||
public static SettingsNavigationItemInfo GetInfo(WinoPage pageType, string manageAccountsDescription = "")
|
||||
{
|
||||
var rootPage = GetRootPage(pageType);
|
||||
return GetNavigationItems(manageAccountsDescription).First(item => item.PageType == rootPage);
|
||||
}
|
||||
|
||||
public static string GetPageTitle(WinoPage pageType)
|
||||
=> pageType switch
|
||||
{
|
||||
WinoPage.SettingOptionsPage => Translator.MenuSettings,
|
||||
WinoPage.ManageAccountsPage => Translator.SettingsManageAccountSettings_Title,
|
||||
WinoPage.AccountManagementPage => Translator.SettingsManageAccountSettings_Title,
|
||||
WinoPage.PersonalizationPage => Translator.SettingsPersonalization_Title,
|
||||
WinoPage.AboutPage => Translator.SettingsAbout_Title,
|
||||
WinoPage.MessageListPage => Translator.SettingsMessageList_Title,
|
||||
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
|
||||
WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title,
|
||||
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
|
||||
WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title,
|
||||
WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title,
|
||||
WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title,
|
||||
WinoPage.StoragePage => Translator.SettingsStorage_Title,
|
||||
WinoPage.EmailTemplatesPage => Translator.SettingsEmailTemplates_Title,
|
||||
WinoPage.CreateEmailTemplatePage => Translator.SettingsEmailTemplates_Title,
|
||||
_ => GetInfo(pageType).Title
|
||||
};
|
||||
|
||||
public static WinoPage GetRootPage(WinoPage pageType)
|
||||
=> pageType switch
|
||||
{
|
||||
WinoPage.AccountManagementPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.AccountDetailsPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.MergedAccountDetailsPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.AliasManagementPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.SignatureManagementPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.ImapCalDavSettingsPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.EmailTemplatesPage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.CreateEmailTemplatePage => WinoPage.ManageAccountsPage,
|
||||
WinoPage.CalendarAccountSettingsPage => WinoPage.CalendarSettingsPage,
|
||||
_ => pageType
|
||||
};
|
||||
}
|
||||
@@ -815,6 +815,7 @@
|
||||
"SettingsNotifications_Title": "Notifications",
|
||||
"SettingsNotificationsAndTaskbar_Description": "Change whether notifications should be displayed and taskbar badge for this account.",
|
||||
"SettingsNotificationsAndTaskbar_Title": "Notifications & Taskbar",
|
||||
"SettingsHome_Title": "Home",
|
||||
"SettingsOptions_Title": "Settings",
|
||||
"SettingsOptions_GeneralSection": "General",
|
||||
"SettingsOptions_MailSection": "Mail",
|
||||
|
||||
@@ -44,6 +44,7 @@ public partial class KeyboardShortcutViewModel : ObservableObject
|
||||
WinoApplicationMode.Mail => Translator.KeyboardShortcuts_ModeMail,
|
||||
WinoApplicationMode.Calendar => Translator.KeyboardShortcuts_ModeCalendar,
|
||||
WinoApplicationMode.Contacts => Translator.ContactsPage_Title,
|
||||
WinoApplicationMode.Settings => Translator.MenuSettings,
|
||||
_ => Mode.ToString()
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Settings;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
namespace Wino.Core.ViewModels;
|
||||
@@ -63,23 +64,8 @@ public partial class SettingOptionsPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
if (type is WinoPage pageType)
|
||||
{
|
||||
string pageTitle = pageType switch
|
||||
{
|
||||
WinoPage.ManageAccountsPage => Translator.SettingsManageAccountSettings_Title,
|
||||
WinoPage.PersonalizationPage => Translator.SettingsPersonalization_Title,
|
||||
WinoPage.AboutPage => Translator.SettingsAbout_Title,
|
||||
WinoPage.MessageListPage => Translator.SettingsMessageList_Title,
|
||||
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
|
||||
WinoPage.LanguageTimePage => Translator.SettingsLanguageTime_Title,
|
||||
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
|
||||
WinoPage.CalendarSettingsPage => Translator.SettingsCalendarSettings_Title,
|
||||
WinoPage.SignatureAndEncryptionPage => Translator.SettingsSignatureAndEncryption_Title,
|
||||
WinoPage.KeyboardShortcutsPage => Translator.Settings_KeyboardShortcuts_Title,
|
||||
WinoPage.StoragePage => Translator.SettingsStorage_Title,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(pageTitle, pageType));
|
||||
var pageInfo = SettingsNavigationInfoProvider.GetInfo(pageType, AccountSummaryText);
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(pageInfo.Title, pageType));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,54 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Settings;
|
||||
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public class SettingsPageViewModel : CoreBaseViewModel
|
||||
public partial class SettingsPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public SettingsPageViewModel(INavigationService navigationService, IStatePersistanceService statePersistenceService)
|
||||
private readonly IAccountService _accountService;
|
||||
|
||||
public SettingsPageViewModel(
|
||||
INavigationService navigationService,
|
||||
IStatePersistanceService statePersistenceService,
|
||||
IAccountService accountService)
|
||||
{
|
||||
NavigationService = navigationService;
|
||||
StatePersistenceService = statePersistenceService;
|
||||
_accountService = accountService;
|
||||
}
|
||||
|
||||
public INavigationService NavigationService { get; }
|
||||
public IStatePersistanceService StatePersistenceService { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string CurrentDescription { get; set; } = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string ManageAccountsDescription { get; set; } = string.Empty;
|
||||
|
||||
public async Task UpdateActivePageAsync(WinoPage pageType)
|
||||
{
|
||||
await EnsureAccountSummaryAsync();
|
||||
|
||||
var info = SettingsNavigationInfoProvider.GetInfo(pageType, ManageAccountsDescription);
|
||||
await ExecuteUIThread(() => CurrentDescription = info.Description);
|
||||
}
|
||||
|
||||
private async Task EnsureAccountSummaryAsync()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(ManageAccountsDescription))
|
||||
return;
|
||||
|
||||
var accounts = await _accountService.GetAccountsAsync().ConfigureAwait(false);
|
||||
var count = accounts?.Count ?? 0;
|
||||
|
||||
await ExecuteUIThread(() =>
|
||||
{
|
||||
ManageAccountsDescription = string.Format(Translator.SettingsOptions_AccountsSummary, count);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,8 @@ public partial class AppPreferencesPageViewModel : MailBaseViewModel
|
||||
[
|
||||
Translator.SettingsAppPreferences_ApplicationMode_Mail,
|
||||
Translator.SettingsAppPreferences_ApplicationMode_Calendar,
|
||||
Translator.ContactsPage_Title
|
||||
Translator.ContactsPage_Title,
|
||||
Translator.MenuSettings
|
||||
];
|
||||
|
||||
SelectedDefaultSearchMode = SearchModes[(int)PreferencesService.DefaultSearchMode];
|
||||
|
||||
@@ -1147,7 +1147,7 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
|
||||
public async void Receive(NavigateAppPreferencesRequested message)
|
||||
{
|
||||
await MenuItemInvokedOrSelectedAsync(SettingsItem, WinoPage.AppPreferencesPage);
|
||||
NavigationService.Navigate(WinoPage.SettingsPage, WinoPage.AppPreferencesPage);
|
||||
}
|
||||
|
||||
protected override void RegisterRecipients()
|
||||
|
||||
@@ -53,6 +53,16 @@ internal static class AppModeActivationResolver
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Contains(value, "wino-settings") ||
|
||||
Contains(value, "--mode=settings") ||
|
||||
Contains(value, "mode=settings") ||
|
||||
Contains(value, "settingsapp") ||
|
||||
EqualsToken(value, "settings"))
|
||||
{
|
||||
mode = WinoApplicationMode.Settings;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Contains(value, "wino-mail") ||
|
||||
Contains(value, "--mode=mail") ||
|
||||
Contains(value, "mode=mail") ||
|
||||
|
||||
@@ -144,12 +144,14 @@ public partial class App : WinoApplication,
|
||||
services.AddSingleton(typeof(MailAppShellViewModel));
|
||||
services.AddSingleton(typeof(CalendarAppShellViewModel));
|
||||
services.AddSingleton(typeof(ContactsShellClient));
|
||||
services.AddSingleton(typeof(SettingsShellClient));
|
||||
services.AddSingleton(typeof(WinoAppShellViewModel));
|
||||
services.AddSingleton<IMailShellClient>(serviceProvider => serviceProvider.GetRequiredService<MailAppShellViewModel>());
|
||||
services.AddSingleton<ICalendarShellClient>(serviceProvider => serviceProvider.GetRequiredService<CalendarAppShellViewModel>());
|
||||
services.AddSingleton<IShellClient>(serviceProvider => serviceProvider.GetRequiredService<MailAppShellViewModel>());
|
||||
services.AddSingleton<IShellClient>(serviceProvider => serviceProvider.GetRequiredService<CalendarAppShellViewModel>());
|
||||
services.AddSingleton<IShellClient>(serviceProvider => serviceProvider.GetRequiredService<ContactsShellClient>());
|
||||
services.AddSingleton<IShellClient>(serviceProvider => serviceProvider.GetRequiredService<SettingsShellClient>());
|
||||
|
||||
services.AddTransient(typeof(MailListPageViewModel));
|
||||
services.AddTransient(typeof(MailRenderingPageViewModel));
|
||||
@@ -966,6 +968,7 @@ public partial class App : WinoApplication,
|
||||
{
|
||||
WinoApplicationMode.Calendar => "--mode=calendar",
|
||||
WinoApplicationMode.Contacts => "--mode=contacts",
|
||||
WinoApplicationMode.Settings => "--mode=settings",
|
||||
_ => "--mode=mail"
|
||||
};
|
||||
|
||||
|
||||
@@ -64,17 +64,11 @@ public sealed partial class AppModeFooterSwitcherControl : Segmented
|
||||
if (_isUpdatingSelection)
|
||||
return;
|
||||
|
||||
if (SelectedIndex == 3)
|
||||
{
|
||||
_navigationService.Navigate(WinoPage.SettingsPage);
|
||||
UpdateSelection(_statePersistenceService.ApplicationMode);
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedMode = SelectedIndex switch
|
||||
{
|
||||
1 => WinoApplicationMode.Calendar,
|
||||
2 => WinoApplicationMode.Contacts,
|
||||
3 => WinoApplicationMode.Settings,
|
||||
_ => WinoApplicationMode.Mail
|
||||
};
|
||||
|
||||
@@ -91,6 +85,7 @@ public sealed partial class AppModeFooterSwitcherControl : Segmented
|
||||
{
|
||||
WinoApplicationMode.Calendar => 1,
|
||||
WinoApplicationMode.Contacts => 2,
|
||||
WinoApplicationMode.Settings => 3,
|
||||
_ => 0
|
||||
};
|
||||
_isUpdatingSelection = false;
|
||||
|
||||
@@ -14,6 +14,8 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
|
||||
public DataTemplate MergedAccountMoreExpansionItemTemplate { get; set; } = null!;
|
||||
public DataTemplate FolderMenuTemplate { get; set; } = null!;
|
||||
public DataTemplate SettingsItemTemplate { get; set; } = null!;
|
||||
public DataTemplate SettingsShellPageItemTemplate { get; set; } = null!;
|
||||
public DataTemplate SettingsShellSectionItemTemplate { get; set; } = null!;
|
||||
public DataTemplate StoreUpdateItemTemplate { get; set; } = null!;
|
||||
public DataTemplate MoreItemsFolderTemplate { get; set; } = null!;
|
||||
public DataTemplate RatingItemTemplate { get; set; } = null!;
|
||||
@@ -38,6 +40,10 @@ public partial class NavigationMenuTemplateSelector : DataTemplateSelector
|
||||
return ContactsMenuItemTemplate;
|
||||
else if (item is SettingsItem)
|
||||
return SettingsItemTemplate;
|
||||
else if (item is SettingsShellPageMenuItem)
|
||||
return SettingsShellPageItemTemplate;
|
||||
else if (item is SettingsShellSectionMenuItem)
|
||||
return SettingsShellSectionItemTemplate;
|
||||
else if (item is StoreUpdateMenuItem)
|
||||
return StoreUpdateItemTemplate;
|
||||
else if (item is SeperatorItem)
|
||||
|
||||
@@ -8,6 +8,7 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Settings;
|
||||
using Wino.Helpers;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.ViewModels.Messages;
|
||||
@@ -66,6 +67,32 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
WinoPage.ContactsPage
|
||||
];
|
||||
|
||||
private static readonly WinoPage[] SettingsOnlyPages =
|
||||
[
|
||||
WinoPage.SettingsPage,
|
||||
WinoPage.SettingOptionsPage,
|
||||
WinoPage.ManageAccountsPage,
|
||||
WinoPage.AccountManagementPage,
|
||||
WinoPage.AccountDetailsPage,
|
||||
WinoPage.MergedAccountDetailsPage,
|
||||
WinoPage.SignatureManagementPage,
|
||||
WinoPage.AboutPage,
|
||||
WinoPage.PersonalizationPage,
|
||||
WinoPage.MessageListPage,
|
||||
WinoPage.ReadComposePanePage,
|
||||
WinoPage.LanguageTimePage,
|
||||
WinoPage.AppPreferencesPage,
|
||||
WinoPage.AliasManagementPage,
|
||||
WinoPage.ImapCalDavSettingsPage,
|
||||
WinoPage.KeyboardShortcutsPage,
|
||||
WinoPage.SignatureAndEncryptionPage,
|
||||
WinoPage.EmailTemplatesPage,
|
||||
WinoPage.CreateEmailTemplatePage,
|
||||
WinoPage.StoragePage,
|
||||
WinoPage.CalendarSettingsPage,
|
||||
WinoPage.CalendarAccountSettingsPage
|
||||
];
|
||||
|
||||
public NavigationService(IStatePersistanceService statePersistanceService, IDispatcher dispatcher, IWinoWindowManager windowManager)
|
||||
{
|
||||
_statePersistanceService = statePersistanceService;
|
||||
@@ -186,7 +213,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
public bool ChangeApplicationMode(WinoApplicationMode mode)
|
||||
=> ExecuteOnNavigationThread(() => ChangeApplicationModeInternal(mode));
|
||||
|
||||
private bool ChangeApplicationModeInternal(WinoApplicationMode mode)
|
||||
private bool ChangeApplicationModeInternal(WinoApplicationMode mode, object? activationParameter = null)
|
||||
{
|
||||
var coreFrame = GetCoreFrameInternal(NavigationReferenceFrame.ShellFrame);
|
||||
|
||||
@@ -217,7 +244,8 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
{
|
||||
shell.ActivateMode(mode, new ShellModeActivationContext
|
||||
{
|
||||
IsInitialActivation = isInitialShellNavigation
|
||||
IsInitialActivation = isInitialShellNavigation,
|
||||
Parameter = activationParameter
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@@ -237,9 +265,15 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
NavigationReferenceFrame frame = NavigationReferenceFrame.InnerShellFrame,
|
||||
NavigationTransitionType transition = NavigationTransitionType.None)
|
||||
{
|
||||
if (page is WinoPage.ManageAccountsPage or WinoPage.AccountManagementPage)
|
||||
if (TryGetSettingsActivationTarget(page, parameter, out var settingsTarget))
|
||||
{
|
||||
return NavigateInternal(WinoPage.SettingsPage, WinoPage.ManageAccountsPage, frame, transition);
|
||||
if (_statePersistanceService.ApplicationMode != WinoApplicationMode.Settings)
|
||||
{
|
||||
return ChangeApplicationModeInternal(WinoApplicationMode.Settings, settingsTarget);
|
||||
}
|
||||
|
||||
page = WinoPage.SettingsPage;
|
||||
parameter = settingsTarget;
|
||||
}
|
||||
|
||||
var pageType = GetPageType(page);
|
||||
@@ -372,12 +406,16 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
private static bool IsContactsOnlyPage(WinoPage page)
|
||||
=> ContactsOnlyPages.Contains(page);
|
||||
|
||||
private static bool IsSettingsOnlyPage(WinoPage page)
|
||||
=> SettingsOnlyPages.Contains(page);
|
||||
|
||||
private static bool IsPageAllowedInMode(WinoApplicationMode mode, WinoPage page)
|
||||
=> mode switch
|
||||
{
|
||||
WinoApplicationMode.Mail => !IsCalendarOnlyPage(page) && !IsContactsOnlyPage(page),
|
||||
WinoApplicationMode.Calendar => !IsMailOnlyPage(page) && !IsContactsOnlyPage(page),
|
||||
WinoApplicationMode.Contacts => !IsMailOnlyPage(page) && !IsCalendarOnlyPage(page),
|
||||
WinoApplicationMode.Mail => !IsCalendarOnlyPage(page) && !IsContactsOnlyPage(page) && !IsSettingsOnlyPage(page),
|
||||
WinoApplicationMode.Calendar => !IsMailOnlyPage(page) && !IsContactsOnlyPage(page) && !IsSettingsOnlyPage(page),
|
||||
WinoApplicationMode.Contacts => !IsMailOnlyPage(page) && !IsCalendarOnlyPage(page) && !IsSettingsOnlyPage(page),
|
||||
WinoApplicationMode.Settings => IsSettingsOnlyPage(page),
|
||||
_ => true
|
||||
};
|
||||
|
||||
@@ -386,6 +424,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
{
|
||||
WinoApplicationMode.Calendar => "Wino Calendar",
|
||||
WinoApplicationMode.Contacts => "Wino Contacts",
|
||||
WinoApplicationMode.Settings => "Wino Settings",
|
||||
_ => "Wino Mail"
|
||||
};
|
||||
|
||||
@@ -406,10 +445,28 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
{
|
||||
WinoApplicationMode.Mail => targetMode == WinoApplicationMode.Calendar,
|
||||
WinoApplicationMode.Calendar => targetMode == WinoApplicationMode.Contacts,
|
||||
WinoApplicationMode.Contacts => targetMode == WinoApplicationMode.Mail,
|
||||
WinoApplicationMode.Contacts => targetMode == WinoApplicationMode.Settings,
|
||||
WinoApplicationMode.Settings => targetMode == WinoApplicationMode.Mail,
|
||||
_ => false
|
||||
};
|
||||
|
||||
private static bool TryGetSettingsActivationTarget(WinoPage page, object? parameter, out WinoPage targetPage)
|
||||
{
|
||||
targetPage = WinoPage.SettingOptionsPage;
|
||||
|
||||
if (page == WinoPage.SettingsPage)
|
||||
{
|
||||
targetPage = parameter as WinoPage? ?? WinoPage.SettingOptionsPage;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsSettingsOnlyPage(page))
|
||||
return false;
|
||||
|
||||
targetPage = SettingsNavigationInfoProvider.GetRootPage(page);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static LoadCalendarMessage CreateLoadCalendarMessage(CalendarPageNavigationArgs args)
|
||||
{
|
||||
var targetDate = args.RequestDefaultNavigation
|
||||
|
||||
@@ -365,6 +365,7 @@
|
||||
<controls:ItemsRepeaterScrollHost HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<ScrollViewer
|
||||
x:Name="MenuItemsScrollViewer"
|
||||
VerticalAlignment="Top"
|
||||
TabNavigation="Local"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<!-- Left nav ItemsRepeater -->
|
||||
|
||||
@@ -53,6 +53,39 @@
|
||||
</coreControls:WinoNavigationViewItem.Icon>
|
||||
</coreControls:WinoNavigationViewItem>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="SettingsShellPageItemTemplate" x:DataType="menu:SettingsShellPageMenuItem">
|
||||
<coreControls:WinoNavigationViewItem
|
||||
Content="{x:Bind Title}"
|
||||
DataContext="{x:Bind}">
|
||||
<muxc:NavigationViewItem.Icon>
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="{x:Bind Glyph}" />
|
||||
</muxc:NavigationViewItem.Icon>
|
||||
</coreControls:WinoNavigationViewItem>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="SettingsShellSectionItemTemplate" x:DataType="menu:SettingsShellSectionMenuItem">
|
||||
<coreControls:WinoNavigationViewItem
|
||||
Margin="0,10,0,2"
|
||||
HorizontalContentAlignment="Center"
|
||||
DataContext="{x:Bind}"
|
||||
IsEnabled="False"
|
||||
SelectsOnInvoked="False">
|
||||
<muxc:NavigationViewItem.Icon>
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Glyph="{x:Bind Glyph}" />
|
||||
</muxc:NavigationViewItem.Icon>
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind Title}"
|
||||
TextWrapping="NoWrap" />
|
||||
</coreControls:WinoNavigationViewItem>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Store Update Item -->
|
||||
<DataTemplate x:Key="StoreUpdateItemTemplate" x:DataType="menu:StoreUpdateMenuItem">
|
||||
<coreControls:WinoNavigationViewItem Content="{x:Bind domain:Translator.MenuUpdateAvailable}" DataContext="{x:Bind}">
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.MenuItems;
|
||||
using Wino.Core.Domain.Models;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Settings;
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
|
||||
namespace Wino.Mail.WinUI.ViewModels;
|
||||
|
||||
public partial class SettingsShellClient(INavigationService navigationService) :
|
||||
CoreBaseViewModel,
|
||||
IShellClient,
|
||||
IRecipient<ActiveSettingsPageChanged>,
|
||||
IRecipient<LanguageChanged>
|
||||
{
|
||||
public WinoApplicationMode Mode => WinoApplicationMode.Settings;
|
||||
public MenuItemCollection? MenuItems { get; private set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial object? SelectedMenuItem { get; set; } = null;
|
||||
|
||||
public bool HandlesNavigationSelection => true;
|
||||
|
||||
protected override void OnDispatcherAssigned()
|
||||
{
|
||||
base.OnDispatcherAssigned();
|
||||
MenuItems ??= new MenuItemCollection(Dispatcher);
|
||||
RebuildMenuItems();
|
||||
}
|
||||
|
||||
public void Activate(ShellModeActivationContext activationContext)
|
||||
{
|
||||
RebuildMenuItems();
|
||||
|
||||
var targetPage = activationContext.Parameter as WinoPage? ?? WinoPage.SettingOptionsPage;
|
||||
SetSelectedRootPage(SettingsNavigationInfoProvider.GetRootPage(targetPage));
|
||||
OnNavigatedTo(NavigationMode.New, activationContext);
|
||||
|
||||
navigationService.Navigate(WinoPage.SettingsPage, targetPage, NavigationReferenceFrame.InnerShellFrame);
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
OnNavigatedFrom(NavigationMode.New, null!);
|
||||
}
|
||||
|
||||
public Task HandleNavigationItemInvokedAsync(IMenuItem? menuItem)
|
||||
{
|
||||
if (menuItem is not SettingsShellPageMenuItem settingsMenuItem)
|
||||
return Task.CompletedTask;
|
||||
|
||||
var currentPage = (SelectedMenuItem as SettingsShellPageMenuItem)?.PageType;
|
||||
if (currentPage == settingsMenuItem.PageType && settingsMenuItem.PageType != WinoPage.SettingOptionsPage)
|
||||
return Task.CompletedTask;
|
||||
|
||||
SetSelectedRootPage(settingsMenuItem.PageType);
|
||||
Messenger.Send(new SettingsRootNavigationRequested(settingsMenuItem.PageType));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task HandleNavigationSelectionChangedAsync(IMenuItem? menuItem)
|
||||
{
|
||||
if (menuItem is not SettingsShellPageMenuItem settingsMenuItem)
|
||||
return Task.CompletedTask;
|
||||
|
||||
if ((SelectedMenuItem as SettingsShellPageMenuItem)?.PageType == settingsMenuItem.PageType)
|
||||
return Task.CompletedTask;
|
||||
|
||||
SetSelectedRootPage(settingsMenuItem.PageType);
|
||||
Messenger.Send(new SettingsRootNavigationRequested(settingsMenuItem.PageType));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task KeyboardShortcutHook(KeyboardShortcutTriggerDetails args) => Task.CompletedTask;
|
||||
|
||||
public void Receive(ActiveSettingsPageChanged message)
|
||||
{
|
||||
SetSelectedRootPage(message.RootPage);
|
||||
}
|
||||
|
||||
public void Receive(LanguageChanged message)
|
||||
{
|
||||
var selectedPage = (SelectedMenuItem as SettingsShellPageMenuItem)?.PageType ?? WinoPage.SettingOptionsPage;
|
||||
RebuildMenuItems();
|
||||
SetSelectedRootPage(selectedPage);
|
||||
}
|
||||
|
||||
private void RebuildMenuItems()
|
||||
{
|
||||
if (MenuItems == null)
|
||||
return;
|
||||
|
||||
var selectedPage = (SelectedMenuItem as SettingsShellPageMenuItem)?.PageType ?? WinoPage.SettingOptionsPage;
|
||||
|
||||
MenuItems.Clear();
|
||||
|
||||
foreach (var item in SettingsNavigationInfoProvider.GetNavigationItems())
|
||||
{
|
||||
if (item.IsSeparator)
|
||||
{
|
||||
MenuItems.Add(new SettingsShellSectionMenuItem(item.Title, item.Glyph));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!item.PageType.HasValue)
|
||||
continue;
|
||||
|
||||
MenuItems.Add(new SettingsShellPageMenuItem(item.PageType.Value, item.Title, item.Description, item.Glyph));
|
||||
}
|
||||
|
||||
SetSelectedRootPage(selectedPage);
|
||||
}
|
||||
|
||||
private void SetSelectedRootPage(WinoPage pageType)
|
||||
{
|
||||
if (MenuItems == null)
|
||||
return;
|
||||
|
||||
var rootPage = SettingsNavigationInfoProvider.GetRootPage(pageType);
|
||||
var selectedItem = MenuItems.OfType<SettingsShellPageMenuItem>()
|
||||
.FirstOrDefault(item => item.PageType == rootPage);
|
||||
|
||||
if (ReferenceEquals(SelectedMenuItem, selectedItem))
|
||||
return;
|
||||
|
||||
SelectedMenuItem = selectedItem;
|
||||
}
|
||||
|
||||
protected override void RegisterRecipients()
|
||||
{
|
||||
base.RegisterRecipients();
|
||||
Messenger.Register<ActiveSettingsPageChanged>(this);
|
||||
Messenger.Register<LanguageChanged>(this);
|
||||
}
|
||||
|
||||
protected override void UnregisterRecipients()
|
||||
{
|
||||
base.UnregisterRecipients();
|
||||
Messenger.Unregister<ActiveSettingsPageChanged>(this);
|
||||
Messenger.Unregister<LanguageChanged>(this);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ public sealed class WinoAppShellViewModel : CoreBaseViewModel, IShellViewModel
|
||||
OnPropertyChanged(nameof(IsMailMode));
|
||||
OnPropertyChanged(nameof(IsCalendarMode));
|
||||
OnPropertyChanged(nameof(IsContactsMode));
|
||||
OnPropertyChanged(nameof(IsSettingsMode));
|
||||
OnPropertyChanged(nameof(SelectedMenuItem));
|
||||
}
|
||||
}
|
||||
@@ -63,6 +64,7 @@ public sealed class WinoAppShellViewModel : CoreBaseViewModel, IShellViewModel
|
||||
public bool IsMailMode => CurrentMode == WinoApplicationMode.Mail;
|
||||
public bool IsCalendarMode => CurrentMode == WinoApplicationMode.Calendar;
|
||||
public bool IsContactsMode => CurrentMode == WinoApplicationMode.Contacts;
|
||||
public bool IsSettingsMode => CurrentMode == WinoApplicationMode.Settings;
|
||||
public MenuItemCollection? CurrentMenuItems => CurrentClient.MenuItems;
|
||||
|
||||
public object? SelectedMenuItem
|
||||
|
||||
@@ -81,7 +81,10 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<controls:SettingsExpander Description="{x:Bind ViewModel.Address, Mode=OneWay}" Header="{x:Bind ViewModel.AccountName, Mode=OneWay}">
|
||||
<controls:SettingsExpander
|
||||
Description="{x:Bind ViewModel.Address, Mode=OneWay}"
|
||||
Header="{x:Bind ViewModel.AccountName, Mode=OneWay}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.HeaderIcon>
|
||||
<BitmapIcon ShowAsMonochrome="False" UriSource="{x:Bind ViewModel.ProviderIconPath, Mode=OneWay}" />
|
||||
</controls:SettingsExpander.HeaderIcon>
|
||||
|
||||
@@ -9,18 +9,17 @@
|
||||
xmlns:enums="using:Wino.Core.Domain.Enums"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="root"
|
||||
Title="{x:Bind domain:Translator.SettingsOptions_Title}"
|
||||
Title="{x:Bind domain:Translator.SettingsHome_Title}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ScrollViewer Padding="0,0,16,0" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="0,8,0,24" Spacing="4">
|
||||
<StackPanel Margin="0,8,0,24" Spacing="12">
|
||||
<StackPanel.ChildrenTransitions>
|
||||
<TransitionCollection>
|
||||
<EntranceThemeTransition FromVerticalOffset="50" IsStaggeringEnabled="True" />
|
||||
</TransitionCollection>
|
||||
</StackPanel.ChildrenTransitions>
|
||||
|
||||
<!-- Hero Banner - Windows 11 style -->
|
||||
<Grid
|
||||
Margin="0,0,0,12"
|
||||
Padding="24,28"
|
||||
@@ -33,8 +32,6 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
<!-- App Info -->
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
@@ -43,6 +40,7 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
@@ -120,7 +118,6 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- Account Management Card -->
|
||||
<controls:SettingsCard
|
||||
Margin="0,0,0,12"
|
||||
Click="SettingOptionClicked"
|
||||
@@ -141,134 +138,6 @@
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- General Section -->
|
||||
<TextBlock
|
||||
Margin="1,8,0,4"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.SettingsOptions_GeneralSection}" />
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsAppPreferences_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsAppPreferences_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.AppPreferencesPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsLanguageTime_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsLanguageTime_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.LanguageTimePage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsPersonalization_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsPersonalization_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.PersonalizationPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsAbout_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsAbout_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.AboutPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Mail Section -->
|
||||
<TextBlock
|
||||
Margin="1,16,0,4"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.SettingsOptions_MailSection}" />
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.Settings_KeyboardShortcuts_Description}"
|
||||
Header="{x:Bind domain:Translator.Settings_KeyboardShortcuts_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.KeyboardShortcutsPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsMessageList_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsMessageList_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.MessageListPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsReadComposePane_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsReadComposePane_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.ReadComposePanePage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsSignatureAndEncryption_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsSignatureAndEncryption_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.SignatureAndEncryptionPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsStorage_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsStorage_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.StoragePage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Calendar Section -->
|
||||
<TextBlock
|
||||
Margin="1,16,0,4"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.SettingsOptions_CalendarSection}" />
|
||||
|
||||
<controls:SettingsCard
|
||||
Click="SettingOptionClicked"
|
||||
Description="{x:Bind domain:Translator.SettingsCalendarSettings_Description}"
|
||||
Header="{x:Bind domain:Translator.SettingsCalendarSettings_Title}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind enums:WinoPage.CalendarSettingsPage}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<FontIcon Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Glyph="" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</controls:SettingsCard>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</abstract:SettingOptionsPageAbstract>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
RowSpacing="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
@@ -43,7 +44,15 @@
|
||||
</winuiControls:BreadcrumbBar.ItemTemplate>
|
||||
</winuiControls:BreadcrumbBar>
|
||||
|
||||
<Frame x:Name="SettingsFrame" Grid.Row="1" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Margin="0,-4,0,4"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentDescription, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
|
||||
<Frame x:Name="SettingsFrame" Grid.Row="2" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</abstract:SettingsPageAbstract>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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;
|
||||
@@ -17,6 +19,7 @@ namespace Wino.Views;
|
||||
public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
IRecipient<BreadcrumbNavigationRequested>,
|
||||
IRecipient<BackBreadcrumNavigationRequested>,
|
||||
IRecipient<SettingsRootNavigationRequested>,
|
||||
IRecipient<MergedInboxRenamed>,
|
||||
IRecipient<AccountUpdatedMessage>
|
||||
{
|
||||
@@ -34,39 +37,9 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
// Register for frame navigation events to track back button visibility
|
||||
SettingsFrame.Navigated -= SettingsFrameNavigated;
|
||||
SettingsFrame.Navigated += SettingsFrameNavigated;
|
||||
PageHistory.Clear();
|
||||
SettingsFrame.BackStack.Clear();
|
||||
SettingsFrame.ForwardStack.Clear();
|
||||
|
||||
SettingsFrame.Navigate(typeof(SettingOptionsPage), null, new SuppressNavigationTransitionInfo());
|
||||
|
||||
var initialRequest = new BreadcrumbNavigationRequested(Translator.MenuSettings, WinoPage.SettingOptionsPage);
|
||||
PageHistory.Add(new BreadcrumbNavigationItemViewModel(initialRequest, true, backStackDepth: SettingsFrame.BackStack.Count + 1));
|
||||
|
||||
if (e.Parameter is WinoPage parameterPage)
|
||||
{
|
||||
switch (parameterPage)
|
||||
{
|
||||
case WinoPage.AppPreferencesPage:
|
||||
NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsAppPreferences_Title, WinoPage.AppPreferencesPage));
|
||||
break;
|
||||
case WinoPage.PersonalizationPage:
|
||||
NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsPersonalization_Title, WinoPage.PersonalizationPage));
|
||||
break;
|
||||
case WinoPage.StoragePage:
|
||||
NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsStorage_Title, WinoPage.StoragePage));
|
||||
break;
|
||||
case WinoPage.EmailTemplatesPage:
|
||||
NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsEmailTemplates_Title, WinoPage.EmailTemplatesPage));
|
||||
break;
|
||||
case WinoPage.ManageAccountsPage:
|
||||
case WinoPage.AccountManagementPage:
|
||||
NavigateBreadcrumb(new BreadcrumbNavigationRequested(Translator.SettingsManageAccountSettings_Title, WinoPage.ManageAccountsPage));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateWindowTitle();
|
||||
var initialPage = e.Parameter as WinoPage? ?? WinoPage.SettingOptionsPage;
|
||||
NavigateToRootPage(initialPage);
|
||||
}
|
||||
|
||||
public override void OnLanguageChanged()
|
||||
@@ -88,6 +61,7 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
manageAccountsEntry.Title = Translator.SettingsManageAccountSettings_Title;
|
||||
}
|
||||
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
|
||||
@@ -108,6 +82,7 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
|
||||
WeakReferenceMessenger.Default.Register<BreadcrumbNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<BackBreadcrumNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<SettingsRootNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<MergedInboxRenamed>(this);
|
||||
WeakReferenceMessenger.Default.Register<AccountUpdatedMessage>(this);
|
||||
}
|
||||
@@ -118,6 +93,7 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
|
||||
WeakReferenceMessenger.Default.Unregister<BreadcrumbNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<BackBreadcrumNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<SettingsRootNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<MergedInboxRenamed>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<AccountUpdatedMessage>(this);
|
||||
}
|
||||
@@ -129,8 +105,8 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
|
||||
private void SettingsFrameNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
// Update back button visibility based on whether we can go back within the frame
|
||||
ViewModel.StatePersistenceService.IsSettingsNavigating = SettingsFrame.CanGoBack;
|
||||
UpdateBackNavigationState();
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
}
|
||||
|
||||
private void GoBackFrame(Core.Domain.Enums.NavigationTransitionEffect slideEffect)
|
||||
@@ -138,7 +114,8 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
if (!BreadcrumbNavigationHelper.GoBack(SettingsFrame, PageHistory, slideEffect))
|
||||
return;
|
||||
|
||||
ViewModel.StatePersistenceService.IsSettingsNavigating = SettingsFrame.CanGoBack;
|
||||
UpdateBackNavigationState();
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
|
||||
@@ -147,7 +124,8 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
if (!BreadcrumbNavigationHelper.NavigateTo(SettingsFrame, PageHistory, args.Index))
|
||||
return;
|
||||
|
||||
ViewModel.StatePersistenceService.IsSettingsNavigating = SettingsFrame.CanGoBack;
|
||||
UpdateBackNavigationState();
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
|
||||
@@ -156,6 +134,15 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
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);
|
||||
@@ -166,6 +153,7 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
activePage.Title = message.Account.Name;
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
UpdateWindowTitle();
|
||||
});
|
||||
}
|
||||
@@ -180,6 +168,7 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
activePage.Title = message.NewName;
|
||||
_ = RefreshCurrentPageStateAsync();
|
||||
UpdateWindowTitle();
|
||||
});
|
||||
}
|
||||
@@ -189,9 +178,43 @@ public sealed partial class SettingsPage : SettingsPageAbstract,
|
||||
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();
|
||||
}
|
||||
|
||||
private void UpdateBackNavigationState()
|
||||
{
|
||||
ViewModel.StatePersistenceService.IsSettingsNavigating = 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;
|
||||
|
||||
@@ -425,6 +425,8 @@
|
||||
NewMailTemplate="{StaticResource CreateNewMailTemplate}"
|
||||
RatingItemTemplate="{StaticResource RatingItemTemplate}"
|
||||
SeperatorTemplate="{StaticResource SeperatorTemplate}"
|
||||
SettingsShellPageItemTemplate="{StaticResource SettingsShellPageItemTemplate}"
|
||||
SettingsShellSectionItemTemplate="{StaticResource SettingsShellSectionItemTemplate}"
|
||||
StoreUpdateItemTemplate="{StaticResource StoreUpdateItemTemplate}" />
|
||||
|
||||
<Style
|
||||
|
||||
@@ -50,6 +50,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
private const string StateDefaultShellContent = "DefaultShellContentState";
|
||||
private const string StateEventDetailsContent = "EventDetailsContentState";
|
||||
private WinoApplicationMode? _activeMode;
|
||||
private bool _isSyncingNavigationViewSelection;
|
||||
|
||||
public WinoAppShell()
|
||||
{
|
||||
@@ -59,9 +60,11 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
ViewModel.MailClient.Dispatcher = pageDispatcher;
|
||||
ViewModel.CalendarClient.Dispatcher = pageDispatcher;
|
||||
ViewModel.GetClient(WinoApplicationMode.Contacts).Dispatcher = pageDispatcher;
|
||||
ViewModel.GetClient(WinoApplicationMode.Settings).Dispatcher = pageDispatcher;
|
||||
|
||||
ViewModel.MailClient.PropertyChanged += MailClientPropertyChanged;
|
||||
ViewModel.CalendarClient.PropertyChanged += CalendarClientPropertyChanged;
|
||||
ViewModel.PropertyChanged += ViewModelPropertyChanged;
|
||||
ViewModel.StatePersistenceService.StatePropertyChanged += StatePersistenceServiceChanged;
|
||||
CalendarTypeSelector.RegisterPropertyChangedCallback(WinoCalendarTypeSelectorControl.SelectedTypeProperty, CalendarTypeSelectorSelectedTypeChanged);
|
||||
|
||||
@@ -151,6 +154,10 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
{
|
||||
ViewModel.CurrentClient.Deactivate();
|
||||
}
|
||||
else if (_activeMode == WinoApplicationMode.Settings)
|
||||
{
|
||||
ViewModel.CurrentClient.Deactivate();
|
||||
}
|
||||
|
||||
DynamicPageShellContentPresenter.Content = null;
|
||||
}
|
||||
@@ -229,12 +236,9 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
private void RefreshNavigationViewBindings(bool syncMailSelection = true)
|
||||
{
|
||||
navigationView.MenuItemsSource = ViewModel.CurrentMenuItems;
|
||||
|
||||
navigationView.SelectionChanged -= MenuSelectionChanged;
|
||||
navigationView.SelectedItem = ViewModel.CurrentClient.HandlesNavigationSelection && syncMailSelection
|
||||
SetNavigationViewSelectedItem(ViewModel.CurrentClient.HandlesNavigationSelection && syncMailSelection
|
||||
? ViewModel.SelectedMenuItem
|
||||
: null;
|
||||
navigationView.SelectionChanged += MenuSelectionChanged;
|
||||
: null);
|
||||
}
|
||||
|
||||
private void UpdateEventDetailsVisualState()
|
||||
@@ -262,6 +266,9 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
|
||||
private async void NavigationViewItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||
{
|
||||
if (_isSyncingNavigationViewSelection)
|
||||
return;
|
||||
|
||||
if (ViewModel.IsCalendarMode)
|
||||
{
|
||||
if (args.InvokedItemContainer is FrameworkElement { DataContext: IMenuItem menuItem })
|
||||
@@ -283,7 +290,13 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
|
||||
private async void MenuSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
if (!ViewModel.IsMailMode)
|
||||
if (_isSyncingNavigationViewSelection)
|
||||
return;
|
||||
|
||||
if (!ViewModel.CurrentClient.HandlesNavigationSelection)
|
||||
return;
|
||||
|
||||
if (ReferenceEquals(args.SelectedItem, ViewModel.SelectedMenuItem))
|
||||
return;
|
||||
|
||||
if (args.SelectedItem is IMenuItem invokedMenuItem)
|
||||
@@ -306,7 +319,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
{
|
||||
foundMenuItem.Expand();
|
||||
await ViewModel.MailClient.NavigateFolderAsync(foundMenuItem);
|
||||
navigationView.SelectedItem = foundMenuItem;
|
||||
SetNavigationViewSelectedItem(foundMenuItem);
|
||||
|
||||
if (message.NavigateMailItem != null)
|
||||
{
|
||||
@@ -327,7 +340,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
{
|
||||
accountFolderMenuItem.Expand();
|
||||
await ViewModel.MailClient.NavigateFolderAsync(accountFolderMenuItem);
|
||||
navigationView.SelectedItem = accountFolderMenuItem;
|
||||
SetNavigationViewSelectedItem(accountFolderMenuItem);
|
||||
WeakReferenceMessenger.Default.Send(new MailItemNavigationRequested(message.NavigateMailItem.UniqueId, ScrollToItem: true));
|
||||
}
|
||||
}
|
||||
@@ -345,9 +358,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
|
||||
ViewModel.NavigationService.Navigate(WinoPage.MailListPage, navigateFolderArgs, NavigationReferenceFrame.InnerShellFrame);
|
||||
|
||||
navigationView.SelectionChanged -= MenuSelectionChanged;
|
||||
navigationView.SelectedItem = message.BaseFolderMenuItem;
|
||||
navigationView.SelectionChanged += MenuSelectionChanged;
|
||||
SetNavigationViewSelectedItem(message.BaseFolderMenuItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -430,9 +441,7 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
{
|
||||
if (e.PropertyName == nameof(IShellClient.SelectedMenuItem) && ViewModel.IsMailMode)
|
||||
{
|
||||
navigationView.SelectionChanged -= MenuSelectionChanged;
|
||||
navigationView.SelectedItem = ViewModel.MailClient.SelectedMenuItem;
|
||||
navigationView.SelectionChanged += MenuSelectionChanged;
|
||||
SetNavigationViewSelectedItem(ViewModel.MailClient.SelectedMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,6 +476,30 @@ public sealed partial class WinoAppShell : Views.Abstract.WinoAppShellAbstract,
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName != nameof(ViewModel.SelectedMenuItem) || !ViewModel.CurrentClient.HandlesNavigationSelection)
|
||||
return;
|
||||
|
||||
SetNavigationViewSelectedItem(ViewModel.SelectedMenuItem);
|
||||
}
|
||||
|
||||
private void SetNavigationViewSelectedItem(object? item)
|
||||
{
|
||||
if (ReferenceEquals(navigationView.SelectedItem, item))
|
||||
return;
|
||||
|
||||
_isSyncingNavigationViewSelection = true;
|
||||
try
|
||||
{
|
||||
navigationView.SelectedItem = item;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSyncingNavigationViewSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void StatePersistenceServiceChanged(object? sender, string propertyName)
|
||||
{
|
||||
if (propertyName == nameof(IStatePersistanceService.CalendarDisplayType))
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Messaging.Client.Navigation;
|
||||
|
||||
public sealed record ActiveSettingsPageChanged(WinoPage RootPage);
|
||||
@@ -0,0 +1,5 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Messaging.Client.Navigation;
|
||||
|
||||
public sealed record SettingsRootNavigationRequested(WinoPage PageType);
|
||||
Reference in New Issue
Block a user