IMAP Improvements (#558)
* Fixing an issue where scrollviewer overrides a part of template in mail list. Adjusted zoomed out header grid's corner radius. * IDLE implementation, imap synchronization strategies basics and condstore synchronization. * Adding iCloud and Yahoo as special IMAP handling scenario. * iCloud special imap handling. * Support for killing synchronizers. * Update privacy policy url. * Batching condstore downloads into 50, using SORT extension for searches if supported. * Bumping some nugets. More on the imap synchronizers. * Delegating idle synchronizations to server to post-sync operations. * Update mailkit to resolve qresync bug with iCloud. * Fixing remote highest mode seq checks for qresync and condstore synchronizers. * Yahoo custom settings. * Bump google sdk package. * Fixing the build issue.... * NRE on canceled token accounts during setup. * Server crash handlers. * Remove ARM32. Upgrade server to .NET 9. * Fix icons for yahoo and apple. * Fixed an issue where disabled folders causing an exception on forced sync. * Remove smtp encoding constraint. * Remove commented code. * Fixing merge conflict * Addressing double registrations for mailkit remote folder events in synchronizers. * Making sure idle canceled result is not reported. * Fixing custom imap server dialog opening. * Fixing the issue with account creation making the previously selected account as selected as well. * Fixing app close behavior and logging app close.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.6 KiB |
BIN
Wino.Core.UWP/Assets/Providers/iCloud.png
Normal file
BIN
Wino.Core.UWP/Assets/Providers/iCloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
132
Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml
Normal file
132
Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml
Normal file
File diff suppressed because one or more lines are too long
76
Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs
Normal file
76
Wino.Core.UWP/Controls/AccountCreationDialogControl.xaml.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
|
||||
namespace Wino.Core.UWP.Controls
|
||||
{
|
||||
public sealed partial class AccountCreationDialogControl : UserControl, IRecipient<CopyAuthURLRequested>
|
||||
{
|
||||
private string copyClipboardURL;
|
||||
|
||||
public event EventHandler CancelClicked;
|
||||
|
||||
public AccountCreationDialogState State
|
||||
{
|
||||
get { return (AccountCreationDialogState)GetValue(StateProperty); }
|
||||
set { SetValue(StateProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialogControl), new PropertyMetadata(AccountCreationDialogState.Idle, new PropertyChangedCallback(OnStateChanged)));
|
||||
|
||||
public AccountCreationDialogControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private static void OnStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (obj is AccountCreationDialogControl dialog)
|
||||
{
|
||||
dialog.UpdateVisualStates();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVisualStates() => VisualStateManager.GoToState(this, State.ToString(), false);
|
||||
|
||||
public async void Receive(CopyAuthURLRequested message)
|
||||
{
|
||||
copyClipboardURL = message.AuthURL;
|
||||
|
||||
await Task.Delay(2000);
|
||||
|
||||
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
AuthHelpDialogButton.Visibility = Windows.UI.Xaml.Visibility.Visible;
|
||||
});
|
||||
}
|
||||
|
||||
private void ControlLoaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register(this);
|
||||
}
|
||||
|
||||
private void ControlUnloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
|
||||
private async void CopyClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(copyClipboardURL)) return;
|
||||
|
||||
var clipboardService = WinoApplication.Current.Services.GetService<IClipboardService>();
|
||||
await clipboardService.CopyClipboardAsync(copyClipboardURL);
|
||||
}
|
||||
|
||||
|
||||
private void CancelButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) => CancelClicked?.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,9 @@ namespace Wino.Core.UWP.Controls
|
||||
{ WinoIconGlyph.EventRespond, "\uE924" },
|
||||
{ WinoIconGlyph.EventReminder, "\uE923" },
|
||||
{ WinoIconGlyph.EventJoinOnline, "\uE926" },
|
||||
{ WinoIconGlyph.ViewMessageSource, "\uE943" }
|
||||
{ WinoIconGlyph.ViewMessageSource, "\uE943" },
|
||||
{ WinoIconGlyph.Apple, "\uE92B" },
|
||||
{ WinoIconGlyph.Yahoo, "\uE92C" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ namespace Wino.Core.UWP.Controls
|
||||
EventEditSeries,
|
||||
EventJoinOnline,
|
||||
ViewMessageSource,
|
||||
Apple,
|
||||
Yahoo
|
||||
}
|
||||
|
||||
public partial class WinoFontIcon : FontIcon
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,50 +1,71 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.UWP;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Dialogs
|
||||
{
|
||||
public sealed partial class AccountCreationDialog : BaseAccountCreationDialog, IRecipient<CopyAuthURLRequested>
|
||||
public sealed partial class AccountCreationDialog : ContentDialog, IAccountCreationDialog
|
||||
{
|
||||
private string copyClipboardURL;
|
||||
private TaskCompletionSource<bool> dialogOpened = new TaskCompletionSource<bool>();
|
||||
public CancellationTokenSource CancellationTokenSource { get; private set; }
|
||||
|
||||
public AccountCreationDialogState State
|
||||
{
|
||||
get { return (AccountCreationDialogState)GetValue(StateProperty); }
|
||||
set { SetValue(StateProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(AccountCreationDialog), new PropertyMetadata(AccountCreationDialogState.Idle));
|
||||
|
||||
public AccountCreationDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
WeakReferenceMessenger.Default.Register(this);
|
||||
}
|
||||
|
||||
public override void OnStateChanged(AccountCreationDialogState state)
|
||||
// Prevent users from dismissing it by ESC key.
|
||||
public void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
|
||||
{
|
||||
var tt = VisualStateManager.GoToState(this, state.ToString(), true);
|
||||
}
|
||||
|
||||
public async void Receive(CopyAuthURLRequested message)
|
||||
{
|
||||
copyClipboardURL = message.AuthURL;
|
||||
|
||||
await Task.Delay(2000);
|
||||
|
||||
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
|
||||
if (args.Result == ContentDialogResult.None)
|
||||
{
|
||||
AuthHelpDialogButton.Visibility = Windows.UI.Xaml.Visibility.Visible;
|
||||
});
|
||||
args.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e) => Complete(true);
|
||||
|
||||
private async void CopyClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
public void Complete(bool cancel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(copyClipboardURL)) return;
|
||||
State = cancel ? AccountCreationDialogState.Canceled : AccountCreationDialogState.Completed;
|
||||
|
||||
var clipboardService = WinoApplication.Current.Services.GetService<IClipboardService>();
|
||||
await clipboardService.CopyClipboardAsync(copyClipboardURL);
|
||||
// Unregister from closing event.
|
||||
Closing -= DialogClosing;
|
||||
|
||||
if (cancel && !CancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void CancelClicked(object sender, System.EventArgs e) => Complete(true);
|
||||
|
||||
public async Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource)
|
||||
{
|
||||
CancellationTokenSource = cancellationTokenSource;
|
||||
|
||||
Opened += DialogOpened;
|
||||
_ = ShowAsync();
|
||||
|
||||
await dialogOpened.Task;
|
||||
}
|
||||
|
||||
private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
|
||||
{
|
||||
Opened -= DialogOpened;
|
||||
|
||||
dialogOpened?.SetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
using System.Threading;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Dialogs
|
||||
{
|
||||
public abstract class BaseAccountCreationDialog : ContentDialog, IAccountCreationDialog
|
||||
{
|
||||
public AccountCreationDialogState State
|
||||
{
|
||||
get { return (AccountCreationDialogState)GetValue(StateProperty); }
|
||||
set { SetValue(StateProperty, value); }
|
||||
}
|
||||
|
||||
public CancellationTokenSource CancellationTokenSource { get; private set; }
|
||||
|
||||
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(AccountCreationDialogState), typeof(BaseAccountCreationDialog), new PropertyMetadata(AccountCreationDialogState.Idle, OnStateChanged));
|
||||
|
||||
private static void OnStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var dialog = d as BaseAccountCreationDialog;
|
||||
dialog.OnStateChanged((AccountCreationDialogState)e.NewValue);
|
||||
}
|
||||
|
||||
public abstract void OnStateChanged(AccountCreationDialogState state);
|
||||
|
||||
// Prevent users from dismissing it by ESC key.
|
||||
public void DialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
|
||||
{
|
||||
if (args.Result == ContentDialogResult.None)
|
||||
{
|
||||
args.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowDialog(CancellationTokenSource cancellationTokenSource)
|
||||
{
|
||||
CancellationTokenSource = cancellationTokenSource;
|
||||
|
||||
_ = ShowAsync();
|
||||
}
|
||||
|
||||
public void Complete(bool cancel)
|
||||
{
|
||||
State = cancel ? AccountCreationDialogState.Canceled : AccountCreationDialogState.Completed;
|
||||
|
||||
// Unregister from closing event.
|
||||
Closing -= DialogClosing;
|
||||
|
||||
if (cancel && !CancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,38 +43,91 @@
|
||||
</ContentDialog.Resources>
|
||||
|
||||
<Grid MinWidth="400" RowSpacing="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Visibility="{x:Bind IsProviderSelectionVisible, Mode=OneWay}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Account Name -->
|
||||
<TextBox
|
||||
x:Name="AccountNameTextbox"
|
||||
Header="{x:Bind domain:Translator.NewAccountDialog_AccountName}"
|
||||
PlaceholderText="{x:Bind domain:Translator.NewAccountDialog_AccountNamePlaceholder}"
|
||||
TextChanged="AccountNameChanged" />
|
||||
<!-- Account Name -->
|
||||
<TextBox
|
||||
x:Name="AccountNameTextbox"
|
||||
Header="{x:Bind domain:Translator.NewAccountDialog_AccountName}"
|
||||
PlaceholderText="{x:Bind domain:Translator.NewAccountDialog_AccountNamePlaceholder}"
|
||||
TextChanged="InputChanged" />
|
||||
|
||||
<!--
|
||||
TODO: Move Name, Sender Name and Color Picker to another Frame.
|
||||
Provider selection should be first, then account details.
|
||||
-->
|
||||
<!--<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Color" />
|
||||
<muxc:ColorPicker x:Name="AccountColorPicker" Grid.Column="1" />
|
||||
</Grid>-->
|
||||
<!--
|
||||
TODO: Move Name, Sender Name and Color Picker to another Frame.
|
||||
Provider selection should be first, then account details.
|
||||
-->
|
||||
<!--<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Color" />
|
||||
<muxc:ColorPicker x:Name="AccountColorPicker" Grid.Column="1" />
|
||||
</Grid>-->
|
||||
|
||||
<ListView
|
||||
Grid.Row="2"
|
||||
Padding="0"
|
||||
ItemTemplate="{StaticResource NewMailProviderTemplate}"
|
||||
ItemsSource="{x:Bind Providers}"
|
||||
SelectedItem="{x:Bind SelectedMailProvider, Mode=TwoWay}"
|
||||
SelectionMode="Single" />
|
||||
<ListView
|
||||
Grid.Row="2"
|
||||
Padding="0"
|
||||
ItemTemplate="{StaticResource NewMailProviderTemplate}"
|
||||
ItemsSource="{x:Bind Providers}"
|
||||
SelectedItem="{x:Bind SelectedMailProvider, Mode=TwoWay}"
|
||||
SelectionMode="Single" />
|
||||
</Grid>
|
||||
|
||||
<!-- Known special IMAP login details. -->
|
||||
<Grid RowSpacing="12" Visibility="{x:Bind IsSpecialImapServerPartVisible, Mode=OneWay}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Button Click="BackClicked">
|
||||
<Button.Content>
|
||||
<Viewbox Width="16">
|
||||
<PathIcon Data="F1 M 20 9.375 C 20 9.544271 19.93815 9.690756 19.814453 9.814453 C 19.690754 9.938151 19.54427 10 19.375 10 L 2.138672 10 L 9.814453 17.685547 C 9.93815 17.809244 10 17.955729 10 18.125 C 10 18.294271 9.93815 18.440756 9.814453 18.564453 C 9.690755 18.68815 9.544271 18.75 9.375 18.75 C 9.205729 18.75 9.059244 18.68815 8.935547 18.564453 L 0.214844 9.84375 C 0.143229 9.772136 0.089518 9.700521 0.053711 9.628906 C 0.017904 9.557292 0 9.472656 0 9.375 C 0 9.277344 0.017904 9.192709 0.053711 9.121094 C 0.089518 9.049479 0.143229 8.977865 0.214844 8.90625 L 8.935547 0.185547 C 9.059244 0.06185 9.205729 0 9.375 0 C 9.544271 0 9.690755 0.06185 9.814453 0.185547 C 9.93815 0.309246 10 0.45573 10 0.625 C 10 0.794271 9.93815 0.940756 9.814453 1.064453 L 2.138672 8.75 L 19.375 8.75 C 19.54427 8.75 19.690754 8.81185 19.814453 8.935547 C 19.93815 9.059245 20 9.205729 20 9.375 Z " />
|
||||
</Viewbox>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
|
||||
<Image
|
||||
Width="150"
|
||||
Height="50"
|
||||
HorizontalAlignment="Center"
|
||||
Source="{x:Bind SelectedMailProvider.ProviderImage, Mode=OneWay}" />
|
||||
|
||||
<TextBox
|
||||
x:Name="DisplayNameTextBox"
|
||||
Grid.Row="1"
|
||||
Header="Display Name"
|
||||
PlaceholderText="eg. John Doe"
|
||||
TextChanged="InputChanged" />
|
||||
|
||||
<TextBox
|
||||
x:Name="SpecialImapAddress"
|
||||
Grid.Row="2"
|
||||
Header="E-mail Address"
|
||||
PlaceholderText="eg. johndoe@testmail.com"
|
||||
TextChanged="InputChanged" />
|
||||
|
||||
<PasswordBox
|
||||
x:Name="AppSpecificPassword"
|
||||
Grid.Row="3"
|
||||
Header="App-Specific Password"
|
||||
PasswordChanged="ImapPasswordChanged" />
|
||||
|
||||
<HyperlinkButton
|
||||
Grid.Row="4"
|
||||
HorizontalAlignment="Right"
|
||||
Click="AppSpecificHelpButtonClicked"
|
||||
Content="How do I get app-specific password?" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
|
||||
@@ -8,6 +11,17 @@ namespace Wino.Core.UWP.Dialogs
|
||||
{
|
||||
public sealed partial class NewAccountDialog : ContentDialog
|
||||
{
|
||||
private Dictionary<SpecialImapProvider, string> helpingLinks = new Dictionary<SpecialImapProvider, string>()
|
||||
{
|
||||
{ SpecialImapProvider.iCloud, "https://support.apple.com/en-us/102654" },
|
||||
{ SpecialImapProvider.Yahoo, "http://help.yahoo.com/kb/SLN15241.html" },
|
||||
};
|
||||
|
||||
public static readonly DependencyProperty IsProviderSelectionVisibleProperty = DependencyProperty.Register(nameof(IsProviderSelectionVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(true));
|
||||
public static readonly DependencyProperty IsSpecialImapServerPartVisibleProperty = DependencyProperty.Register(nameof(IsSpecialImapServerPartVisible), typeof(bool), typeof(NewAccountDialog), new PropertyMetadata(false));
|
||||
public static readonly DependencyProperty SelectedMailProviderProperty = DependencyProperty.Register(nameof(SelectedMailProvider), typeof(ProviderDetail), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedProviderChanged)));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets current selected mail provider in the dialog.
|
||||
/// </summary>
|
||||
@@ -17,7 +31,18 @@ namespace Wino.Core.UWP.Dialogs
|
||||
set { SetValue(SelectedMailProviderProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedMailProviderProperty = DependencyProperty.Register(nameof(SelectedMailProvider), typeof(ProviderDetail), typeof(NewAccountDialog), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedProviderChanged)));
|
||||
|
||||
public bool IsProviderSelectionVisible
|
||||
{
|
||||
get { return (bool)GetValue(IsProviderSelectionVisibleProperty); }
|
||||
set { SetValue(IsProviderSelectionVisibleProperty, value); }
|
||||
}
|
||||
|
||||
public bool IsSpecialImapServerPartVisible
|
||||
{
|
||||
get { return (bool)GetValue(IsSpecialImapServerPartVisibleProperty); }
|
||||
set { SetValue(IsSpecialImapServerPartVisibleProperty, value); }
|
||||
}
|
||||
|
||||
// List of available mail providers for now.
|
||||
|
||||
@@ -45,16 +70,40 @@ namespace Wino.Core.UWP.Dialogs
|
||||
|
||||
private void CreateClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
|
||||
{
|
||||
if (IsSpecialImapServerPartVisible)
|
||||
{
|
||||
// Special imap detail input.
|
||||
|
||||
var details = new SpecialImapProviderDetails(SpecialImapAddress.Text.Trim(), AppSpecificPassword.Password.Trim(), DisplayNameTextBox.Text.Trim(), SelectedMailProvider.SpecialImapProvider);
|
||||
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), details);
|
||||
Hide();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Validate();
|
||||
|
||||
if (IsSecondaryButtonEnabled)
|
||||
{
|
||||
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim());
|
||||
Hide();
|
||||
if (SelectedMailProvider.SpecialImapProvider != SpecialImapProvider.None)
|
||||
{
|
||||
// This step requires app-sepcific password login for some providers.
|
||||
args.Cancel = true;
|
||||
|
||||
IsProviderSelectionVisible = false;
|
||||
IsSpecialImapServerPartVisible = true;
|
||||
|
||||
Validate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = new AccountCreationDialogResult(SelectedMailProvider.Type, AccountNameTextbox.Text.Trim(), null);
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AccountNameChanged(object sender, TextChangedEventArgs e) => Validate();
|
||||
private void InputChanged(object sender, TextChangedEventArgs e) => Validate();
|
||||
private void SenderNameChanged(object sender, TextChangedEventArgs e) => Validate();
|
||||
|
||||
private void Validate()
|
||||
@@ -68,7 +117,10 @@ namespace Wino.Core.UWP.Dialogs
|
||||
{
|
||||
bool shouldEnable = SelectedMailProvider != null
|
||||
&& SelectedMailProvider.IsSupported
|
||||
&& !string.IsNullOrEmpty(AccountNameTextbox.Text);
|
||||
&& !string.IsNullOrEmpty(AccountNameTextbox.Text)
|
||||
&& (IsSpecialImapServerPartVisible ? (!string.IsNullOrEmpty(AppSpecificPassword.Password)
|
||||
&& !string.IsNullOrEmpty(DisplayNameTextBox.Text)
|
||||
&& EmailValidation.EmailValidator.Validate(SpecialImapAddress.Text)) : true);
|
||||
|
||||
IsPrimaryButtonEnabled = shouldEnable;
|
||||
}
|
||||
@@ -79,5 +131,22 @@ namespace Wino.Core.UWP.Dialogs
|
||||
}
|
||||
|
||||
private void DialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => Validate();
|
||||
|
||||
private void BackClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IsSpecialImapServerPartVisible = false;
|
||||
IsProviderSelectionVisible = true;
|
||||
|
||||
Validate();
|
||||
}
|
||||
|
||||
private void ImapPasswordChanged(object sender, RoutedEventArgs e) => Validate();
|
||||
|
||||
private async void AppSpecificHelpButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var helpUrl = helpingLinks[SelectedMailProvider.SpecialImapProvider];
|
||||
|
||||
await Launcher.LaunchUriAsync(new Uri(helpUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Markup;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.UWP.Controls;
|
||||
@@ -262,17 +263,31 @@ namespace Wino.Helpers
|
||||
};
|
||||
}
|
||||
|
||||
public static WinoIconGlyph GetProviderIcon(MailProviderType providerType)
|
||||
|
||||
public static WinoIconGlyph GetProviderIcon(MailProviderType providerType, SpecialImapProvider specialImapProvider)
|
||||
{
|
||||
return providerType switch
|
||||
if (specialImapProvider == SpecialImapProvider.None)
|
||||
{
|
||||
MailProviderType.Outlook => WinoIconGlyph.Microsoft,
|
||||
MailProviderType.Gmail => WinoIconGlyph.Google,
|
||||
MailProviderType.Office365 => WinoIconGlyph.Microsoft,
|
||||
MailProviderType.IMAP4 => WinoIconGlyph.IMAP,
|
||||
_ => WinoIconGlyph.None,
|
||||
};
|
||||
return providerType switch
|
||||
{
|
||||
MailProviderType.Outlook => WinoIconGlyph.Microsoft,
|
||||
MailProviderType.Gmail => WinoIconGlyph.Google,
|
||||
MailProviderType.IMAP4 => WinoIconGlyph.IMAP,
|
||||
_ => WinoIconGlyph.None,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return specialImapProvider switch
|
||||
{
|
||||
SpecialImapProvider.iCloud => WinoIconGlyph.Apple,
|
||||
SpecialImapProvider.Yahoo => WinoIconGlyph.Yahoo,
|
||||
_ => WinoIconGlyph.None,
|
||||
};
|
||||
}
|
||||
}
|
||||
public static WinoIconGlyph GetProviderIcon(MailAccount account)
|
||||
=> GetProviderIcon(account.ProviderType, account.SpecialImapProvider);
|
||||
|
||||
public static Geometry GetPathGeometry(string pathMarkup)
|
||||
{
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Wino.Core.UWP.Services
|
||||
return file;
|
||||
}
|
||||
|
||||
public virtual IAccountCreationDialog GetAccountCreationDialog(MailProviderType type)
|
||||
public virtual IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult)
|
||||
{
|
||||
return new AccountCreationDialog
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using Wino.Core.Integration.Json;
|
||||
using Wino.Messaging;
|
||||
using Wino.Messaging.Client.Connection;
|
||||
using Wino.Messaging.Enums;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.UWP.Services
|
||||
@@ -256,6 +257,9 @@ namespace Wino.Core.UWP.Services
|
||||
case nameof(CopyAuthURLRequested):
|
||||
WeakReferenceMessenger.Default.Send(JsonSerializer.Deserialize(messageJson, CommunicationMessagesContext.Default.CopyAuthURLRequested));
|
||||
break;
|
||||
case nameof(NewMailSynchronizationRequested):
|
||||
WeakReferenceMessenger.Default.Send(JsonSerializer.Deserialize<NewMailSynchronizationRequested>(messageJson));
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid data type name passed to client.");
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
Header="{x:Bind Account.Name}"
|
||||
IsClickEnabled="True">
|
||||
<winuiControls:SettingsCard.HeaderIcon>
|
||||
<coreControls:WinoFontIcon FontSize="64" Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(ProviderDetail.Type)}" />
|
||||
<coreControls:WinoFontIcon FontSize="64" Icon="{x:Bind helpers:XamlHelpers.GetProviderIcon(Account)}" />
|
||||
</winuiControls:SettingsCard.HeaderIcon>
|
||||
</winuiControls:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<None Remove="Assets\FileTypes\type_rar.png" />
|
||||
<None Remove="Assets\FileTypes\type_video.png" />
|
||||
<None Remove="Assets\Providers\Gmail.png" />
|
||||
<None Remove="Assets\Providers\iCloud.png" />
|
||||
<None Remove="Assets\Providers\IMAP4.png" />
|
||||
<None Remove="Assets\Providers\Office 365.png" />
|
||||
<None Remove="Assets\Providers\Outlook.png" />
|
||||
@@ -69,6 +70,7 @@
|
||||
<Content Include="Assets\FileTypes\type_rar.png" />
|
||||
<Content Include="Assets\FileTypes\type_video.png" />
|
||||
<Content Include="Assets\Providers\Gmail.png" />
|
||||
<Content Include="Assets\Providers\iCloud.png" />
|
||||
<Content Include="Assets\Providers\IMAP4.png" />
|
||||
<Content Include="Assets\Providers\Office 365.png" />
|
||||
<Content Include="Assets\Providers\Outlook.png" />
|
||||
@@ -99,6 +101,7 @@
|
||||
<PackageReference Include="Microsoft.AppCenter.Analytics" />
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" />
|
||||
<PackageReference Include="Win2D.uwp" />
|
||||
<PackageReference Include="EmailValidation" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||
|
||||
Reference in New Issue
Block a user