feat(native-participants-pane) volume slider refactoring

This commit is contained in:
Calin Chitu 2021-07-01 13:12:38 +03:00 committed by Hristo Terezov
parent 415562c315
commit 5182a720f9
7 changed files with 95 additions and 29 deletions

View File

@ -60,16 +60,6 @@ export function getRecordingSharingUrl(state: Object) {
return state['features/base/config'].recordingSharingUrl;
}
/**
* Selector used to get if the new participant is starting silent.
*
* @param {Object} state - The global state.
* @returns {string}
*/
export function getIsStartingSilent(state: Object) {
return Boolean(state['features/base/config'].startSilent);
}
/**
* Overrides JSON properties in {@code config} and
* {@code interfaceConfig} Objects with the values from {@code newConfig}.

View File

@ -7,3 +7,8 @@ export const PARTICIPANTS_PANE_CLOSE = 'PARTICIPANTS_PANE_CLOSE';
* Action type to signal the opening of the participants pane.
*/
export const PARTICIPANTS_PANE_OPEN = 'PARTICIPANTS_PANE_OPEN';
/**
* Action type to set the volume of the participant.
*/
export const SET_VOLUME = 'SET_VOLUME';

View File

@ -2,6 +2,7 @@
import { openDialog } from '../base/dialog';
import { SET_VOLUME } from './actionTypes';
import { ContextMenuLobbyParticipantReject, ContextMenuMeetingParticipantDetails } from './components/native';
export * from './actions.any';
@ -25,3 +26,22 @@ export function showContextMenuReject(participant: Object) {
export function showContextMenuDetails(participant: Object) {
return openDialog(ContextMenuMeetingParticipantDetails, { participant });
}
/**
* Sets the volume.
*
* @param {string} participantId - The participant ID associated with the audio.
* @param {string} volume - The volume level.
* @returns {{
* type: SET_VOLUME,
* participantId: string,
* volume: number
* }}
*/
export function setVolume(participantId: string, volume: number) {
return {
type: SET_VOLUME,
participantId,
volume
};
}

View File

@ -7,7 +7,6 @@ import { Divider, Text } from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import { Avatar } from '../../../base/avatar';
import { getIsStartingSilent } from '../../../base/config';
import { hideDialog, openDialog } from '../../../base/dialog/actions';
import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
import {
@ -41,9 +40,6 @@ type Props = {
export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
const dispatch = useDispatch();
const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const isStartingSilent = useSelector(getIsStartingSilent);
const participantsVolume = 1;
const initialParticipantsVolume = isStartingSilent ? undefined : participantsVolume;
const displayName = p.name;
const isLocalModerator = useSelector(isLocalParticipantModerator);
const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
@ -172,8 +168,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
{/* <Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text>*/}
{/* </TouchableOpacity>*/}
<Divider style = { styles.divider } />
<VolumeSlider
initialValue = { initialParticipantsVolume } />
<VolumeSlider participant = { p } />
</BottomSheet>
);
};

View File

@ -2,12 +2,14 @@ import { ReducerRegistry } from '../base/redux';
import {
PARTICIPANTS_PANE_CLOSE,
PARTICIPANTS_PANE_OPEN
PARTICIPANTS_PANE_OPEN,
SET_VOLUME
} from './actionTypes';
import { REDUCER_KEY } from './constants';
const DEFAULT_STATE = {
isOpen: false
isOpen: false,
participantsVolume: {}
};
/**
@ -28,6 +30,16 @@ ReducerRegistry.register(
isOpen: true
};
case SET_VOLUME:
return {
...state,
participantsVolume: {
...state.participantsVolume,
[action.participantId]: action.volume
}
};
default:
return state;
}

View File

@ -2,8 +2,6 @@
import { Component } from 'react';
import { blockParticipantsAudioVideo } from '../actions.any';
type Props = {
/**

View File

@ -6,7 +6,14 @@ import React, { PureComponent } from 'react';
import { View } from 'react-native';
import { withTheme } from 'react-native-paper';
import { translate } from '../../../base/i18n';
import { Icon, IconVolumeEmpty } from '../../../base/icons';
import {
getLocalParticipant,
getParticipantById
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import { setVolume } from '../../../participants-pane/actions.native';
import { VOLUME_SLIDER_SCALE } from '../../constants';
/**
@ -15,11 +22,24 @@ import { VOLUME_SLIDER_SCALE } from '../../constants';
type Props = {
/**
* The value of the audio slider should display at when the component first
* mounts. Changes will be stored in state. The value should be a number
* between 0 and 1.
* Whether the participant enters the conference silent.
*/
initialValue: number,
_startSilent: boolean,
/**
* The volume level for the participant.
*/
_volume: number,
/**
* The redux dispatch function.
*/
dispatch: Function,
/**
* Participant reference
*/
participant: Object,
/**
* Theme used for styles.
@ -58,7 +78,7 @@ class VolumeSlider extends PureComponent<Props, State> {
super(props);
this.state = {
volumeLevel: (props.initialValue || 0) * VOLUME_SLIDER_SCALE
volumeLevel: (props._volume || 0) * VOLUME_SLIDER_SCALE
};
this._originalVolumeChange = this._onVolumeChange;
@ -75,9 +95,10 @@ class VolumeSlider extends PureComponent<Props, State> {
* @returns {ReactElement}
*/
render() {
const { theme } = this.props;
const { _startSilent, theme } = this.props;
const { volumeLevel } = this.state;
const { palette } = theme;
const onVolumeChange = _startSilent ? undefined : this._onVolumeChange;
return (
<View>
@ -89,7 +110,7 @@ class VolumeSlider extends PureComponent<Props, State> {
maximumValue = { VOLUME_SLIDER_SCALE }
minimumTrackTintColor = { palette.action01 }
minimumValue = { 0 }
onValueChange = { this._onVolumeChange }
onValueChange = { onVolumeChange }
thumbTintColor = { palette.field02 }
value = { volumeLevel } />
</View>
@ -106,9 +127,34 @@ class VolumeSlider extends PureComponent<Props, State> {
* @returns {void}
*/
_onVolumeChange(volumeLevel) {
this.setState({ volumeLevel });
const { dispatch, participant } = this.props;
const { id } = participant;
dispatch(setVolume(id, volumeLevel));
}
}
export default withTheme(VolumeSlider);
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code VolumeSlider} component.
*
* @param {Object} state - The Redux state.
* @param {Object} ownProps - The own props of the component.
* @returns {Props}
*/
function mapStateToProps(state, ownProps): Object {
const { participant } = ownProps;
const { startSilent } = state['features/base/config'];
const { participantsVolume } = state['features/participants-pane'];
const getParticipant = participant.id
? getParticipantById(state, participant.id) : getLocalParticipant(state);
const { id } = getParticipant;
return {
_startSilent: Boolean(startSilent),
_volume: participant.local ? undefined : participantsVolume[id]
};
}
export default translate(connect(mapStateToProps)(withTheme(VolumeSlider)));