react-native-ui-lib
Version:
[](https://stand-with-ukraine.pp.ua)
147 lines (145 loc) • 4.87 kB
JavaScript
import _lowerCase from "lodash/lowerCase";
import _isFunction from "lodash/isFunction";
import React, { PureComponent } from 'react';
import { StyleSheet, Text } from 'react-native';
import { NetInfoPackage as NetInfo } from "../../optionalDependencies";
import { Colors, Typography } from "../../style";
import TouchableOpacity from "../touchableOpacity";
import View from "../view";
import { Constants, asBaseComponent } from "../../commons/new";
import { LogService } from "../../services";
import { ConnectionStatusBarProps, DEFAULT_PROPS } from "./types";
export { ConnectionStatusBarProps };
/**
* @description: Top bar to show a "no internet" connection status. Note: Run on real device for best results
* @image: https://user-images.githubusercontent.com/33805983/34683190-f3b1904c-f4a9-11e7-9d46-9a340bd35448.png, https://user-images.githubusercontent.com/33805983/34484206-edc6c6e4-efcb-11e7-88b2-cd394c19dd5e.png
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/ConnectionStatusBarScreen.tsx
* @notes: The component requires installing the '@react-native-community/netinfo' native library
*/
class ConnectionStatusBar extends PureComponent {
static displayName = 'ConnectionStatusBar';
static defaultProps = DEFAULT_PROPS;
static registerGlobalOnConnectionLost(callback) {
ConnectionStatusBar.onConnectionLost = callback;
}
static unregisterGlobalOnConnectionLost() {
delete ConnectionStatusBar.onConnectionLost;
}
constructor(props) {
super(props);
this.generateStyles();
this.onConnectionChange = this.onConnectionChange.bind(this);
this.state = {
isConnected: true,
isCancelled: false
};
if (NetInfo) {
this.getInitialConnectionState();
} else {
// eslint-disable-next-line max-len
LogService.error(`RNUILib ConnectionStatusBar component requires installing "@react-native-community/netinfo" dependency`);
}
}
generateStyles() {
this.styles = createStyles();
}
componentDidMount() {
this.unsubscribe = NetInfo?.addEventListener(this.onConnectionChange);
}
componentWillUnmount() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
onConnectionChange(state) {
const isConnected = this.isStateConnected(state);
if (isConnected !== this.state.isConnected) {
this.setState({
isConnected,
isCancelled: false
});
if (this.props.onConnectionChange) {
this.props.onConnectionChange(isConnected, false);
}
if (!isConnected) {
setTimeout(() => {
this.getInitialConnectionState();
}, 3000);
}
if (!isConnected && _isFunction(ConnectionStatusBar.onConnectionLost)) {
ConnectionStatusBar.onConnectionLost();
}
}
}
async getInitialConnectionState() {
const isConnected = (await NetInfo?.fetch()).isConnected;
this.setState({
isConnected
});
if (this.props.onConnectionChange) {
this.props.onConnectionChange(isConnected, true);
}
}
isStateConnected(state) {
const lowerCaseState = _lowerCase(state.type);
const isConnected = lowerCaseState !== 'none';
return isConnected;
}
render() {
if (this.state.isConnected || this.state.isCancelled) {
return false;
}
const containerStyle = [this.styles.topContainer, this.props.useAbsolutePosition ? this.styles.absolutePosition : null];
return <View useSafeArea style={containerStyle}>
<View style={this.styles.container}>
<View style={{
flex: 1,
flexDirection: 'row'
}}>
<Text style={this.styles.text}>{this.props.label}</Text>
{this.props.allowDismiss && <TouchableOpacity style={this.styles.xContainer} onPress={() => this.setState({
isCancelled: true
})}>
<Text style={this.styles.x}>✕</Text>
</TouchableOpacity>}
</View>
</View>
</View>;
}
}
function createStyles() {
const typography = Constants.isSmallWindow ? Typography.text90 : Typography.text80;
return StyleSheet.create({
topContainer: {
backgroundColor: Colors.grey30
},
absolutePosition: {
...StyleSheet.absoluteFillObject,
bottom: undefined
},
container: {
flexDirection: 'column',
justifyContent: 'center'
},
text: {
flex: 1,
...typography,
textAlign: 'center',
color: Colors.grey60,
marginTop: 8,
marginBottom: 8,
alignSelf: 'center'
},
xContainer: {
paddingLeft: 10,
paddingRight: 10,
alignSelf: 'center'
},
x: {
fontSize: Typography.text80?.fontSize,
color: Colors.black
}
});
}
export { ConnectionStatusBar }; // For tests
export default asBaseComponent(ConnectionStatusBar);