Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

ConnectionIndicator.tsx 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* eslint-disable lines-around-comment */
  2. import React from 'react';
  3. import { StyleProp, View, ViewStyle } from 'react-native';
  4. import { connect } from 'react-redux';
  5. import { IReduxState } from '../../../app/types';
  6. import { IconConnection } from '../../../base/icons/svg';
  7. import { MEDIA_TYPE } from '../../../base/media/constants';
  8. import {
  9. getLocalParticipant,
  10. getParticipantById,
  11. isScreenShareParticipant
  12. } from '../../../base/participants/functions';
  13. // @ts-ignore
  14. import BaseIndicator from '../../../base/react/components/native/BaseIndicator';
  15. import {
  16. getTrackByMediaTypeAndParticipant
  17. } from '../../../base/tracks/functions.native';
  18. // @ts-ignore
  19. import indicatorStyles from '../../../filmstrip/components/native/styles';
  20. import {
  21. isTrackStreamingStatusInactive,
  22. isTrackStreamingStatusInterrupted
  23. } from '../../functions';
  24. import AbstractConnectionIndicator, {
  25. IProps as AbstractProps,
  26. mapStateToProps as _abstractMapStateToProps
  27. } from '../AbstractConnectionIndicator';
  28. import {
  29. CONNECTOR_INDICATOR_COLORS,
  30. CONNECTOR_INDICATOR_LOST,
  31. CONNECTOR_INDICATOR_OTHER,
  32. iconStyle
  33. } from './styles';
  34. type IProps = AbstractProps & {
  35. /**
  36. * Whether connection indicators are disabled or not.
  37. */
  38. _connectionIndicatorDisabled: boolean;
  39. /**
  40. * Whether the inactive connection indicator is disabled or not.
  41. */
  42. _connectionIndicatorInactiveDisabled: boolean;
  43. /**
  44. * Whether the connection is inactive or not.
  45. */
  46. _isConnectionStatusInactive: boolean;
  47. /**
  48. * Whether the connection is interrupted or not.
  49. */
  50. _isConnectionStatusInterrupted: boolean;
  51. /**
  52. * Whether the current participant is a virtual screenshare.
  53. */
  54. _isVirtualScreenshareParticipant: boolean;
  55. /**
  56. * Redux dispatch function.
  57. */
  58. dispatch: Function;
  59. /**
  60. * Icon style override.
  61. */
  62. iconStyle: any;
  63. };
  64. type IState = {
  65. autoHideTimeout: number | undefined;
  66. showIndicator: boolean;
  67. stats: any;
  68. };
  69. /**
  70. * Implements an indicator to show the quality of the connection of a participant.
  71. */
  72. class ConnectionIndicator extends AbstractConnectionIndicator<IProps, IState> {
  73. /**
  74. * Initializes a new {@code ConnectionIndicator} instance.
  75. *
  76. * @inheritdoc
  77. */
  78. constructor(props: IProps) {
  79. super(props);
  80. // @ts-ignore
  81. this.state = {
  82. autoHideTimeout: undefined,
  83. showIndicator: false,
  84. stats: {}
  85. };
  86. }
  87. /**
  88. * Get the icon configuration from CONNECTOR_INDICATOR_COLORS which has a percentage
  89. * that matches or exceeds the passed in percentage. The implementation
  90. * assumes CONNECTOR_INDICATOR_COLORS is already sorted by highest to lowest
  91. * percentage.
  92. *
  93. * @param {number} percent - The connection percentage, out of 100, to find
  94. * the closest matching configuration for.
  95. * @private
  96. * @returns {Object}
  97. */
  98. _getDisplayConfiguration(percent: number): any {
  99. return CONNECTOR_INDICATOR_COLORS.find(x => percent >= x.percent) || {};
  100. }
  101. /**
  102. * Implements React's {@link Component#render()}.
  103. *
  104. * @inheritdoc
  105. * @returns {ReactElement}
  106. */
  107. render() {
  108. const {
  109. _connectionIndicatorInactiveDisabled,
  110. _connectionIndicatorDisabled,
  111. _isVirtualScreenshareParticipant,
  112. _isConnectionStatusInactive,
  113. _isConnectionStatusInterrupted
  114. // @ts-ignore
  115. } = this.props;
  116. const {
  117. showIndicator,
  118. stats
  119. // @ts-ignore
  120. } = this.state;
  121. const { percent } = stats;
  122. if (!showIndicator || typeof percent === 'undefined'
  123. || _connectionIndicatorDisabled || _isVirtualScreenshareParticipant) {
  124. return null;
  125. }
  126. let indicatorColor;
  127. if (_isConnectionStatusInactive) {
  128. if (_connectionIndicatorInactiveDisabled) {
  129. return null;
  130. }
  131. indicatorColor = CONNECTOR_INDICATOR_OTHER;
  132. } else if (_isConnectionStatusInterrupted) {
  133. indicatorColor = CONNECTOR_INDICATOR_LOST;
  134. } else {
  135. const displayConfig = this._getDisplayConfiguration(percent);
  136. if (!displayConfig) {
  137. return null;
  138. }
  139. indicatorColor = displayConfig.color;
  140. }
  141. return (
  142. <View
  143. style = { [
  144. indicatorStyles.indicatorContainer as StyleProp<ViewStyle>,
  145. { backgroundColor: indicatorColor }
  146. ] }>
  147. {/* @ts-ignore */}
  148. <BaseIndicator
  149. icon = { IconConnection }
  150. // @ts-ignore
  151. iconStyle = { this.props.iconStyle || iconStyle } />
  152. </View>
  153. );
  154. }
  155. }
  156. /**
  157. * Maps part of the Redux state to the props of this component.
  158. *
  159. * @param {Object} state - The Redux state.
  160. * @param {IProps} ownProps - The own props of the component.
  161. * @returns {IProps}
  162. */
  163. export function _mapStateToProps(state: IReduxState, ownProps: IProps) {
  164. const { participantId } = ownProps;
  165. const tracks = state['features/base/tracks'];
  166. const participant = participantId ? getParticipantById(state, participantId) : getLocalParticipant(state);
  167. const _isVirtualScreenshareParticipant = isScreenShareParticipant(participant);
  168. let _isConnectionStatusInactive;
  169. let _isConnectionStatusInterrupted;
  170. if (!_isVirtualScreenshareParticipant) {
  171. const _videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, participantId);
  172. _isConnectionStatusInactive = isTrackStreamingStatusInactive(_videoTrack);
  173. _isConnectionStatusInterrupted = isTrackStreamingStatusInterrupted(_videoTrack);
  174. }
  175. return {
  176. ..._abstractMapStateToProps(state),
  177. _connectionIndicatorInactiveDisabled:
  178. Boolean(state['features/base/config'].connectionIndicators?.inactiveDisabled),
  179. _connectionIndicatorDisabled:
  180. Boolean(state['features/base/config'].connectionIndicators?.disabled),
  181. _isVirtualScreenshareParticipant,
  182. _isConnectionStatusInactive,
  183. _isConnectionStatusInterrupted
  184. };
  185. }
  186. // @ts-ignore
  187. export default connect(_mapStateToProps)(ConnectionIndicator);