UNPKG

4 kBPlain TextView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @format
8 */
9
10import {NativeEventSubscription} from 'react-native';
11import NativeInterface from './nativeInterface';
12import InternetReachability from './internetReachability';
13import * as Types from './types';
14import * as PrivateTypes from './privateTypes';
15
16export default class State {
17 private _nativeEventSubscription: NativeEventSubscription | null = null;
18 private _subscriptions = new Set<Types.NetInfoChangeHandler>();
19 private _latestState: Types.NetInfoState | null = null;
20 private _internetReachability: InternetReachability;
21
22 constructor(configuration: Types.NetInfoConfiguration) {
23 // Add the listener to the internet connectivity events
24 this._internetReachability = new InternetReachability(
25 configuration,
26 this._handleInternetReachabilityUpdate,
27 );
28
29 // Add the subscription to the native events
30 this._nativeEventSubscription = NativeInterface.eventEmitter.addListener(
31 PrivateTypes.DEVICE_CONNECTIVITY_EVENT,
32 this._handleNativeStateUpdate,
33 );
34
35 // Fetch the current state from the native module
36 this._fetchCurrentState();
37 }
38
39 private _handleNativeStateUpdate = (
40 state: PrivateTypes.NetInfoNativeModuleState,
41 ): void => {
42 // Update the internet reachability module
43 this._internetReachability.update(state);
44
45 // Convert the state from native to JS shape
46 const convertedState = this._convertState(state);
47
48 // Update the listeners
49 this._latestState = convertedState;
50 this._subscriptions.forEach((handler): void => handler(convertedState));
51 };
52
53 private _handleInternetReachabilityUpdate = (
54 isInternetReachable: boolean | null | undefined,
55 ): void => {
56 if (!this._latestState) {
57 return;
58 }
59
60 const nextState = {
61 ...this._latestState,
62 isInternetReachable,
63 } as Types.NetInfoState;
64 this._latestState = nextState;
65 this._subscriptions.forEach((handler): void => handler(nextState));
66 };
67
68 private _fetchCurrentState = async (
69 requestedInterface?: string,
70 ): Promise<Types.NetInfoState> => {
71 const state = await NativeInterface.getCurrentState(requestedInterface);
72
73 // Update the internet reachability module
74 this._internetReachability.update(state);
75 // Convert and store the new state
76 const convertedState = this._convertState(state);
77 if (!requestedInterface) {
78 this._latestState = convertedState;
79 }
80
81 return convertedState;
82 };
83
84 private _convertState = (
85 input: PrivateTypes.NetInfoNativeModuleState,
86 ): Types.NetInfoState => {
87 if (typeof input.isInternetReachable === 'boolean') {
88 return input as Types.NetInfoState;
89 } else {
90 return {
91 ...input,
92 isInternetReachable: this._internetReachability.currentState(),
93 } as Types.NetInfoState;
94 }
95 };
96
97 public latest = (
98 requestedInterface?: string,
99 ): Promise<Types.NetInfoState> => {
100 if (requestedInterface) {
101 return this._fetchCurrentState(requestedInterface);
102 } else if (this._latestState) {
103 return Promise.resolve(this._latestState);
104 } else {
105 return this._fetchCurrentState();
106 }
107 };
108
109 public add = (handler: Types.NetInfoChangeHandler): void => {
110 // Add the subscription handler to our set
111 this._subscriptions.add(handler);
112
113 // Send it the latest data we have
114 if (this._latestState) {
115 handler(this._latestState);
116 } else {
117 this.latest().then(handler);
118 }
119 };
120
121 public remove = (handler: Types.NetInfoChangeHandler): void => {
122 this._subscriptions.delete(handler);
123 };
124
125 public tearDown = (): void => {
126 if (this._internetReachability) {
127 this._internetReachability.tearDown();
128 }
129
130 if (this._nativeEventSubscription) {
131 this._nativeEventSubscription.remove();
132 }
133
134 this._subscriptions.clear();
135 };
136}