Import functionality for wino accounts, calendar sync UI, bunch of shell improvements
This commit is contained in:
@@ -160,6 +160,13 @@ public partial class AccountDetailsPageViewModel : MailBaseViewModel
|
||||
private void EditAliases()
|
||||
=> Messenger.Send(new BreadcrumbNavigationRequested(Translator.SettingsManageAliases_Title, WinoPage.AliasManagementPage, Account.Id));
|
||||
|
||||
[RelayCommand]
|
||||
private void EditImapCalDavSettings()
|
||||
=> Messenger.Send(new BreadcrumbNavigationRequested(
|
||||
Translator.ImapCalDavSettingsPage_TitleEdit,
|
||||
WinoPage.ImapCalDavSettingsPage,
|
||||
ImapCalDavSettingsNavigationContext.CreateForEditMode(Account.Id)));
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SaveChangesAsync()
|
||||
{
|
||||
|
||||
@@ -13,9 +13,12 @@ using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.AutoDiscovery;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Server;
|
||||
|
||||
namespace Wino.Mail.ViewModels;
|
||||
|
||||
@@ -289,7 +292,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
|
||||
else
|
||||
{
|
||||
PageTitle = Translator.ImapCalDavSettingsPage_TitleEdit;
|
||||
await InitializeEditModeAsync(context.AccountId).ConfigureAwait(false);
|
||||
await InitializeEditModeAsync(context.AccountId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,7 +501,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
|
||||
|
||||
private async Task InitializeEditModeAsync(Guid accountId)
|
||||
{
|
||||
var account = await _accountService.GetAccountAsync(accountId).ConfigureAwait(false);
|
||||
var account = await _accountService.GetAccountAsync(accountId);
|
||||
if (account == null)
|
||||
throw new InvalidOperationException(Translator.Exception_NullAssignedAccount);
|
||||
|
||||
@@ -768,10 +771,26 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
|
||||
serverInformation.AccountId = account.Id;
|
||||
|
||||
account.ServerInformation = serverInformation;
|
||||
account.AttentionReason = AccountAttentionReason.None;
|
||||
|
||||
await _accountService.UpdateAccountCustomServerInformationAsync(serverInformation).ConfigureAwait(false);
|
||||
await _accountService.UpdateAccountAsync(account).ConfigureAwait(false);
|
||||
|
||||
Messenger.Send(new NewMailSynchronizationRequested(new MailSynchronizationOptions
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = MailSynchronizationType.FullFolders
|
||||
}));
|
||||
|
||||
if (account.IsCalendarAccessGranted)
|
||||
{
|
||||
Messenger.Send(new NewCalendarSynchronizationRequested(new CalendarSynchronizationOptions
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = CalendarSynchronizationType.CalendarEvents
|
||||
}));
|
||||
}
|
||||
|
||||
_mailDialogService.InfoBarMessage(
|
||||
Translator.IMAPSetupDialog_ValidationSuccess_Title,
|
||||
Translator.ImapCalDavSettingsPage_SaveSuccessMessage,
|
||||
|
||||
@@ -20,6 +20,8 @@ using Wino.Core.Domain.Models;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Messaging.Client.Accounts;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
@@ -81,7 +83,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly IMimeFileService _mimeFileService;
|
||||
private readonly IWebView2RuntimeValidatorService _webView2RuntimeValidatorService;
|
||||
private readonly IUpdateManager _updateManager;
|
||||
private readonly IStoreUpdateService _storeUpdateService;
|
||||
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
@@ -108,7 +109,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
IConfigurationService configurationService,
|
||||
IStartupBehaviorService startupBehaviorService,
|
||||
IWebView2RuntimeValidatorService webView2RuntimeValidatorService,
|
||||
IUpdateManager updateManager,
|
||||
IStoreUpdateService storeUpdateService)
|
||||
{
|
||||
StatePersistenceService = statePersistanceService;
|
||||
@@ -130,7 +130,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
_notificationBuilder = notificationBuilder;
|
||||
_winoRequestDelegator = winoRequestDelegator;
|
||||
_webView2RuntimeValidatorService = webView2RuntimeValidatorService;
|
||||
_updateManager = updateManager;
|
||||
_storeUpdateService = storeUpdateService;
|
||||
}
|
||||
|
||||
@@ -235,7 +234,8 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
}
|
||||
|
||||
var activationContext = parameters as ShellModeActivationContext;
|
||||
var shouldRunStartupFlows = activationContext?.IsInitialActivation ?? true;
|
||||
var shouldRunStartupFlows = (activationContext?.IsInitialActivation ?? true) &&
|
||||
activationContext?.SuppressStartupFlows != true;
|
||||
var hasExistingAccountMenuItems = MenuItems?.OfType<IAccountMenuItem>().Any() == true;
|
||||
|
||||
PreferencesService.PreferenceChanged -= PreferencesServiceChanged;
|
||||
@@ -258,7 +258,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
|
||||
if (shouldRunStartupFlows)
|
||||
{
|
||||
await ShowWhatIsNewIfNeededAsync();
|
||||
await MakeSureEnableStartupLaunchAsync();
|
||||
}
|
||||
}
|
||||
@@ -296,19 +295,6 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
FooterItems?.Clear();
|
||||
}
|
||||
|
||||
private async Task ShowWhatIsNewIfNeededAsync()
|
||||
{
|
||||
if (!_updateManager.ShouldShowUpdateNotes())
|
||||
return;
|
||||
|
||||
var notes = await _updateManager.GetLatestUpdateNotesAsync();
|
||||
|
||||
if (notes.Sections.Count == 0)
|
||||
return;
|
||||
|
||||
await _dialogService.ShowWhatIsNewDialogAsync(notes);
|
||||
}
|
||||
|
||||
private async Task MakeSureEnableStartupLaunchAsync()
|
||||
{
|
||||
if (!_configurationService.Get<bool>(IsActivateStartupLaunchAskedKey, false))
|
||||
@@ -605,21 +591,75 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
}
|
||||
}
|
||||
|
||||
public Task HandleAccountAttentionAsync(MailAccount account)
|
||||
=> FixAccountIssuesAsync(account);
|
||||
|
||||
private void TriggerFullSynchronization(MailAccount account)
|
||||
{
|
||||
Messenger.Send(new NewMailSynchronizationRequested(new MailSynchronizationOptions
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = MailSynchronizationType.FullFolders
|
||||
}));
|
||||
|
||||
if (account.IsCalendarAccessGranted)
|
||||
{
|
||||
Messenger.Send(new NewCalendarSynchronizationRequested(new CalendarSynchronizationOptions
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Type = CalendarSynchronizationType.CalendarEvents
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FixAccountIssuesAsync(MailAccount account)
|
||||
{
|
||||
// TODO: This area is very unclear. Needs to be rewritten with care.
|
||||
// Fix account issues are expected to not work, but may work for some cases.
|
||||
|
||||
try
|
||||
{
|
||||
if (account.AttentionReason == AccountAttentionReason.InvalidCredentials)
|
||||
await _accountService.FixTokenIssuesAsync(account.Id);
|
||||
{
|
||||
if (account.ProviderType is MailProviderType.Gmail or MailProviderType.Outlook)
|
||||
{
|
||||
await SynchronizationManager.Instance.HandleAuthorizationAsync(
|
||||
account.ProviderType,
|
||||
account,
|
||||
account.ProviderType == MailProviderType.Gmail);
|
||||
|
||||
await _accountService.ClearAccountAttentionAsync(account.Id);
|
||||
|
||||
_dialogService.InfoBarMessage(
|
||||
Translator.Info_AccountIssueFixSuccessTitle,
|
||||
Translator.Info_AccountIssueFixSuccessMessage,
|
||||
InfoBarMessageType.Success);
|
||||
|
||||
TriggerFullSynchronization(account);
|
||||
return;
|
||||
}
|
||||
|
||||
NavigationService.Navigate(WinoPage.SettingsPage, WinoPage.ManageAccountsPage);
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(
|
||||
Translator.ImapCalDavSettingsPage_TitleEdit,
|
||||
WinoPage.ImapCalDavSettingsPage,
|
||||
ImapCalDavSettingsNavigationContext.CreateForEditMode(account.Id)));
|
||||
|
||||
_dialogService.InfoBarMessage(
|
||||
Translator.Info_AccountIssueFixSuccessTitle,
|
||||
Translator.Info_AccountIssueFixImapMessage,
|
||||
InfoBarMessageType.Information);
|
||||
return;
|
||||
}
|
||||
else if (account.AttentionReason == AccountAttentionReason.MissingSystemFolderConfiguration)
|
||||
{
|
||||
await _dialogService.HandleSystemFolderConfigurationDialogAsync(account.Id, _folderService);
|
||||
await _accountService.ClearAccountAttentionAsync(account.Id);
|
||||
|
||||
await _accountService.ClearAccountAttentionAsync(account.Id);
|
||||
_dialogService.InfoBarMessage(
|
||||
Translator.Info_AccountIssueFixSuccessTitle,
|
||||
Translator.Info_AccountIssueFixSuccessMessage,
|
||||
InfoBarMessageType.Success);
|
||||
|
||||
_dialogService.InfoBarMessage(Translator.Info_AccountIssueFixFailedTitle, Translator.Info_AccountIssueFixSuccessMessage, InfoBarMessageType.Success);
|
||||
TriggerFullSynchronization(account);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,27 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Updates;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Mail.ViewModels;
|
||||
|
||||
public partial class WelcomePageV2ViewModel : MailBaseViewModel
|
||||
{
|
||||
private readonly IUpdateManager _updateManager;
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly IWinoAccountDataSyncService _syncService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial List<UpdateNoteSection> UpdateSections { get; set; } = [];
|
||||
|
||||
public WelcomePageV2ViewModel(IUpdateManager updateManager)
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(GetStartedCommand))]
|
||||
[NotifyCanExecuteChangedFor(nameof(ImportFromWinoAccountCommand))]
|
||||
public partial bool IsImportInProgress { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(HasImportStatus))]
|
||||
public partial string ImportStatusMessage { get; set; } = string.Empty;
|
||||
|
||||
public bool HasImportStatus => !string.IsNullOrWhiteSpace(ImportStatusMessage);
|
||||
|
||||
public WelcomePageV2ViewModel(IUpdateManager updateManager,
|
||||
IMailDialogService dialogService,
|
||||
IWinoAccountDataSyncService syncService)
|
||||
{
|
||||
_updateManager = updateManager;
|
||||
_dialogService = dialogService;
|
||||
_syncService = syncService;
|
||||
}
|
||||
|
||||
public override async void OnNavigatedTo(NavigationMode mode, object parameters)
|
||||
@@ -39,11 +59,75 @@ public partial class WelcomePageV2ViewModel : MailBaseViewModel
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
[RelayCommand(CanExecute = nameof(CanOpenWelcomeActions))]
|
||||
private void GetStarted()
|
||||
{
|
||||
Messenger.Send(new BreadcrumbNavigationRequested(
|
||||
Translator.WelcomeWizard_Step2Title,
|
||||
WinoPage.ProviderSelectionPage));
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanOpenWelcomeActions))]
|
||||
private async Task ImportFromWinoAccountAsync()
|
||||
{
|
||||
await ExecuteUIThread(() => ImportStatusMessage = string.Empty);
|
||||
|
||||
try
|
||||
{
|
||||
var account = await _dialogService.ShowWinoAccountLoginDialogAsync().ConfigureAwait(false);
|
||||
if (account == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await ExecuteUIThread(() => IsImportInProgress = true);
|
||||
|
||||
var result = await _syncService.ImportAsync(new WinoAccountSyncSelection()).ConfigureAwait(false);
|
||||
if (result.ImportedMailboxCount > 0)
|
||||
{
|
||||
ReportUIChange(new WelcomeImportCompletedMessage(result.ImportedMailboxCount));
|
||||
return;
|
||||
}
|
||||
|
||||
await ExecuteUIThread(() => ImportStatusMessage = BuildInlineImportMessage(result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _dialogService.ShowMessageAsync(ex.Message, Translator.GeneralTitle_Error, WinoCustomMessageDialogIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await ExecuteUIThread(() => IsImportInProgress = false);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanOpenWelcomeActions() => !IsImportInProgress;
|
||||
|
||||
private static string BuildInlineImportMessage(WinoAccountSyncImportResult result)
|
||||
{
|
||||
var preferencesMessage = result.FailedPreferenceCount > 0
|
||||
? string.Format(Translator.WinoAccount_Management_ImportPartial, result.AppliedPreferenceCount, result.FailedPreferenceCount)
|
||||
: result.HadRemotePreferences
|
||||
? string.Format(Translator.WinoAccount_Management_ImportPreferencesSucceeded, result.AppliedPreferenceCount)
|
||||
: string.Empty;
|
||||
|
||||
if (result.RemoteMailboxCount == 0)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(preferencesMessage)
|
||||
? Translator.WelcomeWindow_ImportNoAccountsFound
|
||||
: $"{preferencesMessage} {Translator.WelcomeWindow_ImportNoAccountsFound}";
|
||||
}
|
||||
|
||||
if (result.SkippedDuplicateMailboxCount > 0 && result.ImportedMailboxCount == 0)
|
||||
{
|
||||
var duplicateMessage = string.Format(Translator.WelcomeWindow_ImportDuplicateAccountsSkipped, result.SkippedDuplicateMailboxCount);
|
||||
return string.IsNullOrWhiteSpace(preferencesMessage)
|
||||
? duplicateMessage
|
||||
: $"{preferencesMessage} {duplicateMessage}";
|
||||
}
|
||||
|
||||
return string.IsNullOrWhiteSpace(preferencesMessage)
|
||||
? Translator.WinoAccount_Management_ImportEmpty
|
||||
: preferencesMessage;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user