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.

ConnectionStatus.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // @flow
  2. import React, { 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. return (
  56. <div className = 'con-status'>
  57. <div className = 'con-status-container'>
  58. <div className = 'con-status-header'>
  59. <div className = { `con-status-circle ${connectionClass}` }>
  60. <Icon
  61. size = { 16 }
  62. src = { icon } />
  63. </div>
  64. <span className = 'con-status-text'>{t(connectionText)}</span>
  65. <Icon
  66. className = { arrowClassName }
  67. // eslint-disable-next-line react/jsx-no-bind
  68. onClick = { () => toggleDetails(!showDetails) }
  69. size = { 24 }
  70. src = { IconArrowDownSmall } />
  71. </div>
  72. { showDetails
  73. && <div className = 'con-status-details'>{detailsText}</div> }
  74. </div>
  75. </div>
  76. );
  77. }
  78. /**
  79. * Maps (parts of) the redux state to the React {@code Component} props.
  80. *
  81. * @param {Object} state - The redux state.
  82. * @returns {Object}
  83. */
  84. function mapStateToProps(state): Object {
  85. const { connectionDetails, connectionType } = getConnectionData(state);
  86. return {
  87. connectionDetails,
  88. connectionType
  89. };
  90. }
  91. export default translate(connect(mapStateToProps)(ConnectionStatus));