FilePickerVM ExistCheckOption /w IfNotEmpty features

Some paths aren't an error condition when the path is completely empty
This commit is contained in:
Justin Swanson 2019-11-17 01:04:53 -06:00
parent a1070928e0
commit cafba5ff81
6 changed files with 92 additions and 27 deletions

View File

@ -60,6 +60,32 @@ namespace Wabbajack
.Switch();
}
/// <summary>
/// Convenience operator to subscribe to the source observable, only when a second "switch" observable is on.
/// When the switch is on, the source will be subscribed to, and its updates passed through.
/// When the switch is off, the subscription to the source observable will be stopped, and no signal will be published.
/// </summary>
/// <param name="source">Source observable to subscribe to if on</param>
/// <param name="filterSwitch">On/Off signal of whether to subscribe to source observable</param>
/// <param name="valueOnOff">Value to fire when switching off</param>
/// <returns>Observable that publishes data from source, if the switch is on.</returns>
public static IObservable<T> FilterSwitch<T>(this IObservable<T> source, IObservable<bool> filterSwitch, T valueWhenOff)
{
return filterSwitch
.DistinctUntilChanged()
.Select(on =>
{
if (on)
{
return source;
}
else
{
return Observable.Return<T>(valueWhenOff);
}
})
.Switch();
}
/// Inspiration:
/// http://reactivex.io/documentation/operators/debounce.html

View File

@ -40,13 +40,13 @@ namespace Wabbajack
{
this.ModlistLocation = new FilePickerVM()
{
DoExistsCheck = true,
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.File,
PromptTitle = "Select Modlist"
};
this.DownloadLocation = new FilePickerVM()
{
DoExistsCheck = true,
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Download Location",
};

View File

@ -36,7 +36,7 @@ namespace Wabbajack
this.settings = settings;
this.ImagePath = new FilePickerVM()
{
DoExistsCheck = false,
ExistCheckOption = FilePickerVM.ExistCheckOptions.IfNotEmpty,
PathType = FilePickerVM.PathTypeOptions.File,
Filters =
{
@ -46,7 +46,7 @@ namespace Wabbajack
this.ReadMeText = new FilePickerVM()
{
PathType = FilePickerVM.PathTypeOptions.File,
DoExistsCheck = false,
ExistCheckOption = FilePickerVM.ExistCheckOptions.IfNotEmpty,
};
}

View File

@ -53,19 +53,19 @@ namespace Wabbajack
{
this.GameLocation = new FilePickerVM()
{
DoExistsCheck = true,
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Game Folder Location"
};
this.DownloadsLocation = new FilePickerVM()
{
DoExistsCheck = true,
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Downloads Folder"
};
this.StagingLocation = new FilePickerVM()
{
DoExistsCheck = true,
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Staging Folder"
};

View File

@ -23,6 +23,13 @@ namespace Wabbajack
Folder
}
public enum ExistCheckOptions
{
Off,
IfNotEmpty,
On
}
public object Parent { get; }
[Reactive]
@ -38,7 +45,7 @@ namespace Wabbajack
public PathTypeOptions PathType { get; set; }
[Reactive]
public bool DoExistsCheck { get; set; }
public ExistCheckOptions ExistCheckOption { get; set; }
[Reactive]
public IObservable<IErrorResponse> AdditionalError { get; set; }
@ -63,28 +70,60 @@ namespace Wabbajack
this.SetTargetPathCommand = ConstructTypicalPickerCommand();
// Check that file exists
this._Exists = Observable.Interval(TimeSpan.FromSeconds(3))
.FilterSwitch(
Observable.CombineLatest(
this.WhenAny(x => x.PathType),
this.WhenAny(x => x.DoExistsCheck),
resultSelector: (type, doExists) => type != PathTypeOptions.Off && doExists))
.Unit()
// Also do it when fields change
.Merge(this.WhenAny(x => x.PathType).Unit())
.Merge(this.WhenAny(x => x.DoExistsCheck).Unit())
.CombineLatest(
this.WhenAny(x => x.DoExistsCheck),
this.WhenAny(x => x.PathType),
this.WhenAny(x => x.TargetPath)
var existsCheckTuple = Observable.CombineLatest(
this.WhenAny(x => x.ExistCheckOption),
this.WhenAny(x => x.PathType),
this.WhenAny(x => x.TargetPath)
// Dont want to debounce the initial value, because we know it's null
.Skip(1)
.Debounce(TimeSpan.FromMilliseconds(200)),
resultSelector: (_, DoExists, Type, Path) => (DoExists, Type, Path))
.Debounce(TimeSpan.FromMilliseconds(200))
.StartWith(default(string)),
resultSelector: (ExistsOption, Type, Path) => (ExistsOption, Type, Path))
.Publish()
.RefCount();
this._Exists = Observable.Interval(TimeSpan.FromSeconds(3))
// Only check exists on timer if desired
.FilterSwitch(existsCheckTuple
.Select(t =>
{
// Don't do exists type if we don't know what path type we're tracking
if (t.Type == PathTypeOptions.Off) return false;
switch (t.ExistsOption)
{
case ExistCheckOptions.Off:
return false;
case ExistCheckOptions.IfNotEmpty:
return !string.IsNullOrWhiteSpace(t.Path);
case ExistCheckOptions.On:
return true;
default:
throw new NotImplementedException();
}
}))
.Unit()
// Also check though, when fields change
.Merge(this.WhenAny(x => x.PathType).Unit())
.Merge(this.WhenAny(x => x.ExistCheckOption).Unit())
.Merge(this.WhenAny(x => x.TargetPath).Unit())
// Signaled to check, get latest params for actual use
.CombineLatest(existsCheckTuple,
resultSelector: (_, tuple) => tuple)
// Refresh exists
.Select(t =>
{
if (!t.DoExists) return true;
switch (t.ExistsOption)
{
case ExistCheckOptions.IfNotEmpty:
if (string.IsNullOrWhiteSpace(t.Path)) return true;
break;
case ExistCheckOptions.On:
break;
case ExistCheckOptions.Off:
default:
return true;
}
switch (t.Type)
{
case PathTypeOptions.Either:

View File

@ -99,7 +99,7 @@ namespace Wabbajack
this.Location = new FilePickerVM()
{
DoExistsCheck = false,
ExistCheckOption = FilePickerVM.ExistCheckOptions.Off,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Installation Directory",
};
@ -107,7 +107,7 @@ namespace Wabbajack
.Select(x => Utils.IsDirectoryPathValid(x));
this.DownloadLocation = new FilePickerVM()
{
DoExistsCheck = false,
ExistCheckOption = FilePickerVM.ExistCheckOptions.Off,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select a location for MO2 downloads",
};