mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 09:12:02 +00:00
cb45eaa0e8
Summary: public Map and Set are a standard JavaScript features, but are only supported in a subset of JSC versions that we target (e.g. iOS 7's JSC doesn't support Set). The consequence of this is that failing to require('Set') before using it won't error during testing on a modern OS, but will fail on older OS versions. This diff makes the Map and Set polyfills available globally to all RN apps to avoid that problem. Reviewed By: davidaurelio Differential Revision: D2833997 fb-gh-sync-id: 713d8b69f6a1bce2472a1b2e6b84f69d75f30289
147 lines
4.2 KiB
JavaScript
147 lines
4.2 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule AppStateIOS
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
var NativeModules = require('NativeModules');
|
|
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
|
var RCTAppState = NativeModules.AppState;
|
|
|
|
var logError = require('logError');
|
|
var invariant = require('invariant');
|
|
|
|
var _eventHandlers = {
|
|
change: new Map(),
|
|
memoryWarning: new Map(),
|
|
};
|
|
|
|
/**
|
|
* `AppStateIOS` can tell you if the app is in the foreground or background,
|
|
* and notify you when the state changes.
|
|
*
|
|
* AppStateIOS is frequently used to determine the intent and proper behavior when
|
|
* handling push notifications.
|
|
*
|
|
* ### iOS App States
|
|
*
|
|
* - `active` - The app is running in the foreground
|
|
* - `background` - The app is running in the background. The user is either
|
|
* in another app or on the home screen
|
|
* - `inactive` - This is a transition state that currently never happens for
|
|
* typical React Native apps.
|
|
*
|
|
* For more information, see
|
|
* [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html)
|
|
*
|
|
* ### Basic Usage
|
|
*
|
|
* To see the current state, you can check `AppStateIOS.currentState`, which
|
|
* will be kept up-to-date. However, `currentState` will be null at launch
|
|
* while `AppStateIOS` retrieves it over the bridge.
|
|
*
|
|
* ```
|
|
* getInitialState: function() {
|
|
* return {
|
|
* currentAppState: AppStateIOS.currentState,
|
|
* };
|
|
* },
|
|
* componentDidMount: function() {
|
|
* AppStateIOS.addEventListener('change', this._handleAppStateChange);
|
|
* },
|
|
* componentWillUnmount: function() {
|
|
* AppStateIOS.removeEventListener('change', this._handleAppStateChange);
|
|
* },
|
|
* _handleAppStateChange: function(currentAppState) {
|
|
* this.setState({ currentAppState, });
|
|
* },
|
|
* render: function() {
|
|
* return (
|
|
* <Text>Current state is: {this.state.currentAppState}</Text>
|
|
* );
|
|
* },
|
|
* ```
|
|
*
|
|
* This example will only ever appear to say "Current state is: active" because
|
|
* the app is only visible to the user when in the `active` state, and the null
|
|
* state will happen only momentarily.
|
|
*/
|
|
|
|
var AppStateIOS = {
|
|
|
|
/**
|
|
* Add a handler to AppState changes by listening to the `change` event type
|
|
* and providing the handler
|
|
*/
|
|
addEventListener: function(
|
|
type: string,
|
|
handler: Function
|
|
) {
|
|
invariant(
|
|
['change', 'memoryWarning'].indexOf(type) !== -1,
|
|
'Trying to subscribe to unknown event: "%s"', type
|
|
);
|
|
if (type === 'change') {
|
|
_eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener(
|
|
'appStateDidChange',
|
|
(appStateData) => {
|
|
handler(appStateData.app_state);
|
|
}
|
|
));
|
|
} else if (type === 'memoryWarning') {
|
|
_eventHandlers[type].set(handler, RCTDeviceEventEmitter.addListener(
|
|
'memoryWarning',
|
|
handler
|
|
));
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Remove a handler by passing the `change` event type and the handler
|
|
*/
|
|
removeEventListener: function(
|
|
type: string,
|
|
handler: Function
|
|
) {
|
|
invariant(
|
|
['change', 'memoryWarning'].indexOf(type) !== -1,
|
|
'Trying to remove listener for unknown event: "%s"', type
|
|
);
|
|
if (!_eventHandlers[type].has(handler)) {
|
|
return;
|
|
}
|
|
_eventHandlers[type].get(handler).remove();
|
|
_eventHandlers[type].delete(handler);
|
|
},
|
|
|
|
// TODO: getCurrentAppState callback seems to be called at a really late stage
|
|
// after app launch. Trying to get currentState when mounting App component
|
|
// will likely to have the initial value here.
|
|
// Initialize to 'active' instead of null.
|
|
currentState: ('active' : ?string),
|
|
|
|
};
|
|
|
|
RCTDeviceEventEmitter.addListener(
|
|
'appStateDidChange',
|
|
(appStateData) => {
|
|
AppStateIOS.currentState = appStateData.app_state;
|
|
}
|
|
);
|
|
|
|
RCTAppState.getCurrentAppState(
|
|
(appStateData) => {
|
|
AppStateIOS.currentState = appStateData.app_state;
|
|
},
|
|
logError
|
|
);
|
|
|
|
module.exports = AppStateIOS;
|