jiti-meet/react/features/base/label/components/Label.native.js

162 lines
4.1 KiB
JavaScript
Raw Normal View History

// @flow
import React from 'react';
2018-09-11 10:16:01 +00:00
import { Animated, Text } from 'react-native';
2020-05-18 11:54:55 +00:00
import Icon from '../../icons/components/Icon';
import { combineStyles, type StyleType } from '../../styles';
import AbstractLabel, {
type Props as AbstractProps
} from './AbstractLabel';
import styles from './styles';
2018-09-11 10:16:01 +00:00
/**
* Const for status string 'in progress'.
*/
const STATUS_IN_PROGRESS = 'in_progress';
/**
* Const for status string 'off'.
*/
const STATUS_OFF = 'off';
type Props = AbstractProps & {
2018-09-11 10:16:01 +00:00
/**
* Status of the label. This prop adds some additional styles based on its
2021-11-04 21:10:43 +00:00
* value. E.g. If status = off, it will render the label symbolising that
* the thing it displays (e.g. Recording) is off.
2018-09-11 10:16:01 +00:00
*/
status: ('in_progress' | 'off' | 'on'),
/**
* Style of the label.
*/
style?: ?StyleType
};
2018-09-11 10:16:01 +00:00
type State = {
/**
* An animation object handling the opacity changes of the in progress
* label.
*/
pulseAnimation: Object
}
/**
* Renders a circular indicator to be used for status icons, such as recording
* on, audio-only conference, video quality and similar.
*/
export default class Label extends AbstractLabel<Props, State> {
2018-09-11 10:16:01 +00:00
/**
* A reference to the started animation of this label.
*/
animationReference: Object;
/**
* Instantiates a new instance of {@code Label}.
2018-09-11 10:16:01 +00:00
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this.state = {
pulseAnimation: new Animated.Value(0)
};
}
2018-09-11 10:16:01 +00:00
/**
* Implements {@code Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._maybeToggleAnimation({}, this.props);
2018-09-11 10:16:01 +00:00
}
/**
* Implements {@code Component#componentDidUpdate}.
2018-09-11 10:16:01 +00:00
*
* @inheritdoc
*/
componentDidUpdate(prevProps: Props) {
this._maybeToggleAnimation(prevProps, this.props);
2018-09-11 10:16:01 +00:00
}
/**
* Implements React {@link Component}'s render.
*
* @inheritdoc
*/
render() {
const { icon, text, status, style } = this.props;
2018-09-11 10:16:01 +00:00
let extraStyle = null;
switch (status) {
case STATUS_IN_PROGRESS:
extraStyle = {
opacity: this.state.pulseAnimation
};
break;
case STATUS_OFF:
extraStyle = styles.labelOff;
break;
}
return (
2018-09-11 10:16:01 +00:00
<Animated.View
style = { [
combineStyles(styles.labelContainer, style),
2018-09-11 10:16:01 +00:00
extraStyle
] }>
{ icon && <Icon
size = '18'
src = { icon } /> }
{ text && <Text style = { styles.labelText }>
{ text }
</Text>}
2018-09-11 10:16:01 +00:00
</Animated.View>
);
}
2018-09-11 10:16:01 +00:00
/**
* Checks if the animation has to be started or stopped and acts
* accordingly.
*
* @param {Props} oldProps - The previous values of the Props.
* @param {Props} newProps - The new values of the Props.
* @returns {void}
*/
_maybeToggleAnimation(oldProps, newProps) {
const { status: oldStatus } = oldProps;
const { status: newStatus } = newProps;
const { pulseAnimation } = this.state;
if (newStatus === STATUS_IN_PROGRESS
&& oldStatus !== STATUS_IN_PROGRESS) {
// Animation must be started
this.animationReference = Animated.loop(Animated.sequence([
Animated.timing(pulseAnimation, {
delay: 500,
toValue: 1,
useNativeDriver: true
}),
Animated.timing(pulseAnimation, {
toValue: 0.3,
useNativeDriver: true
})
]));
this.animationReference.start();
} else if (this.animationReference
&& newStatus !== STATUS_IN_PROGRESS
&& oldStatus === STATUS_IN_PROGRESS) {
// Animation must be stopped
this.animationReference.stop();
}
}
}