Skip to content

Instantly share code, notes, and snippets.

@jittuu
Last active September 13, 2018 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jittuu/44d88213d8e786e62757fe10394144e3 to your computer and use it in GitHub Desktop.
Save jittuu/44d88213d8e786e62757fe10394144e3 to your computer and use it in GitHub Desktop.
import React from 'react';
import {
StyleSheet,
Text,
ViewStyle,
} from 'react-native';
import { TextStyle } from 'react-native';
import { ViewProps } from 'react-native';
import { LayoutAnimation } from 'react-native';
import * as Animatable from 'react-native-animatable';
import firebase, { RNFirebase } from 'react-native-firebase';
import { Observable, Subscription } from 'rxjs';
import { colors } from 'src/colors';
const checkStatus$ = () => {
return new Observable<boolean>(observer => {
const callback = (sn: RNFirebase.database.DataSnapshot) => {
observer.next(sn.val());
};
const ref = firebase.database().ref('meta/checkConnection');
ref.on('value', callback);
return () => {
ref.off('value', callback);
};
});
};
type P = {} & ViewProps;
type Status = 'unknown' | 'justConnected' | 'connected' | 'notConnected';
interface S {
status: Status;
}
export default class extends React.Component<P, S> {
subscription: Subscription;
constructor(props: P) {
super(props);
this.subscription = new Subscription();
this.state = { status: 'unknown' };
}
componentDidMount() {
const connected$ = new Observable<boolean>(observer => {
const query = firebase.database().ref('.info/connected');
const callback = (sn: RNFirebase.database.DataSnapshot) => {
const connected = sn.val() as boolean;
observer.next(connected);
};
query.on(
'value',
callback,
err => observer.error(err),
);
return () => {
query.off('value', callback);
};
}).debounceTime(500)
.switchMap(connected => {
const { status: currentStatus } = this.state;
const status: Status = connected ? 'connected' : 'notConnected';
if (status === currentStatus) {
return Observable.empty<Status>();
}
if (currentStatus === 'notConnected') {
return Observable
.timer(0, 3000)
.take(2)
.map((_, i) => {
if (i === 0) {
return 'justConnected' as Status;
}
return 'connected' as Status;
});
} else {
return Observable.of<Status>(status);
}
});
this.subscription = checkStatus$()
.switchMap(_ => connected$)
.subscribe(status => {
if (status !== 'justConnected') {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
}
this.setState({ status });
});
}
componentWillUnmount() {
this.subscription.unsubscribe();
}
render() {
const { style } = this.props;
const { status } = this.state;
if (status === 'unknown') {
return null;
}
const connected = status === 'connected';
const justConnected = status === 'justConnected';
return (
<Animatable.View
transition={(justConnected ? 'color' : undefined) as any}
duration={1000}
style={[
styles.container,
style,
justConnected && styles.justConnected,
connected && styles.connected,
]}
>
<Text style={styles.text}>
{(status === 'notConnected') ? 'No Internet Connection' : 'Connected!'}
</Text>
</Animatable.View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#65737e',
alignItems: 'center',
justifyContent: 'center',
} as ViewStyle,
justConnected: {
backgroundColor: colors.successColor,
} as ViewStyle,
connected: {
height: 0,
} as ViewStyle,
text: {
margin: 4,
color: '#fff',
} as TextStyle,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment