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.

PreMeetingScreen.tsx 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* eslint-disable lines-around-comment */
  2. import { Theme } from '@mui/material';
  3. import React, { ReactNode } from 'react';
  4. import { makeStyles } from 'tss-react/mui';
  5. import { IReduxState } from '../../../../app/types';
  6. import DeviceStatus from '../../../../prejoin/components/preview/DeviceStatus';
  7. // @ts-ignore
  8. import { Toolbox } from '../../../../toolbox/components/web';
  9. import { getConferenceName } from '../../../conference/functions';
  10. import { PREMEETING_BUTTONS, THIRD_PARTY_PREJOIN_BUTTONS } from '../../../config/constants';
  11. import { getToolbarButtons, isToolbarButtonEnabled } from '../../../config/functions.web';
  12. import { connect } from '../../../redux/functions';
  13. import { withPixelLineHeight } from '../../../styles/functions.web';
  14. import ConnectionStatus from './ConnectionStatus';
  15. // @ts-ignore
  16. import Preview from './Preview';
  17. interface IProps {
  18. /**
  19. * The list of toolbar buttons to render.
  20. */
  21. _buttons: Array<string>;
  22. /**
  23. * The branding background of the premeeting screen(lobby/prejoin).
  24. */
  25. _premeetingBackground: string;
  26. /**
  27. * The name of the meeting that is about to be joined.
  28. */
  29. _roomName: string;
  30. /**
  31. * Children component(s) to be rendered on the screen.
  32. */
  33. children?: ReactNode;
  34. /**
  35. * Additional CSS class names to set on the icon container.
  36. */
  37. className?: string;
  38. /**
  39. * The name of the participant.
  40. */
  41. name?: string;
  42. /**
  43. * Indicates whether the copy url button should be shown.
  44. */
  45. showCopyUrlButton: boolean;
  46. /**
  47. * Indicates whether the device status should be shown.
  48. */
  49. showDeviceStatus: boolean;
  50. /**
  51. * The 'Skip prejoin' button to be rendered (if any).
  52. */
  53. skipPrejoinButton?: ReactNode;
  54. /**
  55. * Whether it's used in the 3rdParty prejoin screen or not.
  56. */
  57. thirdParty?: boolean;
  58. /**
  59. * Title of the screen.
  60. */
  61. title?: string;
  62. /**
  63. * True if the preview overlay should be muted, false otherwise.
  64. */
  65. videoMuted?: boolean;
  66. /**
  67. * The video track to render as preview (if omitted, the default local track will be rendered).
  68. */
  69. videoTrack?: Object;
  70. }
  71. const useStyles = makeStyles()((theme: Theme) => {
  72. return {
  73. subtitle: {
  74. ...withPixelLineHeight(theme.typography.heading5),
  75. color: theme.palette.text01,
  76. marginBottom: theme.spacing(4),
  77. overflow: 'hidden',
  78. textAlign: 'center',
  79. textOverflow: 'ellipsis',
  80. whiteSpace: 'nowrap',
  81. width: '100%'
  82. }
  83. };
  84. });
  85. const PreMeetingScreen = ({
  86. _buttons,
  87. _premeetingBackground,
  88. _roomName,
  89. children,
  90. className,
  91. showDeviceStatus,
  92. skipPrejoinButton,
  93. title,
  94. videoMuted,
  95. videoTrack
  96. }: IProps) => {
  97. const { classes } = useStyles();
  98. const containerClassName = `premeeting-screen ${className ? className : ''}`;
  99. const style = _premeetingBackground ? {
  100. background: _premeetingBackground,
  101. backgroundPosition: 'center',
  102. backgroundSize: 'cover'
  103. } : {};
  104. return (
  105. <div className = { containerClassName }>
  106. <div style = { style }>
  107. <div className = 'content'>
  108. <ConnectionStatus />
  109. <div className = 'content-controls'>
  110. <h1 className = 'title'>
  111. {title}
  112. </h1>
  113. {_roomName && (
  114. <span className = { classes.subtitle }>
  115. {_roomName}
  116. </span>
  117. )}
  118. {children}
  119. {_buttons.length && <Toolbox toolbarButtons = { _buttons } />}
  120. {skipPrejoinButton}
  121. {showDeviceStatus && <DeviceStatus />}
  122. </div>
  123. </div>
  124. </div>
  125. <Preview
  126. videoMuted = { videoMuted }
  127. videoTrack = { videoTrack } />
  128. </div>
  129. );
  130. };
  131. /**
  132. * Maps (parts of) the redux state to the React {@code Component} props.
  133. *
  134. * @param {Object} state - The redux state.
  135. * @param {Object} ownProps - The props passed to the component.
  136. * @returns {Object}
  137. */
  138. function mapStateToProps(state: IReduxState, ownProps: Partial<IProps>) {
  139. const { hiddenPremeetingButtons, hideConferenceSubject } = state['features/base/config'];
  140. const toolbarButtons = getToolbarButtons(state);
  141. const premeetingButtons = (ownProps.thirdParty
  142. ? THIRD_PARTY_PREJOIN_BUTTONS
  143. : PREMEETING_BUTTONS).filter((b: any) => !(hiddenPremeetingButtons || []).includes(b));
  144. const { premeetingBackground } = state['features/dynamic-branding'];
  145. return {
  146. // For keeping backwards compat.: if we pass an empty hiddenPremeetingButtons
  147. // array through external api, we have all prejoin buttons present on premeeting
  148. // screen regardless of passed values into toolbarButtons config overwrite.
  149. // If hiddenPremeetingButtons is missing, we hide the buttons according to
  150. // toolbarButtons config overwrite.
  151. _buttons: hiddenPremeetingButtons
  152. ? premeetingButtons
  153. : premeetingButtons.filter(b => isToolbarButtonEnabled(b, toolbarButtons)),
  154. _premeetingBackground: premeetingBackground,
  155. _roomName: hideConferenceSubject ? undefined : getConferenceName(state)
  156. };
  157. }
  158. export default connect(mapStateToProps)(PreMeetingScreen);