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.

DeviceStatus.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { Theme } from '@mui/material';
  2. import React from 'react';
  3. import { WithTranslation } from 'react-i18next';
  4. import { makeStyles } from 'tss-react/mui';
  5. import { IReduxState } from '../../../app/types';
  6. import { translate } from '../../../base/i18n/functions';
  7. import Icon from '../../../base/icons/components/Icon';
  8. import { IconCheckSolid, IconExclamationTriangle } from '../../../base/icons/svg';
  9. import { connect } from '../../../base/redux/functions';
  10. import {
  11. getDeviceStatusText,
  12. getDeviceStatusType
  13. } from '../../functions';
  14. export interface IProps extends WithTranslation {
  15. /**
  16. * The text to be displayed in relation to the status of the audio/video devices.
  17. */
  18. deviceStatusText?: string;
  19. /**
  20. * The type of status for current devices, controlling the background color of the text.
  21. * Can be `ok` or `warning`.
  22. */
  23. deviceStatusType?: string;
  24. }
  25. const useStyles = makeStyles()((theme: Theme) => {
  26. return {
  27. deviceStatus: {
  28. alignItems: 'center',
  29. color: '#fff',
  30. display: 'flex',
  31. fontSize: '14px',
  32. lineHeight: '20px',
  33. padding: '6px',
  34. textAlign: 'center',
  35. '& span': {
  36. marginLeft: theme.spacing(3)
  37. },
  38. '&.device-status-error': {
  39. alignItems: 'flex-start',
  40. backgroundColor: theme.palette.warning01,
  41. borderRadius: '6px',
  42. color: theme.palette.uiBackground,
  43. padding: '12px 16px',
  44. textAlign: 'left'
  45. },
  46. '& .device-icon': {
  47. backgroundPosition: 'center',
  48. backgroundRepeat: 'no-repeat',
  49. display: 'inline-block',
  50. height: '16px',
  51. width: '16px'
  52. },
  53. '& .device-icon--ok svg path': {
  54. fill: '#189B55'
  55. }
  56. }
  57. };
  58. });
  59. const iconMap = {
  60. warning: {
  61. src: IconExclamationTriangle,
  62. className: 'device-icon--warning'
  63. },
  64. ok: {
  65. src: IconCheckSolid,
  66. className: 'device-icon--ok'
  67. }
  68. };
  69. /**
  70. * Strip showing the current status of the devices.
  71. * User is informed if there are missing or malfunctioning devices.
  72. *
  73. * @returns {ReactElement}
  74. */
  75. function DeviceStatus({ deviceStatusType, deviceStatusText, t }: IProps) {
  76. const { classes, cx } = useStyles();
  77. const { src, className } = iconMap[deviceStatusType as keyof typeof iconMap];
  78. const hasError = deviceStatusType === 'warning';
  79. const containerClassName = cx(classes.deviceStatus, { 'device-status-error': hasError });
  80. return (
  81. <div
  82. className = { containerClassName }
  83. role = 'alert'
  84. tabIndex = { -1 }>
  85. <Icon
  86. className = { `device-icon ${className}` }
  87. size = { 16 }
  88. src = { src } />
  89. <span role = 'heading'>
  90. {hasError ? t('prejoin.errorNoPermissions') : t(deviceStatusText ?? '')}
  91. </span>
  92. </div>
  93. );
  94. }
  95. /**
  96. * Maps (parts of) the redux state to the React {@code Component} props.
  97. *
  98. * @param {Object} state - The redux state.
  99. * @returns {{ deviceStatusText: string, deviceStatusText: string }}
  100. */
  101. function mapStateToProps(state: IReduxState) {
  102. return {
  103. deviceStatusText: getDeviceStatusText(state),
  104. deviceStatusType: getDeviceStatusType(state)
  105. };
  106. }
  107. export default translate(connect(mapStateToProps)(DeviceStatus));