123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // @flow
-
- import { Component } from 'react';
-
- /**
- * {@code AbstractCaptions} properties.
- */
- export type AbstractCaptionsProps = {
-
- /**
- * Whether local participant is requesting to see subtitles.
- */
- _requestingSubtitles: boolean,
-
- /**
- * Transcript texts formatted with participant's name and final content.
- * Mapped by id just to have the keys for convenience during the rendering
- * process.
- */
- _transcripts: ?Map<string, string>
- };
-
- /**
- * Abstract React {@code Component} which can display speech-to-text results
- * from Jigasi as subtitles.
- */
- export class AbstractCaptions<P: AbstractCaptionsProps>
- extends Component<P> {
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {React$Element}
- */
- render() {
- const { _requestingSubtitles, _transcripts } = this.props;
-
- if (!_requestingSubtitles || !_transcripts || !_transcripts.size) {
- return null;
- }
-
- const paragraphs = [];
-
- for (const [ id, text ] of _transcripts) {
- paragraphs.push(this._renderParagraph(id, text));
- }
-
- return this._renderSubtitlesContainer(paragraphs);
- }
-
- /**
- * Renders the transcription text.
- *
- * @abstract
- * @param {string} id - The ID of the transcript message from which the
- * {@code text} has been created.
- * @param {string} text - Subtitles text formatted with the participant's
- * name.
- * @protected
- * @returns {React$Element} - The React element which displays the text.
- */
- _renderParagraph: (id: string, text: string) => React$Element<*>;
-
- /**
- * Renders the subtitles container.
- *
- * @abstract
- * @param {Array<React$Element>} paragraphs - An array of elements created
- * for each subtitle using the {@link _renderParagraph} method.
- * @protected
- * @returns {React$Element} - The subtitles container.
- */
- _renderSubtitlesContainer: (Array<React$Element<*>>) => React$Element<*>;
- }
-
- /**
- * Formats the transcript messages into text by prefixing participant's name to
- * avoid duplicating the effort on platform specific component.
- *
- * @param {Object} state - The redux state.
- * @private
- * @returns {Map<string, string>} - Formatted transcript subtitles mapped by
- * transcript message IDs.
- */
- function _constructTranscripts(state: Object): Map<string, string> {
- const { _transcriptMessages } = state['features/subtitles'];
- const transcripts = new Map();
-
- for (const [ id, transcriptMessage ] of _transcriptMessages) {
- if (transcriptMessage) {
- let text = `${transcriptMessage.participantName}: `;
-
- if (transcriptMessage.final) {
- text += transcriptMessage.final;
- } else {
- const stable = transcriptMessage.stable || '';
- const unstable = transcriptMessage.unstable || '';
-
- text += stable + unstable;
- }
-
- transcripts.set(id, text);
- }
- }
-
- return transcripts;
- }
-
- /**
- * Maps the transcriptionSubtitles in the redux state to the associated props of
- * {@code AbstractCaptions}.
- *
- * @param {Object} state - The redux state.
- * @private
- * @returns {{
- * _requestingSubtitles: boolean,
- * _transcripts: Map<string, string>
- * }}
- */
- export function _abstractMapStateToProps(state: Object) {
- const { _requestingSubtitles } = state['features/subtitles'];
- const transcripts = _constructTranscripts(state);
-
- return {
- _requestingSubtitles,
-
- // avoid rerenders by setting to props new empty Map instances.
- _transcripts: transcripts.size === 0 ? undefined : transcripts
- };
- }
|