feat: Add notification sound functionality and embed support

- Introduced NotificationConfig to manage notification settings, including sound file.
- Added Notification.mp3 asset for notifications.
- Implemented NotificationSoundService to handle playing notification sounds.
- Enhanced ChatRenderer and MainWindow to support emoji rendering.
- Updated MessageDto to allow multiple embeds per message.
- Modified LinkEmbedService to fetch multiple embeds from message content.
- Added data migration for legacy embed JSON format to new array format.
- Adjusted embed handling in ChatService and IrcMessageFormatter to accommodate multiple embeds.
- Updated HubConstants for new embed dimensions and limits.
This commit is contained in:
HueByte
2026-02-19 21:52:18 +01:00
parent 7167b40013
commit b508a5854a
14 changed files with 746 additions and 156 deletions
@@ -0,0 +1,64 @@
using EchoHub.Client.Config;
using NetCoreAudio;
using Serilog;
namespace EchoHub.Client.Services;
public class NotificationSoundService
{
private readonly Player _player = new();
private readonly NotificationConfig _config;
private string? _resolvedSoundPath;
public NotificationSoundService(NotificationConfig config)
{
_config = config;
ResolveSoundPath();
}
public async Task PlayAsync()
{
if (!_config.Enabled || _resolvedSoundPath is null)
return;
try
{
if (_player.Playing)
await _player.Stop();
await _player.Play(_resolvedSoundPath);
}
catch (Exception ex)
{
Log.Warning(ex, "Failed to play notification sound");
}
}
private void ResolveSoundPath()
{
// 1. Explicit path from config (~/.echohub/config.json)
if (!string.IsNullOrWhiteSpace(_config.SoundFile))
{
if (File.Exists(_config.SoundFile))
{
_resolvedSoundPath = Path.GetFullPath(_config.SoundFile);
Log.Debug("Notification sound: {Path} (from config)", _resolvedSoundPath);
return;
}
Log.Warning("Configured sound file not found: {Path}", _config.SoundFile);
}
// 2. Default: Notification.mp3 bundled next to the executable
var defaultPath = Path.Combine(AppContext.BaseDirectory, "Assets", "Notification.mp3");
if (File.Exists(defaultPath))
{
_resolvedSoundPath = defaultPath;
Log.Debug("Notification sound: {Path} (default)", _resolvedSoundPath);
return;
}
Log.Information("No notification sound file found — notifications will be silent");
}
}