Add BrowserView

This commit is contained in:
Timothy Baldridge 2022-03-14 06:40:12 -06:00
parent e4e634a1fd
commit 36eae54bb0
7 changed files with 230 additions and 0 deletions

View File

@ -0,0 +1,11 @@
namespace Wabbajack.Messages;
public class OpenBrowserTab
{
public BrowserTabViewModel ViewModel { get; set; }
public OpenBrowserTab(BrowserTabViewModel viewModel)
{
ViewModel = viewModel;
}
}

View File

@ -0,0 +1,90 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using HtmlAgilityPack;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using ReactiveUI.Fody.Helpers;
using Wabbajack.DTOs.Logins;
using Wabbajack.Views;
namespace Wabbajack;
public abstract class BrowserTabViewModel : ViewModel
{
[Reactive] public string HeaderText { get; set; }
[Reactive] public string Instructions { get; set; }
public BrowserView? Browser { get; set; }
private WebView2 _browser => Browser!.Browser;
public async Task RunWrapper(CancellationToken token)
{
await Run(token);
}
protected abstract Task Run(CancellationToken token);
protected async Task WaitForReady()
{
while (Browser?.Browser.CoreWebView2 == null)
{
await Task.Delay(250);
}
}
public async Task NavigateTo(Uri uri)
{
var tcs = new TaskCompletionSource();
void Completed(object? o, CoreWebView2NavigationCompletedEventArgs a)
{
if (a.IsSuccess)
{
tcs.TrySetResult();
}
else
{
tcs.TrySetException(new Exception($"Navigation error to {uri}"));
}
}
_browser.NavigationCompleted += Completed;
_browser.Source = uri;
await tcs.Task;
_browser.NavigationCompleted -= Completed;
}
public async Task<Cookie[]> GetCookies(string domainEnding, CancellationToken token)
{
var cookies = (await _browser.CoreWebView2.CookieManager.GetCookiesAsync(""))
.Where(c => c.Domain.EndsWith(domainEnding));
return cookies.Select(c => new Cookie
{
Domain = c.Domain,
Name = c.Name,
Path = c.Path,
Value = c.Value
}).ToArray();
}
public async Task<string> EvaluateJavaScript(string js)
{
return await _browser.ExecuteScriptAsync(js);
}
public async Task<HtmlDocument> GetDom(CancellationToken token)
{
var v = HttpUtility.UrlDecode("\u003D");
var source = await EvaluateJavaScript("document.body.outerHTML");
var decoded = JsonSerializer.Deserialize<string>(source);
var doc = new HtmlDocument();
doc.LoadHtml(decoded);
return doc;
}
}

View File

@ -0,0 +1,23 @@
<TabItem x:Class="Wabbajack.Views.BrowserTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:views="clr-namespace:Wabbajack.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabItem.Style>
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}"></Style>
</TabItem.Style>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="16" x:Name="HeaderText">_</TextBlock>
</StackPanel>
</TabItem.Header>
<Grid>
<views:BrowserView x:Name="Browser">
</views:BrowserView>
</Grid>
</TabItem>

View File

@ -0,0 +1,51 @@
using System;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using ReactiveUI;
using Wabbajack.Common;
namespace Wabbajack.Views;
public partial class BrowserTabView : IDisposable
{
private readonly CompositeDisposable _compositeDisposable;
public BrowserTabView(BrowserTabViewModel vm)
{
_compositeDisposable = new CompositeDisposable();
InitializeComponent();
Browser.Browser.Source = new Uri("http://www.google.com");
vm.Browser = Browser;
DataContext = vm;
vm.WhenAnyValue(vm => vm.HeaderText)
.BindTo(this, view => view.HeaderText.Text)
.DisposeWith(_compositeDisposable);
Start().FireAndForget();
}
private async Task Start()
{
await ((BrowserTabViewModel) DataContext).RunWrapper(CancellationToken.None);
ClickClose(this, new RoutedEventArgs());
}
public void Dispose()
{
_compositeDisposable.Dispose();
var vm = (BrowserTabViewModel) DataContext;
vm.Browser = null;
}
private void ClickClose(object sender, RoutedEventArgs e)
{
var tc = (TabControl) this.Parent;
tc.Items.Remove(this);
this.Dispose();
}
}

View File

@ -0,0 +1,34 @@
<reactiveUi:ReactiveUserControl x:TypeArguments="wabbajack:BrowserTabViewModel"
x:Class="Wabbajack.Views.BrowserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:reactiveUi="http://reactiveui.net"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:wabbajack="clr-namespace:Wabbajack"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0">
<iconPacks:PackIconModern Kind="NavigatePrevious"></iconPacks:PackIconModern>
</Button>
<Button Grid.Row="0" Grid.Column="1">
<iconPacks:PackIconModern Kind="Home"></iconPacks:PackIconModern>
</Button>
<TextBox Grid.Row="0" Grid.Column="3" VerticalContentAlignment="Center"></TextBox>
<wpf:WebView2 Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" x:Name="Browser"></wpf:WebView2>
</Grid>
</reactiveUi:ReactiveUserControl>

View File

@ -0,0 +1,13 @@
using System.Windows.Controls;
using ReactiveUI;
namespace Wabbajack.Views;
public partial class BrowserView
{
public BrowserView()
{
InitializeComponent();
}
}

View File

@ -11,6 +11,7 @@ using Wabbajack.Common;
using Wabbajack.Messages; using Wabbajack.Messages;
using Wabbajack.Paths.IO; using Wabbajack.Paths.IO;
using Wabbajack.Util; using Wabbajack.Util;
using Wabbajack.Views;
namespace Wabbajack namespace Wabbajack
{ {
@ -188,5 +189,12 @@ namespace Wabbajack
{ {
this.DragMove(); this.DragMove();
} }
private void OnOpenBrowserTab(OpenBrowserTab msg)
{
var tab = new BrowserTabView(msg.ViewModel);
Tabs.Items.Add(tab);
Tabs.SelectedItem = tab;
}
} }
} }