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.

Conference.web.js 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* global interfaceConfig */
  2. import React, { Component } from 'react';
  3. /**
  4. * For legacy reasons, inline style for display none.
  5. * @type {{display: string}}
  6. */
  7. const DISPLAY_NONE_STYLE = {
  8. display: 'none'
  9. };
  10. /**
  11. * Implements a React Component which renders initial conference layout
  12. */
  13. export default class Conference extends Component {
  14. /**
  15. * Initializes Conference component instance.
  16. *
  17. * @param {Object} props - The read-only properties with which the new
  18. * instance is to be initialized.
  19. */
  20. constructor(props) {
  21. super(props);
  22. const showBrandWatermark = interfaceConfig.SHOW_BRAND_WATERMARK;
  23. const showJitsiWatermark = interfaceConfig.SHOW_JITSI_WATERMARK;
  24. this.state = {
  25. ...this.state,
  26. showBrandWatermark,
  27. showJitsiWatermark,
  28. brandWatermarkLink:
  29. showBrandWatermark ? interfaceConfig.BRAND_WATERMARK_LINK : '',
  30. jitsiWatermarkLink:
  31. showJitsiWatermark ? interfaceConfig.JITSI_WATERMARK_LINK : '',
  32. showPoweredBy: interfaceConfig.SHOW_POWERED_BY
  33. };
  34. }
  35. /**
  36. * Implements React's {@link Component#render()}.
  37. *
  38. * @inheritdoc
  39. * @returns {ReactElement}
  40. */
  41. render() {
  42. return (
  43. <div id = 'videoconference_page'>
  44. <div id = 'mainToolbarContainer'>
  45. <div
  46. className = 'notice'
  47. id = 'notice'
  48. style = { DISPLAY_NONE_STYLE }>
  49. <span
  50. className = 'noticeText'
  51. id = 'noticeText' />
  52. </div>
  53. <div
  54. className = 'toolbar'
  55. id = 'mainToolbar' />
  56. </div>
  57. <div
  58. className = 'hide'
  59. id = 'subject' />
  60. <div
  61. className = 'toolbar'
  62. id = 'extendedToolbar'>
  63. <div id = 'extendedToolbarButtons' />
  64. <a
  65. className = 'button icon-feedback'
  66. id = 'feedbackButton' />
  67. <div id = 'sideToolbarContainer' />
  68. </div>
  69. <div id = 'videospace'>
  70. <div
  71. className = 'videocontainer'
  72. id = 'largeVideoContainer'>
  73. <div id = 'sharedVideo'>
  74. <div id = 'sharedVideoIFrame' />
  75. </div>
  76. <div id = 'etherpad' />
  77. {
  78. this._renderJitsiWatermark()
  79. }
  80. {
  81. this._renderBrandWatermark()
  82. }
  83. {
  84. this._renderPoweredBy()
  85. }
  86. <div id = 'dominantSpeaker'>
  87. <div className = 'dynamic-shadow' />
  88. <img
  89. id = 'dominantSpeakerAvatar'
  90. src = '' />
  91. </div>
  92. <span id = 'remoteConnectionMessage' />
  93. <div id = 'largeVideoWrapper'>
  94. <video
  95. autoPlay = { true }
  96. id = 'largeVideo'
  97. muted = 'true' />
  98. </div>
  99. <span id = 'localConnectionMessage' />
  100. <span
  101. className = 'video-state-indicator moveToCorner'
  102. id = 'videoResolutionLabel'>HD</span>
  103. <span
  104. className
  105. = 'video-state-indicator centeredVideoLabel'
  106. id = 'recordingLabel'>
  107. <span id = 'recordingLabelText' />
  108. <img
  109. className = 'recordingSpinner'
  110. id = 'recordingSpinner'
  111. src = 'images/spin.svg' />
  112. </span>
  113. </div>
  114. <div className = 'filmstrip'>
  115. <div
  116. className = 'filmstrip__videos'
  117. id = 'remoteVideos'>
  118. <span
  119. className = 'videocontainer'
  120. id = 'localVideoContainer'>
  121. <div
  122. className = 'videocontainer__background' />
  123. <span id = 'localVideoWrapper' />
  124. <audio
  125. autoPlay = { true }
  126. id = 'localAudio'
  127. muted = { true } />
  128. <div className = 'videocontainer__toolbar' />
  129. <div
  130. className = 'videocontainer__toptoolbar' />
  131. <div
  132. className
  133. = 'videocontainer__hoverOverlay' />
  134. </span>
  135. <audio
  136. id = 'userJoined'
  137. preload = 'auto'
  138. src = 'sounds/joined.wav' />
  139. <audio
  140. id = 'userLeft'
  141. preload = 'auto'
  142. src = 'sounds/left.wav' />
  143. </div>
  144. </div>
  145. </div>
  146. </div>
  147. );
  148. }
  149. /**
  150. * Method that returns brand watermark element if it is enabled.
  151. *
  152. * @returns {ReactElement|null}
  153. * @private
  154. */
  155. _renderBrandWatermark() {
  156. if (this.state.showBrandWatermark) {
  157. return (
  158. <a
  159. href = { this.state.brandWatermarkLink }
  160. target = '_new'>
  161. <div className = 'watermark rightwatermark' />
  162. </a>
  163. );
  164. }
  165. return null;
  166. }
  167. /**
  168. * Method that returns jitsi watermark element if it is enabled.
  169. *
  170. * @returns {ReactElement|null}
  171. * @private
  172. */
  173. _renderJitsiWatermark() {
  174. if (this.state.showJitsiWatermark) {
  175. return (
  176. <a
  177. href = { this.state.jitsiWatermarkLink }
  178. target = '_new'>
  179. <div className = 'watermark leftwatermark' />
  180. </a>
  181. );
  182. }
  183. return null;
  184. }
  185. /**
  186. * Renders powered by block if it is enabled.
  187. *
  188. * @returns {ReactElement|null}
  189. * @private
  190. */
  191. _renderPoweredBy() {
  192. if (this.state.showPoweredBy) {
  193. return (
  194. <a
  195. className = 'poweredby hide'
  196. href = 'http://jitsi.org'
  197. target = '_new'>
  198. <span data-i18n = 'poweredby' /> jitsi.org
  199. </a>
  200. );
  201. }
  202. return null;
  203. }
  204. }