🆕feat(PageStack): add support for clearing stack on push or replace (#2246)

This commit is contained in:
capdiem
2024-11-18 09:36:47 +08:00
committed by GitHub
parent 238af3d26b
commit 87a871551a
4 changed files with 67 additions and 7 deletions

View File

@@ -47,10 +47,11 @@ public class PageStackNavController()
/// <summary>
/// Push a new page onto the page stack.
/// </summary>
/// <param name="relativeUri"></param>
public void Push(string relativeUri)
/// <param name="relativeUri">the relative URI of the new page</param>
/// <param name="clearStack">determine whether to push new page and remove all old pages</param>
public void Push(string relativeUri, bool clearStack = false)
{
ExecuteIfTimeElapsed(() => StackPush?.Invoke(this, new PageStackPushEventArgs(relativeUri)));
ExecuteIfTimeElapsed(() => StackPush?.Invoke(this, new PageStackPushEventArgs(relativeUri, clearStack)));
}
/// <summary>
@@ -117,9 +118,10 @@ public class PageStackNavController()
/// </summary>
/// <param name="relativeUri"></param>
/// <param name="state"></param>
public void Replace(string relativeUri, object? state = null)
/// <param name="clearStack">determine whether to replace the current page and remove all previous pages</param>
public void Replace(string relativeUri, object? state = null, bool clearStack = false)
{
StackReplace?.Invoke(this, new PageStackReplaceEventArgs(relativeUri, state));
StackReplace?.Invoke(this, new PageStackReplaceEventArgs(relativeUri, state, clearStack));
}
/// <summary>

View File

@@ -1,6 +1,8 @@
namespace Masa.Blazor.Presets.PageStack.NavController;
public class PageStackPushEventArgs(string relativeUri) : EventArgs
public class PageStackPushEventArgs(string relativeUri, bool clearStack) : EventArgs
{
public string RelativeUri { get; } = relativeUri;
public bool ClearStack { get; } = clearStack;
}

View File

@@ -1,8 +1,10 @@
namespace Masa.Blazor.Presets.PageStack.NavController;
public class PageStackReplaceEventArgs(string relativeUri, object? state = null) : EventArgs
public class PageStackReplaceEventArgs(string relativeUri, object? state = null, bool clearStack = false) : EventArgs
{
public string RelativeUri { get; } = relativeUri;
public object? State { get; } = state;
public bool ClearStack { get; } = clearStack;
}

View File

@@ -31,6 +31,18 @@ public partial class PPageStack : PatternPathComponentBase
/// </summary>
private bool _popstateByUserAction;
/// <summary>
/// The flag to indicate whether to push a new page
/// and clear the stack in the next popstate event.
/// </summary>
private string? _uriForPushAndClearStack;
/// <summary>
/// The flag to indicate whether to replace the top page
/// and clear the previous pages in the stack in the next popstate event.
/// </summary>
private (string relativeUri, object? state)? _uriForReplaceAndClearStack;
private string? _lastVisitedTabPath;
private PageType _targetPageType;
private long _lastOnPreviousClickTimestamp;
@@ -113,6 +125,32 @@ public partial class PPageStack : PatternPathComponentBase
[JSInvokable]
public void Popstate(string absolutePath)
{
if (_uriForPushAndClearStack is not null)
{
Push(_uriForPushAndClearStack);
NavigationManager.NavigateTo(_uriForPushAndClearStack);
_uriForPushAndClearStack = null;
_ = Task.Run(async () =>
{
await Task.Delay(300); // wait for the transition to complete
Pages.RemoveRange(0, Pages.Count - 1);
await InvokeAsync(StateHasChanged);
});
return;
}
if (_uriForReplaceAndClearStack.HasValue)
{
var (relativeUri, state) = _uriForReplaceAndClearStack.Value;
Pages.RemoveRange(0, Pages.Count - 1);
InternalReplaceHandler(relativeUri, state);
_uriForReplaceAndClearStack = null;
return;
}
var tabbedPattern = _cachedTabbedPatterns.FirstOrDefault(r => r.IsMatch(absolutePath));
if (tabbedPattern is not null)
@@ -157,6 +195,13 @@ public partial class PPageStack : PatternPathComponentBase
private void InternalStackStackNavManagerOnStackReplace(object? sender, PageStackReplaceEventArgs e)
{
if (e.ClearStack)
{
_ = Js.InvokeVoidAsync(JsInteropConstants.HistoryGo, -(Pages.Count - 1));
_uriForReplaceAndClearStack = (e.RelativeUri, e.State);
return;
}
InternalReplaceHandler(e.RelativeUri, e.State);
}
@@ -182,6 +227,15 @@ public partial class PPageStack : PatternPathComponentBase
private void InternalStackStackNavManagerOnStackPush(object? sender, PageStackPushEventArgs e)
{
if (e.ClearStack)
{
// after calling history.go, a popstate event callback will be triggered,
// where the logic of the stack page is processed (push new page, clean up old page)
_ = Js.InvokeVoidAsync(JsInteropConstants.HistoryGo, -Pages.Count);
_uriForPushAndClearStack = e.RelativeUri;
return;
}
Push(e.RelativeUri);
NavigationManager.NavigateTo(e.RelativeUri);
}