/* eslint-disable lines-around-comment */ import React from 'react'; import { View } from 'react-native'; import { IReduxState } from '../../../app/types'; import { IconConnection } from '../../../base/icons/svg'; import { MEDIA_TYPE } from '../../../base/media/constants'; import { getLocalParticipant, getParticipantById, isScreenShareParticipant } from '../../../base/participants/functions'; // @ts-ignore import BaseIndicator from '../../../base/react/components/native/BaseIndicator'; import { connect } from '../../../base/redux/functions'; import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks/functions.native'; // @ts-ignore import indicatorStyles from '../../../filmstrip/components/native/styles'; import { isTrackStreamingStatusInactive, isTrackStreamingStatusInterrupted } from '../../functions'; import AbstractConnectionIndicator, { type Props as AbstractProps, mapStateToProps as _abstractMapStateToProps // @ts-ignore } from '../AbstractConnectionIndicator'; import { CONNECTOR_INDICATOR_COLORS, CONNECTOR_INDICATOR_LOST, CONNECTOR_INDICATOR_OTHER, iconStyle } from './styles'; type IProps = AbstractProps & { /** * Whether connection indicators are disabled or not. */ _connectionIndicatorDisabled: boolean; /** * Whether the inactive connection indicator is disabled or not. */ _connectionIndicatorInactiveDisabled: boolean; /** * Whether the connection is inactive or not. */ _isConnectionStatusInactive: boolean; /** * Whether the connection is interrupted or not. */ _isConnectionStatusInterrupted: boolean; /** * Whether the current participant is a virtual screenshare. */ _isVirtualScreenshareParticipant: boolean; /** * Redux dispatch function. */ dispatch: Function; /** * Icon style override. */ iconStyle: any; }; type IState = { autoHideTimeout: number | undefined; showIndicator: boolean; stats: any; }; /** * Implements an indicator to show the quality of the connection of a participant. */ class ConnectionIndicator extends AbstractConnectionIndicator { /** * Initializes a new {@code ConnectionIndicator} instance. * * @inheritdoc */ constructor(props: IProps) { super(props); // @ts-ignore this.state = { autoHideTimeout: undefined, showIndicator: false, stats: {} }; } /** * Get the icon configuration from CONNECTOR_INDICATOR_COLORS which has a percentage * that matches or exceeds the passed in percentage. The implementation * assumes CONNECTOR_INDICATOR_COLORS is already sorted by highest to lowest * percentage. * * @param {number} percent - The connection percentage, out of 100, to find * the closest matching configuration for. * @private * @returns {Object} */ _getDisplayConfiguration(percent: number): any { return CONNECTOR_INDICATOR_COLORS.find(x => percent >= x.percent) || {}; } /** * Implements React's {@link Component#render()}. * * @inheritdoc * @returns {ReactElement} */ render() { const { _connectionIndicatorInactiveDisabled, _connectionIndicatorDisabled, _isVirtualScreenshareParticipant, _isConnectionStatusInactive, _isConnectionStatusInterrupted // @ts-ignore } = this.props; const { showIndicator, stats // @ts-ignore } = this.state; const { percent } = stats; if (!showIndicator || typeof percent === 'undefined' || _connectionIndicatorDisabled || _isVirtualScreenshareParticipant) { return null; } let indicatorColor; if (_isConnectionStatusInactive) { if (_connectionIndicatorInactiveDisabled) { return null; } indicatorColor = CONNECTOR_INDICATOR_OTHER; } else if (_isConnectionStatusInterrupted) { indicatorColor = CONNECTOR_INDICATOR_LOST; } else { const displayConfig = this._getDisplayConfiguration(percent); if (!displayConfig) { return null; } indicatorColor = displayConfig.color; } return ( ); } } /** * Maps part of the Redux state to the props of this component. * * @param {Object} state - The Redux state. * @param {IProps} ownProps - The own props of the component. * @returns {IProps} */ export function _mapStateToProps(state: IReduxState, ownProps: IProps) { const { participantId } = ownProps; const tracks = state['features/base/tracks']; const participant = participantId ? getParticipantById(state, participantId) : getLocalParticipant(state); const _isVirtualScreenshareParticipant = isScreenShareParticipant(participant); let _isConnectionStatusInactive; let _isConnectionStatusInterrupted; if (!_isVirtualScreenshareParticipant) { const _videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, participantId); _isConnectionStatusInactive = isTrackStreamingStatusInactive(_videoTrack); _isConnectionStatusInterrupted = isTrackStreamingStatusInterrupted(_videoTrack); } return { ..._abstractMapStateToProps(state), _connectionIndicatorInactiveDisabled: Boolean(state['features/base/config'].connectionIndicators?.inactiveDisabled), _connectionIndicatorDisabled: Boolean(state['features/base/config'].connectionIndicators?.disabled), _isVirtualScreenshareParticipant, _isConnectionStatusInactive, _isConnectionStatusInterrupted }; } // @ts-ignore export default connect(_mapStateToProps)(ConnectionIndicator);