Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

InfoDialogButton.web.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* global interfaceConfig */
  2. import InlineDialog from '@atlaskit/inline-dialog';
  3. import PropTypes from 'prop-types';
  4. import React, { Component } from 'react';
  5. import { connect } from 'react-redux';
  6. import { ToolbarButton, TOOLTIP_TO_POPUP_POSITION } from '../../toolbox';
  7. import { setInfoDialogVisibility } from '../actions';
  8. import { InfoDialog } from './info-dialog';
  9. const { INITIAL_TOOLBAR_TIMEOUT } = interfaceConfig;
  10. /**
  11. * A configuration object to describe how {@code ToolbarButton} should render
  12. * the button.
  13. *
  14. * @type {object}
  15. */
  16. const DEFAULT_BUTTON_CONFIGURATION = {
  17. buttonName: 'info',
  18. classNames: [ 'button', 'icon-info' ],
  19. enabled: true,
  20. id: 'toolbar_button_info',
  21. tooltipKey: 'info.tooltip'
  22. };
  23. /**
  24. * A React Component for displaying a button which opens a dialog with
  25. * information about the conference and with ways to invite people.
  26. *
  27. * @extends Component
  28. */
  29. class InfoDialogButton extends Component {
  30. /**
  31. * {@code InfoDialogButton} component's property types.
  32. *
  33. * @static
  34. */
  35. static propTypes = {
  36. /**
  37. * Whether or not the {@code InfoDialog} should close by itself after a
  38. * a timeout.
  39. */
  40. _shouldAutoClose: PropTypes.bool,
  41. /**
  42. * Whether or not {@code InfoDialog} should be displayed.
  43. */
  44. _showDialog: PropTypes.bool,
  45. /**
  46. * Whether or not the toolbox, in which this component exists, are
  47. * visible.
  48. */
  49. _toolboxVisible: PropTypes.bool,
  50. /**
  51. * Invoked to toggle display of the info dialog
  52. */
  53. dispatch: PropTypes.func,
  54. /**
  55. * From which side tooltips should display. Will be re-used for
  56. * displaying the inline dialog for video quality adjustment.
  57. */
  58. tooltipPosition: PropTypes.string
  59. };
  60. /**
  61. * Initializes new {@code ToolbarButtonWithDialog} instance.
  62. *
  63. * @param {Object} props - The read-only properties with which the new
  64. * instance is to be initialized.
  65. */
  66. constructor(props) {
  67. super(props);
  68. /**
  69. * The timeout to automatically hide the {@code InfoDialog} if it has
  70. * not been interacted with.
  71. *
  72. * @type {timeoutID}
  73. */
  74. this._autoHideDialogTimeout = null;
  75. // Bind event handlers so they are only bound once for every instance.
  76. this._onDialogClose = this._onDialogClose.bind(this);
  77. this._onDialogMouseOver = this._onDialogMouseOver.bind(this);
  78. this._onDialogToggle = this._onDialogToggle.bind(this);
  79. }
  80. /**
  81. * Set a timeout to automatically hide the {@code InfoDialog}.
  82. *
  83. * @inheritdoc
  84. */
  85. componentDidMount() {
  86. if (this.props._shouldAutoClose) {
  87. this._setAutoCloseTimeout();
  88. }
  89. }
  90. /**
  91. * Set or clear the timeout to automatically hide the {@code InfoDialog}.
  92. *
  93. * @inheritdoc
  94. */
  95. componentDidUpdate(prevProps) {
  96. // If the _shouldAutoClose flag has been updated to be true then make
  97. // sure to set _autoHideDialogTimeout.
  98. if (this.props._shouldAutoClose && !prevProps._shouldAutoClose) {
  99. this._setAutoCloseTimeout();
  100. } else {
  101. this._clearAutoCloseTimeout();
  102. }
  103. }
  104. /**
  105. * Update the visibility of the {@code InfoDialog}.
  106. *
  107. * @inheritdoc
  108. */
  109. componentWillReceiveProps(nextProps) {
  110. // Ensure the dialog is closed when the toolbox becomes hidden.
  111. if (nextProps._showDialog && !nextProps._toolboxVisible) {
  112. this._onDialogClose();
  113. }
  114. }
  115. /**
  116. * Clear the timeout to automatically show the {@code InfoDialog}.
  117. *
  118. * @inheritdoc
  119. */
  120. componentWillUnmount() {
  121. this._clearAutoCloseTimeout();
  122. }
  123. /**
  124. * Implements React's {@link Component#render()}.
  125. *
  126. * @inheritdoc
  127. * @returns {ReactElement}
  128. */
  129. render() {
  130. const { _showDialog, _toolboxVisible, tooltipPosition } = this.props;
  131. const buttonConfiguration = {
  132. ...DEFAULT_BUTTON_CONFIGURATION,
  133. classNames: [
  134. ...DEFAULT_BUTTON_CONFIGURATION.classNames,
  135. _showDialog ? 'toggled button-active' : ''
  136. ]
  137. };
  138. return (
  139. <InlineDialog
  140. content = { <InfoDialog
  141. onClose = { this._onDialogClose }
  142. onMouseOver = { this._onDialogMouseOver } /> }
  143. isOpen = { _toolboxVisible && _showDialog }
  144. onClose = { this._onDialogClose }
  145. position = { TOOLTIP_TO_POPUP_POSITION[tooltipPosition] }>
  146. <ToolbarButton
  147. button = { buttonConfiguration }
  148. onClick = { this._onDialogToggle }
  149. tooltipPosition = { tooltipPosition } />
  150. </InlineDialog>
  151. );
  152. }
  153. /**
  154. * Cancels the timeout to automatically hide the {@code InfoDialog}.
  155. *
  156. * @private
  157. * @returns {void}
  158. */
  159. _clearAutoCloseTimeout() {
  160. clearTimeout(this._autoHideDialogTimeout);
  161. this._autoHideDialogTimeout = null;
  162. }
  163. /**
  164. * Hides {@code InfoDialog}.
  165. *
  166. * @private
  167. * @returns {void}
  168. */
  169. _onDialogClose() {
  170. this.props.dispatch(setInfoDialogVisibility(false));
  171. }
  172. /**
  173. * Cancels the timeout to automatically hide the {@code InfoDialog}.
  174. *
  175. * @private
  176. * @returns {void}
  177. */
  178. _onDialogMouseOver() {
  179. this._clearAutoCloseTimeout();
  180. }
  181. /**
  182. * Toggles the display of {@code InfoDialog}.
  183. *
  184. * @private
  185. * @returns {void}
  186. */
  187. _onDialogToggle() {
  188. this.props.dispatch(setInfoDialogVisibility(!this.props._showDialog));
  189. }
  190. /**
  191. * Set a timeout to automatically hide the {@code InfoDialog}.
  192. *
  193. * @private
  194. * @returns {void}
  195. */
  196. _setAutoCloseTimeout() {
  197. this._clearAutoCloseTimeout();
  198. this._autoHideDialogTimeout = setTimeout(() => {
  199. if (this.props._showDialog) {
  200. this._onDialogClose();
  201. }
  202. }, INITIAL_TOOLBAR_TIMEOUT);
  203. }
  204. }
  205. /**
  206. * Maps (parts of) the Redux state to the associated {@code InfoDialogButton}
  207. * component's props.
  208. *
  209. * @param {Object} state - The Redux state.
  210. * @private
  211. * @returns {{
  212. * _shouldAutoClose: boolean,
  213. * _showDialog: boolean,
  214. * _toolboxVisible: boolean
  215. * }}
  216. */
  217. function _mapStateToProps(state) {
  218. const {
  219. infoDialogVisible,
  220. infoDialogWillAutoClose
  221. } = state['features/invite'];
  222. return {
  223. _shouldAutoClose: infoDialogWillAutoClose,
  224. _showDialog: infoDialogVisible,
  225. _toolboxVisible: state['features/toolbox'].visible
  226. };
  227. }
  228. export default connect(_mapStateToProps)(InfoDialogButton);