[React Native] Persist open UIExplorer example between refreshes

This commit is contained in:
Alex Akers 2015-07-02 09:34:34 -07:00
parent 54825b304a
commit 00e85cbc85
3 changed files with 79 additions and 24 deletions

View File

@ -43,6 +43,7 @@ var UIExplorerApp = React.createClass({
/> />
); );
} }
return ( return (
<NavigatorIOS <NavigatorIOS
style={styles.container} style={styles.container}

View File

@ -32,6 +32,7 @@ var {
var { TestModule } = React.addons; var { TestModule } = React.addons;
import type { ExampleModule } from 'ExampleTypes'; import type { ExampleModule } from 'ExampleTypes';
import type { NavigationContext } from 'NavigationContext';
var createExamplePage = require('./createExamplePage'); var createExamplePage = require('./createExamplePage');
@ -129,7 +130,10 @@ COMPONENTS.concat(APIS).forEach((Example) => {
}); });
type Props = { type Props = {
navigator: Array<{title: string, component: ReactClass<any,any,any>}>, navigator: {
navigationContext: NavigationContext,
push: (route: {title: string, component: ReactClass<any,any,any>}) => void,
},
onExternalExampleRequested: Function, onExternalExampleRequested: Function,
onSelectExample: Function, onSelectExample: Function,
isInDrawer: bool, isInDrawer: bool,
@ -149,8 +153,25 @@ class UIExplorerList extends React.Component {
}; };
} }
componentWillMount() {
this.props.navigator.navigationContext.addListener('didfocus', function(event) {
if (event.data.route.title === 'UIExplorer') {
Settings.set({visibleExample: null});
}
});
}
componentDidMount() { componentDidMount() {
this._search(this.state.searchText); this._search(this.state.searchText);
var visibleExampleTitle = Settings.get('visibleExample');
if (visibleExampleTitle) {
var predicate = (example) => example.title === visibleExampleTitle;
var foundExample = APIS.find(predicate) || COMPONENTS.find(predicate);
if (foundExample) {
setTimeout(() => this._openExample(foundExample), 100);
}
}
} }
render() { render() {
@ -240,11 +261,12 @@ class UIExplorerList extends React.Component {
Settings.set({searchText: text}); Settings.set({searchText: text});
} }
_onPressRow(example: any) { _openExample(example: any) {
if (example.external) { if (example.external) {
this.props.onExternalExampleRequested(example); this.props.onExternalExampleRequested(example);
return; return;
} }
var Component = makeRenderable(example); var Component = makeRenderable(example);
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
this.props.navigator.push({ this.props.navigator.push({
@ -258,6 +280,11 @@ class UIExplorerList extends React.Component {
}); });
} }
} }
_onPressRow(example: any) {
Settings.set({visibleExample: example.title});
this._openExample(example);
}
} }
var styles = StyleSheet.create({ var styles = StyleSheet.create({

View File

@ -13,6 +13,7 @@
var EventEmitter = require('EventEmitter'); var EventEmitter = require('EventEmitter');
var Image = require('Image'); var Image = require('Image');
var NavigationContext = require('NavigationContext');
var React = require('React'); var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var RCTNavigatorManager = require('NativeModules').NavigatorManager; var RCTNavigatorManager = require('NativeModules').NavigatorManager;
@ -309,6 +310,7 @@ var NavigatorIOS = React.createClass({
}, },
navigator: (undefined: ?Object), navigator: (undefined: ?Object),
navigationContext: new NavigationContext(),
componentWillMount: function() { componentWillMount: function() {
// Precompute a pack of callbacks that's frequently generated and passed to // Precompute a pack of callbacks that's frequently generated and passed to
@ -323,7 +325,18 @@ var NavigatorIOS = React.createClass({
resetTo: this.resetTo, resetTo: this.resetTo,
popToRoute: this.popToRoute, popToRoute: this.popToRoute,
popToTop: this.popToTop, popToTop: this.popToTop,
navigationContext: this.navigationContext,
}; };
this._emitWillFocus(this.state.routeStack[this.state.observedTopOfStack]);
},
componentDidMount: function() {
this._emitDidFocus(this.state.routeStack[this.state.observedTopOfStack]);
},
componentWillUnmount: function() {
this.navigationContext.dispose();
this.navigationContext = new NavigationContext();
}, },
getInitialState: function(): State { getInitialState: function(): State {
@ -397,6 +410,8 @@ var NavigatorIOS = React.createClass({
_handleNavigatorStackChanged: function(e: Event) { _handleNavigatorStackChanged: function(e: Event) {
var newObservedTopOfStack = e.nativeEvent.stackLength - 1; var newObservedTopOfStack = e.nativeEvent.stackLength - 1;
this._emitDidFocus(this.state.routeStack[newObservedTopOfStack]);
invariant( invariant(
newObservedTopOfStack <= this.state.requestedTopOfStack, newObservedTopOfStack <= this.state.requestedTopOfStack,
'No navigator item should be pushed without JS knowing about it %s %s', newObservedTopOfStack, this.state.requestedTopOfStack 'No navigator item should be pushed without JS knowing about it %s %s', newObservedTopOfStack, this.state.requestedTopOfStack
@ -448,11 +463,21 @@ var NavigatorIOS = React.createClass({
}); });
}, },
_emitDidFocus: function(route: Route) {
this.navigationContext.emit('didfocus', {route: route});
},
_emitWillFocus: function(route: Route) {
this.navigationContext.emit('willfocus', {route: route});
},
push: function(route: Route) { push: function(route: Route) {
invariant(!!route, 'Must supply route to push'); invariant(!!route, 'Must supply route to push');
// Make sure all previous requests are caught up first. Otherwise reject. // Make sure all previous requests are caught up first. Otherwise reject.
if (this.state.requestedTopOfStack === this.state.observedTopOfStack) { if (this.state.requestedTopOfStack === this.state.observedTopOfStack) {
this._tryLockNavigator(() => { this._tryLockNavigator(() => {
this._emitWillFocus(route);
var nextStack = this.state.routeStack.concat([route]); var nextStack = this.state.routeStack.concat([route]);
var nextIDStack = this.state.idStack.concat([getuid()]); var nextIDStack = this.state.idStack.concat([getuid()]);
this.setState({ this.setState({
@ -476,12 +501,11 @@ var NavigatorIOS = React.createClass({
if (this.state.requestedTopOfStack === this.state.observedTopOfStack) { if (this.state.requestedTopOfStack === this.state.observedTopOfStack) {
if (this.state.requestedTopOfStack > 0) { if (this.state.requestedTopOfStack > 0) {
this._tryLockNavigator(() => { this._tryLockNavigator(() => {
invariant( var newRequestedTopOfStack = this.state.requestedTopOfStack - n;
this.state.requestedTopOfStack - n >= 0, invariant(newRequestedTopOfStack >= 0, 'Cannot pop below 0');
'Cannot pop below 0' this._emitWillFocus(this.state.routeStack[newRequestedTopOfStack]);
);
this.setState({ this.setState({
requestedTopOfStack: this.state.requestedTopOfStack - n, requestedTopOfStack: newRequestedTopOfStack,
makingNavigatorRequest: true, makingNavigatorRequest: true,
// Not actually updating the indices yet until we get the native // Not actually updating the indices yet until we get the native
// `onNavigationComplete`. // `onNavigationComplete`.
@ -525,6 +549,9 @@ var NavigatorIOS = React.createClass({
makingNavigatorRequest: false, makingNavigatorRequest: false,
updatingAllIndicesAtOrBeyond: index, updatingAllIndicesAtOrBeyond: index,
}); });
this._emitWillFocus(route);
this._emitDidFocus(route);
}, },
/** /**
@ -659,7 +686,7 @@ var NavigatorIOS = React.createClass({
{this.renderNavigationStackItems()} {this.renderNavigationStackItems()}
</View> </View>
); );
} },
}); });
var styles = StyleSheet.create({ var styles = StyleSheet.create({