Visualizar el estado de la red en una Blazor PWA

En el siguiente articulo voy a mostrar cómo podemos indicarle al usuario si nuestra PWA tienen conexión o no en el momento en que la esta usando. Recordemos que una Progressive web app puede funcionar incluso si no existe conexión a internet, el usuario podrá a navegar y ver la información en memoria y realizar algunas acciones e incluso sincronizar después.

Primero debemos crear un servicio que utilizando una función de javascript que pueda detectar en el browser si hay conexión o no. De momento no tenemos algo para hacerlo directamente en C# con Blazor.

 public class NetworkState : INetworkState
    {
        public event Action StatusChanged;
        public bool IsOnline { get; set; } = true;

        public NetworkState(IJSRuntime jsRuntime)
            => jsRuntime.InvokeVoidAsync("network.initialize",  DotNetObjectReference.Create(this));

        [JSInvokable("Network.StatusChanged")]
        public void OnStatusChanged(bool isOnline)
        {
            if (IsOnline != isOnline)
            {
                IsOnline = isOnline;
                StatusChanged?.Invoke();
            }
        }
       
    }

  public interface INetworkState
    {
       bool IsOnline { get; set; }
       void OnStatusChanged(bool isOnline);
        event Action StatusChanged;
    }

Y tenemos esta función de Javascript que debemos agregar para poder hacer esta detección.

window.network = {
    initialize: function (interop) {
        function handler() {
            interop.invokeMethodAsync("Network.StatusChanged", navigator.onLine);
        }

        window.addEventListener('online', handler);
        window.addEventListener('offline', handler);

        if (!navigator.onLine) {
            handler(navigator.onLine);
        }
    }
};

No olvides agregar la dependencia de este servicio en la configuración.

Services.AddScoped<INetworkState, NetworkState>();

Ahora con este servicio creado y configurado podemos crear nuestro componente para comprobar si efectivamente tenemos conexión o no.

@inject INetworkState State

@if (IsOnline)
{
   <span class="btn-success">Online</span>
}
else 
{
    <span class="btn-danger">Offline, Some functionalities are disabled</span>
}

@code
{
    protected bool IsOnline => State.IsOnline;

    protected override void OnInitialized()
    {
        base.OnInitialized();

        State.StatusChanged += StateHasChanged;
    }

    public void Dispose()
    {
        State.StatusChanged -= StateHasChanged;
    }
}

En el lugar de la aplicación que deseemos podemos incluir nuestro componente compartido para mostrar que la aplicación esta online

 <NetworkStatus />

Y este es el resultado:

Y automáticamente cuando la aplicación tenga problemas de conexión o de internet va ha cambiar a offline: