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
+30
View File
@@ -1,3 +1,6 @@
using System.Windows;
using Notification.Core;
namespace ytLive.ViewModels;
/// <summary>
@@ -10,6 +13,33 @@ namespace ytLive.ViewModels;
public partial class MainViewModel
{
private bool _settingsDrawerOpen;
private NotificationPosition _toastPosition = NotificationPosition.BottomRight;
public NotificationPosition ToastPosition
{
get => _toastPosition;
set
{
if (!IsSupportedToastPosition(value) || !SetProperty(ref _toastPosition, value)) return;
_layoutStore.SaveNotificationPosition(value);
OnPropertyChanged(nameof(ToastAreaMargin));
}
}
public Thickness ToastAreaMargin => ToastPosition switch
{
NotificationPosition.TopLeft => new Thickness(12, 12, 0, 0),
NotificationPosition.TopRight => new Thickness(0, 12, 12, 0),
NotificationPosition.CenterLeft => new Thickness(12, 0, 0, 0),
NotificationPosition.CenterRight => new Thickness(0, 0, 12, 0),
NotificationPosition.BottomLeft => new Thickness(12, 0, 0, 96),
_ => new Thickness(0, 0, 12, 96),
};
private static bool IsSupportedToastPosition(NotificationPosition position)
=> position is NotificationPosition.TopLeft or NotificationPosition.TopRight
or NotificationPosition.CenterLeft or NotificationPosition.CenterRight
or NotificationPosition.BottomLeft or NotificationPosition.BottomRight;
public bool SettingsDrawerOpen
{