wabbajack/Wabbajack/View Models/ModListVM.cs

86 lines
3.5 KiB
C#
Raw Normal View History

2019-11-03 06:01:19 +00:00
using ReactiveUI;
using System;
using System.IO;
using System.IO.Compression;
using System.Reactive.Linq;
using System.Windows.Media.Imaging;
using Wabbajack.Common;
using Wabbajack.Lib;
namespace Wabbajack
{
public class ModListVM : ViewModel
{
public ModList SourceModList { get; }
public string ModListPath { get; }
2019-11-11 11:38:45 +00:00
public string Name => SourceModList.Name;
public string ReportHTML => SourceModList.ReportHTML;
public string Readme => SourceModList.Readme;
public string ImageURL => SourceModList.Image;
public string Author => SourceModList.Author;
public string Description => SourceModList.Description;
public string Website => SourceModList.Website;
public ModManager ModManager => SourceModList.ModManager;
2019-11-03 06:01:19 +00:00
// 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,
// and the cached image will automatically be released when the last interested party is gone.
public IObservable<BitmapImage> ImageObservable { get; }
public ModListVM(ModList sourceModList, string modListPath)
{
2019-11-11 11:38:45 +00:00
ModListPath = modListPath;
SourceModList = sourceModList;
2019-11-03 06:01:19 +00:00
2019-11-11 11:38:45 +00:00
ImageObservable = Observable.Return(this.ImageURL)
2019-11-03 06:01:19 +00:00
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(url =>
{
try
{
if (!File.Exists(url)) return default(MemoryStream);
if (string.IsNullOrWhiteSpace(sourceModList.Image)) return default(MemoryStream);
if (sourceModList.Image.Length != 36) return default(MemoryStream);
using (var fs = new FileStream(this.ModListPath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var ar = new ZipArchive(fs, ZipArchiveMode.Read))
{
var ms = new MemoryStream();
var entry = ar.GetEntry(sourceModList.Image);
using (var e = entry.Open())
{
e.CopyTo(ms);
}
return ms;
}
}
catch (Exception ex)
{
Utils.LogToFile($"Exception while caching Mod List image {this.Name}\n{ex.ExceptionToString()}");
return default(MemoryStream);
}
})
.ObserveOn(RxApp.MainThreadScheduler)
.Select(memStream =>
{
try
{
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = memStream;
image.EndInit();
image.Freeze();
return image;
}
catch (Exception ex)
{
Utils.LogToFile($"Exception while caching Mod List image {this.Name}\n{ex.ExceptionToString()}");
return default(BitmapImage);
}
})
.Replay(1)
.RefCount();
}
}
}