1import NetInfo, { NetInfoState, NetInfoSubscription } from '@react-native-community/netinfo';
2import React from 'react';
3import { ScrollView, View } from 'react-native';
4
5import HeadingText from '../components/HeadingText';
6import MonoText from '../components/MonoText';
7import Colors from '../constants/Colors';
8
9interface ConnectionEvent {
10  time: Date;
11  key: number;
12  connectionInfo: NetInfoState;
13}
14
15interface ConnectionChangeEvent extends ConnectionEvent {
16  connectionInfo: NetInfoState;
17}
18
19interface State {
20  connectionInfo: NetInfoState | null;
21  connectionChangeEvents: ConnectionChangeEvent[];
22}
23
24// See: https://github.com/expo/expo/pull/10229#discussion_r490961694
25// eslint-disable-next-line @typescript-eslint/ban-types
26export default class NetInfoScreen extends React.Component<{}, State> {
27  static navigationOptions = {
28    title: 'NetInfo',
29  };
30
31  readonly state: State = {
32    connectionInfo: null,
33    connectionChangeEvents: [],
34  };
35
36  eventCounter: number = 0;
37  subscription: NetInfoSubscription = NetInfo.addEventListener((connectionInfo) =>
38    this.handleConnectionChange(connectionInfo)
39  );
40
41  componentDidMount() {
42    this.fetchStateAsync();
43  }
44
45  componentWillUnmount() {
46    if (this.subscription) {
47      // Unsubscribe NetInfo events subscription.
48      this.subscription();
49    }
50  }
51
52  async fetchStateAsync() {
53    try {
54      const state = await NetInfo.fetch();
55      this.setState({ connectionInfo: state });
56    } catch (e) {
57      console.warn(e);
58    }
59  }
60
61  handleConnectionChange(connectionInfo: NetInfoState): void {
62    this.setState(({ connectionChangeEvents }) => ({
63      connectionInfo,
64      connectionChangeEvents: [
65        { connectionInfo, time: new Date(), key: this.eventCounter++ },
66        ...connectionChangeEvents,
67      ],
68    }));
69  }
70
71  _renderEvents = (events: ConnectionEvent[]) => {
72    return events.map((event) => (
73      <View key={event.key}>
74        <HeadingText style={{ fontSize: 14 }}>{String(event.time)}</HeadingText>
75        <MonoText key={event.key}>{JSON.stringify(event.connectionInfo, null, 2)}</MonoText>
76      </View>
77    ));
78  };
79
80  render() {
81    return (
82      <ScrollView
83        style={{ flex: 1, backgroundColor: Colors.greyBackground }}
84        contentContainerStyle={{ padding: 10 }}>
85        <HeadingText>NetInfo current state:</HeadingText>
86        <MonoText>{JSON.stringify(this.state.connectionInfo, null, 2)}</MonoText>
87
88        <HeadingText>NetInfo events:</HeadingText>
89        {this._renderEvents(this.state.connectionChangeEvents)}
90      </ScrollView>
91    );
92  }
93}
94