Separation of core library from the UWP app.
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,12 +5,13 @@ using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Core.Domain.Collections;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.MenuItems;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
|
||||
@@ -7,12 +7,12 @@ using System.Threading.Tasks;
|
||||
using CommunityToolkit.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Wino.Core.Domain.Collections;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.Calendar.CalendarTypeStrategies;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Core.ViewModels;
|
||||
using Wino.Messaging.Client.Calendar;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,8 +3,8 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Collections;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.MenuItems;
|
||||
|
||||
namespace Wino.Calendar.Controls
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <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)
|
||||
: base(collection)
|
||||
{
|
||||
@@ -160,7 +160,7 @@ namespace Wino.Core.MenuItems
|
||||
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("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.Models.Folders;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public partial class AccountMenuItem : MenuItemBase<MailAccount, MenuItemBase<IMailItemFolder, FolderMenuItem>>, IAccountMenuItem
|
||||
{
|
||||
@@ -22,7 +22,7 @@ namespace Wino.Core.MenuItems
|
||||
private bool _isEnabled = true;
|
||||
|
||||
public bool IsAttentionRequired => AttentionReason != AccountAttentionReason.None;
|
||||
public bool IsSynchronizationProgressVisible => (SynchronizationProgress > 0 && SynchronizationProgress < 100);
|
||||
public bool IsSynchronizationProgressVisible => SynchronizationProgress > 0 && SynchronizationProgress < 100;
|
||||
|
||||
// We can't determine the progress for gmail synchronization since it is based on history changes.
|
||||
public bool IsProgressIndeterminate => Parameter?.ProviderType == MailProviderType.Gmail;
|
||||
@@ -2,7 +2,7 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class FixAccountIssuesMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>
|
||||
{
|
||||
@@ -7,7 +7,7 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public partial class FolderMenuItem : MenuItemBase<IMailItemFolder, FolderMenuItem>, IFolderMenuItem
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class ManageAccountsMenuItem : MenuItemBase { }
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public partial class MenuItemBase : ObservableObject, IMenuItem
|
||||
{
|
||||
@@ -2,11 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MoreLinq.Extensions;
|
||||
using Wino.Core.Domain.Collections;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class MenuItemCollection : ObservableRangeCollection<IMenuItem>
|
||||
{
|
||||
@@ -108,7 +108,10 @@ namespace Wino.Core.MenuItems
|
||||
public void UpdateUnreadItemCountsToZero()
|
||||
{
|
||||
// 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)
|
||||
@@ -168,7 +171,10 @@ namespace Wino.Core.MenuItems
|
||||
|
||||
await _dispatcher.ExecuteOnUIThread(() =>
|
||||
{
|
||||
accountItems.ForEach(a => a.IsEnabled = isEnabled);
|
||||
foreach (var item in accountItems)
|
||||
{
|
||||
item.IsEnabled = isEnabled;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.Interfaces;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public partial class MergedAccountMenuItem : MenuItemBase<MergedInbox, IMenuItem>, IMergedAccountMenuItem
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class MergedAccountMoreFolderMenuItem : MenuItemBase<object, IMenuItem>
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class NewMailMenuItem : MenuItemBase { }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class RateMenuItem : MenuItemBase { }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class SeperatorItem : MenuItemBase { }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Wino.Core.MenuItems
|
||||
namespace Wino.Core.Domain.MenuItems
|
||||
{
|
||||
public class SettingsItem : MenuItemBase { }
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using MimeKit;
|
||||
using MimeKit.Text;
|
||||
using MimeKit.Tnef;
|
||||
|
||||
namespace Wino.Core.Mime
|
||||
namespace Wino.Core.Domain.Models.MailItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control.
|
||||
@@ -5,6 +5,8 @@
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -58,6 +60,8 @@
|
||||
<EmbeddedResource Include="Translations\zh_CN\resources.json" />
|
||||
</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">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Core.Domain.MenuItems;
|
||||
|
||||
namespace Wino.Core.UWP.Selectors
|
||||
{
|
||||
|
||||
@@ -3,14 +3,10 @@ using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.Foundation.Metadata;
|
||||
using Windows.Security.Authentication.Web;
|
||||
using Windows.Security.Cryptography;
|
||||
using Windows.Security.Cryptography.Core;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.System;
|
||||
using Windows.UI.Shell;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Authorization;
|
||||
|
||||
|
||||
|
||||
@@ -51,46 +47,6 @@ namespace Wino.Services
|
||||
return _mimeMessagesFolder;
|
||||
}
|
||||
|
||||
#region Cryptography
|
||||
|
||||
public string randomDataBase64url(uint length)
|
||||
{
|
||||
IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
|
||||
return base64urlencodeNoPadding(buffer);
|
||||
}
|
||||
|
||||
public IBuffer sha256(string inputString)
|
||||
{
|
||||
HashAlgorithmProvider sha = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||
IBuffer buff = CryptographicBuffer.ConvertStringToBinary(inputString, BinaryStringEncoding.Utf8);
|
||||
return sha.HashData(buff);
|
||||
}
|
||||
|
||||
public string base64urlencodeNoPadding(IBuffer buffer)
|
||||
{
|
||||
string base64 = CryptographicBuffer.EncodeToBase64String(buffer);
|
||||
|
||||
// Converts base64 to base64url.
|
||||
base64 = base64.Replace("+", "-");
|
||||
base64 = base64.Replace("/", "_");
|
||||
|
||||
// Strips padding.
|
||||
base64 = base64.Replace("=", "");
|
||||
|
||||
return base64;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// GMail Integration.
|
||||
public GoogleAuthorizationRequest GetGoogleAuthorizationRequest()
|
||||
{
|
||||
string state = randomDataBase64url(32);
|
||||
string code_verifier = randomDataBase64url(32);
|
||||
string code_challenge = base64urlencodeNoPadding(sha256(code_verifier));
|
||||
|
||||
return new GoogleAuthorizationRequest(state, code_verifier, code_challenge);
|
||||
}
|
||||
|
||||
public async Task<string> GetEditorBundlePathAsync()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.Reader;
|
||||
using Wino.Core.Domain.Translations;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.UWP.Services
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Core.UWP.Services
|
||||
{
|
||||
public static class ThumbnailService
|
||||
{
|
||||
@@ -55,7 +55,7 @@ namespace Wino.Core.Services
|
||||
return new Tuple<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)
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:domain="using:Wino.Core.Domain"
|
||||
xmlns:helpers="using:Wino.Helpers"
|
||||
xmlns:local="using:Wino.Core.UWP.Styles"
|
||||
xmlns:menu="using:Wino.Core.MenuItems"
|
||||
xmlns:menu="using:Wino.Core.Domain.MenuItems"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
|
||||
xmlns:winuiControls="using:CommunityToolkit.WinUI.Controls">
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
<Compile Include="Services\PrintService.cs" />
|
||||
<Compile Include="Services\StartupBehaviorService.cs" />
|
||||
<Compile Include="Services\StatePersistenceService.cs" />
|
||||
<Compile Include="Services\ThumbnailService.cs" />
|
||||
<Compile Include="Services\WinoServerConnectionManager.cs" />
|
||||
<Compile Include="Services\BackgroundTaskService.cs" />
|
||||
<Compile Include="Services\ClipboardService.cs" />
|
||||
@@ -242,6 +243,10 @@
|
||||
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
||||
<Name>Wino.Messaging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj">
|
||||
<Project>{4000a374-59fe-4400-acf6-d40473becd73}</Project>
|
||||
<Name>Wino.Services</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
||||
|
||||
@@ -23,7 +23,7 @@ using Windows.UI.Xaml.Controls;
|
||||
using Wino.Activation;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.UWP
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,7 +3,6 @@ using Serilog.Core;
|
||||
using Wino.Authentication;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Integration.Processors;
|
||||
using Wino.Core.Integration.Threading;
|
||||
using Wino.Core.Services;
|
||||
|
||||
namespace Wino.Core
|
||||
@@ -15,41 +14,20 @@ namespace Wino.Core
|
||||
var loggerLevelSwitcher = new LoggingLevelSwitch();
|
||||
|
||||
services.AddSingleton(loggerLevelSwitcher);
|
||||
services.AddSingleton<ILogInitializer, LogInitializer>();
|
||||
|
||||
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.AddSingleton<ISynchronizerFactory, SynchronizerFactory>();
|
||||
|
||||
services.AddTransient<IGmailChangeProcessor, GmailChangeProcessor>();
|
||||
services.AddTransient<IImapChangeProcessor, ImapChangeProcessor>();
|
||||
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<IWinoRequestDelegator, WinoRequestDelegator>();
|
||||
services.AddTransient<IImapTestService, ImapTestService>();
|
||||
services.AddTransient<IAuthenticationProvider, AuthenticationProvider>();
|
||||
services.AddTransient<IAutoDiscoveryService, AutoDiscoveryService>();
|
||||
services.AddTransient<IContextMenuItemService, ContextMenuItemService>();
|
||||
services.AddTransient<IFontService, FontService>();
|
||||
services.AddTransient<IUnsubscriptionService, UnsubscriptionService>();
|
||||
|
||||
services.AddTransient<IOutlookAuthenticator, OutlookAuthenticator>();
|
||||
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 Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Services;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Extensions
|
||||
{
|
||||
public static class GoogleIntegratorExtensions
|
||||
{
|
||||
public const string INBOX_LABEL_ID = "INBOX";
|
||||
public const string UNREAD_LABEL_ID = "UNREAD";
|
||||
public const string IMPORTANT_LABEL_ID = "IMPORTANT";
|
||||
public const string STARRED_LABEL_ID = "STARRED";
|
||||
public const string DRAFT_LABEL_ID = "DRAFT";
|
||||
public const string SENT_LABEL_ID = "SENT";
|
||||
public const string SPAM_LABEL_ID = "SPAM";
|
||||
public const string CHAT_LABEL_ID = "CHAT";
|
||||
public const string TRASH_LABEL_ID = "TRASH";
|
||||
|
||||
// Category labels.
|
||||
public const string FORUMS_LABEL_ID = "FORUMS";
|
||||
public const string UPDATES_LABEL_ID = "UPDATES";
|
||||
public const string PROMOTIONS_LABEL_ID = "PROMOTIONS";
|
||||
public const string SOCIAL_LABEL_ID = "SOCIAL";
|
||||
public const string PERSONAL_LABEL_ID = "PERSONAL";
|
||||
|
||||
// Label visibility identifiers.
|
||||
private const string SYSTEM_FOLDER_IDENTIFIER = "system";
|
||||
private const string FOLDER_HIDE_IDENTIFIER = "labelHide";
|
||||
|
||||
private const string CATEGORY_PREFIX = "CATEGORY_";
|
||||
private const string FOLDER_SEPERATOR_STRING = "/";
|
||||
private const char FOLDER_SEPERATOR_CHAR = '/';
|
||||
|
||||
private static Dictionary<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)
|
||||
{
|
||||
// 1. Remove CATEGORY_ prefix.
|
||||
var normalizedLabelName = labelName.Replace(CATEGORY_PREFIX, string.Empty);
|
||||
var normalizedLabelName = labelName.Replace(ServiceConstants.CATEGORY_PREFIX, string.Empty);
|
||||
|
||||
// 2. Normalize label name by capitalizing first letter.
|
||||
normalizedLabelName = char.ToUpper(normalizedLabelName[0]) + normalizedLabelName.Substring(1).ToLower();
|
||||
@@ -81,9 +35,9 @@ namespace Wino.Core.Extensions
|
||||
// Even though we normalize the label name, check is done by capitalizing the label name.
|
||||
var capitalNormalizedLabelName = normalizedLabelName.ToUpper();
|
||||
|
||||
bool isSpecialFolder = KnownFolderDictionary.ContainsKey(capitalNormalizedLabelName);
|
||||
bool isSpecialFolder = ServiceConstants.KnownFolderDictionary.ContainsKey(capitalNormalizedLabelName);
|
||||
|
||||
var specialFolderType = isSpecialFolder ? KnownFolderDictionary[capitalNormalizedLabelName] : SpecialFolderType.Other;
|
||||
var specialFolderType = isSpecialFolder ? ServiceConstants.KnownFolderDictionary[capitalNormalizedLabelName] : SpecialFolderType.Other;
|
||||
|
||||
// We used to support FOLDER_HIDE_IDENTIFIER to hide invisible folders.
|
||||
// However, a lot of people complained that they don't see their folders after the initial sync
|
||||
@@ -96,13 +50,13 @@ namespace Wino.Core.Extensions
|
||||
|
||||
bool isHidden = false;
|
||||
|
||||
bool isChildOfCategoryFolder = label.Name.StartsWith(CATEGORY_PREFIX);
|
||||
bool isChildOfCategoryFolder = label.Name.StartsWith(ServiceConstants.CATEGORY_PREFIX);
|
||||
bool isSticky = isSpecialFolder && specialFolderType != SpecialFolderType.Category && !isChildOfCategoryFolder;
|
||||
|
||||
// By default, all special folders update unread count in the UI except Trash.
|
||||
bool shouldShowUnreadCount = specialFolderType != SpecialFolderType.Deleted || specialFolderType != SpecialFolderType.Other;
|
||||
|
||||
bool isSystemFolder = label.Type == SYSTEM_FOLDER_IDENTIFIER;
|
||||
bool isSystemFolder = label.Type == ServiceConstants.SYSTEM_FOLDER_IDENTIFIER;
|
||||
|
||||
var localFolder = new MailItemFolder()
|
||||
{
|
||||
@@ -126,16 +80,16 @@ namespace Wino.Core.Extensions
|
||||
}
|
||||
|
||||
public static bool GetIsDraft(this Message message)
|
||||
=> message?.LabelIds?.Any(a => a == DRAFT_LABEL_ID) ?? false;
|
||||
=> message?.LabelIds?.Any(a => a == ServiceConstants.DRAFT_LABEL_ID) ?? false;
|
||||
|
||||
public static bool GetIsUnread(this Message message)
|
||||
=> message?.LabelIds?.Any(a => a == UNREAD_LABEL_ID) ?? false;
|
||||
=> message?.LabelIds?.Any(a => a == ServiceConstants.UNREAD_LABEL_ID) ?? false;
|
||||
|
||||
public static bool GetIsFocused(this Message message)
|
||||
=> message?.LabelIds?.Any(a => a == IMPORTANT_LABEL_ID) ?? false;
|
||||
=> message?.LabelIds?.Any(a => a == ServiceConstants.IMPORTANT_LABEL_ID) ?? false;
|
||||
|
||||
public static bool GetIsFlagged(this Message message)
|
||||
=> message?.LabelIds?.Any(a => a == STARRED_LABEL_ID) ?? false;
|
||||
=> message?.LabelIds?.Any(a => a == ServiceConstants.STARRED_LABEL_ID) ?? false;
|
||||
|
||||
private static string GetParentFolderRemoteId(string fullLabelName, ListLabelsResponse labelsResponse)
|
||||
{
|
||||
@@ -158,9 +112,9 @@ namespace Wino.Core.Extensions
|
||||
if (string.IsNullOrEmpty(fullFolderName)) return string.Empty;
|
||||
|
||||
// Folders with "//" at the end has "/" as the name.
|
||||
if (fullFolderName.EndsWith(FOLDER_SEPERATOR_STRING)) return FOLDER_SEPERATOR_STRING;
|
||||
if (fullFolderName.EndsWith(ServiceConstants.FOLDER_SEPERATOR_STRING)) return ServiceConstants.FOLDER_SEPERATOR_STRING;
|
||||
|
||||
string[] parts = fullFolderName.Split(FOLDER_SEPERATOR_CHAR);
|
||||
string[] parts = fullFolderName.Split(ServiceConstants.FOLDER_SEPERATOR_CHAR);
|
||||
|
||||
var lastPart = parts[parts.Length - 1];
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using MimeKit;
|
||||
using MimeKit.IO;
|
||||
using MimeKit.IO.Filters;
|
||||
using MimeKit.Utils;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Extensions
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Processors
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Processors
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Processors
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Processors
|
||||
{
|
||||
|
||||
@@ -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.Interfaces;
|
||||
using Wino.Core.Integration.Threading;
|
||||
using Wino.Services.Threading;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
{
|
||||
@@ -8,11 +8,11 @@ namespace Wino.Core.Services
|
||||
{
|
||||
private readonly OutlookThreadingStrategy _outlookThreadingStrategy;
|
||||
private readonly GmailThreadingStrategy _gmailThreadingStrategy;
|
||||
private readonly ImapThreadStrategy _imapThreadStrategy;
|
||||
private readonly ImapThreadingStrategy _imapThreadStrategy;
|
||||
|
||||
public ThreadingStrategyProvider(OutlookThreadingStrategy outlookThreadingStrategy,
|
||||
GmailThreadingStrategy gmailThreadingStrategy,
|
||||
ImapThreadStrategy imapThreadStrategy)
|
||||
ImapThreadingStrategy imapThreadStrategy)
|
||||
{
|
||||
_outlookThreadingStrategy = outlookThreadingStrategy;
|
||||
_gmailThreadingStrategy = gmailThreadingStrategy;
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Wino.Core.Services
|
||||
private readonly IWinoServerConnectionManager _winoServerConnectionManager;
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly ILogger _logger = Log.ForContext<WinoRequestDelegator>();
|
||||
|
||||
public WinoRequestDelegator(IWinoRequestProcessor winoRequestProcessor,
|
||||
IWinoServerConnectionManager winoServerConnectionManager,
|
||||
|
||||
@@ -23,7 +23,6 @@ namespace Wino.Core.Services
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly IKeyPressService _keyPressService;
|
||||
private readonly IPreferencesService _preferencesService;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IMailDialogService _dialogService;
|
||||
private readonly IMailService _mailService;
|
||||
|
||||
@@ -41,14 +40,12 @@ namespace Wino.Core.Services
|
||||
public WinoRequestProcessor(IFolderService folderService,
|
||||
IKeyPressService keyPressService,
|
||||
IPreferencesService preferencesService,
|
||||
IAccountService accountService,
|
||||
IMailDialogService dialogService,
|
||||
IMailService mailService)
|
||||
{
|
||||
_folderService = folderService;
|
||||
_keyPressService = keyPressService;
|
||||
_preferencesService = preferencesService;
|
||||
_accountService = accountService;
|
||||
_dialogService = dialogService;
|
||||
_mailService = mailService;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ using Wino.Core.Requests.Bundles;
|
||||
using Wino.Core.Requests.Folder;
|
||||
using Wino.Core.Requests.Mail;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Synchronizers.Mail
|
||||
{
|
||||
@@ -532,11 +533,11 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
foreach (var labelId in addedLabel.LabelIds)
|
||||
{
|
||||
// When UNREAD label is added mark the message as un-read.
|
||||
if (labelId == GoogleIntegratorExtensions.UNREAD_LABEL_ID)
|
||||
if (labelId == ServiceConstants.UNREAD_LABEL_ID)
|
||||
await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, false).ConfigureAwait(false);
|
||||
|
||||
// When STARRED label is added mark the message as flagged.
|
||||
if (labelId == GoogleIntegratorExtensions.STARRED_LABEL_ID)
|
||||
if (labelId == ServiceConstants.STARRED_LABEL_ID)
|
||||
await _gmailChangeProcessor.ChangeFlagStatusAsync(messageId, true).ConfigureAwait(false);
|
||||
|
||||
await _gmailChangeProcessor.CreateAssignmentAsync(Account.Id, messageId, labelId).ConfigureAwait(false);
|
||||
@@ -552,11 +553,11 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
foreach (var labelId in removedLabel.LabelIds)
|
||||
{
|
||||
// When UNREAD label is removed mark the message as read.
|
||||
if (labelId == GoogleIntegratorExtensions.UNREAD_LABEL_ID)
|
||||
if (labelId == ServiceConstants.UNREAD_LABEL_ID)
|
||||
await _gmailChangeProcessor.ChangeMailReadStatusAsync(messageId, true).ConfigureAwait(false);
|
||||
|
||||
// When STARRED label is removed mark the message as un-flagged.
|
||||
if (labelId == GoogleIntegratorExtensions.STARRED_LABEL_ID)
|
||||
if (labelId == ServiceConstants.STARRED_LABEL_ID)
|
||||
await _gmailChangeProcessor.ChangeFlagStatusAsync(messageId, false).ConfigureAwait(false);
|
||||
|
||||
// For other labels remove the mail assignment.
|
||||
@@ -637,9 +638,9 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
};
|
||||
|
||||
if (isFlagged)
|
||||
batchModifyRequest.AddLabelIds = new List<string>() { GoogleIntegratorExtensions.STARRED_LABEL_ID };
|
||||
batchModifyRequest.AddLabelIds = new List<string>() { ServiceConstants.STARRED_LABEL_ID };
|
||||
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");
|
||||
|
||||
@@ -656,9 +657,9 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
};
|
||||
|
||||
if (readStatus)
|
||||
batchModifyRequest.RemoveLabelIds = new List<string>() { GoogleIntegratorExtensions.UNREAD_LABEL_ID };
|
||||
batchModifyRequest.RemoveLabelIds = new List<string>() { ServiceConstants.UNREAD_LABEL_ID };
|
||||
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");
|
||||
|
||||
@@ -704,11 +705,11 @@ namespace Wino.Core.Synchronizers.Mail
|
||||
|
||||
if (isArchiving)
|
||||
{
|
||||
batchModifyRequest.RemoveLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID };
|
||||
batchModifyRequest.RemoveLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID };
|
||||
}
|
||||
else
|
||||
{
|
||||
batchModifyRequest.AddLabelIds = new[] { GoogleIntegratorExtensions.INBOX_LABEL_ID };
|
||||
batchModifyRequest.AddLabelIds = new[] { ServiceConstants.INBOX_LABEL_ID };
|
||||
}
|
||||
|
||||
var networkCall = _gmailService.Users.Messages.BatchModify(batchModifyRequest, "me");
|
||||
|
||||
@@ -27,6 +27,7 @@ using Wino.Core.Requests.Bundles;
|
||||
using Wino.Core.Requests.Folder;
|
||||
using Wino.Core.Requests.Mail;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Synchronizers.Mail
|
||||
{
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -47,5 +49,6 @@
|
||||
<ProjectReference Include="..\Wino.Authentication\Wino.Authentication.csproj" />
|
||||
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -16,12 +16,11 @@ using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.MenuItems;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Messaging.Client.Accounts;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
@@ -55,7 +54,7 @@ namespace Wino.Mail.ViewModels
|
||||
private readonly SettingsItem SettingsItem = new SettingsItem();
|
||||
private readonly ManageAccountsMenuItem ManageAccountsMenuItem = new ManageAccountsMenuItem();
|
||||
|
||||
public NewMailMenuItem CreateMailMenuItem = new NewMailMenuItem();
|
||||
public IMenuItem CreateMailMenuItem = new NewMailMenuItem();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
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.Core.MenuItems;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Messages
|
||||
{
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -21,6 +24,7 @@
|
||||
<ProjectReference Include="..\Wino.Core.ViewModels\Wino.Core.ViewModels.csproj" />
|
||||
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -10,7 +10,6 @@ using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Views;
|
||||
|
||||
namespace Wino.Activation
|
||||
|
||||
@@ -17,17 +17,14 @@ namespace Wino.Activation
|
||||
/// </summary>
|
||||
internal class ToastNotificationActivationHandler : ActivationHandler<ToastNotificationActivatedEventArgs>
|
||||
{
|
||||
private readonly INativeAppService _nativeAppService;
|
||||
private readonly IMailService _mailService;
|
||||
private readonly IFolderService _folderService;
|
||||
|
||||
private ToastArguments _toastArguments;
|
||||
|
||||
public ToastNotificationActivationHandler(INativeAppService nativeAppService,
|
||||
IMailService mailService,
|
||||
public ToastNotificationActivationHandler(IMailService mailService,
|
||||
IFolderService folderService)
|
||||
{
|
||||
_nativeAppService = nativeAppService;
|
||||
_mailService = mailService;
|
||||
_folderService = folderService;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ using Windows.ApplicationModel.Background;
|
||||
using Windows.UI.Core.Preview;
|
||||
using Windows.UI.Notifications;
|
||||
using Wino.Activation;
|
||||
using Wino.Core;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
@@ -70,7 +69,8 @@ namespace Wino
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.RegisterCoreServices();
|
||||
services.RegisterViewModelService();
|
||||
services.RegisterSharedServices();
|
||||
services.RegisterCoreUWPServices();
|
||||
services.RegisterCoreViewModels();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
xmlns:enums="using:Wino.Core.Domain.Enums"
|
||||
xmlns:helpers="using:Wino.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:menu="using:Wino.Core.MenuItems"
|
||||
xmlns:menu="using:Wino.Core.Domain.MenuItems"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
x:Name="Root"
|
||||
muxc:BackdropMaterial.ApplyToRootOrPageBackground="{ThemeResource UseMica}"
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Microsoft.Xaml.Interactivity;
|
||||
using Windows.UI.Xaml;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.UWP.Controls;
|
||||
|
||||
namespace Wino.Behaviors
|
||||
{
|
||||
public class CreateMailNavigationItemBehavior : Behavior<WinoNavigationViewItem>
|
||||
{
|
||||
public MenuItemBase SelectedMenuItem
|
||||
public IMenuItem SelectedMenuItem
|
||||
{
|
||||
get { return (MenuItemBase)GetValue(SelectedMenuItemProperty); }
|
||||
get { return (IMenuItem)GetValue(SelectedMenuItemProperty); }
|
||||
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); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection<MenuItemBase>), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnMenuItemsChanged));
|
||||
public static readonly DependencyProperty SelectedMenuItemProperty = DependencyProperty.Register(nameof(SelectedMenuItem), typeof(MenuItemBase), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnSelectedMenuItemChanged));
|
||||
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems), typeof(ObservableCollection<IMenuItem>), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnMenuItemsChanged));
|
||||
public static readonly DependencyProperty SelectedMenuItemProperty = DependencyProperty.Register(nameof(SelectedMenuItem), typeof(IMenuItem), typeof(CreateMailNavigationItemBehavior), new PropertyMetadata(null, OnSelectedMenuItemChanged));
|
||||
|
||||
public CreateMailNavigationItemBehavior()
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.UI.Xaml.Shapes;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Core.UWP.Services;
|
||||
|
||||
namespace Wino.Controls
|
||||
{
|
||||
|
||||
@@ -604,10 +604,6 @@
|
||||
<Project>{53723ae8-7e7e-4d54-adab-0a6033255cc8}</Project>
|
||||
<Name>Wino.Core.ViewModels</Name>
|
||||
</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">
|
||||
<Project>{d62f1c03-da57-4709-a640-0283296a8e66}</Project>
|
||||
<Name>Wino.Mail.ViewModels</Name>
|
||||
@@ -616,6 +612,10 @@
|
||||
<Project>{0c307d7e-256f-448c-8265-5622a812fbcc}</Project>
|
||||
<Name>Wino.Messaging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj">
|
||||
<Project>{4000a374-59fe-4400-acf6-d40473becd73}</Project>
|
||||
<Name>Wino.Services</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="WindowsDesktop, Version=10.0.22621.0">
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>12</LangVersion>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
|
||||
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
||||
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -14,7 +14,6 @@ using Wino.Core;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Core.UWP.Services;
|
||||
using Wino.Server.Core;
|
||||
using Wino.Server.MessageHandlers;
|
||||
@@ -68,6 +67,7 @@ namespace Wino.Server
|
||||
services.AddTransient<ServerViewModel>();
|
||||
|
||||
services.RegisterCoreServices();
|
||||
services.RegisterSharedServices();
|
||||
|
||||
// Below services belongs to UWP.Core package and some APIs are not available for WPF.
|
||||
// We register them here to avoid compilation errors.
|
||||
@@ -77,6 +77,7 @@ namespace Wino.Server
|
||||
services.AddSingleton<IPreferencesService, PreferencesService>();
|
||||
services.AddTransient<INotificationBuilder, NotificationBuilder>();
|
||||
services.AddTransient<IUnderlyingThemeService, UnderlyingThemeService>();
|
||||
services.AddSingleton<IApplicationConfiguration, ApplicationConfiguration>();
|
||||
|
||||
// Register server message handler factory.
|
||||
var serverMessageHandlerFactory = new ServerMessageHandlerFactory();
|
||||
|
||||
@@ -13,13 +13,13 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Requests;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Integration.Json;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Messaging;
|
||||
using Wino.Messaging.Client.Authorization;
|
||||
using Wino.Messaging.Enums;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Server.MessageHandlers;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Server
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<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\UnderlyingThemeService.cs" Link="Services\UnderlyingThemeService.cs" />
|
||||
<Compile Include="..\Wino.Core.UWP\Services\ThumbnailService.cs" Link="Services\ThumbnailService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Wino_Icon.ico">
|
||||
@@ -42,5 +43,6 @@
|
||||
<ProjectReference Include="..\Wino.Core.Domain\Wino.Core.Domain.csproj" />
|
||||
<ProjectReference Include="..\Wino.Core\Wino.Core.csproj" />
|
||||
<ProjectReference Include="..\Wino.Messages\Wino.Messaging.csproj" />
|
||||
<ProjectReference Include="..\Wino.Services\Wino.Services.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -11,28 +11,25 @@ using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Messaging.Client.Accounts;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class AccountService : BaseDatabaseService, IAccountService
|
||||
{
|
||||
public IAuthenticator ExternalAuthenticationAuthenticator { get; set; }
|
||||
|
||||
private readonly IAuthenticationProvider _authenticationProvider;
|
||||
private readonly ISignatureService _signatureService;
|
||||
private readonly IPreferencesService _preferencesService;
|
||||
|
||||
private readonly ILogger _logger = Log.ForContext<AccountService>();
|
||||
|
||||
public AccountService(IDatabaseService databaseService,
|
||||
IAuthenticationProvider authenticationProvider,
|
||||
ISignatureService signatureService,
|
||||
IPreferencesService preferencesService) : base(databaseService)
|
||||
{
|
||||
_authenticationProvider = authenticationProvider;
|
||||
_signatureService = signatureService;
|
||||
_preferencesService = preferencesService;
|
||||
}
|
||||
@@ -203,13 +200,13 @@ namespace Wino.Core.Services
|
||||
|
||||
if (account == null) return;
|
||||
|
||||
var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType);
|
||||
//var authenticator = _authenticationProvider.GetAuthenticator(account.ProviderType);
|
||||
|
||||
// This will re-generate token.
|
||||
var token = await authenticator.GenerateTokenInformationAsync(account);
|
||||
//// This will re-generate token.
|
||||
//var token = await authenticator.GenerateTokenInformationAsync(account);
|
||||
|
||||
// TODO: Rest?
|
||||
Guard.IsNotNull(token);
|
||||
// Guard.IsNotNull(token);
|
||||
}
|
||||
|
||||
private Task<MailAccountPreferences> GetAccountPreferencesAsync(Guid accountId)
|
||||
@@ -538,10 +535,10 @@ namespace Wino.Core.Services
|
||||
var currentIdentifier = account.SynchronizationDeltaIdentifier;
|
||||
|
||||
bool shouldUpdateIdentifier = account.ProviderType == MailProviderType.Gmail ?
|
||||
((string.IsNullOrEmpty(currentIdentifier) ? true : !string.IsNullOrEmpty(currentIdentifier)
|
||||
string.IsNullOrEmpty(currentIdentifier) ? true : !string.IsNullOrEmpty(currentIdentifier)
|
||||
&& ulong.TryParse(currentIdentifier, out ulong currentIdentifierValue)
|
||||
&& ulong.TryParse(newIdentifier, out ulong newIdentifierValue)
|
||||
&& newIdentifierValue > currentIdentifierValue)) : true;
|
||||
&& newIdentifierValue > currentIdentifierValue : true;
|
||||
|
||||
if (shouldUpdateIdentifier)
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class ApplicationConfiguration : IApplicationConfiguration
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class BaseDatabaseService
|
||||
{
|
||||
@@ -4,17 +4,11 @@ using System.Threading.Tasks;
|
||||
using MimeKit;
|
||||
using SqlKata;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public interface IContactService
|
||||
{
|
||||
Task<List<AccountContact>> GetAddressInformationAsync(string queryText);
|
||||
Task<AccountContact> GetAddressInformationByAddressAsync(string address);
|
||||
Task SaveAddressInformationAsync(MimeMessage message);
|
||||
}
|
||||
|
||||
public class ContactService : BaseDatabaseService, IContactService
|
||||
{
|
||||
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.Menus;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class ContextMenuItemService : IContextMenuItemService
|
||||
{
|
||||
@@ -93,7 +93,7 @@ namespace Wino.Core.Services
|
||||
};
|
||||
operationList.AddRange(readOperations);
|
||||
|
||||
List<MailOperationMenuItem> flagsOperations = (isAllFlagged, isAllNotFlagged) switch
|
||||
List<MailOperationMenuItem> flagsOperations = (isAllFlagged, isAllNotFlagged) switch
|
||||
{
|
||||
(true, false) => [MailOperationMenuItem.Create(MailOperation.ClearFlag)],
|
||||
(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.Interfaces;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public interface IDatabaseService : IInitializeAsync
|
||||
{
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HtmlAgilityPack;
|
||||
|
||||
namespace Wino.Core.Extensions
|
||||
namespace Wino.Services.Extensions
|
||||
{
|
||||
public static class HtmlAgilityPackExtensions
|
||||
{
|
||||
@@ -81,7 +80,7 @@ namespace Wino.Core.Extensions
|
||||
case HtmlNodeType.Text:
|
||||
// script and style must not be output
|
||||
string parentName = node.ParentNode.Name;
|
||||
if ((parentName == "script") || (parentName == "style"))
|
||||
if (parentName == "script" || parentName == "style")
|
||||
break;
|
||||
|
||||
// get text
|
||||
@@ -5,8 +5,9 @@ using MimeKit;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Extensions
|
||||
namespace Wino.Services.Extensions
|
||||
{
|
||||
public static class MailkitClientExtensions
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
using SqlKata;
|
||||
using SqlKata.Compilers;
|
||||
|
||||
namespace Wino.Core.Extensions
|
||||
namespace Wino.Services.Extensions
|
||||
{
|
||||
public static class SqlKataExtensions
|
||||
{
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using MoreLinq;
|
||||
using Serilog;
|
||||
using SqlKata;
|
||||
using Wino.Core.Domain;
|
||||
@@ -11,20 +10,19 @@ using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.MenuItems;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.MenuItems;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class FolderService : BaseDatabaseService, IFolderService
|
||||
{
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IMimeFileService _mimeFileService;
|
||||
private readonly ILogger _logger = Log.ForContext<FolderService>();
|
||||
|
||||
private readonly SpecialFolderType[] gmailCategoryFolderTypes =
|
||||
@@ -37,11 +35,9 @@ namespace Wino.Core.Services
|
||||
];
|
||||
|
||||
public FolderService(IDatabaseService databaseService,
|
||||
IAccountService accountService,
|
||||
IMimeFileService mimeFileService) : base(databaseService)
|
||||
IAccountService accountService) : base(databaseService)
|
||||
{
|
||||
_accountService = accountService;
|
||||
_mimeFileService = mimeFileService;
|
||||
}
|
||||
|
||||
public async Task ChangeStickyStatusAsync(Guid folderId, bool isSticky)
|
||||
@@ -149,10 +145,10 @@ namespace Wino.Core.Services
|
||||
}
|
||||
else if (account.ProviderType == MailProviderType.Outlook || account.ProviderType == MailProviderType.Office365)
|
||||
{
|
||||
bool belongsToExistingParent = (await Connection
|
||||
bool belongsToExistingParent = await Connection
|
||||
.Table<MailItemFolder>()
|
||||
.Where(a => unstickyItem.ParentRemoteFolderId == a.RemoteFolderId)
|
||||
.CountAsync()) > 0;
|
||||
.CountAsync() > 0;
|
||||
|
||||
// No need to include this as unsticky.
|
||||
if (belongsToExistingParent) continue;
|
||||
@@ -236,14 +232,14 @@ namespace Wino.Core.Services
|
||||
foreach (var item in listingFolders)
|
||||
{
|
||||
// Category type folders should be skipped. They will be categorized under virtual category folder.
|
||||
if (GoogleIntegratorExtensions.SubCategoryFolderLabelIds.Contains(item.RemoteFolderId)) continue;
|
||||
if (ServiceConstants.SubCategoryFolderLabelIds.Contains(item.RemoteFolderId)) continue;
|
||||
|
||||
bool skipEmptyParentRemoteFolders = mailAccount.ProviderType == MailProviderType.Gmail;
|
||||
|
||||
if (skipEmptyParentRemoteFolders && !string.IsNullOrEmpty(item.ParentRemoteFolderId)) continue;
|
||||
|
||||
// Sticky items belong to account menu item directly. Rest goes to More folder.
|
||||
IMenuItem parentFolderMenuItem = item.IsSticky ? accountMenuItem : (GoogleIntegratorExtensions.SubCategoryFolderLabelIds.Contains(item.FolderName.ToUpper()) ? categoryFolderMenuItem : moreFolderMenuItem);
|
||||
IMenuItem parentFolderMenuItem = item.IsSticky ? accountMenuItem : ServiceConstants.SubCategoryFolderLabelIds.Contains(item.FolderName.ToUpper()) ? categoryFolderMenuItem : moreFolderMenuItem;
|
||||
|
||||
var preparedItem = await GetPreparedFolderMenuItemRecursiveAsync(mailAccount, item, parentFolderMenuItem).ConfigureAwait(false);
|
||||
|
||||
@@ -665,9 +661,9 @@ namespace Wino.Core.Services
|
||||
}
|
||||
|
||||
public async Task<bool> IsInboxAvailableForAccountAsync(Guid accountId)
|
||||
=> (await Connection.Table<MailItemFolder>()
|
||||
=> await Connection.Table<MailItemFolder>()
|
||||
.Where(a => a.SpecialFolderType == SpecialFolderType.Inbox && a.MailAccountId == accountId)
|
||||
.CountAsync()) == 1;
|
||||
.CountAsync() == 1;
|
||||
|
||||
public Task UpdateFolderLastSyncDateAsync(Guid folderId)
|
||||
=> Connection.ExecuteAsync("UPDATE MailItemFolder SET LastSynchronizedDate = ? WHERE Id = ?", DateTime.UtcNow, folderId);
|
||||
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 Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class LogInitializer : ILogInitializer
|
||||
{
|
||||
@@ -3,9 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Kiota.Abstractions.Extensions;
|
||||
using MimeKit;
|
||||
using MoreLinq;
|
||||
using Serilog;
|
||||
using SqlKata;
|
||||
using Wino.Core.Domain;
|
||||
@@ -17,10 +15,10 @@ using Wino.Core.Domain.Extensions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Comparers;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public class MailService : BaseDatabaseService, IMailService
|
||||
{
|
||||
@@ -285,7 +283,10 @@ namespace Wino.Core.Services
|
||||
if (!isFolderCached)
|
||||
{
|
||||
folderAssignment = await _folderService.GetFolderAsync(mailCopy.FolderId).ConfigureAwait(false);
|
||||
_ = folderCache.TryAdd(mailCopy.FolderId, folderAssignment);
|
||||
if (!folderCache.ContainsKey(mailCopy.FolderId))
|
||||
{
|
||||
folderCache.Add(mailCopy.FolderId, folderAssignment);
|
||||
}
|
||||
}
|
||||
|
||||
if (folderAssignment != null)
|
||||
@@ -294,8 +295,11 @@ namespace Wino.Core.Services
|
||||
if (!isAccountCached)
|
||||
{
|
||||
accountAssignment = await _accountService.GetAccountAsync(folderAssignment.MailAccountId).ConfigureAwait(false);
|
||||
_ = accountCache.TryAdd(folderAssignment.MailAccountId, accountAssignment);
|
||||
|
||||
if (!accountCache.ContainsKey(folderAssignment.MailAccountId))
|
||||
{
|
||||
accountCache.Add(folderAssignment.MailAccountId, accountAssignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +315,10 @@ namespace Wino.Core.Services
|
||||
|
||||
if (contactAssignment != null)
|
||||
{
|
||||
_ = contactCache.TryAdd(mailCopy.FromAddress, contactAssignment);
|
||||
if (!contactCache.ContainsKey(mailCopy.FromAddress))
|
||||
{
|
||||
contactCache.Add(mailCopy.FromAddress, contactAssignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,7 +735,8 @@ namespace Wino.Core.Services
|
||||
_ => CreateReferencedDraft(builder, message, draftCreationOptions, account, signature),
|
||||
};
|
||||
|
||||
builder.SetHtmlBody(builder.HtmlBody);
|
||||
// TODO: Migration
|
||||
// builder.SetHtmlBody(builder.HtmlBody);
|
||||
|
||||
message.Body = builder.ToMessageBody();
|
||||
|
||||
@@ -8,72 +8,10 @@ using Serilog;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Reader;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Mime;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
public interface IMimeFileService
|
||||
{
|
||||
/// <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
|
||||
{
|
||||
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.Interfaces;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
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.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Threading
|
||||
namespace Wino.Services.Threading
|
||||
{
|
||||
public class APIThreadingStrategy : IThreadingStrategy
|
||||
{
|
||||
@@ -1,9 +1,8 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Threading
|
||||
namespace Wino.Services.Threading
|
||||
{
|
||||
public class GmailThreadingStrategy : APIThreadingStrategy
|
||||
public class GmailThreadingStrategy : APIThreadingStrategy, IGmailThreadingStrategy
|
||||
{
|
||||
public GmailThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { }
|
||||
}
|
||||
@@ -4,22 +4,20 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SqlKata;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Services;
|
||||
using Wino.Services.Extensions;
|
||||
|
||||
namespace Wino.Core.Integration.Threading
|
||||
namespace Wino.Services.Threading
|
||||
{
|
||||
public class ImapThreadStrategy : IThreadingStrategy
|
||||
public class ImapThreadingStrategy : BaseDatabaseService, IImapThreadingStrategy
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly IFolderService _folderService;
|
||||
|
||||
public ImapThreadStrategy(IDatabaseService databaseService, IFolderService folderService)
|
||||
public ImapThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_folderService = folderService;
|
||||
}
|
||||
|
||||
@@ -37,7 +35,7 @@ namespace Wino.Core.Integration.Threading
|
||||
.WhereNot("MailCopy.Id", replyItem.Id)
|
||||
.Select("MailCopy.*");
|
||||
|
||||
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||
return Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
return _databaseService.Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||
return Connection.FindWithQueryAsync<MailCopy>(query.GetRawQuery());
|
||||
}
|
||||
|
||||
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))
|
||||
mailLookupTable.Add(mail.Id, false);
|
||||
|
||||
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Sent);
|
||||
var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, Domain.Enums.SpecialFolderType.Draft);
|
||||
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Sent);
|
||||
var draftFolder = await _folderService.GetSpecialFolderByAccountIdAsync(accountId, SpecialFolderType.Draft);
|
||||
|
||||
// Threading is not possible. Return items as it is.
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Services;
|
||||
|
||||
namespace Wino.Core.Integration.Threading
|
||||
namespace Wino.Services.Threading
|
||||
{
|
||||
// Outlook and Gmail is using the same threading strategy.
|
||||
// Outlook: ConversationId -> it's set as ThreadId
|
||||
// Gmail: ThreadId
|
||||
|
||||
public class OutlookThreadingStrategy : APIThreadingStrategy
|
||||
public class OutlookThreadingStrategy : APIThreadingStrategy, IOutlookThreadingStrategy
|
||||
{
|
||||
public OutlookThreadingStrategy(IDatabaseService databaseService, IFolderService folderService) : base(databaseService, folderService) { }
|
||||
}
|
||||
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.Messaging.Client.Shell;
|
||||
|
||||
namespace Wino.Core.Services
|
||||
namespace Wino.Services
|
||||
{
|
||||
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
|
||||
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Wino.Calendar.Packaging", "Wino.Calendar.Packaging\Wino.Calendar.Packaging.wapproj", "{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wino.Services", "Wino.Services\Wino.Services.csproj", "{4000A374-59FE-4400-ACF6-D40473BECD73}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -392,6 +394,26 @@ Global
|
||||
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.ActiveCfg = Release|x86
|
||||
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Build.0 = Release|x86
|
||||
{7485B18C-F5AB-4ABE-BA7F-05B6623C67C8}.Release|x86.Deploy.0 = Release|x86
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -407,6 +429,7 @@ Global
|
||||
{53723AE8-7E7E-4D54-ADAB-0A6033255CC8} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||
{039AFFA8-C1CC-4E3B-8A31-6814D7557F74} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||
{A4DBA01A-F315-49E0-8428-BB99D32B20F9} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||
{4000A374-59FE-4400-ACF6-D40473BECD73} = {17FF5FAE-F1AC-4572-BAA3-8B86F01EA758}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {721F946E-F69F-4987-823A-D084B436FC1E}
|
||||
|
||||
Reference in New Issue
Block a user