package org.realityforge.arez.browser.extras;

import elemental2.dom.DomGlobal;
import elemental2.dom.EventListener;
import javax.annotation.Nonnull;
import org.realityforge.arez.Unsupported;
import org.realityforge.arez.annotations.Action;
import org.realityforge.arez.annotations.Computed;
import org.realityforge.arez.annotations.Container;
import org.realityforge.arez.annotations.Observable;
import org.realityforge.arez.annotations.OnActivate;
import org.realityforge.arez.annotations.OnDeactivate;

@Unsupported( "This is still considered experimental and will likely evolve over time" )
@Container( singleton = true )
public class NetworkStatus
{
  private final EventListener _listener;
  private boolean _rawOnLine;

  @Nonnull
  public static NetworkStatus create()
  {
    return new Arez_NetworkStatus();
  }

  NetworkStatus()
  {
    _listener = e -> updateOnlineStatus();
    _rawOnLine = DomGlobal.navigator.onLine;
  }

  @Computed
  public boolean isOnLine()
  {
    return isRawOnLine();
  }

  @OnActivate
  final void onOnLineActivate()
  {
    updateOnlineStatus();
    DomGlobal.window.addEventListener( "online", _listener );
    DomGlobal.window.addEventListener( "offline", _listener );
  }

  @OnDeactivate
  final void onOnLineDeactivate()
  {
    DomGlobal.window.removeEventListener( "online", _listener );
    DomGlobal.window.removeEventListener( "offline", _listener );
  }

  @Observable
  boolean isRawOnLine()
  {
    return _rawOnLine;
  }

  void setRawOnLine( final boolean rawOnLine )
  {
    _rawOnLine = rawOnLine;
  }

  @Action
  void updateOnlineStatus()
  {
    setRawOnLine( DomGlobal.navigator.onLine );
  }
}

@@ -499,16 +499,1133 @@
 ivate;%0A%0A
+/**%0A * An observable model that declares state that tracks when the user is %22online%22.%0A * The online state is essentially a reflection of the browsers %22navigator.onLine%22%0A * value. If an observer is observing the model, the model listens for changes from%0A * the browser and updates the online state as appropriate. However if there is no%0A * observer for the state, the model will not listen to to the browser events so as%0A * not to have any significant performance impact.%3C/p%3E%0A *%0A * %3Ch1%3EA very simple example%3C/h1%3E%0A * %3Cpre%3E%7B@code%0A * import com.google.gwt.core.client.EntryPoint;%0A * import elemental2.dom.DomGlobal;%0A * import org.realityforge.arez.Arez;%0A * import org.realityforge.arez.browser.extras.NetworkStatus;%0A *%0A * public class NetworkStatusExample%0A *   implements EntryPoint%0A * %7B%0A *   public void onModuleLoad()%0A *   %7B%0A *     final NetworkStatus networkStatus = NetworkStatus.create();%0A *     Arez.context().autorun( () -%3E %7B%0A *       final String message = %22Network Status: %22 + ( networkStatus.isOnLine() ? %22Online%22 : %22Offline%22 );%0A *       DomGlobal.console.log( message );%0A *     %7D );%0A *   %7D%0A * %7D%0A * %7D%3C/pre%3E%0A */%0A
 @Unsuppo
@@ -1837,16 +1837,116 @@
 nLine;%0A%0A
+  /**%0A   * Create an instance of NetworkStatus.%0A   *%0A   * @return the NetworkStatus instance.%0A   */%0A
   @Nonnu
@@ -2148,16 +2148,154 @@
 e;%0A  %7D%0A%0A
+  /**%0A   * Return true if the browser is online, false otherwise.%0A   *%0A   * @return true if the browser is online, false otherwise.%0A   */%0A
   @Compu

Add some basic documentation