feat(settings): position slide-out notifications

App Settings now chooses one of six ToastArea positions (left/right ×
top/center/bottom), defaulting to the existing bottom-right. The setting is
persisted per profile and the toast area moves immediately; edge gutters keep
bottom notifications above the footer.

ToastPositionIntegrationTests covers live repositioning and restart persistence.
617 tests green, clean build with 0 warnings.

Reference scan: OBS Notifier supports user-configured notification placement:
https://github.com/DmitriySalnikov/OBSNotifier
This commit is contained in:
2026-11-11 10:06:54 -08:00
parent 9621db29c9
commit 2f5d0c1759
11 changed files with 139 additions and 11 deletions
+20
View File
@@ -1,4 +1,5 @@
using Microsoft.Data.Sqlite;
using Notification.Core;
using ytLive.Services.Compositor;
using ytLive.Models;
@@ -6,6 +7,25 @@ namespace ytLive.Services;
public partial class LayoutStore : IDisposable
{
public NotificationPosition LoadNotificationPosition()
{
var value = GetSetting("Notifications.Position");
return Enum.TryParse(value, true, out NotificationPosition position) && IsSupportedNotificationPosition(position)
? position
: NotificationPosition.BottomRight;
}
public void SaveNotificationPosition(NotificationPosition position)
{
if (!IsSupportedNotificationPosition(position)) position = NotificationPosition.BottomRight;
UpsertSetting("Notifications.Position", position.ToString());
}
private static bool IsSupportedNotificationPosition(NotificationPosition position)
=> position is NotificationPosition.TopLeft or NotificationPosition.TopRight
or NotificationPosition.CenterLeft or NotificationPosition.CenterRight
or NotificationPosition.BottomLeft or NotificationPosition.BottomRight;
/// <summary>The last picked mic source name, or null if never chosen. Restored
/// at startup so the sound bar reconnects to the same, already-vetted device.</summary>
public string? LoadMicSourceName()