diff --git a/Wino.Core.Domain/Entities/MailCopy.cs b/Wino.Core.Domain/Entities/MailCopy.cs
index de56aa79..5075227f 100644
--- a/Wino.Core.Domain/Entities/MailCopy.cs
+++ b/Wino.Core.Domain/Entities/MailCopy.cs
@@ -107,6 +107,12 @@ namespace Wino.Core.Domain.Entities
///
public string DraftId { get; set; }
+ ///
+ /// Whether this mail is only created locally.
+ ///
+ [Ignore]
+ public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
+
///
/// Whether this copy is draft or not.
///
diff --git a/Wino.Core.Domain/Enums/MailOperation.cs b/Wino.Core.Domain/Enums/MailOperation.cs
index d221a090..483b5607 100644
--- a/Wino.Core.Domain/Enums/MailOperation.cs
+++ b/Wino.Core.Domain/Enums/MailOperation.cs
@@ -44,6 +44,7 @@
DarkEditor,
LightEditor,
Print,
+ DiscardLocalDraft,
Navigate // For toast activation
}
}
diff --git a/Wino.Core/Services/WinoRequestProcessor.cs b/Wino.Core/Services/WinoRequestProcessor.cs
index 598395ff..93c51693 100644
--- a/Wino.Core/Services/WinoRequestProcessor.cs
+++ b/Wino.Core/Services/WinoRequestProcessor.cs
@@ -25,6 +25,7 @@ namespace Wino.Core.Services
private readonly IPreferencesService _preferencesService;
private readonly IAccountService _accountService;
private readonly IDialogService _dialogService;
+ private readonly IMailService _mailService;
///
/// Set of rules that defines which action should be executed if user wants to toggle an action.
@@ -42,13 +43,15 @@ namespace Wino.Core.Services
IKeyPressService keyPressService,
IPreferencesService preferencesService,
IAccountService accountService,
- IDialogService dialogService) : base(databaseService)
+ IDialogService dialogService,
+ IMailService mailService) : base(databaseService)
{
_folderService = folderService;
_keyPressService = keyPressService;
_preferencesService = preferencesService;
_accountService = accountService;
_dialogService = dialogService;
+ _mailService = mailService;
}
public async Task> PrepareRequestsAsync(MailOperationPreperationRequest preperationRequest)
@@ -91,7 +94,11 @@ namespace Wino.Core.Services
foreach (var item in preperationRequest.MailItems)
{
- requests.Add(await GetSingleRequestAsync(item, action, moveTargetStructure, preperationRequest.ToggleExecution));
+ var singleRequest = await GetSingleRequestAsync(item, action, moveTargetStructure, preperationRequest.ToggleExecution);
+
+ if (singleRequest == null) continue;
+
+ requests.Add(singleRequest);
}
return requests;
@@ -110,6 +117,10 @@ namespace Wino.Core.Services
if (action == MailOperation.SoftDelete && mailItem.IsDraft)
action = MailOperation.HardDelete;
+ // Rule: Soft/Hard deletes on local drafts are always discard local draft.
+ if ((action == MailOperation.SoftDelete || action == MailOperation.HardDelete) && mailItem.IsLocalDraft)
+ action = MailOperation.DiscardLocalDraft;
+
// Rule: Toggle actions must be reverted if ToggleExecution is passed true.
if (shouldToggleActions)
{
@@ -179,8 +190,12 @@ namespace Wino.Core.Services
}
else if (action == MailOperation.AlwaysMoveToFocused || action == MailOperation.AlwaysMoveToOther)
return new AlwaysMoveToRequest(mailItem, action == MailOperation.AlwaysMoveToFocused);
+ else if (action == MailOperation.DiscardLocalDraft)
+ await _mailService.DeleteMailAsync(mailItem.AssignedAccount.Id, mailItem.Id);
else
throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedAction, action));
+
+ return null;
}
public async Task PrepareFolderRequestAsync(FolderOperation operation, IMailItemFolder mailItemFolder)
diff --git a/Wino.Mail.ViewModels/ComposePageViewModel.cs b/Wino.Mail.ViewModels/ComposePageViewModel.cs
index 0cbc30e8..2e083e74 100644
--- a/Wino.Mail.ViewModels/ComposePageViewModel.cs
+++ b/Wino.Mail.ViewModels/ComposePageViewModel.cs
@@ -32,21 +32,23 @@ namespace Wino.Mail.ViewModels
// Update is triggered when we leave the page.
private bool isUpdatingMimeBlocked = false;
- public bool CanSendMail => ComposingAccount != null && !IsLocalDraft && currentMimeMessage != null;
+ private bool canSendMail => ComposingAccount != null && !IsLocalDraft && CurrentMimeMessage != null;
+ [NotifyCanExecuteChangedFor(nameof(DiscardCommand))]
+ [NotifyCanExecuteChangedFor(nameof(SendCommand))]
+ [ObservableProperty]
private MimeMessage currentMimeMessage = null;
+
private readonly BodyBuilder bodyBuilder = new BodyBuilder();
- public bool IsLocalDraft => CurrentMailDraftItem != null
- && !string.IsNullOrEmpty(CurrentMailDraftItem.DraftId)
- && CurrentMailDraftItem.DraftId.StartsWith(Constants.LocalDraftStartPrefix);
-
+ public bool IsLocalDraft => CurrentMailDraftItem?.MailCopy?.IsLocalDraft ?? true;
#region Properties
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(IsLocalDraft))]
- [NotifyPropertyChangedFor(nameof(CanSendMail))]
+ [NotifyCanExecuteChangedFor(nameof(DiscardCommand))]
+ [NotifyCanExecuteChangedFor(nameof(SendCommand))]
private MailItemViewModel currentMailDraftItem;
[ObservableProperty]
@@ -62,6 +64,8 @@ namespace Wino.Mail.ViewModels
private string subject;
[ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(DiscardCommand))]
+ [NotifyCanExecuteChangedFor(nameof(SendCommand))]
private MailAccount composingAccount;
[ObservableProperty]
@@ -136,7 +140,7 @@ namespace Wino.Mail.ViewModels
private void RemoveAttachment(MailAttachmentViewModel attachmentViewModel)
=> IncludedAttachments.Remove(attachmentViewModel);
- [RelayCommand]
+ [RelayCommand(CanExecute = nameof(canSendMail))]
private async Task SendAsync()
{
// TODO: More detailed mail validations.
@@ -161,20 +165,20 @@ namespace Wino.Mail.ViewModels
var assignedAccount = CurrentMailDraftItem.AssignedAccount;
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(assignedAccount.Id, SpecialFolderType.Sent);
- var draftSendPreparationRequest = new SendDraftPreparationRequest(CurrentMailDraftItem.MailCopy, currentMimeMessage, CurrentMailDraftItem.AssignedFolder, sentFolder, CurrentMailDraftItem.AssignedAccount.Preferences);
+ var draftSendPreparationRequest = new SendDraftPreparationRequest(CurrentMailDraftItem.MailCopy, CurrentMimeMessage, CurrentMailDraftItem.AssignedFolder, sentFolder, CurrentMailDraftItem.AssignedAccount.Preferences);
await _worker.ExecuteAsync(draftSendPreparationRequest);
}
private async Task UpdateMimeChangesAsync()
{
- if (isUpdatingMimeBlocked || currentMimeMessage == null || ComposingAccount == null || CurrentMailDraftItem == null) return;
+ if (isUpdatingMimeBlocked || CurrentMimeMessage == null || ComposingAccount == null || CurrentMailDraftItem == null) return;
// Save recipients.
- SaveAddressInfo(ToItems, currentMimeMessage.To);
- SaveAddressInfo(CCItemsItems, currentMimeMessage.Cc);
- SaveAddressInfo(BCCItems, currentMimeMessage.Bcc);
+ SaveAddressInfo(ToItems, CurrentMimeMessage.To);
+ SaveAddressInfo(CCItemsItems, CurrentMimeMessage.Cc);
+ SaveAddressInfo(BCCItems, CurrentMimeMessage.Bcc);
SaveImportance();
SaveSubject();
@@ -184,13 +188,13 @@ namespace Wino.Mail.ViewModels
await UpdateMailCopyAsync();
// Save mime file.
- await _mimeFileService.SaveMimeMessageAsync(CurrentMailDraftItem.MailCopy.FileId, currentMimeMessage, ComposingAccount.Id).ConfigureAwait(false);
+ await _mimeFileService.SaveMimeMessageAsync(CurrentMailDraftItem.MailCopy.FileId, CurrentMimeMessage, ComposingAccount.Id).ConfigureAwait(false);
}
private async Task UpdateMailCopyAsync()
{
- CurrentMailDraftItem.Subject = currentMimeMessage.Subject;
- CurrentMailDraftItem.PreviewText = currentMimeMessage.TextBody;
+ CurrentMailDraftItem.Subject = CurrentMimeMessage.Subject;
+ CurrentMailDraftItem.PreviewText = CurrentMimeMessage.TextBody;
// Update database.
await _mailService.UpdateMailAsync(CurrentMailDraftItem.MailCopy);
@@ -208,13 +212,13 @@ namespace Wino.Mail.ViewModels
}
}
- private void SaveImportance() { currentMimeMessage.Importance = IsImportanceSelected ? SelectedMessageImportance : MessageImportance.Normal; }
+ private void SaveImportance() { CurrentMimeMessage.Importance = IsImportanceSelected ? SelectedMessageImportance : MessageImportance.Normal; }
private void SaveSubject()
{
if (Subject != null)
{
- currentMimeMessage.Subject = Subject;
+ CurrentMimeMessage.Subject = Subject;
}
}
@@ -227,10 +231,10 @@ namespace Wino.Mail.ViewModels
bodyBuilder.TextBody = HtmlAgilityPackExtensions.GetPreviewText(bodyBuilder.HtmlBody);
if (bodyBuilder.HtmlBody != null && bodyBuilder.TextBody != null)
- currentMimeMessage.Body = bodyBuilder.ToMessageBody();
+ CurrentMimeMessage.Body = bodyBuilder.ToMessageBody();
}
- [RelayCommand]
+ [RelayCommand(CanExecute = nameof(canSendMail))]
private async Task DiscardAsync()
{
if (ComposingAccount == null)
@@ -248,7 +252,7 @@ namespace Wino.Mail.ViewModels
isUpdatingMimeBlocked = true;
// Don't send delete request for local drafts. Just delete the record and mime locally.
- if (CurrentMailDraftItem.IsLocalDraft)
+ if (CurrentMailDraftItem.MailCopy.IsLocalDraft)
{
await _mailService.DeleteMailAsync(ComposingAccount.Id, CurrentMailDraftItem.Id);
}
@@ -413,9 +417,8 @@ namespace Wino.Mail.ViewModels
Subject = replyingMime.Subject;
- currentMimeMessage = replyingMime;
+ CurrentMimeMessage = replyingMime;
- OnPropertyChanged(nameof(CanSendMail));
Messenger.Send(new CreateNewComposeMailRequested(renderModel));
});
}
@@ -484,7 +487,9 @@ namespace Wino.Mail.ViewModels
await ExecuteUIThread(() =>
{
CurrentMailDraftItem.Update(updatedMail);
- OnPropertyChanged(nameof(CanSendMail));
+
+ DiscardCommand.NotifyCanExecuteChanged();
+ SendCommand.NotifyCanExecuteChanged();
});
}
}
diff --git a/Wino.Mail.ViewModels/Data/MailItemViewModel.cs b/Wino.Mail.ViewModels/Data/MailItemViewModel.cs
index bc147bc1..e7104246 100644
--- a/Wino.Mail.ViewModels/Data/MailItemViewModel.cs
+++ b/Wino.Mail.ViewModels/Data/MailItemViewModel.cs
@@ -1,6 +1,5 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
-using Wino.Core.Domain;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Models.MailItem;
@@ -13,8 +12,6 @@ namespace Wino.Mail.ViewModels.Data
{
public MailCopy MailCopy { get; private set; } = mailCopy;
- public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
-
public Guid UniqueId => ((IMailItem)MailCopy).UniqueId;
public string ThreadId => ((IMailItem)MailCopy).ThreadId;
public string MessageId => ((IMailItem)MailCopy).MessageId;
@@ -96,7 +93,6 @@ namespace Wino.Mail.ViewModels.Data
OnPropertyChanged(nameof(DraftId));
OnPropertyChanged(nameof(Subject));
OnPropertyChanged(nameof(PreviewText));
- OnPropertyChanged(nameof(IsLocalDraft));
}
}
}
diff --git a/Wino.Mail/Views/ComposePage.xaml b/Wino.Mail/Views/ComposePage.xaml
index f965662a..7faf05df 100644
--- a/Wino.Mail/Views/ComposePage.xaml
+++ b/Wino.Mail/Views/ComposePage.xaml
@@ -152,10 +152,7 @@
-
+