|
|
|
|
//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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|