Simplified compoper and rendering logic through messages.
This commit is contained in:
@@ -29,7 +29,7 @@ using Wino.Messaging.UI;
|
||||
namespace Wino.Mail.ViewModels;
|
||||
|
||||
public partial class ComposePageViewModel : MailBaseViewModel,
|
||||
IRecipient<NewComposeDraftItemRequestedEvent>,
|
||||
IRecipient<ReaderItemRefreshRequestedEvent>,
|
||||
IRecipient<SynchronizationActionsAdded>,
|
||||
IRecipient<SynchronizationActionsCompleted>,
|
||||
IRecipient<AccountSynchronizerStateChanged>
|
||||
@@ -511,8 +511,10 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
||||
}
|
||||
}
|
||||
|
||||
public async void Receive(NewComposeDraftItemRequestedEvent message)
|
||||
public async void Receive(ReaderItemRefreshRequestedEvent message)
|
||||
{
|
||||
if (message.MailItemViewModel == null || !message.MailItemViewModel.IsDraft) return;
|
||||
|
||||
// Save current draft before switching.
|
||||
await UpdateMimeChangesAsync();
|
||||
|
||||
@@ -555,7 +557,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
||||
{
|
||||
base.RegisterRecipients();
|
||||
|
||||
Messenger.Register<NewComposeDraftItemRequestedEvent>(this);
|
||||
Messenger.Register<ReaderItemRefreshRequestedEvent>(this);
|
||||
Messenger.Register<SynchronizationActionsAdded>(this);
|
||||
Messenger.Register<SynchronizationActionsCompleted>(this);
|
||||
Messenger.Register<AccountSynchronizerStateChanged>(this);
|
||||
@@ -565,7 +567,7 @@ public partial class ComposePageViewModel : MailBaseViewModel,
|
||||
{
|
||||
base.UnregisterRecipients();
|
||||
|
||||
Messenger.Unregister<NewComposeDraftItemRequestedEvent>(this);
|
||||
Messenger.Unregister<ReaderItemRefreshRequestedEvent>(this);
|
||||
Messenger.Unregister<SynchronizationActionsAdded>(this);
|
||||
Messenger.Unregister<SynchronizationActionsCompleted>(this);
|
||||
Messenger.Unregister<AccountSynchronizerStateChanged>(this);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Data;
|
||||
|
||||
public partial class AccountContactViewModel : ObservableObject
|
||||
public partial class AccountContactViewModel : ObservableObject, IMailItemDisplayInformation
|
||||
{
|
||||
public string Address { get; set; }
|
||||
public string Name { get; set; }
|
||||
@@ -49,4 +50,25 @@ public partial class AccountContactViewModel : ObservableObject
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool ThumbnailUpdatedEvent { get; set; }
|
||||
|
||||
// IMailItemDisplayInformation implementation for avatar-only rendering.
|
||||
public string Subject => string.Empty;
|
||||
public string FromName => Name ?? string.Empty;
|
||||
public string FromAddress => Address ?? string.Empty;
|
||||
public string PreviewText => string.Empty;
|
||||
public bool IsRead => true;
|
||||
public bool IsDraft => false;
|
||||
public bool HasAttachments => false;
|
||||
public bool IsCalendarEvent => false;
|
||||
public bool IsFlagged => false;
|
||||
public DateTime CreationDate => default;
|
||||
public bool IsBusy => false;
|
||||
public bool IsThreadExpanded => false;
|
||||
public AccountContact SenderContact => new()
|
||||
{
|
||||
Address = Address,
|
||||
Name = Name,
|
||||
Base64ContactPicture = Base64ContactPicture,
|
||||
IsRootContact = IsRootContact
|
||||
};
|
||||
}
|
||||
|
||||
@@ -226,9 +226,17 @@ public partial class MailAppShellViewModel : MailBaseViewModel,
|
||||
|
||||
if (mode == NavigationMode.Back)
|
||||
{
|
||||
// Account list may have changed while this shell was inactive.
|
||||
await RecreateMenuItemsAsync();
|
||||
await RestoreSelectedAccountAfterMenuRefreshAsync(false);
|
||||
// Preserve current mail/folder selection and active rendering page when
|
||||
// switching back from Calendar mode. Recreating menu/folder state here
|
||||
// causes a folder reload, which clears selection and disposes reader page.
|
||||
// Rehydrate only if menu state is unexpectedly empty.
|
||||
if (MenuItems?.Any() != true || FooterItems?.Any() != true)
|
||||
{
|
||||
await CreateFooterItemsAsync();
|
||||
await RecreateMenuItemsAsync();
|
||||
await RestoreSelectedAccountAfterMenuRefreshAsync(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ using IMailService = Wino.Core.Domain.Interfaces.IMailService;
|
||||
namespace Wino.Mail.ViewModels;
|
||||
|
||||
public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
IRecipient<NewMailItemRenderingRequestedEvent>,
|
||||
IRecipient<ReaderItemRefreshRequestedEvent>,
|
||||
IRecipient<ThumbnailAdded>,
|
||||
ITransferProgress // For listening IMAP message download progress.
|
||||
{
|
||||
@@ -127,6 +127,9 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
[ObservableProperty]
|
||||
public partial string ContactPicture { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial IMailItemDisplayInformation CurrentMailItemDisplayInformation { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial DateTime CreationDate { get; set; }
|
||||
public ObservableCollection<AccountContactViewModel> ToItems { get; set; } = [];
|
||||
@@ -361,6 +364,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
|
||||
initializedMailItemViewModel = null;
|
||||
initializedMimeMessageInformation = null;
|
||||
CurrentMailItemDisplayInformation = null;
|
||||
|
||||
// Dispose existing content first.
|
||||
Messenger.Send(new CancelRenderingContentRequested());
|
||||
@@ -447,6 +451,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
}
|
||||
|
||||
initializedMailItemViewModel = mailItemViewModel;
|
||||
await ExecuteUIThread(() => { CurrentMailItemDisplayInformation = mailItemViewModel; });
|
||||
await RenderAsync(mimeMessageInformation);
|
||||
}
|
||||
|
||||
@@ -570,6 +575,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
|
||||
initializedMailItemViewModel = null;
|
||||
initializedMimeMessageInformation = null;
|
||||
CurrentMailItemDisplayInformation = null;
|
||||
|
||||
forceImageLoading = false;
|
||||
|
||||
@@ -798,8 +804,10 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
// For upload.
|
||||
void ITransferProgress.Report(long bytesTransferred) { }
|
||||
|
||||
public async void Receive(NewMailItemRenderingRequestedEvent message)
|
||||
public async void Receive(ReaderItemRefreshRequestedEvent message)
|
||||
{
|
||||
if (message.MailItemViewModel == null || message.MailItemViewModel.IsDraft) return;
|
||||
|
||||
try
|
||||
{
|
||||
await RenderAsync(message.MailItemViewModel, renderCancellationTokenSource.Token);
|
||||
@@ -909,7 +917,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
{
|
||||
base.RegisterRecipients();
|
||||
|
||||
Messenger.Register<NewMailItemRenderingRequestedEvent>(this);
|
||||
Messenger.Register<ReaderItemRefreshRequestedEvent>(this);
|
||||
Messenger.Register<ThumbnailAdded>(this);
|
||||
}
|
||||
|
||||
@@ -917,7 +925,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
|
||||
{
|
||||
base.UnregisterRecipients();
|
||||
|
||||
Messenger.Unregister<NewMailItemRenderingRequestedEvent>(this);
|
||||
Messenger.Unregister<ReaderItemRefreshRequestedEvent>(this);
|
||||
Messenger.Unregister<ThumbnailAdded>(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// When the compose page is already active, but a different draft item is selected.
|
||||
/// To not trigger navigation again and re-use existing WebView2 editor.
|
||||
/// </summary>
|
||||
/// <param name="MailItemViewModel">The new draft mail item to compose.</param>
|
||||
public record NewComposeDraftItemRequestedEvent(MailItemViewModel MailItemViewModel);
|
||||
@@ -1,10 +0,0 @@
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// When the rendering page is active, but new item is requested to be rendered.
|
||||
/// To not trigger navigation again and re-use existing Chromium.
|
||||
/// </summary>
|
||||
/// <param name="MailItemViewModel"></param>
|
||||
public record NewMailItemRenderingRequestedEvent(MailItemViewModel MailItemViewModel);
|
||||
@@ -0,0 +1,10 @@
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
|
||||
namespace Wino.Mail.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Requests refreshing the currently active reader page (mail rendering or compose)
|
||||
/// with a different selected mail item without re-navigation.
|
||||
/// </summary>
|
||||
/// <param name="MailItemViewModel">The selected mail item to refresh with.</param>
|
||||
public record ReaderItemRefreshRequestedEvent(MailItemViewModel MailItemViewModel);
|
||||
Reference in New Issue
Block a user