diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs
index f3fe207a..a018e359 100644
--- a/Wabbajack.Lib/ACompiler.cs
+++ b/Wabbajack.Lib/ACompiler.cs
@@ -18,6 +18,7 @@ namespace Wabbajack.Lib
public string? ModListName, ModListAuthor, ModListDescription, ModListWebsite, ModlistReadme;
public Version? ModlistVersion;
public AbsolutePath ModListImage;
+ public bool ModlistIsNSFW;
protected Version? WabbajackVersion;
public abstract AbsolutePath VFSCacheName { get; }
diff --git a/Wabbajack.Lib/Data.cs b/Wabbajack.Lib/Data.cs
index 1f6b6807..450bfe43 100644
--- a/Wabbajack.Lib/Data.cs
+++ b/Wabbajack.Lib/Data.cs
@@ -108,6 +108,11 @@ namespace Wabbajack.Lib
///
public Version Version = new Version(1, 0, 0, 0);
+ ///
+ /// Whether the Modlist is NSFW or not
+ ///
+ public bool IsNSFW;
+
///
/// The size of all the archives once they're downloaded
///
diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs
index 04f204fb..5a7d313a 100644
--- a/Wabbajack.Lib/MO2Compiler.cs
+++ b/Wabbajack.Lib/MO2Compiler.cs
@@ -303,7 +303,8 @@ namespace Wabbajack.Lib
Description = ModListDescription ?? "",
Readme = ModlistReadme ?? "",
Image = ModListImage != default ? ModListImage.FileName : default,
- Website = ModListWebsite != null ? new Uri(ModListWebsite) : null
+ Website = !string.IsNullOrWhiteSpace(ModListWebsite) ? new Uri(ModListWebsite) : null,
+ IsNSFW = ModlistIsNSFW
};
UpdateTracker.NextStep("Running Validation");
diff --git a/Wabbajack.Lib/ModListRegistry/ModListMetadata.cs b/Wabbajack.Lib/ModListRegistry/ModListMetadata.cs
index df19992b..e0fe28cf 100644
--- a/Wabbajack.Lib/ModListRegistry/ModListMetadata.cs
+++ b/Wabbajack.Lib/ModListRegistry/ModListMetadata.cs
@@ -29,6 +29,9 @@ namespace Wabbajack.Lib.ModListRegistry
[JsonProperty("official")]
public bool Official { get; set; }
+ [JsonProperty("nsfw")]
+ public bool NSFW { get; set; }
+
[JsonProperty("links")]
public LinksObject Links { get; set; } = new LinksObject();
diff --git a/Wabbajack/Settings.cs b/Wabbajack/Settings.cs
index f641f75d..091f7f12 100644
--- a/Wabbajack/Settings.cs
+++ b/Wabbajack/Settings.cs
@@ -130,6 +130,7 @@ namespace Wabbajack
public string Description { get; set; }
public string Website { get; set; }
public string Readme { get; set; }
+ public bool IsNSFW { get; set; }
public AbsolutePath SplashScreen { get; set; }
}
diff --git a/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs b/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
index 623bed28..5d7256cf 100644
--- a/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
+++ b/Wabbajack/View Models/Compilers/ModlistSettingsEditorVM.cs
@@ -20,7 +20,7 @@ namespace Wabbajack
[Reactive]
public string VersionText { get; set; }
- private ObservableAsPropertyHelper _version;
+ private readonly ObservableAsPropertyHelper _version;
public Version Version => _version.Value;
[Reactive]
@@ -37,6 +37,9 @@ namespace Wabbajack
[Reactive]
public string Website { get; set; }
+ [Reactive]
+ public bool IsNSFW { get; set; }
+
public IObservable InError { get; }
public ModlistSettingsEditorVM(CompilationModlistSettings settings)
@@ -81,6 +84,7 @@ namespace Wabbajack
ImagePath.TargetPath = _settings.SplashScreen;
Website = _settings.Website;
VersionText = _settings.Version;
+ IsNSFW = _settings.IsNSFW;
}
public void Save()
@@ -92,6 +96,7 @@ namespace Wabbajack
_settings.Readme = Readme;
_settings.SplashScreen = ImagePath.TargetPath;
_settings.Website = Website;
+ _settings.IsNSFW = IsNSFW;
}
}
}
diff --git a/Wabbajack/View Models/Gallery/ModListGalleryVM.cs b/Wabbajack/View Models/Gallery/ModListGalleryVM.cs
index 5b3d4148..3d20d69e 100644
--- a/Wabbajack/View Models/Gallery/ModListGalleryVM.cs
+++ b/Wabbajack/View Models/Gallery/ModListGalleryVM.cs
@@ -34,6 +34,9 @@ namespace Wabbajack
[Reactive]
public bool OnlyInstalled { get; set; }
+
+ [Reactive]
+ public bool ShowNSFW { get; set; }
private readonly ObservableAsPropertyHelper _Loaded;
public bool Loaded => _Loaded.Value;
@@ -49,6 +52,7 @@ namespace Wabbajack
() =>
{
OnlyInstalled = false;
+ ShowNSFW = false;
Search = string.Empty;
});
@@ -91,7 +95,7 @@ namespace Wabbajack
.Transform(m => new ModListMetadataVM(this, m))
.DisposeMany()
// Filter only installed
- .Filter(predicateChanged: this.WhenAny(x => x.OnlyInstalled)
+ .Filter(this.WhenAny(x => x.OnlyInstalled)
.Select>(onlyInstalled => (vm) =>
{
if (!onlyInstalled) return true;
@@ -99,13 +103,19 @@ namespace Wabbajack
return gameMeta.IsInstalled;
}))
// Filter on search box
- .Filter(predicateChanged: this.WhenAny(x => x.Search)
+ .Filter(this.WhenAny(x => x.Search)
.Debounce(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
.Select>(search => (vm) =>
{
if (string.IsNullOrWhiteSpace(search)) return true;
return vm.Metadata.Title.ContainsCaseInsensitive(search);
}))
+ .Filter(this.WhenAny(x => x.ShowNSFW)
+ .Select>(showNSFW => vm =>
+ {
+ if (!vm.Metadata.NSFW) return true;
+ return vm.Metadata.NSFW && showNSFW;
+ }))
// Put broken lists at bottom
.Sort(Comparer.Create((a, b) => a.IsBroken.CompareTo(b.IsBroken)))
.Bind(ModLists)
diff --git a/Wabbajack/View Models/ModListVM.cs b/Wabbajack/View Models/ModListVM.cs
index accf12bb..44368ab0 100644
--- a/Wabbajack/View Models/ModListVM.cs
+++ b/Wabbajack/View Models/ModListVM.cs
@@ -22,6 +22,7 @@ namespace Wabbajack
public Uri Website => SourceModList?.Website;
public ModManager ModManager => SourceModList?.ModManager ?? ModManager.MO2;
public Version Version => SourceModList?.Version;
+ public bool IsNSFW => SourceModList?.IsNSFW ?? false;
// Image isn't exposed as a direct property, but as an observable.
// This acts as a caching mechanism, as interested parties will trigger it to be created,
diff --git a/Wabbajack/Views/Compilers/CompilerView.xaml b/Wabbajack/Views/Compilers/CompilerView.xaml
index 5fa4a148..cd0247b0 100644
--- a/Wabbajack/Views/Compilers/CompilerView.xaml
+++ b/Wabbajack/Views/Compilers/CompilerView.xaml
@@ -147,6 +147,9 @@
Text="Readme"
ToolTip="Link to the Readme." />
+
!x)
.BindToStrict(this, x => x.SettingsScrollViewer.IsEnabled)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, x => x.CurrentModlistSettings.ModListName, x => x.ModListNameSetting.Text)
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.ModListName, x => x.ModListNameSetting.Text)
.DisposeWith(dispose);
this.BindStrict(ViewModel, x => x.CurrentModlistSettings.VersionText, x => x.VersionSetting.Text)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, x => x.CurrentModlistSettings.AuthorText, x => x.AuthorNameSetting.Text)
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.AuthorText, x => x.AuthorNameSetting.Text)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, x => x.CurrentModlistSettings.Description, x => x.DescriptionSetting.Text)
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.Description, x => x.DescriptionSetting.Text)
.DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.CurrentModlistSettings.ImagePath)
.BindToStrict(this, x => x.ImageFilePicker.PickerVM)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, x => x.CurrentModlistSettings.Website, x => x.WebsiteSetting.Text)
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.Website, x => x.WebsiteSetting.Text)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, x => x.CurrentModlistSettings.Readme, x => x.ReadmeSetting.Text)
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.Readme, x => x.ReadmeSetting.Text)
+ .DisposeWith(dispose);
+ this.BindStrict(ViewModel, x => x.CurrentModlistSettings.IsNSFW, x => x.NSFWSetting.IsChecked)
.DisposeWith(dispose);
// Bottom Compiler Settings
diff --git a/Wabbajack/Views/ModListGalleryView.xaml b/Wabbajack/Views/ModListGalleryView.xaml
index 364e4ec4..018b6eff 100644
--- a/Wabbajack/Views/ModListGalleryView.xaml
+++ b/Wabbajack/Views/ModListGalleryView.xaml
@@ -106,6 +106,12 @@
x:Name="SearchBox"
Width="160"
VerticalContentAlignment="Center" />
+
x.ErrorIcon.Visibility)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, vm => vm.Search, x => x.SearchBox.Text)
+ this.BindStrict(ViewModel, vm => vm.Search, x => x.SearchBox.Text)
.DisposeWith(dispose);
- this.BindStrict(this.ViewModel, vm => vm.OnlyInstalled, x => x.OnlyInstalledCheckbox.IsChecked)
+ this.BindStrict(ViewModel, vm => vm.OnlyInstalled, x => x.OnlyInstalledCheckbox.IsChecked)
+ .DisposeWith(dispose);
+ this.BindStrict(ViewModel, vm => vm.ShowNSFW, x => x.ShowNSFW.IsChecked)
.DisposeWith(dispose);
this.WhenAny(x => x.ViewModel.ClearFiltersCommand)