Files
ShrlAlgoToolkit/WPFluent/Controls/Snackbar/SnackbarPresenter.cs

154 lines
3.9 KiB
C#

// ReSharper disable once CheckNamespace
namespace WPFluent.Controls;
public class SnackbarPresenter : System.Windows.Controls.ContentPresenter
{
public SnackbarPresenter()
{
Unloaded += static(sender, _) =>
{
var self = (SnackbarPresenter)sender;
self.OnUnloaded();
};
}
~SnackbarPresenter()
{
if(!CancellationTokenSource.IsCancellationRequested)
{
CancellationTokenSource.Cancel();
}
CancellationTokenSource.Dispose();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"WpfAnalyzers.DependencyProperty",
"WPF0041:Set mutable dependency properties using SetCurrentValue",
Justification = "SetCurrentValue(ContentProperty, ...) will not work")]
private async Task HidSnackbar(Snackbar snackbar)
{
snackbar.SetCurrentValue(Snackbar.IsShownProperty, false);
await Task.Delay(300);
Content = null;
}
private void ImmediatelyHideCurrent()
{
if(Content is null)
{
return;
}
CancellationTokenSource.Cancel();
ImmediatelyHidSnackbar(Content);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"WpfAnalyzers.DependencyProperty",
"WPF0041:Set mutable dependency properties using SetCurrentValue",
Justification = "SetCurrentValue(ContentProperty, ...) will not work")]
private void ImmediatelyHidSnackbar(Snackbar snackbar)
{
snackbar.SetCurrentValue(Snackbar.IsShownProperty, false);
Content = null;
}
private async Task ShowQueuedSnackbarsAsync()
{
while(Queue.Count > 0 && !CancellationTokenSource.IsCancellationRequested)
{
Snackbar snackbar = Queue.Dequeue();
await ShowSnackbar(snackbar);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"WpfAnalyzers.DependencyProperty",
"WPF0041:Set mutable dependency properties using SetCurrentValue",
Justification = "SetCurrentValue(ContentProperty, ...) will not work")]
private async Task ShowSnackbar(Snackbar snackbar)
{
Content = snackbar;
snackbar.SetCurrentValue(Snackbar.IsShownProperty, true);
try
{
await Task.Delay(snackbar.Timeout, CancellationTokenSource.Token);
} catch
{
return;
}
await HidSnackbar(snackbar);
}
protected virtual void OnUnloaded()
{
if(CancellationTokenSource.IsCancellationRequested)
{
return;
}
ImmediatelyHideCurrent();
ResetCancellationTokenSource();
}
protected void ResetCancellationTokenSource()
{
CancellationTokenSource.Dispose();
CancellationTokenSource = new CancellationTokenSource();
}
protected CancellationTokenSource CancellationTokenSource { get; set; } = new();
protected Queue<Snackbar> Queue { get; } = new();
public virtual void AddToQue(Snackbar snackbar)
{
Queue.Enqueue(snackbar);
if(Content is null)
{
_ = ShowQueuedSnackbarsAsync(); // TODO: Fix detached process
}
}
public virtual async Task HideCurrent()
{
if(Content is null)
{
return;
}
CancellationTokenSource.Cancel();
await HidSnackbar(Content);
ResetCancellationTokenSource();
}
public virtual async Task ImmediatelyDisplay(Snackbar snackbar)
{
await HideCurrent();
await ShowSnackbar(snackbar);
await ShowQueuedSnackbarsAsync();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"WpfAnalyzers.DependencyProperty",
"WPF0012:CLR property type should match registered type",
Justification = "seems harmless")]
public new Snackbar? Content
{
get => (Snackbar?)GetValue(ContentProperty);
protected set => SetValue(ContentProperty, value);
}
}