1
1
/**
2
+ * Copyright (c) 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
2
9
* The examples provided by Facebook are for non-commercial testing and
3
10
* evaluation purposes only.
4
11
*
16
23
*/
17
24
'use strict' ;
18
25
26
+ const AppRegistry = require ( 'AppRegistry' ) ;
27
+ const AsyncStorage = require ( 'AsyncStorage' ) ;
28
+ const BackAndroid = require ( 'BackAndroid' ) ;
29
+ const Dimensions = require ( 'Dimensions' ) ;
30
+ const SplitViewWindows = require ( 'SplitViewWindows' ) ;
31
+ const Linking = require ( 'Linking' ) ;
19
32
const React = require ( 'react' ) ;
20
- const ReactNative = require ( 'react-native' ) ;
21
- const {
22
- AppRegistry,
23
- BackAndroid,
24
- Dimensions,
25
- NavigationExperimental,
26
- SplitViewWindows,
27
- StyleSheet,
28
- View,
29
- StatusBar,
30
- } = ReactNative ;
31
- const {
32
- RootContainer : NavigationRootContainer ,
33
- } = NavigationExperimental ;
34
- const UIExplorerActions = require ( './UIExplorerActions' ) ;
33
+ const StatusBar = require ( 'StatusBar' ) ;
34
+ const StyleSheet = require ( 'StyleSheet' ) ;
35
35
const UIExplorerExampleList = require ( './UIExplorerExampleList' ) ;
36
36
const UIExplorerList = require ( './UIExplorerList' ) ;
37
37
const UIExplorerNavigationReducer = require ( './UIExplorerNavigationReducer' ) ;
38
38
const UIExplorerStateTitleMap = require ( './UIExplorerStateTitleMap' ) ;
39
39
const UIExplorerHeaderWindows = require ( './UIExplorerHeaderWindows' ) ;
40
+ const URIActionMap = require ( './URIActionMap' ) ;
41
+ const View = require ( 'View' ) ;
42
+
43
+ const DRAWER_WIDTH_LEFT = 56 ;
40
44
41
- var DRAWER_WIDTH_LEFT = 56 ;
45
+ type Props = {
46
+ exampleFromAppetizeParams : string ,
47
+ } ;
48
+
49
+ type State = {
50
+ initialExampleUri : ?string ,
51
+ } ;
42
52
43
53
class UIExplorerApp extends React . Component {
54
+ _handleAction : Function ;
55
+ _renderPaneContent : Function ;
56
+ state : State ;
57
+ constructor ( props : Props ) {
58
+ super ( props ) ;
59
+ this . _handleAction = this . _handleAction . bind ( this ) ;
60
+ this . _renderPaneContent = this . _renderPaneContent . bind ( this ) ;
61
+ }
62
+
44
63
componentWillMount ( ) {
45
64
BackAndroid . addEventListener ( 'hardwareBackPress' , this . _handleBackButtonPress . bind ( this ) ) ;
46
65
}
47
-
48
- render ( ) {
49
- return (
50
- < NavigationRootContainer
51
- persistenceKey = "UIExplorerStateNavState"
52
- ref = { navRootRef => { this . _navigationRootRef = navRootRef ; } }
53
- reducer = { UIExplorerNavigationReducer }
54
- renderNavigation = { this . _renderApp . bind ( this ) }
55
- />
56
- ) ;
66
+
67
+ componentDidMount ( ) {
68
+ AsyncStorage . getItem ( 'UIExplorerAppState' , ( err , storedString ) => {
69
+ const exampleAction = URIActionMap ( this . props . exampleFromAppetizeParams ) ;
70
+ if ( err || ! storedString ) {
71
+ const initialAction = exampleAction || { type : 'InitialAction' } ;
72
+ this . setState ( UIExplorerNavigationReducer ( null , initialAction ) ) ;
73
+ return ;
74
+ }
75
+ const storedState = JSON . parse ( storedString ) ;
76
+ if ( exampleAction ) {
77
+ this . setState ( UIExplorerNavigationReducer ( storedState , exampleAction ) ) ;
78
+ return ;
79
+ }
80
+ this . setState ( storedState ) ;
81
+ } ) ;
57
82
}
58
-
59
- _renderApp ( navigationState , onNavigate ) {
60
- if ( ! navigationState ) {
83
+
84
+ render ( ) {
85
+ if ( ! this . state ) {
61
86
return null ;
62
87
}
63
88
return (
@@ -72,49 +97,51 @@ class UIExplorerApp extends React.Component {
72
97
this . _overrideBackPressForSplitView = false ;
73
98
} }
74
99
ref = { ( splitView ) => { this . splitView = splitView ; } }
75
- renderPaneView = { this . _renderPaneContent . bind ( this , onNavigate ) } >
76
- { this . _renderNavigation ( navigationState , onNavigate ) }
100
+ renderPaneView = { this . _renderPaneContent }
101
+ statusBarBackgroundColor = "#589c90" >
102
+ { this . _renderApp ( ) }
77
103
</ SplitViewWindows >
78
104
) ;
79
105
}
80
-
81
- _renderPaneContent ( onNavigate ) {
106
+
107
+ _renderPaneContent ( ) {
82
108
return (
83
- < UIExplorerExampleList
84
- list = { UIExplorerList }
85
- displayTitleRow = { true }
86
- disableSearch = { true }
87
- onNavigate = { ( action ) => {
88
- this . splitView && this . splitView . closePane ( ) ;
89
- onNavigate ( action ) ;
90
- } }
91
- />
109
+ < View style = { styles . paneContentWrapper } >
110
+ < UIExplorerExampleList
111
+ list = { UIExplorerList }
112
+ displayTitleRow = { true }
113
+ disableSearch = { true }
114
+ onNavigate = { this . _handleAction }
115
+ />
116
+ </ View >
92
117
) ;
93
118
}
94
119
95
- _renderNavigation ( navigationState , onNavigate ) {
96
- if ( navigationState . externalExample ) {
97
- var Component = UIExplorerList . Modules [ navigationState . externalExample ] ;
120
+ _renderApp ( ) {
121
+ const {
122
+ externalExample,
123
+ stack,
124
+ } = this . state ;
125
+ if ( externalExample ) {
126
+ const Component = UIExplorerList . Modules [ externalExample ] ;
98
127
return (
99
128
< Component
100
129
onExampleExit = { ( ) => {
101
- onNavigate ( NavigationRootContainer . getBackAction ( ) ) ;
130
+ this . _handleAction ( { type : 'BackAction' } ) ;
102
131
} }
103
132
ref = { ( example ) => { this . _exampleRef = example ; } }
104
133
/>
105
134
) ;
106
135
}
107
- const { stack} = navigationState ;
108
136
const title = UIExplorerStateTitleMap ( stack . children [ stack . index ] ) ;
109
- if ( stack && stack . children [ 1 ] ) {
110
- const { key} = stack . children [ 1 ] ;
137
+ const index = stack . children . length <= 1 ? 1 : stack . index ;
138
+
139
+ if ( stack && stack . children [ index ] ) {
140
+ const { key} = stack . children [ index ] ;
111
141
const ExampleModule = UIExplorerList . Modules [ key ] ;
112
142
const ExampleComponent = UIExplorerExampleList . makeRenderable ( ExampleModule ) ;
113
143
return (
114
144
< View style = { styles . container } >
115
- < StatusBar
116
- backgroundColor = "#589c90"
117
- />
118
145
< UIExplorerHeaderWindows
119
146
onPress = { ( ) => this . splitView . openPane ( ) }
120
147
title = { title }
@@ -128,36 +155,47 @@ class UIExplorerApp extends React.Component {
128
155
}
129
156
return (
130
157
< View style = { styles . container } >
131
- < StatusBar
132
- backgroundColor = "#589c90"
133
- />
134
158
< UIExplorerHeaderWindows
135
159
onPress = { ( ) => this . splitView . openPane ( ) }
136
160
title = { title }
137
161
style = { styles . header }
138
162
/>
139
163
< UIExplorerExampleList
164
+ onNavigate = { this . _handleAction }
140
165
list = { UIExplorerList }
141
166
{ ...stack . children [ 0 ] }
142
167
/>
143
168
</ View >
144
169
) ;
145
170
}
146
171
172
+ _handleAction ( action : Object ) : boolean {
173
+ this . splitView && this . splitView . closePane ( ) ;
174
+ const newState = UIExplorerNavigationReducer ( this . state , action ) ;
175
+ if ( this . state !== newState ) {
176
+ this . setState ( newState ) ;
177
+ AsyncStorage . setItem ( 'UIExplorerAppState' , JSON . stringify ( newState ) ) ;
178
+ return true ;
179
+ }
180
+ return false ;
181
+ }
182
+
147
183
_handleBackButtonPress ( ) {
184
+ if ( this . _overrideBackPressForSplitView ) {
185
+ // This hack is necessary because split view provides an imperative API
186
+ // with open and close methods. This code would be cleaner if the split
187
+ // view provided an `isOpen` prop and allowed us to pass a `onPaneClose` handler.
188
+ this . splitView && this . splitView . closePane ( ) ;
189
+ return true ;
190
+ }
148
191
if (
149
192
this . _exampleRef &&
150
193
this . _exampleRef . handleBackAction &&
151
194
this . _exampleRef . handleBackAction ( )
152
195
) {
153
196
return true ;
154
197
}
155
- if ( this . _navigationRootRef ) {
156
- return this . _navigationRootRef . handleNavigation (
157
- NavigationRootContainer . getBackAction ( )
158
- ) ;
159
- }
160
- return false ;
198
+ return this . _handleAction ( { type : 'BackAction' } ) ;
161
199
}
162
200
}
163
201
@@ -168,6 +206,11 @@ const styles = StyleSheet.create({
168
206
header : {
169
207
backgroundColor : '#E9EAED' ,
170
208
} ,
209
+ paneContentWrapper : {
210
+ flex : 1 ,
211
+ paddingTop : StatusBar . currentHeight ,
212
+ backgroundColor : 'white' ,
213
+ } ,
171
214
} ) ;
172
215
173
216
AppRegistry . registerComponent ( 'UIExplorerApp' , ( ) => UIExplorerApp ) ;
0 commit comments