Removed migrations. New onboarding screen and wizard like steps.
This commit is contained in:
+33
-51
@@ -23,9 +23,9 @@ using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Domain.Models.Updates;
|
||||
using Wino.Mail.Services;
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.WinUI.Activation;
|
||||
using Wino.Mail.WinUI.Interfaces;
|
||||
using Wino.Mail.WinUI.Models;
|
||||
@@ -42,6 +42,7 @@ public partial class App : WinoApplication,
|
||||
IRecipient<NewMailSynchronizationRequested>,
|
||||
IRecipient<NewCalendarSynchronizationRequested>,
|
||||
IRecipient<AccountCreatedMessage>,
|
||||
IRecipient<AccountRemovedMessage>,
|
||||
IRecipient<GetStartedFromWelcomeRequested>
|
||||
{
|
||||
private const int InboxSyncsPerFullSync = 20;
|
||||
@@ -146,6 +147,10 @@ public partial class App : WinoApplication,
|
||||
services.AddTransient(typeof(AccountManagementViewModel));
|
||||
services.AddTransient(typeof(WelcomePageViewModel));
|
||||
services.AddTransient(typeof(WelcomePageV2ViewModel));
|
||||
services.AddTransient(typeof(ProviderSelectionPageViewModel));
|
||||
services.AddTransient(typeof(AccountSetupProgressPageViewModel));
|
||||
services.AddTransient(typeof(SpecialImapCredentialsPageViewModel));
|
||||
services.AddSingleton(typeof(WelcomeWizardContext));
|
||||
|
||||
services.AddTransient(typeof(ComposePageViewModel));
|
||||
services.AddTransient(typeof(IdlePageViewModel));
|
||||
@@ -218,18 +223,10 @@ public partial class App : WinoApplication,
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether the new version requires a migration before starting sync.
|
||||
var updateManager = Services.GetRequiredService<IUpdateManager>();
|
||||
var updateNotes = await updateManager.GetLatestUpdateNotesAsync();
|
||||
bool hasPendingMigration = updateNotes.HasPendingMigrations && updateManager.HasPendingMigrations();
|
||||
|
||||
_preferencesService.PreferenceChanged -= PreferencesServiceChanged;
|
||||
_preferencesService.PreferenceChanged += PreferencesServiceChanged;
|
||||
|
||||
// Hold off sync loop when a migration is required in startup-task (tray-only) mode.
|
||||
// In foreground mode the sync loop starts normally; the ViewModel dialog handles migrations before sync kicks in.
|
||||
if (!hasPendingMigration || !IsStartupTaskLaunch())
|
||||
RestartAutoSynchronizationLoop();
|
||||
RestartAutoSynchronizationLoop();
|
||||
|
||||
// Check if launched from toast notification.
|
||||
if (IsNotificationActivation(out AppNotificationActivatedEventArgs toastArgs))
|
||||
@@ -253,16 +250,7 @@ public partial class App : WinoApplication,
|
||||
// Otherwise, activate the window normally.
|
||||
if (isStartupTaskLaunch)
|
||||
{
|
||||
if (hasPendingMigration)
|
||||
{
|
||||
// Notify the user to open the app to complete the update before sync can resume.
|
||||
Services.GetRequiredService<INotificationBuilder>().CreateMigrationRequiredNotification();
|
||||
LogActivation("Migration required for new version. Sync skipped. User notified via toast.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogActivation("Launched by startup task. Window created but hidden (system tray only).");
|
||||
}
|
||||
LogActivation("Launched by startup task. Window created but hidden (system tray only).");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -305,13 +293,6 @@ public partial class App : WinoApplication,
|
||||
{
|
||||
var toastArguments = ToastArguments.Parse(toastArgs.Argument);
|
||||
|
||||
// Check migration notification activation first.
|
||||
if (toastArguments.Contains(Constants.ToastMigrationRequiredKey))
|
||||
{
|
||||
await HandleMigrationToastActivationAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check calendar reminder toast activation first.
|
||||
if (toastArguments.TryGetValue(Constants.ToastCalendarActionKey, out string calendarAction) &&
|
||||
calendarAction == Constants.ToastCalendarNavigateAction &&
|
||||
@@ -341,29 +322,6 @@ public partial class App : WinoApplication,
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles activation from the migration-required toast notification.
|
||||
/// Opens the app so the shell ViewModel can show the What's New dialog and run migrations.
|
||||
/// </summary>
|
||||
private async Task HandleMigrationToastActivationAsync()
|
||||
{
|
||||
LogActivation("Handling migration toast activation.");
|
||||
|
||||
if (!IsAppRunning())
|
||||
{
|
||||
await CreateAndActivateWindow(null!);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsureMainWindowVisibleAndForeground();
|
||||
}
|
||||
|
||||
// The MailAppShellViewModel.OnNavigatedTo will detect ShouldShowUpdateNotes() == true
|
||||
// and display the What's New dialog (including running migrations) once the XamlRoot is ready.
|
||||
// Restart sync in case it was blocked.
|
||||
RestartAutoSynchronizationLoop();
|
||||
}
|
||||
|
||||
private async Task HandleCalendarToastNavigationAsync(Guid calendarItemId)
|
||||
{
|
||||
var calendarService = Services.GetRequiredService<ICalendarService>();
|
||||
@@ -593,7 +551,7 @@ public partial class App : WinoApplication,
|
||||
InitializeNavigationDispatcher();
|
||||
|
||||
Services.GetRequiredService<INavigationService>()
|
||||
.Navigate(WinoPage.WelcomePageV2, null, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.None);
|
||||
.Navigate(WinoPage.WelcomeHostPage, null, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.None);
|
||||
}
|
||||
|
||||
private void InitializeNavigationDispatcher()
|
||||
@@ -627,6 +585,7 @@ public partial class App : WinoApplication,
|
||||
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<NewCalendarSynchronizationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<AccountCreatedMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<AccountRemovedMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<GetStartedFromWelcomeRequested>(this);
|
||||
}
|
||||
|
||||
@@ -699,6 +658,29 @@ public partial class App : WinoApplication,
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(AccountRemovedMessage message)
|
||||
{
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
|
||||
// Only handle when ShellWindow is active (not during wizard rollback)
|
||||
if (windowManager.GetWindow(WinoWindowKind.Shell) == null)
|
||||
return;
|
||||
|
||||
MainWindow?.DispatcherQueue?.TryEnqueue(async () =>
|
||||
{
|
||||
var accounts = await _accountService!.GetAccountsAsync();
|
||||
if (accounts.Any()) return;
|
||||
|
||||
// All accounts removed — go back to welcome wizard from step 1
|
||||
Services.GetRequiredService<WelcomeWizardContext>().Reset();
|
||||
StopAutoSynchronizationLoop();
|
||||
CreateWelcomeWindow();
|
||||
windowManager.HideWindow(WinoWindowKind.Shell);
|
||||
await NewThemeService.ApplyThemeToActiveWindowAsync();
|
||||
MainWindow?.Activate();
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(GetStartedFromWelcomeRequested message)
|
||||
{
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||
|
||||
<x:String x:Key="ThemeName">Clouds</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///Wino.Mail.WinUI/BackgroundImages/Clouds.jpg</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Clouds.jpg</x:String>
|
||||
|
||||
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||
|
||||
<x:String x:Key="ThemeName">Forest</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///Wino.Mail.WinUI/BackgroundImages/Forest.jpg</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Forest.jpg</x:String>
|
||||
|
||||
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||
|
||||
<x:String x:Key="ThemeName">Garden</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///Wino.Mail.WinUI/BackgroundImages/Garden.jpg</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Garden.jpg</x:String>
|
||||
|
||||
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||
|
||||
<x:String x:Key="ThemeName">Nighty</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///Wino.Mail.WinUI/BackgroundImages/Nighty.jpg</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Nighty.jpg</x:String>
|
||||
|
||||
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xaml="using:Microsoft.UI.Xaml">
|
||||
|
||||
<x:String x:Key="ThemeName">Snowflake</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///Wino.Mail.WinUI/BackgroundImages/Snowflake.jpg</x:String>
|
||||
<x:String x:Key="ThemeBackgroundImage">ms-appx:///BackgroundImages/Snowflake.jpg</x:String>
|
||||
|
||||
<ImageBrush x:Key="WinoApplicationBackgroundColor" ImageSource="{StaticResource ThemeBackgroundImage}" />
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor">Transparent</SolidColorBrush>
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
"hasPendingMigrations": true,
|
||||
"migration": {
|
||||
"titleKey": "WhatIsNew_MigrationPreparing_Title",
|
||||
"descriptionKey": "WhatIsNew_MigrationPreparing_Description"
|
||||
},
|
||||
"sections": [
|
||||
{
|
||||
"title": "# Wino Calendar is here!",
|
||||
|
||||
@@ -49,6 +49,7 @@ public static class CoreUWPContainerSetup
|
||||
services.AddTransient(typeof(AboutPageViewModel));
|
||||
services.AddTransient(typeof(SettingsPageViewModel));
|
||||
services.AddTransient(typeof(ManageAccountsPagePageViewModel));
|
||||
services.AddTransient(typeof(WelcomeHostPageViewModel));
|
||||
services.AddTransient(typeof(KeyboardShortcutsPageViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,40 +22,16 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<controls:UpdateNotesFlipViewControl x:Name="UpdateNotesControl" Sections="{x:Bind Sections, Mode=OneTime}" />
|
||||
|
||||
<StackPanel
|
||||
x:Name="MigrationPanel"
|
||||
Grid.Row="1"
|
||||
Spacing="8"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="MigrationTitleText" Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
<TextBlock x:Name="MigrationDescriptionText" TextWrapping="WrapWholeWords" />
|
||||
<ProgressBar
|
||||
x:Name="MigrationProgressBar"
|
||||
IsIndeterminate="True"
|
||||
Visibility="Collapsed" />
|
||||
<TextBlock
|
||||
x:Name="MigrationErrorText"
|
||||
Foreground="{ThemeResource SystemFillColorCriticalBrush}"
|
||||
TextWrapping="WrapWholeWords"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Button
|
||||
x:Name="ContinueAnywayButton"
|
||||
Click="OnContinueAnywayClicked"
|
||||
Content="{x:Bind domain:Translator.WhatIsNew_ContinueAnywayButton}"
|
||||
Visibility="Collapsed" />
|
||||
<Button
|
||||
x:Name="GetStartedButton"
|
||||
Click="OnGetStartedClicked"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Updates;
|
||||
|
||||
@@ -11,7 +9,6 @@ namespace Wino.Dialogs;
|
||||
public sealed partial class WhatIsNewDialog : ContentDialog
|
||||
{
|
||||
private readonly IUpdateManager _updateManager;
|
||||
private readonly UpdateNotes _notes;
|
||||
|
||||
public List<UpdateNoteSection> Sections { get; }
|
||||
|
||||
@@ -21,15 +18,12 @@ public sealed partial class WhatIsNewDialog : ContentDialog
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_notes = notes;
|
||||
_updateManager = updateManager;
|
||||
Sections = notes.Sections;
|
||||
|
||||
// Show the Get Started button immediately when there is only one page.
|
||||
UpdateNotesControl.SelectedIndexChanged += OnUpdateSectionChanged;
|
||||
UpdateGetStartedButtonVisibility(UpdateNotesControl.SelectedIndex);
|
||||
|
||||
InitializeMigrationStatus();
|
||||
Closing += OnDialogClosing;
|
||||
}
|
||||
|
||||
@@ -43,17 +37,6 @@ public sealed partial class WhatIsNewDialog : ContentDialog
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void InitializeMigrationStatus()
|
||||
{
|
||||
if (!_notes.HasPendingMigrations ||
|
||||
string.IsNullOrWhiteSpace(_notes.Migration.TitleKey) ||
|
||||
string.IsNullOrWhiteSpace(_notes.Migration.DescriptionKey))
|
||||
return;
|
||||
|
||||
MigrationTitleText.Text = Translator.GetTranslatedString(_notes.Migration.TitleKey);
|
||||
MigrationDescriptionText.Text = Translator.GetTranslatedString(_notes.Migration.DescriptionKey);
|
||||
}
|
||||
|
||||
private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args)
|
||||
{
|
||||
// Only allow closing when Get Started button was clicked.
|
||||
@@ -61,41 +44,9 @@ public sealed partial class WhatIsNewDialog : ContentDialog
|
||||
args.Cancel = true;
|
||||
}
|
||||
|
||||
private async void OnGetStartedClicked(object sender, RoutedEventArgs e)
|
||||
private void OnGetStartedClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
GetStartedButton.IsEnabled = false;
|
||||
ContinueAnywayButton.Visibility = Visibility.Collapsed;
|
||||
MigrationErrorText.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (_notes.HasPendingMigrations)
|
||||
{
|
||||
GetStartedButton.Content = Translator.WhatIsNew_PreparingForNewVersionButton;
|
||||
MigrationPanel.Visibility = Visibility.Visible;
|
||||
MigrationProgressBar.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _updateManager.RunPendingMigrationsAsync();
|
||||
_updateManager.MarkUpdateNotesAsSeen();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
MigrationProgressBar.Visibility = Visibility.Collapsed;
|
||||
MigrationErrorText.Text = string.Format(Translator.WhatIsNew_MigrationFailedMessage, ex.GetType().Name);
|
||||
MigrationErrorText.Visibility = Visibility.Visible;
|
||||
ContinueAnywayButton.Visibility = Visibility.Visible;
|
||||
GetStartedButton.IsEnabled = true;
|
||||
GetStartedButton.Content = Translator.WhatIsNew_GetStartedButton;
|
||||
return;
|
||||
}
|
||||
|
||||
_canClose = true;
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnContinueAnywayClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_updateManager.MarkUpdateNotesAsSeen();
|
||||
_canClose = true;
|
||||
Hide();
|
||||
|
||||
@@ -39,6 +39,7 @@ public static class XamlHelpers
|
||||
};
|
||||
}
|
||||
|
||||
public static Visibility BoolToVisibilityConverter(bool value) => value ? Visibility.Visible : Visibility.Collapsed;
|
||||
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
|
||||
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
|
||||
public static bool ReverseBoolConverter(bool value) => !value;
|
||||
@@ -129,6 +130,16 @@ public static class XamlHelpers
|
||||
|
||||
public static SolidColorBrush GetSolidColorBrushFromHex(string colorHex) => string.IsNullOrEmpty(colorHex) ? new SolidColorBrush(Colors.Transparent) : new SolidColorBrush(colorHex.ToColor());
|
||||
public static FontWeight GetFontWeightBySyncState(bool isSyncing) => isSyncing ? FontWeights.SemiBold : FontWeights.Normal;
|
||||
|
||||
public static Brush GetWizardStepBadgeBrush(bool isActive)
|
||||
=> isActive
|
||||
? (Brush)Application.Current.Resources["AccentFillColorDefaultBrush"]
|
||||
: new SolidColorBrush(Color.FromArgb(30, 128, 128, 128));
|
||||
|
||||
public static Brush GetWizardStepNumberForeground(bool isActive)
|
||||
=> isActive
|
||||
? new SolidColorBrush(Colors.White)
|
||||
: (Brush)Application.Current.Resources["TextFillColorSecondaryBrush"];
|
||||
public static FontWeight GetFontWeightByChildSelectedState(bool isChildSelected) => isChildSelected ? FontWeights.SemiBold : FontWeights.Normal;
|
||||
public static FontWeight GetFontWeightByReadState(bool isChildSelected) => isChildSelected ? FontWeights.Normal : FontWeights.SemiBold;
|
||||
public static Visibility StringToVisibilityConverter(string value) => string.IsNullOrWhiteSpace(value) ? Visibility.Collapsed : Visibility.Visible;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class CustomAppTheme : AppThemeBase
|
||||
|
||||
public override async Task<string> GetThemeResourceDictionaryContentAsync()
|
||||
{
|
||||
var customAppThemeFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Wino.Mail.WinUI/AppThemes/Custom.xaml"));
|
||||
var customAppThemeFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///AppThemes/Custom.xaml"));
|
||||
return await FileIO.ReadTextAsync(customAppThemeFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ public class PreDefinedAppTheme : AppThemeBase
|
||||
public override AppThemeType AppThemeType => AppThemeType.PreDefined;
|
||||
|
||||
public override string GetBackgroundPreviewImagePath()
|
||||
=> $"ms-appx:///Wino.Mail.WinUI/BackgroundImages/{ThemeName}.jpg";
|
||||
=> $"ms-appx:///BackgroundImages/{ThemeName}.jpg";
|
||||
|
||||
public override async Task<string> GetThemeResourceDictionaryContentAsync()
|
||||
{
|
||||
var xamlDictionaryFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx://AppThemes/{ThemeName}.xaml"));
|
||||
var xamlDictionaryFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///AppThemes/{ThemeName}.xaml"));
|
||||
return await FileIO.ReadTextAsync(xamlDictionaryFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,11 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
WinoPage.ComposePage,
|
||||
WinoPage.IdlePage,
|
||||
WinoPage.WelcomePage,
|
||||
WinoPage.WelcomePageV2
|
||||
WinoPage.WelcomePageV2,
|
||||
WinoPage.WelcomeHostPage,
|
||||
WinoPage.ProviderSelectionPage,
|
||||
WinoPage.AccountSetupProgressPage,
|
||||
WinoPage.SpecialImapCredentialsPage
|
||||
];
|
||||
|
||||
private static readonly WinoPage[] CalendarOnlyPages =
|
||||
@@ -116,6 +120,10 @@ public class NavigationService : NavigationServiceBase, INavigationService
|
||||
WinoPage.ContactsPage => typeof(ContactsPage),
|
||||
WinoPage.SignatureAndEncryptionPage => typeof(SignatureAndEncryptionPage),
|
||||
WinoPage.StoragePage => typeof(StoragePage),
|
||||
WinoPage.WelcomeHostPage => typeof(WelcomeHostPage),
|
||||
WinoPage.ProviderSelectionPage => typeof(ProviderSelectionPage),
|
||||
WinoPage.AccountSetupProgressPage => typeof(AccountSetupProgressPage),
|
||||
WinoPage.SpecialImapCredentialsPage => typeof(SpecialImapCredentialsPage),
|
||||
WinoPage.CalendarPage => typeof(CalendarPage),
|
||||
WinoPage.EventDetailsPage => typeof(EventDetailsPage),
|
||||
WinoPage.CalendarSettingsPage => typeof(CalendarSettingsPage),
|
||||
|
||||
@@ -317,20 +317,6 @@ public class NotificationBuilder : INotificationBuilder
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void CreateMigrationRequiredNotification()
|
||||
{
|
||||
var builder = new ToastContentBuilder();
|
||||
builder.SetToastScenario(ToastScenario.Default);
|
||||
|
||||
builder.AddText(Translator.WhatIsNew_MigrationNotification_Title);
|
||||
builder.AddText(Translator.WhatIsNew_MigrationNotification_Message);
|
||||
|
||||
builder.AddArgument(Constants.ToastMigrationRequiredKey, bool.TrueString);
|
||||
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||
|
||||
ShowToast(builder);
|
||||
}
|
||||
|
||||
private static void ShowToast(ToastContentBuilder builder, string? tag = null)
|
||||
{
|
||||
var toastNotification = new ToastNotification(builder.GetToastContent().GetXml());
|
||||
|
||||
@@ -107,6 +107,9 @@
|
||||
</controls:Segmented>
|
||||
</StackPanel>
|
||||
</TitleBar.RightHeader>
|
||||
<TitleBar.IconSource>
|
||||
<ImageIconSource ImageSource="/Assets/Wino_Icon.ico" />
|
||||
</TitleBar.IconSource>
|
||||
</TitleBar>
|
||||
|
||||
<Frame
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
public abstract class AccountSetupProgressPageAbstract : BasePage<AccountSetupProgressPageViewModel>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
public abstract class ProviderSelectionPageAbstract : BasePage<ProviderSelectionPageViewModel>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
public abstract class SpecialImapCredentialsPageAbstract : BasePage<SpecialImapCredentialsPageViewModel>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Mail.WinUI;
|
||||
|
||||
namespace Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
public abstract class WelcomeHostPageAbstract : BasePage<WelcomeHostPageViewModel>
|
||||
{
|
||||
}
|
||||
@@ -78,13 +78,9 @@
|
||||
Text="{x:Bind ViewModel.EmailAddress, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
|
||||
<PasswordBox
|
||||
Header="{x:Bind ViewModel.PasswordHeaderText, Mode=OneWay}"
|
||||
Password="{x:Bind ViewModel.Password, Mode=TwoWay}" />
|
||||
<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}" />
|
||||
|
||||
<Button
|
||||
HorizontalAlignment="Left"
|
||||
@@ -131,18 +127,10 @@
|
||||
<FontIcon FontSize="14" Glyph="" />
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind ViewModel.IncomingSectionTitleText, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
Header="{x:Bind ViewModel.IncomingServerHeaderText, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.IncomingServer, Mode=TwoWay}" />
|
||||
<TextBox
|
||||
Header="{x:Bind ViewModel.PortHeaderText, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.IncomingServerPort, Mode=TwoWay}" />
|
||||
<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}" />
|
||||
<TextBox Header="{x:Bind ViewModel.IncomingServerHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.IncomingServer, Mode=TwoWay}" />
|
||||
<TextBox Header="{x:Bind ViewModel.PortHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.IncomingServerPort, Mode=TwoWay}" />
|
||||
<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}"
|
||||
@@ -167,18 +155,10 @@
|
||||
<FontIcon FontSize="14" Glyph="" />
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind ViewModel.OutgoingSectionTitleText, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
Header="{x:Bind ViewModel.OutgoingServerHeaderText, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.OutgoingServer, Mode=TwoWay}" />
|
||||
<TextBox
|
||||
Header="{x:Bind ViewModel.PortHeaderText, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.OutgoingServerPort, Mode=TwoWay}" />
|
||||
<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}" />
|
||||
<TextBox Header="{x:Bind ViewModel.OutgoingServerHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.OutgoingServer, Mode=TwoWay}" />
|
||||
<TextBox Header="{x:Bind ViewModel.PortHeaderText, Mode=OneWay}" Text="{x:Bind ViewModel.OutgoingServerPort, Mode=TwoWay}" />
|
||||
<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}"
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<abstract:AccountSetupProgressPageAbstract
|
||||
x:Class="Wino.Views.AccountSetupProgressPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract"
|
||||
xmlns:accounts="using:Wino.Core.Domain.Models.Accounts"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:domain="using:Wino.Core.Domain"
|
||||
xmlns:helpers="using:Wino.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:winuiControls="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Padding="0,8">
|
||||
<StackPanel
|
||||
MaxWidth="500"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="24">
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.AccountSetup_Title}" />
|
||||
|
||||
<!-- Steps List -->
|
||||
<ListView
|
||||
IsItemClickEnabled="False"
|
||||
ItemsSource="{x:Bind ViewModel.Steps, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Padding" Value="0,6" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="accounts:AccountSetupStepModel">
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="28" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Status indicator -->
|
||||
<Grid
|
||||
Width="20"
|
||||
Height="20"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
|
||||
<!-- Pending: gray circle -->
|
||||
<FontIcon
|
||||
FontSize="16"
|
||||
Foreground="{ThemeResource TextFillColorDisabledBrush}"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(IsPending), Mode=OneWay}" />
|
||||
|
||||
<!-- InProgress: progress ring -->
|
||||
<winuiControls:ProgressRing
|
||||
Width="16"
|
||||
Height="16"
|
||||
IsActive="{x:Bind IsInProgress, Mode=OneWay}"
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(IsInProgress), Mode=OneWay}" />
|
||||
|
||||
<!-- Succeeded: green check -->
|
||||
<FontIcon
|
||||
FontSize="16"
|
||||
Foreground="#107C10"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(IsSucceeded), Mode=OneWay}" />
|
||||
|
||||
<!-- Failed: red error -->
|
||||
<FontIcon
|
||||
FontSize="16"
|
||||
Foreground="#D13438"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(IsFailed), Mode=OneWay}" />
|
||||
</Grid>
|
||||
|
||||
<!-- Step text -->
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{x:Bind Title}" />
|
||||
<TextBlock
|
||||
Foreground="#D13438"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind ErrorMessage, Mode=OneWay}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(IsFailed), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<!-- Success InfoBar -->
|
||||
<winuiControls:InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.IsSetupComplete, Mode=OneWay}"
|
||||
Message="{x:Bind domain:Translator.AccountSetup_SuccessMessage}"
|
||||
Severity="Success" />
|
||||
|
||||
<!-- Failure InfoBar + Buttons -->
|
||||
<StackPanel
|
||||
Spacing="12"
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(ViewModel.IsSetupFailed), Mode=OneWay}">
|
||||
<winuiControls:InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Message="{x:Bind ViewModel.FailureMessage, Mode=OneWay}"
|
||||
Severity="Error" />
|
||||
|
||||
<StackPanel
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Button
|
||||
Command="{x:Bind ViewModel.GoBackCommand}"
|
||||
Content="{x:Bind domain:Translator.AccountSetup_GoBackButton}" />
|
||||
<Button
|
||||
Command="{x:Bind ViewModel.TryAgainCommand}"
|
||||
Content="{x:Bind domain:Translator.AccountSetup_TryAgainButton}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</abstract:AccountSetupProgressPageAbstract>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
|
||||
public sealed partial class AccountSetupProgressPage : AccountSetupProgressPageAbstract
|
||||
{
|
||||
public AccountSetupProgressPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
|
||||
<abstract:ProviderSelectionPageAbstract
|
||||
x:Class="Wino.Views.ProviderSelectionPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract"
|
||||
xmlns:accounts="using:Wino.Core.Domain.Models.Accounts"
|
||||
xmlns:coreViewModelData="using:Wino.Core.ViewModels.Data"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:domain="using:Wino.Core.Domain"
|
||||
xmlns:helpers="using:Wino.Helpers"
|
||||
xmlns:interfaces="using:Wino.Core.Domain.Interfaces"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ScrollViewer
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel
|
||||
MaxWidth="480"
|
||||
Margin="0,24,0,24"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="20">
|
||||
|
||||
<!-- Title -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{x:Bind domain:Translator.ProviderSelection_Title}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.ProviderSelection_Subtitle}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Account Name + Color Picker -->
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox
|
||||
Header="{x:Bind domain:Translator.ProviderSelection_AccountNameHeader}"
|
||||
PlaceholderText="{x:Bind domain:Translator.ProviderSelection_AccountNamePlaceholder}"
|
||||
Text="{x:Bind ViewModel.AccountName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<Button Grid.Column="1" VerticalAlignment="Bottom">
|
||||
<Grid>
|
||||
<!-- No color selected placeholder -->
|
||||
<FontIcon
|
||||
FontSize="16"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind helpers:XamlHelpers.ReverseBoolToVisibilityConverter(ViewModel.IsColorSelected), Mode=OneWay}" />
|
||||
<!-- Color swatch -->
|
||||
<Ellipse
|
||||
Width="16"
|
||||
Height="16"
|
||||
Fill="{x:Bind helpers:XamlHelpers.GetSolidColorBrushFromHex(ViewModel.SelectedColor.Hex), Mode=OneWay}"
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(ViewModel.IsColorSelected), Mode=OneWay}" />
|
||||
</Grid>
|
||||
<Button.Flyout>
|
||||
<Flyout Placement="TopEdgeAlignedLeft">
|
||||
<StackPanel Spacing="8">
|
||||
<GridView
|
||||
Width="150"
|
||||
ItemTemplate="{StaticResource AccountColorTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableColors, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedColor, Mode=TwoWay}" />
|
||||
<HyperlinkButton
|
||||
HorizontalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ClearColorCommand}"
|
||||
Content="{x:Bind domain:Translator.ProviderSelection_ClearColor}"
|
||||
Visibility="{x:Bind helpers:XamlHelpers.BoolToVisibilityConverter(ViewModel.IsColorSelected), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- Provider List -->
|
||||
<ItemsView
|
||||
ItemsSource="{x:Bind ViewModel.Providers, Mode=OneWay}"
|
||||
SelectionChanged="ProviderSelectionChanged"
|
||||
SelectionMode="Single">
|
||||
<ItemsView.Layout>
|
||||
<UniformGridLayout Orientation="Vertical" />
|
||||
</ItemsView.Layout>
|
||||
<ItemsView.ItemTemplate>
|
||||
<DataTemplate x:DataType="interfaces:IProviderDetail">
|
||||
<ItemContainer Padding="12,10">
|
||||
<Grid Padding="16" ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Width="32"
|
||||
Height="32"
|
||||
Source="{x:Bind ProviderImage}" />
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="2">
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind Name}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind Description}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ItemContainer>
|
||||
</DataTemplate>
|
||||
</ItemsView.ItemTemplate>
|
||||
</ItemsView>
|
||||
|
||||
<!-- Continue Button -->
|
||||
<Button
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{x:Bind ViewModel.ProceedCommand}"
|
||||
Content="{x:Bind domain:Translator.ProviderSelection_ContinueButton}"
|
||||
IsEnabled="{x:Bind ViewModel.CanProceed, Mode=OneWay}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</abstract:ProviderSelectionPageAbstract>
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
|
||||
public sealed partial class ProviderSelectionPage : ProviderSelectionPageAbstract
|
||||
{
|
||||
public ProviderSelectionPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ProviderSelectionChanged(ItemsView sender, ItemsViewSelectionChangedEventArgs args)
|
||||
{
|
||||
ViewModel.SelectedProvider = sender.SelectedItem as Wino.Core.Domain.Interfaces.IProviderDetail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<abstract:SpecialImapCredentialsPageAbstract
|
||||
x:Class="Wino.Views.SpecialImapCredentialsPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Mail.WinUI.Views.Abstract"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:domain="using:Wino.Core.Domain"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ScrollViewer
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel
|
||||
MaxWidth="440"
|
||||
Margin="0,24,0,24"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="20">
|
||||
|
||||
<!-- Provider logo -->
|
||||
<Image
|
||||
Height="48"
|
||||
HorizontalAlignment="Center"
|
||||
Source="{x:Bind ViewModel.WizardContext.SelectedProvider.ProviderImage, Mode=OneWay}"
|
||||
Stretch="Uniform" />
|
||||
|
||||
<!-- Title / subtitle -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{x:Bind ViewModel.WizardContext.SelectedProvider.Name, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.ProviderSelection_SpecialImap_Subtitle}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Display Name -->
|
||||
<TextBox
|
||||
Header="{x:Bind domain:Translator.ProviderSelection_DisplayNameHeader}"
|
||||
PlaceholderText="{x:Bind domain:Translator.ProviderSelection_DisplayNamePlaceholder}"
|
||||
Text="{x:Bind ViewModel.DisplayName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<!-- Email -->
|
||||
<TextBox
|
||||
Header="{x:Bind domain:Translator.ProviderSelection_EmailHeader}"
|
||||
PlaceholderText="{x:Bind domain:Translator.ProviderSelection_EmailPlaceholder}"
|
||||
Text="{x:Bind ViewModel.EmailAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<!-- App-Specific Password -->
|
||||
<PasswordBox
|
||||
x:Name="AppPasswordBox"
|
||||
Header="{x:Bind domain:Translator.ProviderSelection_AppPasswordHeader}"
|
||||
PasswordChanged="AppPasswordChanged" />
|
||||
|
||||
<HyperlinkButton
|
||||
HorizontalAlignment="Right"
|
||||
Command="{x:Bind ViewModel.OpenAppPasswordHelpCommand}"
|
||||
Content="{x:Bind domain:Translator.ProviderSelection_AppPasswordHelp}" />
|
||||
|
||||
<!-- Divider -->
|
||||
<Rectangle Height="1" Fill="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
|
||||
<!-- Calendar Mode -->
|
||||
<TextBlock Style="{StaticResource BodyStrongTextBlockStyle}" Text="{x:Bind domain:Translator.ProviderSelection_CalendarModeHeader}" />
|
||||
|
||||
<ListView
|
||||
x:Name="CalendarModeListView"
|
||||
IsItemClickEnabled="False"
|
||||
SelectionChanged="CalendarModeSelectionChanged"
|
||||
SelectionMode="Single">
|
||||
<!-- Disabled -->
|
||||
<ListViewItem>
|
||||
<Grid Padding="12" ColumnSpacing="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon
|
||||
VerticalAlignment="Center"
|
||||
FontSize="18"
|
||||
Glyph="" />
|
||||
<StackPanel Grid.Column="1" Spacing="2">
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind domain:Translator.ProviderSelection_CalendarMode_DisabledTitle}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.ProviderSelection_CalendarMode_DisabledDescription}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
<!-- CalDAV -->
|
||||
<ListViewItem>
|
||||
<Grid Padding="12" ColumnSpacing="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon
|
||||
VerticalAlignment="Center"
|
||||
FontSize="18"
|
||||
Glyph="" />
|
||||
<StackPanel Grid.Column="1" Spacing="2">
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind domain:Translator.ProviderSelection_CalendarMode_CalDavTitle}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.CalendarModeCalDavDescription, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
<!-- Local -->
|
||||
<ListViewItem>
|
||||
<Grid Padding="12" ColumnSpacing="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon
|
||||
VerticalAlignment="Center"
|
||||
FontSize="18"
|
||||
Glyph="" />
|
||||
<StackPanel Grid.Column="1" Spacing="2">
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind domain:Translator.ProviderSelection_CalendarMode_LocalTitle}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind domain:Translator.ProviderSelection_CalendarMode_LocalDescription}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
</ListView>
|
||||
|
||||
<!-- Continue Button -->
|
||||
<Button
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{x:Bind ViewModel.ProceedCommand}"
|
||||
Content="{x:Bind domain:Translator.ProviderSelection_ContinueButton}"
|
||||
IsEnabled="{x:Bind ViewModel.CanProceed, Mode=OneWay}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</abstract:SpecialImapCredentialsPageAbstract>
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Wino.Mail.WinUI.Views.Abstract;
|
||||
|
||||
namespace Wino.Views;
|
||||
|
||||
public sealed partial class SpecialImapCredentialsPage : SpecialImapCredentialsPageAbstract
|
||||
{
|
||||
public SpecialImapCredentialsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void CalendarModeSelectionChanged(object sender, SelectionChangedEventArgs args)
|
||||
{
|
||||
if (sender is ListView lv)
|
||||
ViewModel.SelectedCalendarModeIndex = lv.SelectedIndex;
|
||||
}
|
||||
|
||||
private void AppPasswordChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is PasswordBox pb)
|
||||
ViewModel.AppSpecificPassword = pb.Password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<abstract:WelcomeHostPageAbstract
|
||||
x:Class="Wino.Views.WelcomeHostPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:abstract="using:Wino.Mail.WinUI.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"
|
||||
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
|
||||
xmlns:winuiControls="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid RowSpacing="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Wizard step indicator bar -->
|
||||
<Border
|
||||
Padding="24,20"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<winuiControls:BreadcrumbBar
|
||||
x:Name="Breadcrumb"
|
||||
HorizontalAlignment="Center"
|
||||
ItemClicked="BreadItemClicked"
|
||||
ItemsSource="{x:Bind PageHistory, Mode=OneWay}">
|
||||
<winuiControls:BreadcrumbBar.ItemTemplate>
|
||||
<DataTemplate x:DataType="viewModelData:BreadcrumbNavigationItemViewModel">
|
||||
<winuiControls:BreadcrumbBarItem>
|
||||
<winuiControls:BreadcrumbBarItem.ContentTemplate>
|
||||
<DataTemplate x:DataType="viewModelData:BreadcrumbNavigationItemViewModel">
|
||||
<StackPanel
|
||||
Margin="8,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Border
|
||||
Width="24"
|
||||
Height="24"
|
||||
Background="{x:Bind helpers:XamlHelpers.GetWizardStepBadgeBrush(IsActive), Mode=OneWay}"
|
||||
CornerRadius="12">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="11"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{x:Bind helpers:XamlHelpers.GetWizardStepNumberForeground(IsActive), Mode=OneWay}"
|
||||
Text="{x:Bind StepNumber, Mode=OneWay}" />
|
||||
</Border>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="{x:Bind helpers:XamlHelpers.GetFontWeightBySyncState(IsActive), Mode=OneWay}"
|
||||
Style="{StaticResource BodyTextBlockStyle}"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</winuiControls:BreadcrumbBarItem.ContentTemplate>
|
||||
</winuiControls:BreadcrumbBarItem>
|
||||
</DataTemplate>
|
||||
</winuiControls:BreadcrumbBar.ItemTemplate>
|
||||
</winuiControls:BreadcrumbBar>
|
||||
</Border>
|
||||
|
||||
<Frame
|
||||
x:Name="WizardFrame"
|
||||
Grid.Row="1" />
|
||||
</Grid>
|
||||
</abstract:WelcomeHostPageAbstract>
|
||||
@@ -0,0 +1,96 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using MoreLinq;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.WinUI.Views.Abstract;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
namespace Wino.Views;
|
||||
|
||||
public sealed partial class WelcomeHostPage : WelcomeHostPageAbstract,
|
||||
IRecipient<BreadcrumbNavigationRequested>,
|
||||
IRecipient<BackBreadcrumNavigationRequested>
|
||||
{
|
||||
public ObservableCollection<BreadcrumbNavigationItemViewModel> PageHistory { get; set; } = [];
|
||||
|
||||
public WelcomeHostPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<BreadcrumbNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<BackBreadcrumNavigationRequested>(this);
|
||||
|
||||
// Navigate to the welcome/get-started page without adding it to the wizard breadcrumb.
|
||||
// Breadcrumb steps only start after the user clicks "Get Started".
|
||||
var welcomePageType = ViewModel.NavigationService.GetPageType(WinoPage.WelcomePageV2);
|
||||
WizardFrame.Navigate(welcomePageType, null, new SuppressNavigationTransitionInfo());
|
||||
}
|
||||
|
||||
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<BreadcrumbNavigationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<BackBreadcrumNavigationRequested>(this);
|
||||
|
||||
base.OnNavigatingFrom(e);
|
||||
}
|
||||
|
||||
public void Receive(BreadcrumbNavigationRequested message)
|
||||
{
|
||||
var pageType = ViewModel.NavigationService.GetPageType(message.PageType);
|
||||
if (pageType == null) return;
|
||||
|
||||
WizardFrame.Navigate(pageType, message.Parameter, new SlideNavigationTransitionInfo
|
||||
{
|
||||
Effect = SlideNavigationTransitionEffect.FromRight
|
||||
});
|
||||
|
||||
PageHistory.ForEach(a => a.IsActive = false);
|
||||
PageHistory.Add(new BreadcrumbNavigationItemViewModel(message, isActive: true, stepNumber: PageHistory.Count + 1));
|
||||
}
|
||||
|
||||
public void Receive(BackBreadcrumNavigationRequested message)
|
||||
{
|
||||
GoBackFrame();
|
||||
}
|
||||
|
||||
private void GoBackFrame()
|
||||
{
|
||||
if (!WizardFrame.CanGoBack) return;
|
||||
|
||||
PageHistory.RemoveAt(PageHistory.Count - 1);
|
||||
WizardFrame.GoBack(new SlideNavigationTransitionInfo
|
||||
{
|
||||
Effect = SlideNavigationTransitionEffect.FromLeft
|
||||
});
|
||||
|
||||
if (PageHistory.Count > 0)
|
||||
{
|
||||
PageHistory.ForEach(a => a.IsActive = false);
|
||||
PageHistory[PageHistory.Count - 1].IsActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void BreadItemClicked(Microsoft.UI.Xaml.Controls.BreadcrumbBar sender, Microsoft.UI.Xaml.Controls.BreadcrumbBarItemClickedEventArgs args)
|
||||
{
|
||||
var clickedItem = PageHistory[args.Index];
|
||||
var currentActive = PageHistory.FirstOrDefault(a => a.IsActive);
|
||||
|
||||
// Only allow navigating backwards (clicking items before current)
|
||||
if (currentActive == null || args.Index >= PageHistory.IndexOf(currentActive))
|
||||
return;
|
||||
|
||||
while (PageHistory.FirstOrDefault(a => a.IsActive) != clickedItem && WizardFrame.CanGoBack)
|
||||
{
|
||||
GoBackFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,6 @@ public sealed partial class WelcomeWindow : WindowEx
|
||||
Width = 980;
|
||||
Height = 720;
|
||||
|
||||
//this.IsResizable = false;
|
||||
//this.IsMaximizable = false;
|
||||
|
||||
this.CenterOnScreen();
|
||||
|
||||
var themeService = WinoApplication.Current.Services.GetService<INewThemeService>();
|
||||
|
||||
Reference in New Issue
Block a user