diff --git a/Wabbajack.App/App.axaml.cs b/Wabbajack.App/App.axaml.cs
index 05bab6da..5c8de9fa 100644
--- a/Wabbajack.App/App.axaml.cs
+++ b/Wabbajack.App/App.axaml.cs
@@ -1,8 +1,10 @@
using System;
+using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Avalonia.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@@ -24,6 +26,7 @@ public class App : Application
public override void Initialize()
{
+ Dispatcher.UIThread.Post(() => Thread.CurrentThread.Name = "UIThread");
AvaloniaXamlLoader.Load(this);
}
diff --git a/Wabbajack.App/Assets/Wabbajack.axaml b/Wabbajack.App/Assets/Wabbajack.axaml
index 3d9c8975..46111d3e 100644
--- a/Wabbajack.App/Assets/Wabbajack.axaml
+++ b/Wabbajack.App/Assets/Wabbajack.axaml
@@ -37,7 +37,31 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Wabbajack.App/Controls/FileSelectionBox.axaml.cs b/Wabbajack.App/Controls/FileSelectionBox.axaml.cs
index 92bd55e4..08939f90 100644
--- a/Wabbajack.App/Controls/FileSelectionBox.axaml.cs
+++ b/Wabbajack.App/Controls/FileSelectionBox.axaml.cs
@@ -30,7 +30,7 @@ public partial class FileSelectionBox : ReactiveUserControl
{
- this.Bind(ViewModel, vm => vm.Path, view => view.SelectedPath)
+ this.OneWayBind(ViewModel, vm => vm.Path, view => view.SelectedPath)
.DisposeWith(disposables);
this.WhenAnyValue(view => view.SelectFolder)
.BindTo(ViewModel, vm => vm.SelectFolder)
@@ -41,7 +41,7 @@ public partial class FileSelectionBox : ReactiveUserControl new Extension(s)).ToArray())
.BindTo(ViewModel, vm => vm.Extensions)
.DisposeWith(disposables);
- this.Bind(ViewModel, vm => vm.Path,
+ this.OneWayBind(ViewModel, vm => vm.Path,
view => view.TextBox.Text)
.DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.BrowseCommand,
@@ -67,4 +67,9 @@ public partial class FileSelectionBox : ReactiveUserControl GetValue(SelectFolderProperty);
set => SetValue(SelectFolderProperty, value);
}
+
+ public void Load(AbsolutePath path)
+ {
+ ViewModel.Path = path;
+ }
}
\ No newline at end of file
diff --git a/Wabbajack.App/Controls/LogView.axaml b/Wabbajack.App/Controls/LogView.axaml
index bb33f98d..a59ad25a 100644
--- a/Wabbajack.App/Controls/LogView.axaml
+++ b/Wabbajack.App/Controls/LogView.axaml
@@ -6,23 +6,25 @@
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Wabbajack.App.Controls.LogView">
-
- Current Log Contents
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Current Log Contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Wabbajack.App/Extensions/IObservableExtensions.cs b/Wabbajack.App/Extensions/IObservableExtensions.cs
index 210a9d9d..c28f9bf6 100644
--- a/Wabbajack.App/Extensions/IObservableExtensions.cs
+++ b/Wabbajack.App/Extensions/IObservableExtensions.cs
@@ -1,24 +1,43 @@
using System;
+using System.Linq.Expressions;
using System.Reactive.Disposables;
+using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using ReactiveUI;
namespace Wabbajack.App.Extensions;
public static class IObservableExtensions
{
- public static IObservable SelectAsync(this IObservable input,
- CompositeDisposable disposable,
- Func> func)
+ public static IDisposable SimpleOneWayBind(
+ this TView view,
+ TViewModel? viewModel,
+ Expression> vmProperty,
+ Expression> viewProperty)
+ where TView : class
{
- Subject returnObs = new();
+ var d = viewModel.WhenAny(vmProperty, change => change.Value)
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .BindTo(view, viewProperty);
- input.Subscribe(x => Task.Run(async () =>
- {
- var result = await func(x);
- returnObs.OnNext(result);
- })).DisposeWith(disposable);
+ return Disposable.Create(() => d.Dispose());
+ }
- return returnObs;
+ public static IDisposable SimpleOneWayBind(
+ this TView view,
+ TViewModel? viewModel,
+ Expression> vmProperty,
+ Expression> viewProperty,
+ Func selector)
+ where TView : class
+ {
+ var d = viewModel.WhenAnyValue(vmProperty)
+ .Select(change => selector(change))
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .BindTo(view, viewProperty);
+
+ return Disposable.Create(() => d.Dispose());
}
}
\ No newline at end of file
diff --git a/Wabbajack.App/Extensions/ReactiveUIExtensions.cs b/Wabbajack.App/Extensions/ReactiveUIExtensions.cs
index 50f47067..22b190a3 100644
--- a/Wabbajack.App/Extensions/ReactiveUIExtensions.cs
+++ b/Wabbajack.App/Extensions/ReactiveUIExtensions.cs
@@ -1,5 +1,14 @@
+using System;
+using System.Reactive.Linq;
+using Avalonia.Threading;
+using ReactiveUI;
+
namespace Wabbajack.App.Extensions;
public static class ReactiveUIExtensions
{
+ public static IObservable OnUIThread(this IObservable src)
+ {
+ return src.ObserveOn(AvaloniaScheduler.Instance);
+ }
}
\ No newline at end of file
diff --git a/Wabbajack.App/Interfaces/IScreenView.cs b/Wabbajack.App/Interfaces/IScreenView.cs
index 5ee01c93..d2ce26e5 100644
--- a/Wabbajack.App/Interfaces/IScreenView.cs
+++ b/Wabbajack.App/Interfaces/IScreenView.cs
@@ -5,4 +5,5 @@ namespace Wabbajack.App.Interfaces;
public interface IScreenView
{
public Type ViewModelType { get; }
+ public string HumanName { get; }
}
\ No newline at end of file
diff --git a/Wabbajack.App/Models/SettingsManager.cs b/Wabbajack.App/Models/SettingsManager.cs
index 15335685..7ca49047 100644
--- a/Wabbajack.App/Models/SettingsManager.cs
+++ b/Wabbajack.App/Models/SettingsManager.cs
@@ -48,10 +48,12 @@ public class SettingsManager
try
{
if (path.FileExists())
+ {
await using (var s = path.Open(FileMode.Open))
{
return (await JsonSerializer.DeserializeAsync(s, _dtos.Options))!;
}
+ }
}
catch (Exception ex)
{
diff --git a/Wabbajack.App/Screens/BrowseView.axaml.cs b/Wabbajack.App/Screens/BrowseView.axaml.cs
index 64b8d898..aa766c48 100644
--- a/Wabbajack.App/Screens/BrowseView.axaml.cs
+++ b/Wabbajack.App/Screens/BrowseView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class BrowseView : ScreenBase
{
- public BrowseView()
+ public BrowseView() : base("Web Browser")
{
InitializeComponent();
this.WhenActivated(disposables =>
diff --git a/Wabbajack.App/Screens/CompilationView.axaml.cs b/Wabbajack.App/Screens/CompilationView.axaml.cs
index 18b4e8fe..0f09a05e 100644
--- a/Wabbajack.App/Screens/CompilationView.axaml.cs
+++ b/Wabbajack.App/Screens/CompilationView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class CompilationView : ScreenBase
{
- public CompilationView()
+ public CompilationView() : base("Compiling")
{
InitializeComponent();
diff --git a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs
index 4bc24004..ecb150f8 100644
--- a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs
+++ b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs
@@ -15,7 +15,7 @@ namespace Wabbajack.App.Screens;
public partial class CompilerConfigurationView : ScreenBase
{
- public CompilerConfigurationView()
+ public CompilerConfigurationView() : base("Compiler Configuration")
{
InitializeComponent();
AddAlwaysEnabled.Command = ReactiveCommand.Create(() => AddAlwaysEnabled_Command().FireAndForget());
diff --git a/Wabbajack.App/Screens/ErrorPageView.axaml.cs b/Wabbajack.App/Screens/ErrorPageView.axaml.cs
index 36441c1d..234fb8d6 100644
--- a/Wabbajack.App/Screens/ErrorPageView.axaml.cs
+++ b/Wabbajack.App/Screens/ErrorPageView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class ErrorPageView : ScreenBase
{
- public ErrorPageView()
+ public ErrorPageView() : base("Error")
{
InitializeComponent();
this.WhenActivated(disposables =>
diff --git a/Wabbajack.App/Screens/LauncherView.axaml.cs b/Wabbajack.App/Screens/LauncherView.axaml.cs
index bf0ac326..3c8ccfa9 100644
--- a/Wabbajack.App/Screens/LauncherView.axaml.cs
+++ b/Wabbajack.App/Screens/LauncherView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class LauncherView : ScreenBase
{
- public LauncherView()
+ public LauncherView() : base("Launch Modlist")
{
InitializeComponent();
this.WhenActivated(disposables =>
diff --git a/Wabbajack.App/Screens/LauncherViewModel.cs b/Wabbajack.App/Screens/LauncherViewModel.cs
index 10183ca1..f62793a5 100644
--- a/Wabbajack.App/Screens/LauncherViewModel.cs
+++ b/Wabbajack.App/Screens/LauncherViewModel.cs
@@ -35,20 +35,20 @@ public class LauncherViewModel : ViewModelBase
_logger = logger;
MessageBus.Current.Listen()
- .Subscribe(v => Receive(v))
+ .Subscribe(Receive)
.DisposeWith(VMDisposables);
this.WhenActivated(disposables =>
{
this.WhenAnyValue(v => v.InstallFolder)
- .SelectAsync(disposables, async folder => await manager.GetByInstallFolder(folder))
- .ObserveOn(RxApp.MainThreadScheduler)
+ .SelectMany(async folder => await manager.GetByInstallFolder(folder))
+ .OnUIThread()
.Where(v => v != null)
.BindTo(this, vm => vm.Setting)
.DisposeWith(disposables);
this.WhenAnyValue(v => v.Setting)
- .Where(v => v != default)
+ .Where(v => v != default && v!.Image != default && v!.Image.FileExists())
.Select(v => new Bitmap(v!.Image.ToString()))
.BindTo(this, vm => vm.Image)
.DisposeWith(disposables);
diff --git a/Wabbajack.App/Screens/LogScreenView.axaml.cs b/Wabbajack.App/Screens/LogScreenView.axaml.cs
index 85a85735..dd3cb47e 100644
--- a/Wabbajack.App/Screens/LogScreenView.axaml.cs
+++ b/Wabbajack.App/Screens/LogScreenView.axaml.cs
@@ -4,7 +4,7 @@ namespace Wabbajack.App.Screens;
public partial class LogScreenView : ScreenBase
{
- public LogScreenView()
+ public LogScreenView() : base("Application Log")
{
InitializeComponent();
}
diff --git a/Wabbajack.App/Screens/PlaySelectView.axaml.cs b/Wabbajack.App/Screens/PlaySelectView.axaml.cs
index 28aa6e7f..3a6ffa53 100644
--- a/Wabbajack.App/Screens/PlaySelectView.axaml.cs
+++ b/Wabbajack.App/Screens/PlaySelectView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class PlaySelectView : ScreenBase
{
- public PlaySelectView()
+ public PlaySelectView() : base("Modlist Selection")
{
InitializeComponent();
this.WhenActivated(disposables =>
diff --git a/Wabbajack.App/Screens/SettingsView.axaml.cs b/Wabbajack.App/Screens/SettingsView.axaml.cs
index 0d7f7c1f..fb7fc1cb 100644
--- a/Wabbajack.App/Screens/SettingsView.axaml.cs
+++ b/Wabbajack.App/Screens/SettingsView.axaml.cs
@@ -6,7 +6,7 @@ namespace Wabbajack.App.Screens;
public partial class SettingsView : ScreenBase
{
- public SettingsView()
+ public SettingsView() : base("Settings")
{
InitializeComponent();
this.WhenActivated(disposables =>
diff --git a/Wabbajack.App/Screens/StandardInstallationView.axaml b/Wabbajack.App/Screens/StandardInstallationView.axaml
index d7e35f37..b60d6bf4 100644
--- a/Wabbajack.App/Screens/StandardInstallationView.axaml
+++ b/Wabbajack.App/Screens/StandardInstallationView.axaml
@@ -7,8 +7,8 @@
x:Class="Wabbajack.App.Views.StandardInstallationView">
[20/30] Installing Files
-
-
+
+
diff --git a/Wabbajack.App/Screens/StandardInstallationView.axaml.cs b/Wabbajack.App/Screens/StandardInstallationView.axaml.cs
index 60b12837..1e0d59a1 100644
--- a/Wabbajack.App/Screens/StandardInstallationView.axaml.cs
+++ b/Wabbajack.App/Screens/StandardInstallationView.axaml.cs
@@ -1,18 +1,22 @@
+using System;
using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using Avalonia.Threading;
using ReactiveUI;
+using Wabbajack.App.Extensions;
using Wabbajack.App.ViewModels;
namespace Wabbajack.App.Views;
public partial class StandardInstallationView : ScreenBase
{
- public StandardInstallationView()
+ public StandardInstallationView() : base("Installing")
{
InitializeComponent();
this.WhenActivated(disposables =>
{
- this.Bind(ViewModel, vm => vm.Slide.Image, view => view.SlideImage.Source)
+ this.OneWayBind(ViewModel, vm => vm.Slide.Image, view => view.SlideImage.Source)
.DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.NextCommand, view => view.NextSlide)
@@ -33,8 +37,9 @@ public partial class StandardInstallationView : ScreenBase vm.StepsProgress, view => view.StepsProgress.Value, p => p.Value * 1000)
.DisposeWith(disposables);
- this.OneWayBind(ViewModel, vm => vm.StepProgress, view => view.StepProgress.Value, p => p.Value * 10000)
+ this.OneWayBind(ViewModel, vm => vm.StepProgress, p => p.StepProgress.Value, p => p.Value * 10000)
.DisposeWith(disposables);
+
});
}
}
\ No newline at end of file
diff --git a/Wabbajack.App/Screens/StandardInstallationViewModel.cs b/Wabbajack.App/Screens/StandardInstallationViewModel.cs
index 57ae7134..8d489822 100644
--- a/Wabbajack.App/Screens/StandardInstallationViewModel.cs
+++ b/Wabbajack.App/Screens/StandardInstallationViewModel.cs
@@ -20,6 +20,7 @@ using Wabbajack.App.Utilities;
using Wabbajack.App.ViewModels.SubViewModels;
using Wabbajack.Common;
using Wabbajack.Downloaders.GameFile;
+using Wabbajack.Downloaders.Interfaces;
using Wabbajack.DTOs;
using Wabbajack.DTOs.DownloadStates;
using Wabbajack.DTOs.JsonConverters;
@@ -44,6 +45,7 @@ public class StandardInstallationViewModel : ViewModelBase
private IServiceScope _scope;
private SlideViewModel[] _slides = Array.Empty();
private Timer _slideTimer;
+ private Timer _updateTimer;
public StandardInstallationViewModel(ILogger logger, IServiceProvider provider,
GameLocator locator, DTOSerializer dtos,
@@ -63,6 +65,9 @@ public class StandardInstallationViewModel : ViewModelBase
this.WhenActivated(disposables =>
{
+ _updateTimer = new Timer(UpdateStatus, null, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(100));
+ _updateTimer.DisposeWith(disposables);
+
_slideTimer = new Timer(_ =>
{
if (IsPlaying) NextSlide(1);
@@ -102,12 +107,24 @@ public class StandardInstallationViewModel : ViewModelBase
[Reactive] public string StatusText { get; set; } = "";
[Reactive] public Percent StepsProgress { get; set; } = Percent.Zero;
[Reactive] public Percent StepProgress { get; set; } = Percent.Zero;
+
+ // Not Reactive, so we don't end up spamming the UI threads with events
+ public StatusUpdate _latestStatus = new("", Percent.Zero, Percent.Zero);
public void Receive(StartInstallation msg)
{
Install(msg).FireAndForget();
}
+ private void UpdateStatus(object? state)
+ {
+ Dispatcher.UIThread.Post(() =>
+ {
+ StepsProgress = _latestStatus.StepsProgress;
+ StepProgress = _latestStatus.StepProgress;
+ StatusText = _latestStatus.StatusText;
+ }, DispatcherPriority.Render);
+ }
private void NextSlide(int direction)
{
@@ -175,21 +192,12 @@ public class StandardInstallationViewModel : ViewModelBase
_installer = _provider.GetService()!;
- _installer.OnStatusUpdate = async update =>
- {
- Trace.TraceInformation("Update....");
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- StatusText = update.StatusText;
- StepsProgress = update.StepsProgress;
- StepProgress = update.StepProgress;
- }, DispatcherPriority.Background);
- };
+ _installer.OnStatusUpdate = update => _latestStatus = update;
_logger.LogInformation("Installer created, starting the installation process");
try
{
- var result = await _installer.Begin(CancellationToken.None);
+ var result = await Task.Run(async () => await _installer.Begin(CancellationToken.None));
if (!result) throw new Exception("Installation failed");
if (result) await SaveConfigAndContinue(_config);
@@ -200,6 +208,7 @@ public class StandardInstallationViewModel : ViewModelBase
}
}
+
private async Task SaveConfigAndContinue(InstallerConfiguration config)
{
var path = config.Install.Combine("modlist-image.png");
diff --git a/Wabbajack.App/ViewModels/InstallConfigurationViewModel.cs b/Wabbajack.App/ViewModels/InstallConfigurationViewModel.cs
index e1bb76b3..92907309 100644
--- a/Wabbajack.App/ViewModels/InstallConfigurationViewModel.cs
+++ b/Wabbajack.App/ViewModels/InstallConfigurationViewModel.cs
@@ -27,11 +27,12 @@ public class InstallConfigurationViewModel : ViewModelBase, IActivatableViewMode
{
private readonly DTOSerializer _dtos;
private readonly InstallationStateManager _stateManager;
+ private readonly SettingsManager _settingsManager;
-
- public InstallConfigurationViewModel(DTOSerializer dtos, InstallationStateManager stateManager)
+ public InstallConfigurationViewModel(DTOSerializer dtos, InstallationStateManager stateManager, SettingsManager settingsManager)
{
_stateManager = stateManager;
+ _settingsManager = settingsManager;
_dtos = dtos;
Activator = new ViewModelActivator();
@@ -51,22 +52,22 @@ public class InstallConfigurationViewModel : ViewModelBase, IActivatableViewMode
this.WhenAnyValue(t => t.ModListPath)
.Where(t => t != default)
- .SelectAsync(disposables, async x => await LoadModList(x))
- .Select(x => x)
+ .SelectMany(async x => await LoadModList(x))
+ .OnUIThread()
.ObserveOn(AvaloniaScheduler.Instance)
.BindTo(this, t => t.ModList)
.DisposeWith(disposables);
this.WhenAnyValue(t => t.ModListPath)
.Where(t => t != default)
- .SelectAsync(disposables, async x => await LoadModListImage(x))
- .ObserveOn(AvaloniaScheduler.Instance)
+ .SelectMany(async x => await LoadModListImage(x))
+ .OnUIThread()
.BindTo(this, t => t.ModListImage)
.DisposeWith(disposables);
var settings = this.WhenAnyValue(t => t.ModListPath)
- .SelectAsync(disposables, async v => await _stateManager.Get(v))
- .ObserveOn(RxApp.MainThreadScheduler)
+ .SelectMany(async v => await _stateManager.Get(v))
+ .OnUIThread()
.Where(s => s != null);
settings.Select(s => s!.Install)
@@ -76,9 +77,24 @@ public class InstallConfigurationViewModel : ViewModelBase, IActivatableViewMode
settings.Select(s => s!.Downloads)
.BindTo(this, vm => vm.Download)
.DisposeWith(disposables);
+
+
+ LoadSettings().FireAndForget();
+
});
}
+ private async Task LoadSettings()
+ {
+ var path = await _settingsManager.Load("last-install-path");
+ if (path != default && path.FileExists())
+ {
+ Dispatcher.UIThread.Post(() => {
+ ModListPath = path;
+ });
+ }
+ }
+
[Reactive] public AbsolutePath ModListPath { get; set; }
[Reactive] public AbsolutePath Install { get; set; }
@@ -107,13 +123,15 @@ public class InstallConfigurationViewModel : ViewModelBase, IActivatableViewMode
if (metadataPath.FileExists())
metadata = _dtos.Deserialize(await metadataPath.ReadAllTextAsync());
- _stateManager.SetLastState(new InstallationConfigurationSetting
+ await _stateManager.SetLastState(new InstallationConfigurationSetting
{
ModList = ModListPath,
Downloads = Download,
Install = Install,
Metadata = metadata
- }).FireAndForget();
+ });
+
+ await _settingsManager.Save("last-install-path", ModListPath);
MessageBus.Current.SendMessage(new NavigateTo(typeof(StandardInstallationViewModel)));
MessageBus.Current.SendMessage(new StartInstallation(ModListPath, Install, Download, metadata));
diff --git a/Wabbajack.App/ViewModels/MainWindowViewModel.cs b/Wabbajack.App/ViewModels/MainWindowViewModel.cs
index ef36998b..420e5141 100644
--- a/Wabbajack.App/ViewModels/MainWindowViewModel.cs
+++ b/Wabbajack.App/ViewModels/MainWindowViewModel.cs
@@ -59,8 +59,8 @@ public class MainWindowViewModel : ReactiveValidationObject, IActivatableViewMod
this.WhenActivated(disposables =>
{
BackButton = ReactiveCommand.Create(() => { Receive(new NavigateBack()); },
- this.ObservableForProperty(vm => vm.BreadCrumbs)
- .Select(bc => bc.Value.Count() > 1))
+ this.WhenAnyValue(vm => vm.BreadCrumbs)
+ .Select(bc => bc.Count() > 1))
.DisposeWith(disposables);
SettingsButton = ReactiveCommand.Create(() => { Receive(new NavigateTo(typeof(SettingsViewModel))); })
@@ -68,6 +68,13 @@ public class MainWindowViewModel : ReactiveValidationObject, IActivatableViewMod
LogViewButton = ReactiveCommand.Create(() => { Receive(new NavigateTo(typeof(LogScreenViewModel))); })
.DisposeWith(disposables);
+
+ this.WhenAnyValue(vm => vm.CurrentScreen)
+ .Where(view => view != default)
+ .Select(view => ((IScreenView) view).HumanName)
+ .Select(txt => txt == "" ? "Wabbajack" : $"Wabbajack - {txt}")
+ .BindTo(this, vm => vm.TitleText)
+ .DisposeWith(disposables);
});
CurrentScreen = (Control) _screens.First(s => s.ViewModelType == typeof(ModeSelectionViewModel));
@@ -85,6 +92,8 @@ public class MainWindowViewModel : ReactiveValidationObject, IActivatableViewMod
[Reactive] public ReactiveCommand LogViewButton { get; set; }
[Reactive] public string ResourceStatus { get; set; }
+
+ [Reactive] public string TitleText { get; set; }
public ViewModelActivator Activator { get; }
diff --git a/Wabbajack.App/Views/GuidedWebView.axaml.cs b/Wabbajack.App/Views/GuidedWebView.axaml.cs
index b9e00b00..7c6ac82f 100644
--- a/Wabbajack.App/Views/GuidedWebView.axaml.cs
+++ b/Wabbajack.App/Views/GuidedWebView.axaml.cs
@@ -8,7 +8,7 @@ namespace Wabbajack.App.Views;
public partial class GuidedWebView : ScreenBase
{
- public GuidedWebView() : base(false)
+ public GuidedWebView() : base("Web View", false)
{
InitializeComponent();
diff --git a/Wabbajack.App/Views/InstallConfigurationView.axaml.cs b/Wabbajack.App/Views/InstallConfigurationView.axaml.cs
index e7de5283..5292ca79 100644
--- a/Wabbajack.App/Views/InstallConfigurationView.axaml.cs
+++ b/Wabbajack.App/Views/InstallConfigurationView.axaml.cs
@@ -9,39 +9,44 @@ using Wabbajack.App.ViewModels;
namespace Wabbajack.App.Views;
-public partial class InstallConfigurationView : ReactiveUserControl, IScreenView
+public partial class InstallConfigurationView : ScreenBase, IScreenView
{
- public InstallConfigurationView()
+ public InstallConfigurationView() : base("Install Configuration")
{
InitializeComponent();
DataContext = App.Services.GetService()!;
this.WhenActivated(disposables =>
{
- this.Bind(ViewModel, x => x.ModListPath,
- view => view.ModListFile.SelectedPath)
+ ViewModel.WhenAnyValue(vm => vm.ModListPath)
+ .Subscribe(path => ModListFile.Load(path))
.DisposeWith(disposables);
- this.Bind(ViewModel, x => x.Download,
- view => view.DownloadPath.SelectedPath)
+
+ ViewModel.WhenAnyValue(vm => vm.ModListPath)
+ .Subscribe(path => ModListFile.Load(path))
.DisposeWith(disposables);
- this.Bind(ViewModel, x => x.Install,
- view => view.InstallPath.SelectedPath)
+
+ ViewModel.WhenAnyValue(vm => vm.Download)
+ .Subscribe(path => DownloadPath.Load(path))
+ .DisposeWith(disposables);
+
+ ViewModel.WhenAnyValue(vm => vm.Install)
+ .Subscribe(path => InstallPath.Load(path))
.DisposeWith(disposables);
- ViewModel.WhenAnyValue(x => x.BeginCommand)
- .Where(x => x != default)
- .BindTo(BeginInstall, x => x.Button.Command)
+ this.WhenAnyValue(view => view.ModListFile.SelectedPath)
+ .BindTo(ViewModel, vm => vm.ModListPath)
.DisposeWith(disposables);
- ViewModel.WhenAnyValue(x => x.ModList)
- .Where(x => x != default)
- .Select(x => x!.Name)
- .BindTo(ModListName, x => x.Text)
+ this.WhenAnyValue(view => view.DownloadPath.SelectedPath)
+ .BindTo(ViewModel, vm => vm.Download)
.DisposeWith(disposables);
- ViewModel.WhenAnyValue(x => x.ModListImage)
- .Where(x => x != default)
- .BindTo(ModListImage, x => x.Source)
+ this.WhenAnyValue(view => view.InstallPath.SelectedPath)
+ .BindTo(ViewModel, vm => vm.Install)
+ .DisposeWith(disposables);
+
+ this.BindCommand(ViewModel, vm => vm.BeginCommand, view => view.BeginInstall.Button)
.DisposeWith(disposables);
});
}
diff --git a/Wabbajack.App/Views/MainWindow.axaml b/Wabbajack.App/Views/MainWindow.axaml
index 760bbb33..18c23a71 100644
--- a/Wabbajack.App/Views/MainWindow.axaml
+++ b/Wabbajack.App/Views/MainWindow.axaml
@@ -32,25 +32,26 @@
-
+
+
-
+
-