import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import browser from 'browser-detect'; import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component'; import Button from '/imports/ui/components/button/component'; import { HUNDRED_PERCENT, MAX_PERCENT, STEP } from '/imports/utils/slideCalcUtils'; import cx from 'classnames'; import { styles } from './styles.scss'; import ZoomTool from './zoom-tool/component'; import FullscreenButtonContainer from '../../video-provider/fullscreen-button/container'; import Tooltip from '/imports/ui/components/tooltip/component'; import KEY_CODES from '/imports/utils/keyCodes'; const intlMessages = defineMessages({ previousSlideLabel: { id: 'app.presentation.presentationToolbar.prevSlideLabel', description: 'Previous slide button label', }, previousSlideDesc: { id: 'app.presentation.presentationToolbar.prevSlideDesc', description: 'Aria description for when switching to previous slide', }, nextSlideLabel: { id: 'app.presentation.presentationToolbar.nextSlideLabel', description: 'Next slide button label', }, nextSlideDesc: { id: 'app.presentation.presentationToolbar.nextSlideDesc', description: 'Aria description for when switching to next slide', }, noNextSlideDesc: { id: 'app.presentation.presentationToolbar.noNextSlideDesc', description: '', }, noPrevSlideDesc: { id: 'app.presentation.presentationToolbar.noPrevSlideDesc', description: '', }, skipSlideLabel: { id: 'app.presentation.presentationToolbar.skipSlideLabel', description: 'Aria label for when switching to a specific slide', }, skipSlideDesc: { id: 'app.presentation.presentationToolbar.skipSlideDesc', description: 'Aria description for when switching to a specific slide', }, goToSlide: { id: 'app.presentation.presentationToolbar.goToSlide', description: 'button for slide select', }, selectLabel: { id: 'app.presentation.presentationToolbar.selectLabel', description: 'slide select label', }, fitToWidth: { id: 'app.presentation.presentationToolbar.fitToWidth', description: 'button for fit to width', }, fitToWidthDesc: { id: 'app.presentation.presentationToolbar.fitWidthDesc', description: 'Aria description to display the whole width of the slide', }, fitToPage: { id: 'app.presentation.presentationToolbar.fitToPage', description: 'button label for fit to width', }, fitToPageDesc: { id: 'app.presentation.presentationToolbar.fitScreenDesc', description: 'Aria description to display the whole slide', }, presentationLabel: { id: 'app.presentationUploder.title', description: 'presentation area element label', }, }); class PresentationToolbar extends Component { constructor(props) { super(props); this.state = { sliderValue: 100, }; this.handleValuesChange = this.handleValuesChange.bind(this); this.handleSkipToSlideChange = this.handleSkipToSlideChange.bind(this); this.change = this.change.bind(this); this.renderAriaDescs = this.renderAriaDescs.bind(this); this.switchSlide = this.switchSlide.bind(this); this.setInt = 0; } componentDidMount() { document.addEventListener('keydown', this.switchSlide); } componentWillUnmount() { document.removeEventListener('keydown', this.switchSlide); } switchSlide(event) { const { target, which } = event; const isBody = target.nodeName === 'BODY'; const { actions } = this.props; if (isBody) { if ([KEY_CODES.ARROW_LEFT].includes(which)) { actions.previousSlideHandler(); } if ([KEY_CODES.ARROW_RIGHT].includes(which)) { actions.nextSlideHandler(); } } } handleSkipToSlideChange(event) { const { actions } = this.props; const requestedSlideNum = Number.parseInt(event.target.value, 10); actions.skipToSlideHandler(requestedSlideNum); } handleValuesChange(event) { const { sliderValue } = this.state; this.setState( { sliderValue: event.target.value }, () => this.handleZoom(sliderValue), ); } change(value) { const { zoomChanger } = this.props; zoomChanger(value); } renderAriaDescs() { const { intl } = this.props; return ( ); } renderSkipSlideOpts(numberOfSlides) { // Fill drop down menu with all the slides in presentation const { intl } = this.props; const optionList = []; for (let i = 1; i <= numberOfSlides; i += 1) { optionList.push(( )); } return optionList; } render() { const { currentSlideNum, numberOfSlides, fitToWidthHandler, fitToWidth, actions, intl, zoom, isFullscreen, fullscreenRef, } = this.props; const BROWSER_RESULTS = browser(); const isMobileBrowser = BROWSER_RESULTS.mobile || BROWSER_RESULTS.os.includes('Android'); const tooltipDistance = 35; const startOfSlides = !(currentSlideNum > 1); const endOfSlides = !(currentSlideNum < numberOfSlides); const prevSlideAriaLabel = startOfSlides ? intl.formatMessage(intlMessages.previousSlideLabel) : `${intl.formatMessage(intlMessages.previousSlideLabel)} (${currentSlideNum <= 1 ? '' : (currentSlideNum - 1)})`; const nextSlideAriaLabel = endOfSlides ? intl.formatMessage(intlMessages.nextSlideLabel) : `${intl.formatMessage(intlMessages.nextSlideLabel)} (${currentSlideNum >= 1 ? (currentSlideNum + 1) : ''})`; return (
{this.renderAriaDescs()} {
} {
} {
{ !isMobileBrowser ? ( ) : null }
}
); } } PresentationToolbar.propTypes = { // Number of current slide being displayed currentSlideNum: PropTypes.number.isRequired, // Total number of slides in this presentation numberOfSlides: PropTypes.number.isRequired, // Actions required for the presenter toolbar actions: PropTypes.shape({ nextSlideHandler: PropTypes.func.isRequired, previousSlideHandler: PropTypes.func.isRequired, skipToSlideHandler: PropTypes.func.isRequired, }).isRequired, intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, zoomChanger: PropTypes.func.isRequired, fitToWidthHandler: PropTypes.func.isRequired, fitToWidth: PropTypes.bool.isRequired, fullscreenRef: PropTypes.instanceOf(Element), isFullscreen: PropTypes.bool.isRequired, zoom: PropTypes.number.isRequired, }; PresentationToolbar.defaultProps = { fullscreenRef: null, }; export default injectWbResizeEvent(injectIntl(PresentationToolbar));