using System; using System.Threading.Tasks; using AsyncImageLoader; using Avalonia.Media.Imaging; using StabilityMatrix.Core.Models.FileInterfaces; namespace StabilityMatrix.Avalonia.Models; public record ImageSource : IDisposable { /// /// Local file path /// public FilePath? LocalFile { get; init; } /// /// Remote URL /// public Uri? RemoteUrl { get; init; } /// /// Bitmap /// public Bitmap? Bitmap { get; set; } public ImageSource(FilePath localFile) { LocalFile = localFile; } public ImageSource(Uri remoteUrl) { RemoteUrl = remoteUrl; } public ImageSource(Bitmap bitmap) { Bitmap = bitmap; } public Task BitmapAsync => GetBitmapAsync(); /// /// Get the bitmap /// public async Task GetBitmapAsync() { if (Bitmap is not null) return Bitmap; var loader = ImageLoader.AsyncImageLoader; // Use local file path if available, otherwise remote URL var path = LocalFile?.FullPath ?? RemoteUrl?.ToString(); if (path is null) return null; // Load the image Bitmap = await loader.ProvideImageAsync(path).ConfigureAwait(false); return Bitmap; } /// /// Clears the cached bitmap /// protected virtual void Dispose(bool disposing) { if (!disposing) return; Bitmap?.Dispose(); } /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// public override string ToString() { return LocalFile?.FullPath ?? RemoteUrl?.ToString() ?? ""; } /// /// Implicit conversion to string for async image loader. /// Resolves with the local file path if available, otherwise the remote URL. /// Otherwise returns null. /// public static implicit operator string(ImageSource imageSource) => imageSource.ToString(); }