scratch-www/src/components/helpwidget/helpwidget.jsx
Chris Garrity d538d5d053 Localize the widget
Note that some of the Freshdesk locales don’t match the ones used by Scratch.
2020-05-01 12:09:19 -04:00

181 lines
6.1 KiB
JavaScript

const FormattedMessage = require('react-intl').FormattedMessage;
const injectIntl = require('react-intl').injectIntl;
const intlShape = require('react-intl').intlShape;
const bindAll = require('lodash.bindall');
const connect = require('react-redux').connect;
const PropTypes = require('prop-types');
const React = require('react');
const Button = require('../forms/button.jsx');
const Spinner = require('../spinner/spinner.jsx');
require('./helpwidget.scss');
// map Scratch locale to supported Freshdesk locale
const freshdeskLocale = locale => {
// most locales in Scratch and Freshdesk use the two letter code. Define exceptions:
const localeMap = {
'es-419': 'es-LA',
'ja': 'ja-JP',
'ja-Hira': 'ja-JP',
'lv': 'lv-LV',
'nb': 'nb-NO',
'nn': 'nb-NO',
'pt': 'pt-PT',
'pt-br': 'pt-BR',
'ru': 'ru-RU',
'sv': 'sv-SE',
'zh-cn': 'zh-CN',
'zh-tw': 'zh-TW'
};
if (localeMap.hasOwnProperty(locale)) {
return localeMap[locale];
}
// locale will either be supported by Freshdesk, or will default to English if not
return locale;
};
/**
* Button or link that opens the Freshdesk Help widget
* see https://developers.freshdesk.com/widget-api/
*/
class HelpWidget extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleOpenWidget',
'openPopup'
]);
this.state = {
waiting: false
};
}
componentDidMount () {
if (this.props.subject !== '') {
// if passed Inappropriate content params load the script and open the popup
this.loadScript();
}
}
componentWillUnmount () {
window.FreshworksWidget('destroy');
document.getElementById('helpwidgetscript').remove();
}
loadScript () {
// don't add the script to the page more than once
if (document.getElementById('helpwidgetscript') === null) {
const script = document.createElement('script');
script.id = 'helpwidgetscript';
script.src = 'https://widget.freshworks.com/widgets/4000000089.js';
script.async = true;
script.defer = true;
script.onload = () => this.scriptLoaded();
window.fwSettings = {
widget_id: 4000000089,
locale: freshdeskLocale(this.props.intl.locale)
};
document.body.appendChild(script);
}
}
scriptLoaded () {
// freshdesk widget embed code
/* eslint-disable */
!(function(){if("function"!=typeof window.FreshworksWidget){var n=function(){n.q.push(arguments)};n.q=[],window.FreshworksWidget=n}}())
/* eslint-enable */
// don't show the Freshdesk button
window.FreshworksWidget('hide', 'launcher');
const labels = {};
labels[freshdeskLocale(this.props.intl.locale)] = {
banner: this.props.intl.formatMessage({id: 'helpWidget.banner'}),
contact_form: {
title: this.props.intl.formatMessage({id: 'general.contactUs'}),
submit: this.props.intl.formatMessage({id: 'helpWidget.submit'}),
confirmation: this.props.intl.formatMessage({id: 'helpWidget.confirmation'})
}
};
window.FreshworksWidget('setLabels', labels);
window.FreshworksWidget('disable', 'ticketForm', ['custom_fields.cf_inappropriate_report_link']);
window.FreshworksWidget('hide', 'ticketForm', ['custom_fields.cf_inappropriate_report_link']);
// open the popup already on the form if passed Inappropriate content param
this.openPopup(this.props.subject !== '');
}
handleOpenWidget (e) {
this.setState({waiting: true});
e.preventDefault();
// if the Widget is already defined, just open, otherwise load the widget script
if (typeof window.FreshworksWidget === 'function') {
this.openPopup();
} else {
this.loadScript();
}
}
openPopup (formOpen) {
window.FreshworksWidget('prefill', 'ticketForm', {
subject: this.props.subject,
custom_fields: {
cf_scratch_name: this.props.user.username,
cf_inappropriate_report_link: this.props.body
}
});
if (formOpen) {
window.FreshworksWidget('open', 'ticketForm');
} else {
window.FreshworksWidget('open');
}
// there may still be a little delay before the widget is visible, but there's
// no callback to attach this to.
this.setState({waiting: false});
}
render () {
return (
<a
href="#"
onClick={this.handleOpenWidget}
>
{this.props.button ? (
this.state.waiting ? (
<Button className="gethelp-button">
<Spinner
className="spinner"
/>
<FormattedMessage id="general.getHelp" />
</Button>
) : (
<Button className="gethelp-button">
<FormattedMessage id="general.getHelp" />
</Button>
)
) : (<FormattedMessage id="general.getHelp" />)
}
</a>
);
}
}
HelpWidget.propTypes = {
body: PropTypes.string,
button: PropTypes.bool,
intl: intlShape,
subject: PropTypes.string,
user: PropTypes.shape({
classroomId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
thumbnailUrl: PropTypes.string,
username: PropTypes.string
})
};
HelpWidget.defaultProps = {
body: '',
button: false,
subject: '',
user: {username: ''}
};
const mapStateToProps = state => ({
user: state.session.session.user
});
const ConnectedHelpWidget = connect(mapStateToProps)(HelpWidget);
module.exports = injectIntl(ConnectedHelpWidget);