Fixed sharing plugins when the share dialog of the operating system does not respond (#1088)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-10-19 14:39:12 +02:00
1 parent 7d35536c87
commit f26d132d56
16 files changed
+543 -76

No files matched your search

@@ -1,6 +1,40 @@
using AIStudio.Tools.Rust;
namespace AIStudio.Tools.Services;
public sealed class NativeShareService(RustService rustService)
/// <summary>
/// Hands files to the share sheet of the operating system, and remembers when that share sheet
/// failed.
/// </summary>
/// <remarks>
/// A share sheet which hung once tends to stay broken: on Windows, it then accepts every further
/// request without ever appearing, so the share button seems to do nothing at all. Once the share
/// sheet failed or did not respond, AI Studio therefore exports plugin archives instead, until it
/// restarts. This service is a singleton, so that the decision holds for every window.
/// </remarks>
public sealed class NativeShareService(RustService rustService, ILogger<NativeShareService> logger)
{
public Task<bool> Share(string filePath) => rustService.ShareFile(filePath);
}
private volatile bool isUnavailable;
/// <summary>
/// Whether the share sheet of the operating system can be used. Linux has none, and on Windows
/// and macOS it counts as unavailable once it failed or did not respond.
/// </summary>
public bool IsAvailable => !OperatingSystem.IsLinux() && !this.isUnavailable;
/// <summary>
/// Opens the share sheet of the operating system for a file.
/// </summary>
/// <param name="filePath">The plugin archive to share.</param>
/// <returns>What became of the request.</returns>
public async Task<ShareFileResponse> Share(string filePath)
{
var response = await rustService.ShareFile(filePath);
if (response.Outcome is ShareSheetOutcome.OPENED || this.isUnavailable)
return response;
this.isUnavailable = true;
logger.LogWarning("The native share sheet did not open ({Outcome}). Until AI Studio restarts, plugin archives are exported instead.", response.Outcome);
return response;
}
}