import debounce from 'debounce';
import React from 'react';
import { Animated, View } from 'react-native';
let _shouldUseScreens = true;
export function useScreens(shouldUseScreens = true) {
if (shouldUseScreens) {
console.warn(
'react-native-screens is not fully supported on this platform yet.'
);
}
_shouldUseScreens = shouldUseScreens;
}
export function screensEnabled() {
return _shouldUseScreens;
}
function isAnimatedValue(value) {
return value && value.__getValue && value.addListener;
}
function isPropTruthy(prop) {
let activeValue = prop;
if (isAnimatedValue(prop)) {
activeValue = prop.__getValue();
}
return !!activeValue;
}
export class Screen extends React.Component {
static defaultProps = {
active: true,
};
listenerId = null;
constructor(props) {
super(props);
this._onAnimatedValueUpdated = debounce(this._onAnimatedValueUpdated, 10);
this._addListener(props.active);
}
componentWillUnmount() {
this._removeListener(this.props.active);
}
_addListener = possibleListener => {
if (this.listenerId)
throw new Error(
'Screen: Attempting to observe an animated value while another value is already observed.'
);
if (isAnimatedValue(possibleListener)) {
this.listenerId = possibleListener.addListener(
this._onAnimatedValueUpdated
);
}
};
_removeListener = possibleListener => {
if (isAnimatedValue(possibleListener)) {
possibleListener.removeListener(this.listenerId);
this.listenerId = null;
}
};
shouldComponentUpdate({ active: nextActive }) {
const { active } = this.props;
if (nextActive !== active) {
this._removeListener(active);
this._addListener(nextActive);
this._updateDisplay(isPropTruthy(nextActive));
return false;
}
return true;
}
_onAnimatedValueUpdated = ({ value }) => {
this._updateDisplay(!!value);
};
_updateDisplay = isActive => {
if (isActive === undefined) {
isActive = isPropTruthy(this.props.active);
}
const display = isActive ? 'flex' : 'none';
this.setNativeProps({ style: { display } });
};
setNativeProps = nativeProps => {
if (this._view) {
this._view.setNativeProps(nativeProps);
}
};
_setRef = view => {
this._view = view;
this._updateDisplay();
};
render() {
return <Animated.View {...this.props} ref={this._setRef} />;
}
}
export const ScreenContainer = View;
export const NativeScreen = View;
export const NativeScreenContainer = View;