Translation caching. New ai actions panel.
This commit is contained in:
@@ -160,6 +160,17 @@
|
||||
Visibility="{x:Bind ViewModel.IsDraftBusy, Mode=OneWay}">
|
||||
<ProgressRing IsActive="True" />
|
||||
</AppBarButton>
|
||||
<AppBarToggleButton
|
||||
x:Name="ComposeAiActionsToggleButton"
|
||||
Checked="ComposeAiActionsToggleButton_Checked"
|
||||
MinWidth="40"
|
||||
HorizontalContentAlignment="Center"
|
||||
LabelPosition="Collapsed"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiActions}">
|
||||
<AppBarToggleButton.Icon>
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||
</AppBarToggleButton.Icon>
|
||||
</AppBarToggleButton>
|
||||
<AppBarButton Click="ToggleEditorThemeClicked" ToolTipService.ToolTip="{x:Bind GetEditorThemeToolTip(WebViewEditor.IsEditorDarkMode), Mode=OneWay}">
|
||||
<AppBarButton.Icon>
|
||||
<coreControls:WinoFontIcon Icon="{x:Bind GetEditorThemeIcon(WebViewEditor.IsEditorDarkMode), Mode=OneWay}" />
|
||||
@@ -307,6 +318,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -445,10 +457,19 @@
|
||||
BorderThickness="0"
|
||||
Text="{x:Bind ViewModel.Subject, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<coreControls:AiActionsPanel
|
||||
x:Name="ComposeAiActionsPanel"
|
||||
Grid.Row="5"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,8,0,0"
|
||||
AvailableActions="Rewrite"
|
||||
HtmlHost="{x:Bind}"
|
||||
Visibility="{x:Bind GetAiActionsPanelVisibility(ComposeAiActionsToggleButton.IsChecked), Mode=OneWay}" />
|
||||
|
||||
<!-- Attachments -->
|
||||
<ListView
|
||||
x:Name="AttachmentsListView"
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.ColumnSpan="2"
|
||||
ui:ListViewExtensions.Command="{x:Bind ViewModel.OpenAttachmentCommand}"
|
||||
x:Load="{x:Bind helpers:XamlHelpers.CountToBooleanConverter(ViewModel.IncludedAttachments.Count), Mode=OneWay}"
|
||||
|
||||
@@ -32,12 +32,15 @@ using Wino.Views.Abstract;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class ComposePage : ComposePageAbstract,
|
||||
IAiHtmlActionHost,
|
||||
IRecipient<CreateNewComposeMailRequested>,
|
||||
IRecipient<ApplicationThemeChanged>,
|
||||
IRecipient<ReaderItemRefreshRequestedEvent>
|
||||
{
|
||||
public WebView2 GetWebView() => WebViewEditor.GetUnderlyingWebView();
|
||||
|
||||
public Visibility GetAiActionsPanelVisibility(bool? isChecked) => isChecked == true ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
private readonly List<IDisposable> _disposables = [];
|
||||
|
||||
public ComposePage()
|
||||
@@ -283,6 +286,11 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
ViewModel.IsCCBCCVisible = true;
|
||||
}
|
||||
|
||||
private async void ComposeAiActionsToggleButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await ComposeAiActionsPanel.RefreshAvailabilityAsync();
|
||||
}
|
||||
|
||||
private async void TokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args)
|
||||
{
|
||||
// Check is valid email.
|
||||
@@ -410,11 +418,39 @@ public sealed partial class ComposePage : ComposePageAbstract,
|
||||
base.OnNavigatingFrom(e);
|
||||
|
||||
FocusManager.GotFocus -= GlobalFocusManagerGotFocus;
|
||||
ComposeAiActionsPanel.CancelPendingOperation();
|
||||
await ViewModel.UpdateMimeChangesAsync();
|
||||
|
||||
DisposeDisposables();
|
||||
}
|
||||
|
||||
public async Task<string?> GetCurrentHtmlAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var html = await WebViewEditor.GetHtmlBodyAsync();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return html;
|
||||
}
|
||||
|
||||
public async Task ApplyHtmlResultAsync(string html, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await WebViewEditor.RenderHtmlAsync(html);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
public Task<string?> TryGetCachedTranslationHtmlAsync(string languageCode, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return Task.FromResult<string?>(null);
|
||||
}
|
||||
|
||||
public Task SaveCachedTranslationHtmlAsync(string languageCode, string html, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void OpenAttachment_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is MenuFlyoutItem item && item.CommandParameter is MailAttachmentViewModel attachment)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
xmlns:local="using:Wino.Behaviors"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:coreControls="using:Wino.Mail.WinUI.Controls"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:viewModelData="using:Wino.Mail.ViewModels.Data"
|
||||
x:Name="root"
|
||||
@@ -181,6 +182,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Margin="5,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -273,13 +275,16 @@
|
||||
IsDynamicOverflowEnabled="True"
|
||||
OverflowButtonVisibility="Auto">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<local:BindableCommandBarBehavior ItemClickedCommand="{x:Bind ViewModel.OperationClickedCommand}" PrimaryCommands="{x:Bind ViewModel.MenuItems, Mode=OneWay}" />
|
||||
<local:BindableCommandBarBehavior
|
||||
ItemClickedCommand="{x:Bind ViewModel.OperationClickedCommand}"
|
||||
PrimaryCommands="{x:Bind ViewModel.MenuItems, Mode=OneWay}" />
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<CommandBar.Content>
|
||||
<Grid Padding="0,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -317,6 +322,19 @@
|
||||
<TextBlock FontSize="12" Text="{x:Bind helpers:XamlHelpers.GetCreationDateString(ViewModel.CreationDate, ViewModel.PreferencesService.Prefer24HourTimeFormat), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<AppBarToggleButton
|
||||
x:Name="ReaderAiActionsToggleButton"
|
||||
Grid.Column="2"
|
||||
Checked="ReaderAiActionsToggleButton_Checked"
|
||||
MinWidth="40"
|
||||
HorizontalContentAlignment="Center"
|
||||
LabelPosition="Collapsed"
|
||||
ToolTipService.ToolTip="{x:Bind domain:Translator.Composer_AiActions}">
|
||||
<AppBarToggleButton.Icon>
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||
</AppBarToggleButton.Icon>
|
||||
</AppBarToggleButton>
|
||||
</Grid>
|
||||
</CommandBar.Content>
|
||||
</CommandBar>
|
||||
@@ -409,8 +427,16 @@
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
<coreControls:AiActionsPanel
|
||||
x:Name="ReaderAiActionsPanel"
|
||||
Grid.Row="3"
|
||||
Margin="0,8,0,0"
|
||||
AvailableActions="Translate, Summarize"
|
||||
HtmlHost="{x:Bind}"
|
||||
Visibility="{x:Bind GetAiActionsPanelVisibility(ReaderAiActionsToggleButton.IsChecked), Mode=OneWay}" />
|
||||
|
||||
<!-- Attachments -->
|
||||
<Grid Grid.Row="3">
|
||||
<Grid Grid.Row="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -442,7 +468,7 @@
|
||||
|
||||
<InfoBar
|
||||
x:Name="ImageLoadingDisabledMessage"
|
||||
Grid.Row="4"
|
||||
Grid.Row="5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
x:Load="{x:Bind ViewModel.IsImageRenderingDisabled, Mode=OneWay}"
|
||||
IsOpen="True"
|
||||
@@ -458,7 +484,7 @@
|
||||
|
||||
<ProgressBar
|
||||
x:Name="DownloadingProgressBar"
|
||||
Grid.Row="3"
|
||||
Grid.Row="4"
|
||||
Margin="12,1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -16,6 +17,7 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Printing;
|
||||
using Wino.Mail.ViewModels.Data;
|
||||
using Wino.Mail.WinUI;
|
||||
using Wino.Mail.WinUI.Controls;
|
||||
using Wino.Mail.WinUI.Extensions;
|
||||
using Wino.Messaging.Client.Mails;
|
||||
using Wino.Messaging.Client.Shell;
|
||||
@@ -24,19 +26,24 @@ using Wino.Views.Abstract;
|
||||
namespace Wino.Views.Mail;
|
||||
|
||||
public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||
IAiHtmlActionHost,
|
||||
IRecipient<HtmlRenderingRequested>,
|
||||
IRecipient<CancelRenderingContentRequested>,
|
||||
IRecipient<ApplicationThemeChanged>
|
||||
{
|
||||
private readonly IPreferencesService _preferencesService = App.Current.Services.GetService<IPreferencesService>()!;
|
||||
private readonly IMailDialogService _dialogService = App.Current.Services.GetService<IMailDialogService>()!;
|
||||
private readonly IMimeFileService _mimeFileService = App.Current.Services.GetRequiredService<IMimeFileService>();
|
||||
|
||||
private bool isRenderingInProgress = false;
|
||||
private bool? _lastAppliedDarkTheme;
|
||||
private TaskCompletionSource<bool> DOMLoadedTask = new TaskCompletionSource<bool>();
|
||||
private string _currentRenderedHtml = string.Empty;
|
||||
|
||||
public WebView2 GetWebView() => Chromium;
|
||||
|
||||
public Visibility GetAiActionsPanelVisibility(bool? isChecked) => isChecked == true ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public MailRenderingPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -82,6 +89,7 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||
private async Task RenderInternalAsync(string htmlBody)
|
||||
{
|
||||
isRenderingInProgress = true;
|
||||
_currentRenderedHtml = htmlBody ?? string.Empty;
|
||||
|
||||
await DOMLoadedTask.Task;
|
||||
|
||||
@@ -141,10 +149,63 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
|
||||
|
||||
ViewModel.SaveHTMLasPDFFunc = null;
|
||||
ViewModel.DirectPrintFuncAsync = null;
|
||||
_currentRenderedHtml = string.Empty;
|
||||
ReaderAiActionsPanel.CancelPendingOperation();
|
||||
|
||||
DisposeWebView2();
|
||||
}
|
||||
|
||||
public Task<string?> GetCurrentHtmlAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return Task.FromResult<string?>(_currentRenderedHtml);
|
||||
}
|
||||
|
||||
public async Task ApplyHtmlResultAsync(string html, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await RenderInternalAsync(html);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
private async void ReaderAiActionsToggleButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await ReaderAiActionsPanel.RefreshAvailabilityAsync();
|
||||
}
|
||||
|
||||
public async Task<string?> TryGetCachedTranslationHtmlAsync(string languageCode, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (!ViewModel.CurrentMailAccountId.HasValue || !ViewModel.CurrentMailFileId.HasValue || string.IsNullOrWhiteSpace(languageCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await _mimeFileService.GetTranslatedHtmlAsync(
|
||||
ViewModel.CurrentMailAccountId.Value,
|
||||
ViewModel.CurrentMailFileId.Value,
|
||||
languageCode,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task SaveCachedTranslationHtmlAsync(string languageCode, string html, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (!ViewModel.CurrentMailAccountId.HasValue || !ViewModel.CurrentMailFileId.HasValue || string.IsNullOrWhiteSpace(languageCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await _mimeFileService.SaveTranslatedHtmlAsync(
|
||||
ViewModel.CurrentMailAccountId.Value,
|
||||
ViewModel.CurrentMailFileId.Value,
|
||||
languageCode,
|
||||
html,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void DisposeWebView2()
|
||||
{
|
||||
if (Chromium == null) return;
|
||||
|
||||
Reference in New Issue
Block a user