2020-01-31 22:07:55 +00:00
using System ;
2019-10-12 21:10:58 +00:00
using ReactiveUI ;
2019-08-30 23:57:56 +00:00
using System.Diagnostics ;
2019-07-22 22:17:46 +00:00
using System.IO ;
2019-10-11 11:15:54 +00:00
using System.IO.Compression ;
2019-09-26 03:18:36 +00:00
using System.Linq ;
2019-10-12 03:07:57 +00:00
using System.Reactive.Disposables ;
using System.Reactive.Linq ;
2019-07-22 22:17:46 +00:00
using System.Reflection ;
2019-11-17 23:48:32 +00:00
using System.Threading.Tasks ;
2019-07-31 03:59:19 +00:00
using System.Windows ;
2019-09-26 03:18:36 +00:00
using System.Windows.Media.Imaging ;
2019-07-22 22:17:46 +00:00
using Wabbajack.Common ;
2019-10-16 03:10:34 +00:00
using Wabbajack.Lib ;
2019-11-02 23:23:11 +00:00
using ReactiveUI.Fody.Helpers ;
2019-11-09 01:53:32 +00:00
using System.Windows.Media ;
2019-11-20 00:15:46 +00:00
using DynamicData ;
using DynamicData.Binding ;
2019-12-04 04:12:08 +00:00
using Wabbajack.Common.StatusFeed ;
2019-12-02 05:36:47 +00:00
using System.Reactive ;
2019-12-15 19:20:27 +00:00
using System.Collections.Generic ;
2020-12-07 04:26:02 +00:00
using System.Reactive.Subjects ;
2020-01-05 03:06:34 +00:00
using System.Windows.Input ;
2020-07-15 11:39:47 +00:00
using Microsoft.WindowsAPICodePack.Dialogs ;
2020-01-31 22:07:55 +00:00
using Wabbajack.Common.IO ;
2019-07-22 22:17:46 +00:00
namespace Wabbajack
{
2020-12-07 04:26:02 +00:00
public class InstallerVM : BackNavigatingVM , IBackNavigatingVM , ICpuStatusVM
2019-07-22 22:17:46 +00:00
{
2019-10-13 19:12:33 +00:00
public SlideShow Slideshow { get ; }
2019-10-30 19:45:42 +00:00
2019-10-22 03:03:01 +00:00
public MainWindowVM MWVM { get ; }
2019-10-11 10:14:01 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < ModListVM > _modList ;
public ModListVM ModList = > _modList . Value ;
2019-10-12 03:07:57 +00:00
2019-12-03 05:40:59 +00:00
public FilePickerVM ModListLocation { get ; }
2019-10-12 03:31:33 +00:00
2019-12-02 05:36:47 +00:00
private readonly ObservableAsPropertyHelper < ISubInstallerVM > _installer ;
public ISubInstallerVM Installer = > _installer . Value ;
2019-10-12 18:42:47 +00:00
2019-11-24 03:17:22 +00:00
private readonly ObservableAsPropertyHelper < bool > _installing ;
public bool Installing = > _installing . Value ;
2019-10-12 21:04:14 +00:00
2019-11-02 23:23:11 +00:00
[Reactive]
2019-12-18 03:10:38 +00:00
public bool StartedInstallation { get ; set ; }
[Reactive]
2019-12-19 05:22:39 +00:00
public ErrorResponse ? Completed { get ; set ; }
2019-11-01 00:21:24 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < ImageSource > _image ;
public ImageSource Image = > _image . Value ;
2019-10-30 19:45:42 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < string > _titleText ;
public string TitleText = > _titleText . Value ;
2019-11-01 01:02:39 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < string > _authorText ;
public string AuthorText = > _authorText . Value ;
2019-11-01 01:02:39 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < string > _description ;
public string Description = > _description . Value ;
2019-11-01 01:02:39 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < string > _progressTitle ;
public string ProgressTitle = > _progressTitle . Value ;
2019-11-07 05:33:08 +00:00
2019-11-21 15:45:00 +00:00
private readonly ObservableAsPropertyHelper < string > _modListName ;
public string ModListName = > _modListName . Value ;
2019-11-07 05:37:40 +00:00
2020-02-08 04:35:08 +00:00
private readonly ObservableAsPropertyHelper < Percent > _percentCompleted ;
public Percent PercentCompleted = > _percentCompleted . Value ;
2019-11-24 03:17:22 +00:00
2019-12-15 19:20:27 +00:00
public ObservableCollectionExtended < CPUDisplayVM > StatusList { get ; } = new ObservableCollectionExtended < CPUDisplayVM > ( ) ;
2019-12-04 04:12:08 +00:00
public ObservableCollectionExtended < IStatusMessage > Log = > MWVM . Log ;
2019-11-24 03:17:22 +00:00
2019-12-02 05:36:47 +00:00
private readonly ObservableAsPropertyHelper < ModManager ? > _TargetManager ;
public ModManager ? TargetManager = > _TargetManager . Value ;
2019-12-09 00:19:36 +00:00
private readonly ObservableAsPropertyHelper < IUserIntervention > _ActiveGlobalUserIntervention ;
public IUserIntervention ActiveGlobalUserIntervention = > _ActiveGlobalUserIntervention . Value ;
2020-01-11 20:20:14 +00:00
private readonly ObservableAsPropertyHelper < ( int CurrentCPUs , int DesiredCPUs ) > _CurrentCpuCount ;
public ( int CurrentCPUs , int DesiredCPUs ) CurrentCpuCount = > _CurrentCpuCount . Value ;
2020-01-16 02:29:45 +00:00
private readonly ObservableAsPropertyHelper < bool > _LoadingModlist ;
public bool LoadingModlist = > _LoadingModlist . Value ;
2020-01-16 03:19:00 +00:00
private readonly ObservableAsPropertyHelper < bool > _IsActive ;
public bool IsActive = > _IsActive . Value ;
2019-10-11 22:30:12 +00:00
// Command properties
2020-01-21 01:07:41 +00:00
public ReactiveCommand < Unit , Unit > ShowManifestCommand { get ; }
2020-01-20 22:43:58 +00:00
public ReactiveCommand < Unit , Unit > OpenReadmeCommand { get ; }
2020-01-21 01:07:41 +00:00
public ReactiveCommand < Unit , Unit > VisitModListWebsiteCommand { get ; }
2020-01-07 05:44:05 +00:00
public ReactiveCommand < Unit , Unit > BackCommand { get ; }
2020-12-07 04:26:02 +00:00
2020-01-20 22:43:58 +00:00
public ReactiveCommand < Unit , Unit > CloseWhenCompleteCommand { get ; }
public ReactiveCommand < Unit , Unit > GoToInstallCommand { get ; }
public ReactiveCommand < Unit , Unit > BeginCommand { get ; }
2019-10-11 22:30:12 +00:00
2020-12-07 04:26:02 +00:00
public InstallerVM ( MainWindowVM mainWindowVM ) : base ( mainWindowVM )
2019-07-30 21:45:04 +00:00
{
2020-12-07 04:26:02 +00:00
2019-10-12 08:02:58 +00:00
if ( Path . GetDirectoryName ( Assembly . GetEntryAssembly ( ) . Location . ToLower ( ) ) = = KnownFolders . Downloads . Path . ToLower ( ) )
2019-09-14 04:35:42 +00:00
{
2020-06-01 20:26:03 +00:00
Utils . Error ( new CriticalFailureIntervention (
2019-10-12 09:12:53 +00:00
"Wabbajack is running inside your Downloads folder. This folder is often highly monitored by antivirus software and these can often " +
2019-10-12 08:02:58 +00:00
"conflict with the operations Wabbajack needs to perform. Please move this executable outside of your Downloads folder and then restart the app." ,
2020-06-01 20:26:03 +00:00
"Cannot run inside Downloads" ) ) ;
2019-09-14 04:35:42 +00:00
}
2019-11-21 15:04:33 +00:00
MWVM = mainWindowVM ;
2019-11-06 03:22:38 +00:00
2020-07-15 11:39:47 +00:00
ModListLocation = new FilePickerVM
2019-11-24 08:44:41 +00:00
{
2019-12-14 20:11:39 +00:00
ExistCheckOption = FilePickerVM . CheckOptions . On ,
2019-11-24 08:44:41 +00:00
PathType = FilePickerVM . PathTypeOptions . File ,
2020-01-13 21:11:07 +00:00
PromptTitle = "Select a ModList to install"
2019-11-24 08:44:41 +00:00
} ;
2020-07-15 11:39:47 +00:00
ModListLocation . Filters . Add ( new CommonFileDialogFilter ( "Wabbajack Modlist" , ".wabbajack" ) ) ;
2019-11-09 20:20:32 +00:00
2019-12-02 05:36:47 +00:00
// Swap to proper sub VM based on selected type
_installer = this . WhenAny ( x = > x . TargetManager )
// Delay so the initial VM swap comes in immediately, subVM comes right after
. DelayInitial ( TimeSpan . FromMilliseconds ( 50 ) , RxApp . MainThreadScheduler )
. Select < ModManager ? , ISubInstallerVM > ( type = >
{
switch ( type )
{
case ModManager . MO2 :
return new MO2InstallerVM ( this ) ;
default :
return null ;
}
} )
// Unload old VM
. Pairwise ( )
. Do ( pair = >
{
pair . Previous ? . Unload ( ) ;
} )
. Select ( p = > p . Current )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( Installer ) ) ;
2019-12-02 05:36:47 +00:00
2019-11-06 03:22:38 +00:00
// Load settings
2019-12-03 02:38:33 +00:00
MWVM . Settings . SaveSignal
. Subscribe ( _ = >
2019-11-06 03:22:38 +00:00
{
2019-12-03 05:40:59 +00:00
MWVM . Settings . Installer . LastInstalledListLocation = ModListLocation . TargetPath ;
2019-11-06 03:22:38 +00:00
} )
2019-11-21 15:04:33 +00:00
. DisposeWith ( CompositeDisposable ) ;
2019-09-14 04:35:42 +00:00
2020-01-16 03:19:00 +00:00
_IsActive = this . ConstructIsActive ( MWVM )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( IsActive ) ) ;
2020-01-16 03:19:00 +00:00
// Active path represents the path to currently have loaded
// If we're not actively showing, then "unload" the active path
var activePath = Observable . CombineLatest (
this . WhenAny ( x = > x . ModListLocation . TargetPath ) ,
this . WhenAny ( x = > x . IsActive ) ,
resultSelector : ( path , active ) = > ( path , active ) )
. Select ( x = >
{
2020-03-28 20:04:22 +00:00
if ( ! x . active ) return default ;
2020-01-16 03:19:00 +00:00
return x . path ;
} )
// Throttle slightly so changes happen more atomically
2020-01-17 04:52:29 +00:00
. Throttle ( TimeSpan . FromMilliseconds ( 50 ) , RxApp . MainThreadScheduler )
2020-01-16 03:19:00 +00:00
. Replay ( 1 )
. RefCount ( ) ;
_modList = activePath
2019-10-30 19:45:42 +00:00
. ObserveOn ( RxApp . TaskpoolScheduler )
2020-01-16 03:19:00 +00:00
// Convert from active path to modlist VM
2019-11-06 03:22:38 +00:00
. Select ( modListPath = >
2019-10-28 04:59:58 +00:00
{
2020-03-28 20:04:22 +00:00
if ( modListPath = = default ) return default ;
if ( ! modListPath . Exists ) return default ;
2019-12-03 05:35:51 +00:00
return new ModListVM ( modListPath ) ;
2019-10-28 04:59:58 +00:00
} )
2020-01-16 03:54:06 +00:00
. DisposeOld ( )
2019-10-28 04:59:58 +00:00
. ObserveOnGuiThread ( )
2019-11-03 06:01:19 +00:00
. StartWith ( default ( ModListVM ) )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( ModList ) ) ;
2020-01-16 03:54:06 +00:00
// Force GC collect when modlist changes, just to make sure we clean up any loose large items immediately
this . WhenAny ( x = > x . ModList )
2020-01-17 04:52:29 +00:00
. Delay ( TimeSpan . FromMilliseconds ( 50 ) , RxApp . MainThreadScheduler )
2020-01-16 03:54:06 +00:00
. Subscribe ( x = >
{
GC . Collect ( ) ;
} ) ;
2020-01-16 02:29:45 +00:00
_LoadingModlist = Observable . Merge (
2020-01-16 03:19:00 +00:00
// When active path changes, mark as loading
activePath
2020-01-16 02:29:45 +00:00
. Select ( _ = > true ) ,
// When the resulting modlist comes in, mark it as done
this . WhenAny ( x = > x . ModList )
. Select ( _ = > false ) )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( LoadingModlist ) ) ;
2019-12-02 05:36:47 +00:00
_installing = this . WhenAny ( x = > x . Installer . ActiveInstallation )
2019-12-18 03:10:38 +00:00
. Select ( i = > i ! = null )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( Installing ) ) ;
2019-12-02 05:36:47 +00:00
_TargetManager = this . WhenAny ( x = > x . ModList )
. Select ( modList = > modList ? . ModManager )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( TargetManager ) ) ;
2019-11-24 03:17:22 +00:00
2020-01-13 21:11:07 +00:00
// Add additional error check on ModList
2019-12-03 05:40:59 +00:00
ModListLocation . AdditionalError = this . WhenAny ( x = > x . ModList )
2019-12-03 05:35:51 +00:00
. Select < ModListVM , IErrorResponse > ( modList = >
{
2020-08-11 12:31:58 +00:00
if ( modList = = null ) return ErrorResponse . Fail ( "Modlist path resulted in a null object." ) ;
if ( modList . Error ! = null ) return ErrorResponse . Fail ( "Modlist is corrupt" , modList . Error ) ;
2020-10-01 12:24:26 +00:00
if ( modList . WabbajackVersion ! = null & & modList . WabbajackVersion > Consts . CurrentMinimumWabbajackVersion )
2020-08-11 12:31:58 +00:00
return ErrorResponse . Fail ( "The Modlist you are trying to install was made using a newer Version of Wabbajack. Please update Wabbajack before installing!" ) ;
2019-12-03 05:35:51 +00:00
return ErrorResponse . Success ;
} ) ;
2019-11-24 23:42:28 +00:00
BackCommand = ReactiveCommand . Create (
2019-12-14 03:47:09 +00:00
execute : ( ) = >
{
2019-12-18 03:10:38 +00:00
StartedInstallation = false ;
2019-12-19 05:22:39 +00:00
Completed = null ;
2020-01-05 02:50:05 +00:00
mainWindowVM . NavigateTo ( mainWindowVM . ModeSelectionVM ) ;
2019-12-14 03:47:09 +00:00
} ,
2020-01-05 03:06:34 +00:00
canExecute : Observable . CombineLatest (
this . WhenAny ( x = > x . Installing )
. Select ( x = > ! x ) ,
this . ConstructCanNavigateBack ( ) ,
resultSelector : ( i , b ) = > i & & b )
. ObserveOnGuiThread ( ) ) ;
2019-11-24 23:42:28 +00:00
2019-12-02 05:36:47 +00:00
_percentCompleted = this . WhenAny ( x = > x . Installer . ActiveInstallation )
2019-11-24 03:17:22 +00:00
. StartWith ( default ( AInstaller ) )
2019-12-14 03:47:09 +00:00
. CombineLatest (
this . WhenAny ( x = > x . Completed ) ,
( installer , completed ) = >
2019-11-24 03:17:22 +00:00
{
2019-12-14 03:47:09 +00:00
if ( installer = = null )
{
2020-02-08 04:35:08 +00:00
return Observable . Return < Percent > ( completed ! = null ? Percent . One : Percent . Zero ) ;
2019-12-14 03:47:09 +00:00
}
2020-02-08 04:35:08 +00:00
return installer . PercentCompleted . StartWith ( Percent . Zero ) ;
2019-12-14 03:47:09 +00:00
} )
2019-11-24 03:17:22 +00:00
. Switch ( )
2020-01-17 04:52:29 +00:00
. Debounce ( TimeSpan . FromMilliseconds ( 25 ) , RxApp . MainThreadScheduler )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( PercentCompleted ) ) ;
2019-10-28 04:59:58 +00:00
2019-11-21 15:04:33 +00:00
Slideshow = new SlideShow ( this ) ;
2019-10-30 19:45:42 +00:00
2020-01-13 21:11:07 +00:00
// Set display items to ModList if configuring or complete,
2019-11-01 01:02:39 +00:00
// or to the current slideshow data if installing
2019-11-21 15:45:00 +00:00
_image = Observable . CombineLatest (
2019-12-03 05:35:51 +00:00
this . WhenAny ( x = > x . ModList . Error ) ,
2019-11-03 06:01:19 +00:00
this . WhenAny ( x = > x . ModList )
2020-01-16 03:19:00 +00:00
. Select ( x = > x ? . ImageObservable ? ? Observable . Return ( default ( BitmapImage ) ) )
2019-12-14 20:33:26 +00:00
. Switch ( )
2020-01-16 03:19:00 +00:00
. StartWith ( default ( BitmapImage ) ) ,
2019-11-01 01:02:39 +00:00
this . WhenAny ( x = > x . Slideshow . Image )
. StartWith ( default ( BitmapImage ) ) ,
this . WhenAny ( x = > x . Installing ) ,
2020-01-16 03:19:00 +00:00
this . WhenAny ( x = > x . LoadingModlist ) ,
resultSelector : ( err , modList , slideshow , installing , loading ) = >
2019-12-03 05:35:51 +00:00
{
if ( err ! = null )
{
2020-01-25 23:25:51 +00:00
return ResourceLinks . WabbajackErrLogo . Value ;
2019-12-03 05:35:51 +00:00
}
2020-01-16 03:19:00 +00:00
if ( loading ) return default ;
return installing ? slideshow : modList ;
2019-12-03 05:35:51 +00:00
} )
2019-11-09 01:53:32 +00:00
. Select < BitmapImage , ImageSource > ( x = > x )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( Image ) ) ;
2019-11-21 15:45:00 +00:00
_titleText = Observable . CombineLatest (
2019-12-25 01:42:05 +00:00
this . WhenAny ( x = > x . ModList )
. Select ( modList = > modList ? . Name ? ? string . Empty ) ,
2020-03-04 12:10:49 +00:00
this . WhenAny ( x = > x . Slideshow . TargetMod . State . Name )
2019-11-03 06:01:19 +00:00
. StartWith ( default ( string ) ) ,
2019-11-01 01:02:39 +00:00
this . WhenAny ( x = > x . Installing ) ,
resultSelector : ( modList , mod , installing ) = > installing ? mod : modList )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( TitleText ) ) ;
2019-11-21 15:45:00 +00:00
_authorText = Observable . CombineLatest (
2019-12-25 01:42:05 +00:00
this . WhenAny ( x = > x . ModList )
. Select ( modList = > modList ? . Author ? ? string . Empty ) ,
2020-03-04 12:10:49 +00:00
this . WhenAny ( x = > x . Slideshow . TargetMod . State . Author )
2019-11-03 06:01:19 +00:00
. StartWith ( default ( string ) ) ,
2019-11-01 01:02:39 +00:00
this . WhenAny ( x = > x . Installing ) ,
resultSelector : ( modList , mod , installing ) = > installing ? mod : modList )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( AuthorText ) ) ;
2019-11-21 15:45:00 +00:00
_description = Observable . CombineLatest (
2019-12-25 01:42:05 +00:00
this . WhenAny ( x = > x . ModList )
. Select ( modList = > modList ? . Description ? ? string . Empty ) ,
2020-03-04 12:10:49 +00:00
this . WhenAny ( x = > x . Slideshow . TargetMod . State . Description )
2019-11-03 06:01:19 +00:00
. StartWith ( default ( string ) ) ,
2019-11-01 01:02:39 +00:00
this . WhenAny ( x = > x . Installing ) ,
resultSelector : ( modList , mod , installing ) = > installing ? mod : modList )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( Description ) ) ;
2019-12-03 05:35:51 +00:00
_modListName = Observable . CombineLatest (
this . WhenAny ( x = > x . ModList . Error )
. Select ( x = > x ! = null ) ,
this . WhenAny ( x = > x . ModList )
. Select ( x = > x ? . Name ) ,
resultSelector : ( err , name ) = >
{
if ( err ) return "Corrupted Modlist" ;
return name ;
} )
2020-11-03 14:45:08 +00:00
. Merge ( this . WhenAny ( x = > x . Installer . ActiveInstallation )
. Where ( c = > c ! = null )
. SelectMany ( c = > c . TextStatus ) )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( ModListName ) ) ;
2019-10-30 19:45:42 +00:00
2020-02-01 13:42:31 +00:00
ShowManifestCommand = ReactiveCommand . Create ( ( ) = >
{
2020-11-09 11:26:07 +00:00
Utils . OpenWebsite ( new Uri ( "https://www.wabbajack.org/#/modlists/manifest" ) ) ;
2020-08-30 09:45:46 +00:00
} , this . WhenAny ( x = > x . ModList )
. Select ( x = > x ? . SourceModList ! = null )
. ObserveOnGuiThread ( ) ) ;
2019-11-21 15:04:33 +00:00
OpenReadmeCommand = ReactiveCommand . Create (
2020-04-15 17:40:41 +00:00
execute : ( ) = > this . ModList ? . OpenReadme ( ) ,
2019-10-13 20:14:11 +00:00
canExecute : this . WhenAny ( x = > x . ModList )
. Select ( modList = > ! string . IsNullOrEmpty ( modList ? . Readme ) )
2019-10-12 18:42:47 +00:00
. ObserveOnGuiThread ( ) ) ;
2020-01-21 01:07:41 +00:00
VisitModListWebsiteCommand = ReactiveCommand . Create (
2020-01-20 22:43:58 +00:00
execute : ( ) = >
{
2020-01-26 03:21:41 +00:00
Utils . OpenWebsite ( ModList . Website ) ;
2020-01-20 22:43:58 +00:00
return Unit . Default ;
} ,
2019-11-01 02:57:49 +00:00
canExecute : this . WhenAny ( x = > x . ModList . Website )
2020-03-22 21:55:31 +00:00
. Select ( x = > x ! = null )
2019-11-01 02:57:49 +00:00
. ObserveOnGuiThread ( ) ) ;
2019-10-12 03:07:57 +00:00
2020-01-15 05:24:59 +00:00
_progressTitle = this . WhenAnyValue (
x = > x . Installing ,
x = > x . StartedInstallation ,
x = > x . Completed ,
selector : ( installing , started , completed ) = >
2019-11-07 05:33:08 +00:00
{
2019-12-27 21:50:27 +00:00
if ( installing )
{
return "Installing" ;
}
2020-01-15 05:24:59 +00:00
else if ( started )
{
if ( completed = = null ) return "Installing" ;
return completed . Value . Succeeded ? "Installed" : "Failed" ;
}
2019-12-27 21:50:27 +00:00
else
{
2020-07-19 20:50:11 +00:00
return "Awaiting Input" ;
2019-12-27 21:50:27 +00:00
}
2019-11-07 05:33:08 +00:00
} )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( ProgressTitle ) ) ;
2019-11-24 03:17:22 +00:00
2020-01-10 04:27:59 +00:00
UIUtils . BindCpuStatus (
this . WhenAny ( x = > x . Installer . ActiveInstallation )
. SelectMany ( c = > c ? . QueueStatus ? ? Observable . Empty < CPUStatus > ( ) ) ,
StatusList )
2019-11-24 03:17:22 +00:00
. DisposeWith ( CompositeDisposable ) ;
2019-12-02 05:36:47 +00:00
2019-12-19 01:14:21 +00:00
BeginCommand = ReactiveCommand . CreateFromTask (
canExecute : this . WhenAny ( x = > x . Installer . CanInstall )
2020-07-25 22:58:45 +00:00
. Select ( err = > err . Succeeded ) ,
2019-12-19 01:14:21 +00:00
execute : async ( ) = >
{
try
{
2020-02-04 01:02:57 +00:00
Utils . Log ( $"Starting to install {ModList.Name}" ) ;
2020-12-07 04:26:02 +00:00
IsBackEnabledSubject . OnNext ( false ) ;
2020-01-18 21:57:53 +00:00
var success = await this . Installer . Install ( ) ;
Completed = ErrorResponse . Create ( success ) ;
2019-12-20 05:09:53 +00:00
try
{
2020-04-15 17:40:41 +00:00
this . ModList ? . OpenReadme ( ) ;
2019-12-20 05:09:53 +00:00
}
catch ( Exception ex )
{
Utils . Error ( ex ) ;
}
2019-12-19 01:14:21 +00:00
}
catch ( Exception ex )
2020-12-07 04:26:02 +00:00
{
2020-01-04 02:26:44 +00:00
Utils . Error ( ex , $"Encountered error, can't continue" ) ;
2019-12-19 01:14:21 +00:00
while ( ex . InnerException ! = null ) ex = ex . InnerException ;
2019-12-19 05:22:39 +00:00
Completed = ErrorResponse . Fail ( ex ) ;
2019-12-19 01:14:21 +00:00
}
2020-12-07 04:26:02 +00:00
finally
{
IsBackEnabledSubject . OnNext ( true ) ;
}
2019-12-19 01:14:21 +00:00
} ) ;
2019-12-02 05:36:47 +00:00
// When sub installer begins an install, mark state variable
2019-12-19 01:14:21 +00:00
BeginCommand . StartingExecution ( )
2019-12-02 05:36:47 +00:00
. Subscribe ( _ = >
{
2019-12-18 03:10:38 +00:00
StartedInstallation = true ;
} )
. DisposeWith ( CompositeDisposable ) ;
2019-12-09 00:19:36 +00:00
// Listen for user interventions, and compile a dynamic list of all unhandled ones
var activeInterventions = this . WhenAny ( x = > x . Installer . ActiveInstallation )
2020-01-21 04:23:33 +00:00
. WithLatestFrom (
this . WhenAny ( x = > x . Installer ) ,
( activeInstall , installer ) = >
{
if ( activeInstall = = null ) return Observable . Empty < IChangeSet < IUserIntervention > > ( ) ;
return activeInstall . LogMessages
. WhereCastable < IStatusMessage , IUserIntervention > ( )
. ToObservableChangeSet ( )
. AutoRefresh ( i = > i . Handled )
. Filter ( i = > ! i . Handled )
. Transform ( x = > installer . InterventionConverter ( x ) ) ;
} )
. Switch ( )
2019-12-09 00:19:36 +00:00
. AsObservableList ( ) ;
// Find the top intervention /w no CPU ID to be marked as "global"
_ActiveGlobalUserIntervention = activeInterventions . Connect ( )
. Filter ( x = > x . CpuID = = WorkQueue . UnassignedCpuId )
. QueryWhenChanged ( query = > query . FirstOrDefault ( ) )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( ActiveGlobalUserIntervention ) ) ;
2019-12-11 04:59:15 +00:00
2020-08-08 12:33:36 +00:00
CloseWhenCompleteCommand = ReactiveCommand . CreateFromTask (
2019-12-19 05:22:39 +00:00
canExecute : this . WhenAny ( x = > x . Completed )
. Select ( x = > x ! = null ) ,
2020-08-08 12:33:36 +00:00
execute : async ( ) = >
2019-12-11 04:59:15 +00:00
{
2020-08-08 12:33:36 +00:00
await MWVM . ShutdownApplication ( ) ;
2019-12-11 04:59:15 +00:00
} ) ;
GoToInstallCommand = ReactiveCommand . Create (
canExecute : Observable . CombineLatest (
2019-12-19 05:22:39 +00:00
this . WhenAny ( x = > x . Completed )
. Select ( x = > x ! = null ) ,
2019-12-11 04:59:15 +00:00
this . WhenAny ( x = > x . Installer . SupportsAfterInstallNavigation ) ,
resultSelector : ( complete , supports ) = > complete & & supports ) ,
execute : ( ) = >
{
Installer . AfterInstallNavigation ( ) ;
} ) ;
2020-01-11 20:20:14 +00:00
_CurrentCpuCount = this . WhenAny ( x = > x . Installer . ActiveInstallation . Queue . CurrentCpuCount )
. Switch ( )
2020-01-17 04:48:54 +00:00
. ToGuiProperty ( this , nameof ( CurrentCpuCount ) ) ;
2019-10-09 09:22:03 +00:00
}
2019-10-09 22:59:58 +00:00
}
2019-11-20 00:15:46 +00:00
}