Browse Source

Invalidate cached images on deletion

pull/165/head
Ionite 1 year ago
parent
commit
77a4aa441f
No known key found for this signature in database
  1. 34
      StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs
  2. 26
      StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs

34
StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs

@ -1,10 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading.Tasks;
using AsyncAwaitBestPractices;
using AsyncImageLoader.Loaders;
using Avalonia.Media.Imaging;
using StabilityMatrix.Core.Extensions;
namespace StabilityMatrix.Avalonia;
@ -14,15 +16,19 @@ public readonly record struct ImageLoadFailedEventArgs(string Url, Exception Exc
public class FallbackRamCachedWebImageLoader : RamCachedWebImageLoader
{
private readonly WeakEventManager<ImageLoadFailedEventArgs> loadFailedEventManager = new();
public event EventHandler<ImageLoadFailedEventArgs> LoadFailed
{
add => loadFailedEventManager.AddEventHandler(value);
remove => loadFailedEventManager.RemoveEventHandler(value);
}
protected void OnLoadFailed(string url, Exception exception) => loadFailedEventManager.RaiseEvent(
this, new ImageLoadFailedEventArgs(url, exception), nameof(LoadFailed));
protected void OnLoadFailed(string url, Exception exception) =>
loadFailedEventManager.RaiseEvent(
this,
new ImageLoadFailedEventArgs(url, exception),
nameof(LoadFailed)
);
/// <summary>
/// Attempts to load bitmap
@ -44,17 +50,19 @@ public class FallbackRamCachedWebImageLoader : RamCachedWebImageLoader
return null;
}
}
var internalOrCachedBitmap =
var internalOrCachedBitmap =
await LoadFromInternalAsync(url).ConfigureAwait(false)
?? await LoadFromGlobalCache(url).ConfigureAwait(false);
if (internalOrCachedBitmap != null) return internalOrCachedBitmap;
if (internalOrCachedBitmap != null)
return internalOrCachedBitmap;
try
{
var externalBytes = await LoadDataFromExternalAsync(url).ConfigureAwait(false);
if (externalBytes == null) return null;
if (externalBytes == null)
return null;
using var memoryStream = new MemoryStream(externalBytes);
var bitmap = new Bitmap(memoryStream);
@ -67,4 +75,12 @@ public class FallbackRamCachedWebImageLoader : RamCachedWebImageLoader
}
}
public void RemoveFromCache(string url)
{
// ConcurrentDictionary<string, Task<Bitmap?>> _memoryCache
var cache =
this.GetPrivateField<ConcurrentDictionary<string, Task<Bitmap?>>>("_memoryCache")
?? throw new NullReferenceException("Memory cache not found");
cache.TryRemove(url, out _);
}
}

26
StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using AsyncImageLoader;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
@ -64,25 +65,6 @@ public partial class ImageFolderCardViewModel : ViewModelBase
this.settingsManager = settingsManager;
this.notificationService = notificationService;
// var minDatetime = DateTimeOffset.FromUnixTimeMilliseconds(0);
/*localImagesSource
.Connect()
.DeferUntilLoaded()
.Transform(
imageFile =>
new ImageFolderCardItemViewModel
{
LocalImageFile = imageFile,
ImagePath = Design.IsDesignMode
? imageFile.RelativePath
: imageFile.GetFullPath(settingsManager.ImagesDirectory)
}
)
.SortBy(x => x.LocalImageFile?.LastModifiedAt ?? minDatetime, SortDirection.Descending)
.Bind(Items)
.Subscribe();*/
localImagesSource
.Connect()
.DeferUntilLoaded()
@ -163,6 +145,12 @@ public partial class ImageFolderCardViewModel : ViewModelBase
// Remove from index
await imageIndexService.RemoveImage(item);
// Invalidate cache
if (ImageLoader.AsyncImageLoader is FallbackRamCachedWebImageLoader loader)
{
loader.RemoveFromCache(imagePath);
}
}
/// <summary>

Loading…
Cancel
Save