maksit-postclient/src/MaksIT.PostClient.UI/Views/Mail/ReadingPaneView.axaml.cs

141 lines
3.7 KiB
C#

using System.Diagnostics;
using System.ComponentModel;
using Avalonia.Data;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using MaksIT.PostClient.UI.ViewModels;
namespace MaksIT.PostClient.UI.Views.Mail;
public partial class ReadingPaneView : UserControl {
private MainViewModel? _model;
private NativeWebView? _readingWeb;
public ReadingPaneView() {
InitializeComponent();
DataContextChanged += (_, _) => Hook(DataContext as MainViewModel);
Loaded += (_, _) => LoadReadingHtml();
Hook(DataContext as MainViewModel);
}
private void Hook(MainViewModel? model) {
if (ReferenceEquals(_model, model))
return;
if (_model is not null)
_model.PropertyChanged -= OnModelPropertyChanged;
_model = model;
if (_model is null)
return;
_model.PropertyChanged += OnModelPropertyChanged;
LoadReadingHtml();
}
private void OnModelPropertyChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName is nameof(MainViewModel.ReadingHtmlDocument)
or nameof(MainViewModel.ShowHtmlBody)
or nameof(MainViewModel.HasReading)
or nameof(MainViewModel.HtmlEngineReady))
LoadReadingHtml();
}
private bool EnsureReadingWeb() {
if (_readingWeb is not null)
return true;
if (DataContext is not MainViewModel vm || !vm.HtmlEngineReady)
return false;
try {
var web = new NativeWebView();
web.EnvironmentRequested += (_, args) => WebViewSetup.Apply(args);
web.NavigationStarted += WebViewSetup.OpenExternalLink;
web.Bind(IsVisibleProperty, new Binding(nameof(MainViewModel.ShowHtmlBody)));
ReadingHtmlHost.Children.Add(web);
_readingWeb = web;
return true;
}
catch (Exception) {
if (DataContext is MainViewModel model)
model.DisableHtmlEngine();
return false;
}
}
private void LoadReadingHtml() {
if (DataContext is not MainViewModel vm || !vm.ShowHtmlBody)
return;
if (!EnsureReadingWeb() || _readingWeb is null)
return;
var html = string.IsNullOrWhiteSpace(vm.ReadingHtmlDocument)
? MessageHtml.Document("")
: vm.ReadingHtmlDocument;
try {
WebViewSetup.NavigateHtml(_readingWeb, html);
}
catch {
vm.DisableHtmlEngine();
}
}
private void OnViewFatturaPa(object? sender, RoutedEventArgs e) {
if (DataContext is MainViewModel vm)
vm.ViewFatturaPaCommand.Execute(null);
}
private void OnOpenAttachment(object? sender, RoutedEventArgs e) {
if (sender is not Button { DataContext: MailFileAttachment file })
return;
try {
var dir = Path.Combine(Path.GetTempPath(), "postclient-open");
Directory.CreateDirectory(dir);
var name = file.Name;
foreach (var ch in Path.GetInvalidFileNameChars())
name = name.Replace(ch, '_');
if (string.IsNullOrWhiteSpace(name))
name = "attachment";
var path = Path.Combine(dir, name);
File.WriteAllBytes(path, file.Bytes);
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
}
catch (Exception ex) {
if (DataContext is MainViewModel vm)
vm.Status = ex.Message;
}
}
private async void OnSaveAttachment(object? sender, RoutedEventArgs e) {
if (sender is not Button { DataContext: MailFileAttachment file })
return;
if (TopLevel.GetTopLevel(this) is not { } top)
return;
var result = await top.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions {
Title = "Save attachment",
SuggestedFileName = file.Name
});
var path = result?.TryGetLocalPath();
if (string.IsNullOrWhiteSpace(path))
return;
await File.WriteAllBytesAsync(path, file.Bytes);
}
}