Imap setup simplified and fixed the threading issues.

This commit is contained in:
Burak Kaan Köse
2026-04-13 23:11:35 +02:00
parent a2acad9ea4
commit 2e36772a4c
4 changed files with 268 additions and 286 deletions
@@ -16,7 +16,6 @@ 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;
@@ -319,7 +318,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
try
{
var minimalSettings = BuildMinimalSettingsOrThrow();
await AutoDiscoverAndApplySettingsAsync(minimalSettings).ConfigureAwait(false);
await AutoDiscoverAndApplySettingsAsync(minimalSettings);
_mailDialogService.InfoBarMessage(
Translator.IMAPSetupDialog_ValidationSuccess_Title,
@@ -399,7 +398,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
{
try
{
await EnsureImapSettingsPreparedAsync().ConfigureAwait(false);
await EnsureImapSettingsPreparedAsync();
var serverInformation = BuildServerInformation();
@@ -407,12 +406,12 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
ValidateImapSettings(serverInformation);
ValidateCalendarModeSpecificSettings(serverInformation);
await ValidateImapConnectivityAsync(serverInformation).ConfigureAwait(false);
await ValidateImapConnectivityAsync(serverInformation);
IsImapValidationSucceeded = true;
if (serverInformation.CalendarSupportMode == ImapCalendarSupportMode.CalDav)
{
await ValidateCalDavConnectivityAsync(serverInformation).ConfigureAwait(false);
await ValidateCalDavConnectivityAsync(serverInformation);
IsCalDavValidationSucceeded = true;
}
else
@@ -432,7 +431,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
return;
}
await SaveEditFlowAsync(serverInformation).ConfigureAwait(false);
await SaveEditFlowAsync(serverInformation);
}
catch (Exception ex)
{
@@ -654,7 +653,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
return;
var minimalSettings = BuildMinimalSettingsOrThrow();
await AutoDiscoverAndApplySettingsAsync(minimalSettings).ConfigureAwait(false);
await AutoDiscoverAndApplySettingsAsync(minimalSettings);
if (!HasCompleteImapSettings())
throw new InvalidOperationException(Translator.Exception_ImapAutoDiscoveryFailed);
@@ -676,11 +675,13 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
if (serverInformation == null)
throw new InvalidOperationException(Translator.Exception_ImapAutoDiscoveryFailed);
await ExecuteUIThread(async () =>
{
ApplyServerInformation(serverInformation);
if (IsCalendarSupportEnabled && SelectedCalendarSupportMode == ImapCalendarSupportMode.CalDav)
{
var discoveredCalDavUri = await _autoDiscoveryService.DiscoverCalDavServiceUriAsync(minimalSettings.Email).ConfigureAwait(false);
var discoveredCalDavUri = await _autoDiscoveryService.DiscoverCalDavServiceUriAsync(minimalSettings.Email);
if (discoveredCalDavUri != null)
{
CalDavServiceUrl = discoveredCalDavUri.ToString();
@@ -692,6 +693,7 @@ public partial class ImapCalDavSettingsPageViewModel : MailBaseViewModel
if (string.IsNullOrWhiteSpace(CalDavPassword))
CalDavPassword = minimalSettings.Password;
}
});
}
private async Task ValidateImapConnectivityAsync(CustomServerInformation serverInformation)
{
@@ -4,17 +4,15 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:abstract="using:Wino.Views.Abstract"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="using:Wino.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel
<Grid
MaxWidth="980"
Padding="36,28,36,36"
HorizontalAlignment="Stretch"
Spacing="24">
<!-- Page Header -->
HorizontalAlignment="Center">
<StackPanel Spacing="20">
<StackPanel Spacing="4">
<TextBlock
FontSize="28"
@@ -33,20 +31,12 @@
Visibility="{x:Bind ViewModel.HasProviderHint, Mode=OneWay}" />
</StackPanel>
<!-- Setup Mode Selector -->
<SelectorBar x:Name="SetupModeSelector" SelectionChanged="OnSetupModeSelectionChanged">
<SelectorBarItem Icon="Library" Text="{x:Bind ViewModel.BasicTabText, Mode=OneWay}" />
<SelectorBarItem Icon="Setting" Text="{x:Bind ViewModel.AdvancedTabText, Mode=OneWay}" />
</SelectorBar>
<!-- Basic Setup Card -->
<Border
Padding="20"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
Visibility="{x:Bind helpers:XamlHelpers.ReverseBoolToVisibilityConverter(ViewModel.IsAdvancedSetupSelected), Mode=OneWay}">
CornerRadius="8">
<StackPanel Spacing="16">
<StackPanel Spacing="2">
<TextBlock
@@ -60,44 +50,61 @@
TextWrapping="WrapWholeWords" />
</StackPanel>
<Grid ColumnSpacing="12">
<Grid ColumnSpacing="12" RowSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox
Grid.Row="0"
Grid.Column="0"
Header="{x:Bind ViewModel.DisplayNameHeaderText, Mode=OneWay}"
PlaceholderText="{x:Bind ViewModel.DisplayNamePlaceholderText, Mode=OneWay}"
Text="{x:Bind ViewModel.DisplayName, Mode=TwoWay}" />
<TextBox
Grid.Row="0"
Grid.Column="1"
Header="{x:Bind ViewModel.EmailAddressHeaderText, Mode=OneWay}"
PlaceholderText="{x:Bind ViewModel.EmailAddressPlaceholderText, Mode=OneWay}"
Text="{x:Bind ViewModel.EmailAddress, Mode=TwoWay}" />
<PasswordBox
Grid.Row="1"
Grid.ColumnSpan="2"
Header="{x:Bind ViewModel.PasswordHeaderText, Mode=OneWay}"
Password="{x:Bind ViewModel.Password, Mode=TwoWay}" />
</Grid>
<PasswordBox Header="{x:Bind ViewModel.PasswordHeaderText, Mode=OneWay}" Password="{x:Bind ViewModel.Password, Mode=TwoWay}" />
<CheckBox Content="{x:Bind ViewModel.EnableCalendarSupportText, Mode=OneWay}" IsChecked="{x:Bind ViewModel.IsCalendarSupportEnabled, Mode=TwoWay}" />
<CheckBox
Content="{x:Bind ViewModel.EnableCalendarSupportText, Mode=OneWay}"
IsChecked="{x:Bind ViewModel.IsCalendarSupportEnabled, Mode=TwoWay}" />
<StackPanel Spacing="8">
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.AdvancedSectionDescriptionText, Mode=OneWay}"
TextWrapping="WrapWholeWords" />
<Button
HorizontalAlignment="Left"
Command="{x:Bind ViewModel.AutoDiscoverSettingsCommand}"
Content="{x:Bind ViewModel.AutoDiscoverButtonText, Mode=OneWay}"
Style="{ThemeResource AccentButtonStyle}" />
</StackPanel>
</StackPanel>
</Border>
<!-- Advanced Setup Card -->
<Border
Padding="20"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8"
Visibility="{x:Bind helpers:XamlHelpers.ReverseBoolToVisibilityConverter(ViewModel.IsBasicSetupSelected), Mode=OneWay}">
<StackPanel Spacing="20">
CornerRadius="8">
<StackPanel Spacing="16">
<StackPanel Spacing="2">
<TextBlock
FontSize="16"
@@ -110,13 +117,12 @@
TextWrapping="WrapWholeWords" />
</StackPanel>
<Grid ColumnSpacing="24">
<Grid ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Incoming (IMAP) Settings -->
<Border
Padding="16"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
@@ -131,19 +137,16 @@
<TextBox Header="{x:Bind ViewModel.IncomingUsernameHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.IncomingServerUsername, Mode=TwoWay}" />
<PasswordBox Header="{x:Bind ViewModel.IncomingPasswordHeaderText, Mode=OneWay}" Password="{x:Bind ViewModel.IncomingServerPassword, Mode=TwoWay}" />
<ComboBox
HorizontalAlignment="Stretch"
Header="{x:Bind ViewModel.ConnectionSecurityHeaderText, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.AvailableConnectionSecurityDisplayNames}"
SelectedIndex="{x:Bind ViewModel.SelectedIncomingServerConnectionSecurityIndex, Mode=TwoWay}" />
<ComboBox
HorizontalAlignment="Stretch"
Header="{x:Bind ViewModel.AuthenticationMethodHeaderText, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.AvailableAuthenticationMethodDisplayNames}"
SelectedIndex="{x:Bind ViewModel.SelectedIncomingServerAuthenticationMethodIndex, Mode=TwoWay}" />
</StackPanel>
</Border>
<!-- Outgoing (SMTP) Settings -->
<Border
Grid.Column="1"
Padding="16"
@@ -159,22 +162,24 @@
<TextBox Header="{x:Bind ViewModel.OutgoingUsernameHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.OutgoingServerUsername, Mode=TwoWay}" />
<PasswordBox Header="{x:Bind ViewModel.OutgoingPasswordHeaderText, Mode=OneWay}" Password="{x:Bind ViewModel.OutgoingServerPassword, Mode=TwoWay}" />
<ComboBox
HorizontalAlignment="Stretch"
Header="{x:Bind ViewModel.ConnectionSecurityHeaderText, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.AvailableConnectionSecurityDisplayNames}"
SelectedIndex="{x:Bind ViewModel.SelectedOutgoingServerConnectionSecurityIndex, Mode=TwoWay}" />
<ComboBox
HorizontalAlignment="Stretch"
Header="{x:Bind ViewModel.AuthenticationMethodHeaderText, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.AvailableAuthenticationMethodDisplayNames}"
SelectedIndex="{x:Bind ViewModel.SelectedOutgoingServerAuthenticationMethodIndex, Mode=TwoWay}" />
</StackPanel>
</Border>
</Grid>
<Button
HorizontalAlignment="Right"
Command="{x:Bind ViewModel.TestImapConnectionCommand}"
Content="{x:Bind ViewModel.TestImapButtonText, Mode=OneWay}" />
</StackPanel>
</Border>
<!-- Calendar Settings Card -->
<Border
Padding="20"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
@@ -198,7 +203,6 @@
</StackPanel>
<ComboBox
HorizontalAlignment="Stretch"
Header="{x:Bind ViewModel.CalendarModeHeaderText, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.IsCalendarModeSelectionVisible, Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.AvailableCalendarSupportModeTitles}"
@@ -213,6 +217,7 @@
<HyperlinkButton
Command="{x:Bind ViewModel.ShowLocalCalendarExplanationCommand}"
Content="{x:Bind ViewModel.LocalCalendarLearnMoreText, Mode=OneWay}"
HorizontalAlignment="Left"
IsEnabled="{x:Bind ViewModel.IsLocalCalendarModeSelected, Mode=OneWay}" />
<Grid ColumnSpacing="12" Visibility="{x:Bind ViewModel.IsCalDavSettingsVisible, Mode=OneWay}">
@@ -234,37 +239,32 @@
Header="{x:Bind ViewModel.CalDavPasswordHeaderText, Mode=OneWay}"
Password="{x:Bind ViewModel.CalDavPassword, Mode=TwoWay}"
Visibility="{x:Bind ViewModel.IsCalDavSettingsVisible, Mode=OneWay}" />
<Button
HorizontalAlignment="Right"
Command="{x:Bind ViewModel.TestCalDavConnectionCommand}"
Content="{x:Bind ViewModel.TestCalDavButtonText, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.IsCalDavSettingsVisible, Mode=OneWay}" />
</StackPanel>
</Border>
<!-- Action Bar -->
<Grid Margin="0,4,0,0" ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button
Grid.Column="0"
Command="{x:Bind ViewModel.TestImapConnectionCommand}"
Content="{x:Bind ViewModel.TestImapButtonText, Mode=OneWay}" />
<Button
Grid.Column="1"
Command="{x:Bind ViewModel.TestCalDavConnectionCommand}"
Content="{x:Bind ViewModel.TestCalDavButtonText, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.IsCalDavSettingsVisible, Mode=OneWay}" />
<Button
Grid.Column="3"
Command="{x:Bind ViewModel.CancelCommand}"
Content="{x:Bind ViewModel.CancelButtonText, Mode=OneWay}" />
<Button
Grid.Column="4"
Grid.Column="2"
Command="{x:Bind ViewModel.SaveCommand}"
Content="{x:Bind ViewModel.SaveButtonText, Mode=OneWay}"
Style="{ThemeResource AccentButtonStyle}" />
</Grid>
</StackPanel>
</Grid>
</ScrollViewer>
</abstract:ImapCalDavSettingsPageAbstract>
@@ -1,5 +1,3 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
using Wino.Views.Abstract;
namespace Wino.Views;
@@ -10,22 +8,4 @@ public sealed partial class ImapCalDavSettingsPage : ImapCalDavSettingsPageAbstr
{
InitializeComponent();
}
private void OnSetupModeSelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs e)
{
ViewModel.SelectedSetupTabIndex = SetupModeSelector.SelectedItem == null ? 0 : SetupModeSelector.Items.IndexOf(SetupModeSelector.SelectedItem);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var tabIndex = ViewModel.SelectedSetupTabIndex;
if (tabIndex < 0 || tabIndex >= SetupModeSelector.Items.Count)
{
tabIndex = 0;
}
SetupModeSelector.SelectedItem = SetupModeSelector.Items[tabIndex];
}
}
+1 -1
View File
@@ -475,7 +475,7 @@ public class AccountService : BaseDatabaseService, IAccountService
public async Task UpdateAccountCustomServerInformationAsync(CustomServerInformation customServerInformation)
{
await Connection.UpdateAsync(customServerInformation, typeof(CustomServerInformation)).ConfigureAwait(false);
await Connection.InsertOrReplaceAsync(customServerInformation, typeof(CustomServerInformation)).ConfigureAwait(false);
}
public async Task UpdateAccountAliasesAsync(Guid accountId, List<MailAccountAlias> aliases)