using AIStudio.Tools.Rust; namespace AIStudio.Tools.Services; /// /// Hands files to the share sheet of the operating system, and remembers when that share sheet /// failed. /// /// /// 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. /// public sealed class NativeShareService(RustService rustService, ILogger logger) { private volatile bool isUnavailable; /// /// 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. /// public bool IsAvailable => !OperatingSystem.IsLinux() && !this.isUnavailable; /// /// Opens the share sheet of the operating system for a file. /// /// The plugin archive to share. /// What became of the request. public async Task 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; } }