using Connected.Annotations;
using Connected.Services;
using Microsoft.AspNetCore.Components;
namespace Connected.Components;
public partial class Hidden : UIComponent, IAsyncDisposable
{
private Breakpoint _currentBreakpoint = Breakpoint.None;
private bool _serviceIsReady = false;
private Guid _breakpointServiceSubscriptionId;
[Inject] public IBreakpointService BreakpointService { get; set; }
[CascadingParameter] public Breakpoint CurrentBreakpointFromProvider { get; set; } = Breakpoint.None;
///
/// The screen size(s) depending on which the ChildContent should not be rendered (or should be, if Invert is true)
///
[Parameter]
[Category(CategoryTypes.Hidden.Behavior)]
public Breakpoint Breakpoint { get; set; }
///
/// Inverts the Breakpoint, so that the ChildContent is only rendered when the breakpoint matches the screen size.
///
[Parameter]
[Category(CategoryTypes.Hidden.Behavior)]
public bool Invert { get; set; }
private bool _isHidden = true;
///
/// True if the component is not visible (two-way bindable)
///
[Parameter]
[Category(CategoryTypes.Hidden.Behavior)]
public bool IsHidden
{
get => _isHidden;
set
{
if (_isHidden != value)
{
_isHidden = value;
IsHiddenChanged.InvokeAsync(_isHidden);
}
}
}
///
/// Fires when the breakpoint changes visibility of the component
///
[Parameter] public EventCallback IsHiddenChanged { get; set; }
///
/// Child content of component.
///
[Parameter]
[Category(CategoryTypes.Hidden.Behavior)]
public RenderFragment ChildContent { get; set; }
protected void Update(Breakpoint currentBreakpoint)
{
if (CurrentBreakpointFromProvider != Breakpoint.None)
{
currentBreakpoint = CurrentBreakpointFromProvider;
}
else if (_serviceIsReady == false) { return; }
if (currentBreakpoint == Breakpoint.None) { return; }
_currentBreakpoint = currentBreakpoint;
var hidden = BreakpointService.IsMediaSize(Breakpoint, currentBreakpoint);
if (Invert == true)
{
hidden = !hidden;
}
IsHidden = hidden;
}
protected override void OnParametersSet()
{
base.OnParametersSet();
Update(_currentBreakpoint);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender == true)
{
if (CurrentBreakpointFromProvider == Breakpoint.None)
{
var attachResult = await BreakpointService.Subscribe((x) =>
{
Update(x);
InvokeAsync(StateHasChanged);
});
_serviceIsReady = true;
_breakpointServiceSubscriptionId = attachResult.SubscriptionId;
Update(attachResult.Breakpoint);
StateHasChanged();
}
else
{
_serviceIsReady = true;
}
}
}
public async ValueTask DisposeAsync() => await BreakpointService.Unsubscribe(_breakpointServiceSubscriptionId);
}