import React, { Component } from 'react'; import PropTypes from 'prop-types'; import RenderInBrowser from 'react-render-in-browser'; import { getFormattedColor, denormalizeCoord } from '../helpers'; const DRAW_END = Meteor.settings.public.whiteboard.annotations.status.end; export default class TextDrawComponent extends Component { static getViewerStyles(results) { const styles = { WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)', pointerEvents: 'none', fontStyle: 'normal', fontVariant: 'normal', fontWeight: 'normal', fontStretch: 'normal', lineHeight: 'normal', fontFamily: 'Arial', whiteSpace: 'pre-wrap', wordWrap: 'break-word', wordBreak: 'normal', textAlign: 'left', margin: 0, // padding to match the border of the text area and the flash client's default 1px padding padding: 1, color: results.fontColor, fontSize: results.calcedFontSize, }; return styles; } static getPresenterStyles(results) { const isFireFox = document.body.className.includes('firefox'); const isSarafi = document.body.className.includes('safari'); const styles = { fontFamily: 'Arial', border: `${isFireFox || isSarafi ? '2px' : '1px'} solid black`, width: '100%', height: '100%', resize: 'none', overflow: 'hidden', outline: 'none', color: results.fontColor, fontSize: results.calcedFontSize, padding: '0', }; return styles; } constructor() { super(); this.handleFocus = this.handleFocus.bind(this); this.handleOnBlur = this.handleOnBlur.bind(this); this.onChangeHandler = this.onChangeHandler.bind(this); } componentDidMount() { const { isActive, annotation } = this.props; // iOS doesn't show the keyboard if the input field was focused by event NOT invoked by a user // by it still technically moves the focus there // that's why we have a separate case for iOS - we don't focus here automatically // but we focus on the next "tap" invoked by a user const iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0; const Android = navigator.userAgent.toLowerCase().indexOf('android') > -1; // unsupported Firefox condition (not iOS though) can be removed when FF 59 is released // see https://bugzilla.mozilla.org/show_bug.cgi?id=1409113 const unsupportedFirefox = navigator.userAgent.indexOf('Firefox/57') !== -1 || navigator.userAgent.indexOf('Firefox/58') !== -1; if (iOS || (Android && unsupportedFirefox)) { return; } if (isActive && annotation.status !== DRAW_END) { this.handleFocus(); } } shouldComponentUpdate(nextProps) { const { version, isActive } = this.props; return version !== nextProps.version || isActive !== nextProps.isActive; } // If the user is drawing a text shape and clicks Undo - reset textShapeId componentWillUnmount() { const { isActive, resetTextShapeActiveId } = this.props; if (isActive) { resetTextShapeActiveId(); } } onChangeHandler(event) { const { setTextShapeValue } = this.props; setTextShapeValue(event.target.value); } getCoordinates() { const { annotation, slideWidth, slideHeight } = this.props; const { x, y, textBoxWidth, textBoxHeight, fontColor, fontSize, calcedFontSize, text, } = annotation; const _x = denormalizeCoord(x, slideWidth); const _y = denormalizeCoord(y, slideHeight); const _width = denormalizeCoord(textBoxWidth, slideWidth); const _height = denormalizeCoord(textBoxHeight, slideHeight); const _fontColor = getFormattedColor(fontColor); const _fontSize = fontSize; const _calcedFontSize = (calcedFontSize / 100) * slideHeight; const _text = text; return { x: _x, y: _y, text: _text, width: _width, height: _height, fontSize: _fontSize, fontColor: _fontColor, calcedFontSize: _calcedFontSize, }; } handleOnBlur() { const { annotation } = this.props; // it'd be better to use ref to focus onBlur (handleFocus), but it doesn't want to work in FF // so we are back to the old way of doing things, getElementById and setTimeout const node = document.getElementById(annotation.id); setTimeout(() => { node.focus(); }, 1); } handleFocus() { // Explicitly focus the text input using the raw DOM API this.textArea.focus(); } renderViewerTextShape(results) { const { annotation } = this.props; const styles = TextDrawComponent.getViewerStyles(results); return (

{results.text}

); } renderPresenterTextShape(results) { const { annotation } = this.props; const styles = TextDrawComponent.getPresenterStyles(results); return (