2015-01-30 01:10:49 +00:00
|
|
|
/**
|
2016-03-24 22:48:27 +00:00
|
|
|
* Copyright (c) 2013-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.
|
|
|
|
*
|
2015-03-26 18:24:15 +00:00
|
|
|
* The examples provided by Facebook are for non-commercial testing and
|
|
|
|
* evaluation purposes only.
|
2015-03-23 22:07:33 +00:00
|
|
|
*
|
2015-03-26 18:24:15 +00:00
|
|
|
* Facebook reserves all rights not expressly granted.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2015-01-30 01:10:49 +00:00
|
|
|
*
|
|
|
|
* @providesModule UIExplorerApp
|
2016-02-23 00:15:35 +00:00
|
|
|
* @flow
|
2015-01-30 01:10:49 +00:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2016-05-05 23:51:34 +00:00
|
|
|
const AsyncStorage = require('AsyncStorage');
|
|
|
|
const Linking = require('Linking');
|
2016-04-09 03:36:40 +00:00
|
|
|
const React = require('react');
|
|
|
|
const ReactNative = require('react-native');
|
2016-02-20 00:55:07 +00:00
|
|
|
const UIExplorerList = require('./UIExplorerList.ios');
|
2016-02-23 00:15:35 +00:00
|
|
|
const UIExplorerExampleList = require('./UIExplorerExampleList');
|
|
|
|
const UIExplorerNavigationReducer = require('./UIExplorerNavigationReducer');
|
|
|
|
const UIExplorerStateTitleMap = require('./UIExplorerStateTitleMap');
|
2016-04-04 13:04:54 +00:00
|
|
|
const URIActionMap = require('./URIActionMap');
|
2016-02-23 00:15:35 +00:00
|
|
|
|
2016-02-20 00:55:07 +00:00
|
|
|
const {
|
2015-02-19 14:57:05 +00:00
|
|
|
AppRegistry,
|
2016-02-23 00:15:35 +00:00
|
|
|
NavigationExperimental,
|
|
|
|
SnapshotViewIOS,
|
2015-01-30 01:10:49 +00:00
|
|
|
StyleSheet,
|
2016-02-03 14:40:39 +00:00
|
|
|
View,
|
2016-04-09 03:36:40 +00:00
|
|
|
} = ReactNative;
|
2016-02-29 21:21:43 +00:00
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
const {
|
2016-03-04 22:56:37 +00:00
|
|
|
CardStack: NavigationCardStack,
|
2016-02-23 00:15:35 +00:00
|
|
|
Header: NavigationHeader,
|
|
|
|
} = NavigationExperimental;
|
2015-03-12 19:51:44 +00:00
|
|
|
|
2016-03-04 22:56:37 +00:00
|
|
|
import type { NavigationSceneRendererProps } from 'NavigationTypeDefinition';
|
2016-02-29 21:21:43 +00:00
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
import type { UIExplorerNavigationState } from './UIExplorerNavigationReducer';
|
2015-03-25 02:34:12 +00:00
|
|
|
|
2016-02-29 21:21:43 +00:00
|
|
|
import type { UIExplorerExample } from './UIExplorerList.ios';
|
2016-02-23 00:15:35 +00:00
|
|
|
|
2016-04-04 13:04:54 +00:00
|
|
|
type Props = {
|
|
|
|
exampleFromAppetizeParams: string,
|
|
|
|
};
|
2016-02-23 00:15:44 +00:00
|
|
|
|
2016-05-05 23:51:34 +00:00
|
|
|
type State = UIExplorerNavigationState & {
|
|
|
|
externalExample?: string,
|
2016-04-04 13:04:54 +00:00
|
|
|
};
|
2016-02-23 00:15:44 +00:00
|
|
|
|
2016-05-27 22:30:59 +00:00
|
|
|
const APP_STATE_KEY = 'UIExplorerAppState.v1';
|
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
class UIExplorerApp extends React.Component {
|
2016-06-10 00:48:39 +00:00
|
|
|
_handleBack: Function;
|
|
|
|
_handleAction: Function;
|
|
|
|
_renderCard: Function;
|
NavigationExperimental: Rename `renderOverlay` to `renderHeader`
Summary:
NavigationCardStack is a custom component, and its API should be explicit, not
too generic..
In NavigationCardStack, the prop `renderOverlay` is actually used to render
the NavigationHeader, and we uses absolute position to build the layout for
the header and the body.
One of the problem with using absolute postion and fixed height to build the
layout that contains the header is that the header can't have variant height
easily.
Ideally, if the layout for the header used flex-box, we'd ve able to be more
adaptive to deal with the header that has variant height.
That said, let's rename `renderOverlay` to `renderHeader`, then build the
proper layout that explicitly works better with the header.
If we to need to support overlay in navigation, we may consider add
`renderOverlay` later, if it's really necessary.
Reviewed By: ericvicenti
Differential Revision: D3670224
fbshipit-source-id: ff04acfe9dc995cb57117b3fd9b07d5f97b9c6ee
2016-08-04 18:16:40 +00:00
|
|
|
_renderHeader: Function;
|
2016-02-29 21:21:43 +00:00
|
|
|
_renderScene: Function;
|
2016-03-24 22:48:27 +00:00
|
|
|
_renderTitleComponent: Function;
|
2016-04-04 13:04:54 +00:00
|
|
|
state: State;
|
2016-05-05 23:51:34 +00:00
|
|
|
|
2016-04-04 13:04:54 +00:00
|
|
|
constructor(props: Props) {
|
|
|
|
super(props);
|
|
|
|
}
|
2016-05-05 23:51:34 +00:00
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
componentWillMount() {
|
2016-05-05 23:51:34 +00:00
|
|
|
this._handleAction = this._handleAction.bind(this);
|
2016-06-10 00:48:39 +00:00
|
|
|
this._handleBack = this._handleAction.bind(this, {type: 'back'});
|
NavigationExperimental: Rename `renderOverlay` to `renderHeader`
Summary:
NavigationCardStack is a custom component, and its API should be explicit, not
too generic..
In NavigationCardStack, the prop `renderOverlay` is actually used to render
the NavigationHeader, and we uses absolute position to build the layout for
the header and the body.
One of the problem with using absolute postion and fixed height to build the
layout that contains the header is that the header can't have variant height
easily.
Ideally, if the layout for the header used flex-box, we'd ve able to be more
adaptive to deal with the header that has variant height.
That said, let's rename `renderOverlay` to `renderHeader`, then build the
proper layout that explicitly works better with the header.
If we to need to support overlay in navigation, we may consider add
`renderOverlay` later, if it's really necessary.
Reviewed By: ericvicenti
Differential Revision: D3670224
fbshipit-source-id: ff04acfe9dc995cb57117b3fd9b07d5f97b9c6ee
2016-08-04 18:16:40 +00:00
|
|
|
this._renderHeader = this._renderHeader.bind(this);
|
2016-02-29 21:21:43 +00:00
|
|
|
this._renderScene = this._renderScene.bind(this);
|
2016-03-24 22:48:27 +00:00
|
|
|
this._renderTitleComponent = this._renderTitleComponent.bind(this);
|
2016-02-23 00:15:35 +00:00
|
|
|
}
|
2016-05-05 23:51:34 +00:00
|
|
|
|
2016-04-04 13:04:54 +00:00
|
|
|
componentDidMount() {
|
2016-05-05 23:51:34 +00:00
|
|
|
Linking.getInitialURL().then((url) => {
|
2016-05-27 22:30:59 +00:00
|
|
|
AsyncStorage.getItem(APP_STATE_KEY, (err, storedString) => {
|
2016-05-05 23:51:34 +00:00
|
|
|
const exampleAction = URIActionMap(this.props.exampleFromAppetizeParams);
|
|
|
|
const urlAction = URIActionMap(url);
|
|
|
|
const launchAction = exampleAction || urlAction;
|
|
|
|
if (err || !storedString) {
|
|
|
|
const initialAction = launchAction || {type: 'InitialAction'};
|
|
|
|
this.setState(UIExplorerNavigationReducer(null, initialAction));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const storedState = JSON.parse(storedString);
|
|
|
|
if (launchAction) {
|
|
|
|
this.setState(UIExplorerNavigationReducer(storedState, launchAction));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.setState(storedState);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
Linking.addEventListener('url', (url) => {
|
|
|
|
this._handleAction(URIActionMap(url));
|
|
|
|
});
|
2016-02-23 00:15:35 +00:00
|
|
|
}
|
2016-05-05 23:51:34 +00:00
|
|
|
|
|
|
|
_handleAction(action: Object) {
|
|
|
|
if (!action) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const newState = UIExplorerNavigationReducer(this.state, action);
|
|
|
|
if (this.state !== newState) {
|
|
|
|
this.setState(newState);
|
2016-05-27 22:30:59 +00:00
|
|
|
AsyncStorage.setItem(APP_STATE_KEY, JSON.stringify(this.state));
|
2016-04-04 13:04:54 +00:00
|
|
|
}
|
|
|
|
}
|
2016-05-05 23:51:34 +00:00
|
|
|
|
|
|
|
render() {
|
|
|
|
if (!this.state) {
|
2016-02-23 00:15:35 +00:00
|
|
|
return null;
|
|
|
|
}
|
2016-05-05 23:51:34 +00:00
|
|
|
if (this.state.externalExample) {
|
|
|
|
const Component = UIExplorerList.Modules[this.state.externalExample];
|
2015-03-25 02:34:12 +00:00
|
|
|
return (
|
2016-02-23 00:15:35 +00:00
|
|
|
<Component
|
2015-03-25 02:34:12 +00:00
|
|
|
onExampleExit={() => {
|
2016-05-05 23:51:34 +00:00
|
|
|
this._handleAction({ type: 'BackAction' });
|
2015-03-25 02:34:12 +00:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2016-02-23 00:15:35 +00:00
|
|
|
return (
|
2016-03-04 22:56:37 +00:00
|
|
|
<NavigationCardStack
|
2016-05-05 23:51:34 +00:00
|
|
|
navigationState={this.state.stack}
|
2016-02-23 00:15:35 +00:00
|
|
|
style={styles.container}
|
NavigationExperimental: Rename `renderOverlay` to `renderHeader`
Summary:
NavigationCardStack is a custom component, and its API should be explicit, not
too generic..
In NavigationCardStack, the prop `renderOverlay` is actually used to render
the NavigationHeader, and we uses absolute position to build the layout for
the header and the body.
One of the problem with using absolute postion and fixed height to build the
layout that contains the header is that the header can't have variant height
easily.
Ideally, if the layout for the header used flex-box, we'd ve able to be more
adaptive to deal with the header that has variant height.
That said, let's rename `renderOverlay` to `renderHeader`, then build the
proper layout that explicitly works better with the header.
If we to need to support overlay in navigation, we may consider add
`renderOverlay` later, if it's really necessary.
Reviewed By: ericvicenti
Differential Revision: D3670224
fbshipit-source-id: ff04acfe9dc995cb57117b3fd9b07d5f97b9c6ee
2016-08-04 18:16:40 +00:00
|
|
|
renderHeader={this._renderHeader}
|
2016-03-04 22:56:37 +00:00
|
|
|
renderScene={this._renderScene}
|
2016-08-04 19:39:02 +00:00
|
|
|
onNavigateBack={this._handleBack}
|
2016-02-23 00:15:35 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2015-07-02 16:34:34 +00:00
|
|
|
|
NavigationExperimental: Rename `renderOverlay` to `renderHeader`
Summary:
NavigationCardStack is a custom component, and its API should be explicit, not
too generic..
In NavigationCardStack, the prop `renderOverlay` is actually used to render
the NavigationHeader, and we uses absolute position to build the layout for
the header and the body.
One of the problem with using absolute postion and fixed height to build the
layout that contains the header is that the header can't have variant height
easily.
Ideally, if the layout for the header used flex-box, we'd ve able to be more
adaptive to deal with the header that has variant height.
That said, let's rename `renderOverlay` to `renderHeader`, then build the
proper layout that explicitly works better with the header.
If we to need to support overlay in navigation, we may consider add
`renderOverlay` later, if it's really necessary.
Reviewed By: ericvicenti
Differential Revision: D3670224
fbshipit-source-id: ff04acfe9dc995cb57117b3fd9b07d5f97b9c6ee
2016-08-04 18:16:40 +00:00
|
|
|
_renderHeader(props: NavigationSceneRendererProps): ReactElement<any> {
|
2015-07-02 16:34:34 +00:00
|
|
|
return (
|
2016-02-23 00:15:35 +00:00
|
|
|
<NavigationHeader
|
2016-03-24 22:48:27 +00:00
|
|
|
{...props}
|
2016-06-10 00:48:39 +00:00
|
|
|
onNavigateBack={this._handleBack}
|
2016-03-24 22:48:27 +00:00
|
|
|
renderTitleComponent={this._renderTitleComponent}
|
2016-02-23 00:15:35 +00:00
|
|
|
/>
|
2016-02-29 21:21:43 +00:00
|
|
|
);
|
2016-02-23 00:15:35 +00:00
|
|
|
}
|
|
|
|
|
2016-05-25 01:20:12 +00:00
|
|
|
_renderTitleComponent(props: NavigationSceneRendererProps): ReactElement<any> {
|
2016-03-24 22:48:27 +00:00
|
|
|
return (
|
|
|
|
<NavigationHeader.Title>
|
2016-05-21 01:09:57 +00:00
|
|
|
{UIExplorerStateTitleMap(props.scene.route)}
|
2016-03-24 22:48:27 +00:00
|
|
|
</NavigationHeader.Title>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-05-25 01:20:12 +00:00
|
|
|
_renderScene(props: NavigationSceneRendererProps): ?ReactElement<any> {
|
2016-05-21 01:09:57 +00:00
|
|
|
const state = props.scene.route;
|
2016-02-23 00:15:35 +00:00
|
|
|
if (state.key === 'AppList') {
|
|
|
|
return (
|
|
|
|
<UIExplorerExampleList
|
2016-05-05 23:51:34 +00:00
|
|
|
onNavigate={this._handleAction}
|
2016-02-23 00:15:35 +00:00
|
|
|
list={UIExplorerList}
|
|
|
|
style={styles.exampleContainer}
|
|
|
|
{...state}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const Example = UIExplorerList.Modules[state.key];
|
|
|
|
if (Example) {
|
|
|
|
const Component = UIExplorerExampleList.makeRenderable(Example);
|
|
|
|
return (
|
|
|
|
<View style={styles.exampleContainer}>
|
|
|
|
<Component />
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2016-02-20 00:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
2015-01-30 01:10:49 +00:00
|
|
|
container: {
|
|
|
|
flex: 1,
|
|
|
|
},
|
2016-02-23 00:15:35 +00:00
|
|
|
exampleContainer: {
|
|
|
|
flex: 1,
|
2015-01-30 01:10:49 +00:00
|
|
|
},
|
2015-11-12 19:40:02 +00:00
|
|
|
});
|
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
AppRegistry.registerComponent('SetPropertiesExampleApp', () => require('./SetPropertiesExampleApp'));
|
|
|
|
AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () => require('./RootViewSizeFlexibilityExampleApp'));
|
2015-02-19 14:57:05 +00:00
|
|
|
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
2016-02-23 00:15:35 +00:00
|
|
|
|
|
|
|
// Register suitable examples for snapshot tests
|
|
|
|
UIExplorerList.ComponentExamples.concat(UIExplorerList.APIExamples).forEach((Example: UIExplorerExample) => {
|
|
|
|
const ExampleModule = Example.module;
|
|
|
|
if (ExampleModule.displayName) {
|
2016-07-26 08:00:02 +00:00
|
|
|
class Snapshotter extends React.Component {
|
|
|
|
render() {
|
2016-05-05 23:51:34 +00:00
|
|
|
const Renderable = UIExplorerExampleList.makeRenderable(ExampleModule);
|
2016-02-23 00:15:35 +00:00
|
|
|
return (
|
|
|
|
<SnapshotViewIOS>
|
|
|
|
<Renderable />
|
|
|
|
</SnapshotViewIOS>
|
|
|
|
);
|
2016-07-26 08:00:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-23 00:15:35 +00:00
|
|
|
AppRegistry.registerComponent(ExampleModule.displayName, () => Snapshotter);
|
|
|
|
}
|
|
|
|
});
|
2015-01-30 01:10:49 +00:00
|
|
|
|
|
|
|
module.exports = UIExplorerApp;
|