bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/polling/component.jsx

231 lines
6.8 KiB
React
Raw Normal View History

2018-10-24 22:17:13 +08:00
import React, { Component } from 'react';
import PropTypes from 'prop-types';
2016-06-30 06:00:06 +08:00
import Button from '/imports/ui/components/button/component';
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
import { defineMessages, injectIntl } from 'react-intl';
import cx from 'classnames';
import { Meteor } from 'meteor/meteor';
2018-01-08 14:17:18 +08:00
import { styles } from './styles.scss';
import AudioService from '/imports/ui/components/audio/service';
import Checkbox from '/imports/ui/components/checkbox/component';
2016-05-06 02:50:18 +08:00
2017-04-25 10:08:18 +08:00
const intlMessages = defineMessages({
pollingTitleLabel: {
id: 'app.polling.pollingTitle',
},
pollAnswerLabel: {
id: 'app.polling.pollAnswerLabel',
},
pollAnswerDesc: {
id: 'app.polling.pollAnswerDesc',
2017-04-25 10:08:18 +08:00
},
pollSubmitLabel: {
id: 'app.polling.pollSubmitLabel',
2021-02-05 01:55:18 +08:00
},
2017-04-25 10:08:18 +08:00
});
2018-10-24 22:17:13 +08:00
class Polling extends Component {
constructor(props) {
super(props);
2021-02-05 01:55:18 +08:00
this.state = {
checkedAnswers: [],
};
2021-02-05 01:55:18 +08:00
2018-10-24 22:17:13 +08:00
this.play = this.play.bind(this);
2021-02-05 01:55:18 +08:00
this.renderButtonAnswers = this.renderButtonAnswers.bind(this);
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.renderCheckboxAnswers = this.renderCheckboxAnswers.bind(this);
2018-10-24 22:17:13 +08:00
}
componentDidMount() {
this.play();
}
play() {
AudioService.playAlertSound(`${Meteor.settings.public.app.cdn
2020-12-01 00:09:35 +08:00
+ Meteor.settings.public.app.basename
+ Meteor.settings.public.app.instanceId}`
+ '/resources/sounds/Poll.mp3');
2018-10-24 22:17:13 +08:00
}
renderButtonAnswers(pollAnswerStyles) {
2021-02-05 01:55:18 +08:00
const {
isMeteorConnected,
intl,
poll,
handleVote,
pollAnswerIds,
} = this.props;
return (
<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.id])}
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>
)
2021-02-05 01:55:18 +08:00
}
handleCheckboxChange(pollId, answerId) {
const { checkedAnswers } = this.state;
2021-02-05 01:55:18 +08:00
if (checkedAnswers.includes(answerId)) {
checkedAnswers.splice(checkedAnswers.indexOf(answerId), 1);
2021-02-05 01:55:18 +08:00
} else {
checkedAnswers.push(answerId);
2021-02-05 01:55:18 +08:00
}
checkedAnswers.sort();
2021-02-08 21:23:43 +08:00
this.setState({checkedAnswers: checkedAnswers})
2021-02-05 01:55:18 +08:00
}
handleSubmit(pollId) {
const { handleVote } = this.props;
const { checkedAnswers } = this.state;
handleVote(pollId, checkedAnswers);
2021-02-05 01:55:18 +08:00
}
renderCheckboxAnswers(pollAnswerStyles) {
2021-02-05 01:55:18 +08:00
const {
isMeteorConnected,
intl,
poll,
pollAnswerIds,
} = this.props;
2021-02-08 21:23:43 +08:00
const { checkedAnswers } = this.state;
2021-02-05 01:55:18 +08:00
return (
<div>
<div className={cx(pollAnswerStyles)}>
<div>
{poll.answers.map((pollAnswer) => {
const formattedMessageIndex = pollAnswer.key.toLowerCase();
let label = pollAnswer.key;
if (pollAnswerIds[formattedMessageIndex]) {
label = intl.formatMessage(pollAnswerIds[formattedMessageIndex]);
}
return (
2021-02-05 01:55:18 +08:00
<div
key={pollAnswer.id}
2021-02-05 01:55:18 +08:00
>
<Checkbox
2021-02-08 21:23:33 +08:00
disabled={!isMeteorConnected}
id={`answerInput${pollAnswer.key}`}
onChange={() => this.handleCheckboxChange(poll.pollId, pollAnswer.id)}
checked={checkedAnswers.includes(pollAnswer.id)}
className={styles.checkbox}
ariaLabelledBy={`pollAnswerLabel${pollAnswer.key}`}
ariaDescribedBy={`pollAnswerDesc${pollAnswer.key}`}
/>
<label id={`pollAnswerLabel${pollAnswer.key}`}>
{label}
</label>
<div
className={styles.hidden}
id={`pollAnswerDesc${pollAnswer.key}`}
>
{intl.formatMessage(intlMessages.pollAnswerDesc, { 0: label })}
</div>
2021-02-05 01:55:18 +08:00
</div>
);
})}
</div>
2021-02-05 01:55:18 +08:00
</div>
<div>
<Button
2021-02-08 21:23:58 +08:00
disabled={!isMeteorConnected || checkedAnswers.length === 0}
className={styles.pollingButton}
color="primary"
size="md"
label={intl.formatMessage(intlMessages.pollSubmitLabel)}
onClick={() => this.handleSubmit(poll.pollId)}
2021-02-05 01:55:18 +08:00
/>
</div>
</div>
);
2021-02-05 01:55:18 +08:00
}
2018-10-24 22:17:13 +08:00
render() {
2019-05-23 02:00:44 +08:00
const {
intl,
poll,
2019-05-23 02:00:44 +08:00
} = this.props;
if (!poll) return null;
const { stackOptions, answers } = poll;
const pollAnswerStyles = {
[styles.pollingAnswers]: true,
[styles.removeColumns]: answers.length === 1,
[styles.stacked]: stackOptions,
};
2018-10-24 22:17:13 +08:00
return (
<div className={styles.overlay}>
<div
className={cx({
[styles.pollingContainer]: true,
[styles.autoWidth]: stackOptions,
})}
role="alert"
>
<div className={styles.pollingTitle}>
{intl.formatMessage(intlMessages.pollingTitleLabel)}
</div>
{poll.isMultipleResponse ? this.renderCheckboxAnswers(pollAnswerStyles) : this.renderButtonAnswers(pollAnswerStyles)}
2018-10-24 22:17:13 +08:00
</div>
</div>);
}
}
2017-04-25 10:08:18 +08:00
export default injectIntl(injectWbResizeEvent(Polling));
Polling.propTypes = {
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,
}).isRequired,
};