UNPKG

wcomponent-check-connexion

Version:

web component that is used to check user connexion

215 lines (186 loc) 5.71 kB
import { LitElement, html, css } from "lit-element/lit-element"; export default class CheckConnexion extends LitElement { constructor() { super(); this.tStart = null; this.tEnd = null; this.image = new Image(); this.counter = 0; this.arrTimes = []; this.abortFallback = false; this.timeToCount = 3; this.threshold = 2000; this.offlineTimeout = 2000; this.message = "Disconnected"; this.timeout = () => {}; this.intervalCheckLatency = 6000; this.state = true; } static get properties() { return { timeToCount: { type: Number }, threshold: { type: Number }, offlineTimeout: { type: Number }, message: { type: Text }, intervalCheckLatency: { type: Number }, active: { type: Boolean } }; } /** * init the function which observe if user have connexion * @param _changeProperty */ firstUpdated(_changeProperty) { this.checkConnectivity(); } /** * * @param {boolean} state of the connexion */ changeConnectivity(state) { //fire the event connexion-changed in document const event = new CustomEvent('connexion-changed', { detail: state }); document.dispatchEvent(event); this.changeState(state); //display the div to inform user that they didn't havec connexion if (state) { clearTimeout(this.timeout); } } changeState(state) { if (state !== this.state) { this.state = !this.state; this.requestUpdate(); } } /** * function used to check the connexion of users */ checkConnectivity() { //users have connexion when they load the page ? if (navigator.onLine) { this.changeConnectivity(true); } else { this.timeout = setTimeout(() => { this.changeConnectivity(false); }, this.offlineTimeout); } //event listener online / offline window.addEventListener('online', () => { this.changeConnectivity(true); }); window.addEventListener('offline', () => { this.timeout = setTimeout(() => { this.changeConnectivity(false); }, this.offlineTimeout); }); //timeout in case of the connexion is too slow to load the first request this.timeoutCallback(); //check if the connexion is too slow this.checkLatency(avg => this.handleLatency(avg)); setInterval(() => { this.reset(); this.timeoutCallback(); this.checkLatency(avg => this.handleLatency(avg)); }, this.intervalCheckLatency); } /** * make an average of time to get an image * @param {function} callback */ checkLatency(callback) { this.tStart = new Date().getTime(); if (this.counter < this.timeToCount) { //load image use to check the connexion this.image.src = "https://www.google.com/images/phd/px.gif?t=" + this.tStart; this.image.onload = () => { //disabling the fallback timeout this.abortFallback = true; //add the time to get the image to an array to make the average this.tEnd = new Date().getTime(); let time = this.tEnd - this.tStart; this.arrTimes.push(time); this.checkLatency(callback); this.counter++; }; //if we can't get the image, passing the connectivity to false this.image.offline = () => { this.timeout = setTimeout(() => { this.changeConnectivity(false); }, this.offlineTimeout); }; } else { //average of times to get images const sum = this.arrTimes.reduce((a, b) => a + b); const avg = sum / this.arrTimes.length; callback(avg); } } timeoutCallback() { this.timeout = setTimeout(() => { if (!this.abortFallback) { console.log('Connectivity is too slow, falling back offline experience'); this.changeConnectivity(false); } }, this.threshold + 1); } reset() { this.arrTimes = []; this.counter = 0; } handleLatency(avg) { const isConnectedFast = avg <= this.threshold; if (!isConnectedFast) return this.changeConnectivity(false); this.changeConnectivity(true); } static get styles() { return css` .connexion { --check-connexion-font-size: 2vh; --check-connexion-background-color: #d00000; --check-connexion-text-color: #ffffff; --check-connexion-text-transform: uppercase; --check-connexion-height: 50px; } .connexion { height: 0; opacity: 0; position: fixed; line-height: var(--check-connexion-height); bottom: 0; width: 100%; background-color: var(--check-connexion-background-color); color: var(--check-connexion-text-color); text-align: center; padding: 5px; transition: 1s all ease-in-out; overflow: hidden; } .active { height: var(--check-connexion-height); opacity: 1; } .isDisconnected { font-size: var(--check-connexion-font-size); text-transform: var(--check-connexion-text-transform) } `; } render() { let classInactive = !this.state ? 'active' : ''; return html` <div class="connexion ${classInactive}"> <div class="isDisconnected">${this.message}</div> </div> `; } } customElements.define('check-connexion', CheckConnexion);