chrome-web-share
Version:
A lightweight React Share Button for mobile web with web share api integration, native intent support and fallback
362 lines (309 loc) • 15.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
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 _class, _class2, _temp, _class3, _class4, _temp2;
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _coreDecorators = require('core-decorators');
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _visibility = require('./visibility');
var _visibility2 = _interopRequireDefault(_visibility);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PopupModal = (0, _coreDecorators.autobind)(_class = (_temp = _class2 = function (_PureComponent) {
_inherits(PopupModal, _PureComponent);
_createClass(PopupModal, [{
key: 'isShareDisabled',
value: function isShareDisabled(type) {
var disabled = this.props.disabled;
return disabled && _lodash2.default.includes(disabled, type);
}
}, {
key: 'messageAndLink',
get: function get() {
var _props = this.props,
shareUrl = _props.shareUrl,
shareMessage = _props.shareMessage;
return shareMessage + ' ' + shareUrl;
}
}]);
function PopupModal(props) {
_classCallCheck(this, PopupModal);
return _possibleConstructorReturn(this, (PopupModal.__proto__ || Object.getPrototypeOf(PopupModal)).call(this, props));
}
_createClass(PopupModal, [{
key: 'handleCopyLink',
value: function handleCopyLink(e) {
var onCopySuccess = this.props.onCopySuccess;
var copyTarget = document.querySelector(e.currentTarget.dataset.copytarget || null);
if (copyTarget && copyTarget.select) {
copyTarget.select();
try {
document.execCommand('copy');
copyTarget.blur();
onCopySuccess(copyTarget.value);
} catch (err) {
alert('Your device does not support copying, please copy manually.');
}
}
}
/**
* Helper function to open the App Store if the share does not trigger WhatsApp to launch.
*/
}, {
key: 'handleWhatsAppShare',
value: function handleWhatsAppShare() {
var _this2 = this;
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
var delay = 1000;
var start = new Date().getTime();
var link = /android/i.test(userAgent) ? 'https://play.google.com/store/apps/details?id=com.whatsapp' : /iPad|iPhone|iPod/i.test(userAgent) ? 'https://itunes.apple.com/app/id310633997' : 'https://api.whatsapp.com/send?text=' + encodeURIComponent(this.messageAndLink);
// Checks to see if whatsapp share launched otherwise lets show the user a donwload link for whatsapp
setTimeout(function () {
var end = new Date().getTime();
if (_this2.visibility && _this2.visibility.isHidden() || end - start >= delay * 2) return;
window.open(link, '_blank');
}, delay);
}
}, {
key: 'handleFacebookShare',
value: function handleFacebookShare() {}
}, {
key: 'handleTwitterShare',
value: function handleTwitterShare() {}
}, {
key: 'handleEmailShare',
value: function handleEmailShare() {}
}, {
key: 'setVisibilityRef',
value: function setVisibilityRef(node) {
this.visibility = node;
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
shareMessage = _props2.shareMessage,
shareUrl = _props2.shareUrl,
fbAppId = _props2.fbAppId,
fbDisplayType = _props2.fbDisplayType,
emailAddress = _props2.emailAddress,
copyText = _props2.copyText;
var gmailLink = 'https://mail.google.com/mail/u/0/?view=cm&ui=2&tf=0&fs=1&su=' + shareMessage + '&body=' + shareUrl;
var emailLink = 'mailto:' + emailAddress + '?body=' + shareMessage;
var twitterLink = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(shareMessage) + '&url=' + encodeURIComponent(shareUrl);
var facebookLink = 'https://www.facebook.com/dialog/share?app_id=' + fbAppId + '&display=' + fbDisplayType + '&href=' + encodeURIComponent(shareUrl);
return _react2.default.createElement(
'div',
{ className: 'share-popup' },
this.props.modelOpen && _react2.default.createElement(_visibility2.default, { ref: this.setVisibilityRef }),
!this.isShareDisabled(_utils.BUTTON_TYPES.WHATSAPP) && _react2.default.createElement(
'a',
{ className: 'sp-tab', href: 'whatsapp://send?text=' + encodeURIComponent(this.messageAndLink),
onClick: this.handleWhatsAppShare },
_react2.default.createElement('div', { className: 'icon whatsapp' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
'WhatsApp'
)
),
!this.isShareDisabled(_utils.BUTTON_TYPES.FACEBOOK) && _react2.default.createElement(
'a',
{ className: 'sp-tab',
href: facebookLink,
onClick: this.handleFacebookShare, target: '_blank' },
_react2.default.createElement('div', { className: 'icon fb' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
'Facebook'
)
),
!this.isShareDisabled(_utils.BUTTON_TYPES.TWITTER) && _react2.default.createElement(
'a',
{ className: 'sp-tab',
href: twitterLink,
onClick: this.handleTwitterShare, target: '_blank' },
_react2.default.createElement('div', { className: 'icon twitter' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
'Twitter'
)
),
!this.isShareDisabled(_utils.BUTTON_TYPES.GMAIL) && _react2.default.createElement(
'a',
{ className: 'sp-tab', href: gmailLink, onClick: this.handleEmailShare, target: '_blank' },
_react2.default.createElement('div', { className: 'icon gmail' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
'Mail'
)
),
!this.isShareDisabled(_utils.BUTTON_TYPES.EMAIL) && emailAddress && _react2.default.createElement(
'a',
{ className: 'sp-tab', href: emailLink },
_react2.default.createElement('div', { className: 'icon gmail' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
'E-Mail'
)
),
!this.isShareDisabled(_utils.BUTTON_TYPES.COPY) && _react2.default.createElement(
'div',
{ className: 'sp-tab copy', onClick: this.handleCopyLink, 'data-copytarget': '#shareUrl' },
_react2.default.createElement(
'div',
{ className: 'copy-input' },
_react2.default.createElement('input', { type: 'text', id: 'shareUrl', value: shareUrl, readOnly: true })
),
_react2.default.createElement(
'div',
{ className: 'copy-button' },
_react2.default.createElement('div', { className: 'icon copy' }),
_react2.default.createElement(
'span',
{ className: 'shareMessage' },
copyText
)
)
)
);
}
}]);
return PopupModal;
}(_react.PureComponent), _class2.propTypes = {
disabled: _propTypes2.default.array,
modelOpen: _propTypes2.default.bool,
shareUrl: _propTypes2.default.string,
shareMessage: _propTypes2.default.string,
fbAppId: _propTypes2.default.string,
fbDisplayType: _propTypes2.default.string,
onCopySuccess: _propTypes2.default.func,
emailAddress: _propTypes2.default.string,
copyText: _propTypes2.default.string
}, _class2.defaultProps = {
disabled: [_utils.BUTTON_TYPES.EMAIL],
modelOpen: false,
shareUrl: '',
shareMessage: '',
fbAppId: '',
fbDisplayType: 'touch',
onCopySuccess: function onCopySuccess() {},
copyText: 'Copy to clipboard'
}, _temp)) || _class;
var Button = (0, _coreDecorators.autobind)(_class3 = (_temp2 = _class4 = function (_PureComponent2) {
_inherits(Button, _PureComponent2);
function Button(props) {
_classCallCheck(this, Button);
var _this3 = _possibleConstructorReturn(this, (Button.__proto__ || Object.getPrototypeOf(Button)).call(this, props));
_this3.state = {
modelOpen: false
};
if (props.shouldCloseOnEscape) {
document.addEventListener('keyup', function (e) {
if (e.keyCode === _utils.KEYCODE_ESCAPE) {
_this3.setState({ modelOpen: false });
}
});
}
return _this3;
}
_createClass(Button, [{
key: 'toggleShare',
value: function toggleShare() {
var _props3 = this.props,
onButtonClick = _props3.onButtonClick,
shareMessage = _props3.shareMessage,
shareUrl = _props3.shareUrl,
disableWebShareAPI = _props3.disableWebShareAPI;
var modelOpen = this.state.modelOpen;
if (!modelOpen && onButtonClick) {
onButtonClick();
}
if (navigator && !!navigator.share && !disableWebShareAPI) {
navigator.share({
title: shareMessage,
text: shareMessage + shareUrl,
url: shareUrl
}).then(function () {
return console.log('Successful share');
}).catch(function (error) {
return console.log('Error sharing:', error);
});
} else {
document.body.style.overflow = !modelOpen ? 'hidden' : 'auto';
this.setState({ modelOpen: !modelOpen });
}
}
}, {
key: 'render',
value: function render() {
var _props4 = this.props,
className = _props4.className,
buttonText = _props4.buttonText,
shouldCloseOnEscape = _props4.shouldCloseOnEscape,
disabled = _props4.disabled,
shareUrl = _props4.shareUrl,
shareMessage = _props4.shareMessage,
onCopySuccess = _props4.onCopySuccess,
fbAppId = _props4.fbAppId,
emailAddress = _props4.emailAddress,
copyText = _props4.copyText;
var modelOpen = this.state.modelOpen;
var popupProps = {
disabled: disabled,
shareUrl: shareUrl,
shareMessage: shareMessage,
onCopySuccess: onCopySuccess,
fbAppId: fbAppId,
emailAddress: emailAddress,
copyText: copyText
};
return _react2.default.createElement(
'div',
{ className: className },
_react2.default.createElement(
'div',
{ className: 'share-btn', onClick: this.toggleShare },
buttonText
),
_react2.default.createElement(
'div',
{ className: 'share-modal ' + (modelOpen ? 'open' : '') },
_react2.default.createElement('div', { className: 'overlay', onClick: this.toggleShare }),
_react2.default.createElement(PopupModal, _extends({}, popupProps, {
toggleShare: this.toggleShare,
modelOpen: this.state.modelOpen
}))
)
);
}
}]);
return Button;
}(_react.PureComponent), _class4.propTypes = {
shareUrl: _propTypes2.default.string,
shareMessage: _propTypes2.default.string,
buttonText: _propTypes2.default.string,
onButtonClick: _propTypes2.default.func,
onCopySuccess: _propTypes2.default.func,
fbAppId: _propTypes2.default.string
}, _class4.defaultProps = {
shareUrl: _utils.DEFAULT_STRING,
shareMessage: _utils.DEFAULT_STRING,
buttonText: 'Share',
onButtonClick: _utils.DEFAULT_FUNCTION
}, _temp2)) || _class3;
exports.default = Button;