From 0cd1568c64ccb1ddbc16f9a6c0d97533e2360dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Kaan=20K=C3=B6se?= Date: Sat, 30 Nov 2024 23:05:07 +0100 Subject: [PATCH] Separation of core library from the UWP app. --- .../Wino.Authentication.csproj | 2 + Wino.Calendar.ViewModels/AppShellViewModel.cs | 3 +- .../CalendarPageViewModel.cs | 2 +- .../Wino.Calendar.ViewModels.csproj | 2 + .../Controls/WinoCalendarFlipView.cs | 2 +- .../Collections}/ObservableRangeCollection.cs | 6 +- .../Interfaces/IContactService.cs | 14 ++++ .../Interfaces/IGmailThreadingStrategy.cs | 4 ++ .../Interfaces/IImapThreadingStrategy.cs | 4 ++ .../Interfaces/IMimeFileService.cs | 70 ++++++++++++++++++ .../Interfaces/IOutlookThreadingStrategy.cs | 4 ++ .../MenuItems/AccountMenuItem.cs | 4 +- .../MenuItems/FixAccountIssuesMenuItem.cs | 2 +- .../MenuItems/FolderMenuItem.cs | 2 +- .../MenuItems/ManageAccountsMenuItem.cs | 2 +- .../MenuItems/MenuItemBase.cs | 2 +- .../MenuItems/MenuItemCollection.cs | 14 ++-- .../MenuItems/MergedAccountFolderMenuItem.cs | 2 +- .../MenuItems/MergedAccountMenuItem.cs | 2 +- .../MergedAccountMoreFolderMenuItem.cs | 2 +- .../MenuItems/NewMailMenuItem.cs | 2 +- .../MenuItems/RateMenuItem.cs | 2 +- .../MenuItems/SeperatorItem.cs | 2 +- .../MenuItems/SettingsItem.cs | 2 +- .../Models/MailItem}/HtmlPreviewVisitor.cs | 2 +- Wino.Core.Domain/Wino.Core.Domain.csproj | 4 ++ .../NavigationMenuTemplateSelector.cs | 2 +- Wino.Core.UWP/Services/NativeAppService.cs | 44 ------------ Wino.Core.UWP/Services/PreferencesService.cs | 2 +- .../Services/ThumbnailService.cs | 4 +- Wino.Core.UWP/Styles/DataTemplates.xaml | 2 +- Wino.Core.UWP/Wino.Core.UWP.csproj | 5 ++ Wino.Core.UWP/WinoApplication.cs | 2 +- .../Wino.Core.ViewModels.csproj | 2 + Wino.Core/CoreContainerSetup.cs | 24 +------ .../Extensions/GoogleIntegratorExtensions.cs | 72 ++++--------------- Wino.Core/Extensions/MimeExtensions.cs | 1 + .../Processors/DefaultChangeProcessor.cs | 2 +- .../Processors/GmailChangeProcessor.cs | 2 +- .../Processors/ImapChangeProcessor.cs | 2 +- .../Processors/OutlookChangeProcessor.cs | 2 +- Wino.Core/Services/LaunchProtocolService.cs | 10 --- .../Services/ThreadingStrategyProvider.cs | 6 +- Wino.Core/Services/WinoRequestDelegator.cs | 1 - Wino.Core/Services/WinoRequestProcessor.cs | 3 - Wino.Core/Synchronizers/GmailSynchronizer.cs | 21 +++--- Wino.Core/Synchronizers/ImapSynchronizer.cs | 1 + Wino.Core/Wino.Core.csproj | 3 + Wino.Mail.ViewModels/AppShellViewModel.cs | 5 +- .../MailViewModelsContainerSetup.cs | 14 ++++ .../Messages/ActiveMailItemChangedEvent.cs | 4 +- .../Wino.Mail.ViewModels.csproj | 4 ++ Wino.Mail/Activation/FileActivationHandler.cs | 1 - .../ToastNotificationActivationHandler.cs | 5 +- Wino.Mail/App.xaml.cs | 4 +- Wino.Mail/AppShell.xaml | 2 +- .../CreateMailNavigationItemBehavior.cs | 14 ++-- Wino.Mail/Controls/ImagePreviewControl.cs | 2 +- Wino.Mail/Wino.Mail.csproj | 8 +-- Wino.Messages/Wino.Messaging.csproj | 3 + Wino.Server/App.xaml.cs | 3 +- Wino.Server/ServerContext.cs | 2 +- Wino.Server/Wino.Server.csproj | 2 + .../AccountService.cs | 19 +++-- .../ApplicationConfiguration.cs | 2 +- .../BaseDatabaseService.cs | 2 +- .../ContactService.cs | 12 +--- .../ContextMenuItemService.cs | 4 +- .../DatabaseService.cs | 2 +- .../Extensions/HtmlAgilityPackExtensions.cs | 5 +- .../Extensions/MailkitClientExtensions.cs | 3 +- .../Extensions/SqlKataExtensions.cs | 2 +- .../FolderService.cs | 24 +++---- Wino.Services/LaunchProtocolService.cs | 11 +++ .../LogInitializer.cs | 2 +- .../Services => Wino.Services}/MailService.cs | 24 ++++--- .../MimeFileService.cs | 66 +---------------- Wino.Services/ServiceConstants.cs | 64 +++++++++++++++++ Wino.Services/ServicesContainerSetup.cs | 32 +++++++++ .../SignatureService.cs | 2 +- .../Threading/APIThreadingStrategy.cs | 4 +- .../Threading/GmailThreadingStrategy.cs | 5 +- .../Threading/ImapThreadingStrategy.cs | 20 +++--- .../Threading/OutlookThreadingStrategy.cs | 5 +- Wino.Services/ThreadingStrategyProvider.cs | 31 ++++++++ .../TranslationService.cs | 2 +- Wino.Services/Wino.Services.csproj | 23 ++++++ Wino.sln | 23 ++++++ 88 files changed, 481 insertions(+), 353 deletions(-) rename {Wino.Core/MenuItems => Wino.Core.Domain/Collections}/ObservableRangeCollection.cs (96%) create mode 100644 Wino.Core.Domain/Interfaces/IContactService.cs create mode 100644 Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs create mode 100644 Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs create mode 100644 Wino.Core.Domain/Interfaces/IMimeFileService.cs create mode 100644 Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs rename {Wino.Core => Wino.Core.Domain}/MenuItems/AccountMenuItem.cs (95%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/FixAccountIssuesMenuItem.cs (92%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/FolderMenuItem.cs (98%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/ManageAccountsMenuItem.cs (61%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/MenuItemBase.cs (98%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/MenuItemCollection.cs (95%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/MergedAccountFolderMenuItem.cs (99%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/MergedAccountMenuItem.cs (97%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/MergedAccountMoreFolderMenuItem.cs (89%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/NewMailMenuItem.cs (58%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/RateMenuItem.cs (56%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/SeperatorItem.cs (57%) rename {Wino.Core => Wino.Core.Domain}/MenuItems/SettingsItem.cs (56%) rename {Wino.Core/Mime => Wino.Core.Domain/Models/MailItem}/HtmlPreviewVisitor.cs (99%) rename {Wino.Core => Wino.Core.UWP}/Services/ThumbnailService.cs (94%) delete mode 100644 Wino.Core/Services/LaunchProtocolService.cs create mode 100644 Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs rename {Wino.Core/Services => Wino.Services}/AccountService.cs (97%) rename {Wino.Core/Services => Wino.Services}/ApplicationConfiguration.cs (92%) rename {Wino.Core/Services => Wino.Services}/BaseDatabaseService.cs (95%) rename {Wino.Core/Services => Wino.Services}/ContactService.cs (86%) rename {Wino.Core/Services => Wino.Services}/ContextMenuItemService.cs (98%) rename {Wino.Core/Services => Wino.Services}/DatabaseService.cs (98%) rename {Wino.Core => Wino.Services}/Extensions/HtmlAgilityPackExtensions.cs (96%) rename {Wino.Core => Wino.Services}/Extensions/MailkitClientExtensions.cs (99%) rename {Wino.Core => Wino.Services}/Extensions/SqlKataExtensions.cs (89%) rename {Wino.Core/Services => Wino.Services}/FolderService.cs (97%) create mode 100644 Wino.Services/LaunchProtocolService.cs rename {Wino.Core/Services => Wino.Services}/LogInitializer.cs (97%) rename {Wino.Core/Services => Wino.Services}/MailService.cs (98%) rename {Wino.Core/Services => Wino.Services}/MimeFileService.cs (67%) create mode 100644 Wino.Services/ServiceConstants.cs create mode 100644 Wino.Services/ServicesContainerSetup.cs rename {Wino.Core/Services => Wino.Services}/SignatureService.cs (98%) rename {Wino.Core/Integration => Wino.Services}/Threading/APIThreadingStrategy.cs (98%) rename {Wino.Core/Integration => Wino.Services}/Threading/GmailThreadingStrategy.cs (60%) rename Wino.Core/Integration/Threading/ImapThreadStrategy.cs => Wino.Services/Threading/ImapThreadingStrategy.cs (90%) rename {Wino.Core/Integration => Wino.Services}/Threading/OutlookThreadingStrategy.cs (85%) create mode 100644 Wino.Services/ThreadingStrategyProvider.cs rename {Wino.Core/Services => Wino.Services}/TranslationService.cs (99%) create mode 100644 Wino.Services/Wino.Services.csproj diff --git a/Wino.Authentication/Wino.Authentication.csproj b/Wino.Authentication/Wino.Authentication.csproj index 09b5a3d2..ef267d2f 100644 --- a/Wino.Authentication/Wino.Authentication.csproj +++ b/Wino.Authentication/Wino.Authentication.csproj @@ -6,6 +6,8 @@ Debug;Release 12 AnyCPU;x64;x86 + true + true diff --git a/Wino.Calendar.ViewModels/AppShellViewModel.cs b/Wino.Calendar.ViewModels/AppShellViewModel.cs index 1c7eb4ab..a7de7e14 100644 --- a/Wino.Calendar.ViewModels/AppShellViewModel.cs +++ b/Wino.Calendar.ViewModels/AppShellViewModel.cs @@ -5,12 +5,13 @@ using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; +using Wino.Core.Domain.Collections; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.MenuItems; using Wino.Core.Domain.Models.Calendar; using Wino.Core.Domain.Models.Navigation; using Wino.Core.Extensions; -using Wino.Core.MenuItems; using Wino.Core.ViewModels; using Wino.Messaging.Client.Calendar; using Wino.Messaging.Client.Navigation; diff --git a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs index 75078191..a4f579c9 100644 --- a/Wino.Calendar.ViewModels/CalendarPageViewModel.cs +++ b/Wino.Calendar.ViewModels/CalendarPageViewModel.cs @@ -7,12 +7,12 @@ using System.Threading.Tasks; using CommunityToolkit.Diagnostics; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; +using Wino.Core.Domain.Collections; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Calendar; using Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies; using Wino.Core.Domain.Models.Navigation; -using Wino.Core.MenuItems; using Wino.Core.ViewModels; using Wino.Messaging.Client.Calendar; diff --git a/Wino.Calendar.ViewModels/Wino.Calendar.ViewModels.csproj b/Wino.Calendar.ViewModels/Wino.Calendar.ViewModels.csproj index 8a6621ff..613938db 100644 --- a/Wino.Calendar.ViewModels/Wino.Calendar.ViewModels.csproj +++ b/Wino.Calendar.ViewModels/Wino.Calendar.ViewModels.csproj @@ -4,6 +4,8 @@ netstandard2.0 12 AnyCPU;x64;x86 + true + true diff --git a/Wino.Calendar/Controls/WinoCalendarFlipView.cs b/Wino.Calendar/Controls/WinoCalendarFlipView.cs index c61dfbb6..0f2f5e33 100644 --- a/Wino.Calendar/Controls/WinoCalendarFlipView.cs +++ b/Wino.Calendar/Controls/WinoCalendarFlipView.cs @@ -3,8 +3,8 @@ using System.Linq; using System.Threading.Tasks; using CommunityToolkit.WinUI; using Windows.UI.Xaml.Controls; +using Wino.Core.Domain.Collections; using Wino.Core.Domain.Models.Calendar; -using Wino.Core.MenuItems; namespace Wino.Calendar.Controls { diff --git a/Wino.Core/MenuItems/ObservableRangeCollection.cs b/Wino.Core.Domain/Collections/ObservableRangeCollection.cs similarity index 96% rename from Wino.Core/MenuItems/ObservableRangeCollection.cs rename to Wino.Core.Domain/Collections/ObservableRangeCollection.cs index 25fec47b..b3531c95 100644 --- a/Wino.Core/MenuItems/ObservableRangeCollection.cs +++ b/Wino.Core.Domain/Collections/ObservableRangeCollection.cs @@ -4,7 +4,7 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.Collections { /// /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. @@ -25,7 +25,7 @@ namespace Wino.Core.MenuItems /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. /// /// collection: The collection from which the elements are copied. - /// The collection parameter cannot be null. + /// The collection parameter cannot be null. public ObservableRangeCollection(IEnumerable collection) : base(collection) { @@ -160,7 +160,7 @@ namespace Wino.Core.MenuItems return itemAdded; } - private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List? changedItems = null, int startingIndex = -1) + private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List changedItems = null, int startingIndex = -1) { OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count))); OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); diff --git a/Wino.Core.Domain/Interfaces/IContactService.cs b/Wino.Core.Domain/Interfaces/IContactService.cs new file mode 100644 index 00000000..ddba3b60 --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IContactService.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using MimeKit; +using Wino.Core.Domain.Entities.Shared; + +namespace Wino.Core.Domain.Interfaces +{ + public interface IContactService + { + Task> GetAddressInformationAsync(string queryText); + Task GetAddressInformationByAddressAsync(string address); + Task SaveAddressInformationAsync(MimeMessage message); + } +} diff --git a/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs new file mode 100644 index 00000000..2348d8b2 --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs @@ -0,0 +1,4 @@ +namespace Wino.Core.Domain.Interfaces +{ + public interface IGmailThreadingStrategy : IThreadingStrategy { } +} diff --git a/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs new file mode 100644 index 00000000..47883ac4 --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs @@ -0,0 +1,4 @@ +namespace Wino.Core.Domain.Interfaces +{ + public interface IImapThreadingStrategy : IThreadingStrategy { } +} diff --git a/Wino.Core.Domain/Interfaces/IMimeFileService.cs b/Wino.Core.Domain/Interfaces/IMimeFileService.cs new file mode 100644 index 00000000..f0d584b8 --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IMimeFileService.cs @@ -0,0 +1,70 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MimeKit; +using Wino.Core.Domain.Models.MailItem; +using Wino.Core.Domain.Models.Reader; + +namespace Wino.Core.Domain.Interfaces +{ + public interface IMimeFileService + { + /// + /// Finds the EML file for the given mail id for address, parses and returns MimeMessage. + /// + /// Cancellation token + /// Mime message information + Task GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default); + + /// + /// Gets the mime message information for the given EML file bytes. + /// This override is used when EML file association launch is used + /// because we may not have the access to the file path. + /// + /// Byte array of the file. + /// Cancellation token + /// Mime message information + Task GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default); + + /// + /// Saves EML file to the disk. + /// + /// MailCopy of the native message. + /// MimeMessage that is parsed from native message. + /// Which account Id to save this file for. + Task SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId); + + /// + /// Returns a path that all Mime resources (including eml) is stored for this MailCopyId + /// This is useful for storing previously rendered attachments as well. + /// + /// Account address + /// Resource mail copy id + Task GetMimeResourcePathAsync(Guid accountId, Guid fileId); + + /// + /// Returns whether mime file exists locally or not. + /// + Task IsMimeExistAsync(Guid accountId, Guid fileId); + + /// + /// Creates HtmlPreviewVisitor for the given MimeMessage. + /// + /// Mime + /// File path that mime is located to load resources. + HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath); + + /// + /// Deletes the given mime file from the disk. + /// + Task DeleteMimeMessageAsync(Guid accountId, Guid fileId); + + /// + /// Prepares the final model containing rendering details. + /// + /// Message to render. + /// File path that physical MimeMessage is located. + /// Rendering options + MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null); + } +} diff --git a/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs b/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs new file mode 100644 index 00000000..d3618c9b --- /dev/null +++ b/Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs @@ -0,0 +1,4 @@ +namespace Wino.Core.Domain.Interfaces +{ + public interface IOutlookThreadingStrategy : IThreadingStrategy { } +} diff --git a/Wino.Core/MenuItems/AccountMenuItem.cs b/Wino.Core.Domain/MenuItems/AccountMenuItem.cs similarity index 95% rename from Wino.Core/MenuItems/AccountMenuItem.cs rename to Wino.Core.Domain/MenuItems/AccountMenuItem.cs index a797b2f9..eae3e1a9 100644 --- a/Wino.Core/MenuItems/AccountMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/AccountMenuItem.cs @@ -7,7 +7,7 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public partial class AccountMenuItem : MenuItemBase>, IAccountMenuItem { @@ -22,7 +22,7 @@ namespace Wino.Core.MenuItems private bool _isEnabled = true; public bool IsAttentionRequired => AttentionReason != AccountAttentionReason.None; - public bool IsSynchronizationProgressVisible => (SynchronizationProgress > 0 && SynchronizationProgress < 100); + public bool IsSynchronizationProgressVisible => SynchronizationProgress > 0 && SynchronizationProgress < 100; // We can't determine the progress for gmail synchronization since it is based on history changes. public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail; diff --git a/Wino.Core/MenuItems/FixAccountIssuesMenuItem.cs b/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs similarity index 92% rename from Wino.Core/MenuItems/FixAccountIssuesMenuItem.cs rename to Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs index 741d7fc0..39a58dba 100644 --- a/Wino.Core/MenuItems/FixAccountIssuesMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/FixAccountIssuesMenuItem.cs @@ -2,7 +2,7 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class FixAccountIssuesMenuItem : MenuItemBase { diff --git a/Wino.Core/MenuItems/FolderMenuItem.cs b/Wino.Core.Domain/MenuItems/FolderMenuItem.cs similarity index 98% rename from Wino.Core/MenuItems/FolderMenuItem.cs rename to Wino.Core.Domain/MenuItems/FolderMenuItem.cs index c2f28b33..2e0cc433 100644 --- a/Wino.Core/MenuItems/FolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/FolderMenuItem.cs @@ -7,7 +7,7 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public partial class FolderMenuItem : MenuItemBase, IFolderMenuItem { diff --git a/Wino.Core/MenuItems/ManageAccountsMenuItem.cs b/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs similarity index 61% rename from Wino.Core/MenuItems/ManageAccountsMenuItem.cs rename to Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs index 2d69f5b0..033ab2cc 100644 --- a/Wino.Core/MenuItems/ManageAccountsMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/ManageAccountsMenuItem.cs @@ -1,4 +1,4 @@ -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class ManageAccountsMenuItem : MenuItemBase { } } diff --git a/Wino.Core/MenuItems/MenuItemBase.cs b/Wino.Core.Domain/MenuItems/MenuItemBase.cs similarity index 98% rename from Wino.Core/MenuItems/MenuItemBase.cs rename to Wino.Core.Domain/MenuItems/MenuItemBase.cs index fef4fffd..f0fd5b5f 100644 --- a/Wino.Core/MenuItems/MenuItemBase.cs +++ b/Wino.Core.Domain/MenuItems/MenuItemBase.cs @@ -3,7 +3,7 @@ using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public partial class MenuItemBase : ObservableObject, IMenuItem { diff --git a/Wino.Core/MenuItems/MenuItemCollection.cs b/Wino.Core.Domain/MenuItems/MenuItemCollection.cs similarity index 95% rename from Wino.Core/MenuItems/MenuItemCollection.cs rename to Wino.Core.Domain/MenuItems/MenuItemCollection.cs index 53ac761a..4f16d706 100644 --- a/Wino.Core/MenuItems/MenuItemCollection.cs +++ b/Wino.Core.Domain/MenuItems/MenuItemCollection.cs @@ -2,11 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using MoreLinq.Extensions; +using Wino.Core.Domain.Collections; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class MenuItemCollection : ObservableRangeCollection { @@ -108,7 +108,10 @@ namespace Wino.Core.MenuItems public void UpdateUnreadItemCountsToZero() { // Handle the root folders. - this.OfType().ForEach(a => RecursivelyResetUnreadItemCount(a)); + foreach (var item in this.OfType()) + { + RecursivelyResetUnreadItemCount(item); + } } private void RecursivelyResetUnreadItemCount(IBaseFolderMenuItem baseFolderMenuItem) @@ -168,7 +171,10 @@ namespace Wino.Core.MenuItems await _dispatcher.ExecuteOnUIThread(() => { - accountItems.ForEach(a => a.IsEnabled = isEnabled); + foreach (var item in accountItems) + { + item.IsEnabled = isEnabled; + } }); } diff --git a/Wino.Core/MenuItems/MergedAccountFolderMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs similarity index 99% rename from Wino.Core/MenuItems/MergedAccountFolderMenuItem.cs rename to Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs index 1677a56d..1bf51a27 100644 --- a/Wino.Core/MenuItems/MergedAccountFolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountFolderMenuItem.cs @@ -8,7 +8,7 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { /// /// Menu item that holds a list of folders under the merged account menu item. diff --git a/Wino.Core/MenuItems/MergedAccountMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs similarity index 97% rename from Wino.Core/MenuItems/MergedAccountMenuItem.cs rename to Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs index cf5936d9..7cd00323 100644 --- a/Wino.Core/MenuItems/MergedAccountMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountMenuItem.cs @@ -5,7 +5,7 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public partial class MergedAccountMenuItem : MenuItemBase, IMergedAccountMenuItem { diff --git a/Wino.Core/MenuItems/MergedAccountMoreFolderMenuItem.cs b/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs similarity index 89% rename from Wino.Core/MenuItems/MergedAccountMoreFolderMenuItem.cs rename to Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs index f0a8b0cc..05f2f240 100644 --- a/Wino.Core/MenuItems/MergedAccountMoreFolderMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/MergedAccountMoreFolderMenuItem.cs @@ -1,7 +1,7 @@ using System; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class MergedAccountMoreFolderMenuItem : MenuItemBase { diff --git a/Wino.Core/MenuItems/NewMailMenuItem.cs b/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs similarity index 58% rename from Wino.Core/MenuItems/NewMailMenuItem.cs rename to Wino.Core.Domain/MenuItems/NewMailMenuItem.cs index dc543c2d..c5bff6d7 100644 --- a/Wino.Core/MenuItems/NewMailMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/NewMailMenuItem.cs @@ -1,4 +1,4 @@ -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class NewMailMenuItem : MenuItemBase { } } diff --git a/Wino.Core/MenuItems/RateMenuItem.cs b/Wino.Core.Domain/MenuItems/RateMenuItem.cs similarity index 56% rename from Wino.Core/MenuItems/RateMenuItem.cs rename to Wino.Core.Domain/MenuItems/RateMenuItem.cs index cb339a1a..64030e94 100644 --- a/Wino.Core/MenuItems/RateMenuItem.cs +++ b/Wino.Core.Domain/MenuItems/RateMenuItem.cs @@ -1,4 +1,4 @@ -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class RateMenuItem : MenuItemBase { } } diff --git a/Wino.Core/MenuItems/SeperatorItem.cs b/Wino.Core.Domain/MenuItems/SeperatorItem.cs similarity index 57% rename from Wino.Core/MenuItems/SeperatorItem.cs rename to Wino.Core.Domain/MenuItems/SeperatorItem.cs index 974f36cc..f689497e 100644 --- a/Wino.Core/MenuItems/SeperatorItem.cs +++ b/Wino.Core.Domain/MenuItems/SeperatorItem.cs @@ -1,4 +1,4 @@ -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class SeperatorItem : MenuItemBase { } } diff --git a/Wino.Core/MenuItems/SettingsItem.cs b/Wino.Core.Domain/MenuItems/SettingsItem.cs similarity index 56% rename from Wino.Core/MenuItems/SettingsItem.cs rename to Wino.Core.Domain/MenuItems/SettingsItem.cs index 12aafba9..80617df6 100644 --- a/Wino.Core/MenuItems/SettingsItem.cs +++ b/Wino.Core.Domain/MenuItems/SettingsItem.cs @@ -1,4 +1,4 @@ -namespace Wino.Core.MenuItems +namespace Wino.Core.Domain.MenuItems { public class SettingsItem : MenuItemBase { } } diff --git a/Wino.Core/Mime/HtmlPreviewVisitor.cs b/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs similarity index 99% rename from Wino.Core/Mime/HtmlPreviewVisitor.cs rename to Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs index b7763cab..adabd06e 100644 --- a/Wino.Core/Mime/HtmlPreviewVisitor.cs +++ b/Wino.Core.Domain/Models/MailItem/HtmlPreviewVisitor.cs @@ -5,7 +5,7 @@ using MimeKit; using MimeKit.Text; using MimeKit.Tnef; -namespace Wino.Core.Mime +namespace Wino.Core.Domain.Models.MailItem { /// /// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control. diff --git a/Wino.Core.Domain/Wino.Core.Domain.csproj b/Wino.Core.Domain/Wino.Core.Domain.csproj index 878a68e8..8e33927c 100644 --- a/Wino.Core.Domain/Wino.Core.Domain.csproj +++ b/Wino.Core.Domain/Wino.Core.Domain.csproj @@ -5,6 +5,8 @@ true 12.0 AnyCPU;x64;x86 + true + true @@ -58,6 +60,8 @@ + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs b/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs index 13d2a7c8..807c6a02 100644 --- a/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs +++ b/Wino.Core.UWP/Selectors/NavigationMenuTemplateSelector.cs @@ -1,6 +1,6 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Wino.Core.MenuItems; +using Wino.Core.Domain.MenuItems; namespace Wino.Core.UWP.Selectors { diff --git a/Wino.Core.UWP/Services/NativeAppService.cs b/Wino.Core.UWP/Services/NativeAppService.cs index 9e0e977b..e5abdb6b 100644 --- a/Wino.Core.UWP/Services/NativeAppService.cs +++ b/Wino.Core.UWP/Services/NativeAppService.cs @@ -3,14 +3,10 @@ using System.Threading.Tasks; using Windows.ApplicationModel; using Windows.Foundation.Metadata; using Windows.Security.Authentication.Web; -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; using Windows.Storage; -using Windows.Storage.Streams; using Windows.System; using Windows.UI.Shell; using Wino.Core.Domain.Interfaces; -using Wino.Core.Domain.Models.Authorization; @@ -51,46 +47,6 @@ namespace Wino.Services return _mimeMessagesFolder; } - #region Cryptography - - public string randomDataBase64url(uint length) - { - IBuffer buffer = CryptographicBuffer.GenerateRandom(length); - return base64urlencodeNoPadding(buffer); - } - - public IBuffer sha256(string inputString) - { - HashAlgorithmProvider sha = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256); - IBuffer buff = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf8); - return sha.HashData(buff); - } - - public string base64urlencodeNoPadding(IBuffer buffer) - { - string base64 = CryptographicBuffer.EncodeToBase64String(buffer); - - // Converts base64 to base64url. - base64 = base64.Replace("+", "-"); - base64 = base64.Replace("/", "_"); - - // Strips padding. - base64 = base64.Replace("=", ""); - - return base64; - } - - #endregion - - // GMail Integration. - public GoogleAuthorizationRequest GetGoogleAuthorizationRequest() - { - string state = randomDataBase64url(32); - string code_verifier = randomDataBase64url(32); - string code_challenge = base64urlencodeNoPadding(sha256(code_verifier)); - - return new GoogleAuthorizationRequest(state, code_verifier, code_challenge); - } public async Task GetEditorBundlePathAsync() { diff --git a/Wino.Core.UWP/Services/PreferencesService.cs b/Wino.Core.UWP/Services/PreferencesService.cs index d3720c55..75d4149d 100644 --- a/Wino.Core.UWP/Services/PreferencesService.cs +++ b/Wino.Core.UWP/Services/PreferencesService.cs @@ -9,7 +9,7 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Calendar; using Wino.Core.Domain.Models.Reader; using Wino.Core.Domain.Translations; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.UWP.Services { diff --git a/Wino.Core/Services/ThumbnailService.cs b/Wino.Core.UWP/Services/ThumbnailService.cs similarity index 94% rename from Wino.Core/Services/ThumbnailService.cs rename to Wino.Core.UWP/Services/ThumbnailService.cs index bc32803a..6e776988 100644 --- a/Wino.Core/Services/ThumbnailService.cs +++ b/Wino.Core.UWP/Services/ThumbnailService.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Net.Mail; -namespace Wino.Core.Services +namespace Wino.Core.UWP.Services { public static class ThumbnailService { @@ -55,7 +55,7 @@ namespace Wino.Core.Services return new Tuple(false, host); } - return new Tuple(ThumbnailService.IsKnown(host), host); + return new Tuple(IsKnown(host), host); } public static string GetKnownHostImage(string host) diff --git a/Wino.Core.UWP/Styles/DataTemplates.xaml b/Wino.Core.UWP/Styles/DataTemplates.xaml index 1c5ca6fe..c6bad521 100644 --- a/Wino.Core.UWP/Styles/DataTemplates.xaml +++ b/Wino.Core.UWP/Styles/DataTemplates.xaml @@ -8,7 +8,7 @@ xmlns:domain="using:Wino.Core.Domain" xmlns:helpers="using:Wino.Helpers" xmlns:local="using:Wino.Core.UWP.Styles" - xmlns:menu="using:Wino.Core.MenuItems" + xmlns:menu="using:Wino.Core.Domain.MenuItems" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" xmlns:viewModelData="using:Wino.Mail.ViewModels.Data" xmlns:winuiControls="using:CommunityToolkit.WinUI.Controls"> diff --git a/Wino.Core.UWP/Wino.Core.UWP.csproj b/Wino.Core.UWP/Wino.Core.UWP.csproj index f08a977a..1d57caf8 100644 --- a/Wino.Core.UWP/Wino.Core.UWP.csproj +++ b/Wino.Core.UWP/Wino.Core.UWP.csproj @@ -144,6 +144,7 @@ + @@ -242,6 +243,10 @@ {0c307d7e-256f-448c-8265-5622a812fbcc} Wino.Messaging + + {4000a374-59fe-4400-acf6-d40473becd73} + Wino.Services + diff --git a/Wino.Core.UWP/WinoApplication.cs b/Wino.Core.UWP/WinoApplication.cs index 988e3748..be35832e 100644 --- a/Wino.Core.UWP/WinoApplication.cs +++ b/Wino.Core.UWP/WinoApplication.cs @@ -23,7 +23,7 @@ using Windows.UI.Xaml.Controls; using Wino.Activation; using Wino.Core.Domain; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.UWP { diff --git a/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj b/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj index 2049fb9f..64f13738 100644 --- a/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj +++ b/Wino.Core.ViewModels/Wino.Core.ViewModels.csproj @@ -4,6 +4,8 @@ netstandard2.0 12 AnyCPU;x64;x86 + true + true diff --git a/Wino.Core/CoreContainerSetup.cs b/Wino.Core/CoreContainerSetup.cs index de6da3cf..4db0a3f0 100644 --- a/Wino.Core/CoreContainerSetup.cs +++ b/Wino.Core/CoreContainerSetup.cs @@ -3,7 +3,6 @@ using Serilog.Core; using Wino.Authentication; using Wino.Core.Domain.Interfaces; using Wino.Core.Integration.Processors; -using Wino.Core.Integration.Threading; using Wino.Core.Services; namespace Wino.Core @@ -15,41 +14,20 @@ namespace Wino.Core var loggerLevelSwitcher = new LoggingLevelSwitch(); services.AddSingleton(loggerLevelSwitcher); - services.AddSingleton(); - - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddTransient(); services.AddTransient(); services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddSingleton(); } } } diff --git a/Wino.Core/Extensions/GoogleIntegratorExtensions.cs b/Wino.Core/Extensions/GoogleIntegratorExtensions.cs index 0c773dd1..8ae36947 100644 --- a/Wino.Core/Extensions/GoogleIntegratorExtensions.cs +++ b/Wino.Core/Extensions/GoogleIntegratorExtensions.cs @@ -6,67 +6,21 @@ using Google.Apis.Gmail.v1.Data; using MimeKit; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; +using Wino.Services; +using Wino.Services.Extensions; namespace Wino.Core.Extensions { public static class GoogleIntegratorExtensions { - public const string INBOX_LABEL_ID = "INBOX"; - public const string UNREAD_LABEL_ID = "UNREAD"; - public const string IMPORTANT_LABEL_ID = "IMPORTANT"; - public const string STARRED_LABEL_ID = "STARRED"; - public const string DRAFT_LABEL_ID = "DRAFT"; - public const string SENT_LABEL_ID = "SENT"; - public const string SPAM_LABEL_ID = "SPAM"; - public const string CHAT_LABEL_ID = "CHAT"; - public const string TRASH_LABEL_ID = "TRASH"; - // Category labels. - public const string FORUMS_LABEL_ID = "FORUMS"; - public const string UPDATES_LABEL_ID = "UPDATES"; - public const string PROMOTIONS_LABEL_ID = "PROMOTIONS"; - public const string SOCIAL_LABEL_ID = "SOCIAL"; - public const string PERSONAL_LABEL_ID = "PERSONAL"; - // Label visibility identifiers. - private const string SYSTEM_FOLDER_IDENTIFIER = "system"; - private const string FOLDER_HIDE_IDENTIFIER = "labelHide"; - private const string CATEGORY_PREFIX = "CATEGORY_"; - private const string FOLDER_SEPERATOR_STRING = "/"; - private const char FOLDER_SEPERATOR_CHAR = '/'; - - private static Dictionary KnownFolderDictionary = new Dictionary() - { - { INBOX_LABEL_ID, SpecialFolderType.Inbox }, - { CHAT_LABEL_ID, SpecialFolderType.Chat }, - { IMPORTANT_LABEL_ID, SpecialFolderType.Important }, - { TRASH_LABEL_ID, SpecialFolderType.Deleted }, - { DRAFT_LABEL_ID, SpecialFolderType.Draft }, - { SENT_LABEL_ID, SpecialFolderType.Sent }, - { SPAM_LABEL_ID, SpecialFolderType.Junk }, - { STARRED_LABEL_ID, SpecialFolderType.Starred }, - { UNREAD_LABEL_ID, SpecialFolderType.Unread }, - { FORUMS_LABEL_ID, SpecialFolderType.Forums }, - { UPDATES_LABEL_ID, SpecialFolderType.Updates }, - { PROMOTIONS_LABEL_ID, SpecialFolderType.Promotions }, - { SOCIAL_LABEL_ID, SpecialFolderType.Social}, - { PERSONAL_LABEL_ID, SpecialFolderType.Personal}, - }; - - public static string[] SubCategoryFolderLabelIds = - [ - FORUMS_LABEL_ID, - UPDATES_LABEL_ID, - PROMOTIONS_LABEL_ID, - SOCIAL_LABEL_ID, - PERSONAL_LABEL_ID - ]; private static string GetNormalizedLabelName(string labelName) { // 1. Remove CATEGORY_ prefix. - var normalizedLabelName = labelName.Replace(CATEGORY_PREFIX, string.Empty); + var normalizedLabelName = labelName.Replace(ServiceConstants.CATEGORY_PREFIX, string.Empty); // 2. Normalize label name by capitalizing first letter. normalizedLabelName = char.ToUpper(normalizedLabelName[0]) + normalizedLabelName.Substring(1).ToLower(); @@ -81,9 +35,9 @@ namespace Wino.Core.Extensions // Even though we normalize the label name, check is done by capitalizing the label name. var capitalNormalizedLabelName = normalizedLabelName.ToUpper(); - bool isSpecialFolder = KnownFolderDictionary.ContainsKey(capitalNormalizedLabelName); + bool isSpecialFolder = ServiceConstants.KnownFolderDictionary.ContainsKey(capitalNormalizedLabelName); - var specialFolderType = isSpecialFolder ? KnownFolderDictionary[capitalNormalizedLabelName] : SpecialFolderType.Other; + var specialFolderType = isSpecialFolder ? ServiceConstants.KnownFolderDictionary[capitalNormalizedLabelName] : SpecialFolderType.Other; // We used to support FOLDER_HIDE_IDENTIFIER to hide invisible folders. // However, a lot of people complained that they don't see their folders after the initial sync @@ -96,13 +50,13 @@ namespace Wino.Core.Extensions bool isHidden = false; - bool isChildOfCategoryFolder = label.Name.StartsWith(CATEGORY_PREFIX); + bool isChildOfCategoryFolder = label.Name.StartsWith(ServiceConstants.CATEGORY_PREFIX); bool isSticky = isSpecialFolder && specialFolderType != SpecialFolderType.Category && !isChildOfCategoryFolder; // By default, all special folders update unread count in the UI except Trash. bool shouldShowUnreadCount = specialFolderType != SpecialFolderType.Deleted || specialFolderType != SpecialFolderType.Other; - bool isSystemFolder = label.Type == SYSTEM_FOLDER_IDENTIFIER; + bool isSystemFolder = label.Type == ServiceConstants.SYSTEM_FOLDER_IDENTIFIER; var localFolder = new MailItemFolder() { @@ -126,16 +80,16 @@ namespace Wino.Core.Extensions } public static bool GetIsDraft(this Message message) - => message?.LabelIds?.Any(a => a == DRAFT_LABEL_ID) ?? false; + => message?.LabelIds?.Any(a => a == ServiceConstants.DRAFT_LABEL_ID) ?? false; public static bool GetIsUnread(this Message message) - => message?.LabelIds?.Any(a => a == UNREAD_LABEL_ID) ?? false; + => message?.LabelIds?.Any(a => a == ServiceConstants.UNREAD_LABEL_ID) ?? false; public static bool GetIsFocused(this Message message) - => message?.LabelIds?.Any(a => a == IMPORTANT_LABEL_ID) ?? false; + => message?.LabelIds?.Any(a => a == ServiceConstants.IMPORTANT_LABEL_ID) ?? false; public static bool GetIsFlagged(this Message message) - => message?.LabelIds?.Any(a => a == STARRED_LABEL_ID) ?? false; + => message?.LabelIds?.Any(a => a == ServiceConstants.STARRED_LABEL_ID) ?? false; private static string GetParentFolderRemoteId(string fullLabelName, ListLabelsResponse labelsResponse) { @@ -158,9 +112,9 @@ namespace Wino.Core.Extensions if (string.IsNullOrEmpty(fullFolderName)) return string.Empty; // Folders with "//" at the end has "/" as the name. - if (fullFolderName.EndsWith(FOLDER_SEPERATOR_STRING)) return FOLDER_SEPERATOR_STRING; + if (fullFolderName.EndsWith(ServiceConstants.FOLDER_SEPERATOR_STRING)) return ServiceConstants.FOLDER_SEPERATOR_STRING; - string[] parts = fullFolderName.Split(FOLDER_SEPERATOR_CHAR); + string[] parts = fullFolderName.Split(ServiceConstants.FOLDER_SEPERATOR_CHAR); var lastPart = parts[parts.Length - 1]; diff --git a/Wino.Core/Extensions/MimeExtensions.cs b/Wino.Core/Extensions/MimeExtensions.cs index cc4a30bd..d1ba145a 100644 --- a/Wino.Core/Extensions/MimeExtensions.cs +++ b/Wino.Core/Extensions/MimeExtensions.cs @@ -7,6 +7,7 @@ using MimeKit; using MimeKit.IO; using MimeKit.IO.Filters; using MimeKit.Utils; +using Wino.Services.Extensions; namespace Wino.Core.Extensions { diff --git a/Wino.Core/Integration/Processors/DefaultChangeProcessor.cs b/Wino.Core/Integration/Processors/DefaultChangeProcessor.cs index 61fbcb60..19a78f6e 100644 --- a/Wino.Core/Integration/Processors/DefaultChangeProcessor.cs +++ b/Wino.Core/Integration/Processors/DefaultChangeProcessor.cs @@ -7,7 +7,7 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Synchronization; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.Integration.Processors { diff --git a/Wino.Core/Integration/Processors/GmailChangeProcessor.cs b/Wino.Core/Integration/Processors/GmailChangeProcessor.cs index d23a3653..5615bce8 100644 --- a/Wino.Core/Integration/Processors/GmailChangeProcessor.cs +++ b/Wino.Core/Integration/Processors/GmailChangeProcessor.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.Integration.Processors { diff --git a/Wino.Core/Integration/Processors/ImapChangeProcessor.cs b/Wino.Core/Integration/Processors/ImapChangeProcessor.cs index e394514e..7271926e 100644 --- a/Wino.Core/Integration/Processors/ImapChangeProcessor.cs +++ b/Wino.Core/Integration/Processors/ImapChangeProcessor.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.Integration.Processors { diff --git a/Wino.Core/Integration/Processors/OutlookChangeProcessor.cs b/Wino.Core/Integration/Processors/OutlookChangeProcessor.cs index 1c0262f6..3086b687 100644 --- a/Wino.Core/Integration/Processors/OutlookChangeProcessor.cs +++ b/Wino.Core/Integration/Processors/OutlookChangeProcessor.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; +using Wino.Services; namespace Wino.Core.Integration.Processors { diff --git a/Wino.Core/Services/LaunchProtocolService.cs b/Wino.Core/Services/LaunchProtocolService.cs deleted file mode 100644 index 52252b2c..00000000 --- a/Wino.Core/Services/LaunchProtocolService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Wino.Core.Domain.Interfaces; -using Wino.Core.Domain.Models.Launch; - -namespace Wino.Core.Services; - -public class LaunchProtocolService : ILaunchProtocolService -{ - public object LaunchParameter { get; set; } - public MailToUri MailToUri { get; set; } -} diff --git a/Wino.Core/Services/ThreadingStrategyProvider.cs b/Wino.Core/Services/ThreadingStrategyProvider.cs index 65ba8b10..87b64823 100644 --- a/Wino.Core/Services/ThreadingStrategyProvider.cs +++ b/Wino.Core/Services/ThreadingStrategyProvider.cs @@ -1,6 +1,6 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -using Wino.Core.Integration.Threading; +using Wino.Services.Threading; namespace Wino.Core.Services { @@ -8,11 +8,11 @@ namespace Wino.Core.Services { private readonly OutlookThreadingStrategy _outlookThreadingStrategy; private readonly GmailThreadingStrategy _gmailThreadingStrategy; - private readonly ImapThreadStrategy _imapThreadStrategy; + private readonly ImapThreadingStrategy _imapThreadStrategy; public ThreadingStrategyProvider(OutlookThreadingStrategy outlookThreadingStrategy, GmailThreadingStrategy gmailThreadingStrategy, - ImapThreadStrategy imapThreadStrategy) + ImapThreadingStrategy imapThreadStrategy) { _outlookThreadingStrategy = outlookThreadingStrategy; _gmailThreadingStrategy = gmailThreadingStrategy; diff --git a/Wino.Core/Services/WinoRequestDelegator.cs b/Wino.Core/Services/WinoRequestDelegator.cs index 6223a843..fca62af1 100644 --- a/Wino.Core/Services/WinoRequestDelegator.cs +++ b/Wino.Core/Services/WinoRequestDelegator.cs @@ -22,7 +22,6 @@ namespace Wino.Core.Services private readonly IWinoServerConnectionManager _winoServerConnectionManager; private readonly IFolderService _folderService; private readonly IMailDialogService _dialogService; - private readonly ILogger _logger = Log.ForContext(); public WinoRequestDelegator(IWinoRequestProcessor winoRequestProcessor, IWinoServerConnectionManager winoServerConnectionManager, diff --git a/Wino.Core/Services/WinoRequestProcessor.cs b/Wino.Core/Services/WinoRequestProcessor.cs index 270d118a..ba958b2a 100644 --- a/Wino.Core/Services/WinoRequestProcessor.cs +++ b/Wino.Core/Services/WinoRequestProcessor.cs @@ -23,7 +23,6 @@ namespace Wino.Core.Services private readonly IFolderService _folderService; private readonly IKeyPressService _keyPressService; private readonly IPreferencesService _preferencesService; - private readonly IAccountService _accountService; private readonly IMailDialogService _dialogService; private readonly IMailService _mailService; @@ -41,14 +40,12 @@ namespace Wino.Core.Services public WinoRequestProcessor(IFolderService folderService, IKeyPressService keyPressService, IPreferencesService preferencesService, - IAccountService accountService, IMailDialogService dialogService, IMailService mailService) { _folderService = folderService; _keyPressService = keyPressService; _preferencesService = preferencesService; - _accountService = accountService; _dialogService = dialogService; _mailService = mailService; } diff --git a/Wino.Core/Synchronizers/GmailSynchronizer.cs b/Wino.Core/Synchronizers/GmailSynchronizer.cs index f4a1301b..a2fca285 100644 --- a/Wino.Core/Synchronizers/GmailSynchronizer.cs +++ b/Wino.Core/Synchronizers/GmailSynchronizer.cs @@ -32,6 +32,7 @@ using Wino.Core.Requests.Bundles; using Wino.Core.Requests.Folder; using Wino.Core.Requests.Mail; using Wino.Messaging.UI; +using Wino.Services; namespace Wino.Core.Synchronizers.Mail { @@ -532,11 +533,11 @@ namespace Wino.Core.Synchronizers.Mail foreach (var labelId in addedLabel.LabelIds) { // When UNREAD label is added mark the message as un-read. - if (labelId == GoogleIntegratorExtensions.UNREAD_LABEL_ID) + if (labelId == ServiceConstants.UNREAD_LABEL_ID) await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, false).ConfigureAwait(false); // When STARRED label is added mark the message as flagged. - if (labelId == GoogleIntegratorExtensions.STARRED_LABEL_ID) + if (labelId == ServiceConstants.STARRED_LABEL_ID) await _gmailChangeProcessor.ChangeFlagStatusAsync(messageId, true).ConfigureAwait(false); await _gmailChangeProcessor.CreateAssignmentAsync(Account.Id, messageId, labelId).ConfigureAwait(false); @@ -552,11 +553,11 @@ namespace Wino.Core.Synchronizers.Mail foreach (var labelId in removedLabel.LabelIds) { // When UNREAD label is removed mark the message as read. - if (labelId == GoogleIntegratorExtensions.UNREAD_LABEL_ID) + if (labelId == ServiceConstants.UNREAD_LABEL_ID) await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, true).ConfigureAwait(false); // When STARRED label is removed mark the message as un-flagged. - if (labelId == GoogleIntegratorExtensions.STARRED_LABEL_ID) + if (labelId == ServiceConstants.STARRED_LABEL_ID) await _gmailChangeProcessor.ChangeFlagStatusAsync(messageId, false).ConfigureAwait(false); // For other labels remove the mail assignment. @@ -637,9 +638,9 @@ namespace Wino.Core.Synchronizers.Mail }; if (isFlagged) - batchModifyRequest.AddLabelIds = new List() { GoogleIntegratorExtensions.STARRED_LABEL_ID }; + batchModifyRequest.AddLabelIds = new List() { ServiceConstants.STARRED_LABEL_ID }; else - batchModifyRequest.RemoveLabelIds = new List() { GoogleIntegratorExtensions.STARRED_LABEL_ID }; + batchModifyRequest.RemoveLabelIds = new List() { ServiceConstants.STARRED_LABEL_ID }; var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me"); @@ -656,9 +657,9 @@ namespace Wino.Core.Synchronizers.Mail }; if (readStatus) - batchModifyRequest.RemoveLabelIds = new List() { GoogleIntegratorExtensions.UNREAD_LABEL_ID }; + batchModifyRequest.RemoveLabelIds = new List() { ServiceConstants.UNREAD_LABEL_ID }; else - batchModifyRequest.AddLabelIds = new List() { GoogleIntegratorExtensions.UNREAD_LABEL_ID }; + batchModifyRequest.AddLabelIds = new List() { ServiceConstants.UNREAD_LABEL_ID }; var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me"); @@ -704,11 +705,11 @@ namespace Wino.Core.Synchronizers.Mail if (isArchiving) { - batchModifyRequest.RemoveLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID }; + batchModifyRequest.RemoveLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID }; } else { - batchModifyRequest.AddLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID }; + batchModifyRequest.AddLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID }; } var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me"); diff --git a/Wino.Core/Synchronizers/ImapSynchronizer.cs b/Wino.Core/Synchronizers/ImapSynchronizer.cs index 1ec9dd89..2778cf04 100644 --- a/Wino.Core/Synchronizers/ImapSynchronizer.cs +++ b/Wino.Core/Synchronizers/ImapSynchronizer.cs @@ -27,6 +27,7 @@ using Wino.Core.Requests.Bundles; using Wino.Core.Requests.Folder; using Wino.Core.Requests.Mail; using Wino.Messaging.UI; +using Wino.Services.Extensions; namespace Wino.Core.Synchronizers.Mail { diff --git a/Wino.Core/Wino.Core.csproj b/Wino.Core/Wino.Core.csproj index 56060661..e6215980 100644 --- a/Wino.Core/Wino.Core.csproj +++ b/Wino.Core/Wino.Core.csproj @@ -6,6 +6,8 @@ Debug;Release 12 AnyCPU;x64;x86 + true + true @@ -47,5 +49,6 @@ + diff --git a/Wino.Mail.ViewModels/AppShellViewModel.cs b/Wino.Mail.ViewModels/AppShellViewModel.cs index a4b81d9b..b16a8c53 100644 --- a/Wino.Mail.ViewModels/AppShellViewModel.cs +++ b/Wino.Mail.ViewModels/AppShellViewModel.cs @@ -16,12 +16,11 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.MenuItems; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Synchronization; -using Wino.Core.MenuItems; -using Wino.Core.Services; using Wino.Messaging.Client.Accounts; using Wino.Messaging.Client.Navigation; using Wino.Messaging.Client.Shell; @@ -55,7 +54,7 @@ namespace Wino.Mail.ViewModels private readonly SettingsItem SettingsItem = new SettingsItem(); private readonly ManageAccountsMenuItem ManageAccountsMenuItem = new ManageAccountsMenuItem(); - public NewMailMenuItem CreateMailMenuItem = new NewMailMenuItem(); + public IMenuItem CreateMailMenuItem = new NewMailMenuItem(); #endregion diff --git a/Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs b/Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs new file mode 100644 index 00000000..3ae6f17e --- /dev/null +++ b/Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Wino.Core; + +namespace Wino.Mail.ViewModels +{ + public static class MailViewModelsContainerSetup + { + public static void RegisterViewModelService(this IServiceCollection services) + { + // View models use core services. + services.RegisterCoreServices(); + } + } +} diff --git a/Wino.Mail.ViewModels/Messages/ActiveMailItemChangedEvent.cs b/Wino.Mail.ViewModels/Messages/ActiveMailItemChangedEvent.cs index fb0fc2b9..6e9c213f 100644 --- a/Wino.Mail.ViewModels/Messages/ActiveMailItemChangedEvent.cs +++ b/Wino.Mail.ViewModels/Messages/ActiveMailItemChangedEvent.cs @@ -1,6 +1,4 @@ -using System; -using Wino.Core.MenuItems; -using Wino.Mail.ViewModels.Data; +using Wino.Mail.ViewModels.Data; namespace Wino.Mail.ViewModels.Messages { diff --git a/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj b/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj index 4844085d..6c71fb7c 100644 --- a/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj +++ b/Wino.Mail.ViewModels/Wino.Mail.ViewModels.csproj @@ -4,6 +4,9 @@ netstandard2.0 12 AnyCPU;x64;x86 + + true + true @@ -21,6 +24,7 @@ + diff --git a/Wino.Mail/Activation/FileActivationHandler.cs b/Wino.Mail/Activation/FileActivationHandler.cs index 717d541e..aa6bec91 100644 --- a/Wino.Mail/Activation/FileActivationHandler.cs +++ b/Wino.Mail/Activation/FileActivationHandler.cs @@ -10,7 +10,6 @@ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Animation; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; using Wino.Views; namespace Wino.Activation diff --git a/Wino.Mail/Activation/ToastNotificationActivationHandler.cs b/Wino.Mail/Activation/ToastNotificationActivationHandler.cs index f8e3f3be..9f7cb56f 100644 --- a/Wino.Mail/Activation/ToastNotificationActivationHandler.cs +++ b/Wino.Mail/Activation/ToastNotificationActivationHandler.cs @@ -17,17 +17,14 @@ namespace Wino.Activation /// internal class ToastNotificationActivationHandler : ActivationHandler { - private readonly INativeAppService _nativeAppService; private readonly IMailService _mailService; private readonly IFolderService _folderService; private ToastArguments _toastArguments; - public ToastNotificationActivationHandler(INativeAppService nativeAppService, - IMailService mailService, + public ToastNotificationActivationHandler(IMailService mailService, IFolderService folderService) { - _nativeAppService = nativeAppService; _mailService = mailService; _folderService = folderService; } diff --git a/Wino.Mail/App.xaml.cs b/Wino.Mail/App.xaml.cs index c7e10e0e..806f6399 100644 --- a/Wino.Mail/App.xaml.cs +++ b/Wino.Mail/App.xaml.cs @@ -13,7 +13,6 @@ using Windows.ApplicationModel.Background; using Windows.UI.Core.Preview; using Windows.UI.Notifications; using Wino.Activation; -using Wino.Core; using Wino.Core.Domain; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Exceptions; @@ -70,7 +69,8 @@ namespace Wino { var services = new ServiceCollection(); - services.RegisterCoreServices(); + services.RegisterViewModelService(); + services.RegisterSharedServices(); services.RegisterCoreUWPServices(); services.RegisterCoreViewModels(); diff --git a/Wino.Mail/AppShell.xaml b/Wino.Mail/AppShell.xaml index 15bc5094..56fd82fd 100644 --- a/Wino.Mail/AppShell.xaml +++ b/Wino.Mail/AppShell.xaml @@ -15,7 +15,7 @@ xmlns:enums="using:Wino.Core.Domain.Enums" xmlns:helpers="using:Wino.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:menu="using:Wino.Core.MenuItems" + xmlns:menu="using:Wino.Core.Domain.MenuItems" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" x:Name="Root" muxc:BackdropMaterial.ApplyToRootOrPageBackground="{ThemeResource UseMica}" diff --git a/Wino.Mail/Behaviors/CreateMailNavigationItemBehavior.cs b/Wino.Mail/Behaviors/CreateMailNavigationItemBehavior.cs index 77d35081..c305eb04 100644 --- a/Wino.Mail/Behaviors/CreateMailNavigationItemBehavior.cs +++ b/Wino.Mail/Behaviors/CreateMailNavigationItemBehavior.cs @@ -1,27 +1,27 @@ using System.Collections.ObjectModel; using Microsoft.Xaml.Interactivity; using Windows.UI.Xaml; -using Wino.Core.MenuItems; +using Wino.Core.Domain.Interfaces; using Wino.Core.UWP.Controls; namespace Wino.Behaviors { public class CreateMailNavigationItemBehavior : Behavior { - public MenuItemBase SelectedMenuItem + public IMenuItem SelectedMenuItem { - get { return (MenuItemBase)GetValue(SelectedMenuItemProperty); } + get { return (IMenuItem)GetValue(SelectedMenuItemProperty); } set { SetValue(SelectedMenuItemProperty, value); } } - public ObservableCollection MenuItems + public ObservableCollection MenuItems { - get { return (ObservableCollection)GetValue(MenuItemsProperty); } + get { return (ObservableCollection)GetValue(MenuItemsProperty); } set { SetValue(MenuItemsProperty, value); } } - public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnMenuItemsChanged)); - public static readonly DependencyProperty SelectedMenuItemProperty = DependencyProperty.Register(nameof(SelectedMenuItem), typeof(MenuItemBase), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnSelectedMenuItemChanged)); + public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnMenuItemsChanged)); + public static readonly DependencyProperty SelectedMenuItemProperty = DependencyProperty.Register(nameof(SelectedMenuItem), typeof(IMenuItem), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnSelectedMenuItemChanged)); public CreateMailNavigationItemBehavior() { diff --git a/Wino.Mail/Controls/ImagePreviewControl.cs b/Wino.Mail/Controls/ImagePreviewControl.cs index 344e1057..5a0e9cc1 100644 --- a/Wino.Mail/Controls/ImagePreviewControl.cs +++ b/Wino.Mail/Controls/ImagePreviewControl.cs @@ -11,7 +11,7 @@ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; using Windows.UI.Xaml.Shapes; -using Wino.Core.Services; +using Wino.Core.UWP.Services; namespace Wino.Controls { diff --git a/Wino.Mail/Wino.Mail.csproj b/Wino.Mail/Wino.Mail.csproj index c24cc523..e24d49ef 100644 --- a/Wino.Mail/Wino.Mail.csproj +++ b/Wino.Mail/Wino.Mail.csproj @@ -604,10 +604,6 @@ {53723ae8-7e7e-4d54-adab-0a6033255cc8} Wino.Core.ViewModels - - {E6B1632A-8901-41E8-9DDF-6793C7698B0B} - Wino.Core - {d62f1c03-da57-4709-a640-0283296a8e66} Wino.Mail.ViewModels @@ -616,6 +612,10 @@ {0c307d7e-256f-448c-8265-5622a812fbcc} Wino.Messaging + + {4000a374-59fe-4400-acf6-d40473becd73} + Wino.Services + diff --git a/Wino.Messages/Wino.Messaging.csproj b/Wino.Messages/Wino.Messaging.csproj index 82d1d88f..c012b615 100644 --- a/Wino.Messages/Wino.Messaging.csproj +++ b/Wino.Messages/Wino.Messaging.csproj @@ -4,6 +4,9 @@ netstandard2.0 12 AnyCPU;x64;x86 + + true + true diff --git a/Wino.Server/App.xaml.cs b/Wino.Server/App.xaml.cs index 954273af..f638afcb 100644 --- a/Wino.Server/App.xaml.cs +++ b/Wino.Server/App.xaml.cs @@ -14,7 +14,6 @@ using Wino.Core; using Wino.Core.Domain; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; using Wino.Core.UWP.Services; using Wino.Server.Core; using Wino.Server.MessageHandlers; @@ -68,6 +67,7 @@ namespace Wino.Server services.AddTransient(); services.RegisterCoreServices(); + services.RegisterSharedServices(); // Below services belongs to UWP.Core package and some APIs are not available for WPF. // We register them here to avoid compilation errors. @@ -77,6 +77,7 @@ namespace Wino.Server services.AddSingleton(); services.AddTransient(); services.AddTransient(); + services.AddSingleton(); // Register server message handler factory. var serverMessageHandlerFactory = new ServerMessageHandlerFactory(); diff --git a/Wino.Server/ServerContext.cs b/Wino.Server/ServerContext.cs index ed21889f..e3875573 100644 --- a/Wino.Server/ServerContext.cs +++ b/Wino.Server/ServerContext.cs @@ -13,13 +13,13 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Requests; using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Integration.Json; -using Wino.Core.Services; using Wino.Messaging; using Wino.Messaging.Client.Authorization; using Wino.Messaging.Enums; using Wino.Messaging.Server; using Wino.Messaging.UI; using Wino.Server.MessageHandlers; +using Wino.Services; namespace Wino.Server { diff --git a/Wino.Server/Wino.Server.csproj b/Wino.Server/Wino.Server.csproj index e1a7c79d..ee5fee2a 100644 --- a/Wino.Server/Wino.Server.csproj +++ b/Wino.Server/Wino.Server.csproj @@ -25,6 +25,7 @@ + @@ -42,5 +43,6 @@ + diff --git a/Wino.Core/Services/AccountService.cs b/Wino.Services/AccountService.cs similarity index 97% rename from Wino.Core/Services/AccountService.cs rename to Wino.Services/AccountService.cs index aa07b63f..7dfbddd2 100644 --- a/Wino.Core/Services/AccountService.cs +++ b/Wino.Services/AccountService.cs @@ -11,28 +11,25 @@ using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Accounts; -using Wino.Core.Extensions; using Wino.Messaging.Client.Accounts; using Wino.Messaging.UI; +using Wino.Services.Extensions; -namespace Wino.Core.Services +namespace Wino.Services { public class AccountService : BaseDatabaseService, IAccountService { public IAuthenticator ExternalAuthenticationAuthenticator { get; set; } - private readonly IAuthenticationProvider _authenticationProvider; private readonly ISignatureService _signatureService; private readonly IPreferencesService _preferencesService; private readonly ILogger _logger = Log.ForContext(); public AccountService(IDatabaseService databaseService, - IAuthenticationProvider authenticationProvider, ISignatureService signatureService, IPreferencesService preferencesService) : base(databaseService) { - _authenticationProvider = authenticationProvider; _signatureService = signatureService; _preferencesService = preferencesService; } @@ -203,13 +200,13 @@ namespace Wino.Core.Services if (account == null) return; - var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType); + //var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType); - // This will re-generate token. - var token = await authenticator.GenerateTokenInformationAsync(account); + //// This will re-generate token. + //var token = await authenticator.GenerateTokenInformationAsync(account); // TODO: Rest? - Guard.IsNotNull(token); + // Guard.IsNotNull(token); } private Task GetAccountPreferencesAsync(Guid accountId) @@ -538,10 +535,10 @@ namespace Wino.Core.Services var currentIdentifier = account.SynchronizationDeltaIdentifier; bool shouldUpdateIdentifier = account.ProviderType == MailProviderType.Gmail ? - ((string.IsNullOrEmpty(currentIdentifier) ? true : !string.IsNullOrEmpty(currentIdentifier) + string.IsNullOrEmpty(currentIdentifier) ? true : !string.IsNullOrEmpty(currentIdentifier) && ulong.TryParse(currentIdentifier, out ulong currentIdentifierValue) && ulong.TryParse(newIdentifier, out ulong newIdentifierValue) - && newIdentifierValue > currentIdentifierValue)) : true; + && newIdentifierValue > currentIdentifierValue : true; if (shouldUpdateIdentifier) { diff --git a/Wino.Core/Services/ApplicationConfiguration.cs b/Wino.Services/ApplicationConfiguration.cs similarity index 92% rename from Wino.Core/Services/ApplicationConfiguration.cs rename to Wino.Services/ApplicationConfiguration.cs index d5d12bf8..f03369c4 100644 --- a/Wino.Core/Services/ApplicationConfiguration.cs +++ b/Wino.Services/ApplicationConfiguration.cs @@ -1,6 +1,6 @@ using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Services +namespace Wino.Services { public class ApplicationConfiguration : IApplicationConfiguration { diff --git a/Wino.Core/Services/BaseDatabaseService.cs b/Wino.Services/BaseDatabaseService.cs similarity index 95% rename from Wino.Core/Services/BaseDatabaseService.cs rename to Wino.Services/BaseDatabaseService.cs index 18e6d9ce..ed5cdb72 100644 --- a/Wino.Core/Services/BaseDatabaseService.cs +++ b/Wino.Services/BaseDatabaseService.cs @@ -2,7 +2,7 @@ using SQLite; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Services +namespace Wino.Services { public class BaseDatabaseService { diff --git a/Wino.Core/Services/ContactService.cs b/Wino.Services/ContactService.cs similarity index 86% rename from Wino.Core/Services/ContactService.cs rename to Wino.Services/ContactService.cs index 065d25ed..1757983c 100644 --- a/Wino.Core/Services/ContactService.cs +++ b/Wino.Services/ContactService.cs @@ -4,17 +4,11 @@ using System.Threading.Tasks; using MimeKit; using SqlKata; using Wino.Core.Domain.Entities.Shared; -using Wino.Core.Extensions; +using Wino.Core.Domain.Interfaces; +using Wino.Services.Extensions; -namespace Wino.Core.Services +namespace Wino.Services { - public interface IContactService - { - Task> GetAddressInformationAsync(string queryText); - Task GetAddressInformationByAddressAsync(string address); - Task SaveAddressInformationAsync(MimeMessage message); - } - public class ContactService : BaseDatabaseService, IContactService { public ContactService(IDatabaseService databaseService) : base(databaseService) { } diff --git a/Wino.Core/Services/ContextMenuItemService.cs b/Wino.Services/ContextMenuItemService.cs similarity index 98% rename from Wino.Core/Services/ContextMenuItemService.cs rename to Wino.Services/ContextMenuItemService.cs index e6238e8f..e5c285e1 100644 --- a/Wino.Core/Services/ContextMenuItemService.cs +++ b/Wino.Services/ContextMenuItemService.cs @@ -6,7 +6,7 @@ using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Menus; -namespace Wino.Core.Services +namespace Wino.Services { public class ContextMenuItemService : IContextMenuItemService { @@ -93,7 +93,7 @@ namespace Wino.Core.Services }; operationList.AddRange(readOperations); - List flagsOperations = (isAllFlagged, isAllNotFlagged) switch + List flagsOperations = (isAllFlagged, isAllNotFlagged) switch { (true, false) => [MailOperationMenuItem.Create(MailOperation.ClearFlag)], (false, true) => [MailOperationMenuItem.Create(MailOperation.SetFlag)], diff --git a/Wino.Core/Services/DatabaseService.cs b/Wino.Services/DatabaseService.cs similarity index 98% rename from Wino.Core/Services/DatabaseService.cs rename to Wino.Services/DatabaseService.cs index 4e368aea..68451bb0 100644 --- a/Wino.Core/Services/DatabaseService.cs +++ b/Wino.Services/DatabaseService.cs @@ -5,7 +5,7 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Services +namespace Wino.Services { public interface IDatabaseService : IInitializeAsync { diff --git a/Wino.Core/Extensions/HtmlAgilityPackExtensions.cs b/Wino.Services/Extensions/HtmlAgilityPackExtensions.cs similarity index 96% rename from Wino.Core/Extensions/HtmlAgilityPackExtensions.cs rename to Wino.Services/Extensions/HtmlAgilityPackExtensions.cs index 1c1cc61f..f09ec047 100644 --- a/Wino.Core/Extensions/HtmlAgilityPackExtensions.cs +++ b/Wino.Services/Extensions/HtmlAgilityPackExtensions.cs @@ -1,10 +1,9 @@ using System; -using System.Diagnostics; using System.IO; using System.Linq; using HtmlAgilityPack; -namespace Wino.Core.Extensions +namespace Wino.Services.Extensions { public static class HtmlAgilityPackExtensions { @@ -81,7 +80,7 @@ namespace Wino.Core.Extensions case HtmlNodeType.Text: // script and style must not be output string parentName = node.ParentNode.Name; - if ((parentName == "script") || (parentName == "style")) + if (parentName == "script" || parentName == "style") break; // get text diff --git a/Wino.Core/Extensions/MailkitClientExtensions.cs b/Wino.Services/Extensions/MailkitClientExtensions.cs similarity index 99% rename from Wino.Core/Extensions/MailkitClientExtensions.cs rename to Wino.Services/Extensions/MailkitClientExtensions.cs index 06a32a7b..e4c31750 100644 --- a/Wino.Core/Extensions/MailkitClientExtensions.cs +++ b/Wino.Services/Extensions/MailkitClientExtensions.cs @@ -5,8 +5,9 @@ using MimeKit; using Wino.Core.Domain; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; +using Wino.Services.Extensions; -namespace Wino.Core.Extensions +namespace Wino.Services.Extensions { public static class MailkitClientExtensions { diff --git a/Wino.Core/Extensions/SqlKataExtensions.cs b/Wino.Services/Extensions/SqlKataExtensions.cs similarity index 89% rename from Wino.Core/Extensions/SqlKataExtensions.cs rename to Wino.Services/Extensions/SqlKataExtensions.cs index a974d013..b67871ae 100644 --- a/Wino.Core/Extensions/SqlKataExtensions.cs +++ b/Wino.Services/Extensions/SqlKataExtensions.cs @@ -1,7 +1,7 @@ using SqlKata; using SqlKata.Compilers; -namespace Wino.Core.Extensions +namespace Wino.Services.Extensions { public static class SqlKataExtensions { diff --git a/Wino.Core/Services/FolderService.cs b/Wino.Services/FolderService.cs similarity index 97% rename from Wino.Core/Services/FolderService.cs rename to Wino.Services/FolderService.cs index 7ab178aa..2d65c39a 100644 --- a/Wino.Core/Services/FolderService.cs +++ b/Wino.Services/FolderService.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CommunityToolkit.Mvvm.Messaging; -using MoreLinq; using Serilog; using SqlKata; using Wino.Core.Domain; @@ -11,20 +10,19 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Shared; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.MenuItems; using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Synchronization; -using Wino.Core.Extensions; -using Wino.Core.MenuItems; using Wino.Messaging.UI; +using Wino.Services.Extensions; -namespace Wino.Core.Services +namespace Wino.Services { public class FolderService : BaseDatabaseService, IFolderService { private readonly IAccountService _accountService; - private readonly IMimeFileService _mimeFileService; private readonly ILogger _logger = Log.ForContext(); private readonly SpecialFolderType[] gmailCategoryFolderTypes = @@ -37,11 +35,9 @@ namespace Wino.Core.Services ]; public FolderService(IDatabaseService databaseService, - IAccountService accountService, - IMimeFileService mimeFileService) : base(databaseService) + IAccountService accountService) : base(databaseService) { _accountService = accountService; - _mimeFileService = mimeFileService; } public async Task ChangeStickyStatusAsync(Guid folderId, bool isSticky) @@ -149,10 +145,10 @@ namespace Wino.Core.Services } else if (account.ProviderType == MailProviderType.Outlook || account.ProviderType == MailProviderType.Office365) { - bool belongsToExistingParent = (await Connection + bool belongsToExistingParent = await Connection .Table() .Where(a => unstickyItem.ParentRemoteFolderId == a.RemoteFolderId) - .CountAsync()) > 0; + .CountAsync() > 0; // No need to include this as unsticky. if (belongsToExistingParent) continue; @@ -236,14 +232,14 @@ namespace Wino.Core.Services foreach (var item in listingFolders) { // Category type folders should be skipped. They will be categorized under virtual category folder. - if (GoogleIntegratorExtensions.SubCategoryFolderLabelIds.Contains(item.RemoteFolderId)) continue; + if (ServiceConstants.SubCategoryFolderLabelIds.Contains(item.RemoteFolderId)) continue; bool skipEmptyParentRemoteFolders = mailAccount.ProviderType == MailProviderType.Gmail; if (skipEmptyParentRemoteFolders && !string.IsNullOrEmpty(item.ParentRemoteFolderId)) continue; // Sticky items belong to account menu item directly. Rest goes to More folder. - IMenuItem parentFolderMenuItem = item.IsSticky ? accountMenuItem : (GoogleIntegratorExtensions.SubCategoryFolderLabelIds.Contains(item.FolderName.ToUpper()) ? categoryFolderMenuItem : moreFolderMenuItem); + IMenuItem parentFolderMenuItem = item.IsSticky ? accountMenuItem : ServiceConstants.SubCategoryFolderLabelIds.Contains(item.FolderName.ToUpper()) ? categoryFolderMenuItem : moreFolderMenuItem; var preparedItem = await GetPreparedFolderMenuItemRecursiveAsync(mailAccount, item, parentFolderMenuItem).ConfigureAwait(false); @@ -665,9 +661,9 @@ namespace Wino.Core.Services } public async Task IsInboxAvailableForAccountAsync(Guid accountId) - => (await Connection.Table() + => await Connection.Table() .Where(a => a.SpecialFolderType == SpecialFolderType.Inbox && a.MailAccountId == accountId) - .CountAsync()) == 1; + .CountAsync() == 1; public Task UpdateFolderLastSyncDateAsync(Guid folderId) => Connection.ExecuteAsync("UPDATE MailItemFolder SET LastSynchronizedDate = ? WHERE Id = ?", DateTime.UtcNow, folderId); diff --git a/Wino.Services/LaunchProtocolService.cs b/Wino.Services/LaunchProtocolService.cs new file mode 100644 index 00000000..8d105e5c --- /dev/null +++ b/Wino.Services/LaunchProtocolService.cs @@ -0,0 +1,11 @@ +using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.Models.Launch; + +namespace Wino.Services +{ + public class LaunchProtocolService : ILaunchProtocolService + { + public object LaunchParameter { get; set; } + public MailToUri MailToUri { get; set; } + } +} diff --git a/Wino.Core/Services/LogInitializer.cs b/Wino.Services/LogInitializer.cs similarity index 97% rename from Wino.Core/Services/LogInitializer.cs rename to Wino.Services/LogInitializer.cs index da0ab08f..a4dae199 100644 --- a/Wino.Core/Services/LogInitializer.cs +++ b/Wino.Services/LogInitializer.cs @@ -3,7 +3,7 @@ using Serilog.Core; using Serilog.Exceptions; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Services +namespace Wino.Services { public class LogInitializer : ILogInitializer { diff --git a/Wino.Core/Services/MailService.cs b/Wino.Services/MailService.cs similarity index 98% rename from Wino.Core/Services/MailService.cs rename to Wino.Services/MailService.cs index d58137ca..e5f02cec 100644 --- a/Wino.Core/Services/MailService.cs +++ b/Wino.Services/MailService.cs @@ -3,9 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.Kiota.Abstractions.Extensions; using MimeKit; -using MoreLinq; using Serilog; using SqlKata; using Wino.Core.Domain; @@ -17,10 +15,10 @@ using Wino.Core.Domain.Extensions; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Comparers; using Wino.Core.Domain.Models.MailItem; -using Wino.Core.Extensions; using Wino.Messaging.UI; +using Wino.Services.Extensions; -namespace Wino.Core.Services +namespace Wino.Services { public class MailService : BaseDatabaseService, IMailService { @@ -285,7 +283,10 @@ namespace Wino.Core.Services if (!isFolderCached) { folderAssignment = await _folderService.GetFolderAsync(mailCopy.FolderId).ConfigureAwait(false); - _ = folderCache.TryAdd(mailCopy.FolderId, folderAssignment); + if (!folderCache.ContainsKey(mailCopy.FolderId)) + { + folderCache.Add(mailCopy.FolderId, folderAssignment); + } } if (folderAssignment != null) @@ -294,8 +295,11 @@ namespace Wino.Core.Services if (!isAccountCached) { accountAssignment = await _accountService.GetAccountAsync(folderAssignment.MailAccountId).ConfigureAwait(false); - _ = accountCache.TryAdd(folderAssignment.MailAccountId, accountAssignment); + if (!accountCache.ContainsKey(folderAssignment.MailAccountId)) + { + accountCache.Add(folderAssignment.MailAccountId, accountAssignment); + } } } @@ -311,7 +315,10 @@ namespace Wino.Core.Services if (contactAssignment != null) { - _ = contactCache.TryAdd(mailCopy.FromAddress, contactAssignment); + if (!contactCache.ContainsKey(mailCopy.FromAddress)) + { + contactCache.Add(mailCopy.FromAddress, contactAssignment); + } } } @@ -728,7 +735,8 @@ namespace Wino.Core.Services _ => CreateReferencedDraft(builder, message, draftCreationOptions, account, signature), }; - builder.SetHtmlBody(builder.HtmlBody); + // TODO: Migration + // builder.SetHtmlBody(builder.HtmlBody); message.Body = builder.ToMessageBody(); diff --git a/Wino.Core/Services/MimeFileService.cs b/Wino.Services/MimeFileService.cs similarity index 67% rename from Wino.Core/Services/MimeFileService.cs rename to Wino.Services/MimeFileService.cs index 42a93f65..4507984d 100644 --- a/Wino.Core/Services/MimeFileService.cs +++ b/Wino.Services/MimeFileService.cs @@ -8,72 +8,10 @@ using Serilog; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Reader; -using Wino.Core.Extensions; -using Wino.Core.Mime; +using Wino.Services.Extensions; -namespace Wino.Core.Services +namespace Wino.Services { - public interface IMimeFileService - { - /// - /// Finds the EML file for the given mail id for address, parses and returns MimeMessage. - /// - /// Cancellation token - /// Mime message information - Task GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default); - - /// - /// Gets the mime message information for the given EML file bytes. - /// This override is used when EML file association launch is used - /// because we may not have the access to the file path. - /// - /// Byte array of the file. - /// Cancellation token - /// Mime message information - Task GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default); - - /// - /// Saves EML file to the disk. - /// - /// MailCopy of the native message. - /// MimeMessage that is parsed from native message. - /// Which account Id to save this file for. - Task SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId); - - /// - /// Returns a path that all Mime resources (including eml) is stored for this MailCopyId - /// This is useful for storing previously rendered attachments as well. - /// - /// Account address - /// Resource mail copy id - Task GetMimeResourcePathAsync(Guid accountId, Guid fileId); - - /// - /// Returns whether mime file exists locally or not. - /// - Task IsMimeExistAsync(Guid accountId, Guid fileId); - - /// - /// Creates HtmlPreviewVisitor for the given MimeMessage. - /// - /// Mime - /// File path that mime is located to load resources. - HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath); - - /// - /// Deletes the given mime file from the disk. - /// - Task DeleteMimeMessageAsync(Guid accountId, Guid fileId); - - /// - /// Prepares the final model containing rendering details. - /// - /// Message to render. - /// File path that physical MimeMessage is located. - /// Rendering options - MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null); - } - public class MimeFileService : IMimeFileService { private readonly INativeAppService _nativeAppService; diff --git a/Wino.Services/ServiceConstants.cs b/Wino.Services/ServiceConstants.cs new file mode 100644 index 00000000..c91f749e --- /dev/null +++ b/Wino.Services/ServiceConstants.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using Wino.Core.Domain.Enums; + +namespace Wino.Services +{ + public static class ServiceConstants + { + #region Gmail Constants + + public const string INBOX_LABEL_ID = "INBOX"; + public const string UNREAD_LABEL_ID = "UNREAD"; + public const string IMPORTANT_LABEL_ID = "IMPORTANT"; + public const string STARRED_LABEL_ID = "STARRED"; + public const string DRAFT_LABEL_ID = "DRAFT"; + public const string SENT_LABEL_ID = "SENT"; + public const string SPAM_LABEL_ID = "SPAM"; + public const string CHAT_LABEL_ID = "CHAT"; + public const string TRASH_LABEL_ID = "TRASH"; + + // Category labels. + public const string FORUMS_LABEL_ID = "FORUMS"; + public const string UPDATES_LABEL_ID = "UPDATES"; + public const string PROMOTIONS_LABEL_ID = "PROMOTIONS"; + public const string SOCIAL_LABEL_ID = "SOCIAL"; + public const string PERSONAL_LABEL_ID = "PERSONAL"; + + // Label visibility identifiers. + public const string SYSTEM_FOLDER_IDENTIFIER = "system"; + public const string FOLDER_HIDE_IDENTIFIER = "labelHide"; + + public const string CATEGORY_PREFIX = "CATEGORY_"; + public const string FOLDER_SEPERATOR_STRING = "/"; + public const char FOLDER_SEPERATOR_CHAR = '/'; + + public static Dictionary KnownFolderDictionary = new Dictionary() + { + { INBOX_LABEL_ID, SpecialFolderType.Inbox }, + { CHAT_LABEL_ID, SpecialFolderType.Chat }, + { IMPORTANT_LABEL_ID, SpecialFolderType.Important }, + { TRASH_LABEL_ID, SpecialFolderType.Deleted }, + { DRAFT_LABEL_ID, SpecialFolderType.Draft }, + { SENT_LABEL_ID, SpecialFolderType.Sent }, + { SPAM_LABEL_ID, SpecialFolderType.Junk }, + { STARRED_LABEL_ID, SpecialFolderType.Starred }, + { UNREAD_LABEL_ID, SpecialFolderType.Unread }, + { FORUMS_LABEL_ID, SpecialFolderType.Forums }, + { UPDATES_LABEL_ID, SpecialFolderType.Updates }, + { PROMOTIONS_LABEL_ID, SpecialFolderType.Promotions }, + { SOCIAL_LABEL_ID, SpecialFolderType.Social}, + { PERSONAL_LABEL_ID, SpecialFolderType.Personal}, + }; + + public static string[] SubCategoryFolderLabelIds = + [ + FORUMS_LABEL_ID, + UPDATES_LABEL_ID, + PROMOTIONS_LABEL_ID, + SOCIAL_LABEL_ID, + PERSONAL_LABEL_ID + ]; + + #endregion + } +} diff --git a/Wino.Services/ServicesContainerSetup.cs b/Wino.Services/ServicesContainerSetup.cs new file mode 100644 index 00000000..bc09bf58 --- /dev/null +++ b/Wino.Services/ServicesContainerSetup.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using Wino.Core.Domain.Interfaces; +using Wino.Services.Threading; + +namespace Wino.Services +{ + public static class ServicesContainerSetup + { + public static void RegisterSharedServices(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + + services.AddSingleton(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } + } +} diff --git a/Wino.Core/Services/SignatureService.cs b/Wino.Services/SignatureService.cs similarity index 98% rename from Wino.Core/Services/SignatureService.cs rename to Wino.Services/SignatureService.cs index ee6a4b40..d5ccae7d 100644 --- a/Wino.Core/Services/SignatureService.cs +++ b/Wino.Services/SignatureService.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Interfaces; -namespace Wino.Core.Services +namespace Wino.Services { public class SignatureService(IDatabaseService databaseService) : BaseDatabaseService(databaseService), ISignatureService { diff --git a/Wino.Core/Integration/Threading/APIThreadingStrategy.cs b/Wino.Services/Threading/APIThreadingStrategy.cs similarity index 98% rename from Wino.Core/Integration/Threading/APIThreadingStrategy.cs rename to Wino.Services/Threading/APIThreadingStrategy.cs index 25d65060..e8d95832 100644 --- a/Wino.Core/Integration/Threading/APIThreadingStrategy.cs +++ b/Wino.Services/Threading/APIThreadingStrategy.cs @@ -7,9 +7,9 @@ using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; -using Wino.Core.Services; +using Wino.Services; -namespace Wino.Core.Integration.Threading +namespace Wino.Services.Threading { public class APIThreadingStrategy : IThreadingStrategy { diff --git a/Wino.Core/Integration/Threading/GmailThreadingStrategy.cs b/Wino.Services/Threading/GmailThreadingStrategy.cs similarity index 60% rename from Wino.Core/Integration/Threading/GmailThreadingStrategy.cs rename to Wino.Services/Threading/GmailThreadingStrategy.cs index 5cd0ce1c..c171b44b 100644 --- a/Wino.Core/Integration/Threading/GmailThreadingStrategy.cs +++ b/Wino.Services/Threading/GmailThreadingStrategy.cs @@ -1,9 +1,8 @@ using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; -namespace Wino.Core.Integration.Threading +namespace Wino.Services.Threading { - public class GmailThreadingStrategy : APIThreadingStrategy + public class GmailThreadingStrategy : APIThreadingStrategy, IGmailThreadingStrategy { public GmailThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { } } diff --git a/Wino.Core/Integration/Threading/ImapThreadStrategy.cs b/Wino.Services/Threading/ImapThreadingStrategy.cs similarity index 90% rename from Wino.Core/Integration/Threading/ImapThreadStrategy.cs rename to Wino.Services/Threading/ImapThreadingStrategy.cs index bb70e14d..3f377f09 100644 --- a/Wino.Core/Integration/Threading/ImapThreadStrategy.cs +++ b/Wino.Services/Threading/ImapThreadingStrategy.cs @@ -4,22 +4,20 @@ using System.Linq; using System.Threading.Tasks; using SqlKata; using Wino.Core.Domain.Entities.Mail; +using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Folders; using Wino.Core.Domain.Models.MailItem; -using Wino.Core.Extensions; -using Wino.Core.Services; +using Wino.Services.Extensions; -namespace Wino.Core.Integration.Threading +namespace Wino.Services.Threading { - public class ImapThreadStrategy : IThreadingStrategy + public class ImapThreadingStrategy : BaseDatabaseService, IImapThreadingStrategy { - private readonly IDatabaseService _databaseService; private readonly IFolderService _folderService; - public ImapThreadStrategy(IDatabaseService databaseService, IFolderService folderService) + public ImapThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService) { - _databaseService = databaseService; _folderService = folderService; } @@ -37,7 +35,7 @@ namespace Wino.Core.Integration.Threading .WhereNot("MailCopy.Id", replyItem.Id) .Select("MailCopy.*"); - return _databaseService.Connection.FindWithQueryAsync(query.GetRawQuery()); + return Connection.FindWithQueryAsync(query.GetRawQuery()); } private Task GetInReplyToReplyAsync(IMailItem originalItem, Guid accountId, Guid threadingFolderId, Guid sentFolderId, Guid draftFolderId) @@ -56,7 +54,7 @@ namespace Wino.Core.Integration.Threading var raq = query.GetRawQuery(); - return _databaseService.Connection.FindWithQueryAsync(query.GetRawQuery()); + return Connection.FindWithQueryAsync(query.GetRawQuery()); } public async Task> ThreadItemsAsync(List items, IMailItemFolder threadingForFolder) @@ -75,8 +73,8 @@ namespace Wino.Core.Integration.Threading if (!mailLookupTable.ContainsKey(mail.Id)) mailLookupTable.Add(mail.Id, false); - var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Sent); - var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Draft); + var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Sent); + var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Draft); // Threading is not possible. Return items as it is. diff --git a/Wino.Core/Integration/Threading/OutlookThreadingStrategy.cs b/Wino.Services/Threading/OutlookThreadingStrategy.cs similarity index 85% rename from Wino.Core/Integration/Threading/OutlookThreadingStrategy.cs rename to Wino.Services/Threading/OutlookThreadingStrategy.cs index 89c4bd89..2c93f456 100644 --- a/Wino.Core/Integration/Threading/OutlookThreadingStrategy.cs +++ b/Wino.Services/Threading/OutlookThreadingStrategy.cs @@ -1,13 +1,12 @@ using Wino.Core.Domain.Interfaces; -using Wino.Core.Services; -namespace Wino.Core.Integration.Threading +namespace Wino.Services.Threading { // Outlook and Gmail is using the same threading strategy. // Outlook: ConversationId -> it's set as ThreadId // Gmail: ThreadId - public class OutlookThreadingStrategy : APIThreadingStrategy + public class OutlookThreadingStrategy : APIThreadingStrategy, IOutlookThreadingStrategy { public OutlookThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { } } diff --git a/Wino.Services/ThreadingStrategyProvider.cs b/Wino.Services/ThreadingStrategyProvider.cs new file mode 100644 index 00000000..ee4f2070 --- /dev/null +++ b/Wino.Services/ThreadingStrategyProvider.cs @@ -0,0 +1,31 @@ +using Wino.Core.Domain.Enums; +using Wino.Core.Domain.Interfaces; + +namespace Wino.Services +{ + public class ThreadingStrategyProvider : IThreadingStrategyProvider + { + private readonly IOutlookThreadingStrategy _outlookThreadingStrategy; + private readonly IGmailThreadingStrategy _gmailThreadingStrategy; + private readonly IImapThreadingStrategy _imapThreadStrategy; + + public ThreadingStrategyProvider(IOutlookThreadingStrategy outlookThreadingStrategy, + IGmailThreadingStrategy gmailThreadingStrategy, + IImapThreadingStrategy imapThreadStrategy) + { + _outlookThreadingStrategy = outlookThreadingStrategy; + _gmailThreadingStrategy = gmailThreadingStrategy; + _imapThreadStrategy = imapThreadStrategy; + } + + public IThreadingStrategy GetStrategy(MailProviderType mailProviderType) + { + return mailProviderType switch + { + MailProviderType.Outlook or MailProviderType.Office365 => _outlookThreadingStrategy, + MailProviderType.Gmail => _gmailThreadingStrategy, + _ => _imapThreadStrategy, + }; + } + } +} diff --git a/Wino.Core/Services/TranslationService.cs b/Wino.Services/TranslationService.cs similarity index 99% rename from Wino.Core/Services/TranslationService.cs rename to Wino.Services/TranslationService.cs index a4f78df3..dc94dfc2 100644 --- a/Wino.Core/Services/TranslationService.cs +++ b/Wino.Services/TranslationService.cs @@ -10,7 +10,7 @@ using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.Translations; using Wino.Messaging.Client.Shell; -namespace Wino.Core.Services +namespace Wino.Services { public class TranslationService : ITranslationService { diff --git a/Wino.Services/Wino.Services.csproj b/Wino.Services/Wino.Services.csproj new file mode 100644 index 00000000..f9b91d3f --- /dev/null +++ b/Wino.Services/Wino.Services.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0 + 12.0 + + + + + + + + + + + + + + + + + + diff --git a/Wino.sln b/Wino.sln index 19e2eeb3..93f7f32d 100644 --- a/Wino.sln +++ b/Wino.sln @@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Calendar", "Wino.Calen EndProject Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wino.Calendar.Packaging", "Wino.Calendar.Packaging\Wino.Calendar.Packaging.wapproj", "{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Services", "Wino.Services\Wino.Services.csproj", "{4000A374-59FE-4400-ACF6-D40473BECD73}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -392,6 +394,26 @@ Global {7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.ActiveCfg = Release|x86 {7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Build.0 = Release|x86 {7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Deploy.0 = Release|x86 + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM.ActiveCfg = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM.Build.0 = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM64.Build.0 = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x64.ActiveCfg = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x64.Build.0 = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x86.ActiveCfg = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x86.Build.0 = Debug|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|Any CPU.Build.0 = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM.ActiveCfg = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM.Build.0 = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM64.ActiveCfg = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM64.Build.0 = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x64.ActiveCfg = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x64.Build.0 = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x86.ActiveCfg = Release|Any CPU + {4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -407,6 +429,7 @@ Global {53723AE8-7E7E-4D54-ADAB-0A6033255CC8} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758} {039AFFA8-C1CC-4E3B-8A31-6814D7557F74} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758} {A4DBA01A-F315-49E0-8428-BB99D32B20F9} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758} + {4000A374-59FE-4400-ACF6-D40473BECD73} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {721F946E-F69F-4987-823A-D084B436FC1E}