Small fixes to the gallery

This commit is contained in:
Timothy Baldridge 2021-10-27 15:47:58 -06:00
parent 1cd5d01f1c
commit 193907d198
7 changed files with 77 additions and 20 deletions

View File

@ -6,8 +6,8 @@ public class Configuration
{
public AbsolutePath ModListsDownloadLocation { get; set; }
public AbsolutePath SavedSettingsLocation { get; set; }
public AbsolutePath EncryptedDataLocation { get; set; }
public AbsolutePath LogLocation { get; set; }
public AbsolutePath ImageCacheLocation { get; set; }
}

View File

@ -42,6 +42,7 @@ public partial class BrowseItemView : ReactiveUserControl<BrowseItemViewModel>
{
return modListState switch
{
ModListState.Disabled => MaterialIconKind.Error,
ModListState.Downloaded => MaterialIconKind.PlayArrow,
ModListState.Downloading => MaterialIconKind.LocalAreaNetworkPending,
ModListState.NotDownloaded => MaterialIconKind.Download,

View File

@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Wabbajack.App.Messages;
using Wabbajack.App.Models;
using Wabbajack.App.ViewModels;
using Wabbajack.Common;
using Wabbajack.Downloaders;
@ -28,7 +29,8 @@ public enum ModListState
{
Downloaded,
NotDownloaded,
Downloading
Downloading,
Disabled
}
public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
@ -43,11 +45,12 @@ public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
private readonly ILogger _logger;
private readonly ModlistMetadata _metadata;
private readonly ModListSummary _summary;
private readonly ImageCache _imageCache;
public BrowseItemViewModel(ModlistMetadata metadata, ModListSummary summary, HttpClient client,
IResource<HttpClient> limiter,
FileHashCache hashCache, Configuration configuration, DownloadDispatcher dispatcher,
IResource<DownloadDispatcher> downloadLimiter, GameLocator gameLocator,
IResource<DownloadDispatcher> downloadLimiter, GameLocator gameLocator, ImageCache imageCache,
DTOSerializer dtos, ILogger logger)
{
Activator = new ViewModelActivator();
@ -59,6 +62,7 @@ public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
_configuration = configuration;
_dispatcher = dispatcher;
_downloadLimiter = downloadLimiter;
_imageCache = imageCache;
_logger = logger;
_dtos = dtos;
@ -87,7 +91,7 @@ public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
}
},
this.ObservableForProperty(t => t.State)
.Select(c => c.Value != ModListState.Downloading)
.Select(c => c.Value != ModListState.Downloading && c.Value != ModListState.Disabled)
.StartWith(true));
LoadListImage().FireAndForget();
@ -96,7 +100,7 @@ public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
public string Title => _metadata.ImageContainsTitle ? "" : _metadata.Title;
public string MachineURL => _metadata.Links.MachineURL;
public string Description => _metadata.Description;
public string Description => State == ModListState.Disabled ? "Disabled: Under Construction \n " + _metadata.Description : _metadata.Description;
public Uri ImageUri => new(_metadata.Links.ImageUri);
@ -163,13 +167,14 @@ public class BrowseItemViewModel : ViewModelBase, IActivatableViewModel
public async Task LoadListImage()
{
using var job = await _limiter.Begin("Loading modlist image", 0, CancellationToken.None);
var response = await _client.GetByteArrayAsync(ImageUri);
Image = new Bitmap(new MemoryStream(response));
Image = await _imageCache.From(ImageUri);
}
public async Task<ModListState> GetState()
{
if (_metadata.ForceDown || _summary.HasFailures)
return ModListState.Disabled;
var file = ModListLocation;
if (!file.FileExists())
return ModListState.NotDownloaded;

View File

@ -0,0 +1,47 @@
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using SkiaSharp;
using Wabbajack.Hashing.xxHash64;
using Wabbajack.Paths.IO;
using Wabbajack.RateLimiter;
namespace Wabbajack.App.Models;
public class ImageCache
{
private readonly Configuration _configuration;
private readonly HttpClient _client;
private readonly IResource<HttpClient> _limiter;
public ImageCache(Configuration configuration, HttpClient client, IResource<HttpClient> limiter)
{
_configuration = configuration;
_configuration.ImageCacheLocation.CreateDirectory();
_client = client;
_limiter = limiter;
}
public async Task<IBitmap> From(Uri uri)
{
var hash = (await Encoding.UTF8.GetBytes(uri.ToString()).Hash()).ToHex();
var file = _configuration.ImageCacheLocation.Combine(hash);
if (!file.FileExists())
{
using var job = await _limiter.Begin("Loading Image", 0, CancellationToken.None);
var wdata = await _client.GetByteArrayAsync(uri);
await file.WriteAllBytesAsync(wdata);
return new Bitmap(new MemoryStream(wdata));
}
var data = await file.ReadAllBytesAsync();
return new Bitmap(new MemoryStream(data));
}
}

View File

@ -63,18 +63,16 @@
</WrapPanel>
<ScrollViewer Grid.Row="1">
<ItemsControl x:Name="GalleryList" x:FieldModifier="public">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<ItemsRepeater x:Name="GalleryList" x:FieldModifier="public">
<ItemsRepeater.Layout>
<UniformGridLayout></UniformGridLayout>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<controls:BrowseItemView />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>

View File

@ -48,10 +48,12 @@ public class BrowseViewModel : ViewModelBase, IActivatableViewModel
private readonly SourceCache<GameSelectorItemViewModel, string> _gamesList = new(x => x.Name);
private readonly SourceCache<BrowseItemViewModel, string> _modLists = new(x => x.MachineURL);
private readonly ImageCache _imageCache;
public BrowseViewModel(ILogger<BrowseViewModel> logger, Client wjClient, HttpClient httpClient,
IResource<HttpClient> limiter, FileHashCache hashCache,
IResource<DownloadDispatcher> dispatcherLimiter, DownloadDispatcher dispatcher, GameLocator gameLocator,
ImageCache imageCache,
DTOSerializer dtos, Configuration configuration)
{
LoadingLock = new LoadingLock();
@ -65,6 +67,7 @@ public class BrowseViewModel : ViewModelBase, IActivatableViewModel
_dispatcher = dispatcher;
_dispatcherLimiter = dispatcherLimiter;
_gameLocator = gameLocator;
_imageCache = imageCache;
_dtos = dtos;
@ -131,6 +134,7 @@ public class BrowseViewModel : ViewModelBase, IActivatableViewModel
.Filter(onlyInstalledGamesFilter)
.Filter(onlyUtilityListsFilter)
.Filter(showNSFWFilter)
.SortBy(x => x.State == ModListState.Disabled ? 1 : 0)
.Bind(out _filteredModLists)
.Subscribe();
@ -191,7 +195,7 @@ public class BrowseViewModel : ViewModelBase, IActivatableViewModel
if (!summaries.TryGetValue(m.Links.MachineURL, out var summary)) summary = new ModListSummary();
return new BrowseItemViewModel(m, summary, _httpClient, _limiter, _hashCache, _configuration, _dispatcher,
_dispatcherLimiter, _gameLocator, _dtos, _logger);
_dispatcherLimiter, _gameLocator, _imageCache, _dtos, _logger);
});
_modLists.Edit(lsts =>

View File

@ -57,6 +57,7 @@ public static class ServiceExtensions
services.AddSingleton<IScreenView, BrowseView>();
services.AddSingleton<IScreenView, LauncherView>();
services.AddSingleton<IScreenView, PlaySelectView>();
services.AddSingleton<ImageCache>();
services.AddSingleton<InstallationStateManager>();
services.AddSingleton<HttpClient>();
@ -97,7 +98,8 @@ public static class ServiceExtensions
EncryptedDataLocation = KnownFolders.WabbajackAppLocal.Combine("encrypted"),
ModListsDownloadLocation = KnownFolders.EntryPoint.Combine("downloaded_mod_lists"),
SavedSettingsLocation = KnownFolders.WabbajackAppLocal.Combine("saved_settings"),
LogLocation = KnownFolders.EntryPoint.Combine("logs")
LogLocation = KnownFolders.EntryPoint.Combine("logs"),
ImageCacheLocation = KnownFolders.WabbajackAppLocal.Combine("image_cache")
});
services.AddSingleton<SettingsManager>();