import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import { toast } from 'react-toastify'; import Icon from '/imports/ui/components/common/icon/component'; import { ENTER } from '/imports/utils/keyCodes'; import Styled from './styles'; import { Meteor } from 'meteor/meteor'; import TooltipContainer from '/imports/ui/components/common/tooltip/container'; const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator; const messages = defineMessages({ lowerHandsLabel: { id: 'app.statusNotifier.lowerHands', description: 'text displayed to clear all raised hands', }, lowerHandDescOneUser: { id: 'app.statusNotifier.lowerHandDescOneUser', description: 'text displayed to clear a single user raised hands', }, raisedHandsTitle: { id: 'app.statusNotifier.raisedHandsTitle', description: 'heading for raised hands toast', }, raisedHandDesc: { id: 'app.statusNotifier.raisedHandDesc', description: 'label for multiple users with raised hands', }, raisedHandDescOneUser: { id: 'app.statusNotifier.raisedHandDescOneUser', description: 'label for a single user with raised hand', }, and: { id: 'app.statusNotifier.and', description: 'used as conjunction word', }, }); const MAX_AVATAR_COUNT = 3; class RaiseHandNotifier extends Component { constructor(props) { super(props); this.statusNotifierId = null; this.audio = new Audio(`${Meteor.settings.public.app.cdn + Meteor.settings.public.app.basename + Meteor.settings.public.app.instanceId}/resources/sounds/bbb-handRaise.mp3`); this.renderRaisedHands = this.renderRaisedHands.bind(this); this.getRaisedHandNames = this.getRaisedHandNames.bind(this); this.raisedHandAvatars = this.raisedHandAvatars.bind(this); } componentDidUpdate(prevProps) { const { raiseHandUsers, raiseHandAudioAlert, raiseHandPushAlert, isViewer, isPresenter, } = this.props; if (isViewer && !isPresenter) { if (this.statusNotifierId) toast.dismiss(this.statusNotifierId); return false; } if (raiseHandUsers.length === 0) { return this.statusNotifierId ? toast.dismiss(this.statusNotifierId) : null; } if (raiseHandAudioAlert && raiseHandUsers.length > prevProps.raiseHandUsers.length) { this.audio.play(); } if (raiseHandPushAlert) { if (this.statusNotifierId) { return toast.update(this.statusNotifierId, { render: this.renderRaisedHands(), }); } this.statusNotifierId = toast(this.renderRaisedHands(), { onClose: () => { this.statusNotifierId = null; }, autoClose: false, closeOnClick: false, closeButton: false, className: 'raiseHandToast', }); } return true; } getRaisedHandNames() { const { raiseHandUsers, intl } = this.props; if (raiseHandUsers.length === 0) return ''; const _names = raiseHandUsers.map((u) => u.name); const { length } = _names; const and = intl.formatMessage(messages.and); let formattedNames = ''; switch (length) { case 1: formattedNames = _names; break; case 2: formattedNames = _names.join(` ${and} `); break; case 3: formattedNames = _names.slice(0, length - 1).join(', '); formattedNames += ` ${and} ${_names.slice(length - 1)}`; break; default: formattedNames = _names.slice(0, MAX_AVATAR_COUNT).join(', '); formattedNames += ` ${and} ${length - MAX_AVATAR_COUNT}+ `; break; } const raisedHandMessageString = length === 1 ? messages.raisedHandDescOneUser : messages.raisedHandDesc; return intl.formatMessage(raisedHandMessageString, { 0: formattedNames }); } raisedHandAvatars() { const { raiseHandUsers, clearUserStatus, intl } = this.props; let users = raiseHandUsers; if (raiseHandUsers.length > MAX_AVATAR_COUNT) users = users.slice(0, MAX_AVATAR_COUNT); const avatars = users.map((u) => ( clearUserStatus(u.userId)} onKeyDown={(e) => (e.keyCode === ENTER ? clearUserStatus(u.userId) : null)} data-test="avatarsWrapperAvatar" moderator={u.role === ROLE_MODERATOR} avatar={u.avatar} > {u.name.slice(0, 2)} )); if (raiseHandUsers.length > MAX_AVATAR_COUNT) { avatars.push( {raiseHandUsers.length} , ); } return avatars; } renderRaisedHands() { const { raiseHandUsers, intl, lowerUserHands } = this.props; const formattedRaisedHands = this.getRaisedHandNames(); return (
{this.raisedHandAvatars()}
{intl.formatMessage(messages.raisedHandsTitle)}
{formattedRaisedHands}
{ raiseHandUsers.map((u) => lowerUserHands(u.userId)); }} data-test="raiseHandRejection" />
); } render() { return null; } } export default injectIntl(RaiseHandNotifier); RaiseHandNotifier.propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, lowerUserHands: PropTypes.func.isRequired, raiseHandUsers: PropTypes.instanceOf(Array).isRequired, raiseHandAudioAlert: PropTypes.bool.isRequired, raiseHandPushAlert: PropTypes.bool.isRequired, };