Outlook auth fix and actually syncing.

This commit is contained in:
Burak Kaan Köse
2025-10-06 17:46:00 +02:00
parent 9623c2e6d2
commit 309e891594
14 changed files with 85 additions and 22 deletions
@@ -40,6 +40,7 @@ public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator
ListOperatingSystemAccounts = true, ListOperatingSystemAccounts = true,
}; };
var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId) var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId)
.WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd) .WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd)
.WithBroker(options) .WithBroker(options)
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.Folders;
@@ -20,7 +21,7 @@ public interface IBaseFolderMenuItem : IMenuItem
int UnreadItemCount { get; set; } int UnreadItemCount { get; set; }
SpecialFolderType SpecialFolderType { get; } SpecialFolderType SpecialFolderType { get; }
IEnumerable<IMailItemFolder> HandlingFolders { get; } IEnumerable<IMailItemFolder> HandlingFolders { get; }
IEnumerable<IMenuItem> SubMenuItems { get; } ObservableCollection<IMenuItem> SubMenuItems { get; }
bool IsMoveTarget { get; } bool IsMoveTarget { get; }
bool IsSticky { get; } bool IsSticky { get; }
bool IsSystemFolder { get; } bool IsSystemFolder { get; }
@@ -45,6 +45,11 @@ public interface ISynchronizationManager
/// </summary> /// </summary>
Task QueueRequestAsync(IRequestBase request, Guid accountId); Task QueueRequestAsync(IRequestBase request, Guid accountId);
/// <summary>
/// Queues a mail action request to the corresponding account's synchronizer with optional synchronization triggering.
/// </summary>
Task QueueRequestAsync(IRequestBase request, Guid accountId, bool triggerSynchronization);
/// <summary> /// <summary>
/// Handles folder synchronization for the given account. /// Handles folder synchronization for the given account.
/// </summary> /// </summary>
+4 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Entities.Shared;
@@ -20,6 +21,8 @@ public partial class FolderMenuItem : MenuItemBase<IMailItemFolder, FolderMenuIt
public bool IsSticky => Parameter.IsSticky; public bool IsSticky => Parameter.IsSticky;
public bool IsSystemFolder => Parameter.IsSystemFolder; public bool IsSystemFolder => Parameter.IsSystemFolder;
/// <summary> /// <summary>
/// Display name of the folder. More and Category folders have localized display names. /// Display name of the folder. More and Category folders have localized display names.
/// </summary> /// </summary>
@@ -53,7 +56,7 @@ public partial class FolderMenuItem : MenuItemBase<IMailItemFolder, FolderMenuIt
public bool ShowUnreadCount => Parameter.ShowUnreadCount; public bool ShowUnreadCount => Parameter.ShowUnreadCount;
IEnumerable<IMenuItem> IBaseFolderMenuItem.SubMenuItems => SubMenuItems; public new ObservableCollection<IMenuItem> SubMenuItems { get; set; } = new ObservableCollection<IMenuItem>();
public FolderMenuItem(IMailItemFolder folderStructure, MailAccount parentAccount, IMenuItem parentMenuItem) : base(folderStructure, folderStructure.Id, parentMenuItem) public FolderMenuItem(IMailItemFolder folderStructure, MailAccount parentAccount, IMenuItem parentMenuItem) : base(folderStructure, folderStructure.Id, parentMenuItem)
{ {
@@ -37,6 +37,11 @@ public class DialogServiceBase : IDialogServiceBase
ApplicationResourceManager = applicationResourceManager; ApplicationResourceManager = applicationResourceManager;
} }
protected XamlRoot GetXamlRoot()
{
return WinoApplication.MainWindow?.Content?.XamlRoot;
}
public async Task<string> PickFilePathAsync(string saveFileName) public async Task<string> PickFilePathAsync(string saveFileName)
{ {
var picker = new FolderPicker() var picker = new FolderPicker()
@@ -122,7 +127,8 @@ public class DialogServiceBase : IDialogServiceBase
{ {
return new AccountCreationDialog return new AccountCreationDialog
{ {
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme(),
XamlRoot = GetXamlRoot()
}; };
} }
@@ -195,6 +201,8 @@ public class DialogServiceBase : IDialogServiceBase
try try
{ {
dialog.XamlRoot = GetXamlRoot();
return await dialog.ShowAsync(); return await dialog.ShowAsync();
} }
catch (Exception ex) catch (Exception ex)
+9 -10
View File
@@ -1,10 +1,8 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.Foundation.Metadata;
using Windows.Storage; using Windows.Storage;
using Windows.System; using Windows.System;
using Windows.UI.Shell;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
@@ -88,20 +86,21 @@ public class NativeAppService : INativeAppService
return string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision); return string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision);
} }
[Obsolete("Not supported for Win SDK")]
public async Task PinAppToTaskbarAsync() public async Task PinAppToTaskbarAsync()
{ {
// If Start screen manager API's aren't present // If Start screen manager API's aren't present
if (!ApiInformation.IsTypePresent("Windows.UI.Shell.TaskbarManager")) return; //if (!ApiInformation.IsTypePresent("Windows.UI.Shell.TaskbarManager")) return;
// Get the taskbar manager //// Get the taskbar manager
var taskbarManager = TaskbarManager.GetDefault(); //var taskbarManager = TaskbarManager.GetDefault();
// If Taskbar doesn't allow pinning, don't show the tip //// If Taskbar doesn't allow pinning, don't show the tip
if (!taskbarManager.IsPinningAllowed) return; //if (!taskbarManager.IsPinningAllowed) return;
// If already pinned, don't show the tip //// If already pinned, don't show the tip
if (await taskbarManager.IsCurrentAppPinnedAsync()) return; //if (await taskbarManager.IsCurrentAppPinnedAsync()) return;
await taskbarManager.RequestPinCurrentAppAsync(); //await taskbarManager.RequestPinCurrentAppAsync();
} }
} }
+4 -2
View File
@@ -198,8 +198,10 @@ public class NewThemeService : INewThemeService
await ApplyCustomThemeAsync(true); await ApplyCustomThemeAsync(true);
// Registering to color changes, thus we notice when user changes theme system wide // Registering to color changes, thus we notice when user changes theme system wide
uiSettings.ColorValuesChanged -= UISettingsColorChanged;
uiSettings.ColorValuesChanged += UISettingsColorChanged; // TODO: WinUI: This event seems to be very unreliable. It causes a crash when the function runs under.
//uiSettings.ColorValuesChanged -= UISettingsColorChanged;
//uiSettings.ColorValuesChanged += UISettingsColorChanged;
isInitialized = true; isInitialized = true;
} }
@@ -227,7 +227,7 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
public bool IsNavigationPaneOpened public bool IsNavigationPaneOpened
{ {
get => _configurationService.Get(nameof(IsNavigationPaneOpened), true); get => _configurationService.Get(nameof(IsNavigationPaneOpened), true);
set => SaveProperty(propertyName: nameof(IsNavigationPaneOpened), value); set => SetPropertyAndSave(propertyName: nameof(IsNavigationPaneOpened), value);
} }
public bool AutoSelectNextItem public bool AutoSelectNextItem
@@ -194,6 +194,17 @@ public class SynchronizationManager : ISynchronizationManager
/// <param name="request">Request to queue</param> /// <param name="request">Request to queue</param>
/// <param name="accountId">Account ID to queue the request for</param> /// <param name="accountId">Account ID to queue the request for</param>
public async Task QueueRequestAsync(IRequestBase request, Guid accountId) public async Task QueueRequestAsync(IRequestBase request, Guid accountId)
{
await QueueRequestAsync(request, accountId, triggerSynchronization: true);
}
/// <summary>
/// Queues a mail action request to the corresponding account's synchronizer with optional synchronization triggering.
/// </summary>
/// <param name="request">Request to queue</param>
/// <param name="accountId">Account ID to queue the request for</param>
/// <param name="triggerSynchronization">Whether to automatically trigger synchronization after queuing the request</param>
public async Task QueueRequestAsync(IRequestBase request, Guid accountId, bool triggerSynchronization)
{ {
EnsureInitialized(); EnsureInitialized();
@@ -208,6 +219,32 @@ public class SynchronizationManager : ISynchronizationManager
request.GetType().Name, accountId); request.GetType().Name, accountId);
synchronizer.QueueRequest(request); synchronizer.QueueRequest(request);
if (triggerSynchronization)
{
// Trigger synchronization to execute the queued request
_logger.Debug("Triggering synchronization to execute queued request for account {AccountId}", accountId);
var synchronizationOptions = new MailSynchronizationOptions()
{
AccountId = accountId,
Type = MailSynchronizationType.ExecuteRequests
};
// Trigger synchronization asynchronously without waiting for completion
// This matches the pattern used in WinoRequestDelegator
_ = Task.Run(async () =>
{
try
{
await SynchronizeMailAsync(synchronizationOptions);
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to execute synchronization after queuing request for account {AccountId}", accountId);
}
});
}
} }
/// <summary> /// <summary>
+2 -1
View File
@@ -135,7 +135,8 @@ public class WinoRequestDelegator : IWinoRequestDelegator
private async Task QueueRequestAsync(IRequestBase request, Guid accountId) private async Task QueueRequestAsync(IRequestBase request, Guid accountId)
{ {
await SynchronizationManager.Instance.QueueRequestAsync(request, accountId); // Don't trigger synchronization for individual requests - we'll trigger it once for all requests
await SynchronizationManager.Instance.QueueRequestAsync(request, accountId, triggerSynchronization: false);
} }
private Task QueueSynchronizationAsync(Guid accountId) private Task QueueSynchronizationAsync(Guid accountId)
+6 -3
View File
@@ -83,18 +83,21 @@ public partial class App : WinoApplication, IRecipient<NewMailSynchronizationReq
// TODO: Check app relaunch mutex before loading anything. // TODO: Check app relaunch mutex before loading anything.
// Initialize NewThemeService first to get backdrop settings before creating window // Initialize NewThemeService first to get backdrop settings before creating window
var newThemeService = Services.GetService<INewThemeService>(); var newThemeService = Services.GetRequiredService<INewThemeService>();
var configService = Services.GetService<IConfigurationService>(); var configService = Services.GetRequiredService<IConfigurationService>();
var nativeAppService = Services.GetRequiredService<INativeAppService>();
// Load saved backdrop type before creating window // Load saved backdrop type before creating window
var savedBackdropType = (WindowBackdropType)configService.Get("WindowBackdropTypeKey", (int)WindowBackdropType.Mica); var savedBackdropType = (WindowBackdropType)configService.Get("WindowBackdropTypeKey", (int)WindowBackdropType.Mica);
MainWindow = new ShellWindow(); MainWindow = new ShellWindow();
nativeAppService.GetCoreWindowHwnd = () => WinRT.Interop.WindowNative.GetWindowHandle(MainWindow);
await InitializeServicesAsync(); await InitializeServicesAsync();
// Initialize system tray // Initialize system tray
var systemTrayService = Services.GetService<ISystemTrayService>(); var systemTrayService = Services.GetRequiredService<ISystemTrayService>();
if (systemTrayService != null) if (systemTrayService != null)
{ {
systemTrayService.Initialize(); systemTrayService.Initialize();
+3 -1
View File
@@ -37,9 +37,11 @@ public class DialogService : DialogServiceBase, IMailDialogService
{ {
if (accountCreationDialogResult.ProviderType == MailProviderType.IMAP4) if (accountCreationDialogResult.ProviderType == MailProviderType.IMAP4)
{ {
return new NewImapSetupDialog return new NewImapSetupDialog
{ {
RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme() RequestedTheme = ThemeService.RootTheme.ToWindowsElementTheme(),
XamlRoot = GetXamlRoot()
}; };
} }
else else
+1
View File
@@ -21,6 +21,7 @@
<TitleBar <TitleBar
x:Name="ShellTitleBar" x:Name="ShellTitleBar"
Title="{x:Bind StatePersistanceService.CoreWindowTitle, Mode=OneWay}" Title="{x:Bind StatePersistanceService.CoreWindowTitle, Mode=OneWay}"
Margin="-3,-3,0,0"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
BackRequested="BackButtonClicked" BackRequested="BackButtonClicked"
+1 -1
View File
@@ -209,7 +209,7 @@
<KeyboardAccelerator Key="Delete" Invoked="DeleteAllInvoked" /> <KeyboardAccelerator Key="Delete" Invoked="DeleteAllInvoked" />
</Page.KeyboardAccelerators> </Page.KeyboardAccelerators>
<wino:BasePage.ShellContent> <wino:BasePage.ShellContent>
<Grid HorizontalAlignment="Stretch" Background="Red"> <Grid HorizontalAlignment="Stretch">
<!-- Hidden focus receiver... --> <!-- Hidden focus receiver... -->
<TextBox <TextBox
Grid.Column="1" Grid.Column="1"