feat(rn, thumbnail) Updated indicators on native (#11280)

Remove tint for participant in large view
Change pinned indicator from border to icon
On stage view move screen sharing indicator from top to bottom
On stage view show pinned indicator instead of moderator indicator
This commit is contained in:
Robert Pintilii 2022-03-31 14:39:49 +03:00 committed by GitHub
parent 343a1b87e2
commit ec0e824a43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 91 deletions

View File

@ -45,11 +45,6 @@ export default {
'LargeVideo': { 'LargeVideo': {
background: '#040404' background: '#040404'
}, },
'Thumbnail': {
activeParticipantHighlight: 'rgb(81, 214, 170)',
activeParticipantTint: 'rgba(49, 183, 106, 0.3)',
background: '#36383C'
},
'Toolbox': { 'Toolbox': {
button: 'rgb(255, 255, 255)', button: 'rgb(255, 255, 255)',
buttonToggled: 'rgb(38, 58, 76)', buttonToggled: 'rgb(38, 58, 76)',

View File

@ -13,7 +13,6 @@ import {
} from '../../media'; } from '../../media';
import { Container, TintedView } from '../../react'; import { Container, TintedView } from '../../react';
import { connect } from '../../redux'; import { connect } from '../../redux';
import type { StyleType } from '../../styles';
import { TestHint } from '../../testing/components'; import { TestHint } from '../../testing/components';
import { getTrackByMediaTypeAndParticipant } from '../../tracks'; import { getTrackByMediaTypeAndParticipant } from '../../tracks';
import { shouldRenderParticipantVideo, getParticipantById } from '../functions'; import { shouldRenderParticipantVideo, getParticipantById } from '../functions';
@ -91,17 +90,6 @@ type Props = {
*/ */
t: Function, t: Function,
/**
* If true, a tinting will be applied to the view, regardless of video or
* avatar is rendered.
*/
tintEnabled: boolean,
/**
* The style of the tinting when applied.
*/
tintStyle: StyleType,
/** /**
* The test hint id which can be used to locate the {@code ParticipantView} * The test hint id which can be used to locate the {@code ParticipantView}
* on the jitsi-meet-torture side. If not provided, the * on the jitsi-meet-torture side. If not provided, the
@ -193,15 +181,12 @@ class ParticipantView extends Component<Props> {
_renderVideo: renderVideo, _renderVideo: renderVideo,
_videoTrack: videoTrack, _videoTrack: videoTrack,
disableVideo, disableVideo,
onPress, onPress
tintStyle
} = this.props; } = this.props;
// If the connection has problems, we will "tint" the video / avatar. // If the connection has problems, we will "tint" the video / avatar.
const connectionProblem const connectionProblem
= connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE; = connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE;
const useTint
= connectionProblem || this.props.tintEnabled;
const testHintId const testHintId
= this.props.testHintId = this.props.testHintId
@ -241,12 +226,10 @@ class ParticipantView extends Component<Props> {
size = { this.props.avatarSize } /> size = { this.props.avatarSize } />
</View> } </View> }
{ useTint { connectionProblem
// If the connection has problems, tint the video / avatar. // If the connection has problems, tint the video / avatar.
&& <TintedView && <TintedView /> }
style = {
connectionProblem ? undefined : tintStyle } /> }
{ this.props.useConnectivityInfoLabel { this.props.useConnectivityInfoLabel
&& this._renderConnectionInfo(connectionStatus) } && this._renderConnectionInfo(connectionStatus) }

View File

@ -0,0 +1,17 @@
// @flow
import React from 'react';
import { IconPinParticipant } from '../../../base/icons';
import { BaseIndicator } from '../../../base/react';
/**
* Thumbnail badge for displaying if a participant is pinned.
*
* @returns {React$Element<any>}
*/
export default function PinnedIndicator() {
return (
<BaseIndicator icon = { IconPinParticipant } />
);
}

View File

@ -4,7 +4,6 @@ import React, { PureComponent } from 'react';
import { Image, View } from 'react-native'; import { Image, View } from 'react-native';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import { ColorSchemeRegistry } from '../../../base/color-scheme';
import { MEDIA_TYPE, VIDEO_TYPE } from '../../../base/media'; import { MEDIA_TYPE, VIDEO_TYPE } from '../../../base/media';
import { import {
PARTICIPANT_ROLE, PARTICIPANT_ROLE,
@ -18,7 +17,6 @@ import {
} from '../../../base/participants'; } from '../../../base/participants';
import { Container } from '../../../base/react'; import { Container } from '../../../base/react';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { StyleType } from '../../../base/styles';
import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks'; import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
import { ConnectionIndicator } from '../../../connection-indicator'; import { ConnectionIndicator } from '../../../connection-indicator';
import { DisplayNameLabel } from '../../../display-name'; import { DisplayNameLabel } from '../../../display-name';
@ -32,6 +30,7 @@ import { SQUARE_TILE_ASPECT_RATIO } from '../../constants';
import AudioMutedIndicator from './AudioMutedIndicator'; import AudioMutedIndicator from './AudioMutedIndicator';
import ModeratorIndicator from './ModeratorIndicator'; import ModeratorIndicator from './ModeratorIndicator';
import PinnedIndicator from './PinnedIndicator';
import RaisedHandIndicator from './RaisedHandIndicator'; import RaisedHandIndicator from './RaisedHandIndicator';
import ScreenShareIndicator from './ScreenShareIndicator'; import ScreenShareIndicator from './ScreenShareIndicator';
import styles, { AVATAR_SIZE } from './styles'; import styles, { AVATAR_SIZE } from './styles';
@ -79,11 +78,6 @@ type Props = {
*/ */
_participantId: string, _participantId: string,
/**
* Indicates whether the participant is displayed on the large video.
*/
_participantInLargeVideo: boolean,
/** /**
* Indicates whether the participant is pinned or not. * Indicates whether the participant is pinned or not.
*/ */
@ -104,18 +98,6 @@ type Props = {
*/ */
_renderModeratorIndicator: boolean, _renderModeratorIndicator: boolean,
/**
* The color-schemed stylesheet of the feature.
*/
_styles: StyleType,
/**
* If true, there will be no color overlay (tint) on the thumbnail
* indicating the participant associated with the thumbnail is displayed on
* large video. By default there will be a tint.
*/
disableTint?: boolean,
/** /**
* Invoked to trigger state changes in Redux. * Invoked to trigger state changes in Redux.
*/ */
@ -208,7 +190,9 @@ class Thumbnail extends PureComponent<Props> {
_isFakeParticipant, _isFakeParticipant,
_renderModeratorIndicator: renderModeratorIndicator, _renderModeratorIndicator: renderModeratorIndicator,
_participantId: participantId, _participantId: participantId,
renderDisplayName _pinned,
renderDisplayName,
tileView
} = this.props; } = this.props;
const indicators = []; const indicators = [];
@ -221,7 +205,7 @@ class Thumbnail extends PureComponent<Props> {
] }> ] }>
<ConnectionIndicator participantId = { participantId } /> <ConnectionIndicator participantId = { participantId } />
<RaisedHandIndicator participantId = { participantId } /> <RaisedHandIndicator participantId = { participantId } />
{isScreenShare && ( {tileView && isScreenShare && (
<View style = { styles.indicatorContainer }> <View style = { styles.indicatorContainer }>
<ScreenShareIndicator /> <ScreenShareIndicator />
</View> </View>
@ -232,7 +216,11 @@ class Thumbnail extends PureComponent<Props> {
style = { styles.thumbnailIndicatorContainer }> style = { styles.thumbnailIndicatorContainer }>
<Container style = { (audioMuted || renderModeratorIndicator) && styles.bottomIndicatorsContainer }> <Container style = { (audioMuted || renderModeratorIndicator) && styles.bottomIndicatorsContainer }>
{ audioMuted && <AudioMutedIndicator /> } { audioMuted && <AudioMutedIndicator /> }
{ !tileView && _pinned && <PinnedIndicator />}
{ renderModeratorIndicator && <ModeratorIndicator />} { renderModeratorIndicator && <ModeratorIndicator />}
{ !tileView && isScreenShare
&& <ScreenShareIndicator />
}
</Container> </Container>
{ {
renderDisplayName && <DisplayNameLabel renderDisplayName && <DisplayNameLabel
@ -257,12 +245,8 @@ class Thumbnail extends PureComponent<Props> {
_isScreenShare: isScreenShare, _isScreenShare: isScreenShare,
_isFakeParticipant, _isFakeParticipant,
_participantId: participantId, _participantId: participantId,
_participantInLargeVideo: participantInLargeVideo,
_pinned,
_raisedHand, _raisedHand,
_renderDominantSpeakerIndicator, _renderDominantSpeakerIndicator,
_styles,
disableTint,
height, height,
tileView tileView
} = this.props; } = this.props;
@ -281,7 +265,6 @@ class Thumbnail extends PureComponent<Props> {
onLongPress = { this._onThumbnailLongPress } onLongPress = { this._onThumbnailLongPress }
style = { [ style = { [
styles.thumbnail, styles.thumbnail,
_pinned && !tileView ? _styles.thumbnailPinned : null,
styleOverrides, styleOverrides,
_raisedHand ? styles.thumbnailRaisedHand : null, _raisedHand ? styles.thumbnailRaisedHand : null,
_renderDominantSpeakerIndicator ? styles.thumbnailDominantSpeaker : null _renderDominantSpeakerIndicator ? styles.thumbnailDominantSpeaker : null
@ -295,8 +278,6 @@ class Thumbnail extends PureComponent<Props> {
avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE } avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
disableVideo = { isScreenShare || _isFakeParticipant } disableVideo = { isScreenShare || _isFakeParticipant }
participantId = { participantId } participantId = { participantId }
tintEnabled = { participantInLargeVideo && !disableTint }
tintStyle = { _styles.activeThumbnailTint }
zOrder = { 1 } /> zOrder = { 1 } />
{ {
this._renderIndicators() this._renderIndicators()
@ -316,13 +297,9 @@ class Thumbnail extends PureComponent<Props> {
* @returns {Object} * @returns {Object}
*/ */
function _mapStateToProps(state, ownProps) { function _mapStateToProps(state, ownProps) {
// We need read-only access to the state of features/large-video so that the
// filmstrip doesn't render the video of the participant who is rendered on
// the stage i.e. as a large video.
const largeVideo = state['features/large-video'];
const { ownerId } = state['features/shared-video']; const { ownerId } = state['features/shared-video'];
const tracks = state['features/base/tracks']; const tracks = state['features/base/tracks'];
const { participantID } = ownProps; const { participantID, tileView } = ownProps;
const participant = getParticipantByIdOrUndefined(state, participantID); const participant = getParticipantByIdOrUndefined(state, participantID);
const localParticipantId = getLocalParticipant(state).id; const localParticipantId = getLocalParticipant(state).id;
const id = participant?.id; const id = participant?.id;
@ -334,9 +311,8 @@ function _mapStateToProps(state, ownProps) {
const participantCount = getParticipantCount(state); const participantCount = getParticipantCount(state);
const renderDominantSpeakerIndicator = participant && participant.dominantSpeaker && participantCount > 2; const renderDominantSpeakerIndicator = participant && participant.dominantSpeaker && participantCount > 2;
const _isEveryoneModerator = isEveryoneModerator(state); const _isEveryoneModerator = isEveryoneModerator(state);
const renderModeratorIndicator = !_isEveryoneModerator const renderModeratorIndicator = tileView && !_isEveryoneModerator
&& participant?.role === PARTICIPANT_ROLE.MODERATOR; && participant?.role === PARTICIPANT_ROLE.MODERATOR;
const participantInLargeVideo = id === largeVideo.participantId;
const { gifUrl: gifSrc } = getGifForParticipant(state, id); const { gifUrl: gifSrc } = getGifForParticipant(state, id);
const mode = getGifDisplayMode(state); const mode = getGifDisplayMode(state);
@ -347,13 +323,11 @@ function _mapStateToProps(state, ownProps) {
_isScreenShare: isScreenShare, _isScreenShare: isScreenShare,
_local: participant?.local, _local: participant?.local,
_localVideoOwner: Boolean(ownerId === localParticipantId), _localVideoOwner: Boolean(ownerId === localParticipantId),
_participantInLargeVideo: participantInLargeVideo,
_participantId: id, _participantId: id,
_pinned: participant?.pinned, _pinned: participant?.pinned,
_raisedHand: hasRaisedHand(participant), _raisedHand: hasRaisedHand(participant),
_renderDominantSpeakerIndicator: renderDominantSpeakerIndicator, _renderDominantSpeakerIndicator: renderDominantSpeakerIndicator,
_renderModeratorIndicator: renderModeratorIndicator, _renderModeratorIndicator: renderModeratorIndicator
_styles: ColorSchemeRegistry.get(state, 'Thumbnail')
}; };
} }

View File

@ -263,7 +263,6 @@ class TileView extends PureComponent<Props> {
return ( return (
<Thumbnail <Thumbnail
disableTint = { true }
height = { _thumbnailHeight } height = { _thumbnailHeight }
key = { item } key = { item }
participantID = { item } participantID = { item }

View File

@ -1,6 +1,5 @@
// @flow // @flow
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
import BaseTheme from '../../../base/ui/components/BaseTheme.native'; import BaseTheme from '../../../base/ui/components/BaseTheme.native';
import { SMALL_THUMBNAIL_SIZE } from '../../constants'; import { SMALL_THUMBNAIL_SIZE } from '../../constants';
@ -178,29 +177,3 @@ export default {
resizeMode: 'contain' resizeMode: 'contain'
} }
}; };
/**
* Color schemed styles for the @{code Thumbnail} component.
*/
ColorSchemeRegistry.register('Thumbnail', {
/**
* Tinting style of the on-stage participant thumbnail.
*/
activeThumbnailTint: {
backgroundColor: schemeColor('activeParticipantTint')
},
/**
* Pinned video thumbnail style.
*/
thumbnailPinned: {
borderColor: schemeColor('activeParticipantHighlight'),
shadowColor: schemeColor('activeParticipantHighlight'),
shadowOffset: {
height: 5,
width: 5
},
shadowRadius: 5
}
});