diff --git a/src/Disqord.Extensions.Interactivity/Menus/MenuBase.cs b/src/Disqord.Extensions.Interactivity/Menus/MenuBase.cs
index e99aae75f..27d7ab4a4 100644
--- a/src/Disqord.Extensions.Interactivity/Menus/MenuBase.cs
+++ b/src/Disqord.Extensions.Interactivity/Menus/MenuBase.cs
@@ -129,6 +129,58 @@ public ViewBase? View
}
private ViewBase? _view;
+ ///
+ /// Gets or sets the timeout of this menu.
+ ///
+ public TimeSpan Timeout
+ {
+ get => _timeout;
+ set
+ {
+ if (_timeout == value)
+ {
+ if (value == System.Threading.Timeout.InfiniteTimeSpan)
+ {
+ return;
+ }
+
+ RefreshTimeout();
+ }
+ else
+ {
+ lock (_disposeLock)
+ {
+ _timeout = value;
+ if (value == System.Threading.Timeout.InfiniteTimeSpan)
+ {
+ _timeoutTimer?.Dispose();
+ return;
+ }
+
+ _timeoutTimer = new Timer(TimerCallback, this, value, System.Threading.Timeout.InfiniteTimeSpan);
+ return;
+
+ static void TimerCallback(object? state)
+ {
+ var menu = Unsafe.As(state)!;
+ lock (menu._disposeLock)
+ {
+ if (!menu.IsRunning)
+ return;
+
+ var cts = menu._cts;
+ if (cts == null)
+ return;
+
+ cts.Cancel();
+ menu._tcs!.Cancel(cts.Token);
+ }
+ }
+ }
+ }
+ }
+ }
+
private Tcs? _tcs;
private Cts? _cts;
private TimeSpan _timeout;
@@ -168,14 +220,14 @@ protected virtual void ValidateView()
/// Refreshes the timeout of this menu.
/// By default, is called by .
///
- protected void RefreshTimeout()
+ public void RefreshTimeout()
{
if (!IsRunning)
return;
lock (_disposeLock)
{
- _timeoutTimer?.Change(_timeout, Timeout.InfiniteTimeSpan);
+ _timeoutTimer?.Change(_timeout, System.Threading.Timeout.InfiniteTimeSpan);
}
}
@@ -367,38 +419,16 @@ internal void Start(TimeSpan timeout, CancellationToken cancellationToken)
_tcs = new Tcs();
_cts = Cts.Linked(Client.StoppingToken, cancellationToken);
- static void CancellationCallback(object? state, CancellationToken cancellationToken)
- {
- var tcs = Unsafe.As(state)!;
- tcs.Cancel(cancellationToken);
- }
-
_cts.Token.UnsafeRegister(CancellationCallback, _tcs);
- if (timeout == Timeout.InfiniteTimeSpan)
- return;
+ Timeout = timeout;
+ return;
- // We store the timeout so it can be refreshed when a button is triggered in HandleInteractionAsync.
- _timeout = timeout;
-
- static void TimerCallback(object? state)
+ static void CancellationCallback(object? state, CancellationToken cancellationToken)
{
- var menu = Unsafe.As(state)!;
- lock (menu._disposeLock)
- {
- if (!menu.IsRunning)
- return;
-
- var cts = menu._cts;
- if (cts == null)
- return;
-
- cts.Cancel();
- menu._tcs!.Cancel(cts.Token);
- }
+ var tcs = Unsafe.As(state)!;
+ tcs.Cancel(cancellationToken);
}
-
- _timeoutTimer = new Timer(TimerCallback, this, timeout, Timeout.InfiniteTimeSpan);
}
///