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.3KB

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