StartVideoModal.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import ReactHtmlParser from 'react-html-parser';
  4. import './StartVideoModal.scss';
  5. import { SVGIcon } from 'ca-ui-toolkit';
  6. import play32 from '@ba-ui-toolkit/ba-graphics/dist/icons/play_32.svg';
  7. import { Dialog } from 'ca-ui-toolkit';
  8. const DASHBOARD_TUTORIAL_IMG_PATH = 'images/tutVideo_Dashboard.png';
  9. const EXPLORE_TUTORIAL_IMG_PATH = 'images/tutVideo_Explore.png';
  10. const OVERVIEW_TUTORIAL_IMG_PATH = 'images/tutVideo_Overview.png';
  11. /*
  12. Metadata for three videos:
  13. - Thumbnail & title are hard-coded in this repo
  14. - For video replacement, contact Reimar S. to change the mapping of tiny URLs
  15. */
  16. const metadata = {
  17. 0:{
  18. thumbnail: OVERVIEW_TUTORIAL_IMG_PATH,
  19. link: 'https://ibm.biz/BdzbpD',
  20. title_string: 'modal_how_video_title_overview'
  21. },
  22. 1:{
  23. thumbnail: DASHBOARD_TUTORIAL_IMG_PATH,
  24. link: 'https://ibm.biz/BdzbpF',
  25. title_string: 'modal_how_video_title_dashboard'
  26. },
  27. 2:{
  28. thumbnail: EXPLORE_TUTORIAL_IMG_PATH,
  29. link: 'https://ibm.biz/BdzbpR',
  30. title_string: 'modal_how_video_title_exploration'
  31. }
  32. };
  33. export class StartVideoModal extends Component {
  34. static propTypes = {
  35. /** Handler to close the modal */
  36. closeHandler: PropTypes.func.isRequired,
  37. /** A copy of the i18n object used to translate strings */
  38. stringGetter: PropTypes.object
  39. };
  40. state = {
  41. selectedVideo: 0,
  42. playing: false
  43. };
  44. // Click handler called when user clicks on the video option
  45. _selectVideo = (index) => {
  46. this.setState({
  47. playing: false,
  48. selectedVideo: index
  49. });
  50. }
  51. // Click handler called when user clicks play button
  52. _playVideo = () => {
  53. this.setState({ playing: true });
  54. }
  55. // Return the generic youtube iframe for embedded video
  56. _youtubeVideoSrc = (link) => {
  57. return (<iframe
  58. width="756"
  59. height="424"
  60. src={link}
  61. frameBorder="0"
  62. allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
  63. allowFullScreen>
  64. </iframe>);
  65. }
  66. // Handler to open the video via tabbing action
  67. _selectVideoViaTabbing = (e, index) => {
  68. e.stopPropagation();
  69. // If not a shift click, ctrl click or a right click or the user pressed enter on the context menu
  70. if((e.type == 'click' && !e.shiftKey && !e.ctrlKey && e.nativeEvent.which !== 3) || (e.type=='keyup' && e.keyCode === 13)) {
  71. e.persist();
  72. this._selectVideo(index);
  73. }
  74. }
  75. // Handler to play the video via tabbing action
  76. _playVideoViaTabbing = (e) => {
  77. e.stopPropagation();
  78. // If not a shift click, ctrl click or a right click or the user pressed enter on the context menu
  79. if((e.type == 'click' && !e.shiftKey && !e.ctrlKey && e.nativeEvent.which !== 3) || (e.type=='keyup' && e.keyCode === 13)) {
  80. e.persist();
  81. this._playVideo();
  82. }
  83. }
  84. render() {
  85. const dialogProps = {
  86. size: 'large',
  87. width: '804px',
  88. minWidth: '804px',
  89. clickaway: true,
  90. theme: 'ba-theme-default',
  91. className: 'startVideoModal_dialog',
  92. style: { 'padding-bottom': '64px' },
  93. startingFocusIndex: -1
  94. };
  95. const { stringGetter } = this.props;
  96. const mainScreen = this.state.playing ? (<div className='largeVideoThumbnail' >{this._youtubeVideoSrc(metadata[this.state.selectedVideo].link)}</div>):
  97. (<div className='largeVideoThumbnail'>
  98. <img src={metadata[this.state.selectedVideo].thumbnail}></img>
  99. <div className='playIndicator' tabIndex='1' onKeyUp={(e) => {this._playVideoViaTabbing(e);}} onClick={() => this._playVideo()}>
  100. {stringGetter.get('modal_how_play')} <SVGIcon className='playIcon' size='large' iconId={play32.id} />
  101. </div>
  102. </div>);
  103. return (<Dialog
  104. {...dialogProps}
  105. onClose={() => {
  106. this.props.closeHandler();
  107. }}
  108. >
  109. <Dialog.Header>{stringGetter.get('modal_how_title')}</Dialog.Header>
  110. <Dialog.Body>
  111. <div className='mainVideoSection'>
  112. {mainScreen}
  113. </div>
  114. <div className='videoOptionSection'>
  115. <div tabIndex='1' onKeyUp={(e) => {this._selectVideoViaTabbing(e, 0);}} onClick={() => this._selectVideo(0)} className={this.state.selectedVideo === 0 ? 'optionSelected optionBlock optionBlockSeprator' : 'optionBlock optionBlockSeprator'}>
  116. <img className='smallVideoThumbnail' src={ metadata[0].thumbnail }></img>
  117. <div className='smallVideoDescription' >
  118. <label className='videoTitle'>{ stringGetter.get(metadata[0].title_string) }</label>
  119. </div>
  120. </div>
  121. <div tabIndex='1' onKeyUp={(e) => {this._selectVideoViaTabbing(e, 1);}} onClick={() => this._selectVideo(1)} className={this.state.selectedVideo === 1 ? 'optionSelected optionBlock optionBlockSeprator' : 'optionBlock optionBlockSeprator'}>
  122. <img className='smallVideoThumbnail' src={ metadata[1].thumbnail }></img>
  123. <div className='smallVideoDescription'>
  124. <label className='videoTitle' >{ stringGetter.get(metadata[1].title_string) }</label>
  125. </div>
  126. </div>
  127. <div tabIndex='1' onKeyUp={(e) => {this._selectVideoViaTabbing(e, 2);}} onClick={() => this._selectVideo(2)} className={this.state.selectedVideo === 2 ? 'optionSelected optionBlock' : 'optionBlock' }>
  128. <img className='smallVideoThumbnail' src={ metadata[2].thumbnail }></img>
  129. <div className='smallVideoDescription'>
  130. <label className='videoTitle'>{ stringGetter.get(metadata[2].title_string) }</label>
  131. </div>
  132. </div>
  133. </div>
  134. </Dialog.Body>
  135. </Dialog>);
  136. }
  137. }