From 5c853c4433a7c8900d7f93fbeb9dc041c2c1b474 Mon Sep 17 00:00:00 2001 From: Eric Vicenti Date: Wed, 11 Mar 2015 20:48:43 -0700 Subject: [PATCH] [ReactNative] AppState cleanup, remove Subscribable, add in OSS examples --- Examples/UIExplorer/AppStateIOSExample.js | 69 ++++++++++++++++++++ Examples/UIExplorer/UIExplorerList.js | 1 + Libraries/AppState/AppState.js | 16 +---- Libraries/AppStateIOS/AppStateIOS.android.js | 24 +++++++ Libraries/AppStateIOS/AppStateIOS.ios.js | 55 ++++++++++++++++ Libraries/react-native/react-native.js | 1 + 6 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 Examples/UIExplorer/AppStateIOSExample.js create mode 100644 Libraries/AppStateIOS/AppStateIOS.android.js create mode 100644 Libraries/AppStateIOS/AppStateIOS.ios.js diff --git a/Examples/UIExplorer/AppStateIOSExample.js b/Examples/UIExplorer/AppStateIOSExample.js new file mode 100644 index 000000000..845b2e049 --- /dev/null +++ b/Examples/UIExplorer/AppStateIOSExample.js @@ -0,0 +1,69 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @providesModule AppStateIOSExample + */ +'use strict'; + +var React = require('react-native'); +var { + AppStateIOS, + Text, + View +} = React; + +var AppStateSubscription = React.createClass({ + getInitialState() { + return { + appState: AppStateIOS.currentState, + previousAppStates: [], + }; + }, + componentDidMount: function() { + AppStateIOS.addEventListener('change', this._handleAppStateChange); + }, + componentWillUnmount: function() { + AppStateIOS.removeEventListener('change', this._handleAppStateChange); + }, + _handleAppStateChange: function(appState) { + var previousAppStates = this.state.previousAppStates.slice(); + previousAppStates.push(this.state.appState); + this.setState({ + appState, + previousAppStates, + }); + }, + render() { + if (this.props.showCurrentOnly) { + return ( + + {this.state.appState} + + ); + } + return ( + + {JSON.stringify(this.state.previousAppStates)} + + ); + } +}); + +exports.title = 'AppStateIOS'; +exports.description = 'iOS app background status'; +exports.examples = [ + { + title: 'AppStateIOS.currentState', + description: 'Can be null on app initialization', + render() { return {AppStateIOS.currentState}; } + }, + { + title: 'Subscribed AppStateIOS:', + description: 'This changes according to the current state, so you can only ever see it rendered as "active"', + render() { return ; } + }, + { + title: 'Previous states:', + render() { return ; } + }, +]; diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js index 456e76b63..ab8aed798 100644 --- a/Examples/UIExplorer/UIExplorerList.js +++ b/Examples/UIExplorer/UIExplorerList.js @@ -40,6 +40,7 @@ var EXAMPLES = [ require('./AsyncStorageExample'), require('./CameraRollExample.ios'), require('./MapViewExample'), + require('./AppStateIOSExample'), require('./AdSupportIOSExample'), require('./AppStateExample'), ]; diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index 691ab9d69..43b9db1a5 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -21,21 +21,9 @@ var AppState = { getApplicationIconBadgeNumber: function(callback) { RKAppState.getApplicationIconBadgeNumber(callback); - } -} + }, -AppState.backgroundStatus = new Subscribable( - RCTDeviceEventEmitter, - 'appStateDidChange', - (resp) => resp.app_state, - RKAppState.getCurrentAppState -); - -AppState.BackgroundStatus = keyMirror({ - active: true, - background: true, - inactive: true, -}); +}; // This check avoids redboxing if native RKReachability library isn't included in app // TODO: Move reachability API into separate JS module to prevent need for this diff --git a/Libraries/AppStateIOS/AppStateIOS.android.js b/Libraries/AppStateIOS/AppStateIOS.android.js new file mode 100644 index 000000000..4bc7e691c --- /dev/null +++ b/Libraries/AppStateIOS/AppStateIOS.android.js @@ -0,0 +1,24 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @providesModule AppStateIOS + */ +'use strict'; + +var warning = require('warning'); + +class AppStateIOS { + + static addEventListener(type, handler) { + warning('Cannot listen to AppStateIOS events on Android.'); + } + + static removeEventListener(type, handler) { + warning('Cannot remove AppStateIOS listener on Android.'); + } + +} + +AppStateIOS.currentState = null; + +module.exports = AppStateIOS; diff --git a/Libraries/AppStateIOS/AppStateIOS.ios.js b/Libraries/AppStateIOS/AppStateIOS.ios.js new file mode 100644 index 000000000..8f03654b5 --- /dev/null +++ b/Libraries/AppStateIOS/AppStateIOS.ios.js @@ -0,0 +1,55 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @providesModule AppStateIOS + */ +'use strict'; + +var NativeModules = require('NativeModules'); +var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +var RKAppState = NativeModules.RKAppState; + +var logError = require('logError'); + +var DEVICE_APPSTATE_EVENT = 'appStateDidChange'; + +var _appStateHandlers = {}; + +class AppStateIOS { + + static addEventListener(type, handler) { + _appStateHandlers[handler] = RCTDeviceEventEmitter.addListener( + DEVICE_APPSTATE_EVENT, + (appStateData) => { + handler(appStateData.app_state); + } + ); + } + + static removeEventListener(type, handler) { + if (!_appStateHandlers[handler]) { + return; + } + _appStateHandlers[handler].remove(); + _appStateHandlers[handler] = null; + } + +} + +AppStateIOS.currentState = null; + +RCTDeviceEventEmitter.addListener( + DEVICE_APPSTATE_EVENT, + (appStateData) => { + AppStateIOS.currentState = appStateData.app_state; + } +); + +RKAppState.getCurrentAppState( + (appStateData) => { + AppStateIOS.currentState = appStateData.app_state; + }, + logError +); + +module.exports = AppStateIOS; diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js index 18c590c97..48217795f 100644 --- a/Libraries/react-native/react-native.js +++ b/Libraries/react-native/react-native.js @@ -11,6 +11,7 @@ var ReactNative = { ActivityIndicatorIOS: require('ActivityIndicatorIOS'), AppRegistry: require('AppRegistry'), AppState: require('AppState'), + AppStateIOS: require('AppStateIOS'), AsyncStorage: require('AsyncStorage'), CameraRoll: require('CameraRoll'), DatePickerIOS: require('DatePickerIOS'),