Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Service): breakpoint service doesn't work when interactive per page/component enabled #2131

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions src/Masa.Blazor/Components/App/MApp.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@ protected override void OnInitialized()
_ = UpsertThemeStyle(MasaBlazor.Theme);
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);

if (firstRender)
{
await OnJSInteropReadyAsync();
StateHasChanged();
}
}

private void OnStateChanged(object? sender, EventArgs e)
{
InvokeAsync(StateHasChanged);
Expand All @@ -57,11 +46,6 @@ private void OnDefaultsChanged(object? sender, EventArgs e)
InvokeAsync(StateHasChanged);
}

private async Task OnJSInteropReadyAsync()
{
await MasaBlazor.Breakpoint.InitAsync(Js);
}

private void OnThemeChange(Theme theme)
{
InvokeAsync(async () =>
Expand Down
11 changes: 11 additions & 0 deletions src/Masa.Blazor/Core/MasaComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ protected MasaComponentBase()
[Inject] public IJSRuntime Js { get; set; } = null!;

[Inject] private ILoggerFactory LoggerFactory { get; set; } = null!;

[Inject] private MasaBlazor MasaBlazor { get; set; } = null!;

[CascadingParameter] protected IDefaultsProvider? DefaultsProvider { get; set; }

Expand Down Expand Up @@ -232,6 +234,15 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);

// Before the interactive component publishing released by Blazor in .NET 8.0,
// only need to initialize the breakpoint service in the root component (MApp).
// But after the interactive component publishing,
// need to try to initialize the breakpoint service in each component.
if (firstRender)
{
MasaBlazor.Breakpoint.Init(Js);
}

// TODO: is this necessary?
if (_elementReferenceChanged)
{
Expand Down
34 changes: 20 additions & 14 deletions src/Masa.Blazor/Services/Breakpoint/Breakpoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using Masa.Blazor.Utils;

namespace Masa.Blazor;

Expand All @@ -13,11 +14,8 @@ public class BreakpointOptions

public class Breakpoint
{
public Breakpoint()
{
}

private IJSRuntime? JSRuntime { get; set; }
private readonly Throttle _throttle = new(500);
private IJSRuntime? _jsRuntime;

/// <summary>
/// Indicates that the breakpoint has been calculated. If not, the breakpoint will not work.
Expand Down Expand Up @@ -104,15 +102,23 @@ public void Deconstruct(
mobileBreakpoint = MobileBreakpoint;
}

public async Task InitAsync(IJSRuntime jsRuntime)
public void Init(IJSRuntime jsRuntime)
{
JSRuntime = jsRuntime;
_throttle.Execute(() =>
{
if (_jsRuntime is not null)
{
return;
}

_jsRuntime = jsRuntime;

await ResizeAsync();
_ = ResizeAsync();

_ = JSRuntime.AddHtmlElementEventListener("window", "resize", ResizeAsync,
new EventListenerOptions { Passive = true },
new EventListenerExtras(debounce: 200));
_ = _jsRuntime.AddHtmlElementEventListener("window", "resize", ResizeAsync,
new EventListenerOptions { Passive = true },
new EventListenerExtras(debounce: 200));
});
}

private async Task ResizeAsync()
Expand Down Expand Up @@ -207,12 +213,12 @@ private async Task<double> GetClientSizeAsync(string sizeName)

private async Task<double?> GetNumberPropAsync(string selector, string name)
{
if (JSRuntime is null)
if (_jsRuntime is null)
{
throw new NullReferenceException("JSRuntime is null. Please call UpdateJsRuntime(IJSRuntime jsRuntime) first.");
throw new NullReferenceException("JSRuntime is not initialized.");
}

var jsonElement = await JSRuntime.InvokeAsync<JsonElement>(JsInteropConstants.GetProp, selector, name);
var jsonElement = await _jsRuntime.InvokeAsync<JsonElement>(JsInteropConstants.GetProp, selector, name);
return jsonElement.ValueKind == JsonValueKind.Number ? jsonElement.GetDouble() : null;
}
}
24 changes: 24 additions & 0 deletions src/Masa.Blazor/Utils/Throttle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Masa.Blazor.Utils;

public class Throttle(TimeSpan delay)
{
private DateTime _lastExecutionTime = DateTime.MinValue;
private readonly object _lock = new();

public Throttle(int delay) : this(TimeSpan.FromMilliseconds(delay))
{
}

public void Execute(Action action)
{
lock (_lock)
{
var now = DateTime.UtcNow;
if (now - _lastExecutionTime >= delay)
{
_lastExecutionTime = now;
action();
}
}
}
}
Loading