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.

ConnectionIndicatorIcon.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // @flow
  2. import clsx from 'clsx';
  3. import React, { useEffect } from 'react';
  4. import { useDispatch, useSelector } from 'react-redux';
  5. import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
  6. import { Icon, IconConnectionActive, IconConnectionInactive } from '../../../base/icons';
  7. import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
  8. import { trackStreamingStatusChanged } from '../../../base/tracks';
  9. type Props = {
  10. /**
  11. * An object containing the CSS classes.
  12. */
  13. classes: Object,
  14. /**
  15. * A CSS class that interprets the current connection status as a color.
  16. */
  17. colorClass: string,
  18. /**
  19. * Disable/enable inactive indicator.
  20. */
  21. connectionIndicatorInactiveDisabled: boolean,
  22. /**
  23. * JitsiTrack instance.
  24. */
  25. track: Object,
  26. /**
  27. * Whether or not the connection status is inactive.
  28. */
  29. isConnectionStatusInactive: boolean,
  30. /**
  31. * Whether or not the connection status is interrupted.
  32. */
  33. isConnectionStatusInterrupted: boolean,
  34. }
  35. export const ConnectionIndicatorIcon = ({
  36. classes,
  37. colorClass,
  38. connectionIndicatorInactiveDisabled,
  39. isConnectionStatusInactive,
  40. isConnectionStatusInterrupted,
  41. track
  42. }: Props) => {
  43. const sourceNameSignalingEnabled = useSelector(state => getSourceNameSignalingFeatureFlag(state));
  44. const dispatch = useDispatch();
  45. const sourceName = track?.jitsiTrack?.getSourceName();
  46. const handleTrackStreamingStatusChanged = (jitsiTrack, streamingStatus) => {
  47. dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
  48. };
  49. // TODO: replace this with a custom hook to be reused where track streaming status is needed.
  50. // TODO: In the hood the listener should updates a local track streaming status instead of that in redux store.
  51. useEffect(() => {
  52. if (track && !track.local && sourceNameSignalingEnabled) {
  53. track.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED, handleTrackStreamingStatusChanged);
  54. dispatch(trackStreamingStatusChanged(track.jitsiTrack, track.jitsiTrack.getTrackStreamingStatus?.()));
  55. }
  56. return () => {
  57. if (track && !track.local && sourceNameSignalingEnabled) {
  58. track.jitsiTrack.off(
  59. JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
  60. handleTrackStreamingStatusChanged
  61. );
  62. dispatch(trackStreamingStatusChanged(track.jitsiTrack, track.jitsiTrack.getTrackStreamingStatus?.()));
  63. }
  64. };
  65. }, [ sourceName ]);
  66. if (isConnectionStatusInactive) {
  67. if (connectionIndicatorInactiveDisabled) {
  68. return null;
  69. }
  70. return (
  71. <span className = 'connection_ninja'>
  72. <Icon
  73. className = { clsx(classes.icon, classes.inactiveIcon, colorClass) }
  74. size = { 24 }
  75. src = { IconConnectionInactive } />
  76. </span>
  77. );
  78. }
  79. let emptyIconWrapperClassName = 'connection_empty';
  80. if (isConnectionStatusInterrupted) {
  81. // emptyIconWrapperClassName is used by the torture tests to identify lost connection status handling.
  82. emptyIconWrapperClassName = 'connection_lost';
  83. }
  84. return (
  85. <span className = { emptyIconWrapperClassName }>
  86. <Icon
  87. className = { clsx(classes.icon, colorClass) }
  88. size = { 12 }
  89. src = { IconConnectionActive } />
  90. </span>
  91. );
  92. };