You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

InfoDialog.web.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import React, { Component } from 'react';
  2. import { connect } from 'react-redux';
  3. import PropTypes from 'prop-types';
  4. import { getInviteURL } from '../../base/connection';
  5. import { translate } from '../../base/i18n';
  6. import { openAddPeopleDialog } from '../actions';
  7. const logger = require('jitsi-meet-logger').getLogger(__filename);
  8. declare var interfaceConfig: Object;
  9. /**
  10. * A React Component with the contents for a dialog that shows information about
  11. * the current conference and provides ways to invite other participants.
  12. *
  13. * @extends Component
  14. */
  15. class InfoDialog extends Component {
  16. /**
  17. * {@code InfoDialog} component's property types.
  18. *
  19. * @static
  20. */
  21. static propTypes = {
  22. /**
  23. * The current url of the conference to be copied onto the clipboard.
  24. */
  25. _inviteURL: PropTypes.string,
  26. /**
  27. * Whether or not the link to open the {@code AddPeopleDialog} should be
  28. * displayed.
  29. */
  30. _showAddPeople: PropTypes.bool,
  31. /**
  32. * Invoked to open a dialog for adding participants to the conference.
  33. */
  34. dispatch: PropTypes.func,
  35. /**
  36. * Callback invoked when the dialog should be closed.
  37. */
  38. onClose: PropTypes.func,
  39. /**
  40. * Callback invoked when a mouse-related event has been detected.
  41. */
  42. onMouseOver: PropTypes.func,
  43. /**
  44. * Invoked to obtain translated strings.
  45. */
  46. t: PropTypes.func
  47. };
  48. /**
  49. * Initializes new {@code InfoDialog} instance.
  50. *
  51. * @param {Object} props - The read-only properties with which the new
  52. * instance is to be initialized.
  53. */
  54. constructor(props) {
  55. super(props);
  56. /**
  57. * The internal reference to the DOM/HTML element backing the React
  58. * {@code Component} input. It is necessary for the implementation
  59. * of copying to the clipboard.
  60. *
  61. * @private
  62. * @type {HTMLInputElement}
  63. */
  64. this._copyElement = null;
  65. // Bind event handlers so they are only bound once for every instance.
  66. this._onCopyInviteURL = this._onCopyInviteURL.bind(this);
  67. this._onOpenInviteDialog = this._onOpenInviteDialog.bind(this);
  68. this._setCopyElement = this._setCopyElement.bind(this);
  69. }
  70. /**
  71. * Implements React's {@link Component#render()}.
  72. *
  73. * @inheritdoc
  74. * @returns {ReactElement}
  75. */
  76. render() {
  77. return (
  78. <div
  79. className = 'info-dialog'
  80. onMouseOver = { this.props.onMouseOver } >
  81. <div className = 'info-dialog-column'>
  82. <h4 className = 'info-dialog-icon'>
  83. <i className = 'icon-info' />
  84. </h4>
  85. </div>
  86. <div className = 'info-dialog-column'>
  87. <div className = 'info-dialog-title'>
  88. { this.props.t('info.title') }
  89. </div>
  90. <div
  91. className = 'info-dialog-conference-url'
  92. ref = { this._inviteUrlElement }>
  93. { this.props._inviteURL }
  94. <input
  95. className = 'info-dialog-copy-element'
  96. readOnly = { true }
  97. ref = { this._setCopyElement }
  98. tabIndex = '-1'
  99. value = { this.props._inviteURL } />
  100. </div>
  101. <div className = 'info-dialog-action-links'>
  102. <div className = 'info-dialog-action-link'>
  103. <a onClick = { this._onCopyInviteURL }>
  104. { this.props.t('info.copy') }
  105. </a>
  106. </div>
  107. { this.props._showAddPeople
  108. ? <div className = 'info-dialog-action-link'>
  109. <a onClick = { this._onOpenInviteDialog }>
  110. { this.props.t('info.invite', {
  111. app: interfaceConfig.ADD_PEOPLE_APP_NAME
  112. }) }
  113. </a>
  114. </div>
  115. : null }
  116. </div>
  117. </div>
  118. </div>
  119. );
  120. }
  121. /**
  122. * Callback invoked to copy the contents of {@code this._copyElement} to the
  123. * clipboard.
  124. *
  125. * @private
  126. * @returns {void}
  127. */
  128. _onCopyInviteURL() {
  129. try {
  130. this._copyElement.select();
  131. document.execCommand('copy');
  132. this._copyElement.blur();
  133. } catch (err) {
  134. logger.error('error when copying the text', err);
  135. }
  136. }
  137. /**
  138. * Callback invoked to open the {@code AddPeople} dialog.
  139. *
  140. * @private
  141. * @returns {void}
  142. */
  143. _onOpenInviteDialog() {
  144. this.props.dispatch(openAddPeopleDialog());
  145. if (this.props.onClose) {
  146. this.props.onClose();
  147. }
  148. }
  149. /**
  150. * Sets the internal reference to the DOM/HTML element backing the React
  151. * {@code Component} input.
  152. *
  153. * @param {HTMLInputElement} element - The DOM/HTML element for this
  154. * {@code Component}'s input.
  155. * @private
  156. * @returns {void}
  157. */
  158. _setCopyElement(element) {
  159. this._copyElement = element;
  160. }
  161. }
  162. /**
  163. * Maps (parts of) the Redux state to the associated props for the
  164. * {@code InfoDialog} component.
  165. *
  166. * @param {Object} state - The Redux state.
  167. * @private
  168. * @returns {{
  169. * _inviteURL: string
  170. * }}
  171. */
  172. function _mapStateToProps(state) {
  173. return {
  174. _inviteURL: getInviteURL(state),
  175. _showAddPeople: !state['features/jwt'].isGuest
  176. };
  177. }
  178. export default translate(connect(_mapStateToProps)(InfoDialog));