snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
This commit is contained in:
179
react/features/base/label/components/native/Label.tsx
Normal file
179
react/features/base/label/components/native/Label.tsx
Normal file
@@ -0,0 +1,179 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Animated, Text, ViewStyle } from 'react-native';
|
||||
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { StyleType, combineStyles } from '../../../styles/functions.native';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Const for status string 'in progress'.
|
||||
*/
|
||||
const STATUS_IN_PROGRESS = 'in_progress';
|
||||
|
||||
/**
|
||||
* Const for status string 'off'.
|
||||
*/
|
||||
const STATUS_OFF = 'off';
|
||||
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* An SVG icon to be rendered as the content of the label.
|
||||
*/
|
||||
icon?: Function;
|
||||
|
||||
/**
|
||||
* Color for the icon.
|
||||
*/
|
||||
iconColor?: string;
|
||||
|
||||
/**
|
||||
* Status of the label. This prop adds some additional styles based on its
|
||||
* value. E.g. If status = off, it will render the label symbolising that
|
||||
* the thing it displays (e.g. Recording) is off.
|
||||
*/
|
||||
status?: 'in_progress' | 'off' | 'on';
|
||||
|
||||
/**
|
||||
* Style of the label.
|
||||
*/
|
||||
style?: StyleType;
|
||||
|
||||
/**
|
||||
* String or component that will be rendered as the label itself.
|
||||
*/
|
||||
text?: string;
|
||||
|
||||
/**
|
||||
* Custom styles for the text.
|
||||
*/
|
||||
textStyle?: StyleType;
|
||||
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
||||
/**
|
||||
* An animation object handling the opacity changes of the in progress
|
||||
* label.
|
||||
*/
|
||||
pulseAnimation: Animated.Value;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 Component<IProps, State> {
|
||||
/**
|
||||
* A reference to the started animation of this label.
|
||||
*/
|
||||
animationReference: Animated.CompositeAnimation;
|
||||
|
||||
/**
|
||||
* Instantiates a new instance of {@code Label}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
pulseAnimation: new Animated.Value(0)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code Component#componentDidMount}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
override componentDidMount() {
|
||||
this._maybeToggleAnimation({}, this.props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code Component#componentDidUpdate}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
override componentDidUpdate(prevProps: IProps) {
|
||||
this._maybeToggleAnimation(prevProps, this.props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React {@link Component}'s render.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
override render() {
|
||||
const { icon, text, status, style, iconColor, textStyle } = this.props;
|
||||
|
||||
let extraStyle = null;
|
||||
|
||||
switch (status) {
|
||||
case STATUS_IN_PROGRESS:
|
||||
extraStyle = {
|
||||
opacity: this.state.pulseAnimation
|
||||
};
|
||||
break;
|
||||
case STATUS_OFF:
|
||||
extraStyle = styles.labelOff;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
style = { [
|
||||
combineStyles(styles.labelContainer, style ?? {}),
|
||||
extraStyle as ViewStyle
|
||||
] }>
|
||||
{ icon && <Icon
|
||||
color = { iconColor }
|
||||
size = '18'
|
||||
src = { icon } /> }
|
||||
{ text && <Text style = { [ styles.labelText, textStyle ] }>
|
||||
{ text }
|
||||
</Text>}
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the animation has to be started or stopped and acts
|
||||
* accordingly.
|
||||
*
|
||||
* @param {IProps} oldProps - The previous values of the Props.
|
||||
* @param {IProps} newProps - The new values of the Props.
|
||||
* @returns {void}
|
||||
*/
|
||||
_maybeToggleAnimation(oldProps: Partial<IProps>, newProps: IProps) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user