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>
|
/// </summary>
|
||||||
public string DraftId { get; set; }
|
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>
|
/// <summary>
|
||||||
/// Whether this copy is draft or not.
|
/// Whether this copy is draft or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
DarkEditor,
|
DarkEditor,
|
||||||
LightEditor,
|
LightEditor,
|
||||||
Print,
|
Print,
|
||||||
|
DiscardLocalDraft,
|
||||||
Navigate // For toast activation
|
Navigate // For toast activation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace Wino.Core.Services
|
|||||||
private readonly IPreferencesService _preferencesService;
|
private readonly IPreferencesService _preferencesService;
|
||||||
private readonly IAccountService _accountService;
|
private readonly IAccountService _accountService;
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set of rules that defines which action should be executed if user wants to toggle an action.
|
/// 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,
|
IKeyPressService keyPressService,
|
||||||
IPreferencesService preferencesService,
|
IPreferencesService preferencesService,
|
||||||
IAccountService accountService,
|
IAccountService accountService,
|
||||||
IDialogService dialogService) : base(databaseService)
|
IDialogService dialogService,
|
||||||
|
IMailService mailService) : base(databaseService)
|
||||||
{
|
{
|
||||||
_folderService = folderService;
|
_folderService = folderService;
|
||||||
_keyPressService = keyPressService;
|
_keyPressService = keyPressService;
|
||||||
_preferencesService = preferencesService;
|
_preferencesService = preferencesService;
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
|
_mailService = mailService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<IRequest>> PrepareRequestsAsync(MailOperationPreperationRequest preperationRequest)
|
public async Task<List<IRequest>> PrepareRequestsAsync(MailOperationPreperationRequest preperationRequest)
|
||||||
@@ -91,7 +94,11 @@ namespace Wino.Core.Services
|
|||||||
|
|
||||||
foreach (var item in preperationRequest.MailItems)
|
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;
|
return requests;
|
||||||
@@ -110,6 +117,10 @@ namespace Wino.Core.Services
|
|||||||
if (action == MailOperation.SoftDelete && mailItem.IsDraft)
|
if (action == MailOperation.SoftDelete && mailItem.IsDraft)
|
||||||
action = MailOperation.HardDelete;
|
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.
|
// Rule: Toggle actions must be reverted if ToggleExecution is passed true.
|
||||||
if (shouldToggleActions)
|
if (shouldToggleActions)
|
||||||
{
|
{
|
||||||
@@ -179,8 +190,12 @@ namespace Wino.Core.Services
|
|||||||
}
|
}
|
||||||
else if (action == MailOperation.AlwaysMoveToFocused || action == MailOperation.AlwaysMoveToOther)
|
else if (action == MailOperation.AlwaysMoveToFocused || action == MailOperation.AlwaysMoveToOther)
|
||||||
return new AlwaysMoveToRequest(mailItem, action == MailOperation.AlwaysMoveToFocused);
|
return new AlwaysMoveToRequest(mailItem, action == MailOperation.AlwaysMoveToFocused);
|
||||||
|
else if (action == MailOperation.DiscardLocalDraft)
|
||||||
|
await _mailService.DeleteMailAsync(mailItem.AssignedAccount.Id, mailItem.Id);
|
||||||
else
|
else
|
||||||
throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedAction, action));
|
throw new NotSupportedException(string.Format(Translator.Exception_UnsupportedAction, action));
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IRequest> PrepareFolderRequestAsync(FolderOperation operation, IMailItemFolder mailItemFolder)
|
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.
|
// Update is triggered when we leave the page.
|
||||||
private bool isUpdatingMimeBlocked = false;
|
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 MimeMessage currentMimeMessage = null;
|
||||||
|
|
||||||
private readonly BodyBuilder bodyBuilder = new BodyBuilder();
|
private readonly BodyBuilder bodyBuilder = new BodyBuilder();
|
||||||
|
|
||||||
public bool IsLocalDraft => CurrentMailDraftItem != null
|
public bool IsLocalDraft => CurrentMailDraftItem?.MailCopy?.IsLocalDraft ?? true;
|
||||||
&& !string.IsNullOrEmpty(CurrentMailDraftItem.DraftId)
|
|
||||||
&& CurrentMailDraftItem.DraftId.StartsWith(Constants.LocalDraftStartPrefix);
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
[NotifyPropertyChangedFor(nameof(IsLocalDraft))]
|
[NotifyPropertyChangedFor(nameof(IsLocalDraft))]
|
||||||
[NotifyPropertyChangedFor(nameof(CanSendMail))]
|
[NotifyCanExecuteChangedFor(nameof(DiscardCommand))]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(SendCommand))]
|
||||||
private MailItemViewModel currentMailDraftItem;
|
private MailItemViewModel currentMailDraftItem;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -62,6 +64,8 @@ namespace Wino.Mail.ViewModels
|
|||||||
private string subject;
|
private string subject;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(DiscardCommand))]
|
||||||
|
[NotifyCanExecuteChangedFor(nameof(SendCommand))]
|
||||||
private MailAccount composingAccount;
|
private MailAccount composingAccount;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -136,7 +140,7 @@ namespace Wino.Mail.ViewModels
|
|||||||
private void RemoveAttachment(MailAttachmentViewModel attachmentViewModel)
|
private void RemoveAttachment(MailAttachmentViewModel attachmentViewModel)
|
||||||
=> IncludedAttachments.Remove(attachmentViewModel);
|
=> IncludedAttachments.Remove(attachmentViewModel);
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand(CanExecute = nameof(canSendMail))]
|
||||||
private async Task SendAsync()
|
private async Task SendAsync()
|
||||||
{
|
{
|
||||||
// TODO: More detailed mail validations.
|
// TODO: More detailed mail validations.
|
||||||
@@ -161,20 +165,20 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
var assignedAccount = CurrentMailDraftItem.AssignedAccount;
|
var assignedAccount = CurrentMailDraftItem.AssignedAccount;
|
||||||
var sentFolder = await _folderService.GetSpecialFolderByAccountIdAsync(assignedAccount.Id, SpecialFolderType.Sent);
|
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);
|
await _worker.ExecuteAsync(draftSendPreparationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateMimeChangesAsync()
|
private async Task UpdateMimeChangesAsync()
|
||||||
{
|
{
|
||||||
if (isUpdatingMimeBlocked || currentMimeMessage == null || ComposingAccount == null || CurrentMailDraftItem == null) return;
|
if (isUpdatingMimeBlocked || CurrentMimeMessage == null || ComposingAccount == null || CurrentMailDraftItem == null) return;
|
||||||
|
|
||||||
// Save recipients.
|
// Save recipients.
|
||||||
|
|
||||||
SaveAddressInfo(ToItems, currentMimeMessage.To);
|
SaveAddressInfo(ToItems, CurrentMimeMessage.To);
|
||||||
SaveAddressInfo(CCItemsItems, currentMimeMessage.Cc);
|
SaveAddressInfo(CCItemsItems, CurrentMimeMessage.Cc);
|
||||||
SaveAddressInfo(BCCItems, currentMimeMessage.Bcc);
|
SaveAddressInfo(BCCItems, CurrentMimeMessage.Bcc);
|
||||||
|
|
||||||
SaveImportance();
|
SaveImportance();
|
||||||
SaveSubject();
|
SaveSubject();
|
||||||
@@ -184,13 +188,13 @@ namespace Wino.Mail.ViewModels
|
|||||||
await UpdateMailCopyAsync();
|
await UpdateMailCopyAsync();
|
||||||
|
|
||||||
// Save mime file.
|
// 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()
|
private async Task UpdateMailCopyAsync()
|
||||||
{
|
{
|
||||||
CurrentMailDraftItem.Subject = currentMimeMessage.Subject;
|
CurrentMailDraftItem.Subject = CurrentMimeMessage.Subject;
|
||||||
CurrentMailDraftItem.PreviewText = currentMimeMessage.TextBody;
|
CurrentMailDraftItem.PreviewText = CurrentMimeMessage.TextBody;
|
||||||
|
|
||||||
// Update database.
|
// Update database.
|
||||||
await _mailService.UpdateMailAsync(CurrentMailDraftItem.MailCopy);
|
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()
|
private void SaveSubject()
|
||||||
{
|
{
|
||||||
if (Subject != null)
|
if (Subject != null)
|
||||||
{
|
{
|
||||||
currentMimeMessage.Subject = Subject;
|
CurrentMimeMessage.Subject = Subject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +231,10 @@ namespace Wino.Mail.ViewModels
|
|||||||
bodyBuilder.TextBody = HtmlAgilityPackExtensions.GetPreviewText(bodyBuilder.HtmlBody);
|
bodyBuilder.TextBody = HtmlAgilityPackExtensions.GetPreviewText(bodyBuilder.HtmlBody);
|
||||||
|
|
||||||
if (bodyBuilder.HtmlBody != null && bodyBuilder.TextBody != null)
|
if (bodyBuilder.HtmlBody != null && bodyBuilder.TextBody != null)
|
||||||
currentMimeMessage.Body = bodyBuilder.ToMessageBody();
|
CurrentMimeMessage.Body = bodyBuilder.ToMessageBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand(CanExecute = nameof(canSendMail))]
|
||||||
private async Task DiscardAsync()
|
private async Task DiscardAsync()
|
||||||
{
|
{
|
||||||
if (ComposingAccount == null)
|
if (ComposingAccount == null)
|
||||||
@@ -248,7 +252,7 @@ namespace Wino.Mail.ViewModels
|
|||||||
isUpdatingMimeBlocked = true;
|
isUpdatingMimeBlocked = true;
|
||||||
|
|
||||||
// Don't send delete request for local drafts. Just delete the record and mime locally.
|
// 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);
|
await _mailService.DeleteMailAsync(ComposingAccount.Id, CurrentMailDraftItem.Id);
|
||||||
}
|
}
|
||||||
@@ -413,9 +417,8 @@ namespace Wino.Mail.ViewModels
|
|||||||
|
|
||||||
Subject = replyingMime.Subject;
|
Subject = replyingMime.Subject;
|
||||||
|
|
||||||
currentMimeMessage = replyingMime;
|
CurrentMimeMessage = replyingMime;
|
||||||
|
|
||||||
OnPropertyChanged(nameof(CanSendMail));
|
|
||||||
Messenger.Send(new CreateNewComposeMailRequested(renderModel));
|
Messenger.Send(new CreateNewComposeMailRequested(renderModel));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -484,7 +487,9 @@ namespace Wino.Mail.ViewModels
|
|||||||
await ExecuteUIThread(() =>
|
await ExecuteUIThread(() =>
|
||||||
{
|
{
|
||||||
CurrentMailDraftItem.Update(updatedMail);
|
CurrentMailDraftItem.Update(updatedMail);
|
||||||
OnPropertyChanged(nameof(CanSendMail));
|
|
||||||
|
DiscardCommand.NotifyCanExecuteChanged();
|
||||||
|
SendCommand.NotifyCanExecuteChanged();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Wino.Core.Domain;
|
|
||||||
using Wino.Core.Domain.Entities;
|
using Wino.Core.Domain.Entities;
|
||||||
using Wino.Core.Domain.Models.MailItem;
|
using Wino.Core.Domain.Models.MailItem;
|
||||||
|
|
||||||
@@ -13,8 +12,6 @@ namespace Wino.Mail.ViewModels.Data
|
|||||||
{
|
{
|
||||||
public MailCopy MailCopy { get; private set; } = mailCopy;
|
public MailCopy MailCopy { get; private set; } = mailCopy;
|
||||||
|
|
||||||
public bool IsLocalDraft => !string.IsNullOrEmpty(DraftId) && DraftId.StartsWith(Constants.LocalDraftStartPrefix);
|
|
||||||
|
|
||||||
public Guid UniqueId => ((IMailItem)MailCopy).UniqueId;
|
public Guid UniqueId => ((IMailItem)MailCopy).UniqueId;
|
||||||
public string ThreadId => ((IMailItem)MailCopy).ThreadId;
|
public string ThreadId => ((IMailItem)MailCopy).ThreadId;
|
||||||
public string MessageId => ((IMailItem)MailCopy).MessageId;
|
public string MessageId => ((IMailItem)MailCopy).MessageId;
|
||||||
@@ -96,7 +93,6 @@ namespace Wino.Mail.ViewModels.Data
|
|||||||
OnPropertyChanged(nameof(DraftId));
|
OnPropertyChanged(nameof(DraftId));
|
||||||
OnPropertyChanged(nameof(Subject));
|
OnPropertyChanged(nameof(Subject));
|
||||||
OnPropertyChanged(nameof(PreviewText));
|
OnPropertyChanged(nameof(PreviewText));
|
||||||
OnPropertyChanged(nameof(IsLocalDraft));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,10 +152,7 @@
|
|||||||
<controls:WinoFontIcon Icon="Delete" />
|
<controls:WinoFontIcon Icon="Delete" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarButton
|
<AppBarButton Label="Send" Command="{x:Bind ViewModel.SendCommand}">
|
||||||
Label="Send"
|
|
||||||
IsEnabled="{x:Bind ViewModel.CanSendMail, Mode=OneWay}"
|
|
||||||
Command="{x:Bind ViewModel.SendCommand}">
|
|
||||||
<AppBarButton.Icon>
|
<AppBarButton.Icon>
|
||||||
<controls:WinoFontIcon Icon="Send" />
|
<controls:WinoFontIcon Icon="Send" />
|
||||||
</AppBarButton.Icon>
|
</AppBarButton.Icon>
|
||||||
|
|||||||
Reference in New Issue
Block a user