UNPKG

labo-components

Version:
150 lines (130 loc) 4.99 kB
import React from 'react'; import PropTypes from 'prop-types'; import TranscriptUtil from '../../../util/TranscriptUtil'; import FlexPlayerUtil from '../../../util/FlexPlayerUtil'; import TimeUtil from "../../../util/TimeUtil"; import { VIEW_LIST, VIEW_WORDCLOUD } from '../ContentAnnotationsColumn'; import TimedList from './TimedList'; import WordCloud from './WordCloud'; import { sanitize } from '../../shared/WordCloudHelpers'; import MediaEvents from '../_MediaEvents'; /* This component shows ASR transcriptions in a TimedList or WordCloud */ export default class ASR extends React.PureComponent { constructor(props) { super(props); } /* ----------------------- RENDER LIST -------------------*/ //TODO update this to map from an array of TranscriptLines renderList = (mediaObject, transcript, searchTerm, mediaEvents) => { // convert transcript to item list for TimedList const items = transcript.lines.map((item, index) => ({ //TODO the ASR timings need to be fixed for DAAN/IMMIX, then this works properly and the old stuff can go id: 'ca_' + item.type + '_' + index, start : item.start, startLabel : TimeUtil.formatMillisToTime(item.start, mediaObject), data: item.text })); return ( <TimedList items={items} mediaEvents={mediaEvents} searchTerm={searchTerm} /> ); }; /* ----------------------- RENDER WORDCLOUD -------------------*/ renderWordCloud(transcript, searchTerm, mediaEvents, mediaObject) { // get raw word list from transcript const words = transcript.lines.reduce( (w, item) => w.concat(item.text.split(' ')), [] ); // When click on a word, onSeek the player to the next occurence of the given word // Start on the start of the ASR item for context const onWordClick = word => { // get current player position const pos = mediaEvents.getData(MediaEvents.PLAYER_POS); // get next occurence let hit = null; transcript.lines.some(item => { const itemStart = FlexPlayerUtil.timeRelativeToOnAir( item.start / 1000, mediaObject ); // if item in the future, or no first hit if (itemStart > pos || hit == null) { // sanitize the words const words = sanitize(item.text); word = word.replace('_', ' '); // if word exists if (words.indexOf(word) !== -1) { // store first hit if (!hit) { hit = item; } // if future hit, store and return if (itemStart > pos) { hit = item; return true; } } } return false; }); // check if an item was hit if (hit != null && mediaObject) { // Update player by triggering SET_PLAYER_POS event this.props.mediaEvents.trigger( MediaEvents.SET_PLAYER_POS, FlexPlayerUtil.timeRelativeToOnAir( hit.start / 1000, mediaObject ) ); } }; return ( <WordCloud words={words} mediaEvents={mediaEvents} size={100} searchTerm={searchTerm} onClick={onWordClick} /> ); } /* ----------------------- RENDER -------------------*/ render = () => { if (!this.props.activeMediaObject || !this.props.transcript) { return null; } switch (this.props.view) { case VIEW_LIST: return this.renderList( this.props.activeMediaObject, this.props.transcript, this.props.searchTerm, this.props.mediaEvents ); case VIEW_WORDCLOUD: return this.renderWordCloud( this.props.transcript, this.props.searchTerm, this.props.mediaEvents, this.props.activeMediaObject ); default: return null; } }; } ASR.propTypes = { searchTerm: PropTypes.string.isRequired, view: PropTypes.string.isRequired, resource: PropTypes.object.isRequired, activeMediaObject: PropTypes.object.isRequired, mediaEvents: PropTypes.object.isRequired, transcript: PropTypes.object };