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:
parent
343a1b87e2
commit
ec0e824a43
|
@ -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)',
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
|
@ -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 } />
|
||||||
|
);
|
||||||
|
}
|
|
@ -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')
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in New Issue