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.

ContactListPanel.web.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import Button from '@atlaskit/button';
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { connect } from 'react-redux';
  5. import { translate } from '../../base/i18n';
  6. import { getAvatarURL, getParticipants } from '../../base/participants';
  7. import { openInviteDialog } from '../../invite';
  8. import ContactListItem from './ContactListItem';
  9. declare var interfaceConfig: Object;
  10. /**
  11. * React component for showing a list of current conference participants, the
  12. * current conference lock state, and a button to open the invite dialog.
  13. *
  14. * @extends Component
  15. */
  16. class ContactListPanel extends Component {
  17. /**
  18. * Default values for {@code ContactListPanel} component's properties.
  19. *
  20. * @static
  21. */
  22. static propTypes = {
  23. /**
  24. * Whether or not the conference is currently locked with a password.
  25. */
  26. _locked: PropTypes.bool,
  27. /**
  28. * The participants to show in the contact list.
  29. */
  30. _participants: PropTypes.array,
  31. /**
  32. * Invoked to open an invite dialog.
  33. */
  34. dispatch: PropTypes.func,
  35. /**
  36. * Invoked to obtain translated strings.
  37. */
  38. t: PropTypes.func
  39. };
  40. /**
  41. * Initializes a new {@code ContactListPanel} instance.
  42. *
  43. * @param {Object} props - The read-only properties with which the new
  44. * instance is to be initialized.
  45. */
  46. constructor(props) {
  47. super(props);
  48. // Bind event handler so it is only bound once for every instance.
  49. this._onOpenInviteDialog = this._onOpenInviteDialog.bind(this);
  50. }
  51. /**
  52. * Implements React's {@link Component#render()}.
  53. *
  54. * @inheritdoc
  55. */
  56. render() {
  57. const { _locked, _participants, t } = this.props;
  58. return (
  59. <div className = 'contact-list-panel'>
  60. <div className = 'title'>
  61. { t('contactlist', { pcount: _participants.length }) }
  62. </div>
  63. <div className = 'sideToolbarBlock first'>
  64. <Button
  65. appearance = 'primary'
  66. className = 'contact-list-panel-invite-button'
  67. id = 'addParticipantsBtn'
  68. onClick = { this._onOpenInviteDialog }
  69. type = 'button'>
  70. { t('addParticipants') }
  71. </Button>
  72. <div>
  73. { _locked
  74. ? this._renderLockedMessage()
  75. : this._renderUnlockedMessage() }
  76. </div>
  77. </div>
  78. <ul id = 'contacts'>
  79. { this._renderContacts() }
  80. </ul>
  81. </div>
  82. );
  83. }
  84. /**
  85. * Dispatches an action to open an invite dialog.
  86. *
  87. * @private
  88. * @returns {void}
  89. */
  90. _onOpenInviteDialog() {
  91. this.props.dispatch(openInviteDialog());
  92. }
  93. /**
  94. * Renders React Elements for displaying information about each participant
  95. * in the contact list.
  96. *
  97. * @private
  98. * @returns {ReactElement[]}
  99. */
  100. _renderContacts() {
  101. return this.props._participants.map(participant => {
  102. const { id, name } = participant;
  103. return (
  104. <ContactListItem
  105. avatarURI = { interfaceConfig.SHOW_CONTACTLIST_AVATARS
  106. ? getAvatarURL(participant) : null }
  107. id = { id }
  108. key = { id }
  109. name = { name } />
  110. );
  111. });
  112. }
  113. /**
  114. * Renders a React Element for informing the conference is currently locked.
  115. *
  116. * @private
  117. * @returns {ReactElement}
  118. */
  119. _renderLockedMessage() {
  120. return (
  121. <p
  122. className = 'form-control__hint form-control_full-width'
  123. id = 'contactListroomLocked'>
  124. <span className = 'icon-security-locked' />
  125. <span>{ this.props.t('roomLocked') }</span>
  126. </p>
  127. );
  128. }
  129. /**
  130. * Renders a React Element for informing the conference is currently not
  131. * locked.
  132. *
  133. * @private
  134. * @returns {ReactElement}
  135. */
  136. _renderUnlockedMessage() {
  137. return (
  138. <p
  139. className = 'form-control__hint form-control_full-width'
  140. id = 'contactListroomUnlocked'>
  141. <span className = 'icon-security' />
  142. <span>{ this.props.t('roomUnlocked') }</span>
  143. </p>
  144. );
  145. }
  146. }
  147. /**
  148. * Maps (parts of) the Redux state to the associated {@code ContactListPanel}'s
  149. * props.
  150. *
  151. * @param {Object} state - The Redux state.
  152. * @private
  153. * @returns {{
  154. * _locked: boolean,
  155. * _participants: Array
  156. * }}
  157. */
  158. function _mapStateToProps(state) {
  159. return {
  160. _locked: state['features/base/conference'].locked,
  161. _participants: getParticipants(state)
  162. };
  163. }
  164. export default translate(connect(_mapStateToProps)(ContactListPanel));