react-detect-offline
Advanced tools
Comparing version 1.0.5 to 1.0.6
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.Offline = exports.Online = undefined; | ||
exports.Detector = exports.Offline = exports.Online = undefined; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _react = require('react'); | ||
var _react = require("react"); | ||
@@ -25,3 +25,41 @@ var _react2 = _interopRequireDefault(_react); | ||
var unsupportedUserAgentsPattern = /Windows.*Chrome/; | ||
var config = { | ||
poll: unsupportedUserAgentsPattern.test(navigator.userAgent), | ||
url: "https://ipv4.icanhazip.com/", | ||
timeout: 5000, | ||
interval: 5000 | ||
}; | ||
var ping = function ping(config) { | ||
return new Promise(function (resolve, reject) { | ||
var isOnline = function isOnline() { | ||
return resolve(true); | ||
}; | ||
var isOffline = function isOffline() { | ||
return resolve(false); | ||
}; | ||
var xhr = new XMLHttpRequest(); | ||
xhr.onerror = isOffline; | ||
xhr.ontimeout = isOffline; | ||
xhr.onload = function () { | ||
var response = xhr.responseText.trim(); | ||
if (!response) { | ||
isOffline(); | ||
} else { | ||
isOnline(); | ||
} | ||
}; | ||
xhr.open("GET", config.url); | ||
xhr.timeout = config.url; | ||
xhr.send(); | ||
}); | ||
}; | ||
// base class that detects offline/online changes | ||
var Base = function (_Component) { | ||
@@ -36,3 +74,3 @@ _inherits(Base, _Component); | ||
_this.state = { | ||
online: navigator.onLine | ||
online: typeof navigator.onLine === "boolean" ? navigator.onLine : true | ||
}; | ||
@@ -42,3 +80,2 @@ // bind event handlers | ||
_this.goOffline = _this.goOffline.bind(_this); | ||
_this.handleDebugKeydown = _this.handleDebugKeydown.bind(_this); | ||
return _this; | ||
@@ -48,3 +85,3 @@ } | ||
_createClass(Base, [{ | ||
key: 'renderChildren', | ||
key: "renderChildren", | ||
value: function renderChildren() { | ||
@@ -70,8 +107,8 @@ var children = this.props.children; | ||
if (!wrapperType) { | ||
if (typeof firstChild === 'string' || firstChild.type === 'span') { | ||
if (typeof firstChild === "string" || firstChild.type === "span") { | ||
// use span for string or span children | ||
wrapperType = 'span'; | ||
wrapperType = "span"; | ||
} else { | ||
// fallback on div | ||
wrapperType = 'div'; | ||
wrapperType = "div"; | ||
} | ||
@@ -82,38 +119,59 @@ } | ||
}, { | ||
key: 'goOnline', | ||
key: "goOnline", | ||
value: function goOnline() { | ||
this.setState({ online: true }); | ||
if (!this.state.online) { | ||
this.callOnChangeHandler(true); | ||
this.setState({ online: true }); | ||
} | ||
} | ||
}, { | ||
key: 'goOffline', | ||
key: "goOffline", | ||
value: function goOffline() { | ||
this.setState({ online: false }); | ||
if (this.state.online) { | ||
this.callOnChangeHandler(false); | ||
this.setState({ online: false }); | ||
} | ||
} | ||
}, { | ||
key: 'handleDebugKeydown', | ||
value: function handleDebugKeydown(_ref) { | ||
var keyCode = _ref.keyCode, | ||
shiftKey = _ref.shiftKey, | ||
metaKey = _ref.metaKey; | ||
if (keyCode === 48 && shiftKey && metaKey) { | ||
this.setState({ online: !this.state.online }); | ||
key: "callOnChangeHandler", | ||
value: function callOnChangeHandler(online) { | ||
if (this.props.onChange) { | ||
this.props.onChange(online); | ||
} | ||
} | ||
}, { | ||
key: 'componentDidMount', | ||
key: "startPolling", | ||
value: function startPolling() { | ||
var _this2 = this; | ||
this.pollingId = setInterval(function () { | ||
ping(config).then(function (online) { | ||
online ? _this2.goOnline() : _this2.goOffline(); | ||
}); | ||
}, config.interval); | ||
} | ||
}, { | ||
key: "stopPolling", | ||
value: function stopPolling() { | ||
clearInterval(this.pollingId); | ||
} | ||
}, { | ||
key: "componentDidMount", | ||
value: function componentDidMount() { | ||
window.addEventListener('online', this.goOnline); | ||
window.addEventListener('offline', this.goOffline); | ||
window.addEventListener("online", this.goOnline); | ||
window.addEventListener("offline", this.goOffline); | ||
if (parseInt(window.location.port) >= 1024) { | ||
window.addEventListener('keydown', this.handleDebugKeydown); | ||
if (config.poll) { | ||
this.startPolling(); | ||
} | ||
} | ||
}, { | ||
key: 'componentWillUnmount', | ||
key: "componentWillUnmount", | ||
value: function componentWillUnmount() { | ||
window.removeEventListener('online', this.goOnline); | ||
window.removeEventListener('offline', this.goOffline); | ||
window.removeEventListener('keydown', this.handleDebugKeydown); | ||
window.removeEventListener("online", this.goOnline); | ||
window.removeEventListener("offline", this.goOffline); | ||
if (config.poll) { | ||
this.stopPolling(); | ||
} | ||
} | ||
@@ -135,3 +193,3 @@ }]); | ||
_createClass(Online, [{ | ||
key: 'render', | ||
key: "render", | ||
value: function render() { | ||
@@ -155,3 +213,3 @@ return this.state.online ? this.renderChildren() : null; | ||
_createClass(Offline, [{ | ||
key: 'render', | ||
key: "render", | ||
value: function render() { | ||
@@ -163,2 +221,21 @@ return !this.state.online ? this.renderChildren() : null; | ||
return Offline; | ||
}(Base); | ||
var Detector = exports.Detector = function (_Base3) { | ||
_inherits(Detector, _Base3); | ||
function Detector() { | ||
_classCallCheck(this, Detector); | ||
return _possibleConstructorReturn(this, (Detector.__proto__ || Object.getPrototypeOf(Detector)).apply(this, arguments)); | ||
} | ||
_createClass(Detector, [{ | ||
key: "render", | ||
value: function render() { | ||
return this.props.render({ online: this.state.online }); | ||
} | ||
}]); | ||
return Detector; | ||
}(Base); |
{ | ||
"name": "react-detect-offline", | ||
"version": "1.0.5", | ||
"version": "1.0.6", | ||
"description": "Offline and Online components for React", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -27,5 +27,5 @@ [![npm](https://img.shields.io/npm/v/react-detect-offline.svg)](https://www.npmjs.com/package/react-detect-offline) | ||
`<Online>` - Component that renders its children only when the browser is online. | ||
`<Online/>` - Component that renders its children only when the browser is online. | ||
`<Offline>` - Component that renders its children only when the browser is not online. | ||
`<Offline/>` - Component that renders its children only when the browser is not online. | ||
@@ -32,0 +32,0 @@ **Note:** `Online` and `Offline` are mutually exclusive; if one is rendering, the other will not be. |
113
src/index.js
@@ -1,3 +0,41 @@ | ||
import React, { Component, isValidElement, Children, createElement } from "react"; | ||
import React, { | ||
Component, | ||
isValidElement, | ||
Children, | ||
createElement | ||
} from "react"; | ||
const unsupportedUserAgentsPattern = /Windows.*Chrome/; | ||
const config = { | ||
poll: unsupportedUserAgentsPattern.test(navigator.userAgent), | ||
url: "https://ipv4.icanhazip.com/", | ||
timeout: 5000, | ||
interval: 5000 | ||
}; | ||
const ping = config => { | ||
return new Promise((resolve, reject) => { | ||
const isOnline = () => resolve(true); | ||
const isOffline = () => resolve(false); | ||
const xhr = new XMLHttpRequest(); | ||
xhr.onerror = isOffline; | ||
xhr.ontimeout = isOffline; | ||
xhr.onload = () => { | ||
const response = xhr.responseText.trim(); | ||
if (!response) { | ||
isOffline(); | ||
} else { | ||
isOnline(); | ||
} | ||
}; | ||
xhr.open("GET", config.url); | ||
xhr.timeout = config.url; | ||
xhr.send(); | ||
}); | ||
}; | ||
// base class that detects offline/online changes | ||
@@ -8,3 +46,3 @@ class Base extends Component { | ||
this.state = { | ||
online: navigator.onLine, | ||
online: typeof navigator.onLine === "boolean" ? navigator.onLine : true | ||
}; | ||
@@ -14,3 +52,2 @@ // bind event handlers | ||
this.goOffline = this.goOffline.bind(this); | ||
this.handleDebugKeydown = this.handleDebugKeydown.bind(this); | ||
} | ||
@@ -22,6 +59,10 @@ renderChildren() { | ||
// usual case: one child that is a react Element | ||
if (React.isValidElement(children)) { return children; } | ||
if (React.isValidElement(children)) { | ||
return children; | ||
} | ||
// no children | ||
if (!children) { return null; } | ||
if (!children) { | ||
return null; | ||
} | ||
@@ -33,8 +74,8 @@ // string children, multiple children, or something else | ||
if (!wrapperType) { | ||
if (typeof firstChild === 'string' || firstChild.type === 'span') { | ||
if (typeof firstChild === "string" || firstChild.type === "span") { | ||
// use span for string or span children | ||
wrapperType = 'span'; | ||
wrapperType = "span"; | ||
} else { | ||
// fallback on div | ||
wrapperType = 'div'; | ||
wrapperType = "div"; | ||
} | ||
@@ -44,25 +85,51 @@ } | ||
} | ||
goOnline() { | ||
this.setState({ online: true }); | ||
if (!this.state.online) { | ||
this.callOnChangeHandler(true); | ||
this.setState({ online: true }); | ||
} | ||
} | ||
goOffline() { | ||
this.setState({ online: false }); | ||
if (this.state.online) { | ||
this.callOnChangeHandler(false); | ||
this.setState({ online: false }); | ||
} | ||
} | ||
handleDebugKeydown({ keyCode, shiftKey, metaKey }) { | ||
if (keyCode === 48 && shiftKey && metaKey) { | ||
this.setState({ online: !this.state.online }); | ||
callOnChangeHandler(online) { | ||
if (this.props.onChange) { | ||
this.props.onChange(online); | ||
} | ||
} | ||
startPolling() { | ||
this.pollingId = setInterval(() => { | ||
ping(config).then(online => { | ||
online ? this.goOnline() : this.goOffline(); | ||
}); | ||
}, config.interval); | ||
} | ||
stopPolling() { | ||
clearInterval(this.pollingId); | ||
} | ||
componentDidMount() { | ||
window.addEventListener('online', this.goOnline); | ||
window.addEventListener('offline', this.goOffline); | ||
window.addEventListener("online", this.goOnline); | ||
window.addEventListener("offline", this.goOffline); | ||
if (parseInt(window.location.port) >= 1024) { | ||
window.addEventListener('keydown', this.handleDebugKeydown); | ||
if (config.poll) { | ||
this.startPolling(); | ||
} | ||
} | ||
componentWillUnmount() { | ||
window.removeEventListener('online', this.goOnline); | ||
window.removeEventListener('offline', this.goOffline); | ||
window.removeEventListener('keydown', this.handleDebugKeydown); | ||
window.removeEventListener("online", this.goOnline); | ||
window.removeEventListener("offline", this.goOffline); | ||
if (config.poll) { | ||
this.stopPolling(); | ||
} | ||
} | ||
@@ -82,1 +149,7 @@ } | ||
} | ||
export class Detector extends Base { | ||
render() { | ||
return this.props.render({ online: this.state.online }); | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
71831
315