You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Components/Snackbar/Snackbar.cs

112 lines
2.9 KiB

2 years ago
//Copyright(c) Alessandro Ghidini.All rights reserved.
//Changes and improvements Copyright (c) The MudBlazor Team.
namespace Connected.Components;
public class Snackbar : IDisposable
{
private Timer Timer { get; set; }
internal SnackBarMessageState State { get; }
public string Message => SnackbarMessage.Text;
internal SnackbarMessage SnackbarMessage { get; }
public event Action<Snackbar> OnClose;
public event Action OnUpdate;
public Severity Severity => State.Options.Severity;
internal Snackbar(SnackbarMessage message, SnackbarOptions options)
{
SnackbarMessage = message;
State = new SnackBarMessageState(options);
Timer = new Timer(TimerElapsed, null, Timeout.Infinite, Timeout.Infinite);
}
internal void Init() => TransitionTo(SnackbarState.Showing);
internal void Clicked(bool fromCloseIcon)
{
if (!fromCloseIcon)
{
// Do not start the hiding transition if no click action
if (State.Options.Onclick == null)
return;
// Click action is executed only if it's not from the close icon
State.Options.Onclick.Invoke(this);
}
State.UserHasInteracted = true;
TransitionTo(SnackbarState.Hiding);
}
private void TransitionTo(SnackbarState state)
{
StopTimer();
State.SnackbarState = state;
var options = State.Options;
if (state.IsShowing())
{
if (options.ShowTransitionDuration <= 0) TransitionTo(SnackbarState.Visible);
else StartTimer(options.ShowTransitionDuration);
}
else if (state.IsVisible() && !options.RequireInteraction)
{
if (options.VisibleStateDuration <= 0) TransitionTo(SnackbarState.Hiding);
else StartTimer(options.VisibleStateDuration);
}
else if (state.IsHiding())
{
if (options.HideTransitionDuration <= 0) OnClose?.Invoke(this);
else StartTimer(options.HideTransitionDuration);
}
OnUpdate?.Invoke();
}
private void TimerElapsed(object state)
{
switch (State.SnackbarState)
{
case SnackbarState.Showing:
TransitionTo(SnackbarState.Visible);
break;
case SnackbarState.Visible:
TransitionTo(SnackbarState.Hiding);
break;
case SnackbarState.Hiding:
OnClose?.Invoke(this);
break;
}
}
private void StartTimer(int duration)
{
State.Stopwatch.Restart();
Timer?.Change(duration, Timeout.Infinite);
}
private void StopTimer()
{
State.Stopwatch.Stop();
Timer?.Change(Timeout.Infinite, Timeout.Infinite);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
StopTimer();
var timer = Timer;
Timer = null;
timer?.Dispose();
}
}