Skip to content

Commit

Permalink
Merge pull request #275 from sirdoombox/main
Browse files Browse the repository at this point in the history
Fixed a few bugs in toasts.
  • Loading branch information
kikipoulet authored Aug 17, 2024
2 parents 4095bef + 5abbc9c commit fd9608b
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<HyperlinkButton
NavigateUri="https://github.com/kikipoulet/SukiUI/blob/main/SukiUI.Demo/Features/ControlsLibrary/Toasts/ToastsViewModel.cs"
Content="Source Here." />
<Button Command="{Binding DismissAllToastsCommand}" Content="Click To Dismiss All Active Toasts" HorizontalAlignment="Left" Classes="Flat"/>
</StackPanel>
</suki:GroupBox>
</suki:GlassCard>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,7 @@ void ShowCallbackToast()

[RelayCommand]
private void ShowToastWindow() => new ToastWindowDemo(toastManager).Show();

[RelayCommand]
private void DismissAllToasts() => toastManager.DismissAll();
}
9 changes: 6 additions & 3 deletions SukiUI/Controls/Hosts/SukiToastHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,11 @@ private void DetachManagerEvents(ISukiToastManager oldManager)
private void ManagerOnToastDismissed(object sender, SukiToastManagerEventArgs args) =>
ClearToast(args.Toast);

private void ManagerOnAllToastsDismissed(object sender, EventArgs e) =>
Items.Clear();
private void ManagerOnAllToastsDismissed(object sender, EventArgs e)
{
foreach(var toast in Items)
ClearToast((ISukiToast)toast!);
}

private void ManagerOnToastQueued(object sender, SukiToastManagerEventArgs args)
{
Expand All @@ -120,7 +123,7 @@ private void ManagerOnToastQueued(object sender, SukiToastManagerEventArgs args)

private void ClearToast(ISukiToast toast)
{
if (!Items.Contains(toast)) return;
if (Manager.IsDismissed(toast)) return;
toast.AnimateDismiss();
Task.Delay(300).ContinueWith(_ =>
{
Expand Down
3 changes: 3 additions & 0 deletions SukiUI/Controls/SukiToast.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public ObservableCollection<object> ActionButtons
get => GetValue(ActionButtonsProperty);
set => SetValue(ActionButtonsProperty, value);
}

public Action<ISukiToast>? DelayDismissAction { get; set; }

public SukiToast()
{
Expand Down Expand Up @@ -102,6 +104,7 @@ public ISukiToast ResetToDefault()
ActionButtons.Clear();
OnDismissed = null;
OnClicked = null;
DelayDismissAction = null;
DockPanel.SetDock(this, Dock.Bottom);
return this;
}
Expand Down
5 changes: 5 additions & 0 deletions SukiUI/Toasts/ISukiToast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ public interface ISukiToast
void AnimateShow();
void AnimateDismiss();
ISukiToast ResetToDefault();
/// <summary>
/// This is what's called when a delay based dismiss is used.
/// This is tracked so that it can be disposed of when the toast is dismissed by other means.
/// </summary>
Action<ISukiToast>? DelayDismissAction { get; set; }
}
}
5 changes: 5 additions & 0 deletions SukiUI/Toasts/ISukiToastManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,10 @@ public interface ISukiToastManager
/// Dismisses all toasts from the stack immediately.
/// </summary>
void DismissAll();

/// <summary>
/// Checks to see if a <see cref="ISukiToast"/> has already been dismissed from the stack.
/// </summary>
bool IsDismissed(ISukiToast toast);
}
}
12 changes: 10 additions & 2 deletions SukiUI/Toasts/SukiToastBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@ public void SetType(NotificationType type)
}


public void Delay(TimeSpan delay, Action<ISukiToast> action) =>
Task.Delay(delay).ContinueWith(_ => action(Toast), TaskScheduler.FromCurrentSynchronizationContext());
public void Delay(TimeSpan delay, Action<ISukiToast> action)
{
Toast.DelayDismissAction = action;
Task.Delay(delay).ContinueWith(_ =>
{
if (Toast.DelayDismissAction != action) return;
Toast.DelayDismissAction.Invoke(Toast);
},
TaskScheduler.FromCurrentSynchronizationContext());
}

public void SetOnDismiss(Action<ISukiToast> action) => Toast.OnDismissed = action;

Expand Down
15 changes: 9 additions & 6 deletions SukiUI/Toasts/SukiToastManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

namespace SukiUI.Toasts
{
// It's important that events are raised BEFORE removing them from the manager so that the animation only plays once.
public class SukiToastManager : ISukiToastManager
{
public event SukiToastManagerEventHandler? OnToastQueued;
public event SukiToastManagerEventHandler? OnToastDismissed;
public event EventHandler? OnAllToastsDismissed;

private readonly List<ISukiToast> _toasts = new();

public void Queue(ISukiToast toast)
Expand All @@ -20,34 +21,36 @@ public void Queue(ISukiToast toast)

public void Dismiss(ISukiToast toast)
{
if(!_toasts.Remove(toast)) return;
if (!_toasts.Contains(toast)) return;
OnToastDismissed?.Invoke(this, new SukiToastManagerEventArgs(toast));
_toasts.Remove(toast);
}

public void Dismiss(int count)
{
if (!_toasts.Any()) return;
if(count > _toasts.Count) count = _toasts.Count;
if (count > _toasts.Count) count = _toasts.Count;
for (var i = 0; i < count; i++)
{
var removed = _toasts[i];
_toasts.RemoveAt(i);
OnToastDismissed?.Invoke(this, new SukiToastManagerEventArgs(removed));
_toasts.RemoveAt(i);
}
}

public void EnsureMaximum(int maxAllowed)
{
Console.WriteLine($"{maxAllowed} - {_toasts.Count}");
if (_toasts.Count <= maxAllowed) return;
Dismiss(_toasts.Count - maxAllowed);
}

public void DismissAll()
{
if (!_toasts.Any()) return;
_toasts.Clear();
OnAllToastsDismissed?.Invoke(this, EventArgs.Empty);
_toasts.Clear();
}

public bool IsDismissed(ISukiToast toast) => !_toasts.Contains(toast);
}
}

0 comments on commit fd9608b

Please sign in to comment.