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); }