file scoped namespaces (#565)
This commit is contained in:
@@ -6,125 +6,124 @@ using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public partial class AboutPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public partial class AboutPageViewModel : CoreBaseViewModel
|
||||
private readonly IStoreRatingService _storeRatingService;
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
private readonly IApplicationConfiguration _appInitializerService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly ILogInitializer _logInitializer;
|
||||
|
||||
public string VersionName => _nativeAppService.GetFullAppVersion();
|
||||
public string DiscordChannelUrl => "https://discord.gg/windows-apps-hub-714581497222398064";
|
||||
public string GitHubUrl => "https://github.com/bkaankose/Wino-Mail/";
|
||||
public string PrivacyPolicyUrl => "https://www.winomail.app/support/privacy";
|
||||
public string PaypalUrl => "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US";
|
||||
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
|
||||
public AboutPageViewModel(IStoreRatingService storeRatingService,
|
||||
IMailDialogService dialogService,
|
||||
INativeAppService nativeAppService,
|
||||
IPreferencesService preferencesService,
|
||||
IApplicationConfiguration appInitializerService,
|
||||
IClipboardService clipboardService,
|
||||
IFileService fileService,
|
||||
ILogInitializer logInitializer)
|
||||
{
|
||||
private readonly IStoreRatingService _storeRatingService;
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
private readonly IApplicationConfiguration _appInitializerService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly ILogInitializer _logInitializer;
|
||||
_storeRatingService = storeRatingService;
|
||||
_dialogService = dialogService;
|
||||
_nativeAppService = nativeAppService;
|
||||
_logInitializer = logInitializer;
|
||||
_appInitializerService = appInitializerService;
|
||||
_clipboardService = clipboardService;
|
||||
_fileService = fileService;
|
||||
|
||||
public string VersionName => _nativeAppService.GetFullAppVersion();
|
||||
public string DiscordChannelUrl => "https://discord.gg/windows-apps-hub-714581497222398064";
|
||||
public string GitHubUrl => "https://github.com/bkaankose/Wino-Mail/";
|
||||
public string PrivacyPolicyUrl => "https://www.winomail.app/support/privacy";
|
||||
public string PaypalUrl => "https://paypal.me/bkaankose?country.x=PL&locale.x=en_US";
|
||||
PreferencesService = preferencesService;
|
||||
}
|
||||
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
protected override void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
|
||||
public AboutPageViewModel(IStoreRatingService storeRatingService,
|
||||
IMailDialogService dialogService,
|
||||
INativeAppService nativeAppService,
|
||||
IPreferencesService preferencesService,
|
||||
IApplicationConfiguration appInitializerService,
|
||||
IClipboardService clipboardService,
|
||||
IFileService fileService,
|
||||
ILogInitializer logInitializer)
|
||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||
PreferencesService.PreferenceChanged += PreferencesChanged;
|
||||
}
|
||||
|
||||
protected override void OnDeactivated()
|
||||
{
|
||||
base.OnDeactivated();
|
||||
|
||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||
}
|
||||
|
||||
private void PreferencesChanged(object sender, string e)
|
||||
{
|
||||
if (e == nameof(PreferencesService.IsLoggingEnabled))
|
||||
{
|
||||
_storeRatingService = storeRatingService;
|
||||
_dialogService = dialogService;
|
||||
_nativeAppService = nativeAppService;
|
||||
_logInitializer = logInitializer;
|
||||
_appInitializerService = appInitializerService;
|
||||
_clipboardService = clipboardService;
|
||||
_fileService = fileService;
|
||||
|
||||
PreferencesService = preferencesService;
|
||||
_logInitializer.RefreshLoggingLevel();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivated()
|
||||
[RelayCommand]
|
||||
private async Task CopyDiagnosticId()
|
||||
{
|
||||
try
|
||||
{
|
||||
base.OnActivated();
|
||||
|
||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||
PreferencesService.PreferenceChanged += PreferencesChanged;
|
||||
await _clipboardService.CopyClipboardAsync(PreferencesService.DiagnosticId);
|
||||
_dialogService.InfoBarMessage(Translator.Buttons_Copy, string.Format(Translator.ClipboardTextCopied_Message, "Id"), InfoBarMessageType.Success);
|
||||
}
|
||||
|
||||
protected override void OnDeactivated()
|
||||
catch (Exception ex)
|
||||
{
|
||||
base.OnDeactivated();
|
||||
|
||||
PreferencesService.PreferenceChanged -= PreferencesChanged;
|
||||
_dialogService.InfoBarMessage(Translator.GeneralTitle_Error, string.Format(Translator.ClipboardTextCopyFailed_Message, "Id"), InfoBarMessageType.Error);
|
||||
Log.Error(ex, "Failed to copy diagnostic id to clipboard.");
|
||||
}
|
||||
}
|
||||
|
||||
private void PreferencesChanged(object sender, string e)
|
||||
[RelayCommand]
|
||||
private async Task ShareWinoLogAsync()
|
||||
{
|
||||
var appDataFolder = _appInitializerService.ApplicationDataFolderPath;
|
||||
|
||||
var selectedFolderPath = await _dialogService.PickWindowsFolderAsync();
|
||||
|
||||
if (string.IsNullOrEmpty(selectedFolderPath)) return;
|
||||
|
||||
var areLogsSaved = await _fileService.SaveLogsToFolderAsync(appDataFolder, selectedFolderPath).ConfigureAwait(false);
|
||||
|
||||
if (areLogsSaved)
|
||||
{
|
||||
if (e == nameof(PreferencesService.IsLoggingEnabled))
|
||||
{
|
||||
_logInitializer.RefreshLoggingLevel();
|
||||
}
|
||||
_dialogService.InfoBarMessage(Translator.Info_LogsSavedTitle, string.Format(Translator.Info_LogsSavedMessage, Constants.LogArchiveFileName), InfoBarMessageType.Success);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task CopyDiagnosticId()
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
await _clipboardService.CopyClipboardAsync(PreferencesService.DiagnosticId);
|
||||
_dialogService.InfoBarMessage(Translator.Buttons_Copy, string.Format(Translator.ClipboardTextCopied_Message, "Id"), InfoBarMessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dialogService.InfoBarMessage(Translator.GeneralTitle_Error, string.Format(Translator.ClipboardTextCopyFailed_Message, "Id"), InfoBarMessageType.Error);
|
||||
Log.Error(ex, "Failed to copy diagnostic id to clipboard.");
|
||||
}
|
||||
_dialogService.InfoBarMessage(Translator.Info_LogsNotFoundTitle, Translator.Info_LogsNotFoundMessage, InfoBarMessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ShareWinoLogAsync()
|
||||
[RelayCommand]
|
||||
private async Task Navigate(object url)
|
||||
{
|
||||
if (url is string stringUrl)
|
||||
{
|
||||
var appDataFolder = _appInitializerService.ApplicationDataFolderPath;
|
||||
|
||||
var selectedFolderPath = await _dialogService.PickWindowsFolderAsync();
|
||||
|
||||
if (string.IsNullOrEmpty(selectedFolderPath)) return;
|
||||
|
||||
var areLogsSaved = await _fileService.SaveLogsToFolderAsync(appDataFolder, selectedFolderPath).ConfigureAwait(false);
|
||||
|
||||
if (areLogsSaved)
|
||||
{
|
||||
_dialogService.InfoBarMessage(Translator.Info_LogsSavedTitle, string.Format(Translator.Info_LogsSavedMessage, Constants.LogArchiveFileName), InfoBarMessageType.Success);
|
||||
}
|
||||
if (stringUrl == "Store")
|
||||
await ShowRateDialogAsync();
|
||||
else
|
||||
{
|
||||
_dialogService.InfoBarMessage(Translator.Info_LogsNotFoundTitle, Translator.Info_LogsNotFoundMessage, InfoBarMessageType.Error);
|
||||
// Discord disclaimer message about server.
|
||||
if (stringUrl == DiscordChannelUrl)
|
||||
await _dialogService.ShowMessageAsync(Translator.DiscordChannelDisclaimerMessage,
|
||||
Translator.DiscordChannelDisclaimerTitle,
|
||||
WinoCustomMessageDialogIcon.Warning);
|
||||
|
||||
await _nativeAppService.LaunchUriAsync(new Uri(stringUrl));
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task Navigate(object url)
|
||||
{
|
||||
if (url is string stringUrl)
|
||||
{
|
||||
if (stringUrl == "Store")
|
||||
await ShowRateDialogAsync();
|
||||
else
|
||||
{
|
||||
// Discord disclaimer message about server.
|
||||
if (stringUrl == DiscordChannelUrl)
|
||||
await _dialogService.ShowMessageAsync(Translator.DiscordChannelDisclaimerMessage,
|
||||
Translator.DiscordChannelDisclaimerTitle,
|
||||
WinoCustomMessageDialogIcon.Warning);
|
||||
|
||||
await _nativeAppService.LaunchUriAsync(new Uri(stringUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync();
|
||||
}
|
||||
|
||||
private Task ShowRateDialogAsync() => _storeRatingService.LaunchStorePageForReviewAsync();
|
||||
}
|
||||
|
||||
@@ -13,126 +13,125 @@ using Wino.Core.Domain.Models.Store;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public abstract partial class AccountManagementPageViewModelBase : CoreBaseViewModel
|
||||
{
|
||||
public abstract partial class AccountManagementPageViewModelBase : CoreBaseViewModel
|
||||
public ObservableCollection<IAccountProviderDetailViewModel> Accounts { get; set; } = [];
|
||||
|
||||
public bool IsPurchasePanelVisible => !HasUnlimitedAccountProduct;
|
||||
public bool IsAccountCreationAlmostOnLimit => Accounts != null && Accounts.Count == FREE_ACCOUNT_COUNT - 1;
|
||||
public bool HasAccountsDefined => Accounts != null && Accounts.Any();
|
||||
public bool CanReorderAccounts => Accounts?.Sum(a => a.HoldingAccountCount) > 1;
|
||||
|
||||
public string UsedAccountsString => string.Format(Translator.WinoUpgradeRemainingAccountsMessage, Accounts.Count, FREE_ACCOUNT_COUNT);
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsPurchasePanelVisible))]
|
||||
private bool hasUnlimitedAccountProduct;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsAccountCreationAlmostOnLimit))]
|
||||
[NotifyPropertyChangedFor(nameof(IsPurchasePanelVisible))]
|
||||
private bool isAccountCreationBlocked;
|
||||
|
||||
[ObservableProperty]
|
||||
private IAccountProviderDetailViewModel _startupAccount;
|
||||
|
||||
public int FREE_ACCOUNT_COUNT { get; } = 3;
|
||||
protected IDialogServiceBase DialogService { get; }
|
||||
protected IWinoServerConnectionManager WinoServerConnectionManager { get; }
|
||||
protected INavigationService NavigationService { get; }
|
||||
protected IAccountService AccountService { get; }
|
||||
protected IProviderService ProviderService { get; }
|
||||
protected IStoreManagementService StoreManagementService { get; }
|
||||
protected IAuthenticationProvider AuthenticationProvider { get; }
|
||||
protected IPreferencesService PreferencesService { get; }
|
||||
|
||||
public AccountManagementPageViewModelBase(IDialogServiceBase dialogService,
|
||||
IWinoServerConnectionManager winoServerConnectionManager,
|
||||
INavigationService navigationService,
|
||||
IAccountService accountService,
|
||||
IProviderService providerService,
|
||||
IStoreManagementService storeManagementService,
|
||||
IAuthenticationProvider authenticationProvider,
|
||||
IPreferencesService preferencesService)
|
||||
{
|
||||
public ObservableCollection<IAccountProviderDetailViewModel> Accounts { get; set; } = [];
|
||||
DialogService = dialogService;
|
||||
WinoServerConnectionManager = winoServerConnectionManager;
|
||||
NavigationService = navigationService;
|
||||
AccountService = accountService;
|
||||
ProviderService = providerService;
|
||||
StoreManagementService = storeManagementService;
|
||||
AuthenticationProvider = authenticationProvider;
|
||||
PreferencesService = preferencesService;
|
||||
}
|
||||
|
||||
public bool IsPurchasePanelVisible => !HasUnlimitedAccountProduct;
|
||||
public bool IsAccountCreationAlmostOnLimit => Accounts != null && Accounts.Count == FREE_ACCOUNT_COUNT - 1;
|
||||
public bool HasAccountsDefined => Accounts != null && Accounts.Any();
|
||||
public bool CanReorderAccounts => Accounts?.Sum(a => a.HoldingAccountCount) > 1;
|
||||
[RelayCommand]
|
||||
private void NavigateAccountDetails(AccountProviderDetailViewModel accountDetails)
|
||||
{
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(accountDetails.Account.Name,
|
||||
WinoPage.AccountDetailsPage,
|
||||
accountDetails.Account.Id));
|
||||
}
|
||||
|
||||
public string UsedAccountsString => string.Format(Translator.WinoUpgradeRemainingAccountsMessage, Accounts.Count, FREE_ACCOUNT_COUNT);
|
||||
[RelayCommand]
|
||||
public async Task PurchaseUnlimitedAccountAsync()
|
||||
{
|
||||
var purchaseResult = await StoreManagementService.PurchaseAsync(StoreProductType.UnlimitedAccounts);
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsPurchasePanelVisible))]
|
||||
private bool hasUnlimitedAccountProduct;
|
||||
if (purchaseResult == StorePurchaseResult.Succeeded)
|
||||
DialogService.InfoBarMessage(Translator.Info_PurchaseThankYouTitle, Translator.Info_PurchaseThankYouMessage, InfoBarMessageType.Success);
|
||||
else if (purchaseResult == StorePurchaseResult.AlreadyPurchased)
|
||||
DialogService.InfoBarMessage(Translator.Info_PurchaseExistsTitle, Translator.Info_PurchaseExistsMessage, InfoBarMessageType.Warning);
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsAccountCreationAlmostOnLimit))]
|
||||
[NotifyPropertyChangedFor(nameof(IsPurchasePanelVisible))]
|
||||
private bool isAccountCreationBlocked;
|
||||
bool shouldRefreshPurchasePanel = purchaseResult == StorePurchaseResult.Succeeded || purchaseResult == StorePurchaseResult.AlreadyPurchased;
|
||||
|
||||
[ObservableProperty]
|
||||
private IAccountProviderDetailViewModel _startupAccount;
|
||||
|
||||
public int FREE_ACCOUNT_COUNT { get; } = 3;
|
||||
protected IDialogServiceBase DialogService { get; }
|
||||
protected IWinoServerConnectionManager WinoServerConnectionManager { get; }
|
||||
protected INavigationService NavigationService { get; }
|
||||
protected IAccountService AccountService { get; }
|
||||
protected IProviderService ProviderService { get; }
|
||||
protected IStoreManagementService StoreManagementService { get; }
|
||||
protected IAuthenticationProvider AuthenticationProvider { get; }
|
||||
protected IPreferencesService PreferencesService { get; }
|
||||
|
||||
public AccountManagementPageViewModelBase(IDialogServiceBase dialogService,
|
||||
IWinoServerConnectionManager winoServerConnectionManager,
|
||||
INavigationService navigationService,
|
||||
IAccountService accountService,
|
||||
IProviderService providerService,
|
||||
IStoreManagementService storeManagementService,
|
||||
IAuthenticationProvider authenticationProvider,
|
||||
IPreferencesService preferencesService)
|
||||
if (shouldRefreshPurchasePanel)
|
||||
{
|
||||
DialogService = dialogService;
|
||||
WinoServerConnectionManager = winoServerConnectionManager;
|
||||
NavigationService = navigationService;
|
||||
AccountService = accountService;
|
||||
ProviderService = providerService;
|
||||
StoreManagementService = storeManagementService;
|
||||
AuthenticationProvider = authenticationProvider;
|
||||
PreferencesService = preferencesService;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void NavigateAccountDetails(AccountProviderDetailViewModel accountDetails)
|
||||
{
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(accountDetails.Account.Name,
|
||||
WinoPage.AccountDetailsPage,
|
||||
accountDetails.Account.Id));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async Task PurchaseUnlimitedAccountAsync()
|
||||
{
|
||||
var purchaseResult = await StoreManagementService.PurchaseAsync(StoreProductType.UnlimitedAccounts);
|
||||
|
||||
if (purchaseResult == StorePurchaseResult.Succeeded)
|
||||
DialogService.InfoBarMessage(Translator.Info_PurchaseThankYouTitle, Translator.Info_PurchaseThankYouMessage, InfoBarMessageType.Success);
|
||||
else if (purchaseResult == StorePurchaseResult.AlreadyPurchased)
|
||||
DialogService.InfoBarMessage(Translator.Info_PurchaseExistsTitle, Translator.Info_PurchaseExistsMessage, InfoBarMessageType.Warning);
|
||||
|
||||
bool shouldRefreshPurchasePanel = purchaseResult == StorePurchaseResult.Succeeded || purchaseResult == StorePurchaseResult.AlreadyPurchased;
|
||||
|
||||
if (shouldRefreshPurchasePanel)
|
||||
{
|
||||
await ManageStorePurchasesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ManageStorePurchasesAsync()
|
||||
{
|
||||
await ExecuteUIThread(async () =>
|
||||
{
|
||||
HasUnlimitedAccountProduct = await StoreManagementService.HasProductAsync(StoreProductType.UnlimitedAccounts);
|
||||
|
||||
if (!HasUnlimitedAccountProduct)
|
||||
IsAccountCreationBlocked = Accounts.Count >= FREE_ACCOUNT_COUNT;
|
||||
else
|
||||
IsAccountCreationBlocked = false;
|
||||
});
|
||||
}
|
||||
|
||||
public AccountProviderDetailViewModel GetAccountProviderDetails(MailAccount account)
|
||||
{
|
||||
var provider = ProviderService.GetProviderDetail(account.ProviderType);
|
||||
|
||||
return new AccountProviderDetailViewModel(provider, account);
|
||||
}
|
||||
|
||||
public abstract Task InitializeAccountsAsync();
|
||||
|
||||
public override void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
Accounts.CollectionChanged -= AccountsChanged;
|
||||
Accounts.CollectionChanged += AccountsChanged;
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedFrom(mode, parameters);
|
||||
|
||||
Accounts.CollectionChanged -= AccountsChanged;
|
||||
}
|
||||
|
||||
private void AccountsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(nameof(HasAccountsDefined));
|
||||
await ManageStorePurchasesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ManageStorePurchasesAsync()
|
||||
{
|
||||
await ExecuteUIThread(async () =>
|
||||
{
|
||||
HasUnlimitedAccountProduct = await StoreManagementService.HasProductAsync(StoreProductType.UnlimitedAccounts);
|
||||
|
||||
if (!HasUnlimitedAccountProduct)
|
||||
IsAccountCreationBlocked = Accounts.Count >= FREE_ACCOUNT_COUNT;
|
||||
else
|
||||
IsAccountCreationBlocked = false;
|
||||
});
|
||||
}
|
||||
|
||||
public AccountProviderDetailViewModel GetAccountProviderDetails(MailAccount account)
|
||||
{
|
||||
var provider = ProviderService.GetProviderDetail(account.ProviderType);
|
||||
|
||||
return new AccountProviderDetailViewModel(provider, account);
|
||||
}
|
||||
|
||||
public abstract Task InitializeAccountsAsync();
|
||||
|
||||
public override void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedTo(mode, parameters);
|
||||
|
||||
Accounts.CollectionChanged -= AccountsChanged;
|
||||
Accounts.CollectionChanged += AccountsChanged;
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationMode mode, object parameters)
|
||||
{
|
||||
base.OnNavigatedFrom(mode, parameters);
|
||||
|
||||
Accounts.CollectionChanged -= AccountsChanged;
|
||||
}
|
||||
|
||||
private void AccountsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(nameof(HasAccountsDefined));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
{
|
||||
public class CalendarBaseViewModel : CoreBaseViewModel, IRecipient<CalendarItemAdded>
|
||||
{
|
||||
public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem);
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { }
|
||||
}
|
||||
public class CalendarBaseViewModel : CoreBaseViewModel, IRecipient<CalendarItemAdded>
|
||||
{
|
||||
public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem);
|
||||
|
||||
protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { }
|
||||
}
|
||||
|
||||
@@ -7,49 +7,48 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
{
|
||||
public class CoreBaseViewModel : ObservableRecipient,
|
||||
INavigationAware,
|
||||
IRecipient<AccountCreatedMessage>,
|
||||
IRecipient<AccountRemovedMessage>,
|
||||
IRecipient<AccountUpdatedMessage>
|
||||
{
|
||||
private IDispatcher _dispatcher;
|
||||
public IDispatcher Dispatcher
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dispatcher;
|
||||
}
|
||||
set
|
||||
{
|
||||
_dispatcher = value;
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
OnDispatcherAssigned();
|
||||
}
|
||||
public class CoreBaseViewModel : ObservableRecipient,
|
||||
INavigationAware,
|
||||
IRecipient<AccountCreatedMessage>,
|
||||
IRecipient<AccountRemovedMessage>,
|
||||
IRecipient<AccountUpdatedMessage>
|
||||
{
|
||||
private IDispatcher _dispatcher;
|
||||
public IDispatcher Dispatcher
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dispatcher;
|
||||
}
|
||||
set
|
||||
{
|
||||
_dispatcher = value;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
OnDispatcherAssigned();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnNavigatedTo(NavigationMode mode, object parameters) { IsActive = true; }
|
||||
|
||||
public virtual void OnNavigatedFrom(NavigationMode mode, object parameters) { IsActive = false; }
|
||||
|
||||
public virtual void OnPageLoaded() { }
|
||||
|
||||
public async Task ExecuteUIThread(Action action) => await Dispatcher?.ExecuteOnUIThread(action);
|
||||
public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IUIMessage => Messenger.Send(message);
|
||||
|
||||
protected virtual void OnDispatcherAssigned() { }
|
||||
|
||||
protected virtual void OnAccountCreated(MailAccount createdAccount) { }
|
||||
protected virtual void OnAccountRemoved(MailAccount removedAccount) { }
|
||||
protected virtual void OnAccountUpdated(MailAccount updatedAccount) { }
|
||||
|
||||
void IRecipient<AccountCreatedMessage>.Receive(AccountCreatedMessage message) => OnAccountCreated(message.Account);
|
||||
void IRecipient<AccountRemovedMessage>.Receive(AccountRemovedMessage message) => OnAccountRemoved(message.Account);
|
||||
void IRecipient<AccountUpdatedMessage>.Receive(AccountUpdatedMessage message) => OnAccountUpdated(message.Account);
|
||||
}
|
||||
|
||||
public virtual void OnNavigatedTo(NavigationMode mode, object parameters) { IsActive = true; }
|
||||
|
||||
public virtual void OnNavigatedFrom(NavigationMode mode, object parameters) { IsActive = false; }
|
||||
|
||||
public virtual void OnPageLoaded() { }
|
||||
|
||||
public async Task ExecuteUIThread(Action action) => await Dispatcher?.ExecuteOnUIThread(action);
|
||||
public void ReportUIChange<TMessage>(TMessage message) where TMessage : class, IUIMessage => Messenger.Send(message);
|
||||
|
||||
protected virtual void OnDispatcherAssigned() { }
|
||||
|
||||
protected virtual void OnAccountCreated(MailAccount createdAccount) { }
|
||||
protected virtual void OnAccountRemoved(MailAccount removedAccount) { }
|
||||
protected virtual void OnAccountUpdated(MailAccount updatedAccount) { }
|
||||
|
||||
void IRecipient<AccountCreatedMessage>.Receive(AccountCreatedMessage message) => OnAccountCreated(message.Account);
|
||||
void IRecipient<AccountRemovedMessage>.Receive(AccountRemovedMessage message) => OnAccountRemoved(message.Account);
|
||||
void IRecipient<AccountUpdatedMessage>.Receive(AccountUpdatedMessage message) => OnAccountUpdated(message.Account);
|
||||
}
|
||||
|
||||
@@ -3,32 +3,31 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Data
|
||||
namespace Wino.Mail.ViewModels.Data;
|
||||
|
||||
public partial class AccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
|
||||
{
|
||||
public partial class AccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
|
||||
|
||||
[ObservableProperty]
|
||||
private MailAccount account;
|
||||
|
||||
public IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
public Guid StartupEntityId => Account.Id;
|
||||
|
||||
public string StartupEntityTitle => Account.Name;
|
||||
|
||||
public int Order => Account.Order;
|
||||
|
||||
public string StartupEntityAddresses => Account.Address;
|
||||
|
||||
public int HoldingAccountCount => 1;
|
||||
|
||||
public bool HasProfilePicture => !string.IsNullOrEmpty(Account.Base64ProfilePictureData);
|
||||
|
||||
public AccountProviderDetailViewModel(IProviderDetail providerDetail, MailAccount account)
|
||||
{
|
||||
|
||||
[ObservableProperty]
|
||||
private MailAccount account;
|
||||
|
||||
public IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
public Guid StartupEntityId => Account.Id;
|
||||
|
||||
public string StartupEntityTitle => Account.Name;
|
||||
|
||||
public int Order => Account.Order;
|
||||
|
||||
public string StartupEntityAddresses => Account.Address;
|
||||
|
||||
public int HoldingAccountCount => 1;
|
||||
|
||||
public bool HasProfilePicture => !string.IsNullOrEmpty(Account.Base64ProfilePictureData);
|
||||
|
||||
public AccountProviderDetailViewModel(IProviderDetail providerDetail, MailAccount account)
|
||||
{
|
||||
ProviderDetail = providerDetail;
|
||||
Account = account;
|
||||
}
|
||||
ProviderDetail = providerDetail;
|
||||
Account = account;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Wino.Core.ViewModels.Data
|
||||
namespace Wino.Core.ViewModels.Data;
|
||||
|
||||
public class AppColorViewModel : ObservableObject
|
||||
{
|
||||
public class AppColorViewModel : ObservableObject
|
||||
private string _hex;
|
||||
|
||||
public string Hex
|
||||
{
|
||||
private string _hex;
|
||||
get => _hex;
|
||||
set => SetProperty(ref _hex, value);
|
||||
}
|
||||
|
||||
public string Hex
|
||||
{
|
||||
get => _hex;
|
||||
set => SetProperty(ref _hex, value);
|
||||
}
|
||||
public bool IsAccentColor { get; }
|
||||
|
||||
public bool IsAccentColor { get; }
|
||||
|
||||
public AppColorViewModel(string hex, bool isAccentColor = false)
|
||||
{
|
||||
IsAccentColor = isAccentColor;
|
||||
Hex = hex;
|
||||
}
|
||||
public AppColorViewModel(string hex, bool isAccentColor = false)
|
||||
{
|
||||
IsAccentColor = isAccentColor;
|
||||
Hex = hex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Data
|
||||
namespace Wino.Mail.ViewModels.Data;
|
||||
|
||||
public partial class BreadcrumbNavigationItemViewModel : ObservableObject
|
||||
{
|
||||
public partial class BreadcrumbNavigationItemViewModel : ObservableObject
|
||||
[ObservableProperty]
|
||||
private string title;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isActive;
|
||||
|
||||
public BreadcrumbNavigationRequested Request { get; set; }
|
||||
|
||||
public BreadcrumbNavigationItemViewModel(BreadcrumbNavigationRequested request, bool isActive)
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string title;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool isActive;
|
||||
|
||||
public BreadcrumbNavigationRequested Request { get; set; }
|
||||
|
||||
public BreadcrumbNavigationItemViewModel(BreadcrumbNavigationRequested request, bool isActive)
|
||||
{
|
||||
Request = request;
|
||||
Title = request.PageTitle;
|
||||
IsActive = isActive;
|
||||
}
|
||||
Request = request;
|
||||
Title = request.PageTitle;
|
||||
IsActive = isActive;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,31 +6,30 @@ using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
|
||||
namespace Wino.Core.ViewModels.Data
|
||||
namespace Wino.Core.ViewModels.Data;
|
||||
|
||||
public partial class MergedAccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
|
||||
{
|
||||
public partial class MergedAccountProviderDetailViewModel : ObservableObject, IAccountProviderDetailViewModel
|
||||
public List<AccountProviderDetailViewModel> HoldingAccounts { get; }
|
||||
public MergedInbox MergedInbox { get; }
|
||||
|
||||
public string AccountAddresses => string.Join(", ", HoldingAccounts.Select(a => a.Account.Address));
|
||||
|
||||
public Guid StartupEntityId => MergedInbox.Id;
|
||||
|
||||
public string StartupEntityTitle => MergedInbox.Name;
|
||||
|
||||
public int Order => 0;
|
||||
|
||||
public IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
public string StartupEntityAddresses => AccountAddresses;
|
||||
|
||||
public int HoldingAccountCount => HoldingAccounts.Count;
|
||||
|
||||
public MergedAccountProviderDetailViewModel(MergedInbox mergedInbox, List<AccountProviderDetailViewModel> holdingAccounts)
|
||||
{
|
||||
public List<AccountProviderDetailViewModel> HoldingAccounts { get; }
|
||||
public MergedInbox MergedInbox { get; }
|
||||
|
||||
public string AccountAddresses => string.Join(", ", HoldingAccounts.Select(a => a.Account.Address));
|
||||
|
||||
public Guid StartupEntityId => MergedInbox.Id;
|
||||
|
||||
public string StartupEntityTitle => MergedInbox.Name;
|
||||
|
||||
public int Order => 0;
|
||||
|
||||
public IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
public string StartupEntityAddresses => AccountAddresses;
|
||||
|
||||
public int HoldingAccountCount => HoldingAccounts.Count;
|
||||
|
||||
public MergedAccountProviderDetailViewModel(MergedInbox mergedInbox, List<AccountProviderDetailViewModel> holdingAccounts)
|
||||
{
|
||||
MergedInbox = mergedInbox;
|
||||
HoldingAccounts = holdingAccounts;
|
||||
}
|
||||
MergedInbox = mergedInbox;
|
||||
HoldingAccounts = holdingAccounts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
{
|
||||
public class ManageAccountsPagePageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public ManageAccountsPagePageViewModel(INavigationService navigationService)
|
||||
{
|
||||
NavigationService = navigationService;
|
||||
}
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public INavigationService NavigationService { get; }
|
||||
public class ManageAccountsPagePageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public ManageAccountsPagePageViewModel(INavigationService navigationService)
|
||||
{
|
||||
NavigationService = navigationService;
|
||||
}
|
||||
|
||||
public INavigationService NavigationService { get; }
|
||||
}
|
||||
|
||||
@@ -11,282 +11,281 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Personalization;
|
||||
using Wino.Core.ViewModels.Data;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public partial class PersonalizationPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public partial class PersonalizationPageViewModel : CoreBaseViewModel
|
||||
public IStatePersistanceService StatePersistenceService { get; }
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
|
||||
private readonly IDialogServiceBase _dialogService;
|
||||
private readonly IThemeService _themeService;
|
||||
|
||||
private bool isPropChangeDisabled = false;
|
||||
|
||||
// Sample mail copy to use in previewing mail display modes.
|
||||
public MailCopy DemoPreviewMailCopy { get; } = new MailCopy()
|
||||
{
|
||||
public IStatePersistanceService StatePersistenceService { get; }
|
||||
public IPreferencesService PreferencesService { get; }
|
||||
FromName = "Sender Name",
|
||||
Subject = "Mail Subject",
|
||||
PreviewText = "Thank you for using Wino Mail. We hope you enjoy the experience.",
|
||||
};
|
||||
|
||||
private readonly IDialogServiceBase _dialogService;
|
||||
private readonly IThemeService _themeService;
|
||||
#region Personalization
|
||||
|
||||
private bool isPropChangeDisabled = false;
|
||||
public bool IsSelectedWindowsAccentColor => SelectedAppColor == Colors.LastOrDefault();
|
||||
|
||||
// Sample mail copy to use in previewing mail display modes.
|
||||
public MailCopy DemoPreviewMailCopy { get; } = new MailCopy()
|
||||
public ObservableCollection<AppColorViewModel> Colors { get; set; } = [];
|
||||
|
||||
public List<ElementThemeContainer> ElementThemes { get; set; } =
|
||||
[
|
||||
new ElementThemeContainer(ApplicationElementTheme.Light, Translator.ElementTheme_Light),
|
||||
new ElementThemeContainer(ApplicationElementTheme.Dark, Translator.ElementTheme_Dark),
|
||||
new ElementThemeContainer(ApplicationElementTheme.Default, Translator.ElementTheme_Default),
|
||||
];
|
||||
|
||||
public List<MailListDisplayMode> InformationDisplayModes { get; set; } =
|
||||
[
|
||||
MailListDisplayMode.Compact,
|
||||
MailListDisplayMode.Medium,
|
||||
MailListDisplayMode.Spacious
|
||||
];
|
||||
|
||||
public List<AppThemeBase> AppThemes { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private ElementThemeContainer selectedElementTheme;
|
||||
|
||||
[ObservableProperty]
|
||||
private MailListDisplayMode selectedInfoDisplayMode;
|
||||
|
||||
private AppColorViewModel _selectedAppColor;
|
||||
|
||||
public AppColorViewModel SelectedAppColor
|
||||
{
|
||||
get => _selectedAppColor;
|
||||
set
|
||||
{
|
||||
FromName = "Sender Name",
|
||||
Subject = "Mail Subject",
|
||||
PreviewText = "Thank you for using Wino Mail. We hope you enjoy the experience.",
|
||||
};
|
||||
|
||||
#region Personalization
|
||||
|
||||
public bool IsSelectedWindowsAccentColor => SelectedAppColor == Colors.LastOrDefault();
|
||||
|
||||
public ObservableCollection<AppColorViewModel> Colors { get; set; } = [];
|
||||
|
||||
public List<ElementThemeContainer> ElementThemes { get; set; } =
|
||||
[
|
||||
new ElementThemeContainer(ApplicationElementTheme.Light, Translator.ElementTheme_Light),
|
||||
new ElementThemeContainer(ApplicationElementTheme.Dark, Translator.ElementTheme_Dark),
|
||||
new ElementThemeContainer(ApplicationElementTheme.Default, Translator.ElementTheme_Default),
|
||||
];
|
||||
|
||||
public List<MailListDisplayMode> InformationDisplayModes { get; set; } =
|
||||
[
|
||||
MailListDisplayMode.Compact,
|
||||
MailListDisplayMode.Medium,
|
||||
MailListDisplayMode.Spacious
|
||||
];
|
||||
|
||||
public List<AppThemeBase> AppThemes { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private ElementThemeContainer selectedElementTheme;
|
||||
|
||||
[ObservableProperty]
|
||||
private MailListDisplayMode selectedInfoDisplayMode;
|
||||
|
||||
private AppColorViewModel _selectedAppColor;
|
||||
|
||||
public AppColorViewModel SelectedAppColor
|
||||
{
|
||||
get => _selectedAppColor;
|
||||
set
|
||||
if (SetProperty(ref _selectedAppColor, value))
|
||||
{
|
||||
if (SetProperty(ref _selectedAppColor, value))
|
||||
{
|
||||
UseAccentColor = value == Colors?.LastOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _useAccentColor;
|
||||
public bool UseAccentColor
|
||||
{
|
||||
get => _useAccentColor;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _useAccentColor, value))
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
SelectedAppColor = Colors?.LastOrDefault();
|
||||
}
|
||||
else if (SelectedAppColor == Colors?.LastOrDefault())
|
||||
{
|
||||
// Unchecking from accent color.
|
||||
|
||||
SelectedAppColor = Colors?.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow app theme change for system themes.
|
||||
public bool CanSelectElementTheme => SelectedAppTheme != null &&
|
||||
(SelectedAppTheme.AppThemeType == AppThemeType.System || SelectedAppTheme.AppThemeType == AppThemeType.Custom);
|
||||
|
||||
private AppThemeBase _selectedAppTheme;
|
||||
|
||||
public AppThemeBase SelectedAppTheme
|
||||
{
|
||||
get => _selectedAppTheme;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedAppTheme, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(CanSelectElementTheme));
|
||||
|
||||
if (!CanSelectElementTheme)
|
||||
{
|
||||
SelectedElementTheme = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[RelayCommand]
|
||||
private void ResetMailListPaneLength()
|
||||
{
|
||||
StatePersistenceService.MailListPaneLength = 420;
|
||||
_dialogService.InfoBarMessage(Translator.GeneralTitle_Info, Translator.Info_MailListSizeResetSuccessMessage, InfoBarMessageType.Success);
|
||||
}
|
||||
|
||||
public AsyncRelayCommand CreateCustomThemeCommand { get; set; }
|
||||
public PersonalizationPageViewModel(IDialogServiceBase dialogService,
|
||||
IStatePersistanceService statePersistanceService,
|
||||
IThemeService themeService,
|
||||
IPreferencesService preferencesService)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
_themeService = themeService;
|
||||
|
||||
StatePersistenceService = statePersistanceService;
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
CreateCustomThemeCommand = new AsyncRelayCommand(CreateCustomThemeAsync);
|
||||
}
|
||||
|
||||
private async Task CreateCustomThemeAsync()
|
||||
{
|
||||
bool isThemeCreated = await _dialogService.ShowCustomThemeBuilderDialogAsync();
|
||||
|
||||
if (isThemeCreated)
|
||||
{
|
||||
// Reload themes.
|
||||
|
||||
await InitializeSettingsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeColors()
|
||||
{
|
||||
Colors.Add(new AppColorViewModel("#0078d7"));
|
||||
Colors.Add(new AppColorViewModel("#00838c"));
|
||||
Colors.Add(new AppColorViewModel("#e3008c"));
|
||||
Colors.Add(new AppColorViewModel("#ca4f07"));
|
||||
Colors.Add(new AppColorViewModel("#e81123"));
|
||||
Colors.Add(new AppColorViewModel("#00819e"));
|
||||
Colors.Add(new AppColorViewModel("#10893e"));
|
||||
Colors.Add(new AppColorViewModel("#881798"));
|
||||
Colors.Add(new AppColorViewModel("#c239b3"));
|
||||
Colors.Add(new AppColorViewModel("#767676"));
|
||||
Colors.Add(new AppColorViewModel("#e1b12c"));
|
||||
Colors.Add(new AppColorViewModel("#16a085"));
|
||||
Colors.Add(new AppColorViewModel("#0984e3"));
|
||||
Colors.Add(new AppColorViewModel("#4a69bd"));
|
||||
Colors.Add(new AppColorViewModel("#05c46b"));
|
||||
|
||||
// Add system accent color as last item.
|
||||
|
||||
Colors.Add(new AppColorViewModel(_themeService.GetSystemAccentColorHex(), true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set selections from settings service.
|
||||
/// </summary>
|
||||
private void SetInitialValues()
|
||||
{
|
||||
SelectedElementTheme = ElementThemes.Find(a => a.NativeTheme == _themeService.RootTheme);
|
||||
SelectedInfoDisplayMode = PreferencesService.MailItemDisplayMode;
|
||||
|
||||
var currentAccentColor = _themeService.AccentColor;
|
||||
|
||||
bool isWindowsColor = string.IsNullOrEmpty(currentAccentColor);
|
||||
|
||||
if (isWindowsColor)
|
||||
{
|
||||
SelectedAppColor = Colors.LastOrDefault();
|
||||
UseAccentColor = true;
|
||||
}
|
||||
else
|
||||
SelectedAppColor = Colors.FirstOrDefault(a => a.Hex == currentAccentColor);
|
||||
|
||||
SelectedAppTheme = AppThemes.Find(a => a.Id == _themeService.CurrentApplicationThemeId);
|
||||
}
|
||||
|
||||
protected override async void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
|
||||
await InitializeSettingsAsync();
|
||||
}
|
||||
|
||||
private async Task InitializeSettingsAsync()
|
||||
{
|
||||
Deactivate();
|
||||
|
||||
AppThemes = await _themeService.GetAvailableThemesAsync();
|
||||
|
||||
OnPropertyChanged(nameof(AppThemes));
|
||||
|
||||
InitializeColors();
|
||||
SetInitialValues();
|
||||
|
||||
PropertyChanged -= PersonalizationSettingsUpdated;
|
||||
PropertyChanged += PersonalizationSettingsUpdated;
|
||||
|
||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||
|
||||
_themeService.AccentColorChanged += AccentColorChanged;
|
||||
_themeService.ElementThemeChanged += ElementThemeChanged;
|
||||
}
|
||||
|
||||
private void AccentColorChanged(object sender, string e)
|
||||
{
|
||||
isPropChangeDisabled = true;
|
||||
|
||||
SelectedAppColor = Colors.FirstOrDefault(a => a.Hex == e);
|
||||
|
||||
isPropChangeDisabled = false;
|
||||
}
|
||||
|
||||
private void ElementThemeChanged(object sender, ApplicationElementTheme e)
|
||||
{
|
||||
isPropChangeDisabled = true;
|
||||
|
||||
SelectedElementTheme = ElementThemes.Find(a => a.NativeTheme == e);
|
||||
|
||||
isPropChangeDisabled = false;
|
||||
}
|
||||
|
||||
protected override void OnDeactivated()
|
||||
{
|
||||
base.OnDeactivated();
|
||||
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
private void Deactivate()
|
||||
{
|
||||
PropertyChanged -= PersonalizationSettingsUpdated;
|
||||
|
||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||
|
||||
if (AppThemes != null)
|
||||
{
|
||||
AppThemes.Clear();
|
||||
AppThemes = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void PersonalizationSettingsUpdated(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (isPropChangeDisabled)
|
||||
return;
|
||||
|
||||
if (e.PropertyName == nameof(SelectedElementTheme) && SelectedElementTheme != null)
|
||||
{
|
||||
_themeService.RootTheme = SelectedElementTheme.NativeTheme;
|
||||
}
|
||||
else if (e.PropertyName == nameof(SelectedAppTheme))
|
||||
{
|
||||
_themeService.CurrentApplicationThemeId = SelectedAppTheme.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.PropertyName == nameof(SelectedInfoDisplayMode))
|
||||
PreferencesService.MailItemDisplayMode = SelectedInfoDisplayMode;
|
||||
else if (e.PropertyName == nameof(SelectedAppColor))
|
||||
_themeService.AccentColor = SelectedAppColor.Hex;
|
||||
UseAccentColor = value == Colors?.LastOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _useAccentColor;
|
||||
public bool UseAccentColor
|
||||
{
|
||||
get => _useAccentColor;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _useAccentColor, value))
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
SelectedAppColor = Colors?.LastOrDefault();
|
||||
}
|
||||
else if (SelectedAppColor == Colors?.LastOrDefault())
|
||||
{
|
||||
// Unchecking from accent color.
|
||||
|
||||
SelectedAppColor = Colors?.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow app theme change for system themes.
|
||||
public bool CanSelectElementTheme => SelectedAppTheme != null &&
|
||||
(SelectedAppTheme.AppThemeType == AppThemeType.System || SelectedAppTheme.AppThemeType == AppThemeType.Custom);
|
||||
|
||||
private AppThemeBase _selectedAppTheme;
|
||||
|
||||
public AppThemeBase SelectedAppTheme
|
||||
{
|
||||
get => _selectedAppTheme;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedAppTheme, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(CanSelectElementTheme));
|
||||
|
||||
if (!CanSelectElementTheme)
|
||||
{
|
||||
SelectedElementTheme = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[RelayCommand]
|
||||
private void ResetMailListPaneLength()
|
||||
{
|
||||
StatePersistenceService.MailListPaneLength = 420;
|
||||
_dialogService.InfoBarMessage(Translator.GeneralTitle_Info, Translator.Info_MailListSizeResetSuccessMessage, InfoBarMessageType.Success);
|
||||
}
|
||||
|
||||
public AsyncRelayCommand CreateCustomThemeCommand { get; set; }
|
||||
public PersonalizationPageViewModel(IDialogServiceBase dialogService,
|
||||
IStatePersistanceService statePersistanceService,
|
||||
IThemeService themeService,
|
||||
IPreferencesService preferencesService)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
_themeService = themeService;
|
||||
|
||||
StatePersistenceService = statePersistanceService;
|
||||
PreferencesService = preferencesService;
|
||||
|
||||
CreateCustomThemeCommand = new AsyncRelayCommand(CreateCustomThemeAsync);
|
||||
}
|
||||
|
||||
private async Task CreateCustomThemeAsync()
|
||||
{
|
||||
bool isThemeCreated = await _dialogService.ShowCustomThemeBuilderDialogAsync();
|
||||
|
||||
if (isThemeCreated)
|
||||
{
|
||||
// Reload themes.
|
||||
|
||||
await InitializeSettingsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeColors()
|
||||
{
|
||||
Colors.Add(new AppColorViewModel("#0078d7"));
|
||||
Colors.Add(new AppColorViewModel("#00838c"));
|
||||
Colors.Add(new AppColorViewModel("#e3008c"));
|
||||
Colors.Add(new AppColorViewModel("#ca4f07"));
|
||||
Colors.Add(new AppColorViewModel("#e81123"));
|
||||
Colors.Add(new AppColorViewModel("#00819e"));
|
||||
Colors.Add(new AppColorViewModel("#10893e"));
|
||||
Colors.Add(new AppColorViewModel("#881798"));
|
||||
Colors.Add(new AppColorViewModel("#c239b3"));
|
||||
Colors.Add(new AppColorViewModel("#767676"));
|
||||
Colors.Add(new AppColorViewModel("#e1b12c"));
|
||||
Colors.Add(new AppColorViewModel("#16a085"));
|
||||
Colors.Add(new AppColorViewModel("#0984e3"));
|
||||
Colors.Add(new AppColorViewModel("#4a69bd"));
|
||||
Colors.Add(new AppColorViewModel("#05c46b"));
|
||||
|
||||
// Add system accent color as last item.
|
||||
|
||||
Colors.Add(new AppColorViewModel(_themeService.GetSystemAccentColorHex(), true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set selections from settings service.
|
||||
/// </summary>
|
||||
private void SetInitialValues()
|
||||
{
|
||||
SelectedElementTheme = ElementThemes.Find(a => a.NativeTheme == _themeService.RootTheme);
|
||||
SelectedInfoDisplayMode = PreferencesService.MailItemDisplayMode;
|
||||
|
||||
var currentAccentColor = _themeService.AccentColor;
|
||||
|
||||
bool isWindowsColor = string.IsNullOrEmpty(currentAccentColor);
|
||||
|
||||
if (isWindowsColor)
|
||||
{
|
||||
SelectedAppColor = Colors.LastOrDefault();
|
||||
UseAccentColor = true;
|
||||
}
|
||||
else
|
||||
SelectedAppColor = Colors.FirstOrDefault(a => a.Hex == currentAccentColor);
|
||||
|
||||
SelectedAppTheme = AppThemes.Find(a => a.Id == _themeService.CurrentApplicationThemeId);
|
||||
}
|
||||
|
||||
protected override async void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
|
||||
await InitializeSettingsAsync();
|
||||
}
|
||||
|
||||
private async Task InitializeSettingsAsync()
|
||||
{
|
||||
Deactivate();
|
||||
|
||||
AppThemes = await _themeService.GetAvailableThemesAsync();
|
||||
|
||||
OnPropertyChanged(nameof(AppThemes));
|
||||
|
||||
InitializeColors();
|
||||
SetInitialValues();
|
||||
|
||||
PropertyChanged -= PersonalizationSettingsUpdated;
|
||||
PropertyChanged += PersonalizationSettingsUpdated;
|
||||
|
||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||
|
||||
_themeService.AccentColorChanged += AccentColorChanged;
|
||||
_themeService.ElementThemeChanged += ElementThemeChanged;
|
||||
}
|
||||
|
||||
private void AccentColorChanged(object sender, string e)
|
||||
{
|
||||
isPropChangeDisabled = true;
|
||||
|
||||
SelectedAppColor = Colors.FirstOrDefault(a => a.Hex == e);
|
||||
|
||||
isPropChangeDisabled = false;
|
||||
}
|
||||
|
||||
private void ElementThemeChanged(object sender, ApplicationElementTheme e)
|
||||
{
|
||||
isPropChangeDisabled = true;
|
||||
|
||||
SelectedElementTheme = ElementThemes.Find(a => a.NativeTheme == e);
|
||||
|
||||
isPropChangeDisabled = false;
|
||||
}
|
||||
|
||||
protected override void OnDeactivated()
|
||||
{
|
||||
base.OnDeactivated();
|
||||
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
private void Deactivate()
|
||||
{
|
||||
PropertyChanged -= PersonalizationSettingsUpdated;
|
||||
|
||||
_themeService.AccentColorChanged -= AccentColorChanged;
|
||||
_themeService.ElementThemeChanged -= ElementThemeChanged;
|
||||
|
||||
if (AppThemes != null)
|
||||
{
|
||||
AppThemes.Clear();
|
||||
AppThemes = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void PersonalizationSettingsUpdated(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (isPropChangeDisabled)
|
||||
return;
|
||||
|
||||
if (e.PropertyName == nameof(SelectedElementTheme) && SelectedElementTheme != null)
|
||||
{
|
||||
_themeService.RootTheme = SelectedElementTheme.NativeTheme;
|
||||
}
|
||||
else if (e.PropertyName == nameof(SelectedAppTheme))
|
||||
{
|
||||
_themeService.CurrentApplicationThemeId = SelectedAppTheme.Id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.PropertyName == nameof(SelectedInfoDisplayMode))
|
||||
PreferencesService.MailItemDisplayMode = SelectedInfoDisplayMode;
|
||||
else if (e.PropertyName == nameof(SelectedAppColor))
|
||||
_themeService.AccentColor = SelectedAppColor.Hex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,55 +9,54 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Settings;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public partial class SettingOptionsPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public partial class SettingOptionsPageViewModel : CoreBaseViewModel
|
||||
private readonly ISettingsBuilderService _settingsBuilderService;
|
||||
|
||||
[RelayCommand]
|
||||
private void GoAccountSettings() => Messenger.Send<NavigateManageAccountsRequested>();
|
||||
|
||||
[RelayCommand]
|
||||
public void NavigateSubDetail(object type)
|
||||
{
|
||||
private readonly ISettingsBuilderService _settingsBuilderService;
|
||||
|
||||
[RelayCommand]
|
||||
private void GoAccountSettings() => Messenger.Send<NavigateManageAccountsRequested>();
|
||||
|
||||
[RelayCommand]
|
||||
public void NavigateSubDetail(object type)
|
||||
if (type is WinoPage pageType)
|
||||
{
|
||||
if (type is WinoPage pageType)
|
||||
if (pageType == WinoPage.AccountManagementPage)
|
||||
{
|
||||
if (pageType == WinoPage.AccountManagementPage)
|
||||
{
|
||||
GoAccountSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
string pageTitle = pageType switch
|
||||
{
|
||||
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,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(pageTitle, pageType));
|
||||
GoAccountSettings();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private List<SettingOption> _settingOptions = new();
|
||||
string pageTitle = pageType switch
|
||||
{
|
||||
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,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
public SettingOptionsPageViewModel(ISettingsBuilderService settingsBuilderService)
|
||||
{
|
||||
_settingsBuilderService = settingsBuilderService;
|
||||
|
||||
ReloadSettings();
|
||||
}
|
||||
|
||||
private void ReloadSettings()
|
||||
{
|
||||
SettingOptions = _settingsBuilderService.GetSettingItems();
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(pageTitle, pageType));
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private List<SettingOption> _settingOptions = new();
|
||||
|
||||
public SettingOptionsPageViewModel(ISettingsBuilderService settingsBuilderService)
|
||||
{
|
||||
_settingsBuilderService = settingsBuilderService;
|
||||
|
||||
ReloadSettings();
|
||||
}
|
||||
|
||||
private void ReloadSettings()
|
||||
{
|
||||
SettingOptions = _settingsBuilderService.GetSettingItems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
{
|
||||
public class SettingsPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public SettingsPageViewModel(INavigationService navigationService)
|
||||
{
|
||||
NavigationService = navigationService;
|
||||
}
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public INavigationService NavigationService { get; }
|
||||
public class SettingsPageViewModel : CoreBaseViewModel
|
||||
{
|
||||
public SettingsPageViewModel(INavigationService navigationService)
|
||||
{
|
||||
NavigationService = navigationService;
|
||||
}
|
||||
|
||||
public INavigationService NavigationService { get; }
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.ViewModels
|
||||
namespace Wino.Core.ViewModels;
|
||||
|
||||
public class SettingsDialogViewModel : CoreBaseViewModel
|
||||
{
|
||||
public class SettingsDialogViewModel : CoreBaseViewModel
|
||||
public SettingsDialogViewModel(IMailDialogService dialogService)
|
||||
{
|
||||
public SettingsDialogViewModel(IMailDialogService dialogService)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user