Fixed an issue where local draft is deleted via hover over action or delete button instead of discard button. Disabled discarding local drafts in compose page.
This commit is contained in:
@@ -107,6 +107,12 @@ namespace Wino.Core.Domain.Entities
|
||||
/// </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 copy is draft or not.
|
||||
/// </summary>
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
DarkEditor,
|
||||
LightEditor,
|
||||
Print,
|
||||
DiscardLocalDraft,
|
||||
Navigate // For toast activation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Wino.Core.Services
|
||||
private readonly IPreferencesService _preferencesService;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IMailService _mailService;
|
||||
|
||||
/// <summary>
|
||||
/// 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<List<IRequest>> 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<IRequest> PrepareFolderRequestAsync(FolderOperation operation, IMailItemFolder mailItemFolder)
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +152,7 @@
|
||||
<controls:WinoFontIcon Icon="Delete" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
Label="Send"
|
||||
IsEnabled="{x:Bind ViewModel.CanSendMail, Mode=OneWay}"
|
||||
Command="{x:Bind ViewModel.SendCommand}">
|
||||
<AppBarButton Label="Send" Command="{x:Bind ViewModel.SendCommand}">
|
||||
<AppBarButton.Icon>
|
||||
<controls:WinoFontIcon Icon="Send" />
|
||||
</AppBarButton.Icon>
|
||||
|
||||
Reference in New Issue
Block a user