using System; using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; using System.Reactive.Subjects; using Microsoft.Extensions.Logging; using ReactiveUI; using ReactiveUI.Fody.Helpers; using Wabbajack.Common; using Wabbajack; using Wabbajack.Messages; namespace Wabbajack { public interface IBackNavigatingVM : IReactiveObject { ViewModel NavigateBackTarget { get; set; } ReactiveCommand BackCommand { get; } Subject IsBackEnabledSubject { get; } IObservable IsBackEnabled { get; } } public class BackNavigatingVM : ViewModel, IBackNavigatingVM { [Reactive] public ViewModel NavigateBackTarget { get; set; } public ReactiveCommand BackCommand { get; protected set; } [Reactive] public bool IsActive { get; set; } public Subject IsBackEnabledSubject { get; } = new Subject(); public IObservable IsBackEnabled { get; } public BackNavigatingVM(ILogger logger) { IsBackEnabled = IsBackEnabledSubject.StartWith(true); BackCommand = ReactiveCommand.Create( execute: () => logger.CatchAndLog(() => { NavigateBack.Send(); Unload(); }), canExecute: this.ConstructCanNavigateBack() .ObserveOnGuiThread()); this.WhenActivated(disposables => { IsActive = true; Disposable.Create(() => IsActive = false).DisposeWith(disposables); }); } public virtual void Unload() { } } public static class IBackNavigatingVMExt { public static IObservable ConstructCanNavigateBack(this IBackNavigatingVM vm) { return vm.WhenAny(x => x.NavigateBackTarget) .CombineLatest(vm.IsBackEnabled) .Select(x => x.First != null && x.Second); } public static IObservable ConstructIsActive(this IBackNavigatingVM vm, MainWindowVM mwvm) { return mwvm.WhenAny(x => x.ActivePane) .Select(x => object.ReferenceEquals(vm, x)); } } }