using System.Diagnostics; using Toak.Core.Interfaces; namespace Toak.IO; public class Notifications : INotifications { private bool _notifySendAvailable = true; public void Notify(string summary, string body = "") { if (!_notifySendAvailable) return; try { var pInfo = new ProcessStartInfo { FileName = "notify-send", Arguments = $"-a \"Toak\" \"{summary}\" \"{body}\"", UseShellExecute = false, CreateNoWindow = true }; Process.Start(pInfo); } catch (System.ComponentModel.Win32Exception) { Console.WriteLine("[Notifications] 'notify-send' executable not found. Notifications will be disabled."); _notifySendAvailable = false; } catch (Exception ex) { Console.WriteLine($"[Notifications] Failed to send notification: {ex.Message}"); } } private bool _paplayAvailable = true; public void PlaySound(string soundPath) { if (!_paplayAvailable || string.IsNullOrWhiteSpace(soundPath)) return; try { var absolutePath = soundPath; if (!Path.IsPathRooted(absolutePath)) absolutePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, absolutePath); if (!File.Exists(absolutePath)) { var resourceName = "Toak." + soundPath.Replace("/", ".").Replace("\\", "."); using var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream != null) { absolutePath = Path.Combine(Path.GetTempPath(), "toak_" + Path.GetFileName(soundPath)); if (!File.Exists(absolutePath)) { using var fileStream = File.Create(absolutePath); stream.CopyTo(fileStream); } } else { return; } } var pInfo = new ProcessStartInfo { FileName = "paplay", Arguments = $"\"{absolutePath}\"", UseShellExecute = false, CreateNoWindow = true }; Process.Start(pInfo); } catch (System.ComponentModel.Win32Exception) { Console.WriteLine("[Notifications] 'paplay' executable not found. Sound effects will be disabled."); _paplayAvailable = false; } catch (Exception ex) { Console.WriteLine($"[Notifications] Failed to play sound: {ex.Message}"); } } }