Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

Watermarks.tsx 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. import React, { Component } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { connect } from 'react-redux';
  4. import { IReduxState } from '../../../../app/types';
  5. import { isVpaasMeeting } from '../../../../jaas/functions';
  6. import { translate } from '../../../i18n/functions';
  7. /**
  8. * The CSS style of the element with CSS class {@code rightwatermark}.
  9. *
  10. * @private
  11. */
  12. const _RIGHT_WATERMARK_STYLE = {
  13. backgroundImage: 'url(images/rightwatermark.png)'
  14. };
  15. /**
  16. * The type of the React {@code Component} props of {@link Watermarks}.
  17. */
  18. interface IProps extends WithTranslation {
  19. /**
  20. * The link used to navigate to on logo click.
  21. */
  22. _logoLink: string;
  23. /**
  24. * The url for the logo.
  25. */
  26. _logoUrl?: string;
  27. /**
  28. * If the Jitsi watermark should be displayed or not.
  29. */
  30. _showJitsiWatermark: boolean;
  31. /**
  32. * The default value for the Jitsi logo URL.
  33. */
  34. defaultJitsiLogoURL?: string;
  35. /**
  36. * Whether the watermark should have a `top` and `left` value.
  37. */
  38. noMargins: boolean;
  39. }
  40. /**
  41. * The type of the React {@code Component} state of {@link Watermarks}.
  42. */
  43. type State = {
  44. /**
  45. * The url to open when clicking the brand watermark.
  46. */
  47. brandWatermarkLink: string;
  48. /**
  49. * Whether or not the brand watermark should be displayed.
  50. */
  51. showBrandWatermark: boolean;
  52. /**
  53. * Whether or not the show the "powered by Jitsi.org" link.
  54. */
  55. showPoweredBy: boolean;
  56. };
  57. /**
  58. * A Web Component which renders watermarks such as Jits, brand, powered by,
  59. * etc.
  60. */
  61. class Watermarks extends Component<IProps, State> {
  62. /**
  63. * Initializes a new Watermarks instance.
  64. *
  65. * @param {Object} props - The read-only properties with which the new
  66. * instance is to be initialized.
  67. */
  68. constructor(props: IProps) {
  69. super(props);
  70. const showBrandWatermark = interfaceConfig.SHOW_BRAND_WATERMARK;
  71. this.state = {
  72. brandWatermarkLink:
  73. showBrandWatermark ? interfaceConfig.BRAND_WATERMARK_LINK : '',
  74. showBrandWatermark,
  75. showPoweredBy: interfaceConfig.SHOW_POWERED_BY
  76. };
  77. }
  78. /**
  79. * Implements React's {@link Component#render()}.
  80. *
  81. * @inheritdoc
  82. * @returns {ReactElement}
  83. */
  84. render() {
  85. return (
  86. <div>
  87. {
  88. this._renderJitsiWatermark()
  89. }
  90. {
  91. this._renderBrandWatermark()
  92. }
  93. {
  94. this._renderPoweredBy()
  95. }
  96. </div>
  97. );
  98. }
  99. /**
  100. * Renders a brand watermark if it is enabled.
  101. *
  102. * @private
  103. * @returns {ReactElement|null} Watermark element or null.
  104. */
  105. _renderBrandWatermark() {
  106. let reactElement = null;
  107. if (this.state.showBrandWatermark) {
  108. reactElement = (
  109. <div
  110. className = 'watermark rightwatermark'
  111. style = { _RIGHT_WATERMARK_STYLE } />
  112. );
  113. const { brandWatermarkLink } = this.state;
  114. if (brandWatermarkLink) {
  115. reactElement = (
  116. <a
  117. href = { brandWatermarkLink }
  118. target = '_new'>
  119. { reactElement }
  120. </a>
  121. );
  122. }
  123. }
  124. return reactElement;
  125. }
  126. /**
  127. * Renders a Jitsi watermark if it is enabled.
  128. *
  129. * @private
  130. * @returns {ReactElement|null}
  131. */
  132. _renderJitsiWatermark() {
  133. const {
  134. _logoLink,
  135. _logoUrl,
  136. _showJitsiWatermark
  137. } = this.props;
  138. const { noMargins, t } = this.props;
  139. const className = `watermark ${noMargins ? 'leftwatermarknomargin' : 'leftwatermark'}`;
  140. let reactElement = null;
  141. if (_showJitsiWatermark) {
  142. const style = {
  143. backgroundImage: `url(${_logoUrl})`,
  144. maxWidth: 140,
  145. maxHeight: 70,
  146. position: _logoLink ? 'static' : 'absolute'
  147. } as const;
  148. reactElement = (<div
  149. className = { className }
  150. style = { style } />);
  151. if (_logoLink) {
  152. reactElement = (
  153. <a
  154. aria-label = { t('jitsiHome', { logo: interfaceConfig.APP_NAME }) }
  155. className = { className }
  156. href = { _logoLink }
  157. target = '_new'>
  158. { reactElement }
  159. </a>
  160. );
  161. }
  162. }
  163. return reactElement;
  164. }
  165. /**
  166. * Renders a powered by block if it is enabled.
  167. *
  168. * @private
  169. * @returns {ReactElement|null}
  170. */
  171. _renderPoweredBy() {
  172. if (this.state.showPoweredBy) {
  173. const { t } = this.props;
  174. return (
  175. <a
  176. className = 'poweredby'
  177. href = 'http://jitsi.org'
  178. target = '_new'>
  179. <span>{ t('poweredby') } jitsi.org</span>
  180. </a>
  181. );
  182. }
  183. return null;
  184. }
  185. }
  186. /**
  187. * Maps parts of Redux store to component prop types.
  188. *
  189. * @param {Object} state - Snapshot of Redux store.
  190. * @param {Object} ownProps - Component's own props.
  191. * @returns {IProps}
  192. */
  193. function _mapStateToProps(state: IReduxState, ownProps: any) {
  194. const {
  195. customizationReady,
  196. customizationFailed,
  197. defaultBranding,
  198. useDynamicBrandingData,
  199. logoClickUrl,
  200. logoImageUrl
  201. } = state['features/dynamic-branding'];
  202. const isValidRoom = state['features/base/conference'].room;
  203. const { defaultLogoUrl } = state['features/base/config'];
  204. const {
  205. JITSI_WATERMARK_LINK,
  206. SHOW_JITSI_WATERMARK
  207. } = interfaceConfig;
  208. let _showJitsiWatermark = (
  209. customizationReady && !customizationFailed
  210. && SHOW_JITSI_WATERMARK)
  211. || !isValidRoom;
  212. let _logoUrl: string | undefined = logoImageUrl;
  213. let _logoLink = logoClickUrl;
  214. if (useDynamicBrandingData) {
  215. if (isVpaasMeeting(state)) {
  216. // don't show logo if request fails or no logo set for vpaas meetings
  217. _showJitsiWatermark = !customizationFailed && Boolean(logoImageUrl);
  218. } else if (defaultBranding) {
  219. _logoUrl = defaultLogoUrl;
  220. _logoLink = JITSI_WATERMARK_LINK;
  221. }
  222. } else {
  223. // When there is no custom branding data use defaults
  224. _logoUrl = ownProps.defaultJitsiLogoURL || defaultLogoUrl;
  225. _logoLink = JITSI_WATERMARK_LINK;
  226. }
  227. return {
  228. _logoLink,
  229. _logoUrl,
  230. _showJitsiWatermark
  231. };
  232. }
  233. export default translate(connect(_mapStateToProps)(Watermarks));