Simplified compoper and rendering logic through messages.
This commit is contained in:
@@ -43,10 +43,7 @@
|
||||
</Grid.ContextFlyout>-->
|
||||
|
||||
<Viewbox Width="24">
|
||||
<controls:ImagePreviewControl
|
||||
FromAddress="{x:Bind Address}"
|
||||
FromName="{x:Bind Name}"
|
||||
SenderContactPicture="{x:Bind Base64ContactPicture}" />
|
||||
<PersonPicture DisplayName="{x:Bind Name, Mode=OneTime}" />
|
||||
</Viewbox>
|
||||
|
||||
<TextBlock
|
||||
@@ -62,10 +59,7 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:ImagePreviewControl
|
||||
FromAddress="{x:Bind Address}"
|
||||
FromName="{x:Bind Name}"
|
||||
SenderContactPicture="{x:Bind Base64ContactPicture}" />
|
||||
<PersonPicture DisplayName="{x:Bind Name, Mode=OneTime}" />
|
||||
<TextBlock Grid.Column="1">
|
||||
<Run FontWeight="SemiBold" Text="{x:Bind Name}" /><LineBreak /><Run Text="{x:Bind Address}" />
|
||||
</TextBlock>
|
||||
@@ -485,8 +479,8 @@
|
||||
<TextBlock FontWeight="SemiBold" Text="{x:Bind Subject}" />
|
||||
<TextBlock FontSize="12" Text="{x:Bind Issuer}" />
|
||||
<TextBlock>
|
||||
<Run Text="{x:Bind domain:Translator.Composer_CertificateExpires}" />
|
||||
<Run Text="{x:Bind NotAfter, Mode=OneWay}" />
|
||||
<Run Text="{x:Bind domain:Translator.Composer_CertificateExpires, Mode=OneTime}" />
|
||||
<Run Text="{x:Bind NotAfter, Mode=OneTime}" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Wino.Views.Mail;
|
||||
public sealed partial class ComposePage : ComposePageAbstract,
|
||||
IRecipient<CreateNewComposeMailRequested>,
|
||||
IRecipient<ApplicationThemeChanged>,
|
||||
IRecipient<NewComposeDraftItemRequestedEvent>
|
||||
IRecipient<ReaderItemRefreshRequestedEvent>
|
||||
{
|
||||
public WebView2 GetWebView() => WebViewEditor.GetUnderlyingWebView();
|
||||
|
||||
@@ -302,8 +302,10 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
WebViewEditor.IsEditorDarkMode = message.IsUnderlyingThemeDark;
|
||||
}
|
||||
|
||||
void IRecipient<NewComposeDraftItemRequestedEvent>.Receive(NewComposeDraftItemRequestedEvent message)
|
||||
void IRecipient<ReaderItemRefreshRequestedEvent>.Receive(ReaderItemRefreshRequestedEvent message)
|
||||
{
|
||||
if (message.MailItemViewModel == null || !message.MailItemViewModel.IsDraft) return;
|
||||
|
||||
// Reset the initial focus flag so ToBox gets focus for the new draft.
|
||||
isInitialFocusHandled = false;
|
||||
}
|
||||
@@ -423,7 +425,7 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
|
||||
WeakReferenceMessenger.Default.Register<CreateNewComposeMailRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
|
||||
WeakReferenceMessenger.Default.Register<NewComposeDraftItemRequestedEvent>(this);
|
||||
WeakReferenceMessenger.Default.Register<ReaderItemRefreshRequestedEvent>(this);
|
||||
}
|
||||
|
||||
protected override void UnregisterRecipients()
|
||||
@@ -432,7 +434,7 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
|
||||
WeakReferenceMessenger.Default.Unregister<CreateNewComposeMailRequested>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<NewComposeDraftItemRequestedEvent>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ReaderItemRefreshRequestedEvent>(this);
|
||||
}
|
||||
|
||||
// TODO: Save mime on closing the app.
|
||||
|
||||
@@ -47,6 +47,8 @@ public sealed partial class MailListPage : MailListPageAbstract,
|
||||
IRecipient<DisposeRenderingFrameRequested>
|
||||
{
|
||||
private const double RENDERING_COLUMN_MIN_WIDTH = 375;
|
||||
private const int IDLE_NAVIGATION_DELAY_MS = 120;
|
||||
private int _idleNavigationRequestVersion = 0;
|
||||
|
||||
private IStatePersistanceService StatePersistenceService { get; } = WinoApplication.Current.Services.GetService<IStatePersistanceService>() ?? throw new Exception($"Can't resolve {nameof(KeyPressService)}");
|
||||
private IKeyPressService KeyPressService { get; } = WinoApplication.Current.Services.GetService<IKeyPressService>() ?? throw new Exception($"Can't resolve {nameof(KeyPressService)}");
|
||||
@@ -80,6 +82,8 @@ public sealed partial class MailListPage : MailListPageAbstract,
|
||||
{
|
||||
base.OnNavigatedFrom(e);
|
||||
|
||||
InvalidatePendingIdleNavigation();
|
||||
|
||||
this.Bindings.StopTracking();
|
||||
|
||||
ViewModel.MailCollection.ItemSelectionChanged -= WinoMailCollectionSelectionChanged;
|
||||
@@ -280,17 +284,12 @@ public sealed partial class MailListPage : MailListPageAbstract,
|
||||
// No active mail item. Go to empty page.
|
||||
if (message.SelectedMailItemViewModel == null)
|
||||
{
|
||||
if (IsRenderingPageActive())
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new CancelRenderingContentRequested());
|
||||
}
|
||||
|
||||
// Ensure rendering frame actually navigates away from Compose/Rendering pages.
|
||||
// Otherwise those pages keep their messenger registrations alive.
|
||||
ViewModel.NavigationService.Navigate(WinoPage.IdlePage, null, NavigationReferenceFrame.RenderingFrame, NavigationTransitionType.DrillIn);
|
||||
_ = NavigateIdleWhenSelectionSettlesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidatePendingIdleNavigation();
|
||||
|
||||
// Navigate to composing page.
|
||||
if (message.SelectedMailItemViewModel.IsDraft)
|
||||
{
|
||||
@@ -309,7 +308,7 @@ public sealed partial class MailListPage : MailListPageAbstract,
|
||||
{
|
||||
// Composer is already active. Skip connected animation since the page
|
||||
// will be reused in-place (no navigation occurs).
|
||||
// NavigationService will send NewComposeDraftItemRequestedEvent instead.
|
||||
// NavigationService will send ReaderItemRefreshRequestedEvent instead.
|
||||
}
|
||||
else
|
||||
composerPageTransition = NavigationTransitionType.DrillIn;
|
||||
@@ -337,6 +336,34 @@ public sealed partial class MailListPage : MailListPageAbstract,
|
||||
private bool IsRenderingPageActive() => RenderingFrame.Content is MailRenderingPage;
|
||||
private bool IsComposingPageActive() => RenderingFrame.Content is ComposePage;
|
||||
|
||||
private void InvalidatePendingIdleNavigation()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
_idleNavigationRequestVersion++;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task NavigateIdleWhenSelectionSettlesAsync()
|
||||
{
|
||||
int requestVersion = ++_idleNavigationRequestVersion;
|
||||
|
||||
await Task.Delay(IDLE_NAVIGATION_DELAY_MS);
|
||||
|
||||
if (requestVersion != _idleNavigationRequestVersion) return;
|
||||
if (ViewModel.MailCollection.SelectedItemsCount != 0) return;
|
||||
|
||||
if (IsRenderingPageActive())
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new CancelRenderingContentRequested());
|
||||
}
|
||||
|
||||
// Ensure rendering frame actually navigates away from Compose/Rendering pages.
|
||||
// Otherwise those pages keep their messenger registrations alive.
|
||||
ViewModel.NavigationService.Navigate(WinoPage.IdlePage, null, NavigationReferenceFrame.RenderingFrame, NavigationTransitionType.DrillIn);
|
||||
UpdateAdaptiveness();
|
||||
}
|
||||
|
||||
private void PrepareComposePageWebViewTransition()
|
||||
{
|
||||
var webView = GetComposerPageWebView();
|
||||
|
||||
@@ -46,10 +46,7 @@
|
||||
Grid.RowSpan="2"
|
||||
Width="36"
|
||||
Height="36"
|
||||
FromAddress="{x:Bind Address}"
|
||||
FromName="{x:Bind Name}"
|
||||
SenderContactPicture="{x:Bind Base64ContactPicture}"
|
||||
ThumbnailUpdatedEvent="{x:Bind ThumbnailUpdatedEvent, Mode=OneWay}" />
|
||||
MailItemInformation="{x:Bind}" />
|
||||
|
||||
<TextBlock Grid.Column="1" Text="{x:Bind Name}" />
|
||||
|
||||
@@ -291,9 +288,7 @@
|
||||
Width="36"
|
||||
Height="36"
|
||||
FontSize="16"
|
||||
FromAddress="{x:Bind ViewModel.FromAddress, Mode=OneWay}"
|
||||
FromName="{x:Bind ViewModel.FromName, Mode=OneWay}"
|
||||
SenderContactPicture="{x:Bind ViewModel.ContactPicture, Mode=OneWay}" />
|
||||
MailItemInformation="{x:Bind ViewModel.CurrentMailItemDisplayInformation, Mode=OneWay}" />
|
||||
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
|
||||
@@ -164,16 +164,18 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
// Initialize WebView2 wiring before base navigation invokes ViewModel rendering.
|
||||
// Base.OnNavigatedTo triggers VM.OnNavigatedTo, which can send HtmlRenderingRequested.
|
||||
DOMLoadedTask = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
Chromium.CoreWebView2Initialized -= CoreWebViewInitialized;
|
||||
Chromium.CoreWebView2Initialized += CoreWebViewInitialized;
|
||||
_ = Chromium.EnsureCoreWebView2Async();
|
||||
|
||||
base.OnNavigatedTo(e);
|
||||
|
||||
var anim = ConnectedAnimationService.GetForCurrentView().GetAnimation("WebViewConnectedAnimation");
|
||||
anim?.TryStart(Chromium);
|
||||
|
||||
Chromium.CoreWebView2Initialized -= CoreWebViewInitialized;
|
||||
Chromium.CoreWebView2Initialized += CoreWebViewInitialized;
|
||||
|
||||
_ = Chromium.EnsureCoreWebView2Async();
|
||||
|
||||
// We don't have shell initialized here. It's only standalone EML viewing.
|
||||
// Shift command bar from top to adjust the design.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user