Separation of core library from the UWP app.
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ using System.Threading.Tasks;
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Wino.Core.Domain.Collections;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.MenuItems;
|
||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.Extensions;
|
using Wino.Core.Extensions;
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
using Wino.Core.ViewModels;
|
using Wino.Core.ViewModels;
|
||||||
using Wino.Messaging.Client.Calendar;
|
using Wino.Messaging.Client.Calendar;
|
||||||
using Wino.Messaging.Client.Navigation;
|
using Wino.Messaging.Client.Navigation;
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ using System.Threading.Tasks;
|
|||||||
using CommunityToolkit.Diagnostics;
|
using CommunityToolkit.Diagnostics;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Wino.Core.Domain.Collections;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies;
|
using Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
using Wino.Core.ViewModels;
|
using Wino.Core.ViewModels;
|
||||||
using Wino.Messaging.Client.Calendar;
|
using Wino.Messaging.Client.Calendar;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.WinUI;
|
using CommunityToolkit.WinUI;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Wino.Core.Domain.Collections;
|
||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
|
|
||||||
namespace Wino.Calendar.Controls
|
namespace Wino.Calendar.Controls
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.Collections
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
|
/// 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.
|
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collection">collection: The collection from which the elements are copied.</param>
|
/// <param name="collection">collection: The collection from which the elements are copied.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception>
|
/// <exception cref="ArgumentNullException">The collection parameter cannot be null.</exception>
|
||||||
public ObservableRangeCollection(IEnumerable<T> collection)
|
public ObservableRangeCollection(IEnumerable<T> collection)
|
||||||
: base(collection)
|
: base(collection)
|
||||||
{
|
{
|
||||||
@@ -160,7 +160,7 @@ namespace Wino.Core.MenuItems
|
|||||||
return itemAdded;
|
return itemAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List<T>? changedItems = null, int startingIndex = -1)
|
private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List<T> changedItems = null, int startingIndex = -1)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||||
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
||||||
14
Wino.Core.Domain/Interfaces/IContactService.cs
Normal file
14
Wino.Core.Domain/Interfaces/IContactService.cs
Normal file
@@ -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<List<AccountContact>> GetAddressInformationAsync(string queryText);
|
||||||
|
Task<AccountContact> GetAddressInformationByAddressAsync(string address);
|
||||||
|
Task SaveAddressInformationAsync(MimeMessage message);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs
Normal file
4
Wino.Core.Domain/Interfaces/IGmailThreadingStrategy.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Wino.Core.Domain.Interfaces
|
||||||
|
{
|
||||||
|
public interface IGmailThreadingStrategy : IThreadingStrategy { }
|
||||||
|
}
|
||||||
4
Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs
Normal file
4
Wino.Core.Domain/Interfaces/IImapThreadingStrategy.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Wino.Core.Domain.Interfaces
|
||||||
|
{
|
||||||
|
public interface IImapThreadingStrategy : IThreadingStrategy { }
|
||||||
|
}
|
||||||
70
Wino.Core.Domain/Interfaces/IMimeFileService.cs
Normal file
70
Wino.Core.Domain/Interfaces/IMimeFileService.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the EML file for the given mail id for address, parses and returns MimeMessage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
|
/// <returns>Mime message information</returns>
|
||||||
|
Task<MimeMessageInformation> GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileBytes">Byte array of the file.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
|
/// <returns>Mime message information</returns>
|
||||||
|
Task<MimeMessageInformation> GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves EML file to the disk.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="copy">MailCopy of the native message.</param>
|
||||||
|
/// <param name="mimeMessage">MimeMessage that is parsed from native message.</param>
|
||||||
|
/// <param name="accountId">Which account Id to save this file for.</param>
|
||||||
|
Task<bool> SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a path that all Mime resources (including eml) is stored for this MailCopyId
|
||||||
|
/// This is useful for storing previously rendered attachments as well.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="accountAddress">Account address</param>
|
||||||
|
/// <param name="mailCopyId">Resource mail copy id</param>
|
||||||
|
Task<string> GetMimeResourcePathAsync(Guid accountId, Guid fileId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether mime file exists locally or not.
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> IsMimeExistAsync(Guid accountId, Guid fileId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates HtmlPreviewVisitor for the given MimeMessage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Mime</param>
|
||||||
|
/// <param name="mimeLocalPath">File path that mime is located to load resources.</param>
|
||||||
|
HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes the given mime file from the disk.
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> DeleteMimeMessageAsync(Guid accountId, Guid fileId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepares the final model containing rendering details.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Message to render.</param>
|
||||||
|
/// <param name="mimeLocalPath">File path that physical MimeMessage is located.</param>
|
||||||
|
/// <param name="options">Rendering options</param>
|
||||||
|
MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs
Normal file
4
Wino.Core.Domain/Interfaces/IOutlookThreadingStrategy.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Wino.Core.Domain.Interfaces
|
||||||
|
{
|
||||||
|
public interface IOutlookThreadingStrategy : IThreadingStrategy { }
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ using Wino.Core.Domain.Enums;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IMailItemFolder, FolderMenuItem>>, IAccountMenuItem
|
public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IMailItemFolder, FolderMenuItem>>, IAccountMenuItem
|
||||||
{
|
{
|
||||||
@@ -22,7 +22,7 @@ namespace Wino.Core.MenuItems
|
|||||||
private bool _isEnabled = true;
|
private bool _isEnabled = true;
|
||||||
|
|
||||||
public bool IsAttentionRequired => AttentionReason != AccountAttentionReason.None;
|
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.
|
// We can't determine the progress for gmail synchronization since it is based on history changes.
|
||||||
public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail;
|
public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail;
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class FixAccountIssuesMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>
|
public class FixAccountIssuesMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>
|
||||||
{
|
{
|
||||||
@@ -7,7 +7,7 @@ using Wino.Core.Domain.Enums;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public partial class FolderMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>, IFolderMenuItem
|
public partial class FolderMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>, IFolderMenuItem
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class ManageAccountsMenuItem : MenuItemBase { }
|
public class ManageAccountsMenuItem : MenuItemBase { }
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ using System.Collections.ObjectModel;
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public partial class MenuItemBase : ObservableObject, IMenuItem
|
public partial class MenuItemBase : ObservableObject, IMenuItem
|
||||||
{
|
{
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MoreLinq.Extensions;
|
using Wino.Core.Domain.Collections;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class MenuItemCollection : ObservableRangeCollection<IMenuItem>
|
public class MenuItemCollection : ObservableRangeCollection<IMenuItem>
|
||||||
{
|
{
|
||||||
@@ -108,7 +108,10 @@ namespace Wino.Core.MenuItems
|
|||||||
public void UpdateUnreadItemCountsToZero()
|
public void UpdateUnreadItemCountsToZero()
|
||||||
{
|
{
|
||||||
// Handle the root folders.
|
// Handle the root folders.
|
||||||
this.OfType<IBaseFolderMenuItem>().ForEach(a => RecursivelyResetUnreadItemCount(a));
|
foreach (var item in this.OfType<IBaseFolderMenuItem>())
|
||||||
|
{
|
||||||
|
RecursivelyResetUnreadItemCount(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecursivelyResetUnreadItemCount(IBaseFolderMenuItem baseFolderMenuItem)
|
private void RecursivelyResetUnreadItemCount(IBaseFolderMenuItem baseFolderMenuItem)
|
||||||
@@ -168,7 +171,10 @@ namespace Wino.Core.MenuItems
|
|||||||
|
|
||||||
await _dispatcher.ExecuteOnUIThread(() =>
|
await _dispatcher.ExecuteOnUIThread(() =>
|
||||||
{
|
{
|
||||||
accountItems.ForEach(a => a.IsEnabled = isEnabled);
|
foreach (var item in accountItems)
|
||||||
|
{
|
||||||
|
item.IsEnabled = isEnabled;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ using Wino.Core.Domain.Enums;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Menu item that holds a list of folders under the merged account menu item.
|
/// Menu item that holds a list of folders under the merged account menu item.
|
||||||
@@ -5,7 +5,7 @@ using Wino.Core.Domain.Entities.Mail;
|
|||||||
using Wino.Core.Domain.Entities.Shared;
|
using Wino.Core.Domain.Entities.Shared;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public partial class MergedAccountMenuItem : MenuItemBase<MergedInbox, IMenuItem>, IMergedAccountMenuItem
|
public partial class MergedAccountMenuItem : MenuItemBase<MergedInbox, IMenuItem>, IMergedAccountMenuItem
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class MergedAccountMoreFolderMenuItem : MenuItemBase<object, IMenuItem>
|
public class MergedAccountMoreFolderMenuItem : MenuItemBase<object, IMenuItem>
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class NewMailMenuItem : MenuItemBase { }
|
public class NewMailMenuItem : MenuItemBase { }
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class RateMenuItem : MenuItemBase { }
|
public class RateMenuItem : MenuItemBase { }
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class SeperatorItem : MenuItemBase { }
|
public class SeperatorItem : MenuItemBase { }
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Wino.Core.MenuItems
|
namespace Wino.Core.Domain.MenuItems
|
||||||
{
|
{
|
||||||
public class SettingsItem : MenuItemBase { }
|
public class SettingsItem : MenuItemBase { }
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ using MimeKit;
|
|||||||
using MimeKit.Text;
|
using MimeKit.Text;
|
||||||
using MimeKit.Tnef;
|
using MimeKit.Tnef;
|
||||||
|
|
||||||
namespace Wino.Core.Mime
|
namespace Wino.Core.Domain.Models.MailItem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control.
|
/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control.
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
<LangVersion>12.0</LangVersion>
|
<LangVersion>12.0</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -58,6 +60,8 @@
|
|||||||
<EmbeddedResource Include="Translations\zh_CN\resources.json" />
|
<EmbeddedResource Include="Translations\zh_CN\resources.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.Diagnostics" Version="8.3.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
|
||||||
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Wino.Core.MenuItems;
|
using Wino.Core.Domain.MenuItems;
|
||||||
|
|
||||||
namespace Wino.Core.UWP.Selectors
|
namespace Wino.Core.UWP.Selectors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,14 +3,10 @@ using System.Threading.Tasks;
|
|||||||
using Windows.ApplicationModel;
|
using Windows.ApplicationModel;
|
||||||
using Windows.Foundation.Metadata;
|
using Windows.Foundation.Metadata;
|
||||||
using Windows.Security.Authentication.Web;
|
using Windows.Security.Authentication.Web;
|
||||||
using Windows.Security.Cryptography;
|
|
||||||
using Windows.Security.Cryptography.Core;
|
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.Storage.Streams;
|
|
||||||
using Windows.System;
|
using Windows.System;
|
||||||
using Windows.UI.Shell;
|
using Windows.UI.Shell;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Authorization;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -51,46 +47,6 @@ namespace Wino.Services
|
|||||||
return _mimeMessagesFolder;
|
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<string> GetEditorBundlePathAsync()
|
public async Task<string> GetEditorBundlePathAsync()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using Wino.Core.Domain.Interfaces;
|
|||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
using Wino.Core.Domain.Models.Reader;
|
||||||
using Wino.Core.Domain.Translations;
|
using Wino.Core.Domain.Translations;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.UWP.Services
|
namespace Wino.Core.UWP.Services
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Core.UWP.Services
|
||||||
{
|
{
|
||||||
public static class ThumbnailService
|
public static class ThumbnailService
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ namespace Wino.Core.Services
|
|||||||
return new Tuple<bool, string>(false, host);
|
return new Tuple<bool, string>(false, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Tuple<bool, string>(ThumbnailService.IsKnown(host), host);
|
return new Tuple<bool, string>(IsKnown(host), host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetKnownHostImage(string host)
|
public static string GetKnownHostImage(string host)
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:domain="using:Wino.Core.Domain"
|
xmlns:domain="using:Wino.Core.Domain"
|
||||||
xmlns:helpers="using:Wino.Helpers"
|
xmlns:helpers="using:Wino.Helpers"
|
||||||
xmlns:local="using:Wino.Core.UWP.Styles"
|
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:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
|
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
|
||||||
xmlns:winuiControls="using:CommunityToolkit.WinUI.Controls">
|
xmlns:winuiControls="using:CommunityToolkit.WinUI.Controls">
|
||||||
|
|||||||
@@ -144,6 +144,7 @@
|
|||||||
<Compile Include="Services\PrintService.cs" />
|
<Compile Include="Services\PrintService.cs" />
|
||||||
<Compile Include="Services\StartupBehaviorService.cs" />
|
<Compile Include="Services\StartupBehaviorService.cs" />
|
||||||
<Compile Include="Services\StatePersistenceService.cs" />
|
<Compile Include="Services\StatePersistenceService.cs" />
|
||||||
|
<Compile Include="Services\ThumbnailService.cs" />
|
||||||
<Compile Include="Services\WinoServerConnectionManager.cs" />
|
<Compile Include="Services\WinoServerConnectionManager.cs" />
|
||||||
<Compile Include="Services\BackgroundTaskService.cs" />
|
<Compile Include="Services\BackgroundTaskService.cs" />
|
||||||
<Compile Include="Services\ClipboardService.cs" />
|
<Compile Include="Services\ClipboardService.cs" />
|
||||||
@@ -242,6 +243,10 @@
|
|||||||
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
||||||
<Name>Wino.Messaging</Name>
|
<Name>Wino.Messaging</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj">
|
||||||
|
<Project>{4000a374-59fe-4400-acf6-d40473becd73}</Project>
|
||||||
|
<Name>Wino.Services</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using Wino.Activation;
|
using Wino.Activation;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.UWP
|
namespace Wino.Core.UWP
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Serilog.Core;
|
|||||||
using Wino.Authentication;
|
using Wino.Authentication;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Integration.Processors;
|
using Wino.Core.Integration.Processors;
|
||||||
using Wino.Core.Integration.Threading;
|
|
||||||
using Wino.Core.Services;
|
using Wino.Core.Services;
|
||||||
|
|
||||||
namespace Wino.Core
|
namespace Wino.Core
|
||||||
@@ -15,41 +14,20 @@ namespace Wino.Core
|
|||||||
var loggerLevelSwitcher = new LoggingLevelSwitch();
|
var loggerLevelSwitcher = new LoggingLevelSwitch();
|
||||||
|
|
||||||
services.AddSingleton(loggerLevelSwitcher);
|
services.AddSingleton(loggerLevelSwitcher);
|
||||||
services.AddSingleton<ILogInitializer, LogInitializer>();
|
services.AddSingleton<ISynchronizerFactory, SynchronizerFactory>();
|
||||||
|
|
||||||
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
|
||||||
services.AddSingleton<ITranslationService, TranslationService>();
|
|
||||||
services.AddSingleton<IDatabaseService, DatabaseService>();
|
|
||||||
services.AddSingleton<IThreadingStrategyProvider, ThreadingStrategyProvider>();
|
|
||||||
services.AddSingleton<IMimeFileService, MimeFileService>();
|
|
||||||
services.AddSingleton<ILaunchProtocolService, LaunchProtocolService>();
|
|
||||||
|
|
||||||
services.AddTransient<IGmailChangeProcessor, GmailChangeProcessor>();
|
services.AddTransient<IGmailChangeProcessor, GmailChangeProcessor>();
|
||||||
services.AddTransient<IImapChangeProcessor, ImapChangeProcessor>();
|
services.AddTransient<IImapChangeProcessor, ImapChangeProcessor>();
|
||||||
services.AddTransient<IOutlookChangeProcessor, OutlookChangeProcessor>();
|
services.AddTransient<IOutlookChangeProcessor, OutlookChangeProcessor>();
|
||||||
|
|
||||||
services.AddTransient<IFolderService, FolderService>();
|
|
||||||
services.AddTransient<IMailService, MailService>();
|
|
||||||
services.AddTransient<IAccountService, AccountService>();
|
|
||||||
services.AddTransient<IContactService, ContactService>();
|
|
||||||
services.AddTransient<ISignatureService, SignatureService>();
|
|
||||||
services.AddTransient<IWinoRequestProcessor, WinoRequestProcessor>();
|
services.AddTransient<IWinoRequestProcessor, WinoRequestProcessor>();
|
||||||
services.AddTransient<IWinoRequestDelegator, WinoRequestDelegator>();
|
services.AddTransient<IWinoRequestDelegator, WinoRequestDelegator>();
|
||||||
services.AddTransient<IImapTestService, ImapTestService>();
|
services.AddTransient<IImapTestService, ImapTestService>();
|
||||||
services.AddTransient<IAuthenticationProvider, AuthenticationProvider>();
|
services.AddTransient<IAuthenticationProvider, AuthenticationProvider>();
|
||||||
services.AddTransient<IAutoDiscoveryService, AutoDiscoveryService>();
|
services.AddTransient<IAutoDiscoveryService, AutoDiscoveryService>();
|
||||||
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
|
||||||
services.AddTransient<IFontService, FontService>();
|
services.AddTransient<IFontService, FontService>();
|
||||||
services.AddTransient<IUnsubscriptionService, UnsubscriptionService>();
|
services.AddTransient<IUnsubscriptionService, UnsubscriptionService>();
|
||||||
|
|
||||||
services.AddTransient<IOutlookAuthenticator, OutlookAuthenticator>();
|
services.AddTransient<IOutlookAuthenticator, OutlookAuthenticator>();
|
||||||
services.AddTransient<IGmailAuthenticator, GmailAuthenticator>();
|
services.AddTransient<IGmailAuthenticator, GmailAuthenticator>();
|
||||||
|
|
||||||
services.AddTransient<OutlookThreadingStrategy>();
|
|
||||||
services.AddTransient<GmailThreadingStrategy>();
|
|
||||||
services.AddTransient<ImapThreadStrategy>();
|
|
||||||
|
|
||||||
services.AddSingleton<ISynchronizerFactory, SynchronizerFactory>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,67 +6,21 @@ using Google.Apis.Gmail.v1.Data;
|
|||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Wino.Core.Domain.Entities.Mail;
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Services;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Extensions
|
namespace Wino.Core.Extensions
|
||||||
{
|
{
|
||||||
public static class GoogleIntegratorExtensions
|
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<string, SpecialFolderType> KnownFolderDictionary = new Dictionary<string, SpecialFolderType>()
|
|
||||||
{
|
|
||||||
{ 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)
|
private static string GetNormalizedLabelName(string labelName)
|
||||||
{
|
{
|
||||||
// 1. Remove CATEGORY_ prefix.
|
// 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.
|
// 2. Normalize label name by capitalizing first letter.
|
||||||
normalizedLabelName = char.ToUpper(normalizedLabelName[0]) + normalizedLabelName.Substring(1).ToLower();
|
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.
|
// Even though we normalize the label name, check is done by capitalizing the label name.
|
||||||
var capitalNormalizedLabelName = normalizedLabelName.ToUpper();
|
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.
|
// 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
|
// 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 isHidden = false;
|
||||||
|
|
||||||
bool isChildOfCategoryFolder = label.Name.StartsWith(CATEGORY_PREFIX);
|
bool isChildOfCategoryFolder = label.Name.StartsWith(ServiceConstants.CATEGORY_PREFIX);
|
||||||
bool isSticky = isSpecialFolder && specialFolderType != SpecialFolderType.Category && !isChildOfCategoryFolder;
|
bool isSticky = isSpecialFolder && specialFolderType != SpecialFolderType.Category && !isChildOfCategoryFolder;
|
||||||
|
|
||||||
// By default, all special folders update unread count in the UI except Trash.
|
// By default, all special folders update unread count in the UI except Trash.
|
||||||
bool shouldShowUnreadCount = specialFolderType != SpecialFolderType.Deleted || specialFolderType != SpecialFolderType.Other;
|
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()
|
var localFolder = new MailItemFolder()
|
||||||
{
|
{
|
||||||
@@ -126,16 +80,16 @@ namespace Wino.Core.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static bool GetIsDraft(this Message message)
|
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)
|
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)
|
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)
|
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)
|
private static string GetParentFolderRemoteId(string fullLabelName, ListLabelsResponse labelsResponse)
|
||||||
{
|
{
|
||||||
@@ -158,9 +112,9 @@ namespace Wino.Core.Extensions
|
|||||||
if (string.IsNullOrEmpty(fullFolderName)) return string.Empty;
|
if (string.IsNullOrEmpty(fullFolderName)) return string.Empty;
|
||||||
|
|
||||||
// Folders with "//" at the end has "/" as the name.
|
// 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];
|
var lastPart = parts[parts.Length - 1];
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using MimeKit;
|
|||||||
using MimeKit.IO;
|
using MimeKit.IO;
|
||||||
using MimeKit.IO.Filters;
|
using MimeKit.IO.Filters;
|
||||||
using MimeKit.Utils;
|
using MimeKit.Utils;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Extensions
|
namespace Wino.Core.Extensions
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using Wino.Core.Domain.Entities.Shared;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Synchronization;
|
using Wino.Core.Domain.Models.Synchronization;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.Integration.Processors
|
namespace Wino.Core.Integration.Processors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.Integration.Processors
|
namespace Wino.Core.Integration.Processors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.Integration.Processors
|
namespace Wino.Core.Integration.Processors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.Integration.Processors
|
namespace Wino.Core.Integration.Processors
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Integration.Threading;
|
using Wino.Services.Threading;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Core.Services
|
||||||
{
|
{
|
||||||
@@ -8,11 +8,11 @@ namespace Wino.Core.Services
|
|||||||
{
|
{
|
||||||
private readonly OutlookThreadingStrategy _outlookThreadingStrategy;
|
private readonly OutlookThreadingStrategy _outlookThreadingStrategy;
|
||||||
private readonly GmailThreadingStrategy _gmailThreadingStrategy;
|
private readonly GmailThreadingStrategy _gmailThreadingStrategy;
|
||||||
private readonly ImapThreadStrategy _imapThreadStrategy;
|
private readonly ImapThreadingStrategy _imapThreadStrategy;
|
||||||
|
|
||||||
public ThreadingStrategyProvider(OutlookThreadingStrategy outlookThreadingStrategy,
|
public ThreadingStrategyProvider(OutlookThreadingStrategy outlookThreadingStrategy,
|
||||||
GmailThreadingStrategy gmailThreadingStrategy,
|
GmailThreadingStrategy gmailThreadingStrategy,
|
||||||
ImapThreadStrategy imapThreadStrategy)
|
ImapThreadingStrategy imapThreadStrategy)
|
||||||
{
|
{
|
||||||
_outlookThreadingStrategy = outlookThreadingStrategy;
|
_outlookThreadingStrategy = outlookThreadingStrategy;
|
||||||
_gmailThreadingStrategy = gmailThreadingStrategy;
|
_gmailThreadingStrategy = gmailThreadingStrategy;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ namespace Wino.Core.Services
|
|||||||
private readonly IWinoServerConnectionManager _winoServerConnectionManager;
|
private readonly IWinoServerConnectionManager _winoServerConnectionManager;
|
||||||
private readonly IFolderService _folderService;
|
private readonly IFolderService _folderService;
|
||||||
private readonly IMailDialogService _dialogService;
|
private readonly IMailDialogService _dialogService;
|
||||||
private readonly ILogger _logger = Log.ForContext<WinoRequestDelegator>();
|
|
||||||
|
|
||||||
public WinoRequestDelegator(IWinoRequestProcessor winoRequestProcessor,
|
public WinoRequestDelegator(IWinoRequestProcessor winoRequestProcessor,
|
||||||
IWinoServerConnectionManager winoServerConnectionManager,
|
IWinoServerConnectionManager winoServerConnectionManager,
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ namespace Wino.Core.Services
|
|||||||
private readonly IFolderService _folderService;
|
private readonly IFolderService _folderService;
|
||||||
private readonly IKeyPressService _keyPressService;
|
private readonly IKeyPressService _keyPressService;
|
||||||
private readonly IPreferencesService _preferencesService;
|
private readonly IPreferencesService _preferencesService;
|
||||||
private readonly IAccountService _accountService;
|
|
||||||
private readonly IMailDialogService _dialogService;
|
private readonly IMailDialogService _dialogService;
|
||||||
private readonly IMailService _mailService;
|
private readonly IMailService _mailService;
|
||||||
|
|
||||||
@@ -41,14 +40,12 @@ namespace Wino.Core.Services
|
|||||||
public WinoRequestProcessor(IFolderService folderService,
|
public WinoRequestProcessor(IFolderService folderService,
|
||||||
IKeyPressService keyPressService,
|
IKeyPressService keyPressService,
|
||||||
IPreferencesService preferencesService,
|
IPreferencesService preferencesService,
|
||||||
IAccountService accountService,
|
|
||||||
IMailDialogService dialogService,
|
IMailDialogService dialogService,
|
||||||
IMailService mailService)
|
IMailService mailService)
|
||||||
{
|
{
|
||||||
_folderService = folderService;
|
_folderService = folderService;
|
||||||
_keyPressService = keyPressService;
|
_keyPressService = keyPressService;
|
||||||
_preferencesService = preferencesService;
|
_preferencesService = preferencesService;
|
||||||
_accountService = accountService;
|
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
_mailService = mailService;
|
_mailService = mailService;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ using Wino.Core.Requests.Bundles;
|
|||||||
using Wino.Core.Requests.Folder;
|
using Wino.Core.Requests.Folder;
|
||||||
using Wino.Core.Requests.Mail;
|
using Wino.Core.Requests.Mail;
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.Synchronizers.Mail
|
namespace Wino.Core.Synchronizers.Mail
|
||||||
{
|
{
|
||||||
@@ -532,11 +533,11 @@ namespace Wino.Core.Synchronizers.Mail
|
|||||||
foreach (var labelId in addedLabel.LabelIds)
|
foreach (var labelId in addedLabel.LabelIds)
|
||||||
{
|
{
|
||||||
// When UNREAD label is added mark the message as un-read.
|
// 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);
|
await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, false).ConfigureAwait(false);
|
||||||
|
|
||||||
// When STARRED label is added mark the message as flagged.
|
// 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.ChangeFlagStatusAsync(messageId, true).ConfigureAwait(false);
|
||||||
|
|
||||||
await _gmailChangeProcessor.CreateAssignmentAsync(Account.Id, messageId, labelId).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)
|
foreach (var labelId in removedLabel.LabelIds)
|
||||||
{
|
{
|
||||||
// When UNREAD label is removed mark the message as read.
|
// 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);
|
await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, true).ConfigureAwait(false);
|
||||||
|
|
||||||
// When STARRED label is removed mark the message as un-flagged.
|
// 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);
|
await _gmailChangeProcessor.ChangeFlagStatusAsync(messageId, false).ConfigureAwait(false);
|
||||||
|
|
||||||
// For other labels remove the mail assignment.
|
// For other labels remove the mail assignment.
|
||||||
@@ -637,9 +638,9 @@ namespace Wino.Core.Synchronizers.Mail
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (isFlagged)
|
if (isFlagged)
|
||||||
batchModifyRequest.AddLabelIds = new List<string>() { GoogleIntegratorExtensions.STARRED_LABEL_ID };
|
batchModifyRequest.AddLabelIds = new List<string>() { ServiceConstants.STARRED_LABEL_ID };
|
||||||
else
|
else
|
||||||
batchModifyRequest.RemoveLabelIds = new List<string>() { GoogleIntegratorExtensions.STARRED_LABEL_ID };
|
batchModifyRequest.RemoveLabelIds = new List<string>() { ServiceConstants.STARRED_LABEL_ID };
|
||||||
|
|
||||||
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||||
|
|
||||||
@@ -656,9 +657,9 @@ namespace Wino.Core.Synchronizers.Mail
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (readStatus)
|
if (readStatus)
|
||||||
batchModifyRequest.RemoveLabelIds = new List<string>() { GoogleIntegratorExtensions.UNREAD_LABEL_ID };
|
batchModifyRequest.RemoveLabelIds = new List<string>() { ServiceConstants.UNREAD_LABEL_ID };
|
||||||
else
|
else
|
||||||
batchModifyRequest.AddLabelIds = new List<string>() { GoogleIntegratorExtensions.UNREAD_LABEL_ID };
|
batchModifyRequest.AddLabelIds = new List<string>() { ServiceConstants.UNREAD_LABEL_ID };
|
||||||
|
|
||||||
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||||
|
|
||||||
@@ -704,11 +705,11 @@ namespace Wino.Core.Synchronizers.Mail
|
|||||||
|
|
||||||
if (isArchiving)
|
if (isArchiving)
|
||||||
{
|
{
|
||||||
batchModifyRequest.RemoveLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID };
|
batchModifyRequest.RemoveLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
batchModifyRequest.AddLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID };
|
batchModifyRequest.AddLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID };
|
||||||
}
|
}
|
||||||
|
|
||||||
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ using Wino.Core.Requests.Bundles;
|
|||||||
using Wino.Core.Requests.Folder;
|
using Wino.Core.Requests.Folder;
|
||||||
using Wino.Core.Requests.Mail;
|
using Wino.Core.Requests.Mail;
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Synchronizers.Mail
|
namespace Wino.Core.Synchronizers.Mail
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -47,5 +49,6 @@
|
|||||||
<ProjectReference Include="..\Wino.Authentication\Wino.Authentication.csproj" />
|
<ProjectReference Include="..\Wino.Authentication\Wino.Authentication.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||||
|
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -16,12 +16,11 @@ using Wino.Core.Domain.Entities.Mail;
|
|||||||
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.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.MenuItems;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Navigation;
|
using Wino.Core.Domain.Models.Navigation;
|
||||||
using Wino.Core.Domain.Models.Synchronization;
|
using Wino.Core.Domain.Models.Synchronization;
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
using Wino.Core.Services;
|
|
||||||
using Wino.Messaging.Client.Accounts;
|
using Wino.Messaging.Client.Accounts;
|
||||||
using Wino.Messaging.Client.Navigation;
|
using Wino.Messaging.Client.Navigation;
|
||||||
using Wino.Messaging.Client.Shell;
|
using Wino.Messaging.Client.Shell;
|
||||||
@@ -55,7 +54,7 @@ namespace Wino.Mail.ViewModels
|
|||||||
private readonly SettingsItem SettingsItem = new SettingsItem();
|
private readonly SettingsItem SettingsItem = new SettingsItem();
|
||||||
private readonly ManageAccountsMenuItem ManageAccountsMenuItem = new ManageAccountsMenuItem();
|
private readonly ManageAccountsMenuItem ManageAccountsMenuItem = new ManageAccountsMenuItem();
|
||||||
|
|
||||||
public NewMailMenuItem CreateMailMenuItem = new NewMailMenuItem();
|
public IMenuItem CreateMailMenuItem = new NewMailMenuItem();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
14
Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs
Normal file
14
Wino.Mail.ViewModels/MailViewModelsContainerSetup.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using Wino.Mail.ViewModels.Data;
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
using Wino.Mail.ViewModels.Data;
|
|
||||||
|
|
||||||
namespace Wino.Mail.ViewModels.Messages
|
namespace Wino.Mail.ViewModels.Messages
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -21,6 +24,7 @@
|
|||||||
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj" />
|
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||||
|
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using Windows.UI.Xaml.Media.Animation;
|
using Windows.UI.Xaml.Media.Animation;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
|
||||||
using Wino.Views;
|
using Wino.Views;
|
||||||
|
|
||||||
namespace Wino.Activation
|
namespace Wino.Activation
|
||||||
|
|||||||
@@ -17,17 +17,14 @@ namespace Wino.Activation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ToastNotificationActivationHandler : ActivationHandler<ToastNotificationActivatedEventArgs>
|
internal class ToastNotificationActivationHandler : ActivationHandler<ToastNotificationActivatedEventArgs>
|
||||||
{
|
{
|
||||||
private readonly INativeAppService _nativeAppService;
|
|
||||||
private readonly IMailService _mailService;
|
private readonly IMailService _mailService;
|
||||||
private readonly IFolderService _folderService;
|
private readonly IFolderService _folderService;
|
||||||
|
|
||||||
private ToastArguments _toastArguments;
|
private ToastArguments _toastArguments;
|
||||||
|
|
||||||
public ToastNotificationActivationHandler(INativeAppService nativeAppService,
|
public ToastNotificationActivationHandler(IMailService mailService,
|
||||||
IMailService mailService,
|
|
||||||
IFolderService folderService)
|
IFolderService folderService)
|
||||||
{
|
{
|
||||||
_nativeAppService = nativeAppService;
|
|
||||||
_mailService = mailService;
|
_mailService = mailService;
|
||||||
_folderService = folderService;
|
_folderService = folderService;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ using Windows.ApplicationModel.Background;
|
|||||||
using Windows.UI.Core.Preview;
|
using Windows.UI.Core.Preview;
|
||||||
using Windows.UI.Notifications;
|
using Windows.UI.Notifications;
|
||||||
using Wino.Activation;
|
using Wino.Activation;
|
||||||
using Wino.Core;
|
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Exceptions;
|
using Wino.Core.Domain.Exceptions;
|
||||||
@@ -70,7 +69,8 @@ namespace Wino
|
|||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
|
||||||
services.RegisterCoreServices();
|
services.RegisterViewModelService();
|
||||||
|
services.RegisterSharedServices();
|
||||||
services.RegisterCoreUWPServices();
|
services.RegisterCoreUWPServices();
|
||||||
services.RegisterCoreViewModels();
|
services.RegisterCoreViewModels();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
xmlns:enums="using:Wino.Core.Domain.Enums"
|
xmlns:enums="using:Wino.Core.Domain.Enums"
|
||||||
xmlns:helpers="using:Wino.Helpers"
|
xmlns:helpers="using:Wino.Helpers"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
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"
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
x:Name="Root"
|
x:Name="Root"
|
||||||
muxc:BackdropMaterial.ApplyToRootOrPageBackground="{ThemeResource UseMica}"
|
muxc:BackdropMaterial.ApplyToRootOrPageBackground="{ThemeResource UseMica}"
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using Microsoft.Xaml.Interactivity;
|
using Microsoft.Xaml.Interactivity;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Wino.Core.MenuItems;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.UWP.Controls;
|
using Wino.Core.UWP.Controls;
|
||||||
|
|
||||||
namespace Wino.Behaviors
|
namespace Wino.Behaviors
|
||||||
{
|
{
|
||||||
public class CreateMailNavigationItemBehavior : Behavior<WinoNavigationViewItem>
|
public class CreateMailNavigationItemBehavior : Behavior<WinoNavigationViewItem>
|
||||||
{
|
{
|
||||||
public MenuItemBase SelectedMenuItem
|
public IMenuItem SelectedMenuItem
|
||||||
{
|
{
|
||||||
get { return (MenuItemBase)GetValue(SelectedMenuItemProperty); }
|
get { return (IMenuItem)GetValue(SelectedMenuItemProperty); }
|
||||||
set { SetValue(SelectedMenuItemProperty, value); }
|
set { SetValue(SelectedMenuItemProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<MenuItemBase> MenuItems
|
public ObservableCollection<IMenuItem> MenuItems
|
||||||
{
|
{
|
||||||
get { return (ObservableCollection<MenuItemBase>)GetValue(MenuItemsProperty); }
|
get { return (ObservableCollection<IMenuItem>)GetValue(MenuItemsProperty); }
|
||||||
set { SetValue(MenuItemsProperty, value); }
|
set { SetValue(MenuItemsProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection<MenuItemBase>), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnMenuItemsChanged));
|
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection<IMenuItem>), 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 SelectedMenuItemProperty = DependencyProperty.Register(nameof(SelectedMenuItem), typeof(IMenuItem), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnSelectedMenuItemChanged));
|
||||||
|
|
||||||
public CreateMailNavigationItemBehavior()
|
public CreateMailNavigationItemBehavior()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
using Windows.UI.Xaml.Shapes;
|
using Windows.UI.Xaml.Shapes;
|
||||||
using Wino.Core.Services;
|
using Wino.Core.UWP.Services;
|
||||||
|
|
||||||
namespace Wino.Controls
|
namespace Wino.Controls
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -604,10 +604,6 @@
|
|||||||
<Project>{53723ae8-7e7e-4d54-adab-0a6033255cc8}</Project>
|
<Project>{53723ae8-7e7e-4d54-adab-0a6033255cc8}</Project>
|
||||||
<Name>Wino.Core.ViewModels</Name>
|
<Name>Wino.Core.ViewModels</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj">
|
|
||||||
<Project>{E6B1632A-8901-41E8-9DDF-6793C7698B0B}</Project>
|
|
||||||
<Name>Wino.Core</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\Wino.Mail.ViewModels\Wino.Mail.ViewModels.csproj">
|
<ProjectReference Include="..\Wino.Mail.ViewModels\Wino.Mail.ViewModels.csproj">
|
||||||
<Project>{d62f1c03-da57-4709-a640-0283296a8e66}</Project>
|
<Project>{d62f1c03-da57-4709-a640-0283296a8e66}</Project>
|
||||||
<Name>Wino.Mail.ViewModels</Name>
|
<Name>Wino.Mail.ViewModels</Name>
|
||||||
@@ -616,6 +612,10 @@
|
|||||||
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
||||||
<Name>Wino.Messaging</Name>
|
<Name>Wino.Messaging</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj">
|
||||||
|
<Project>{4000a374-59fe-4400-acf6-d40473becd73}</Project>
|
||||||
|
<Name>Wino.Services</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>12</LangVersion>
|
<LangVersion>12</LangVersion>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
|
||||||
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||||
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ using Wino.Core;
|
|||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Services;
|
|
||||||
using Wino.Core.UWP.Services;
|
using Wino.Core.UWP.Services;
|
||||||
using Wino.Server.Core;
|
using Wino.Server.Core;
|
||||||
using Wino.Server.MessageHandlers;
|
using Wino.Server.MessageHandlers;
|
||||||
@@ -68,6 +67,7 @@ namespace Wino.Server
|
|||||||
services.AddTransient<ServerViewModel>();
|
services.AddTransient<ServerViewModel>();
|
||||||
|
|
||||||
services.RegisterCoreServices();
|
services.RegisterCoreServices();
|
||||||
|
services.RegisterSharedServices();
|
||||||
|
|
||||||
// Below services belongs to UWP.Core package and some APIs are not available for WPF.
|
// Below services belongs to UWP.Core package and some APIs are not available for WPF.
|
||||||
// We register them here to avoid compilation errors.
|
// We register them here to avoid compilation errors.
|
||||||
@@ -77,6 +77,7 @@ namespace Wino.Server
|
|||||||
services.AddSingleton<IPreferencesService, PreferencesService>();
|
services.AddSingleton<IPreferencesService, PreferencesService>();
|
||||||
services.AddTransient<INotificationBuilder, NotificationBuilder>();
|
services.AddTransient<INotificationBuilder, NotificationBuilder>();
|
||||||
services.AddTransient<IUnderlyingThemeService, UnderlyingThemeService>();
|
services.AddTransient<IUnderlyingThemeService, UnderlyingThemeService>();
|
||||||
|
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
||||||
|
|
||||||
// Register server message handler factory.
|
// Register server message handler factory.
|
||||||
var serverMessageHandlerFactory = new ServerMessageHandlerFactory();
|
var serverMessageHandlerFactory = new ServerMessageHandlerFactory();
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ using Wino.Core.Domain.Interfaces;
|
|||||||
using Wino.Core.Domain.Models.Requests;
|
using Wino.Core.Domain.Models.Requests;
|
||||||
using Wino.Core.Domain.Models.Synchronization;
|
using Wino.Core.Domain.Models.Synchronization;
|
||||||
using Wino.Core.Integration.Json;
|
using Wino.Core.Integration.Json;
|
||||||
using Wino.Core.Services;
|
|
||||||
using Wino.Messaging;
|
using Wino.Messaging;
|
||||||
using Wino.Messaging.Client.Authorization;
|
using Wino.Messaging.Client.Authorization;
|
||||||
using Wino.Messaging.Enums;
|
using Wino.Messaging.Enums;
|
||||||
using Wino.Messaging.Server;
|
using Wino.Messaging.Server;
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
using Wino.Server.MessageHandlers;
|
using Wino.Server.MessageHandlers;
|
||||||
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Server
|
namespace Wino.Server
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
<Compile Include="..\Wino.Core.UWP\Services\PreferencesService.cs" Link="Services\PreferencesService.cs" />
|
<Compile Include="..\Wino.Core.UWP\Services\PreferencesService.cs" Link="Services\PreferencesService.cs" />
|
||||||
<Compile Include="..\Wino.Core.UWP\Services\NotificationBuilder.cs" Link="Services\NotificationBuilder.cs" />
|
<Compile Include="..\Wino.Core.UWP\Services\NotificationBuilder.cs" Link="Services\NotificationBuilder.cs" />
|
||||||
<Compile Include="..\Wino.Core.UWP\Services\UnderlyingThemeService.cs" Link="Services\UnderlyingThemeService.cs" />
|
<Compile Include="..\Wino.Core.UWP\Services\UnderlyingThemeService.cs" Link="Services\UnderlyingThemeService.cs" />
|
||||||
|
<Compile Include="..\Wino.Core.UWP\Services\ThumbnailService.cs" Link="Services\ThumbnailService.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Images\Wino_Icon.ico">
|
<Resource Include="Images\Wino_Icon.ico">
|
||||||
@@ -42,5 +43,6 @@
|
|||||||
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
||||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||||
|
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -11,28 +11,25 @@ using Wino.Core.Domain.Entities.Shared;
|
|||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Accounts;
|
using Wino.Core.Domain.Models.Accounts;
|
||||||
using Wino.Core.Extensions;
|
|
||||||
using Wino.Messaging.Client.Accounts;
|
using Wino.Messaging.Client.Accounts;
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class AccountService : BaseDatabaseService, IAccountService
|
public class AccountService : BaseDatabaseService, IAccountService
|
||||||
{
|
{
|
||||||
public IAuthenticator ExternalAuthenticationAuthenticator { get; set; }
|
public IAuthenticator ExternalAuthenticationAuthenticator { get; set; }
|
||||||
|
|
||||||
private readonly IAuthenticationProvider _authenticationProvider;
|
|
||||||
private readonly ISignatureService _signatureService;
|
private readonly ISignatureService _signatureService;
|
||||||
private readonly IPreferencesService _preferencesService;
|
private readonly IPreferencesService _preferencesService;
|
||||||
|
|
||||||
private readonly ILogger _logger = Log.ForContext<AccountService>();
|
private readonly ILogger _logger = Log.ForContext<AccountService>();
|
||||||
|
|
||||||
public AccountService(IDatabaseService databaseService,
|
public AccountService(IDatabaseService databaseService,
|
||||||
IAuthenticationProvider authenticationProvider,
|
|
||||||
ISignatureService signatureService,
|
ISignatureService signatureService,
|
||||||
IPreferencesService preferencesService) : base(databaseService)
|
IPreferencesService preferencesService) : base(databaseService)
|
||||||
{
|
{
|
||||||
_authenticationProvider = authenticationProvider;
|
|
||||||
_signatureService = signatureService;
|
_signatureService = signatureService;
|
||||||
_preferencesService = preferencesService;
|
_preferencesService = preferencesService;
|
||||||
}
|
}
|
||||||
@@ -203,13 +200,13 @@ namespace Wino.Core.Services
|
|||||||
|
|
||||||
if (account == null) return;
|
if (account == null) return;
|
||||||
|
|
||||||
var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType);
|
//var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType);
|
||||||
|
|
||||||
// This will re-generate token.
|
//// This will re-generate token.
|
||||||
var token = await authenticator.GenerateTokenInformationAsync(account);
|
//var token = await authenticator.GenerateTokenInformationAsync(account);
|
||||||
|
|
||||||
// TODO: Rest?
|
// TODO: Rest?
|
||||||
Guard.IsNotNull(token);
|
// Guard.IsNotNull(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<MailAccountPreferences> GetAccountPreferencesAsync(Guid accountId)
|
private Task<MailAccountPreferences> GetAccountPreferencesAsync(Guid accountId)
|
||||||
@@ -538,10 +535,10 @@ namespace Wino.Core.Services
|
|||||||
var currentIdentifier = account.SynchronizationDeltaIdentifier;
|
var currentIdentifier = account.SynchronizationDeltaIdentifier;
|
||||||
|
|
||||||
bool shouldUpdateIdentifier = account.ProviderType == MailProviderType.Gmail ?
|
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(currentIdentifier, out ulong currentIdentifierValue)
|
||||||
&& ulong.TryParse(newIdentifier, out ulong newIdentifierValue)
|
&& ulong.TryParse(newIdentifier, out ulong newIdentifierValue)
|
||||||
&& newIdentifierValue > currentIdentifierValue)) : true;
|
&& newIdentifierValue > currentIdentifierValue : true;
|
||||||
|
|
||||||
if (shouldUpdateIdentifier)
|
if (shouldUpdateIdentifier)
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class ApplicationConfiguration : IApplicationConfiguration
|
public class ApplicationConfiguration : IApplicationConfiguration
|
||||||
{
|
{
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using SQLite;
|
using SQLite;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class BaseDatabaseService
|
public class BaseDatabaseService
|
||||||
{
|
{
|
||||||
@@ -4,17 +4,11 @@ using System.Threading.Tasks;
|
|||||||
using MimeKit;
|
using MimeKit;
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
using Wino.Core.Domain.Entities.Shared;
|
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<List<AccountContact>> GetAddressInformationAsync(string queryText);
|
|
||||||
Task<AccountContact> GetAddressInformationByAddressAsync(string address);
|
|
||||||
Task SaveAddressInformationAsync(MimeMessage message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ContactService : BaseDatabaseService, IContactService
|
public class ContactService : BaseDatabaseService, IContactService
|
||||||
{
|
{
|
||||||
public ContactService(IDatabaseService databaseService) : base(databaseService) { }
|
public ContactService(IDatabaseService databaseService) : base(databaseService) { }
|
||||||
@@ -6,7 +6,7 @@ using Wino.Core.Domain.Models.Folders;
|
|||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Menus;
|
using Wino.Core.Domain.Models.Menus;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class ContextMenuItemService : IContextMenuItemService
|
public class ContextMenuItemService : IContextMenuItemService
|
||||||
{
|
{
|
||||||
@@ -93,7 +93,7 @@ namespace Wino.Core.Services
|
|||||||
};
|
};
|
||||||
operationList.AddRange(readOperations);
|
operationList.AddRange(readOperations);
|
||||||
|
|
||||||
List<MailOperationMenuItem> flagsOperations = (isAllFlagged, isAllNotFlagged) switch
|
List<MailOperationMenuItem> flagsOperations = (isAllFlagged, isAllNotFlagged) switch
|
||||||
{
|
{
|
||||||
(true, false) => [MailOperationMenuItem.Create(MailOperation.ClearFlag)],
|
(true, false) => [MailOperationMenuItem.Create(MailOperation.ClearFlag)],
|
||||||
(false, true) => [MailOperationMenuItem.Create(MailOperation.SetFlag)],
|
(false, true) => [MailOperationMenuItem.Create(MailOperation.SetFlag)],
|
||||||
@@ -5,7 +5,7 @@ using Wino.Core.Domain.Entities.Mail;
|
|||||||
using Wino.Core.Domain.Entities.Shared;
|
using Wino.Core.Domain.Entities.Shared;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public interface IDatabaseService : IInitializeAsync
|
public interface IDatabaseService : IInitializeAsync
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
|
|
||||||
namespace Wino.Core.Extensions
|
namespace Wino.Services.Extensions
|
||||||
{
|
{
|
||||||
public static class HtmlAgilityPackExtensions
|
public static class HtmlAgilityPackExtensions
|
||||||
{
|
{
|
||||||
@@ -81,7 +80,7 @@ namespace Wino.Core.Extensions
|
|||||||
case HtmlNodeType.Text:
|
case HtmlNodeType.Text:
|
||||||
// script and style must not be output
|
// script and style must not be output
|
||||||
string parentName = node.ParentNode.Name;
|
string parentName = node.ParentNode.Name;
|
||||||
if ((parentName == "script") || (parentName == "style"))
|
if (parentName == "script" || parentName == "style")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// get text
|
// get text
|
||||||
@@ -5,8 +5,9 @@ using MimeKit;
|
|||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Entities.Mail;
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Extensions
|
namespace Wino.Services.Extensions
|
||||||
{
|
{
|
||||||
public static class MailkitClientExtensions
|
public static class MailkitClientExtensions
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using SqlKata;
|
using SqlKata;
|
||||||
using SqlKata.Compilers;
|
using SqlKata.Compilers;
|
||||||
|
|
||||||
namespace Wino.Core.Extensions
|
namespace Wino.Services.Extensions
|
||||||
{
|
{
|
||||||
public static class SqlKataExtensions
|
public static class SqlKataExtensions
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using MoreLinq;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
@@ -11,20 +10,19 @@ using Wino.Core.Domain.Entities.Mail;
|
|||||||
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.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.MenuItems;
|
||||||
using Wino.Core.Domain.Models.Accounts;
|
using Wino.Core.Domain.Models.Accounts;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Synchronization;
|
using Wino.Core.Domain.Models.Synchronization;
|
||||||
using Wino.Core.Extensions;
|
|
||||||
using Wino.Core.MenuItems;
|
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class FolderService : BaseDatabaseService, IFolderService
|
public class FolderService : BaseDatabaseService, IFolderService
|
||||||
{
|
{
|
||||||
private readonly IAccountService _accountService;
|
private readonly IAccountService _accountService;
|
||||||
private readonly IMimeFileService _mimeFileService;
|
|
||||||
private readonly ILogger _logger = Log.ForContext<FolderService>();
|
private readonly ILogger _logger = Log.ForContext<FolderService>();
|
||||||
|
|
||||||
private readonly SpecialFolderType[] gmailCategoryFolderTypes =
|
private readonly SpecialFolderType[] gmailCategoryFolderTypes =
|
||||||
@@ -37,11 +35,9 @@ namespace Wino.Core.Services
|
|||||||
];
|
];
|
||||||
|
|
||||||
public FolderService(IDatabaseService databaseService,
|
public FolderService(IDatabaseService databaseService,
|
||||||
IAccountService accountService,
|
IAccountService accountService) : base(databaseService)
|
||||||
IMimeFileService mimeFileService) : base(databaseService)
|
|
||||||
{
|
{
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
_mimeFileService = mimeFileService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ChangeStickyStatusAsync(Guid folderId, bool isSticky)
|
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)
|
else if (account.ProviderType == MailProviderType.Outlook || account.ProviderType == MailProviderType.Office365)
|
||||||
{
|
{
|
||||||
bool belongsToExistingParent = (await Connection
|
bool belongsToExistingParent = await Connection
|
||||||
.Table<MailItemFolder>()
|
.Table<MailItemFolder>()
|
||||||
.Where(a => unstickyItem.ParentRemoteFolderId == a.RemoteFolderId)
|
.Where(a => unstickyItem.ParentRemoteFolderId == a.RemoteFolderId)
|
||||||
.CountAsync()) > 0;
|
.CountAsync() > 0;
|
||||||
|
|
||||||
// No need to include this as unsticky.
|
// No need to include this as unsticky.
|
||||||
if (belongsToExistingParent) continue;
|
if (belongsToExistingParent) continue;
|
||||||
@@ -236,14 +232,14 @@ namespace Wino.Core.Services
|
|||||||
foreach (var item in listingFolders)
|
foreach (var item in listingFolders)
|
||||||
{
|
{
|
||||||
// Category type folders should be skipped. They will be categorized under virtual category folder.
|
// 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;
|
bool skipEmptyParentRemoteFolders = mailAccount.ProviderType == MailProviderType.Gmail;
|
||||||
|
|
||||||
if (skipEmptyParentRemoteFolders && !string.IsNullOrEmpty(item.ParentRemoteFolderId)) continue;
|
if (skipEmptyParentRemoteFolders && !string.IsNullOrEmpty(item.ParentRemoteFolderId)) continue;
|
||||||
|
|
||||||
// Sticky items belong to account menu item directly. Rest goes to More folder.
|
// 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);
|
var preparedItem = await GetPreparedFolderMenuItemRecursiveAsync(mailAccount, item, parentFolderMenuItem).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -665,9 +661,9 @@ namespace Wino.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> IsInboxAvailableForAccountAsync(Guid accountId)
|
public async Task<bool> IsInboxAvailableForAccountAsync(Guid accountId)
|
||||||
=> (await Connection.Table<MailItemFolder>()
|
=> await Connection.Table<MailItemFolder>()
|
||||||
.Where(a => a.SpecialFolderType == SpecialFolderType.Inbox && a.MailAccountId == accountId)
|
.Where(a => a.SpecialFolderType == SpecialFolderType.Inbox && a.MailAccountId == accountId)
|
||||||
.CountAsync()) == 1;
|
.CountAsync() == 1;
|
||||||
|
|
||||||
public Task UpdateFolderLastSyncDateAsync(Guid folderId)
|
public Task UpdateFolderLastSyncDateAsync(Guid folderId)
|
||||||
=> Connection.ExecuteAsync("UPDATE MailItemFolder SET LastSynchronizedDate = ? WHERE Id = ?", DateTime.UtcNow, folderId);
|
=> Connection.ExecuteAsync("UPDATE MailItemFolder SET LastSynchronizedDate = ? WHERE Id = ?", DateTime.UtcNow, folderId);
|
||||||
11
Wino.Services/LaunchProtocolService.cs
Normal file
11
Wino.Services/LaunchProtocolService.cs
Normal file
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ using Serilog.Core;
|
|||||||
using Serilog.Exceptions;
|
using Serilog.Exceptions;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class LogInitializer : ILogInitializer
|
public class LogInitializer : ILogInitializer
|
||||||
{
|
{
|
||||||
@@ -3,9 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Kiota.Abstractions.Extensions;
|
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using MoreLinq;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
@@ -17,10 +15,10 @@ using Wino.Core.Domain.Extensions;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Comparers;
|
using Wino.Core.Domain.Models.Comparers;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Extensions;
|
|
||||||
using Wino.Messaging.UI;
|
using Wino.Messaging.UI;
|
||||||
|
using Wino.Services.Extensions;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class MailService : BaseDatabaseService, IMailService
|
public class MailService : BaseDatabaseService, IMailService
|
||||||
{
|
{
|
||||||
@@ -285,7 +283,10 @@ namespace Wino.Core.Services
|
|||||||
if (!isFolderCached)
|
if (!isFolderCached)
|
||||||
{
|
{
|
||||||
folderAssignment = await _folderService.GetFolderAsync(mailCopy.FolderId).ConfigureAwait(false);
|
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)
|
if (folderAssignment != null)
|
||||||
@@ -294,8 +295,11 @@ namespace Wino.Core.Services
|
|||||||
if (!isAccountCached)
|
if (!isAccountCached)
|
||||||
{
|
{
|
||||||
accountAssignment = await _accountService.GetAccountAsync(folderAssignment.MailAccountId).ConfigureAwait(false);
|
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)
|
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),
|
_ => CreateReferencedDraft(builder, message, draftCreationOptions, account, signature),
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.SetHtmlBody(builder.HtmlBody);
|
// TODO: Migration
|
||||||
|
// builder.SetHtmlBody(builder.HtmlBody);
|
||||||
|
|
||||||
message.Body = builder.ToMessageBody();
|
message.Body = builder.ToMessageBody();
|
||||||
|
|
||||||
@@ -8,72 +8,10 @@ using Serilog;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Domain.Models.Reader;
|
using Wino.Core.Domain.Models.Reader;
|
||||||
using Wino.Core.Extensions;
|
using Wino.Services.Extensions;
|
||||||
using Wino.Core.Mime;
|
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public interface IMimeFileService
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Finds the EML file for the given mail id for address, parses and returns MimeMessage.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cancellationToken">Cancellation token</param>
|
|
||||||
/// <returns>Mime message information</returns>
|
|
||||||
Task<MimeMessageInformation> GetMimeMessageInformationAsync(Guid fileId, Guid accountId, CancellationToken cancellationToken = default);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileBytes">Byte array of the file.</param>
|
|
||||||
/// <param name="cancellationToken">Cancellation token</param>
|
|
||||||
/// <returns>Mime message information</returns>
|
|
||||||
Task<MimeMessageInformation> GetMimeMessageInformationAsync(byte[] fileBytes, string emlFilePath, CancellationToken cancellationToken = default);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves EML file to the disk.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="copy">MailCopy of the native message.</param>
|
|
||||||
/// <param name="mimeMessage">MimeMessage that is parsed from native message.</param>
|
|
||||||
/// <param name="accountId">Which account Id to save this file for.</param>
|
|
||||||
Task<bool> SaveMimeMessageAsync(Guid fileId, MimeMessage mimeMessage, Guid accountId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a path that all Mime resources (including eml) is stored for this MailCopyId
|
|
||||||
/// This is useful for storing previously rendered attachments as well.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="accountAddress">Account address</param>
|
|
||||||
/// <param name="mailCopyId">Resource mail copy id</param>
|
|
||||||
Task<string> GetMimeResourcePathAsync(Guid accountId, Guid fileId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether mime file exists locally or not.
|
|
||||||
/// </summary>
|
|
||||||
Task<bool> IsMimeExistAsync(Guid accountId, Guid fileId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates HtmlPreviewVisitor for the given MimeMessage.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message">Mime</param>
|
|
||||||
/// <param name="mimeLocalPath">File path that mime is located to load resources.</param>
|
|
||||||
HtmlPreviewVisitor CreateHTMLPreviewVisitor(MimeMessage message, string mimeLocalPath);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the given mime file from the disk.
|
|
||||||
/// </summary>
|
|
||||||
Task<bool> DeleteMimeMessageAsync(Guid accountId, Guid fileId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Prepares the final model containing rendering details.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message">Message to render.</param>
|
|
||||||
/// <param name="mimeLocalPath">File path that physical MimeMessage is located.</param>
|
|
||||||
/// <param name="options">Rendering options</param>
|
|
||||||
MailRenderModel GetMailRenderModel(MimeMessage message, string mimeLocalPath, MailRenderingOptions options = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MimeFileService : IMimeFileService
|
public class MimeFileService : IMimeFileService
|
||||||
{
|
{
|
||||||
private readonly INativeAppService _nativeAppService;
|
private readonly INativeAppService _nativeAppService;
|
||||||
64
Wino.Services/ServiceConstants.cs
Normal file
64
Wino.Services/ServiceConstants.cs
Normal file
@@ -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<string, SpecialFolderType> KnownFolderDictionary = new Dictionary<string, SpecialFolderType>()
|
||||||
|
{
|
||||||
|
{ 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
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Wino.Services/ServicesContainerSetup.cs
Normal file
32
Wino.Services/ServicesContainerSetup.cs
Normal file
@@ -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<ITranslationService, TranslationService>();
|
||||||
|
services.AddSingleton<IDatabaseService, DatabaseService>();
|
||||||
|
|
||||||
|
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
||||||
|
services.AddSingleton<ILogInitializer, LogInitializer>();
|
||||||
|
services.AddSingleton<ILaunchProtocolService, LaunchProtocolService>();
|
||||||
|
services.AddSingleton<IMimeFileService, MimeFileService>();
|
||||||
|
|
||||||
|
services.AddTransient<IMailService, MailService>();
|
||||||
|
services.AddTransient<IFolderService, FolderService>();
|
||||||
|
services.AddTransient<IAccountService, AccountService>();
|
||||||
|
services.AddTransient<IContactService, ContactService>();
|
||||||
|
services.AddTransient<ISignatureService, SignatureService>();
|
||||||
|
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
||||||
|
|
||||||
|
services.AddSingleton<IThreadingStrategyProvider, ThreadingStrategyProvider>();
|
||||||
|
services.AddTransient<IOutlookThreadingStrategy, OutlookThreadingStrategy>();
|
||||||
|
services.AddTransient<IGmailThreadingStrategy, GmailThreadingStrategy>();
|
||||||
|
services.AddTransient<IImapThreadingStrategy, ImapThreadingStrategy>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Threading.Tasks;
|
|||||||
using Wino.Core.Domain.Entities.Mail;
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class SignatureService(IDatabaseService databaseService) : BaseDatabaseService(databaseService), ISignatureService
|
public class SignatureService(IDatabaseService databaseService) : BaseDatabaseService(databaseService), ISignatureService
|
||||||
{
|
{
|
||||||
@@ -7,9 +7,9 @@ using Wino.Core.Domain.Enums;
|
|||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
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
|
public class APIThreadingStrategy : IThreadingStrategy
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using Wino.Core.Domain.Interfaces;
|
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) { }
|
public GmailThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { }
|
||||||
}
|
}
|
||||||
@@ -4,22 +4,20 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
using Wino.Core.Domain.Entities.Mail;
|
using Wino.Core.Domain.Entities.Mail;
|
||||||
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
using Wino.Core.Domain.Models.Folders;
|
using Wino.Core.Domain.Models.Folders;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
using Wino.Core.Extensions;
|
using Wino.Services.Extensions;
|
||||||
using Wino.Core.Services;
|
|
||||||
|
|
||||||
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;
|
private readonly IFolderService _folderService;
|
||||||
|
|
||||||
public ImapThreadStrategy(IDatabaseService databaseService, IFolderService folderService)
|
public ImapThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService)
|
||||||
{
|
{
|
||||||
_databaseService = databaseService;
|
|
||||||
_folderService = folderService;
|
_folderService = folderService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ namespace Wino.Core.Integration.Threading
|
|||||||
.WhereNot("MailCopy.Id", replyItem.Id)
|
.WhereNot("MailCopy.Id", replyItem.Id)
|
||||||
.Select("MailCopy.*");
|
.Select("MailCopy.*");
|
||||||
|
|
||||||
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
return Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<MailCopy> GetInReplyToReplyAsync(IMailItem originalItem, Guid accountId, Guid threadingFolderId, Guid sentFolderId, Guid draftFolderId)
|
private Task<MailCopy> GetInReplyToReplyAsync(IMailItem originalItem, Guid accountId, Guid threadingFolderId, Guid sentFolderId, Guid draftFolderId)
|
||||||
@@ -56,7 +54,7 @@ namespace Wino.Core.Integration.Threading
|
|||||||
|
|
||||||
var raq = query.GetRawQuery();
|
var raq = query.GetRawQuery();
|
||||||
|
|
||||||
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
return Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items, IMailItemFolder threadingForFolder)
|
public async Task<List<IMailItem>> ThreadItemsAsync(List<MailCopy> items, IMailItemFolder threadingForFolder)
|
||||||
@@ -75,8 +73,8 @@ namespace Wino.Core.Integration.Threading
|
|||||||
if (!mailLookupTable.ContainsKey(mail.Id))
|
if (!mailLookupTable.ContainsKey(mail.Id))
|
||||||
mailLookupTable.Add(mail.Id, false);
|
mailLookupTable.Add(mail.Id, false);
|
||||||
|
|
||||||
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Sent);
|
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Sent);
|
||||||
var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Draft);
|
var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Draft);
|
||||||
|
|
||||||
// Threading is not possible. Return items as it is.
|
// Threading is not possible. Return items as it is.
|
||||||
|
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
using Wino.Core.Domain.Interfaces;
|
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 and Gmail is using the same threading strategy.
|
||||||
// Outlook: ConversationId -> it's set as ThreadId
|
// Outlook: ConversationId -> it's set as ThreadId
|
||||||
// Gmail: ThreadId
|
// Gmail: ThreadId
|
||||||
|
|
||||||
public class OutlookThreadingStrategy : APIThreadingStrategy
|
public class OutlookThreadingStrategy : APIThreadingStrategy, IOutlookThreadingStrategy
|
||||||
{
|
{
|
||||||
public OutlookThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { }
|
public OutlookThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { }
|
||||||
}
|
}
|
||||||
31
Wino.Services/ThreadingStrategyProvider.cs
Normal file
31
Wino.Services/ThreadingStrategyProvider.cs
Normal file
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ using Wino.Core.Domain.Interfaces;
|
|||||||
using Wino.Core.Domain.Models.Translations;
|
using Wino.Core.Domain.Models.Translations;
|
||||||
using Wino.Messaging.Client.Shell;
|
using Wino.Messaging.Client.Shell;
|
||||||
|
|
||||||
namespace Wino.Core.Services
|
namespace Wino.Services
|
||||||
{
|
{
|
||||||
public class TranslationService : ITranslationService
|
public class TranslationService : ITranslationService
|
||||||
{
|
{
|
||||||
23
Wino.Services/Wino.Services.csproj
Normal file
23
Wino.Services/Wino.Services.csproj
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<LangVersion>12.0</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.70" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||||
|
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||||
|
<PackageReference Include="SqlKata" Version="2.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||||
|
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
23
Wino.sln
23
Wino.sln
@@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Calendar", "Wino.Calen
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wino.Calendar.Packaging", "Wino.Calendar.Packaging\Wino.Calendar.Packaging.wapproj", "{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}"
|
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wino.Calendar.Packaging", "Wino.Calendar.Packaging\Wino.Calendar.Packaging.wapproj", "{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Services", "Wino.Services\Wino.Services.csproj", "{4000A374-59FE-4400-ACF6-D40473BECD73}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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.ActiveCfg = Release|x86
|
||||||
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Build.0 = Release|x86
|
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Build.0 = Release|x86
|
||||||
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Deploy.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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -407,6 +429,7 @@ Global
|
|||||||
{53723AE8-7E7E-4D54-ADAB-0A6033255CC8} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
{53723AE8-7E7E-4D54-ADAB-0A6033255CC8} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||||
{039AFFA8-C1CC-4E3B-8A31-6814D7557F74} = {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}
|
{A4DBA01A-F315-49E0-8428-BB99D32B20F9} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||||
|
{4000A374-59FE-4400-ACF6-D40473BECD73} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {721F946E-F69F-4987-823A-D084B436FC1E}
|
SolutionGuid = {721F946E-F69F-4987-823A-D084B436FC1E}
|
||||||
|
|||||||
Reference in New Issue
Block a user