teamsiso/src/TeamsISO.App/ViewModels/ToastViewModel.cs
Zac Gaetano 8e66491e09
Some checks failed
CI / build-and-test (push) Failing after 26s
Add manual X close to toast notification
Toast was auto-dismiss-only (3s timer). Operators running a live show want to clear visual clutter without waiting — added a small X button to the right of the message that calls ToastViewModel.DismissCommand (stops timer + hides immediately).

Implementation: ToastViewModel gained a DismissCommand RelayCommand and a Hide() helper. MainWindow toast overlay gained a 20x20 button bound to the command, custom inline template (rounded transparent bg, hover lifts to Wd.Button.HoverBg).
2026-05-10 14:05:28 -04:00

84 lines
2.5 KiB
C#

using System.Windows.Input;
using System.Windows.Threading;
namespace TeamsISO.App.ViewModels;
/// <summary>
/// Lightweight transient-notification view-model. The main view holds a single
/// instance bound to a small overlay at the bottom of the content area.
/// <see cref="Show"/> displays a message for a fixed duration before auto-hiding;
/// successive Show calls reset the timer instead of stacking, so the user always
/// sees the most recent action's feedback.
/// </summary>
public sealed class ToastViewModel : ObservableObject
{
private readonly DispatcherTimer _hideTimer;
private string _message = string.Empty;
private bool _isVisible;
private string _accent = "Wd.Accent.Cyan";
public ToastViewModel(Dispatcher dispatcher)
{
_hideTimer = new DispatcherTimer(DispatcherPriority.Background, dispatcher)
{
Interval = TimeSpan.FromSeconds(3),
};
_hideTimer.Tick += (_, _) =>
{
_hideTimer.Stop();
IsVisible = false;
};
DismissCommand = new RelayCommand(Hide);
}
/// <summary>
/// Manual dismiss. Stops the auto-hide timer and hides the toast
/// immediately. Bound to the X close button on the toast overlay so an
/// operator running a live show can clear visual clutter without waiting
/// 3 seconds.
/// </summary>
public ICommand DismissCommand { get; }
private void Hide()
{
_hideTimer.Stop();
IsVisible = false;
}
public string Message
{
get => _message;
private set => SetField(ref _message, value);
}
public bool IsVisible
{
get => _isVisible;
private set => SetField(ref _isVisible, value);
}
/// <summary>
/// Brush resource key for the accent dot. "Wd.Accent.Cyan" for success-style
/// (default), "Wd.Accent.Coral" for warnings.
/// </summary>
public string Accent
{
get => _accent;
private set => SetField(ref _accent, value);
}
/// <summary>Show a success-style toast for ~3 seconds.</summary>
public void Show(string message) => ShowImpl(message, "Wd.Accent.Cyan");
/// <summary>Show a warning-style toast (coral accent) for ~3 seconds.</summary>
public void Warn(string message) => ShowImpl(message, "Wd.Accent.Coral");
private void ShowImpl(string message, string accentKey)
{
Message = message;
Accent = accentKey;
IsVisible = true;
_hideTimer.Stop();
_hideTimer.Start();
}
}