2021-12-27 05:18:52 +00:00
|
|
|
|
using DynamicData.Binding;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
using ReactiveUI;
|
|
|
|
|
using ReactiveUI.Fody.Helpers;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Reactive.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows;
|
|
|
|
|
using System.Windows.Input;
|
2021-12-28 00:53:14 +00:00
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2021-12-27 23:15:30 +00:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
using Wabbajack.Common;
|
2021-12-28 00:53:14 +00:00
|
|
|
|
using Wabbajack.Downloaders.GameFile;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
using Wabbajack.Lib;
|
2021-12-26 22:05:28 +00:00
|
|
|
|
using Wabbajack.Lib.Interventions;
|
2021-12-27 23:15:30 +00:00
|
|
|
|
using Wabbajack.Networking.WabbajackClientApi;
|
2021-12-27 05:18:52 +00:00
|
|
|
|
using Wabbajack.Paths;
|
|
|
|
|
using Wabbajack.View_Models;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
|
|
|
|
|
namespace Wabbajack
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Main View Model for the application.
|
|
|
|
|
/// Keeps track of which sub view is being shown in the window, and has some singleton wiring like WorkQueue and Logging.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class MainWindowVM : ViewModel
|
|
|
|
|
{
|
|
|
|
|
public MainWindow MainWindow { get; }
|
|
|
|
|
|
|
|
|
|
public MainSettings Settings { get; }
|
|
|
|
|
|
|
|
|
|
[Reactive]
|
|
|
|
|
public ViewModel ActivePane { get; private set; }
|
|
|
|
|
|
|
|
|
|
public ObservableCollectionExtended<IStatusMessage> Log { get; } = new ObservableCollectionExtended<IStatusMessage>();
|
|
|
|
|
|
|
|
|
|
public readonly Lazy<CompilerVM> Compiler;
|
|
|
|
|
public readonly Lazy<InstallerVM> Installer;
|
|
|
|
|
public readonly Lazy<SettingsVM> SettingsPane;
|
|
|
|
|
public readonly Lazy<ModListGalleryVM> Gallery;
|
|
|
|
|
public readonly ModeSelectionVM ModeSelectionVM;
|
|
|
|
|
public readonly Lazy<ModListContentsVM> ModListContentsVM;
|
|
|
|
|
public readonly UserInterventionHandlers UserInterventionHandlers;
|
2021-12-27 23:15:30 +00:00
|
|
|
|
private readonly Client _wjClient;
|
|
|
|
|
private readonly ILogger<MainWindowVM> _logger;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
|
|
|
|
|
public ICommand CopyVersionCommand { get; }
|
|
|
|
|
public ICommand ShowLoginManagerVM { get; }
|
|
|
|
|
public ICommand OpenSettingsCommand { get; }
|
|
|
|
|
|
|
|
|
|
public string VersionDisplay { get; }
|
|
|
|
|
|
|
|
|
|
[Reactive]
|
|
|
|
|
public bool UpdateAvailable { get; private set; }
|
|
|
|
|
|
2021-12-28 00:53:14 +00:00
|
|
|
|
public MainWindowVM(ILogger<MainWindowVM> logger, MainWindow mainWindow, MainSettings settings, Client wjClient,
|
|
|
|
|
ServiceProvider serviceProvider)
|
2021-12-26 21:56:44 +00:00
|
|
|
|
{
|
2021-12-27 23:15:30 +00:00
|
|
|
|
_logger = logger;
|
|
|
|
|
_wjClient = wjClient;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
ConverterRegistration.Register();
|
|
|
|
|
MainWindow = mainWindow;
|
|
|
|
|
Settings = settings;
|
2021-12-28 00:53:14 +00:00
|
|
|
|
Installer = new Lazy<InstallerVM>(() => new InstallerVM(serviceProvider.GetService<ILogger<InstallerVM>>(), this, serviceProvider));
|
2021-12-26 21:56:44 +00:00
|
|
|
|
Compiler = new Lazy<CompilerVM>(() => new CompilerVM(this));
|
2021-12-28 00:53:14 +00:00
|
|
|
|
SettingsPane = new Lazy<SettingsVM>(() => new SettingsVM(serviceProvider.GetService<ILogger<SettingsVM>>(), this, serviceProvider));
|
|
|
|
|
Gallery = new Lazy<ModListGalleryVM>(() => new ModListGalleryVM(serviceProvider.GetService<ILogger<ModListGalleryVM>>(), this,
|
|
|
|
|
serviceProvider.GetService<Client>(), serviceProvider.GetService<GameLocator>(), serviceProvider));
|
2021-12-26 21:56:44 +00:00
|
|
|
|
ModeSelectionVM = new ModeSelectionVM(this);
|
2021-12-28 00:53:14 +00:00
|
|
|
|
ModListContentsVM = new Lazy<ModListContentsVM>(() => new ModListContentsVM(serviceProvider.GetService<ILogger<ModListContentsVM>>(), this));
|
|
|
|
|
UserInterventionHandlers = new UserInterventionHandlers(serviceProvider.GetService<ILogger<UserInterventionHandlers>>(), this);
|
2021-12-26 21:56:44 +00:00
|
|
|
|
|
|
|
|
|
// Set up logging
|
2021-12-28 00:53:14 +00:00
|
|
|
|
/* TODO
|
2021-12-26 21:56:44 +00:00
|
|
|
|
Utils.LogMessages
|
|
|
|
|
.ObserveOn(RxApp.TaskpoolScheduler)
|
|
|
|
|
.ToObservableChangeSet()
|
|
|
|
|
.Buffer(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler)
|
|
|
|
|
.Where(l => l.Count > 0)
|
|
|
|
|
.FlattenBufferResult()
|
|
|
|
|
.ObserveOnGuiThread()
|
|
|
|
|
.Bind(Log)
|
|
|
|
|
.Subscribe()
|
|
|
|
|
.DisposeWith(CompositeDisposable);
|
|
|
|
|
|
|
|
|
|
Utils.LogMessages
|
|
|
|
|
.Where(a => a is IUserIntervention or CriticalFailureIntervention)
|
|
|
|
|
.ObserveOnGuiThread()
|
|
|
|
|
.SelectTask(async msg =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await UserInterventionHandlers.Handle(msg);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
when (ex.GetType() != typeof(TaskCanceledException))
|
|
|
|
|
{
|
2021-12-27 23:15:30 +00:00
|
|
|
|
_logger.LogError(ex, "Error while handling user intervention of type {Type}",msg?.GetType());
|
2021-12-26 21:56:44 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (msg is IUserIntervention {Handled: false} intervention)
|
|
|
|
|
{
|
|
|
|
|
intervention.Cancel();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception cancelEx)
|
|
|
|
|
{
|
2021-12-27 23:15:30 +00:00
|
|
|
|
_logger.LogError(cancelEx, "Error while cancelling user intervention of type {Type}",msg?.GetType());
|
2021-12-26 21:56:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.Subscribe()
|
|
|
|
|
.DisposeWith(CompositeDisposable);
|
2021-12-28 00:53:14 +00:00
|
|
|
|
*/
|
2021-12-26 21:56:44 +00:00
|
|
|
|
|
|
|
|
|
if (IsStartingFromModlist(out var path))
|
|
|
|
|
{
|
|
|
|
|
Installer.Value.ModListLocation.TargetPath = path;
|
|
|
|
|
NavigateTo(Installer.Value);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Start on mode selection
|
|
|
|
|
NavigateTo(ModeSelectionVM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var assembly = Assembly.GetExecutingAssembly();
|
|
|
|
|
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
|
|
|
|
|
Consts.CurrentMinimumWabbajackVersion = Version.Parse(fvi.FileVersion);
|
|
|
|
|
VersionDisplay = $"v{fvi.FileVersion}";
|
2021-12-27 23:15:30 +00:00
|
|
|
|
_logger.LogInformation("Wabbajack Version: {FileVersion}", fvi.FileVersion);
|
2021-12-26 21:56:44 +00:00
|
|
|
|
|
2021-12-27 23:15:30 +00:00
|
|
|
|
Task.Run(() => _wjClient.SendMetric("started_wabbajack", fvi.FileVersion)).FireAndForget();
|
|
|
|
|
Task.Run(() => _wjClient.SendMetric("started_sha", ThisAssembly.Git.Sha));
|
2021-12-26 21:56:44 +00:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2021-12-27 23:15:30 +00:00
|
|
|
|
_logger.LogError(ex, "During App configuration");
|
2021-12-26 21:56:44 +00:00
|
|
|
|
VersionDisplay = "ERROR";
|
|
|
|
|
}
|
|
|
|
|
CopyVersionCommand = ReactiveCommand.Create(() =>
|
|
|
|
|
{
|
|
|
|
|
Clipboard.SetText($"Wabbajack {VersionDisplay}\n{ThisAssembly.Git.Sha}");
|
|
|
|
|
});
|
|
|
|
|
OpenSettingsCommand = ReactiveCommand.Create(
|
|
|
|
|
canExecute: this.WhenAny(x => x.ActivePane)
|
|
|
|
|
.Select(active => !SettingsPane.IsValueCreated || !object.ReferenceEquals(active, SettingsPane.Value)),
|
|
|
|
|
execute: () => NavigateTo(SettingsPane.Value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool IsStartingFromModlist(out AbsolutePath modlistPath)
|
|
|
|
|
{
|
2021-12-28 00:53:14 +00:00
|
|
|
|
/* TODO
|
2021-12-26 21:56:44 +00:00
|
|
|
|
if (CLIArguments.InstallPath == null)
|
|
|
|
|
{
|
|
|
|
|
modlistPath = default;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
modlistPath = (AbsolutePath)CLIArguments.InstallPath;
|
|
|
|
|
return true;
|
2021-12-28 00:53:14 +00:00
|
|
|
|
*/
|
|
|
|
|
return false;
|
2021-12-26 21:56:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OpenInstaller(AbsolutePath path)
|
|
|
|
|
{
|
|
|
|
|
if (path == default) return;
|
|
|
|
|
var installer = Installer.Value;
|
|
|
|
|
Settings.Installer.LastInstalledListLocation = path;
|
|
|
|
|
NavigateTo(installer);
|
|
|
|
|
installer.ModListLocation.TargetPath = path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void NavigateTo(ViewModel vm)
|
|
|
|
|
{
|
|
|
|
|
ActivePane = vm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void NavigateTo<T>(T vm)
|
|
|
|
|
where T : ViewModel, IBackNavigatingVM
|
|
|
|
|
{
|
|
|
|
|
vm.NavigateBackTarget = ActivePane;
|
|
|
|
|
ActivePane = vm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task ShutdownApplication()
|
|
|
|
|
{
|
|
|
|
|
Dispose();
|
|
|
|
|
Settings.PosX = MainWindow.Left;
|
|
|
|
|
Settings.PosY = MainWindow.Top;
|
|
|
|
|
Settings.Width = MainWindow.Width;
|
|
|
|
|
Settings.Height = MainWindow.Height;
|
|
|
|
|
await MainSettings.SaveSettings(Settings);
|
|
|
|
|
Application.Current.Shutdown();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|