您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ConnectionStatus.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // @flow
  2. import React, { useCallback, useState } from 'react';
  3. import { translate } from '../../../i18n';
  4. import { Icon, IconArrowDownSmall, IconWifi1Bar, IconWifi2Bars, IconWifi3Bars } from '../../../icons';
  5. import { connect } from '../../../redux';
  6. import { CONNECTION_TYPE } from '../../constants';
  7. import { getConnectionData } from '../../functions';
  8. type Props = {
  9. /**
  10. * List of strings with details about the connection.
  11. */
  12. connectionDetails: string[],
  13. /**
  14. * The type of the connection. Can be: 'none', 'poor', 'nonOptimal' or 'good'.
  15. */
  16. connectionType: string,
  17. /**
  18. * Used for translation.
  19. */
  20. t: Function
  21. }
  22. const CONNECTION_TYPE_MAP = {
  23. [CONNECTION_TYPE.POOR]: {
  24. connectionClass: 'con-status--poor',
  25. icon: IconWifi1Bar,
  26. connectionText: 'prejoin.connection.poor'
  27. },
  28. [CONNECTION_TYPE.NON_OPTIMAL]: {
  29. connectionClass: 'con-status--non-optimal',
  30. icon: IconWifi2Bars,
  31. connectionText: 'prejoin.connection.nonOptimal'
  32. },
  33. [CONNECTION_TYPE.GOOD]: {
  34. connectionClass: 'con-status--good',
  35. icon: IconWifi3Bars,
  36. connectionText: 'prejoin.connection.good'
  37. }
  38. };
  39. /**
  40. * Component displaying information related to the connection & audio/video quality.
  41. *
  42. * @param {Props} props - The props of the component.
  43. * @returns {ReactElement}
  44. */
  45. function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
  46. if (connectionType === CONNECTION_TYPE.NONE) {
  47. return null;
  48. }
  49. const { connectionClass, icon, connectionText } = CONNECTION_TYPE_MAP[connectionType];
  50. const [ showDetails, toggleDetails ] = useState(false);
  51. const arrowClassName = showDetails
  52. ? 'con-status-arrow con-status-arrow--up'
  53. : 'con-status-arrow';
  54. const detailsText = connectionDetails.map(t).join(' ');
  55. const detailsClassName = showDetails
  56. ? 'con-status-details-visible'
  57. : 'con-status-details-hidden';
  58. const onToggleDetails = useCallback(e => {
  59. e.preventDefault();
  60. toggleDetails(!showDetails);
  61. }, [ showDetails, toggleDetails ]);
  62. const onKeyPressToggleDetails = useCallback(e => {
  63. if (toggleDetails && (e.key === ' ' || e.key === 'Enter')) {
  64. e.preventDefault();
  65. toggleDetails(!showDetails);
  66. }
  67. }, [ showDetails, toggleDetails ]);
  68. return (
  69. <div className = 'con-status'>
  70. <div
  71. aria-level = { 1 }
  72. className = 'con-status-header'
  73. role = 'heading'>
  74. <div className = { `con-status-circle ${connectionClass}` }>
  75. <Icon
  76. size = { 16 }
  77. src = { icon } />
  78. </div>
  79. <span
  80. aria-hidden = { !showDetails }
  81. className = 'con-status-text'
  82. id = 'connection-status-description'>{t(connectionText)}</span>
  83. <Icon
  84. ariaDescribedBy = 'connection-status-description'
  85. ariaPressed = { showDetails }
  86. className = { arrowClassName }
  87. onClick = { onToggleDetails }
  88. onKeyPress = { onKeyPressToggleDetails }
  89. role = 'button'
  90. size = { 24 }
  91. src = { IconArrowDownSmall }
  92. tabIndex = { 0 } />
  93. </div>
  94. <div
  95. aria-level = '2'
  96. className = { `con-status-details ${detailsClassName}` }
  97. role = 'heading'>
  98. {detailsText}</div>
  99. </div>
  100. );
  101. }
  102. /**
  103. * Maps (parts of) the redux state to the React {@code Component} props.
  104. *
  105. * @param {Object} state - The redux state.
  106. * @returns {Object}
  107. */
  108. function mapStateToProps(state): Object {
  109. const { connectionDetails, connectionType } = getConnectionData(state);
  110. return {
  111. connectionDetails,
  112. connectionType
  113. };
  114. }
  115. export default translate(connect(mapStateToProps)(ConnectionStatus));