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 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* @flow */
  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 ContactListItem from './ContactListItem';
  8. declare var interfaceConfig: Object;
  9. /**
  10. * React component for showing a list of current conference participants.
  11. *
  12. * @extends Component
  13. */
  14. class ContactListPanel extends Component<*> {
  15. /**
  16. * Default values for {@code ContactListPanel} component's properties.
  17. *
  18. * @static
  19. */
  20. static propTypes = {
  21. /**
  22. * The participants to show in the contact list.
  23. */
  24. _participants: PropTypes.array,
  25. /**
  26. * Whether or not participant avatars should be displayed.
  27. */
  28. _showAvatars: PropTypes.bool,
  29. /**
  30. * Invoked to obtain translated strings.
  31. */
  32. t: PropTypes.func
  33. };
  34. /**
  35. * Implements React's {@link Component#render()}.
  36. *
  37. * @inheritdoc
  38. */
  39. render() {
  40. const { _participants, t } = this.props;
  41. return (
  42. <div className = 'contact-list-panel'>
  43. <div className = 'title'>
  44. { t('contactlist', { count: _participants.length }) }
  45. </div>
  46. <ul id = 'contacts'>
  47. { this._renderContacts() }
  48. </ul>
  49. </div>
  50. );
  51. }
  52. /**
  53. * Renders React Elements for displaying information about each participant
  54. * in the contact list.
  55. *
  56. * @private
  57. * @returns {ReactElement[]}
  58. */
  59. _renderContacts() {
  60. const { t } = this.props;
  61. const meString = t('me');
  62. return this.props._participants.map(participant => {
  63. const { id, local, name } = participant;
  64. let displayName;
  65. // FIXME this duplicates the logic from SpeakerStats.js, but
  66. // currently it seems that the
  67. // interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME is freely used in
  68. // multiple other places. A proper fix should take care of all
  69. // usages. Also conference.js has getParticipantDisplayName which
  70. // generates HTML span making things even harder to be cleaned up
  71. // properly.
  72. if (local) {
  73. displayName
  74. = name ? `${name} (${meString})` : meString;
  75. } else {
  76. displayName
  77. = name ? name : interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME;
  78. }
  79. return (
  80. <ContactListItem
  81. avatarURI = { this.props._showAvatars
  82. ? getAvatarURL(participant) : null }
  83. id = { id }
  84. key = { id }
  85. name = { displayName } />
  86. );
  87. });
  88. }
  89. }
  90. /**
  91. * Maps (parts of) the Redux state to the associated {@code ContactListPanel}'s
  92. * props.
  93. *
  94. * @param {Object} state - The Redux state.
  95. * @private
  96. * @returns {{
  97. * _locked: boolean,
  98. * _participants: Array
  99. * }}
  100. */
  101. function _mapStateToProps(state) {
  102. return {
  103. _participants: getParticipants(state),
  104. _showAvatars: interfaceConfig.SHOW_CONTACTLIST_AVATARS
  105. };
  106. }
  107. export default translate(connect(_mapStateToProps)(ContactListPanel));