Browse Source

Fix crashes during gallery operations if file is externally deleted

pull/240/head
Ionite 1 year ago
parent
commit
ed882f83e5
No known key found for this signature in database
  1. 52
      StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs

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

@ -4,7 +4,6 @@ using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsyncAwaitBestPractices; using AsyncAwaitBestPractices;
using AsyncImageLoader; using AsyncImageLoader;
using Avalonia;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
@ -120,20 +119,50 @@ public partial class ImageFolderCardViewModel : ViewModelBase
imageIndexService.RefreshIndexForAllCollections().SafeFireAndForget(); imageIndexService.RefreshIndexForAllCollections().SafeFireAndForget();
} }
/// <summary>
/// Gets the image path if it exists, returns null.
/// If the image path is resolved but the file doesn't exist, it will be removed from the index.
/// </summary>
private FilePath? GetImagePathIfExists(LocalImageFile item)
{
if (item.GetFullPath(settingsManager.ImagesDirectory) is not { } imagePath)
{
return null;
}
var imageFile = new FilePath(imagePath);
if (!imageFile.Exists)
{
// Remove from index
imageIndexService.InferenceImages.Remove(item);
// Invalidate cache
if (ImageLoader.AsyncImageLoader is FallbackRamCachedWebImageLoader loader)
{
loader.RemoveAllNamesFromCache(imageFile.Name);
}
return null;
}
return imageFile;
}
/// <summary> /// <summary>
/// Handles image clicks to show preview /// Handles image clicks to show preview
/// </summary> /// </summary>
[RelayCommand] [RelayCommand]
private async Task OnImageClick(LocalImageFile item) private async Task OnImageClick(LocalImageFile item)
{ {
if (item.GetFullPath(settingsManager.ImagesDirectory) is not { } imagePath) if (GetImagePathIfExists(item) is not { } imageFile)
{ {
return; return;
} }
var currentIndex = LocalImages.IndexOf(item); var currentIndex = LocalImages.IndexOf(item);
var image = new ImageSource(new FilePath(imagePath)); var image = new ImageSource(imageFile);
// Preload // Preload
await image.GetBitmapAsync(); await image.GetBitmapAsync();
@ -163,7 +192,7 @@ public partial class ImageFolderCardViewModel : ViewModelBase
// Preload // Preload
await newImageSource.GetBitmapAsync(); await newImageSource.GetBitmapAsync();
var oldImageSource = sender.ImageSource; // var oldImageSource = sender.ImageSource;
sender.ImageSource = newImageSource; sender.ImageSource = newImageSource;
sender.LocalImageFile = newImage; sender.LocalImageFile = newImage;
@ -185,13 +214,12 @@ public partial class ImageFolderCardViewModel : ViewModelBase
[RelayCommand] [RelayCommand]
private async Task OnImageDelete(LocalImageFile? item) private async Task OnImageDelete(LocalImageFile? item)
{ {
if (item?.GetFullPath(settingsManager.ImagesDirectory) is not { } imagePath) if (item is null || GetImagePathIfExists(item) is not { } imageFile)
{ {
return; return;
} }
// Delete the file // Delete the file
var imageFile = new FilePath(imagePath);
var result = await notificationService.TryAsync(imageFile.DeleteAsync()); var result = await notificationService.TryAsync(imageFile.DeleteAsync());
if (!result.IsSuccessful) if (!result.IsSuccessful)
@ -215,14 +243,14 @@ public partial class ImageFolderCardViewModel : ViewModelBase
[RelayCommand] [RelayCommand]
private async Task OnImageCopy(LocalImageFile? item) private async Task OnImageCopy(LocalImageFile? item)
{ {
if (item?.GetFullPath(settingsManager.ImagesDirectory) is not { } imagePath) if (item is null || GetImagePathIfExists(item) is not { } imageFile)
{ {
return; return;
} }
var clipboard = App.Clipboard; var clipboard = App.Clipboard;
await clipboard.SetFileDataObjectAsync(imagePath); await clipboard.SetFileDataObjectAsync(imageFile.FullPath);
} }
/// <summary> /// <summary>
@ -231,12 +259,12 @@ public partial class ImageFolderCardViewModel : ViewModelBase
[RelayCommand] [RelayCommand]
private async Task OnImageOpen(LocalImageFile? item) private async Task OnImageOpen(LocalImageFile? item)
{ {
if (item?.GetFullPath(settingsManager.ImagesDirectory) is not { } imagePath) if (item is null || GetImagePathIfExists(item) is not { } imageFile)
{ {
return; return;
} }
await ProcessRunner.OpenFileBrowser(imagePath); await ProcessRunner.OpenFileBrowser(imageFile);
} }
/// <summary> /// <summary>
@ -248,13 +276,11 @@ public partial class ImageFolderCardViewModel : ViewModelBase
bool includeMetadata = false bool includeMetadata = false
) )
{ {
if (item?.GetFullPath(settingsManager.ImagesDirectory) is not { } sourcePath) if (item is null || GetImagePathIfExists(item) is not { } sourceFile)
{ {
return; return;
} }
var sourceFile = new FilePath(sourcePath);
var formatName = format.ToString(); var formatName = format.ToString();
var storageFile = await App.StorageProvider.SaveFilePickerAsync( var storageFile = await App.StorageProvider.SaveFilePickerAsync(

Loading…
Cancel
Save