wabbajack/Wabbajack/View Models/ModListGalleryVM.cs

79 lines
2.6 KiB
C#
Raw Normal View History

2019-11-30 09:08:04 +00:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
2020-01-19 04:37:21 +00:00
using ReactiveUI.Fody.Helpers;
using Wabbajack.Common;
2019-11-30 09:08:04 +00:00
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack
{
public class ModListGalleryVM : BackNavigatingVM
2019-11-30 09:08:04 +00:00
{
public MainWindowVM MWVM { get; }
public ObservableCollectionExtended<ModListMetadataVM> ModLists { get; } = new ObservableCollectionExtended<ModListMetadataVM>();
private int missingHashFallbackCounter;
2020-01-19 04:37:21 +00:00
[Reactive]
public IErrorResponse Error { get; set; }
2019-11-30 09:08:04 +00:00
public ModListGalleryVM(MainWindowVM mainWindowVM)
: base(mainWindowVM)
2019-11-30 09:08:04 +00:00
{
MWVM = mainWindowVM;
2020-01-16 03:54:06 +00:00
Observable.Return(Unit.Default)
2019-11-30 09:08:04 +00:00
.ObserveOn(RxApp.TaskpoolScheduler)
2019-12-06 05:59:57 +00:00
.SelectTask(async _ =>
2019-11-30 09:08:04 +00:00
{
2020-01-19 04:37:21 +00:00
try
{
Error = null;
var list = await ModlistMetadata.LoadFromGithub();
return list.AsObservableChangeSet(x => x.DownloadMetadata?.Hash ?? $"Fallback{missingHashFallbackCounter++}");
}
catch (Exception ex)
{
Utils.Error(ex);
Error = ErrorResponse.Fail(ex);
return Observable.Empty<IChangeSet<ModlistMetadata, string>>();
}
2019-11-30 09:08:04 +00:00
})
2020-01-16 03:54:06 +00:00
// Unsubscribe and release when not active
.FlowSwitch(
this.WhenAny(x => x.IsActive),
valueWhenOff: Observable.Return(ChangeSet<ModlistMetadata, string>.Empty))
// Convert to VM and bind to resulting list
2019-11-30 09:08:04 +00:00
.Switch()
.ObserveOnGuiThread()
.Transform(m => new ModListMetadataVM(this, m))
2020-01-16 03:54:06 +00:00
.DisposeMany()
2019-11-30 09:08:04 +00:00
.Bind(ModLists)
.Subscribe()
.DisposeWith(CompositeDisposable);
2020-01-16 03:54:06 +00:00
// Extra GC when navigating away, just to immediately clean up modlist metadata
this.WhenAny(x => x.IsActive)
.Where(x => !x)
.Skip(1)
.Delay(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler)
2020-01-16 03:54:06 +00:00
.Subscribe(_ =>
{
GC.Collect();
})
.DisposeWith(CompositeDisposable);
2019-11-30 09:08:04 +00:00
}
}
}