Skip to content

Commit

Permalink
🐛 (Service): breakpoint service doesn't work when interactive per pag…
Browse files Browse the repository at this point in the history
…e/component enabled (#2131)
  • Loading branch information
capdiem authored Sep 4, 2024
1 parent dcc9b44 commit 0d4de39
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 30 deletions.
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();
}
}
}
}

0 comments on commit 0d4de39

Please sign in to comment.