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.

BroadcastsDropdown.web.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import {
  2. DropdownItem,
  3. DropdownItemGroup,
  4. DropdownMenuStateless
  5. } from '@atlaskit/dropdown-menu';
  6. import React, { PureComponent } from 'react';
  7. import PropTypes from 'prop-types';
  8. import { translate } from '../../../base/i18n';
  9. /**
  10. * A dropdown to select a YouTube broadcast.
  11. *
  12. * @extends Component
  13. */
  14. class BroadcastsDropdown extends PureComponent {
  15. /**
  16. * Default values for {@code StreamKeyForm} component's properties.
  17. *
  18. * @static
  19. */
  20. static defaultProps = {
  21. broadcasts: []
  22. };
  23. /**
  24. * {@code BroadcastsDropdown} component's property types.
  25. */
  26. static propTypes = {
  27. /**
  28. * Broadcasts available for selection. Each broadcast item should be an
  29. * object with a title for display in the dropdown and a boundStreamID
  30. * to return in the {@link onBroadcastSelected} callback.
  31. */
  32. broadcasts: PropTypes.array,
  33. /**
  34. * Callback invoked when an item in the dropdown is selected. The
  35. * selected broadcast's boundStreamID will be passed back.
  36. */
  37. onBroadcastSelected: PropTypes.func,
  38. /**
  39. * The boundStreamID of the broadcast that should display as selected in
  40. * the dropdown.
  41. */
  42. selectedBroadcastID: PropTypes.string,
  43. /**
  44. * Invoked to obtain translated strings.
  45. */
  46. t: PropTypes.func
  47. };
  48. /**
  49. * The initial state of a {@code StreamKeyForm} instance.
  50. *
  51. * @type {{
  52. * isDropdownOpen: boolean
  53. * }}
  54. */
  55. state = {
  56. isDropdownOpen: false
  57. };
  58. /**
  59. * Initializes a new {@code BroadcastsDropdown} instance.
  60. *
  61. * @param {Props} props - The React {@code Component} props to initialize
  62. * the new {@code BroadcastsDropdown} instance with.
  63. */
  64. constructor(props) {
  65. super(props);
  66. // Bind event handlers so they are only bound once per instance.
  67. this._onDropdownOpenChange = this._onDropdownOpenChange.bind(this);
  68. this._onSelect = this._onSelect.bind(this);
  69. }
  70. /**
  71. * Implements React's {@link Component#render()}.
  72. *
  73. * @inheritdoc
  74. * @returns {ReactElement}
  75. */
  76. render() {
  77. const { broadcasts, selectedBroadcastID, t } = this.props;
  78. const dropdownItems = broadcasts.map(broadcast =>
  79. // eslint-disable-next-line react/jsx-wrap-multilines
  80. <DropdownItem
  81. key = { broadcast.boundStreamID }
  82. // eslint-disable-next-line react/jsx-no-bind
  83. onClick = { () => this._onSelect(broadcast.boundStreamID) }>
  84. { broadcast.title }
  85. </DropdownItem>
  86. );
  87. const selected = this.props.broadcasts.find(
  88. broadcast => broadcast.boundStreamID === selectedBroadcastID);
  89. const triggerText = (selected && selected.title)
  90. || t('liveStreaming.choose');
  91. return (
  92. <div className = 'broadcast-dropdown'>
  93. <DropdownMenuStateless
  94. isOpen = { this.state.isDropdownOpen }
  95. onItemActivated = { this._onSelect }
  96. onOpenChange = { this._onDropdownOpenChange }
  97. shouldFitContainer = { true }
  98. trigger = { triggerText }
  99. triggerButtonProps = {{
  100. className: 'broadcast-dropdown-trigger',
  101. shouldFitContainer: true
  102. }}
  103. triggerType = 'button'>
  104. <DropdownItemGroup>
  105. { dropdownItems }
  106. </DropdownItemGroup>
  107. </DropdownMenuStateless>
  108. </div>
  109. );
  110. }
  111. /**
  112. * Transforms the passed in broadcasts into an array of objects that can
  113. * be parsed by {@code DropdownMenuStateless}.
  114. *
  115. * @param {Array<Object>} broadcasts - The YouTube broadcasts to display.
  116. * @private
  117. * @returns {Array<Object>}
  118. */
  119. _formatBroadcasts(broadcasts) {
  120. return broadcasts.map(broadcast => {
  121. return {
  122. content: broadcast.title,
  123. value: broadcast
  124. };
  125. });
  126. }
  127. /**
  128. * Sets the dropdown to be displayed or not based on the passed in event.
  129. *
  130. * @param {Object} dropdownEvent - The event passed from
  131. * {@code DropdownMenuStateless} indicating if the dropdown should be open
  132. * or closed.
  133. * @private
  134. * @returns {void}
  135. */
  136. _onDropdownOpenChange(dropdownEvent) {
  137. this.setState({
  138. isDropdownOpen: dropdownEvent.isOpen
  139. });
  140. }
  141. /**
  142. * Callback invoked when an item has been clicked in the dropdown menu.
  143. *
  144. * @param {Object} boundStreamID - The bound stream ID for the selected
  145. * broadcast.
  146. * @returns {void}
  147. */
  148. _onSelect(boundStreamID) {
  149. this.props.onBroadcastSelected(boundStreamID);
  150. }
  151. }
  152. export default translate(BroadcastsDropdown);