Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AbstractCaptions.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // @flow
  2. import { Component } from 'react';
  3. /**
  4. * {@code AbstractCaptions} properties.
  5. */
  6. export type AbstractCaptionsProps = {
  7. /**
  8. * Whether local participant is requesting to see subtitles.
  9. */
  10. _requestingSubtitles: boolean,
  11. /**
  12. * Transcript texts formatted with participant's name and final content.
  13. * Mapped by id just to have the keys for convenience during the rendering
  14. * process.
  15. */
  16. _transcripts: ?Map<string, string>
  17. };
  18. /**
  19. * Abstract React {@code Component} which can display speech-to-text results
  20. * from Jigasi as subtitles.
  21. */
  22. export class AbstractCaptions<P: AbstractCaptionsProps>
  23. extends Component<P> {
  24. /**
  25. * Implements React's {@link Component#render()}.
  26. *
  27. * @inheritdoc
  28. * @returns {React$Element}
  29. */
  30. render() {
  31. const { _requestingSubtitles, _transcripts } = this.props;
  32. if (!_requestingSubtitles || !_transcripts || !_transcripts.size) {
  33. return null;
  34. }
  35. const paragraphs = [];
  36. for (const [ id, text ] of _transcripts) {
  37. paragraphs.push(this._renderParagraph(id, text));
  38. }
  39. return this._renderSubtitlesContainer(paragraphs);
  40. }
  41. /**
  42. * Renders the transcription text.
  43. *
  44. * @abstract
  45. * @param {string} id - The ID of the transcript message from which the
  46. * {@code text} has been created.
  47. * @param {string} text - Subtitles text formatted with the participant's
  48. * name.
  49. * @protected
  50. * @returns {React$Element} - The React element which displays the text.
  51. */
  52. _renderParagraph: (id: string, text: string) => React$Element<*>;
  53. /**
  54. * Renders the subtitles container.
  55. *
  56. * @abstract
  57. * @param {Array<React$Element>} paragraphs - An array of elements created
  58. * for each subtitle using the {@link _renderParagraph} method.
  59. * @protected
  60. * @returns {React$Element} - The subtitles container.
  61. */
  62. _renderSubtitlesContainer: (Array<React$Element<*>>) => React$Element<*>;
  63. }
  64. /**
  65. * Formats the transcript messages into text by prefixing participant's name to
  66. * avoid duplicating the effort on platform specific component.
  67. *
  68. * @param {Object} state - The redux state.
  69. * @private
  70. * @returns {Map<string, string>} - Formatted transcript subtitles mapped by
  71. * transcript message IDs.
  72. */
  73. function _constructTranscripts(state: Object): Map<string, string> {
  74. const { _transcriptMessages } = state['features/subtitles'];
  75. const transcripts = new Map();
  76. for (const [ id, transcriptMessage ] of _transcriptMessages) {
  77. if (transcriptMessage) {
  78. let text = `${transcriptMessage.participantName}: `;
  79. if (transcriptMessage.final) {
  80. text += transcriptMessage.final;
  81. } else {
  82. const stable = transcriptMessage.stable || '';
  83. const unstable = transcriptMessage.unstable || '';
  84. text += stable + unstable;
  85. }
  86. transcripts.set(id, text);
  87. }
  88. }
  89. return transcripts;
  90. }
  91. /**
  92. * Maps the transcriptionSubtitles in the redux state to the associated props of
  93. * {@code AbstractCaptions}.
  94. *
  95. * @param {Object} state - The redux state.
  96. * @private
  97. * @returns {{
  98. * _requestingSubtitles: boolean,
  99. * _transcripts: Map<string, string>
  100. * }}
  101. */
  102. export function _abstractMapStateToProps(state: Object) {
  103. const { _requestingSubtitles } = state['features/subtitles'];
  104. const transcripts = _constructTranscripts(state);
  105. return {
  106. _requestingSubtitles,
  107. // avoid rerenders by setting to props new empty Map instances.
  108. _transcripts: transcripts.size === 0 ? undefined : transcripts
  109. };
  110. }