@@ -149,7 +149,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,static,exter
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_style_namespace_declarations = file_scoped:error
|
||||
csharp_style_namespace_declarations = block_scoped:silent
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
@@ -287,6 +287,4 @@ csharp_style_prefer_top_level_statements = true:silent
|
||||
csharp_style_prefer_utf8_string_literals = true:suggestion
|
||||
csharp_style_prefer_readonly_struct = true:suggestion
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
|
||||
csharp_style_prefer_primary_constructors = true:silent
|
||||
csharp_prefer_system_threading_lock = true:suggestion
|
||||
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
|
||||
@@ -1,16 +1,17 @@
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Authentication;
|
||||
|
||||
public abstract class BaseAuthenticator
|
||||
namespace Wino.Authentication
|
||||
{
|
||||
public abstract MailProviderType ProviderType { get; }
|
||||
protected IAuthenticatorConfig AuthenticatorConfig { get; }
|
||||
|
||||
protected BaseAuthenticator(IAuthenticatorConfig authenticatorConfig)
|
||||
public abstract class BaseAuthenticator
|
||||
{
|
||||
public abstract MailProviderType ProviderType { get; }
|
||||
protected IAuthenticatorConfig AuthenticatorConfig { get; }
|
||||
|
||||
AuthenticatorConfig = authenticatorConfig;
|
||||
protected BaseAuthenticator(IAuthenticatorConfig authenticatorConfig)
|
||||
{
|
||||
|
||||
AuthenticatorConfig = authenticatorConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,44 +7,45 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Authentication;
|
||||
|
||||
namespace Wino.Authentication;
|
||||
|
||||
public class GmailAuthenticator : BaseAuthenticator, IGmailAuthenticator
|
||||
namespace Wino.Authentication
|
||||
{
|
||||
public GmailAuthenticator(IAuthenticatorConfig authConfig) : base(authConfig)
|
||||
public class GmailAuthenticator : BaseAuthenticator, IGmailAuthenticator
|
||||
{
|
||||
}
|
||||
|
||||
public string ClientId => AuthenticatorConfig.GmailAuthenticatorClientId;
|
||||
public bool ProposeCopyAuthURL { get; set; }
|
||||
|
||||
public override MailProviderType ProviderType => MailProviderType.Gmail;
|
||||
|
||||
/// <summary>
|
||||
/// Generates the token information for the given account.
|
||||
/// For gmail, interactivity is automatically handled when you get the token.
|
||||
/// </summary>
|
||||
/// <param name="account">Account to get token for.</param>
|
||||
public Task<TokenInformationEx> GenerateTokenInformationAsync(MailAccount account)
|
||||
=> GetTokenInformationAsync(account);
|
||||
|
||||
public async Task<TokenInformationEx> GetTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
var userCredential = await GetGoogleUserCredentialAsync(account);
|
||||
|
||||
if (userCredential.Token.IsStale)
|
||||
public GmailAuthenticator(IAuthenticatorConfig authConfig) : base(authConfig)
|
||||
{
|
||||
await userCredential.RefreshTokenAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
return new TokenInformationEx(userCredential.Token.AccessToken, account.Address);
|
||||
}
|
||||
public string ClientId => AuthenticatorConfig.GmailAuthenticatorClientId;
|
||||
public bool ProposeCopyAuthURL { get; set; }
|
||||
|
||||
private Task<UserCredential> GetGoogleUserCredentialAsync(MailAccount account)
|
||||
{
|
||||
return GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets()
|
||||
public override MailProviderType ProviderType => MailProviderType.Gmail;
|
||||
|
||||
/// <summary>
|
||||
/// Generates the token information for the given account.
|
||||
/// For gmail, interactivity is automatically handled when you get the token.
|
||||
/// </summary>
|
||||
/// <param name="account">Account to get token for.</param>
|
||||
public Task<TokenInformationEx> GenerateTokenInformationAsync(MailAccount account)
|
||||
=> GetTokenInformationAsync(account);
|
||||
|
||||
public async Task<TokenInformationEx> GetTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
ClientId = ClientId
|
||||
}, AuthenticatorConfig.GmailScope, account.Id.ToString(), CancellationToken.None, new FileDataStore(AuthenticatorConfig.GmailTokenStoreIdentifier));
|
||||
var userCredential = await GetGoogleUserCredentialAsync(account);
|
||||
|
||||
if (userCredential.Token.IsStale)
|
||||
{
|
||||
await userCredential.RefreshTokenAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
return new TokenInformationEx(userCredential.Token.AccessToken, account.Address);
|
||||
}
|
||||
|
||||
private Task<UserCredential> GetGoogleUserCredentialAsync(MailAccount account)
|
||||
{
|
||||
return GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets()
|
||||
{
|
||||
ClientId = ClientId
|
||||
}, AuthenticatorConfig.GmailScope, account.Id.ToString(), CancellationToken.None, new FileDataStore(AuthenticatorConfig.GmailTokenStoreIdentifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,115 +11,116 @@ using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Authentication;
|
||||
|
||||
namespace Wino.Authentication;
|
||||
|
||||
public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator
|
||||
namespace Wino.Authentication
|
||||
{
|
||||
private const string TokenCacheFileName = "OutlookCache.bin";
|
||||
private bool isTokenCacheAttached = false;
|
||||
|
||||
// Outlook
|
||||
private const string Authority = "https://login.microsoftonline.com/common";
|
||||
|
||||
public override MailProviderType ProviderType => MailProviderType.Outlook;
|
||||
|
||||
private readonly IPublicClientApplication _publicClientApplication;
|
||||
private readonly IApplicationConfiguration _applicationConfiguration;
|
||||
|
||||
public OutlookAuthenticator(INativeAppService nativeAppService,
|
||||
IApplicationConfiguration applicationConfiguration,
|
||||
IAuthenticatorConfig authenticatorConfig) : base(authenticatorConfig)
|
||||
public class OutlookAuthenticator : BaseAuthenticator, IOutlookAuthenticator
|
||||
{
|
||||
_applicationConfiguration = applicationConfiguration;
|
||||
private const string TokenCacheFileName = "OutlookCache.bin";
|
||||
private bool isTokenCacheAttached = false;
|
||||
|
||||
var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri();
|
||||
// Outlook
|
||||
private const string Authority = "https://login.microsoftonline.com/common";
|
||||
|
||||
var options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows)
|
||||
public override MailProviderType ProviderType => MailProviderType.Outlook;
|
||||
|
||||
private readonly IPublicClientApplication _publicClientApplication;
|
||||
private readonly IApplicationConfiguration _applicationConfiguration;
|
||||
|
||||
public OutlookAuthenticator(INativeAppService nativeAppService,
|
||||
IApplicationConfiguration applicationConfiguration,
|
||||
IAuthenticatorConfig authenticatorConfig) : base(authenticatorConfig)
|
||||
{
|
||||
Title = "Wino Mail",
|
||||
ListOperatingSystemAccounts = true,
|
||||
};
|
||||
_applicationConfiguration = applicationConfiguration;
|
||||
|
||||
var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId)
|
||||
.WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd)
|
||||
.WithBroker(options)
|
||||
.WithDefaultRedirectUri()
|
||||
.WithAuthority(Authority);
|
||||
var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri();
|
||||
|
||||
_publicClientApplication = outlookAppBuilder.Build();
|
||||
}
|
||||
var options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows)
|
||||
{
|
||||
Title = "Wino Mail",
|
||||
ListOperatingSystemAccounts = true,
|
||||
};
|
||||
|
||||
public string[] Scope => AuthenticatorConfig.OutlookScope;
|
||||
var outlookAppBuilder = PublicClientApplicationBuilder.Create(AuthenticatorConfig.OutlookAuthenticatorClientId)
|
||||
.WithParentActivityOrWindow(nativeAppService.GetCoreWindowHwnd)
|
||||
.WithBroker(options)
|
||||
.WithDefaultRedirectUri()
|
||||
.WithAuthority(Authority);
|
||||
|
||||
private async Task EnsureTokenCacheAttachedAsync()
|
||||
{
|
||||
if (!isTokenCacheAttached)
|
||||
{
|
||||
var storageProperties = new StorageCreationPropertiesBuilder(TokenCacheFileName, _applicationConfiguration.PublisherSharedFolderPath).Build();
|
||||
var msalcachehelper = await MsalCacheHelper.CreateAsync(storageProperties);
|
||||
msalcachehelper.RegisterCache(_publicClientApplication.UserTokenCache);
|
||||
|
||||
isTokenCacheAttached = true;
|
||||
_publicClientApplication = outlookAppBuilder.Build();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<TokenInformationEx> GetTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
await EnsureTokenCacheAttachedAsync();
|
||||
public string[] Scope => AuthenticatorConfig.OutlookScope;
|
||||
|
||||
var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(a => a.Username == account.Address);
|
||||
|
||||
if (storedAccount == null)
|
||||
return await GenerateTokenInformationAsync(account);
|
||||
|
||||
try
|
||||
private async Task EnsureTokenCacheAttachedAsync()
|
||||
{
|
||||
var authResult = await _publicClientApplication.AcquireTokenSilent(Scope, storedAccount).ExecuteAsync();
|
||||
if (!isTokenCacheAttached)
|
||||
{
|
||||
var storageProperties = new StorageCreationPropertiesBuilder(TokenCacheFileName, _applicationConfiguration.PublisherSharedFolderPath).Build();
|
||||
var msalcachehelper = await MsalCacheHelper.CreateAsync(storageProperties);
|
||||
msalcachehelper.RegisterCache(_publicClientApplication.UserTokenCache);
|
||||
|
||||
return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username);
|
||||
isTokenCacheAttached = true;
|
||||
}
|
||||
}
|
||||
catch (MsalUiRequiredException)
|
||||
{
|
||||
// Somehow MSAL is not able to refresh the token silently.
|
||||
// Force interactive login.
|
||||
|
||||
return await GenerateTokenInformationAsync(account);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<TokenInformationEx> GenerateTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
try
|
||||
public async Task<TokenInformationEx> GetTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
await EnsureTokenCacheAttachedAsync();
|
||||
|
||||
var authResult = await _publicClientApplication
|
||||
.AcquireTokenInteractive(Scope)
|
||||
.ExecuteAsync();
|
||||
var storedAccount = (await _publicClientApplication.GetAccountsAsync()).FirstOrDefault(a => a.Username == account.Address);
|
||||
|
||||
// If the account is null, it means it's the initial creation of it.
|
||||
// If not, make sure the authenticated user address matches the username.
|
||||
// When people refresh their token, accounts must match.
|
||||
if (storedAccount == null)
|
||||
return await GenerateTokenInformationAsync(account);
|
||||
|
||||
if (account?.Address != null && !account.Address.Equals(authResult.Account.Username, StringComparison.OrdinalIgnoreCase))
|
||||
try
|
||||
{
|
||||
throw new AuthenticationException("Authenticated address does not match with your account address.");
|
||||
var authResult = await _publicClientApplication.AcquireTokenSilent(Scope, storedAccount).ExecuteAsync();
|
||||
|
||||
return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username);
|
||||
}
|
||||
catch (MsalUiRequiredException)
|
||||
{
|
||||
// Somehow MSAL is not able to refresh the token silently.
|
||||
// Force interactive login.
|
||||
|
||||
return await GenerateTokenInformationAsync(account);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<TokenInformationEx> GenerateTokenInformationAsync(MailAccount account)
|
||||
{
|
||||
try
|
||||
{
|
||||
await EnsureTokenCacheAttachedAsync();
|
||||
|
||||
var authResult = await _publicClientApplication
|
||||
.AcquireTokenInteractive(Scope)
|
||||
.ExecuteAsync();
|
||||
|
||||
// If the account is null, it means it's the initial creation of it.
|
||||
// If not, make sure the authenticated user address matches the username.
|
||||
// When people refresh their token, accounts must match.
|
||||
|
||||
if (account?.Address != null && !account.Address.Equals(authResult.Account.Username, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new AuthenticationException("Authenticated address does not match with your account address.");
|
||||
}
|
||||
|
||||
return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username);
|
||||
}
|
||||
catch (MsalClientException msalClientException)
|
||||
{
|
||||
if (msalClientException.ErrorCode == "authentication_canceled" || msalClientException.ErrorCode == "access_denied")
|
||||
throw new AccountSetupCanceledException();
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return new TokenInformationEx(authResult.AccessToken, authResult.Account.Username);
|
||||
throw new AuthenticationException(Translator.Exception_UnknowErrorDuringAuthentication, new Exception(Translator.Exception_TokenGenerationFailed));
|
||||
}
|
||||
catch (MsalClientException msalClientException)
|
||||
{
|
||||
if (msalClientException.ErrorCode == "authentication_canceled" || msalClientException.ErrorCode == "access_denied")
|
||||
throw new AccountSetupCanceledException();
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
throw new AuthenticationException(Translator.Exception_UnknowErrorDuringAuthentication, new Exception(Translator.Exception_TokenGenerationFailed));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Calendar.Services;
|
||||
|
||||
public class CalendarAuthenticatorConfig : IAuthenticatorConfig
|
||||
namespace Wino.Calendar.Services
|
||||
{
|
||||
public string OutlookAuthenticatorClientId => "b19c2035-d740-49ff-b297-de6ec561b208";
|
||||
|
||||
public string[] OutlookScope => new string[]
|
||||
public class CalendarAuthenticatorConfig : IAuthenticatorConfig
|
||||
{
|
||||
"Calendars.Read",
|
||||
"Calendars.Read.Shared",
|
||||
"offline_access",
|
||||
"Calendars.ReadBasic",
|
||||
"Calendars.ReadWrite",
|
||||
"Calendars.ReadWrite.Shared",
|
||||
"User.Read"
|
||||
};
|
||||
public string OutlookAuthenticatorClientId => "b19c2035-d740-49ff-b297-de6ec561b208";
|
||||
|
||||
public string GmailAuthenticatorClientId => "973025879644-s7b4ur9p3rlgop6a22u7iuptdc0brnrn.apps.googleusercontent.com";
|
||||
public string[] OutlookScope => new string[]
|
||||
{
|
||||
"Calendars.Read",
|
||||
"Calendars.Read.Shared",
|
||||
"offline_access",
|
||||
"Calendars.ReadBasic",
|
||||
"Calendars.ReadWrite",
|
||||
"Calendars.ReadWrite.Shared",
|
||||
"User.Read"
|
||||
};
|
||||
|
||||
public string[] GmailScope => new string[]
|
||||
{
|
||||
"https://www.googleapis.com/auth/calendar",
|
||||
"https://www.googleapis.com/auth/calendar.events",
|
||||
"https://www.googleapis.com/auth/calendar.settings.readonly",
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"
|
||||
};
|
||||
public string GmailAuthenticatorClientId => "973025879644-s7b4ur9p3rlgop6a22u7iuptdc0brnrn.apps.googleusercontent.com";
|
||||
|
||||
public string GmailTokenStoreIdentifier => "WinoCalendarGmailTokenStore";
|
||||
public string[] GmailScope => new string[]
|
||||
{
|
||||
"https://www.googleapis.com/auth/calendar",
|
||||
"https://www.googleapis.com/auth/calendar.events",
|
||||
"https://www.googleapis.com/auth/calendar.settings.readonly",
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"
|
||||
};
|
||||
|
||||
public string GmailTokenStoreIdentifier => "WinoCalendarGmailTokenStore";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,149 +7,150 @@ using Wino.Core.Domain.Entities.Calendar;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
namespace Wino.Core.Domain.Collections;
|
||||
|
||||
public class CalendarEventCollection
|
||||
namespace Wino.Core.Domain.Collections
|
||||
{
|
||||
public event EventHandler<ICalendarItem> CalendarItemAdded;
|
||||
public event EventHandler<ICalendarItem> CalendarItemRemoved;
|
||||
|
||||
public event EventHandler CalendarItemsCleared;
|
||||
|
||||
private ObservableRangeCollection<ICalendarItem> _internalRegularEvents = [];
|
||||
private ObservableRangeCollection<ICalendarItem> _internalAllDayEvents = [];
|
||||
|
||||
public ReadOnlyObservableCollection<ICalendarItem> RegularEvents { get; }
|
||||
public ReadOnlyObservableCollection<ICalendarItem> AllDayEvents { get; } // TODO: Rename this to include multi-day events.
|
||||
public ITimePeriod Period { get; }
|
||||
public CalendarSettings Settings { get; }
|
||||
|
||||
private readonly List<ICalendarItem> _allItems = new List<ICalendarItem>();
|
||||
|
||||
public CalendarEventCollection(ITimePeriod period, CalendarSettings settings)
|
||||
public class CalendarEventCollection
|
||||
{
|
||||
Period = period;
|
||||
Settings = settings;
|
||||
public event EventHandler<ICalendarItem> CalendarItemAdded;
|
||||
public event EventHandler<ICalendarItem> CalendarItemRemoved;
|
||||
|
||||
RegularEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalRegularEvents);
|
||||
AllDayEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalAllDayEvents);
|
||||
}
|
||||
public event EventHandler CalendarItemsCleared;
|
||||
|
||||
public bool HasCalendarEvent(AccountCalendar accountCalendar)
|
||||
=> _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
|
||||
private ObservableRangeCollection<ICalendarItem> _internalRegularEvents = [];
|
||||
private ObservableRangeCollection<ICalendarItem> _internalAllDayEvents = [];
|
||||
|
||||
public ICalendarItem GetCalendarItem(Guid calendarItemId)
|
||||
{
|
||||
return _allItems.FirstOrDefault(x => x.Id == calendarItemId);
|
||||
}
|
||||
public ReadOnlyObservableCollection<ICalendarItem> RegularEvents { get; }
|
||||
public ReadOnlyObservableCollection<ICalendarItem> AllDayEvents { get; } // TODO: Rename this to include multi-day events.
|
||||
public ITimePeriod Period { get; }
|
||||
public CalendarSettings Settings { get; }
|
||||
|
||||
public void ClearSelectionStates()
|
||||
{
|
||||
foreach (var item in _allItems)
|
||||
private readonly List<ICalendarItem> _allItems = new List<ICalendarItem>();
|
||||
|
||||
public CalendarEventCollection(ITimePeriod period, CalendarSettings settings)
|
||||
{
|
||||
if (item is ICalendarItemViewModel calendarItemViewModel)
|
||||
Period = period;
|
||||
Settings = settings;
|
||||
|
||||
RegularEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalRegularEvents);
|
||||
AllDayEvents = new ReadOnlyObservableCollection<ICalendarItem>(_internalAllDayEvents);
|
||||
}
|
||||
|
||||
public bool HasCalendarEvent(AccountCalendar accountCalendar)
|
||||
=> _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
|
||||
|
||||
public ICalendarItem GetCalendarItem(Guid calendarItemId)
|
||||
{
|
||||
return _allItems.FirstOrDefault(x => x.Id == calendarItemId);
|
||||
}
|
||||
|
||||
public void ClearSelectionStates()
|
||||
{
|
||||
foreach (var item in _allItems)
|
||||
{
|
||||
calendarItemViewModel.IsSelected = false;
|
||||
if (item is ICalendarItemViewModel calendarItemViewModel)
|
||||
{
|
||||
calendarItemViewModel.IsSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void FilterByCalendars(IEnumerable<Guid> visibleCalendarIds)
|
||||
{
|
||||
foreach (var item in _allItems)
|
||||
public void FilterByCalendars(IEnumerable<Guid> visibleCalendarIds)
|
||||
{
|
||||
var collections = GetProperCollectionsForCalendarItem(item);
|
||||
foreach (var item in _allItems)
|
||||
{
|
||||
var collections = GetProperCollectionsForCalendarItem(item);
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
if (!visibleCalendarIds.Contains(item.AssignedCalendar.Id) && collection.Contains(item))
|
||||
{
|
||||
RemoveCalendarItemInternal(collection, item, false);
|
||||
}
|
||||
else if (visibleCalendarIds.Contains(item.AssignedCalendar.Id) && !collection.Contains(item))
|
||||
{
|
||||
AddCalendarItemInternal(collection, item, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ObservableRangeCollection<ICalendarItem>> GetProperCollectionsForCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
// All-day events go to all days.
|
||||
// Multi-day events go to both.
|
||||
// Anything else goes to regular.
|
||||
|
||||
if (calendarItem.IsAllDayEvent)
|
||||
{
|
||||
return [_internalAllDayEvents];
|
||||
}
|
||||
else if (calendarItem.IsMultiDayEvent)
|
||||
{
|
||||
return [_internalRegularEvents, _internalAllDayEvents];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [_internalRegularEvents];
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
var collections = GetProperCollectionsForCalendarItem(calendarItem);
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
if (!visibleCalendarIds.Contains(item.AssignedCalendar.Id) && collection.Contains(item))
|
||||
{
|
||||
RemoveCalendarItemInternal(collection, item, false);
|
||||
}
|
||||
else if (visibleCalendarIds.Contains(item.AssignedCalendar.Id) && !collection.Contains(item))
|
||||
{
|
||||
AddCalendarItemInternal(collection, item, false);
|
||||
}
|
||||
AddCalendarItemInternal(collection, calendarItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ObservableRangeCollection<ICalendarItem>> GetProperCollectionsForCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
// All-day events go to all days.
|
||||
// Multi-day events go to both.
|
||||
// Anything else goes to regular.
|
||||
|
||||
if (calendarItem.IsAllDayEvent)
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
return [_internalAllDayEvents];
|
||||
}
|
||||
else if (calendarItem.IsMultiDayEvent)
|
||||
{
|
||||
return [_internalRegularEvents, _internalAllDayEvents];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [_internalRegularEvents];
|
||||
}
|
||||
}
|
||||
var collections = GetProperCollectionsForCalendarItem(calendarItem);
|
||||
|
||||
public void AddCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
var collections = GetProperCollectionsForCalendarItem(calendarItem);
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
AddCalendarItemInternal(collection, calendarItem);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
var collections = GetProperCollectionsForCalendarItem(calendarItem);
|
||||
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
RemoveCalendarItemInternal(collection, calendarItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool create = true)
|
||||
{
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
|
||||
collection.Add(calendarItem);
|
||||
|
||||
if (create)
|
||||
{
|
||||
_allItems.Add(calendarItem);
|
||||
foreach (var collection in collections)
|
||||
{
|
||||
RemoveCalendarItemInternal(collection, calendarItem);
|
||||
}
|
||||
}
|
||||
|
||||
CalendarItemAdded?.Invoke(this, calendarItem);
|
||||
}
|
||||
|
||||
private void RemoveCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool destroy = true)
|
||||
{
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
|
||||
collection.Remove(calendarItem);
|
||||
|
||||
if (destroy)
|
||||
private void AddCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool create = true)
|
||||
{
|
||||
_allItems.Remove(calendarItem);
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
|
||||
collection.Add(calendarItem);
|
||||
|
||||
if (create)
|
||||
{
|
||||
_allItems.Add(calendarItem);
|
||||
}
|
||||
|
||||
CalendarItemAdded?.Invoke(this, calendarItem);
|
||||
}
|
||||
|
||||
CalendarItemRemoved?.Invoke(this, calendarItem);
|
||||
}
|
||||
private void RemoveCalendarItemInternal(ObservableRangeCollection<ICalendarItem> collection, ICalendarItem calendarItem, bool destroy = true)
|
||||
{
|
||||
if (calendarItem is not ICalendarItemViewModel)
|
||||
throw new ArgumentException("CalendarItem must be of type ICalendarItemViewModel", nameof(calendarItem));
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_internalAllDayEvents.Clear();
|
||||
_internalRegularEvents.Clear();
|
||||
_allItems.Clear();
|
||||
collection.Remove(calendarItem);
|
||||
|
||||
CalendarItemsCleared?.Invoke(this, EventArgs.Empty);
|
||||
if (destroy)
|
||||
{
|
||||
_allItems.Remove(calendarItem);
|
||||
}
|
||||
|
||||
CalendarItemRemoved?.Invoke(this, calendarItem);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_internalAllDayEvents.Clear();
|
||||
_internalRegularEvents.Clear();
|
||||
_allItems.Clear();
|
||||
|
||||
CalendarItemsCleared?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,40 +2,41 @@
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
namespace Wino.Core.Domain.Collections;
|
||||
|
||||
public class DayRangeCollection : ObservableRangeCollection<DayRangeRenderModel>
|
||||
namespace Wino.Core.Domain.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the range of dates that are currently displayed in the collection.
|
||||
/// </summary>
|
||||
public DateRange DisplayRange
|
||||
public class DayRangeCollection : ObservableRangeCollection<DayRangeRenderModel>
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Gets the range of dates that are currently displayed in the collection.
|
||||
/// </summary>
|
||||
public DateRange DisplayRange
|
||||
{
|
||||
if (Count == 0) return null;
|
||||
get
|
||||
{
|
||||
if (Count == 0) return null;
|
||||
|
||||
var minimumLoadedDate = this[0].CalendarRenderOptions.DateRange.StartDate;
|
||||
var maximumLoadedDate = this[Count - 1].CalendarRenderOptions.DateRange.EndDate;
|
||||
var minimumLoadedDate = this[0].CalendarRenderOptions.DateRange.StartDate;
|
||||
var maximumLoadedDate = this[Count - 1].CalendarRenderOptions.DateRange.EndDate;
|
||||
|
||||
return new DateRange(minimumLoadedDate, maximumLoadedDate);
|
||||
return new DateRange(minimumLoadedDate, maximumLoadedDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
foreach (var dayRange in this)
|
||||
public void RemoveCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
foreach (var dayRange in this)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
foreach (var dayRange in this)
|
||||
public void AddCalendarItem(ICalendarItem calendarItem)
|
||||
{
|
||||
var calendarDayModel = dayRange.CalendarDays.FirstOrDefault(x => x.Period.HasInside(calendarItem.Period.Start));
|
||||
calendarDayModel?.EventsCollection.AddCalendarItem(calendarItem);
|
||||
foreach (var dayRange in this)
|
||||
{
|
||||
var calendarDayModel = dayRange.CalendarDays.FirstOrDefault(x => x.Period.HasInside(calendarItem.Period.Start));
|
||||
calendarDayModel?.EventsCollection.AddCalendarItem(calendarItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,170 +4,171 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ObservableRangeCollection<T> : ObservableCollection<T>
|
||||
namespace Wino.Core.Domain.Collections
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
|
||||
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
|
||||
/// </summary>
|
||||
public ObservableRangeCollection()
|
||||
: base()
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ObservableRangeCollection<T> : ObservableCollection<T>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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="ArgumentNullException">The collection parameter cannot be null.</exception>
|
||||
public ObservableRangeCollection(IEnumerable<T> collection)
|
||||
: base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
|
||||
/// </summary>
|
||||
public void AddRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset)
|
||||
throw new ArgumentException("Mode must be either Add or Reset for AddRange.", nameof(notificationMode));
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
var startIndex = Count;
|
||||
|
||||
var itemsAdded = AddArrangeCore(collection);
|
||||
|
||||
if (!itemsAdded)
|
||||
return;
|
||||
|
||||
if (notificationMode == NotifyCollectionChangedAction.Reset)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
|
||||
/// </summary>
|
||||
public ObservableRangeCollection()
|
||||
: base()
|
||||
{
|
||||
RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var changedItems = collection is List<T> ? (List<T>)collection : new List<T>(collection);
|
||||
|
||||
RaiseChangeNotificationEvents(
|
||||
action: NotifyCollectionChangedAction.Add,
|
||||
changedItems: changedItems,
|
||||
startingIndex: startIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive.
|
||||
/// </summary>
|
||||
public void RemoveRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset)
|
||||
throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", nameof(notificationMode));
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
if (notificationMode == NotifyCollectionChangedAction.Reset)
|
||||
/// <summary>
|
||||
/// 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="ArgumentNullException">The collection parameter cannot be null.</exception>
|
||||
public ObservableRangeCollection(IEnumerable<T> collection)
|
||||
: base(collection)
|
||||
{
|
||||
var raiseEvents = false;
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Items.Remove(item);
|
||||
raiseEvents = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
/// <summary>
|
||||
/// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
|
||||
/// </summary>
|
||||
public void AddRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset)
|
||||
throw new ArgumentException("Mode must be either Add or Reset for AddRange.", nameof(notificationMode));
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
var startIndex = Count;
|
||||
|
||||
var itemsAdded = AddArrangeCore(collection);
|
||||
|
||||
if (!itemsAdded)
|
||||
return;
|
||||
|
||||
if (notificationMode == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var changedItems = new List<T>(collection);
|
||||
for (var i = 0; i < changedItems.Count; i++)
|
||||
{
|
||||
if (!Items.Remove(changedItems[i]))
|
||||
{
|
||||
changedItems.RemoveAt(i); //Can't use a foreach because changedItems is intended to be (carefully) modified
|
||||
i--;
|
||||
return;
|
||||
}
|
||||
|
||||
var changedItems = collection is List<T> ? (List<T>)collection : new List<T>(collection);
|
||||
|
||||
RaiseChangeNotificationEvents(
|
||||
action: NotifyCollectionChangedAction.Add,
|
||||
changedItems: changedItems,
|
||||
startingIndex: startIndex);
|
||||
}
|
||||
|
||||
if (changedItems.Count == 0)
|
||||
return;
|
||||
|
||||
RaiseChangeNotificationEvents(
|
||||
action: NotifyCollectionChangedAction.Remove,
|
||||
changedItems: changedItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current collection and replaces it with the specified item.
|
||||
/// </summary>
|
||||
public void Replace(T item) => ReplaceRange(new T[] { item });
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current collection and replaces it with the specified collection.
|
||||
/// </summary>
|
||||
public void ReplaceRange(IEnumerable<T> collection)
|
||||
{
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
var previouslyEmpty = Items.Count == 0;
|
||||
|
||||
Items.Clear();
|
||||
|
||||
AddArrangeCore(collection);
|
||||
|
||||
var currentlyEmpty = Items.Count == 0;
|
||||
|
||||
if (previouslyEmpty && currentlyEmpty)
|
||||
return;
|
||||
|
||||
RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
|
||||
}
|
||||
|
||||
public void InsertRange(IEnumerable<T> items)
|
||||
{
|
||||
CheckReentrancy();
|
||||
|
||||
foreach (var item in items)
|
||||
Items.Insert(0, item);
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
private bool AddArrangeCore(IEnumerable<T> collection)
|
||||
{
|
||||
var itemAdded = false;
|
||||
foreach (var item in collection)
|
||||
/// <summary>
|
||||
/// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive.
|
||||
/// </summary>
|
||||
public void RemoveRange(IEnumerable<T> collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
Items.Add(item);
|
||||
itemAdded = true;
|
||||
if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset)
|
||||
throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", nameof(notificationMode));
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
if (notificationMode == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
var raiseEvents = false;
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Items.Remove(item);
|
||||
raiseEvents = true;
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var changedItems = new List<T>(collection);
|
||||
for (var i = 0; i < changedItems.Count; i++)
|
||||
{
|
||||
if (!Items.Remove(changedItems[i]))
|
||||
{
|
||||
changedItems.RemoveAt(i); //Can't use a foreach because changedItems is intended to be (carefully) modified
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (changedItems.Count == 0)
|
||||
return;
|
||||
|
||||
RaiseChangeNotificationEvents(
|
||||
action: NotifyCollectionChangedAction.Remove,
|
||||
changedItems: changedItems);
|
||||
}
|
||||
return itemAdded;
|
||||
}
|
||||
|
||||
private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List<T> changedItems = null, int startingIndex = -1)
|
||||
{
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
||||
/// <summary>
|
||||
/// Clears the current collection and replaces it with the specified item.
|
||||
/// </summary>
|
||||
public void Replace(T item) => ReplaceRange(new T[] { item });
|
||||
|
||||
if (changedItems is null)
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action));
|
||||
else
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, changedItems: changedItems, startingIndex: startingIndex));
|
||||
/// <summary>
|
||||
/// Clears the current collection and replaces it with the specified collection.
|
||||
/// </summary>
|
||||
public void ReplaceRange(IEnumerable<T> collection)
|
||||
{
|
||||
if (collection == null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
var previouslyEmpty = Items.Count == 0;
|
||||
|
||||
Items.Clear();
|
||||
|
||||
AddArrangeCore(collection);
|
||||
|
||||
var currentlyEmpty = Items.Count == 0;
|
||||
|
||||
if (previouslyEmpty && currentlyEmpty)
|
||||
return;
|
||||
|
||||
RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
|
||||
}
|
||||
|
||||
public void InsertRange(IEnumerable<T> items)
|
||||
{
|
||||
CheckReentrancy();
|
||||
|
||||
foreach (var item in items)
|
||||
Items.Insert(0, item);
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
private bool AddArrangeCore(IEnumerable<T> collection)
|
||||
{
|
||||
var itemAdded = false;
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Items.Add(item);
|
||||
itemAdded = true;
|
||||
}
|
||||
return itemAdded;
|
||||
}
|
||||
|
||||
private void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List<T> changedItems = null, int startingIndex = -1)
|
||||
{
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
||||
|
||||
if (changedItems is null)
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action));
|
||||
else
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, changedItems: changedItems, startingIndex: startingIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
namespace Wino.Core.Domain;
|
||||
|
||||
public static class Constants
|
||||
namespace Wino.Core.Domain
|
||||
{
|
||||
/// <summary>
|
||||
/// MIME header that exists in all the drafts created from Wino.
|
||||
/// </summary>
|
||||
public const string WinoLocalDraftHeader = "X-Wino-Draft-Id";
|
||||
public const string LocalDraftStartPrefix = "localDraft_";
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// MIME header that exists in all the drafts created from Wino.
|
||||
/// </summary>
|
||||
public const string WinoLocalDraftHeader = "X-Wino-Draft-Id";
|
||||
public const string LocalDraftStartPrefix = "localDraft_";
|
||||
|
||||
public const string CalendarEventRecurrenceRuleSeperator = "___";
|
||||
public const string CalendarEventRecurrenceRuleSeperator = "___";
|
||||
|
||||
public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey);
|
||||
public const string ToastActionKey = nameof(ToastActionKey);
|
||||
public const string ToastMailUniqueIdKey = nameof(ToastMailUniqueIdKey);
|
||||
public const string ToastActionKey = nameof(ToastActionKey);
|
||||
|
||||
public const string ClientLogFile = "Client_.log";
|
||||
public const string ServerLogFile = "Server_.log";
|
||||
public const string LogArchiveFileName = "WinoLogs.zip";
|
||||
public const string ClientLogFile = "Client_.log";
|
||||
public const string ServerLogFile = "Server_.log";
|
||||
public const string LogArchiveFileName = "WinoLogs.zip";
|
||||
|
||||
public const string WinoMailIdentiifer = nameof(WinoMailIdentiifer);
|
||||
public const string WinoCalendarIdentifier = nameof(WinoCalendarIdentifier);
|
||||
public const string WinoMailIdentiifer = nameof(WinoMailIdentiifer);
|
||||
public const string WinoCalendarIdentifier = nameof(WinoCalendarIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,24 @@
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
public class AccountCalendar : IAccountCalendar
|
||||
namespace Wino.Core.Domain.Entities.Calendar
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid AccountId { get; set; }
|
||||
public string RemoteCalendarId { get; set; }
|
||||
public string SynchronizationDeltaToken { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
public bool IsExtended { get; set; } = true;
|
||||
public class AccountCalendar : IAccountCalendar
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid AccountId { get; set; }
|
||||
public string RemoteCalendarId { get; set; }
|
||||
public string SynchronizationDeltaToken { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
public bool IsExtended { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Unused for now.
|
||||
/// </summary>
|
||||
public string TextColorHex { get; set; }
|
||||
public string BackgroundColorHex { get; set; }
|
||||
public string TimeZone { get; set; }
|
||||
/// <summary>
|
||||
/// Unused for now.
|
||||
/// </summary>
|
||||
public string TextColorHex { get; set; }
|
||||
public string BackgroundColorHex { get; set; }
|
||||
public string TimeZone { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
// TODO: Connect to Contact store with Wino People.
|
||||
public class CalendarEventAttendee
|
||||
namespace Wino.Core.Domain.Entities.Calendar
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid CalendarItemId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public AttendeeStatus AttendenceStatus { get; set; }
|
||||
public bool IsOrganizer { get; set; }
|
||||
public bool IsOptionalAttendee { get; set; }
|
||||
public string Comment { get; set; }
|
||||
// TODO: Connect to Contact store with Wino People.
|
||||
public class CalendarEventAttendee
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid CalendarItemId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public AttendeeStatus AttendenceStatus { get; set; }
|
||||
public bool IsOrganizer { get; set; }
|
||||
public bool IsOptionalAttendee { get; set; }
|
||||
public string Comment { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,175 +5,176 @@ using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
[DebuggerDisplay("{Title} ({StartDate} - {EndDate})")]
|
||||
public class CalendarItem : ICalendarItem
|
||||
namespace Wino.Core.Domain.Entities.Calendar
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public string RemoteEventId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Location { get; set; }
|
||||
|
||||
public DateTime StartDate { get; set; }
|
||||
|
||||
public DateTime EndDate
|
||||
[DebuggerDisplay("{Title} ({StartDate} - {EndDate})")]
|
||||
public class CalendarItem : ICalendarItem
|
||||
{
|
||||
get
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public string RemoteEventId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Location { get; set; }
|
||||
|
||||
public DateTime StartDate { get; set; }
|
||||
|
||||
public DateTime EndDate
|
||||
{
|
||||
return StartDate.AddSeconds(DurationInSeconds);
|
||||
get
|
||||
{
|
||||
return StartDate.AddSeconds(DurationInSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan StartDateOffset { get; set; }
|
||||
public TimeSpan EndDateOffset { get; set; }
|
||||
public TimeSpan StartDateOffset { get; set; }
|
||||
public TimeSpan EndDateOffset { get; set; }
|
||||
|
||||
private ITimePeriod _period;
|
||||
public ITimePeriod Period
|
||||
{
|
||||
get
|
||||
private ITimePeriod _period;
|
||||
public ITimePeriod Period
|
||||
{
|
||||
_period ??= new TimeRange(StartDate, EndDate);
|
||||
get
|
||||
{
|
||||
_period ??= new TimeRange(StartDate, EndDate);
|
||||
|
||||
return _period;
|
||||
return _period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events that starts at midnight and ends at midnight are considered all-day events.
|
||||
/// </summary>
|
||||
public bool IsAllDayEvent
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Events that starts at midnight and ends at midnight are considered all-day events.
|
||||
/// </summary>
|
||||
public bool IsAllDayEvent
|
||||
{
|
||||
return
|
||||
StartDate.TimeOfDay == TimeSpan.Zero &&
|
||||
EndDate.TimeOfDay == TimeSpan.Zero;
|
||||
get
|
||||
{
|
||||
return
|
||||
StartDate.TimeOfDay == TimeSpan.Zero &&
|
||||
EndDate.TimeOfDay == TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events that are either an exceptional instance of a recurring event or occurrences.
|
||||
/// IsOccurrence is used to display occurrence instances of parent recurring events.
|
||||
/// IsOccurrence == false && IsRecurringChild == true => exceptional single instance.
|
||||
/// </summary>
|
||||
public bool IsRecurringChild
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Events that are either an exceptional instance of a recurring event or occurrences.
|
||||
/// IsOccurrence is used to display occurrence instances of parent recurring events.
|
||||
/// IsOccurrence == false && IsRecurringChild == true => exceptional single instance.
|
||||
/// </summary>
|
||||
public bool IsRecurringChild
|
||||
{
|
||||
return RecurringCalendarItemId != null;
|
||||
get
|
||||
{
|
||||
return RecurringCalendarItemId != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events that are either an exceptional instance of a recurring event or occurrences.
|
||||
/// </summary>
|
||||
public bool IsRecurringEvent => IsRecurringChild || IsRecurringParent;
|
||||
/// <summary>
|
||||
/// Events that are either an exceptional instance of a recurring event or occurrences.
|
||||
/// </summary>
|
||||
public bool IsRecurringEvent => IsRecurringChild || IsRecurringParent;
|
||||
|
||||
/// <summary>
|
||||
/// Events that are the master event definition of recurrence events.
|
||||
/// </summary>
|
||||
public bool IsRecurringParent
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Events that are the master event definition of recurrence events.
|
||||
/// </summary>
|
||||
public bool IsRecurringParent
|
||||
{
|
||||
return !string.IsNullOrEmpty(Recurrence) && RecurringCalendarItemId == null;
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(Recurrence) && RecurringCalendarItemId == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events that are not all-day events and last more than one day are considered multi-day events.
|
||||
/// </summary>
|
||||
public bool IsMultiDayEvent
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Events that are not all-day events and last more than one day are considered multi-day events.
|
||||
/// </summary>
|
||||
public bool IsMultiDayEvent
|
||||
{
|
||||
return Period.Duration.TotalDays >= 1 && !IsAllDayEvent;
|
||||
get
|
||||
{
|
||||
return Period.Duration.TotalDays >= 1 && !IsAllDayEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double DurationInSeconds { get; set; }
|
||||
public string Recurrence { get; set; }
|
||||
public double DurationInSeconds { get; set; }
|
||||
public string Recurrence { get; set; }
|
||||
|
||||
public string OrganizerDisplayName { get; set; }
|
||||
public string OrganizerEmail { get; set; }
|
||||
public string OrganizerDisplayName { get; set; }
|
||||
public string OrganizerEmail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The id of the parent calendar item of the recurring event.
|
||||
/// Exceptional instances are stored as a separate calendar item.
|
||||
/// This makes the calendar item a child of the recurring event.
|
||||
/// </summary>
|
||||
public Guid? RecurringCalendarItemId { get; set; }
|
||||
/// <summary>
|
||||
/// The id of the parent calendar item of the recurring event.
|
||||
/// Exceptional instances are stored as a separate calendar item.
|
||||
/// This makes the calendar item a child of the recurring event.
|
||||
/// </summary>
|
||||
public Guid? RecurringCalendarItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates read-only events. Default is false.
|
||||
/// </summary>
|
||||
public bool IsLocked { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates read-only events. Default is false.
|
||||
/// </summary>
|
||||
public bool IsLocked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Hidden events must not be displayed to the user.
|
||||
/// This usually happens when a child instance of recurring parent is cancelled after creation.
|
||||
/// </summary>
|
||||
public bool IsHidden { get; set; }
|
||||
/// <summary>
|
||||
/// Hidden events must not be displayed to the user.
|
||||
/// This usually happens when a child instance of recurring parent is cancelled after creation.
|
||||
/// </summary>
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
// TODO
|
||||
public string CustomEventColorHex { get; set; }
|
||||
public string HtmlLink { get; set; }
|
||||
public CalendarItemStatus Status { get; set; }
|
||||
public CalendarItemVisibility Visibility { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset UpdatedAt { get; set; }
|
||||
public Guid CalendarId { get; set; }
|
||||
// TODO
|
||||
public string CustomEventColorHex { get; set; }
|
||||
public string HtmlLink { get; set; }
|
||||
public CalendarItemStatus Status { get; set; }
|
||||
public CalendarItemVisibility Visibility { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
public DateTimeOffset UpdatedAt { get; set; }
|
||||
public Guid CalendarId { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public IAccountCalendar AssignedCalendar { get; set; }
|
||||
[Ignore]
|
||||
public IAccountCalendar AssignedCalendar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this item does not really exist in the database or not.
|
||||
/// These are used to display occurrence instances of parent recurring events.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public bool IsOccurrence { get; set; }
|
||||
/// <summary>
|
||||
/// Whether this item does not really exist in the database or not.
|
||||
/// These are used to display occurrence instances of parent recurring events.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public bool IsOccurrence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id to load information related to this event.
|
||||
/// Occurrences tracked by the parent recurring event if they are not exceptional instances.
|
||||
/// Recurring children here are exceptional instances. They have their own info in the database including Id.
|
||||
/// </summary>
|
||||
public Guid EventTrackingId => IsOccurrence ? RecurringCalendarItemId.Value : Id;
|
||||
/// <summary>
|
||||
/// Id to load information related to this event.
|
||||
/// Occurrences tracked by the parent recurring event if they are not exceptional instances.
|
||||
/// Recurring children here are exceptional instances. They have their own info in the database including Id.
|
||||
/// </summary>
|
||||
public Guid EventTrackingId => IsOccurrence ? RecurringCalendarItemId.Value : Id;
|
||||
|
||||
public CalendarItem CreateRecurrence(DateTime startDate, double durationInSeconds)
|
||||
{
|
||||
// Create a copy with the new start date and duration
|
||||
|
||||
return new CalendarItem
|
||||
public CalendarItem CreateRecurrence(DateTime startDate, double durationInSeconds)
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Title = Title,
|
||||
Description = Description,
|
||||
Location = Location,
|
||||
StartDate = startDate,
|
||||
DurationInSeconds = durationInSeconds,
|
||||
Recurrence = Recurrence,
|
||||
OrganizerDisplayName = OrganizerDisplayName,
|
||||
OrganizerEmail = OrganizerEmail,
|
||||
RecurringCalendarItemId = Id,
|
||||
AssignedCalendar = AssignedCalendar,
|
||||
CalendarId = CalendarId,
|
||||
CreatedAt = CreatedAt,
|
||||
UpdatedAt = UpdatedAt,
|
||||
Visibility = Visibility,
|
||||
Status = Status,
|
||||
CustomEventColorHex = CustomEventColorHex,
|
||||
HtmlLink = HtmlLink,
|
||||
StartDateOffset = StartDateOffset,
|
||||
EndDateOffset = EndDateOffset,
|
||||
RemoteEventId = RemoteEventId,
|
||||
IsHidden = IsHidden,
|
||||
IsLocked = IsLocked,
|
||||
IsOccurrence = true
|
||||
};
|
||||
// Create a copy with the new start date and duration
|
||||
|
||||
return new CalendarItem
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Title = Title,
|
||||
Description = Description,
|
||||
Location = Location,
|
||||
StartDate = startDate,
|
||||
DurationInSeconds = durationInSeconds,
|
||||
Recurrence = Recurrence,
|
||||
OrganizerDisplayName = OrganizerDisplayName,
|
||||
OrganizerEmail = OrganizerEmail,
|
||||
RecurringCalendarItemId = Id,
|
||||
AssignedCalendar = AssignedCalendar,
|
||||
CalendarId = CalendarId,
|
||||
CreatedAt = CreatedAt,
|
||||
UpdatedAt = UpdatedAt,
|
||||
Visibility = Visibility,
|
||||
Status = Status,
|
||||
CustomEventColorHex = CustomEventColorHex,
|
||||
HtmlLink = HtmlLink,
|
||||
StartDateOffset = StartDateOffset,
|
||||
EndDateOffset = EndDateOffset,
|
||||
RemoteEventId = RemoteEventId,
|
||||
IsHidden = IsHidden,
|
||||
IsLocked = IsLocked,
|
||||
IsOccurrence = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Calendar;
|
||||
|
||||
public class Reminder
|
||||
namespace Wino.Core.Domain.Entities.Calendar
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid CalendarItemId { get; set; }
|
||||
public class Reminder
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public Guid CalendarItemId { get; set; }
|
||||
|
||||
public DateTimeOffset ReminderTime { get; set; }
|
||||
public CalendarItemReminderType ReminderType { get; set; }
|
||||
public DateTimeOffset ReminderTime { get; set; }
|
||||
public CalendarItemReminderType ReminderType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Mail;
|
||||
|
||||
public class AccountSignature
|
||||
namespace Wino.Core.Domain.Entities.Mail
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public class AccountSignature
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public string HtmlBody { get; set; }
|
||||
public string HtmlBody { get; set; }
|
||||
|
||||
public Guid MailAccountId { get; set; }
|
||||
public Guid MailAccountId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +1,63 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Mail;
|
||||
|
||||
public class RemoteAccountAlias
|
||||
namespace Wino.Core.Domain.Entities.Mail
|
||||
{
|
||||
/// <summary>
|
||||
/// Display address of the alias.
|
||||
/// </summary>
|
||||
public string AliasAddress { get; set; }
|
||||
public class RemoteAccountAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// Display address of the alias.
|
||||
/// </summary>
|
||||
public string AliasAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Address to be included in Reply-To header when alias is used for sending messages.
|
||||
/// </summary>
|
||||
public string ReplyToAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Address to be included in Reply-To header when alias is used for sending messages.
|
||||
/// </summary>
|
||||
public string ReplyToAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this alias is the primary alias for the account.
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; set; }
|
||||
/// <summary>
|
||||
/// Whether this alias is the primary alias for the account.
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the alias is verified by the server.
|
||||
/// Only Gmail aliases are verified for now.
|
||||
/// Non-verified alias messages might be rejected by SMTP server.
|
||||
/// </summary>
|
||||
public bool IsVerified { get; set; }
|
||||
/// <summary>
|
||||
/// Whether the alias is verified by the server.
|
||||
/// Only Gmail aliases are verified for now.
|
||||
/// Non-verified alias messages might be rejected by SMTP server.
|
||||
/// </summary>
|
||||
public bool IsVerified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this alias is the root alias for the account.
|
||||
/// Root alias means the first alias that was created for the account.
|
||||
/// It can't be deleted or changed.
|
||||
/// </summary>
|
||||
public bool IsRootAlias { get; set; }
|
||||
/// <summary>
|
||||
/// Whether this alias is the root alias for the account.
|
||||
/// Root alias means the first alias that was created for the account.
|
||||
/// It can't be deleted or changed.
|
||||
/// </summary>
|
||||
public bool IsRootAlias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional sender name for the alias.
|
||||
/// Falls back to account's sender name if not set when preparing messages.
|
||||
/// Used for Gmail only.
|
||||
/// </summary>
|
||||
public string AliasSenderName { get; set; }
|
||||
}
|
||||
|
||||
public class MailAccountAlias : RemoteAccountAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id for the alias.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account id that this alias is attached to.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Root aliases can't be deleted.
|
||||
/// </summary>
|
||||
public bool CanDelete => !IsRootAlias;
|
||||
/// <summary>
|
||||
/// Optional sender name for the alias.
|
||||
/// Falls back to account's sender name if not set when preparing messages.
|
||||
/// Used for Gmail only.
|
||||
/// </summary>
|
||||
public string AliasSenderName { get; set; }
|
||||
}
|
||||
|
||||
public class MailAccountAlias : RemoteAccountAlias
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id for the alias.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account id that this alias is attached to.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Root aliases can't be deleted.
|
||||
/// </summary>
|
||||
public bool CanDelete => !IsRootAlias;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,152 +5,153 @@ using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Mail;
|
||||
|
||||
/// <summary>
|
||||
/// Summary of the parsed MIME messages.
|
||||
/// Wino will do non-network operations on this table and others from the original MIME.
|
||||
/// </summary>
|
||||
public class MailCopy : IMailItem
|
||||
namespace Wino.Core.Domain.Entities.Mail
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id of the mail.
|
||||
/// Summary of the parsed MIME messages.
|
||||
/// Wino will do non-network operations on this table and others from the original MIME.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public Guid UniqueId { get; set; }
|
||||
public class MailCopy : IMailItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id of the mail.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public Guid UniqueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Not unique id of the item. Some operations held on this Id, some on the UniqueId.
|
||||
/// Same message can be in different folder. In that case UniqueId is used.
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// Not unique id of the item. Some operations held on this Id, some on the UniqueId.
|
||||
/// Same message can be in different folder. In that case UniqueId is used.
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Folder that this mail belongs to.
|
||||
/// </summary>
|
||||
public Guid FolderId { get; set; }
|
||||
/// <summary>
|
||||
/// Folder that this mail belongs to.
|
||||
/// </summary>
|
||||
public Guid FolderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Conversation id for the mail.
|
||||
/// </summary>
|
||||
public string ThreadId { get; set; }
|
||||
/// <summary>
|
||||
/// Conversation id for the mail.
|
||||
/// </summary>
|
||||
public string ThreadId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MIME MessageId if exists.
|
||||
/// </summary>
|
||||
public string MessageId { get; set; }
|
||||
/// <summary>
|
||||
/// MIME MessageId if exists.
|
||||
/// </summary>
|
||||
public string MessageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// References header from MIME
|
||||
/// </summary>
|
||||
public string References { get; set; }
|
||||
/// <summary>
|
||||
/// References header from MIME
|
||||
/// </summary>
|
||||
public string References { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// In-Reply-To header from MIME
|
||||
/// </summary>
|
||||
public string InReplyTo { get; set; }
|
||||
/// <summary>
|
||||
/// In-Reply-To header from MIME
|
||||
/// </summary>
|
||||
public string InReplyTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name for the sender.
|
||||
/// </summary>
|
||||
public string FromName { get; set; }
|
||||
/// <summary>
|
||||
/// Name for the sender.
|
||||
/// </summary>
|
||||
public string FromName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Address of the sender.
|
||||
/// </summary>
|
||||
public string FromAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Address of the sender.
|
||||
/// </summary>
|
||||
public string FromAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Subject of the mail.
|
||||
/// </summary>
|
||||
public string Subject { get; set; }
|
||||
/// <summary>
|
||||
/// Subject of the mail.
|
||||
/// </summary>
|
||||
public string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Short preview of the content.
|
||||
/// </summary>
|
||||
public string PreviewText { get; set; }
|
||||
/// <summary>
|
||||
/// Short preview of the content.
|
||||
/// </summary>
|
||||
public string PreviewText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date that represents this mail has been created in provider servers.
|
||||
/// Stored always in UTC.
|
||||
/// </summary>
|
||||
public DateTime CreationDate { get; set; }
|
||||
/// <summary>
|
||||
/// Date that represents this mail has been created in provider servers.
|
||||
/// Stored always in UTC.
|
||||
/// </summary>
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Importance of the mail.
|
||||
/// </summary>
|
||||
public MailImportance Importance { get; set; }
|
||||
/// <summary>
|
||||
/// Importance of the mail.
|
||||
/// </summary>
|
||||
public MailImportance Importance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read status for the mail.
|
||||
/// </summary>
|
||||
public bool IsRead { get; set; }
|
||||
/// <summary>
|
||||
/// Read status for the mail.
|
||||
/// </summary>
|
||||
public bool IsRead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flag status.
|
||||
/// Flagged for Outlook.
|
||||
/// Important for Gmail.
|
||||
/// </summary>
|
||||
public bool IsFlagged { get; set; }
|
||||
/// <summary>
|
||||
/// Flag status.
|
||||
/// Flagged for Outlook.
|
||||
/// Important for Gmail.
|
||||
/// </summary>
|
||||
public bool IsFlagged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// To support Outlook.
|
||||
/// Gmail doesn't use it.
|
||||
/// </summary>
|
||||
public bool IsFocused { get; set; }
|
||||
/// <summary>
|
||||
/// To support Outlook.
|
||||
/// Gmail doesn't use it.
|
||||
/// </summary>
|
||||
public bool IsFocused { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether mail has attachments included or not.
|
||||
/// </summary>
|
||||
public bool HasAttachments { get; set; }
|
||||
/// <summary>
|
||||
/// Whether mail has attachments included or not.
|
||||
/// </summary>
|
||||
public bool HasAttachments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Assigned draft id.
|
||||
/// </summary>
|
||||
public string DraftId { get; set; }
|
||||
/// <summary>
|
||||
/// Assigned draft id.
|
||||
/// </summary>
|
||||
public string DraftId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this mail is only created locally.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
|
||||
/// <summary>
|
||||
/// Whether this mail is only created locally.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
|
||||
|
||||
/// <summary>
|
||||
/// Whether this copy is draft or not.
|
||||
/// </summary>
|
||||
public bool IsDraft { get; set; }
|
||||
/// <summary>
|
||||
/// Whether this copy is draft or not.
|
||||
/// </summary>
|
||||
public bool IsDraft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File id that this mail is assigned to.
|
||||
/// This Id is immutable. It's used to find the file in the file system.
|
||||
/// Even after mapping local draft to remote draft, it will not change.
|
||||
/// </summary>
|
||||
public Guid FileId { get; set; }
|
||||
/// <summary>
|
||||
/// File id that this mail is assigned to.
|
||||
/// This Id is immutable. It's used to find the file in the file system.
|
||||
/// Even after mapping local draft to remote draft, it will not change.
|
||||
/// </summary>
|
||||
public Guid FileId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Folder that this mail is assigned to.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailItemFolder AssignedFolder { get; set; }
|
||||
/// <summary>
|
||||
/// Folder that this mail is assigned to.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailItemFolder AssignedFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account that this mail is assigned to.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailAccount AssignedAccount { get; set; }
|
||||
/// <summary>
|
||||
/// Account that this mail is assigned to.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailAccount AssignedAccount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contact information of the sender if exists.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public AccountContact SenderContact { get; set; }
|
||||
/// <summary>
|
||||
/// Contact information of the sender if exists.
|
||||
/// Warning: This field is not populated by queries.
|
||||
/// Services or View Models are responsible for populating this field.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public AccountContact SenderContact { get; set; }
|
||||
|
||||
public IEnumerable<Guid> GetContainingIds() => [UniqueId];
|
||||
public override string ToString() => $"{Subject} <-> {Id}";
|
||||
public IEnumerable<Guid> GetContainingIds() => [UniqueId];
|
||||
public override string ToString() => $"{Subject} <-> {Id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,70 +5,71 @@ using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Models.Folders;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Mail;
|
||||
|
||||
[DebuggerDisplay("{FolderName} - {SpecialFolderType}")]
|
||||
public class MailItemFolder : IMailItemFolder
|
||||
namespace Wino.Core.Domain.Entities.Mail
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string RemoteFolderId { get; set; }
|
||||
public string ParentRemoteFolderId { get; set; }
|
||||
|
||||
public Guid MailAccountId { get; set; }
|
||||
public string FolderName { get; set; }
|
||||
public SpecialFolderType SpecialFolderType { get; set; }
|
||||
public bool IsSystemFolder { get; set; }
|
||||
public bool IsSticky { get; set; }
|
||||
public bool IsSynchronizationEnabled { get; set; }
|
||||
public bool IsHidden { get; set; }
|
||||
public bool ShowUnreadCount { get; set; }
|
||||
public DateTime? LastSynchronizedDate { get; set; }
|
||||
|
||||
// For IMAP
|
||||
public uint UidValidity { get; set; }
|
||||
public long HighestModeSeq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Outlook shares delta changes per-folder. Gmail is for per-account.
|
||||
/// This is only used for Outlook provider.
|
||||
/// </summary>
|
||||
public string DeltaToken { get; set; }
|
||||
|
||||
// For GMail Labels
|
||||
public string TextColorHex { get; set; }
|
||||
public string BackgroundColorHex { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public List<IMailItemFolder> ChildFolders { get; set; } = [];
|
||||
|
||||
// Category and Move type folders are not valid move targets.
|
||||
// These folders are virtual. They don't exist on the server.
|
||||
public bool IsMoveTarget => !(SpecialFolderType == SpecialFolderType.More || SpecialFolderType == SpecialFolderType.Category);
|
||||
|
||||
public bool ContainsSpecialFolderType(SpecialFolderType type)
|
||||
[DebuggerDisplay("{FolderName} - {SpecialFolderType}")]
|
||||
public class MailItemFolder : IMailItemFolder
|
||||
{
|
||||
if (SpecialFolderType == type)
|
||||
return true;
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
foreach (var child in ChildFolders)
|
||||
public string RemoteFolderId { get; set; }
|
||||
public string ParentRemoteFolderId { get; set; }
|
||||
|
||||
public Guid MailAccountId { get; set; }
|
||||
public string FolderName { get; set; }
|
||||
public SpecialFolderType SpecialFolderType { get; set; }
|
||||
public bool IsSystemFolder { get; set; }
|
||||
public bool IsSticky { get; set; }
|
||||
public bool IsSynchronizationEnabled { get; set; }
|
||||
public bool IsHidden { get; set; }
|
||||
public bool ShowUnreadCount { get; set; }
|
||||
public DateTime? LastSynchronizedDate { get; set; }
|
||||
|
||||
// For IMAP
|
||||
public uint UidValidity { get; set; }
|
||||
public long HighestModeSeq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Outlook shares delta changes per-folder. Gmail is for per-account.
|
||||
/// This is only used for Outlook provider.
|
||||
/// </summary>
|
||||
public string DeltaToken { get; set; }
|
||||
|
||||
// For GMail Labels
|
||||
public string TextColorHex { get; set; }
|
||||
public string BackgroundColorHex { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public List<IMailItemFolder> ChildFolders { get; set; } = [];
|
||||
|
||||
// Category and Move type folders are not valid move targets.
|
||||
// These folders are virtual. They don't exist on the server.
|
||||
public bool IsMoveTarget => !(SpecialFolderType == SpecialFolderType.More || SpecialFolderType == SpecialFolderType.Category);
|
||||
|
||||
public bool ContainsSpecialFolderType(SpecialFolderType type)
|
||||
{
|
||||
if (child.SpecialFolderType == type)
|
||||
{
|
||||
if (SpecialFolderType == type)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
foreach (var child in ChildFolders)
|
||||
{
|
||||
return child.ContainsSpecialFolderType(type);
|
||||
if (child.SpecialFolderType == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return child.ContainsSpecialFolderType(type);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
public static MailItemFolder CreateMoreFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.More, FolderName = Translator.MoreFolderNameOverride };
|
||||
public static MailItemFolder CreateCategoriesFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.Category, FolderName = Translator.CategoriesFolderNameOverride };
|
||||
|
||||
public override string ToString() => FolderName;
|
||||
}
|
||||
|
||||
public static MailItemFolder CreateMoreFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.More, FolderName = Translator.MoreFolderNameOverride };
|
||||
public static MailItemFolder CreateCategoriesFolder() => new MailItemFolder() { IsSticky = true, SpecialFolderType = SpecialFolderType.Category, FolderName = Translator.CategoriesFolderNameOverride };
|
||||
|
||||
public override string ToString() => FolderName;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Mail;
|
||||
|
||||
public class MergedInbox
|
||||
namespace Wino.Core.Domain.Entities.Mail
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public class MergedInbox
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,75 +2,76 @@
|
||||
using System.Collections.Generic;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
/// <summary>
|
||||
/// Back storage for simple name-address book.
|
||||
/// These values will be inserted during MIME fetch.
|
||||
/// </summary>
|
||||
|
||||
// TODO: This can easily evolve to Contact store, just like People app in Windows 10/11.
|
||||
// Do it.
|
||||
public class AccountContact : IEquatable<AccountContact>
|
||||
namespace Wino.Core.Domain.Entities.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// E-mail address of the contact.
|
||||
/// Back storage for simple name-address book.
|
||||
/// These values will be inserted during MIME fetch.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Display name of the contact.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Base64 encoded profile image of the contact.
|
||||
/// </summary>
|
||||
public string Base64ContactPicture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All registered accounts have their contacts registered as root.
|
||||
/// Root contacts must not be overridden by any configuration.
|
||||
/// They are created on account creation.
|
||||
/// </summary>
|
||||
public bool IsRootContact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Short display name of the contact.
|
||||
/// Eather Name or Address.
|
||||
/// </summary>
|
||||
public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};";
|
||||
|
||||
public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>";
|
||||
|
||||
public override bool Equals(object obj)
|
||||
// TODO: This can easily evolve to Contact store, just like People app in Windows 10/11.
|
||||
// Do it.
|
||||
public class AccountContact : IEquatable<AccountContact>
|
||||
{
|
||||
return Equals(obj as AccountContact);
|
||||
}
|
||||
/// <summary>
|
||||
/// E-mail address of the contact.
|
||||
/// </summary>
|
||||
[PrimaryKey]
|
||||
public string Address { get; set; }
|
||||
|
||||
public bool Equals(AccountContact other)
|
||||
{
|
||||
return other is not null &&
|
||||
Address == other.Address &&
|
||||
Name == other.Name;
|
||||
}
|
||||
/// <summary>
|
||||
/// Display name of the contact.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = -1717786383;
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Address);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name);
|
||||
return hashCode;
|
||||
}
|
||||
/// <summary>
|
||||
/// Base64 encoded profile image of the contact.
|
||||
/// </summary>
|
||||
public string Base64ContactPicture { get; set; }
|
||||
|
||||
public static bool operator ==(AccountContact left, AccountContact right)
|
||||
{
|
||||
return EqualityComparer<AccountContact>.Default.Equals(left, right);
|
||||
}
|
||||
/// <summary>
|
||||
/// All registered accounts have their contacts registered as root.
|
||||
/// Root contacts must not be overridden by any configuration.
|
||||
/// They are created on account creation.
|
||||
/// </summary>
|
||||
public bool IsRootContact { get; set; }
|
||||
|
||||
public static bool operator !=(AccountContact left, AccountContact right)
|
||||
{
|
||||
return !(left == right);
|
||||
/// <summary>
|
||||
/// Short display name of the contact.
|
||||
/// Eather Name or Address.
|
||||
/// </summary>
|
||||
public string ShortDisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? $"{Address.ToLowerInvariant()};" : $"{Name};";
|
||||
|
||||
public string DisplayName => Address == Name || string.IsNullOrWhiteSpace(Name) ? Address.ToLowerInvariant() : $"{Name} <{Address.ToLowerInvariant()}>";
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as AccountContact);
|
||||
}
|
||||
|
||||
public bool Equals(AccountContact other)
|
||||
{
|
||||
return other is not null &&
|
||||
Address == other.Address &&
|
||||
Name == other.Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = -1717786383;
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Address);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static bool operator ==(AccountContact left, AccountContact right)
|
||||
{
|
||||
return EqualityComparer<AccountContact>.Default.Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(AccountContact left, AccountContact right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,51 +2,52 @@
|
||||
using SQLite;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
public class CustomServerInformation
|
||||
namespace Wino.Core.Domain.Entities.Shared
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public class CustomServerInformation
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This field is ignored. DisplayName is stored in MailAccount as SenderName from now.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public string DisplayName { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string IncomingServer { get; set; }
|
||||
public string IncomingServerUsername { get; set; }
|
||||
public string IncomingServerPassword { get; set; }
|
||||
public string IncomingServerPort { get; set; }
|
||||
/// <summary>
|
||||
/// This field is ignored. DisplayName is stored in MailAccount as SenderName from now.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public string DisplayName { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string IncomingServer { get; set; }
|
||||
public string IncomingServerUsername { get; set; }
|
||||
public string IncomingServerPassword { get; set; }
|
||||
public string IncomingServerPort { get; set; }
|
||||
|
||||
public CustomIncomingServerType IncomingServerType { get; set; }
|
||||
public CustomIncomingServerType IncomingServerType { get; set; }
|
||||
|
||||
public string OutgoingServer { get; set; }
|
||||
public string OutgoingServerPort { get; set; }
|
||||
public string OutgoingServerUsername { get; set; }
|
||||
public string OutgoingServerPassword { get; set; }
|
||||
public string OutgoingServer { get; set; }
|
||||
public string OutgoingServerPort { get; set; }
|
||||
public string OutgoingServerUsername { get; set; }
|
||||
public string OutgoingServerPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// useSSL True: SslOnConnect
|
||||
/// useSSL False: StartTlsWhenAvailable
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// useSSL True: SslOnConnect
|
||||
/// useSSL False: StartTlsWhenAvailable
|
||||
/// </summary>
|
||||
|
||||
public ImapConnectionSecurity IncomingServerSocketOption { get; set; }
|
||||
public ImapAuthenticationMethod IncomingAuthenticationMethod { get; set; }
|
||||
public ImapConnectionSecurity IncomingServerSocketOption { get; set; }
|
||||
public ImapAuthenticationMethod IncomingAuthenticationMethod { get; set; }
|
||||
|
||||
|
||||
public ImapConnectionSecurity OutgoingServerSocketOption { get; set; }
|
||||
public ImapAuthenticationMethod OutgoingAuthenticationMethod { get; set; }
|
||||
public ImapConnectionSecurity OutgoingServerSocketOption { get; set; }
|
||||
public ImapAuthenticationMethod OutgoingAuthenticationMethod { get; set; }
|
||||
|
||||
public string ProxyServer { get; set; }
|
||||
public string ProxyServerPort { get; set; }
|
||||
public string ProxyServer { get; set; }
|
||||
public string ProxyServerPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of concurrent clients that can connect to the server.
|
||||
/// Default is 5.
|
||||
/// </summary>
|
||||
public int MaxConcurrentClients { get; set; }
|
||||
/// <summary>
|
||||
/// Number of concurrent clients that can connect to the server.
|
||||
/// Default is 5.
|
||||
/// </summary>
|
||||
public int MaxConcurrentClients { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,108 +3,109 @@ using SQLite;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
public class MailAccount
|
||||
namespace Wino.Core.Domain.Entities.Shared
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public class MailAccount
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Given name of the account in Wino.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Given name of the account in Wino.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TODO: Display name of the authenticated user/account.
|
||||
/// API integrations will query this value from the API.
|
||||
/// IMAP is populated by user on setup dialog.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// TODO: Display name of the authenticated user/account.
|
||||
/// API integrations will query this value from the API.
|
||||
/// IMAP is populated by user on setup dialog.
|
||||
/// </summary>
|
||||
|
||||
public string SenderName { get; set; }
|
||||
public string SenderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account e-mail address.
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
/// <summary>
|
||||
/// Account e-mail address.
|
||||
/// </summary>
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provider type of the account. Outlook,Gmail etc...
|
||||
/// </summary>
|
||||
public MailProviderType ProviderType { get; set; }
|
||||
/// <summary>
|
||||
/// Provider type of the account. Outlook,Gmail etc...
|
||||
/// </summary>
|
||||
public MailProviderType ProviderType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For tracking mail change delta.
|
||||
/// Gmail : historyId
|
||||
/// Outlook: deltaToken
|
||||
/// </summary>
|
||||
public string SynchronizationDeltaIdentifier { get; set; }
|
||||
/// <summary>
|
||||
/// For tracking mail change delta.
|
||||
/// Gmail : historyId
|
||||
/// Outlook: deltaToken
|
||||
/// </summary>
|
||||
public string SynchronizationDeltaIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For tracking calendar change delta.
|
||||
/// Gmail: It's per-calendar, so unused.
|
||||
/// Outlook: deltaLink
|
||||
/// </summary>
|
||||
public string CalendarSynchronizationDeltaIdentifier { get; set; }
|
||||
/// <summary>
|
||||
/// For tracking calendar change delta.
|
||||
/// Gmail: It's per-calendar, so unused.
|
||||
/// Outlook: deltaLink
|
||||
/// </summary>
|
||||
public string CalendarSynchronizationDeltaIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TODO: Gets or sets the custom account identifier color in hex.
|
||||
/// </summary>
|
||||
public string AccountColorHex { get; set; }
|
||||
/// <summary>
|
||||
/// TODO: Gets or sets the custom account identifier color in hex.
|
||||
/// </summary>
|
||||
public string AccountColorHex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Base64 encoded profile picture of the account.
|
||||
/// </summary>
|
||||
public string Base64ProfilePictureData { get; set; }
|
||||
/// <summary>
|
||||
/// Base64 encoded profile picture of the account.
|
||||
/// </summary>
|
||||
public string Base64ProfilePictureData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the listing order of the account in the accounts list.
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the listing order of the account in the accounts list.
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has any reason for an interactive user action to fix continue operating.
|
||||
/// </summary>
|
||||
public AccountAttentionReason AttentionReason { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has any reason for an interactive user action to fix continue operating.
|
||||
/// </summary>
|
||||
public AccountAttentionReason AttentionReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id of the merged inbox this account belongs to.
|
||||
/// </summary>
|
||||
public Guid? MergedInboxId { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the id of the merged inbox this account belongs to.
|
||||
/// </summary>
|
||||
public Guid? MergedInboxId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the additional IMAP provider assignment for the account.
|
||||
/// Providers that use IMAP as a synchronizer but have special requirements.
|
||||
/// </summary>
|
||||
public SpecialImapProvider SpecialImapProvider { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the additional IMAP provider assignment for the account.
|
||||
/// Providers that use IMAP as a synchronizer but have special requirements.
|
||||
/// </summary>
|
||||
public SpecialImapProvider SpecialImapProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the merged inbox this account belongs to.
|
||||
/// Ignored for all SQLite operations.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MergedInbox MergedInbox { get; set; }
|
||||
/// <summary>
|
||||
/// Contains the merged inbox this account belongs to.
|
||||
/// Ignored for all SQLite operations.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MergedInbox MergedInbox { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Populated only when account has custom server information.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Populated only when account has custom server information.
|
||||
/// </summary>
|
||||
|
||||
[Ignore]
|
||||
public CustomServerInformation ServerInformation { get; set; }
|
||||
[Ignore]
|
||||
public CustomServerInformation ServerInformation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Account preferences.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailAccountPreferences Preferences { get; set; }
|
||||
/// <summary>
|
||||
/// Account preferences.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
public MailAccountPreferences Preferences { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform ProfileInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsProfileInfoSyncSupported => ProviderType == MailProviderType.Outlook || ProviderType == MailProviderType.Gmail;
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform ProfileInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsProfileInfoSyncSupported => ProviderType == MailProviderType.Outlook || ProviderType == MailProviderType.Gmail;
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform AliasInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsAliasSyncSupported => ProviderType == MailProviderType.Gmail;
|
||||
/// <summary>
|
||||
/// Gets whether the account can perform AliasInformation sync type.
|
||||
/// </summary>
|
||||
public bool IsAliasSyncSupported => ProviderType == MailProviderType.Gmail;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,54 @@
|
||||
using System;
|
||||
using SQLite;
|
||||
|
||||
namespace Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
public class MailAccountPreferences
|
||||
namespace Wino.Core.Domain.Entities.Shared
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
public class MailAccountPreferences
|
||||
{
|
||||
[PrimaryKey]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id of the account in MailAccount table.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
/// <summary>
|
||||
/// Id of the account in MailAccount table.
|
||||
/// </summary>
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether sent draft messages should be appended to the sent folder.
|
||||
/// Some IMAP servers do this automatically, some don't.
|
||||
/// It's disabled by default.
|
||||
/// </summary>
|
||||
public bool ShouldAppendMessagesToSentFolder { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets whether sent draft messages should be appended to the sent folder.
|
||||
/// Some IMAP servers do this automatically, some don't.
|
||||
/// It's disabled by default.
|
||||
/// </summary>
|
||||
public bool ShouldAppendMessagesToSentFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the notifications are enabled for the account.
|
||||
/// </summary>
|
||||
public bool IsNotificationsEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets whether the notifications are enabled for the account.
|
||||
/// </summary>
|
||||
public bool IsNotificationsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has Focused inbox support.
|
||||
/// Null if the account provider type doesn't support Focused inbox.
|
||||
/// </summary>
|
||||
public bool? IsFocusedInboxEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets whether the account has Focused inbox support.
|
||||
/// Null if the account provider type doesn't support Focused inbox.
|
||||
/// </summary>
|
||||
public bool? IsFocusedInboxEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether signature should be appended automatically.
|
||||
/// </summary>
|
||||
public bool IsSignatureEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets whether signature should be appended automatically.
|
||||
/// </summary>
|
||||
public bool IsSignatureEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether this account's unread items should be included in taskbar badge.
|
||||
/// </summary>
|
||||
public bool IsTaskbarBadgeEnabled { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Gets or sets whether this account's unread items should be included in taskbar badge.
|
||||
/// </summary>
|
||||
public bool IsTaskbarBadgeEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets signature for new messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForNewMessages { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets signature for new messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForNewMessages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets signature for following messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForFollowingMessages { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets signature for following messages. Null if signature is not needed.
|
||||
/// </summary>
|
||||
public Guid? SignatureIdForFollowingMessages { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum AccountAttentionReason
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
InvalidCredentials,
|
||||
MissingSystemFolderConfiguration
|
||||
public enum AccountAttentionReason
|
||||
{
|
||||
None,
|
||||
InvalidCredentials,
|
||||
MissingSystemFolderConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum AccountCreationDialogState
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Idle,
|
||||
SigningIn,
|
||||
PreparingFolders,
|
||||
Completed,
|
||||
ManuelSetupWaiting,
|
||||
TestingConnection,
|
||||
AutoDiscoverySetup,
|
||||
AutoDiscoveryInProgress,
|
||||
FetchingProfileInformation,
|
||||
Canceled,
|
||||
FetchingEvents
|
||||
public enum AccountCreationDialogState
|
||||
{
|
||||
Idle,
|
||||
SigningIn,
|
||||
PreparingFolders,
|
||||
Completed,
|
||||
ManuelSetupWaiting,
|
||||
TestingConnection,
|
||||
AutoDiscoverySetup,
|
||||
AutoDiscoveryInProgress,
|
||||
FetchingProfileInformation,
|
||||
Canceled,
|
||||
FetchingEvents
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the state of synchronizer.
|
||||
/// </summary>
|
||||
public enum AccountSynchronizerState
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Idle,
|
||||
ExecutingRequests,
|
||||
Synchronizing
|
||||
/// <summary>
|
||||
/// Indicates the state of synchronizer.
|
||||
/// </summary>
|
||||
public enum AccountSynchronizerState
|
||||
{
|
||||
Idle,
|
||||
ExecutingRequests,
|
||||
Synchronizing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum AppLanguage
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
English,
|
||||
Deutsch,
|
||||
Russian,
|
||||
Turkish,
|
||||
Polish,
|
||||
Czech,
|
||||
Chinese,
|
||||
Spanish,
|
||||
French,
|
||||
Indonesian,
|
||||
Greek,
|
||||
PortugeseBrazil,
|
||||
Italian,
|
||||
Romanian
|
||||
public enum AppLanguage
|
||||
{
|
||||
None,
|
||||
English,
|
||||
Deutsch,
|
||||
Russian,
|
||||
Turkish,
|
||||
Polish,
|
||||
Czech,
|
||||
Chinese,
|
||||
Spanish,
|
||||
French,
|
||||
Indonesian,
|
||||
Greek,
|
||||
PortugeseBrazil,
|
||||
Italian,
|
||||
Romanian
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum AppThemeType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
System,
|
||||
PreDefined,
|
||||
Custom,
|
||||
public enum AppThemeType
|
||||
{
|
||||
System,
|
||||
PreDefined,
|
||||
Custom,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum ApplicationElementTheme
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Default,
|
||||
Light,
|
||||
Dark
|
||||
public enum ApplicationElementTheme
|
||||
{
|
||||
Default,
|
||||
Light,
|
||||
Dark
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum AttendeeStatus
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
NeedsAction,
|
||||
Accepted,
|
||||
Tentative,
|
||||
Declined
|
||||
public enum AttendeeStatus
|
||||
{
|
||||
NeedsAction,
|
||||
Accepted,
|
||||
Tentative,
|
||||
Declined
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum BackgroundSynchronizationReason
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
SessionConnected,
|
||||
Timer
|
||||
public enum BackgroundSynchronizationReason
|
||||
{
|
||||
SessionConnected,
|
||||
Timer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarDisplayType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Day,
|
||||
Week,
|
||||
WorkWeek,
|
||||
Month,
|
||||
Year
|
||||
public enum CalendarDisplayType
|
||||
{
|
||||
Day,
|
||||
Week,
|
||||
WorkWeek,
|
||||
Month,
|
||||
Year
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarEventTargetType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Single, // Show details for a single event.
|
||||
Series // Show the series event. Parent of all recurring events.
|
||||
public enum CalendarEventTargetType
|
||||
{
|
||||
Single, // Show details for a single event.
|
||||
Series // Show the series event. Parent of all recurring events.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Trigger to load more data.
|
||||
/// </summary>
|
||||
public enum CalendarInitInitiative
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
User,
|
||||
App
|
||||
/// <summary>
|
||||
/// Trigger to load more data.
|
||||
/// </summary>
|
||||
public enum CalendarInitInitiative
|
||||
{
|
||||
User,
|
||||
App
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarItemRecurrenceFrequency
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Daily,
|
||||
Weekly,
|
||||
Monthly,
|
||||
Yearly
|
||||
public enum CalendarItemRecurrenceFrequency
|
||||
{
|
||||
Daily,
|
||||
Weekly,
|
||||
Monthly,
|
||||
Yearly
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarItemReminderType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Popup,
|
||||
Email
|
||||
public enum CalendarItemReminderType
|
||||
{
|
||||
Popup,
|
||||
Email
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarItemStatus
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
NotResponded,
|
||||
Confirmed,
|
||||
Tentative,
|
||||
Cancelled,
|
||||
public enum CalendarItemStatus
|
||||
{
|
||||
NotResponded,
|
||||
Confirmed,
|
||||
Tentative,
|
||||
Cancelled,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarItemVisibility
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Default,
|
||||
Public,
|
||||
Private,
|
||||
Confidential
|
||||
public enum CalendarItemVisibility
|
||||
{
|
||||
Default,
|
||||
Public,
|
||||
Private,
|
||||
Confidential
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Which way in time to load more data for calendar.
|
||||
/// </summary>
|
||||
public enum CalendarLoadDirection
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Replace,
|
||||
Previous,
|
||||
Next
|
||||
/// <summary>
|
||||
/// Which way in time to load more data for calendar.
|
||||
/// </summary>
|
||||
public enum CalendarLoadDirection
|
||||
{
|
||||
Replace,
|
||||
Previous,
|
||||
Next
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarOrientation
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Horizontal,
|
||||
Vertical
|
||||
public enum CalendarOrientation
|
||||
{
|
||||
Horizontal,
|
||||
Vertical
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CalendarSynchronizationType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
ExecuteRequests, // Execute all requests in the queue.
|
||||
CalendarMetadata, // Sync calendar metadata.
|
||||
CalendarEvents, // Sync all events for all calendars.
|
||||
SingleCalendar, // Sync events for only specified calendars.
|
||||
UpdateProfile // Update profile information only.
|
||||
public enum CalendarSynchronizationType
|
||||
{
|
||||
ExecuteRequests, // Execute all requests in the queue.
|
||||
CalendarMetadata, // Sync calendar metadata.
|
||||
CalendarEvents, // Sync all events for all calendars.
|
||||
SingleCalendar, // Sync events for only specified calendars.
|
||||
UpdateProfile // Update profile information only.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum ChangeRequestType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
MailMarkAs,
|
||||
MailChangeFlag,
|
||||
MailHardDelete,
|
||||
MailMove,
|
||||
MailAlwaysMoveTo,
|
||||
MailChangeFocused,
|
||||
MailArchive,
|
||||
MailUnarchive,
|
||||
FolderMarkAsRead,
|
||||
FolderDelete,
|
||||
FolderEmpty,
|
||||
FolderRename,
|
||||
CreateNewDraft,
|
||||
CreateReplyDraft,
|
||||
CreateForwardDraft,
|
||||
DiscardDraft,
|
||||
SendDraft,
|
||||
FetchSingleItem
|
||||
public enum ChangeRequestType
|
||||
{
|
||||
MailMarkAs,
|
||||
MailChangeFlag,
|
||||
MailHardDelete,
|
||||
MailMove,
|
||||
MailAlwaysMoveTo,
|
||||
MailChangeFocused,
|
||||
MailArchive,
|
||||
MailUnarchive,
|
||||
FolderMarkAsRead,
|
||||
FolderDelete,
|
||||
FolderEmpty,
|
||||
FolderRename,
|
||||
CreateNewDraft,
|
||||
CreateReplyDraft,
|
||||
CreateForwardDraft,
|
||||
DiscardDraft,
|
||||
SendDraft,
|
||||
FetchSingleItem
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum CustomIncomingServerType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
POP3,
|
||||
IMAP4
|
||||
public enum CustomIncomingServerType
|
||||
{
|
||||
POP3,
|
||||
IMAP4
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum DayHeaderDisplayType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
TwelveHour,
|
||||
TwentyFourHour,
|
||||
public enum DayHeaderDisplayType
|
||||
{
|
||||
TwelveHour,
|
||||
TwentyFourHour,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum DraftCreationReason
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Empty,
|
||||
Reply,
|
||||
ReplyAll,
|
||||
Forward
|
||||
public enum DraftCreationReason
|
||||
{
|
||||
Empty,
|
||||
Reply,
|
||||
ReplyAll,
|
||||
Forward
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum FilterOptionType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
All,
|
||||
Unread,
|
||||
Flagged,
|
||||
Mentions,
|
||||
Files
|
||||
public enum FilterOptionType
|
||||
{
|
||||
All,
|
||||
Unread,
|
||||
Flagged,
|
||||
Mentions,
|
||||
Files
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Defines all possible folder operations that can be done.
|
||||
/// Available values for each folder is returned by IContextMenuProvider
|
||||
/// that integrators hold.
|
||||
/// </summary>
|
||||
public enum FolderOperation
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
Pin,
|
||||
Unpin,
|
||||
MarkAllAsRead,
|
||||
DontSync,
|
||||
Empty,
|
||||
Rename,
|
||||
Delete,
|
||||
Move,
|
||||
TurnOffNotifications,
|
||||
CreateSubFolder,
|
||||
Seperator
|
||||
/// <summary>
|
||||
/// Defines all possible folder operations that can be done.
|
||||
/// Available values for each folder is returned by IContextMenuProvider
|
||||
/// that integrators hold.
|
||||
/// </summary>
|
||||
public enum FolderOperation
|
||||
{
|
||||
None,
|
||||
Pin,
|
||||
Unpin,
|
||||
MarkAllAsRead,
|
||||
DontSync,
|
||||
Empty,
|
||||
Rename,
|
||||
Delete,
|
||||
Move,
|
||||
TurnOffNotifications,
|
||||
CreateSubFolder,
|
||||
Seperator
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum ImapAuthenticationMethod
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Auto,
|
||||
None,
|
||||
NormalPassword,
|
||||
EncryptedPassword,
|
||||
Ntlm,
|
||||
CramMd5,
|
||||
DigestMd5
|
||||
public enum ImapAuthenticationMethod
|
||||
{
|
||||
Auto,
|
||||
None,
|
||||
NormalPassword,
|
||||
EncryptedPassword,
|
||||
Ntlm,
|
||||
CramMd5,
|
||||
DigestMd5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum ImapConnectionSecurity
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Auto,
|
||||
None,
|
||||
StartTls,
|
||||
SslTls
|
||||
public enum ImapConnectionSecurity
|
||||
{
|
||||
Auto,
|
||||
None,
|
||||
StartTls,
|
||||
SslTls
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum InfoBarAnimationType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
SlideFromRightToLeft,
|
||||
SlideFromBottomToTop
|
||||
public enum InfoBarAnimationType
|
||||
{
|
||||
SlideFromRightToLeft,
|
||||
SlideFromBottomToTop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum InfoBarMessageType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Information,
|
||||
Success,
|
||||
Warning,
|
||||
Error
|
||||
public enum InfoBarMessageType
|
||||
{
|
||||
Information,
|
||||
Success,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailAttachmentType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
Executable,
|
||||
Image,
|
||||
Audio,
|
||||
Video,
|
||||
PDF,
|
||||
HTML,
|
||||
RarArchive,
|
||||
Archive,
|
||||
Other
|
||||
public enum MailAttachmentType
|
||||
{
|
||||
None,
|
||||
Executable,
|
||||
Image,
|
||||
Audio,
|
||||
Video,
|
||||
PDF,
|
||||
HTML,
|
||||
RarArchive,
|
||||
Archive,
|
||||
Other
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailImportance
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Low,
|
||||
Normal,
|
||||
High
|
||||
public enum MailImportance
|
||||
{
|
||||
Low,
|
||||
Normal,
|
||||
High
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailListDisplayMode
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Spacious,
|
||||
Medium,
|
||||
Compact,
|
||||
public enum MailListDisplayMode
|
||||
{
|
||||
Spacious,
|
||||
Medium,
|
||||
Compact,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailMarkAsOption
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
WhenSelected,
|
||||
DontMark,
|
||||
AfterDelay
|
||||
public enum MailMarkAsOption
|
||||
{
|
||||
WhenSelected,
|
||||
DontMark,
|
||||
AfterDelay
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,58 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
// Synchronizer requests.
|
||||
public enum MailSynchronizerOperation
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
MarkRead,
|
||||
Move,
|
||||
Delete, // Hard delete.
|
||||
CreateDraft,
|
||||
Send,
|
||||
ChangeFlag,
|
||||
AlwaysMoveTo,
|
||||
MoveToFocused,
|
||||
Archive,
|
||||
}
|
||||
// Synchronizer requests.
|
||||
public enum MailSynchronizerOperation
|
||||
{
|
||||
MarkRead,
|
||||
Move,
|
||||
Delete, // Hard delete.
|
||||
CreateDraft,
|
||||
Send,
|
||||
ChangeFlag,
|
||||
AlwaysMoveTo,
|
||||
MoveToFocused,
|
||||
Archive,
|
||||
}
|
||||
|
||||
public enum FolderSynchronizerOperation
|
||||
{
|
||||
RenameFolder,
|
||||
EmptyFolder,
|
||||
MarkFolderRead,
|
||||
}
|
||||
public enum FolderSynchronizerOperation
|
||||
{
|
||||
RenameFolder,
|
||||
EmptyFolder,
|
||||
MarkFolderRead,
|
||||
}
|
||||
|
||||
// UI requests
|
||||
public enum MailOperation
|
||||
{
|
||||
None,
|
||||
Archive,
|
||||
UnArchive,
|
||||
SoftDelete,
|
||||
HardDelete,
|
||||
Move,
|
||||
MoveToJunk,
|
||||
MoveToFocused,
|
||||
MoveToOther,
|
||||
AlwaysMoveToOther,
|
||||
AlwaysMoveToFocused,
|
||||
SetFlag,
|
||||
ClearFlag,
|
||||
MarkAsRead,
|
||||
MarkAsUnread,
|
||||
MarkAsNotJunk,
|
||||
Seperator,
|
||||
Ignore,
|
||||
Reply,
|
||||
ReplyAll,
|
||||
Zoom,
|
||||
SaveAs,
|
||||
Find,
|
||||
Forward,
|
||||
DarkEditor,
|
||||
LightEditor,
|
||||
Print,
|
||||
ViewMessageSource,
|
||||
DiscardLocalDraft,
|
||||
Navigate // For toast activation
|
||||
// UI requests
|
||||
public enum MailOperation
|
||||
{
|
||||
None,
|
||||
Archive,
|
||||
UnArchive,
|
||||
SoftDelete,
|
||||
HardDelete,
|
||||
Move,
|
||||
MoveToJunk,
|
||||
MoveToFocused,
|
||||
MoveToOther,
|
||||
AlwaysMoveToOther,
|
||||
AlwaysMoveToFocused,
|
||||
SetFlag,
|
||||
ClearFlag,
|
||||
MarkAsRead,
|
||||
MarkAsUnread,
|
||||
MarkAsNotJunk,
|
||||
Seperator,
|
||||
Ignore,
|
||||
Reply,
|
||||
ReplyAll,
|
||||
Zoom,
|
||||
SaveAs,
|
||||
Find,
|
||||
Forward,
|
||||
DarkEditor,
|
||||
LightEditor,
|
||||
Print,
|
||||
ViewMessageSource,
|
||||
DiscardLocalDraft,
|
||||
Navigate // For toast activation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailProviderType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Outlook,
|
||||
Gmail,
|
||||
IMAP4 = 4 // 2-3 were removed after release. Don't change for backward compatibility.
|
||||
public enum MailProviderType
|
||||
{
|
||||
Outlook,
|
||||
Gmail,
|
||||
IMAP4 = 4 // 2-3 were removed after release. Don't change for backward compatibility.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum MailSynchronizationType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
UpdateProfile, // Only update profile information
|
||||
ExecuteRequests, // Run the queued requests, and then synchronize if needed.
|
||||
FoldersOnly, // Only synchronize folder metadata.
|
||||
InboxOnly, // Only Inbox, Sent, Draft and Deleted folders.
|
||||
CustomFolders, // Only sync folders that are specified in the options.
|
||||
FullFolders, // Synchronize all folders. This won't update profile or alias information.
|
||||
Alias, // Only update alias information
|
||||
IMAPIdle // Idle client triggered synchronization.
|
||||
public enum MailSynchronizationType
|
||||
{
|
||||
UpdateProfile, // Only update profile information
|
||||
ExecuteRequests, // Run the queued requests, and then synchronize if needed.
|
||||
FoldersOnly, // Only synchronize folder metadata.
|
||||
InboxOnly, // Only Inbox, Sent, Draft and Deleted folders.
|
||||
CustomFolders, // Only sync folders that are specified in the options.
|
||||
FullFolders, // Synchronize all folders. This won't update profile or alias information.
|
||||
Alias, // Only update alias information
|
||||
IMAPIdle // Idle client triggered synchronization.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum NavigationReferenceFrame
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
ShellFrame,
|
||||
RenderingFrame
|
||||
public enum NavigationReferenceFrame
|
||||
{
|
||||
ShellFrame,
|
||||
RenderingFrame
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the potential reasons for picking folder in the folder picking dialog.
|
||||
/// </summary>
|
||||
public enum PickFolderReason
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Move,
|
||||
SpecialFolder,
|
||||
Any
|
||||
/// <summary>
|
||||
/// Defines the potential reasons for picking folder in the folder picking dialog.
|
||||
/// </summary>
|
||||
public enum PickFolderReason
|
||||
{
|
||||
Move,
|
||||
SpecialFolder,
|
||||
Any
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum PrintingResult
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Abandoned,
|
||||
Canceled,
|
||||
Failed,
|
||||
Submitted
|
||||
public enum PrintingResult
|
||||
{
|
||||
Abandoned,
|
||||
Canceled,
|
||||
Failed,
|
||||
Submitted
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// What should happen to server app when the client is terminated.
|
||||
/// </summary>
|
||||
public enum ServerBackgroundMode
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
MinimizedTray, // Still runs, tray icon is visible.
|
||||
Invisible, // Still runs, tray icon is invisible.
|
||||
Terminate // Server is terminated as Wino terminates.
|
||||
/// <summary>
|
||||
/// What should happen to server app when the client is terminated.
|
||||
/// </summary>
|
||||
public enum ServerBackgroundMode
|
||||
{
|
||||
MinimizedTray, // Still runs, tray icon is visible.
|
||||
Invisible, // Still runs, tray icon is invisible.
|
||||
Terminate // Server is terminated as Wino terminates.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum SortingOptionType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
ReceiveDate,
|
||||
Sender
|
||||
public enum SortingOptionType
|
||||
{
|
||||
ReceiveDate,
|
||||
Sender
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum SpecialFolderType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Inbox,
|
||||
Starred,
|
||||
Important,
|
||||
Sent,
|
||||
Draft,
|
||||
Archive,
|
||||
Deleted,
|
||||
Junk,
|
||||
Chat,
|
||||
Category,
|
||||
Unread,
|
||||
Forums,
|
||||
Updates,
|
||||
Personal,
|
||||
Promotions,
|
||||
Social,
|
||||
Other,
|
||||
More
|
||||
public enum SpecialFolderType
|
||||
{
|
||||
Inbox,
|
||||
Starred,
|
||||
Important,
|
||||
Sent,
|
||||
Draft,
|
||||
Archive,
|
||||
Deleted,
|
||||
Junk,
|
||||
Chat,
|
||||
Category,
|
||||
Unread,
|
||||
Forums,
|
||||
Updates,
|
||||
Personal,
|
||||
Promotions,
|
||||
Social,
|
||||
Other,
|
||||
More
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum SpecialImapProvider
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
iCloud,
|
||||
Yahoo
|
||||
public enum SpecialImapProvider
|
||||
{
|
||||
None,
|
||||
iCloud,
|
||||
Yahoo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum StartupBehaviorResult
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Enabled,
|
||||
Disabled,
|
||||
DisabledByUser,
|
||||
DisabledByPolicy,
|
||||
Fatal
|
||||
public enum StartupBehaviorResult
|
||||
{
|
||||
Enabled,
|
||||
Disabled,
|
||||
DisabledByUser,
|
||||
DisabledByPolicy,
|
||||
Fatal
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
// From the SDK.
|
||||
public enum StorePurchaseResult
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// The purchase request succeeded.
|
||||
Succeeded,
|
||||
//
|
||||
// Summary:
|
||||
// The current user has already purchased the specified app or add-on.
|
||||
AlreadyPurchased,
|
||||
//
|
||||
// Summary:
|
||||
// The purchase request did not succeed.
|
||||
NotPurchased,
|
||||
// From the SDK.
|
||||
public enum StorePurchaseResult
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// The purchase request succeeded.
|
||||
Succeeded,
|
||||
//
|
||||
// Summary:
|
||||
// The current user has already purchased the specified app or add-on.
|
||||
AlreadyPurchased,
|
||||
//
|
||||
// Summary:
|
||||
// The purchase request did not succeed.
|
||||
NotPurchased,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum SynchronizationCompletedState
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Success, // All succeeded.
|
||||
Canceled, // Canceled by user or HTTP call.
|
||||
Failed // Exception.
|
||||
public enum SynchronizationCompletedState
|
||||
{
|
||||
Success, // All succeeded.
|
||||
Canceled, // Canceled by user or HTTP call.
|
||||
Failed // Exception.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration for the source of synchronization.
|
||||
/// Right now it can either be from the client or the server.
|
||||
/// </summary>
|
||||
public enum SynchronizationSource
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Client,
|
||||
Server
|
||||
/// <summary>
|
||||
/// Enumeration for the source of synchronization.
|
||||
/// Right now it can either be from the client or the server.
|
||||
/// </summary>
|
||||
public enum SynchronizationSource
|
||||
{
|
||||
Client,
|
||||
Server
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum WinoAppType
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Unknown,
|
||||
Mail,
|
||||
Calendar
|
||||
public enum WinoAppType
|
||||
{
|
||||
Unknown,
|
||||
Mail,
|
||||
Calendar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum WinoCustomMessageDialogIcon
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
Information,
|
||||
Warning,
|
||||
Error,
|
||||
Question
|
||||
public enum WinoCustomMessageDialogIcon
|
||||
{
|
||||
Information,
|
||||
Warning,
|
||||
Error,
|
||||
Question
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// All registered views.
|
||||
/// </summary>
|
||||
public enum WinoPage
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
IdlePage,
|
||||
ComposePage,
|
||||
SettingsPage,
|
||||
MailRenderingPage,
|
||||
WelcomePage,
|
||||
AccountDetailsPage,
|
||||
MergedAccountDetailsPage,
|
||||
ManageAccountsPage,
|
||||
AccountManagementPage,
|
||||
SignatureManagementPage,
|
||||
AboutPage,
|
||||
PersonalizationPage,
|
||||
MessageListPage,
|
||||
MailListPage,
|
||||
ReadComposePanePage,
|
||||
LanguageTimePage,
|
||||
AppPreferencesPage,
|
||||
SettingOptionsPage,
|
||||
AliasManagementPage,
|
||||
/// <summary>
|
||||
/// All registered views.
|
||||
/// </summary>
|
||||
public enum WinoPage
|
||||
{
|
||||
None,
|
||||
IdlePage,
|
||||
ComposePage,
|
||||
SettingsPage,
|
||||
MailRenderingPage,
|
||||
WelcomePage,
|
||||
AccountDetailsPage,
|
||||
MergedAccountDetailsPage,
|
||||
ManageAccountsPage,
|
||||
AccountManagementPage,
|
||||
SignatureManagementPage,
|
||||
AboutPage,
|
||||
PersonalizationPage,
|
||||
MessageListPage,
|
||||
MailListPage,
|
||||
ReadComposePanePage,
|
||||
LanguageTimePage,
|
||||
AppPreferencesPage,
|
||||
SettingOptionsPage,
|
||||
AliasManagementPage,
|
||||
|
||||
// Calendar
|
||||
CalendarPage,
|
||||
CalendarSettingsPage,
|
||||
EventDetailsPage
|
||||
// Calendar
|
||||
CalendarPage,
|
||||
CalendarSettingsPage,
|
||||
EventDetailsPage
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
namespace Wino.Core.Domain.Enums;
|
||||
|
||||
public enum WinoServerConnectionStatus
|
||||
namespace Wino.Core.Domain.Enums
|
||||
{
|
||||
None,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disconnected,
|
||||
Failed
|
||||
public enum WinoServerConnectionStatus
|
||||
{
|
||||
None,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disconnected,
|
||||
Failed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class AccountSetupCanceledException : System.Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public class AccountSetupCanceledException : System.Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Thrown when IAuthenticator requires user interaction to fix authentication issues.
|
||||
/// It can be expired and can't restorable token, or some stuff that requires re-authentication.
|
||||
/// </summary>
|
||||
public class AuthenticationAttentionException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public AuthenticationAttentionException(MailAccount account)
|
||||
/// <summary>
|
||||
/// Thrown when IAuthenticator requires user interaction to fix authentication issues.
|
||||
/// It can be expired and can't restorable token, or some stuff that requires re-authentication.
|
||||
/// </summary>
|
||||
public class AuthenticationAttentionException : Exception
|
||||
{
|
||||
Account = account;
|
||||
}
|
||||
public AuthenticationAttentionException(MailAccount account)
|
||||
{
|
||||
Account = account;
|
||||
}
|
||||
|
||||
public MailAccount Account { get; }
|
||||
public MailAccount Account { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// All exceptions related to authentication.
|
||||
/// </summary>
|
||||
public class AuthenticationException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public AuthenticationException(string message) : base(message)
|
||||
/// <summary>
|
||||
/// All exceptions related to authentication.
|
||||
/// </summary>
|
||||
public class AuthenticationException : Exception
|
||||
{
|
||||
}
|
||||
public AuthenticationException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public AuthenticationException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
public AuthenticationException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// An exception thrown when the background task registration is failed.
|
||||
/// </summary>
|
||||
public class BackgroundTaskRegistrationFailedException : Exception { }
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception thrown when the background task registration is failed.
|
||||
/// </summary>
|
||||
public class BackgroundTaskRegistrationFailedException : Exception { }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Thrown when composer cant find the mime to load.
|
||||
/// </summary>
|
||||
public class ComposerMimeNotFoundException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrown when composer cant find the mime to load.
|
||||
/// </summary>
|
||||
public class ComposerMimeNotFoundException : Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class CustomThemeCreationFailedException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public CustomThemeCreationFailedException(string message) : base(message)
|
||||
public class CustomThemeCreationFailedException : Exception
|
||||
{
|
||||
public CustomThemeCreationFailedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class GoogleAuthenticationException : System.Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public GoogleAuthenticationException(string message) : base(message) { }
|
||||
public class GoogleAuthenticationException : System.Exception
|
||||
{
|
||||
public GoogleAuthenticationException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class ImapClientPoolException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
||||
public class ImapClientPoolException : Exception
|
||||
{
|
||||
ProtocolLog = protocolLog;
|
||||
}
|
||||
public ImapClientPoolException(Exception innerException, string protocolLog) : base(Translator.Exception_ImapClientPoolFailed, innerException)
|
||||
{
|
||||
ProtocolLog = protocolLog;
|
||||
}
|
||||
|
||||
public string ProtocolLog { get; }
|
||||
public string ProtocolLog { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
using Wino.Core.Domain.Models.AutoDiscovery;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class ImapConnectionFailedPackage
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public ImapConnectionFailedPackage(string errorMessage, string protocolLog, AutoDiscoverySettings settings)
|
||||
public class ImapConnectionFailedPackage
|
||||
{
|
||||
ErrorMessage = errorMessage;
|
||||
ProtocolLog = protocolLog;
|
||||
Settings = settings;
|
||||
}
|
||||
public ImapConnectionFailedPackage(string errorMessage, string protocolLog, AutoDiscoverySettings settings)
|
||||
{
|
||||
ErrorMessage = errorMessage;
|
||||
ProtocolLog = protocolLog;
|
||||
Settings = settings;
|
||||
}
|
||||
|
||||
public AutoDiscoverySettings Settings { get; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public string ProtocolLog { get; }
|
||||
public AutoDiscoverySettings Settings { get; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public string ProtocolLog { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class ImapSynchronizerStrategyException : System.Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public ImapSynchronizerStrategyException(string message) : base(message)
|
||||
public class ImapSynchronizerStrategyException : System.Exception
|
||||
{
|
||||
public ImapSynchronizerStrategyException(string message) : base(message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class ImapTestSSLCertificateException : System.Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public ImapTestSSLCertificateException(string issuer, string expirationDateString, string validFromDateString)
|
||||
public class ImapTestSSLCertificateException : System.Exception
|
||||
{
|
||||
Issuer = issuer;
|
||||
ExpirationDateString = expirationDateString;
|
||||
ValidFromDateString = validFromDateString;
|
||||
public ImapTestSSLCertificateException(string issuer, string expirationDateString, string validFromDateString)
|
||||
{
|
||||
Issuer = issuer;
|
||||
ExpirationDateString = expirationDateString;
|
||||
ValidFromDateString = validFromDateString;
|
||||
}
|
||||
|
||||
public string Issuer { get; set; }
|
||||
public string ExpirationDateString { get; set; }
|
||||
public string ValidFromDateString { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public string Issuer { get; set; }
|
||||
public string ExpirationDateString { get; set; }
|
||||
public string ValidFromDateString { get; set; }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class InvalidMoveTargetException : Exception { }
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public class InvalidMoveTargetException : Exception { }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class MissingAliasException : System.Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public MissingAliasException() : base(Translator.Exception_MissingAlias) { }
|
||||
public class MissingAliasException : System.Exception
|
||||
{
|
||||
public MissingAliasException() : base(Translator.Exception_MissingAlias) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class SynchronizerEntityNotFoundException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public SynchronizerEntityNotFoundException(string message) : base(message)
|
||||
public class SynchronizerEntityNotFoundException : Exception
|
||||
{
|
||||
public SynchronizerEntityNotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
public class SynchronizerException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public SynchronizerException(string message) : base(message)
|
||||
public class SynchronizerException : Exception
|
||||
{
|
||||
}
|
||||
public SynchronizerException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public SynchronizerException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
public SynchronizerException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// When IMAP account's system folder configuration setup is not done yet.
|
||||
/// </summary>
|
||||
public class SystemFolderConfigurationMissingException : System.Exception { }
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// When IMAP account's system folder configuration setup is not done yet.
|
||||
/// </summary>
|
||||
public class SystemFolderConfigurationMissingException : System.Exception { }
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when special folder is needed for an operation but it couldn't be found.
|
||||
/// </summary>
|
||||
public class UnavailableSpecialFolderException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public UnavailableSpecialFolderException(SpecialFolderType specialFolderType, Guid accountId)
|
||||
/// <summary>
|
||||
/// Emitted when special folder is needed for an operation but it couldn't be found.
|
||||
/// </summary>
|
||||
public class UnavailableSpecialFolderException : Exception
|
||||
{
|
||||
SpecialFolderType = specialFolderType;
|
||||
AccountId = accountId;
|
||||
}
|
||||
public UnavailableSpecialFolderException(SpecialFolderType specialFolderType, Guid accountId)
|
||||
{
|
||||
SpecialFolderType = specialFolderType;
|
||||
AccountId = accountId;
|
||||
}
|
||||
|
||||
public SpecialFolderType SpecialFolderType { get; }
|
||||
public Guid AccountId { get; set; }
|
||||
public SpecialFolderType SpecialFolderType { get; }
|
||||
public Guid AccountId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// All server crash types. Wino Server ideally should not throw anything else than this Exception type.
|
||||
/// </summary>
|
||||
public class WinoServerException : Exception
|
||||
namespace Wino.Core.Domain.Exceptions
|
||||
{
|
||||
public WinoServerException(string message) : base(message) { }
|
||||
/// <summary>
|
||||
/// All server crash types. Wino Server ideally should not throw anything else than this Exception type.
|
||||
/// </summary>
|
||||
public class WinoServerException : Exception
|
||||
{
|
||||
public WinoServerException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
using System;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
|
||||
namespace Wino.Core.Domain.Extensions;
|
||||
|
||||
public static class DateTimeExtensions
|
||||
namespace Wino.Core.Domain.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a date range for the month of the given date.
|
||||
/// </summary>
|
||||
/// <param name="date">Date to get range for.</param>
|
||||
public static DateRange GetMonthDateRangeStartingWeekday(this DateTime date, DayOfWeek WeekStartDay)
|
||||
public static class DateTimeExtensions
|
||||
{
|
||||
DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1);
|
||||
/// <summary>
|
||||
/// Returns a date range for the month of the given date.
|
||||
/// </summary>
|
||||
/// <param name="date">Date to get range for.</param>
|
||||
public static DateRange GetMonthDateRangeStartingWeekday(this DateTime date, DayOfWeek WeekStartDay)
|
||||
{
|
||||
DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1);
|
||||
|
||||
int daysToSubtract = (7 + (firstDayOfMonth.DayOfWeek - WeekStartDay)) % 7;
|
||||
DateTime rangeStart = firstDayOfMonth.AddDays(-daysToSubtract);
|
||||
int daysToSubtract = (7 + (firstDayOfMonth.DayOfWeek - WeekStartDay)) % 7;
|
||||
DateTime rangeStart = firstDayOfMonth.AddDays(-daysToSubtract);
|
||||
|
||||
DateTime rangeEnd = rangeStart.AddDays(34);
|
||||
DateTime rangeEnd = rangeStart.AddDays(34);
|
||||
|
||||
return new DateRange(rangeStart, rangeEnd);
|
||||
}
|
||||
return new DateRange(rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
public static DateTime GetWeekStartDateForDate(this DateTime date, DayOfWeek firstDayOfWeek)
|
||||
{
|
||||
// Detect the first day of the week that contains the selected date.
|
||||
int diff = (7 + (date.DayOfWeek - firstDayOfWeek)) % 7;
|
||||
public static DateTime GetWeekStartDateForDate(this DateTime date, DayOfWeek firstDayOfWeek)
|
||||
{
|
||||
// Detect the first day of the week that contains the selected date.
|
||||
int diff = (7 + (date.DayOfWeek - firstDayOfWeek)) % 7;
|
||||
|
||||
// Start loading from this date instead of visible date.
|
||||
return date.AddDays(-diff).Date;
|
||||
// Start loading from this date instead of visible date.
|
||||
return date.AddDays(-diff).Date;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wino.Core.Domain.Extensions;
|
||||
|
||||
public static class ExceptionExtensions
|
||||
namespace Wino.Core.Domain.Extensions
|
||||
{
|
||||
public static IEnumerable<Exception> GetInnerExceptions(this Exception ex)
|
||||
public static class ExceptionExtensions
|
||||
{
|
||||
if (ex == null)
|
||||
public static IEnumerable<Exception> GetInnerExceptions(this Exception ex)
|
||||
{
|
||||
throw new ArgumentNullException("ex");
|
||||
}
|
||||
if (ex == null)
|
||||
{
|
||||
throw new ArgumentNullException("ex");
|
||||
}
|
||||
|
||||
var innerException = ex;
|
||||
do
|
||||
{
|
||||
yield return innerException;
|
||||
innerException = innerException.InnerException;
|
||||
var innerException = ex;
|
||||
do
|
||||
{
|
||||
yield return innerException;
|
||||
innerException = innerException.InnerException;
|
||||
}
|
||||
while (innerException != null);
|
||||
}
|
||||
while (innerException != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Wino.Core.Domain.Extensions;
|
||||
|
||||
public static class MimeExtensions
|
||||
namespace Wino.Core.Domain.Extensions
|
||||
{
|
||||
public static string GetBase64MimeMessage(this MimeKit.MimeMessage message)
|
||||
public static class MimeExtensions
|
||||
{
|
||||
using MemoryStream memoryStream = new();
|
||||
public static string GetBase64MimeMessage(this MimeKit.MimeMessage message)
|
||||
{
|
||||
using MemoryStream memoryStream = new();
|
||||
|
||||
message.WriteTo(memoryStream);
|
||||
message.WriteTo(memoryStream);
|
||||
|
||||
return Convert.ToBase64String(memoryStream.ToArray());
|
||||
return Convert.ToBase64String(memoryStream.ToArray());
|
||||
}
|
||||
|
||||
public static MimeKit.MimeMessage GetMimeMessageFromBase64(this string base64)
|
||||
=> MimeKit.MimeMessage.Load(new System.IO.MemoryStream(Convert.FromBase64String(base64)));
|
||||
}
|
||||
|
||||
public static MimeKit.MimeMessage GetMimeMessageFromBase64(this string base64)
|
||||
=> MimeKit.MimeMessage.Load(new System.IO.MemoryStream(Convert.FromBase64String(base64)));
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountCalendar
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
string Name { get; set; }
|
||||
string TextColorHex { get; set; }
|
||||
string BackgroundColorHex { get; set; }
|
||||
bool IsPrimary { get; set; }
|
||||
Guid AccountId { get; set; }
|
||||
string RemoteCalendarId { get; set; }
|
||||
bool IsExtended { get; set; }
|
||||
Guid Id { get; set; }
|
||||
public interface IAccountCalendar
|
||||
{
|
||||
string Name { get; set; }
|
||||
string TextColorHex { get; set; }
|
||||
string BackgroundColorHex { get; set; }
|
||||
bool IsPrimary { get; set; }
|
||||
Guid AccountId { get; set; }
|
||||
string RemoteCalendarId { get; set; }
|
||||
bool IsExtended { get; set; }
|
||||
Guid Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
using System.Threading.Tasks;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountCreationDialog
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource);
|
||||
void Complete(bool cancel);
|
||||
AccountCreationDialogState State { get; set; }
|
||||
public interface IAccountCreationDialog
|
||||
{
|
||||
Task ShowDialogAsync(CancellationTokenSource cancellationTokenSource);
|
||||
void Complete(bool cancel);
|
||||
AccountCreationDialogState State { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountMenuItem : IMenuItem
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
bool IsEnabled { get; set; }
|
||||
double SynchronizationProgress { get; set; }
|
||||
int UnreadItemCount { get; set; }
|
||||
IEnumerable<MailAccount> HoldingAccounts { get; }
|
||||
void UpdateAccount(MailAccount account);
|
||||
}
|
||||
public interface IAccountMenuItem : IMenuItem
|
||||
{
|
||||
bool IsEnabled { get; set; }
|
||||
double SynchronizationProgress { get; set; }
|
||||
int UnreadItemCount { get; set; }
|
||||
IEnumerable<MailAccount> HoldingAccounts { get; }
|
||||
void UpdateAccount(MailAccount account);
|
||||
}
|
||||
|
||||
public interface IMergedAccountMenuItem : IAccountMenuItem
|
||||
{
|
||||
int MergedAccountCount { get; }
|
||||
public interface IMergedAccountMenuItem : IAccountMenuItem
|
||||
{
|
||||
int MergedAccountCount { get; }
|
||||
|
||||
MergedInbox Parameter { get; }
|
||||
MergedInbox Parameter { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountPickerDialog
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
public interface IAccountPickerDialog
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,38 @@
|
||||
using System;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountProviderDetailViewModel
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity id that will help to identify the startup entity on launch.
|
||||
/// </summary>
|
||||
Guid StartupEntityId { get; }
|
||||
public interface IAccountProviderDetailViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity id that will help to identify the startup entity on launch.
|
||||
/// </summary>
|
||||
Guid StartupEntityId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Name representation of the view model that will be used to identify the startup entity on launch.
|
||||
/// </summary>
|
||||
string StartupEntityTitle { get; }
|
||||
/// <summary>
|
||||
/// Name representation of the view model that will be used to identify the startup entity on launch.
|
||||
/// </summary>
|
||||
string StartupEntityTitle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// E-mail addresses that this account holds.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// E-mail addresses that this account holds.
|
||||
/// </summary>
|
||||
|
||||
string StartupEntityAddresses { get; }
|
||||
string StartupEntityAddresses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the account order in the accounts list.
|
||||
/// </summary>
|
||||
int Order { get; }
|
||||
/// <summary>
|
||||
/// Represents the account order in the accounts list.
|
||||
/// </summary>
|
||||
int Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Provider details of the account.
|
||||
/// </summary>
|
||||
IProviderDetail ProviderDetail { get; set; }
|
||||
/// <summary>
|
||||
/// Provider details of the account.
|
||||
/// </summary>
|
||||
IProviderDetail ProviderDetail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many accounts this provider has.
|
||||
/// </summary>
|
||||
int HoldingAccountCount { get; }
|
||||
/// <summary>
|
||||
/// How many accounts this provider has.
|
||||
/// </summary>
|
||||
int HoldingAccountCount { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountProviderDetails
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
MailAccount Account { get; set; }
|
||||
bool AutoExtend { get; set; }
|
||||
IProviderDetail ProviderDetail { get; set; }
|
||||
public interface IAccountProviderDetails
|
||||
{
|
||||
MailAccount Account { get; set; }
|
||||
bool AutoExtend { get; set; }
|
||||
IProviderDetail ProviderDetail { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,155 +5,156 @@ using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
|
||||
namespace Wino.Core.Domain.Interfaces;
|
||||
|
||||
public interface IAccountService
|
||||
namespace Wino.Core.Domain.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Current IAuthenticator that should receive external authentication process to continue with.
|
||||
/// For example: Google auth will launch a browser authentication. After it completes, this is the IAuthenticator
|
||||
/// to continue process for token exchange.
|
||||
/// </summary>
|
||||
IAuthenticator ExternalAuthenticationAuthenticator { get; set; }
|
||||
public interface IAccountService
|
||||
{
|
||||
/// <summary>
|
||||
/// Current IAuthenticator that should receive external authentication process to continue with.
|
||||
/// For example: Google auth will launch a browser authentication. After it completes, this is the IAuthenticator
|
||||
/// to continue process for token exchange.
|
||||
/// </summary>
|
||||
IAuthenticator ExternalAuthenticationAuthenticator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all local accounts.
|
||||
/// </summary>
|
||||
/// <returns>All local accounts</returns>
|
||||
Task<List<MailAccount>> GetAccountsAsync();
|
||||
/// <summary>
|
||||
/// Returns all local accounts.
|
||||
/// </summary>
|
||||
/// <returns>All local accounts</returns>
|
||||
Task<List<MailAccount>> GetAccountsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Returns single MailAccount
|
||||
/// </summary>
|
||||
/// <param name="accountId">AccountId.</param>
|
||||
Task<MailAccount> GetAccountAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Returns single MailAccount
|
||||
/// </summary>
|
||||
/// <param name="accountId">AccountId.</param>
|
||||
Task<MailAccount> GetAccountAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all information about the account, including token information.
|
||||
/// </summary>
|
||||
/// <param name="account">MailAccount to be removed</param>
|
||||
Task DeleteAccountAsync(MailAccount account);
|
||||
/// <summary>
|
||||
/// Deletes all information about the account, including token information.
|
||||
/// </summary>
|
||||
/// <param name="account">MailAccount to be removed</param>
|
||||
Task DeleteAccountAsync(MailAccount account);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the custom server information for the given account id.
|
||||
/// </summary>
|
||||
Task<CustomServerInformation> GetAccountCustomServerInformationAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Returns the custom server information for the given account id.
|
||||
/// </summary>
|
||||
Task<CustomServerInformation> GetAccountCustomServerInformationAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the given account properties.
|
||||
/// </summary>
|
||||
Task UpdateAccountAsync(MailAccount account);
|
||||
/// <summary>
|
||||
/// Updates the given account properties.
|
||||
/// </summary>
|
||||
Task UpdateAccountAsync(MailAccount account);
|
||||
|
||||
/// <summary>
|
||||
/// Creates new account with the given server information if any.
|
||||
/// Also sets the account as Startup account if there are no accounts.
|
||||
/// </summary>
|
||||
Task CreateAccountAsync(MailAccount account, CustomServerInformation customServerInformation);
|
||||
/// <summary>
|
||||
/// Creates new account with the given server information if any.
|
||||
/// Also sets the account as Startup account if there are no accounts.
|
||||
/// </summary>
|
||||
Task CreateAccountAsync(MailAccount account, CustomServerInformation customServerInformation);
|
||||
|
||||
/// <summary>
|
||||
/// Fixed authentication errors for account by forcing interactive login.
|
||||
/// </summary>
|
||||
Task FixTokenIssuesAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Fixed authentication errors for account by forcing interactive login.
|
||||
/// </summary>
|
||||
Task FixTokenIssuesAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Removed the attention from an account.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to remove from</param>
|
||||
Task ClearAccountAttentionAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Removed the attention from an account.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to remove from</param>
|
||||
Task ClearAccountAttentionAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the account synchronization identifier.
|
||||
/// For example: Gmail uses this identifier to keep track of the last synchronization.
|
||||
/// Update is ignored for Gmail if the new identifier is older than the current one.
|
||||
/// </summary>
|
||||
/// <param name="newIdentifier">Identifier to update</param>
|
||||
/// <returns>Current account synchronization modifier.</returns>
|
||||
Task<string> UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier);
|
||||
/// <summary>
|
||||
/// Updates the account synchronization identifier.
|
||||
/// For example: Gmail uses this identifier to keep track of the last synchronization.
|
||||
/// Update is ignored for Gmail if the new identifier is older than the current one.
|
||||
/// </summary>
|
||||
/// <param name="newIdentifier">Identifier to update</param>
|
||||
/// <returns>Current account synchronization modifier.</returns>
|
||||
Task<string> UpdateSynchronizationIdentifierAsync(Guid accountId, string newIdentifier);
|
||||
|
||||
/// <summary>
|
||||
/// Renames the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged Inbox id</param>
|
||||
/// <param name="newName">New name for the merged/linked inbox.</param>
|
||||
Task RenameMergedAccountAsync(Guid mergedInboxId, string newName);
|
||||
/// <summary>
|
||||
/// Renames the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged Inbox id</param>
|
||||
/// <param name="newName">New name for the merged/linked inbox.</param>
|
||||
Task RenameMergedAccountAsync(Guid mergedInboxId, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new merged inbox with the given accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInbox">Merged inbox properties.</param>
|
||||
/// <param name="accountsToMerge">List of accounts to merge together.</param>
|
||||
Task CreateMergeAccountsAsync(MergedInbox mergedInbox, IEnumerable<MailAccount> accountsToMerge);
|
||||
/// <summary>
|
||||
/// Creates a new merged inbox with the given accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInbox">Merged inbox properties.</param>
|
||||
/// <param name="accountsToMerge">List of accounts to merge together.</param>
|
||||
Task CreateMergeAccountsAsync(MergedInbox mergedInbox, IEnumerable<MailAccount> accountsToMerge);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the merged inbox with the given id with the new linked accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Updating merged inbox id.</param>
|
||||
/// <param name="linkedAccountIds">List of linked account ids.</param>
|
||||
Task UpdateMergedInboxAsync(Guid mergedInboxId, IEnumerable<Guid> linkedAccountIds);
|
||||
/// <summary>
|
||||
/// Updates the merged inbox with the given id with the new linked accounts.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Updating merged inbox id.</param>
|
||||
/// <param name="linkedAccountIds">List of linked account ids.</param>
|
||||
Task UpdateMergedInboxAsync(Guid mergedInboxId, IEnumerable<Guid> linkedAccountIds);
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged inbox id to destroy.</param>
|
||||
Task UnlinkMergedInboxAsync(Guid mergedInboxId);
|
||||
/// <summary>
|
||||
/// Destroys the merged inbox with the given id.
|
||||
/// </summary>
|
||||
/// <param name="mergedInboxId">Merged inbox id to destroy.</param>
|
||||
Task UnlinkMergedInboxAsync(Guid mergedInboxId);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the account listing orders.
|
||||
/// </summary>
|
||||
/// <param name="accountIdOrderPair">AccountId-OrderNumber pair for all accounts.</param>
|
||||
Task UpdateAccountOrdersAsync(Dictionary<Guid, int> accountIdOrderPair);
|
||||
/// <summary>
|
||||
/// Updates the account listing orders.
|
||||
/// </summary>
|
||||
/// <param name="accountIdOrderPair">AccountId-OrderNumber pair for all accounts.</param>
|
||||
Task UpdateAccountOrdersAsync(Dictionary<Guid, int> accountIdOrderPair);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the account aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>A list of MailAccountAlias that has e-mail aliases.</returns>
|
||||
Task<List<MailAccountAlias>> GetAccountAliasesAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Returns the account aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>A list of MailAccountAlias that has e-mail aliases.</returns>
|
||||
Task<List<MailAccountAlias>> GetAccountAliasesAsync(Guid accountId);
|
||||
|
||||
/// <summary>
|
||||
/// Updated account's aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update aliases for.</param>
|
||||
/// <param name="aliases">Full list of updated aliases.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateAccountAliasesAsync(Guid accountId, List<MailAccountAlias> aliases);
|
||||
/// <summary>
|
||||
/// Updated account's aliases.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update aliases for.</param>
|
||||
/// <param name="aliases">Full list of updated aliases.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateAccountAliasesAsync(Guid accountId, List<MailAccountAlias> aliases);
|
||||
|
||||
/// <summary>
|
||||
/// Delete account alias.
|
||||
/// </summary>
|
||||
/// <param name="aliasId">Alias to remove.</param>
|
||||
Task DeleteAccountAliasAsync(Guid aliasId);
|
||||
/// <summary>
|
||||
/// Delete account alias.
|
||||
/// </summary>
|
||||
/// <param name="aliasId">Alias to remove.</param>
|
||||
Task DeleteAccountAliasAsync(Guid aliasId);
|
||||
|
||||
/// <summary>
|
||||
/// Updated profile information of the account.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update info for.</param>
|
||||
/// <param name="profileInformation">Info data.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateProfileInformationAsync(Guid accountId, ProfileInformation profileInformation);
|
||||
/// <summary>
|
||||
/// Updated profile information of the account.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id to update info for.</param>
|
||||
/// <param name="profileInformation">Info data.</param>
|
||||
/// <returns></returns>
|
||||
Task UpdateProfileInformationAsync(Guid accountId, ProfileInformation profileInformation);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a root + primary alias for the account.
|
||||
/// This is only called when the account is created.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <param name="address">Address to create root primary alias from.</param>
|
||||
Task CreateRootAliasAsync(Guid accountId, string address);
|
||||
/// <summary>
|
||||
/// Creates a root + primary alias for the account.
|
||||
/// This is only called when the account is created.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <param name="address">Address to create root primary alias from.</param>
|
||||
Task CreateRootAliasAsync(Guid accountId, string address);
|
||||
|
||||
/// <summary>
|
||||
/// Will compare local-remote aliases and update the local ones or add/delete new ones.
|
||||
/// </summary>
|
||||
/// <param name="remoteAccountAliases">Remotely fetched basic alias info from synchronizer.</param>
|
||||
/// <param name="account">Account to update remote aliases for..</param>
|
||||
Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases);
|
||||
/// <summary>
|
||||
/// Will compare local-remote aliases and update the local ones or add/delete new ones.
|
||||
/// </summary>
|
||||
/// <param name="remoteAccountAliases">Remotely fetched basic alias info from synchronizer.</param>
|
||||
/// <param name="account">Account to update remote aliases for..</param>
|
||||
Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary account alias for the given account id.
|
||||
/// Used when creating draft messages.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>Primary alias for the account.</returns>
|
||||
Task<MailAccountAlias> GetPrimaryAccountAliasAsync(Guid accountId);
|
||||
Task<bool> IsAccountFocusedEnabledAsync(Guid accountId);
|
||||
/// <summary>
|
||||
/// Gets the primary account alias for the given account id.
|
||||
/// Used when creating draft messages.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Account id.</param>
|
||||
/// <returns>Primary alias for the account.</returns>
|
||||
Task<MailAccountAlias> GetPrimaryAccountAliasAsync(Guid accountId);
|
||||
Task<bool> IsAccountFocusedEnabledAsync(Guid accountId);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user