2018-10-24 22:17:13 +08:00
|
|
|
import React, { Component } from 'react';
|
2017-09-26 07:45:44 +08:00
|
|
|
import PropTypes from 'prop-types';
|
2016-06-30 06:00:06 +08:00
|
|
|
import Button from '/imports/ui/components/button/component';
|
2017-09-26 07:45:44 +08:00
|
|
|
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
|
2018-04-14 02:52:18 +08:00
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2019-03-28 23:58:10 +08:00
|
|
|
import cx from 'classnames';
|
2018-01-08 14:17:18 +08:00
|
|
|
import { styles } from './styles.scss';
|
2016-05-06 02:50:18 +08:00
|
|
|
|
2020-09-22 00:00:05 +08:00
|
|
|
const MAX_INPUT_CHARS = 45;
|
|
|
|
|
2017-04-25 10:08:18 +08:00
|
|
|
const intlMessages = defineMessages({
|
|
|
|
pollingTitleLabel: {
|
|
|
|
id: 'app.polling.pollingTitle',
|
2018-04-14 03:05:15 +08:00
|
|
|
},
|
|
|
|
pollAnswerLabel: {
|
|
|
|
id: 'app.polling.pollAnswerLabel',
|
|
|
|
},
|
|
|
|
pollAnswerDesc: {
|
|
|
|
id: 'app.polling.pollAnswerDesc',
|
2017-04-25 10:08:18 +08:00
|
|
|
},
|
2020-09-21 20:07:36 +08:00
|
|
|
pollQestionTitle: {
|
|
|
|
id: 'app.polling.pollQestionTitle',
|
|
|
|
},
|
|
|
|
submitLabel: {
|
|
|
|
id: 'app.polling.submitLabel',
|
|
|
|
},
|
|
|
|
submitAriaLabel: {
|
|
|
|
id: 'app.polling.submitAriaLabel',
|
|
|
|
},
|
|
|
|
responsePlaceholder: {
|
|
|
|
id: 'app.polling.responsePlaceholder',
|
|
|
|
},
|
2017-04-25 10:08:18 +08:00
|
|
|
});
|
|
|
|
|
2020-09-22 00:00:05 +08:00
|
|
|
const validateInput = (i) => {
|
|
|
|
let _input = i;
|
|
|
|
if (/^\s/.test(_input)) _input = '';
|
|
|
|
return _input;
|
|
|
|
};
|
|
|
|
|
2018-10-24 22:17:13 +08:00
|
|
|
class Polling extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2018-10-17 06:06:50 +08:00
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
this.state = {
|
|
|
|
typedAns: '',
|
|
|
|
};
|
|
|
|
|
2018-10-24 22:17:13 +08:00
|
|
|
this.play = this.play.bind(this);
|
2020-09-22 00:00:05 +08:00
|
|
|
this.handleUpdateResponseInput = this.handleUpdateResponseInput.bind(this);
|
2018-10-24 22:17:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
this.play();
|
|
|
|
}
|
|
|
|
|
|
|
|
play() {
|
2019-03-29 23:47:07 +08:00
|
|
|
this.alert = new Audio(`${Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename}/resources/sounds/Poll.mp3`);
|
2018-10-24 22:17:13 +08:00
|
|
|
this.alert.play();
|
|
|
|
}
|
|
|
|
|
2020-09-22 00:00:05 +08:00
|
|
|
handleUpdateResponseInput(e) {
|
|
|
|
this.responseInput.value = validateInput(e.target.value);
|
|
|
|
this.setState({ typedAns: this.responseInput.value });
|
|
|
|
}
|
|
|
|
|
2018-10-24 22:17:13 +08:00
|
|
|
render() {
|
2019-05-23 02:00:44 +08:00
|
|
|
const {
|
2019-06-28 00:46:14 +08:00
|
|
|
isMeteorConnected,
|
|
|
|
intl,
|
|
|
|
poll,
|
|
|
|
handleVote,
|
2020-09-21 20:07:36 +08:00
|
|
|
handleTypedVote,
|
2019-06-28 00:46:14 +08:00
|
|
|
pollAnswerIds,
|
2019-05-23 02:00:44 +08:00
|
|
|
} = this.props;
|
2020-09-21 20:07:36 +08:00
|
|
|
|
|
|
|
const {
|
|
|
|
typedAns,
|
|
|
|
} = this.state;
|
|
|
|
|
|
|
|
const { stackOptions, answers, question } = poll;
|
2019-03-28 23:58:10 +08:00
|
|
|
const pollAnswerStyles = {
|
|
|
|
[styles.pollingAnswers]: true,
|
|
|
|
[styles.removeColumns]: answers.length === 1,
|
|
|
|
[styles.stacked]: stackOptions,
|
|
|
|
};
|
2018-10-24 22:17:13 +08:00
|
|
|
|
|
|
|
return (
|
2018-10-26 00:07:24 +08:00
|
|
|
<div className={styles.overlay}>
|
2019-03-28 23:58:10 +08:00
|
|
|
<div
|
|
|
|
className={cx({
|
|
|
|
[styles.pollingContainer]: true,
|
|
|
|
[styles.autoWidth]: stackOptions,
|
|
|
|
})}
|
|
|
|
role="alert"
|
|
|
|
>
|
2020-09-21 20:07:36 +08:00
|
|
|
{question.length > 0 && (
|
|
|
|
<span className={styles.qHeader}>
|
|
|
|
<div className={styles.qTitle}>{intl.formatMessage(intlMessages.pollQestionTitle)}</div>
|
|
|
|
<div className={styles.qText}>{question}</div>
|
|
|
|
</span>)
|
|
|
|
}
|
2020-09-22 00:00:05 +08:00
|
|
|
{ poll.pollType !== 'RP' && (
|
2020-09-21 20:07:36 +08:00
|
|
|
<span>
|
|
|
|
{question.length === 0
|
|
|
|
&& (
|
|
|
|
<div className={styles.pollingTitle}>
|
|
|
|
{intl.formatMessage(intlMessages.pollingTitleLabel)}
|
|
|
|
</div>
|
|
|
|
)
|
2019-05-23 02:00:44 +08:00
|
|
|
}
|
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
<div className={cx(pollAnswerStyles)}>
|
|
|
|
{poll.answers.map((pollAnswer) => {
|
|
|
|
const formattedMessageIndex = pollAnswer.key.toLowerCase();
|
|
|
|
let label = pollAnswer.key;
|
|
|
|
if (pollAnswerIds[formattedMessageIndex]) {
|
|
|
|
label = intl.formatMessage(pollAnswerIds[formattedMessageIndex]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
key={pollAnswer.id}
|
|
|
|
className={styles.pollButtonWrapper}
|
|
|
|
>
|
|
|
|
<Button
|
|
|
|
disabled={!isMeteorConnected}
|
|
|
|
className={styles.pollingButton}
|
|
|
|
color="primary"
|
|
|
|
size="md"
|
|
|
|
label={label}
|
|
|
|
key={pollAnswer.key}
|
|
|
|
onClick={() => handleVote(poll.pollId, pollAnswer)}
|
|
|
|
aria-labelledby={`pollAnswerLabel${pollAnswer.key}`}
|
|
|
|
aria-describedby={`pollAnswerDesc${pollAnswer.key}`}
|
|
|
|
/>
|
|
|
|
<div
|
|
|
|
className={styles.hidden}
|
|
|
|
id={`pollAnswerLabel${pollAnswer.key}`}
|
|
|
|
>
|
|
|
|
{intl.formatMessage(intlMessages.pollAnswerLabel, { 0: label })}
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
className={styles.hidden}
|
|
|
|
id={`pollAnswerDesc${pollAnswer.key}`}
|
|
|
|
>
|
|
|
|
{intl.formatMessage(intlMessages.pollAnswerDesc, { 0: label })}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
</span>
|
2020-09-22 00:00:05 +08:00
|
|
|
)
|
2020-09-21 20:07:36 +08:00
|
|
|
}
|
|
|
|
{ poll.pollType === 'RP'
|
|
|
|
&& (
|
|
|
|
<div className={styles.typedResponseWrapper}>
|
|
|
|
<input
|
2020-09-22 00:00:05 +08:00
|
|
|
onChange={(e) => {
|
|
|
|
this.handleUpdateResponseInput(e);
|
|
|
|
}}
|
2020-09-21 20:07:36 +08:00
|
|
|
type="text"
|
|
|
|
className={styles.typedResponseInput}
|
|
|
|
placeholder={intl.formatMessage(intlMessages.responsePlaceholder)}
|
2020-09-22 00:00:05 +08:00
|
|
|
maxLength={MAX_INPUT_CHARS}
|
|
|
|
ref={(r) => { this.responseInput = r; }}
|
2020-09-21 20:07:36 +08:00
|
|
|
/>
|
|
|
|
<Button
|
2020-09-22 06:52:38 +08:00
|
|
|
className={styles.submitVoteBtn}
|
2020-09-21 20:07:36 +08:00
|
|
|
disabled={typedAns.length === 0}
|
|
|
|
color="primary"
|
|
|
|
size="sm"
|
|
|
|
label={intl.formatMessage(intlMessages.submitLabel)}
|
|
|
|
aria-label={intl.formatMessage(intlMessages.submitAriaLabel)}
|
|
|
|
onClick={() => {
|
|
|
|
handleTypedVote(poll.pollId, typedAns);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2018-10-24 22:17:13 +08:00
|
|
|
</div>
|
|
|
|
</div>);
|
|
|
|
}
|
|
|
|
}
|
2017-04-25 10:08:18 +08:00
|
|
|
|
2018-04-14 02:52:18 +08:00
|
|
|
export default injectIntl(injectWbResizeEvent(Polling));
|
2017-09-26 07:45:44 +08:00
|
|
|
|
2018-04-14 02:52:18 +08:00
|
|
|
Polling.propTypes = {
|
2017-09-26 07:45:44 +08:00
|
|
|
intl: PropTypes.shape({
|
|
|
|
formatMessage: PropTypes.func.isRequired,
|
|
|
|
}).isRequired,
|
|
|
|
handleVote: PropTypes.func.isRequired,
|
|
|
|
poll: PropTypes.shape({
|
|
|
|
pollId: PropTypes.string.isRequired,
|
2018-03-13 00:29:22 +08:00
|
|
|
answers: PropTypes.arrayOf(PropTypes.shape({
|
|
|
|
id: PropTypes.number.isRequired,
|
|
|
|
key: PropTypes.string.isRequired,
|
|
|
|
}).isRequired).isRequired,
|
2017-09-26 07:45:44 +08:00
|
|
|
}).isRequired,
|
|
|
|
};
|