Browse Source

Destroy modals on setRoot (#5302)

When setRoot is called, modals should be destroyed, while Overlay components can remain on screen.
Guy Carmeli 5 years ago
parent
commit
f06787dec9
No account linked to committer's email address

+ 6
- 0
e2e/Modals.test.js View File

118
     await expect(elementByLabel('Modal Stack Position: 1')).toBeVisible();
118
     await expect(elementByLabel('Modal Stack Position: 1')).toBeVisible();
119
   });
119
   });
120
 
120
 
121
+  it('setRoot dismisses modals', async () => {
122
+    await elementById(TestIDs.SET_ROOT).tap();
123
+    await expect(elementById(TestIDs.MODAL_SCREEN_HEADER)).toBeNotVisible();
124
+    await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
125
+  });
126
+
121
   it(':android: override hardware back button in modal with stack', async () => {
127
   it(':android: override hardware back button in modal with stack', async () => {
122
     await elementById(TestIDs.PUSH_BTN).tap();
128
     await elementById(TestIDs.PUSH_BTN).tap();
123
     await elementById(TestIDs.ADD_BACK_HANDLER).tap();
129
     await elementById(TestIDs.ADD_BACK_HANDLER).tap();

+ 6
- 5
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/navigator/Navigator.java View File

50
         return defaultOptions;
50
         return defaultOptions;
51
     }
51
     }
52
 
52
 
53
-    public FrameLayout getRootLayout() {
53
+    FrameLayout getRootLayout() {
54
         return rootLayout;
54
         return rootLayout;
55
     }
55
     }
56
 
56
 
129
 
129
 
130
     public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
130
     public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
131
         destroyRoot();
131
         destroyRoot();
132
+        modalStack.destroy();
132
         final boolean removeSplashView = isRootNotCreated();
133
         final boolean removeSplashView = isRootNotCreated();
133
         if (isRootNotCreated()) getView();
134
         if (isRootNotCreated()) getView();
134
         root = viewController;
135
         root = viewController;
138
                 if (removeSplashView) removePreviousContentView();
139
                 if (removeSplashView) removePreviousContentView();
139
                 super.onSuccess(childId);
140
                 super.onSuccess(childId);
140
             }
141
             }
141
-        }, reactInstanceManager);
142
-    }
143
 
142
 
144
-    private void removePreviousContentView() {
145
-        contentLayout.removeViewAt(0);
143
+            private void removePreviousContentView() {
144
+                contentLayout.removeViewAt(0);
145
+            }
146
+        }, reactInstanceManager);
146
     }
147
     }
147
 
148
 
148
     public void mergeOptions(final String componentId, Options options) {
149
     public void mergeOptions(final String componentId, Options options) {

+ 8
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/navigator/NavigatorTest.java View File

47
 import java.util.List;
47
 import java.util.List;
48
 
48
 
49
 import static org.assertj.core.api.Java6Assertions.assertThat;
49
 import static org.assertj.core.api.Java6Assertions.assertThat;
50
+import static org.junit.Assert.assertTrue;
50
 import static org.mockito.ArgumentMatchers.any;
51
 import static org.mockito.ArgumentMatchers.any;
51
 import static org.mockito.ArgumentMatchers.eq;
52
 import static org.mockito.ArgumentMatchers.eq;
52
 import static org.mockito.Mockito.spy;
53
 import static org.mockito.Mockito.spy;
166
         assertIsChild(uut.getRootLayout(), child2.getView());
167
         assertIsChild(uut.getRootLayout(), child2.getView());
167
     }
168
     }
168
 
169
 
170
+    @Test
171
+    public void setRoot_destroysModals() {
172
+        uut.showModal(child1, new CommandListenerAdapter());
173
+        uut.setRoot(child2, new CommandListenerAdapter(), reactInstanceManager);
174
+        assertTrue(child1.isDestroyed());
175
+    }
176
+
169
     @Test
177
     @Test
170
     public void hasUniqueId() {
178
     public void hasUniqueId() {
171
         assertThat(uut.getId()).startsWith("navigator");
179
         assertThat(uut.getId()).startsWith("navigator");

+ 5
- 0
playground/src/screens/ModalScreen.js View File

3
 const Root = require('../components/Root');
3
 const Root = require('../components/Root');
4
 const Button = require('../components/Button')
4
 const Button = require('../components/Button')
5
 const Navigation = require('./../services/Navigation');
5
 const Navigation = require('./../services/Navigation');
6
+const { stack } = require('../commons/Layouts');
6
 const Screens = require('./Screens');
7
 const Screens = require('./Screens');
7
 const {
8
 const {
8
   PUSH_BTN,
9
   PUSH_BTN,
15
   DISMISS_ALL_PREVIOUS_MODAL_BTN,
16
   DISMISS_ALL_PREVIOUS_MODAL_BTN,
16
   DISMISS_ALL_MODALS_BTN,
17
   DISMISS_ALL_MODALS_BTN,
17
   DISMISS_FIRST_MODAL_BTN,
18
   DISMISS_FIRST_MODAL_BTN,
19
+  SET_ROOT
18
 } = require('../testIDs');
20
 } = require('../testIDs');
19
 
21
 
20
 class ModalScreen extends React.Component {
22
 class ModalScreen extends React.Component {
46
         <Button label='Dismiss All Modals' testID={DISMISS_ALL_MODALS_BTN} onPress={this.dismissAllModals} />
48
         <Button label='Dismiss All Modals' testID={DISMISS_ALL_MODALS_BTN} onPress={this.dismissAllModals} />
47
         {this.props.previousModalIds && (<Button label='Dismiss First Modal' testID={DISMISS_FIRST_MODAL_BTN} onPress={this.dismissFirstModal} />)}
49
         {this.props.previousModalIds && (<Button label='Dismiss First Modal' testID={DISMISS_FIRST_MODAL_BTN} onPress={this.dismissFirstModal} />)}
48
         <Button label='Push screen' testID={PUSH_BTN} onPress={this.pushScreen} />
50
         <Button label='Push screen' testID={PUSH_BTN} onPress={this.pushScreen} />
51
+        <Button label='Set Root' testID={SET_ROOT} onPress={this.setRoot} />
49
       </Root>
52
       </Root>
50
     );
53
     );
51
   }
54
   }
83
 
86
 
84
   pushScreen = () => Navigation.push(this, Screens.Pushed);
87
   pushScreen = () => Navigation.push(this, Screens.Pushed);
85
 
88
 
89
+  setRoot = () => Navigation.setRoot(stack(Screens.Pushed));
90
+
86
   getModalPosition = () => this.props.modalPosition || 1;
91
   getModalPosition = () => this.props.modalPosition || 1;
87
 
92
 
88
   getPreviousModalId = () => _.last(this.props.previousModalIds);
93
   getPreviousModalId = () => _.last(this.props.previousModalIds);

+ 4
- 2
playground/src/services/Navigation.js View File

27
 
27
 
28
 const mergeOptions = (selfOrCompId, options) => Navigation.mergeOptions(compId(selfOrCompId), options);
28
 const mergeOptions = (selfOrCompId, options) => Navigation.mergeOptions(compId(selfOrCompId), options);
29
 
29
 
30
-const setStackRoot = (self, root) => Navigation.setStackRoot(self.props.componentId, root)
30
+const setStackRoot = (self, root) => Navigation.setStackRoot(self.props.componentId, root);
31
+
32
+const setRoot = (root) => Navigation.setRoot(root.root ? root : { root: component(root, {}) });
31
 
33
 
32
 const compId = (selfOrCompId) => {
34
 const compId = (selfOrCompId) => {
33
   return get(selfOrCompId, 'props.componentId', selfOrCompId);
35
   return get(selfOrCompId, 'props.componentId', selfOrCompId);
49
   events: Navigation.events.bind(Navigation),
51
   events: Navigation.events.bind(Navigation),
50
   popTo: Navigation.popTo.bind(Navigation),
52
   popTo: Navigation.popTo.bind(Navigation),
51
   setDefaultOptions: Navigation.setDefaultOptions.bind(Navigation),
53
   setDefaultOptions: Navigation.setDefaultOptions.bind(Navigation),
52
-  setRoot: Navigation.setRoot.bind(Navigation),
54
+  setRoot,
53
   TouchablePreview: Navigation.TouchablePreview,
55
   TouchablePreview: Navigation.TouchablePreview,
54
   setStackRoot,
56
   setStackRoot,
55
   constants
57
   constants

+ 1
- 0
playground/src/testIDs.js View File

125
   SET_INTERCEPT_TOUCH: `SET_INTERCEPT_TOUCH`,
125
   SET_INTERCEPT_TOUCH: `SET_INTERCEPT_TOUCH`,
126
   PUSH_BOTTOM_TABS_BUTTON: `PUSH_BOTTOM_TABS_BUTTON`,
126
   PUSH_BOTTOM_TABS_BUTTON: `PUSH_BOTTOM_TABS_BUTTON`,
127
   SET_STACK_ROOT_BUTTON: `SET_STACK_ROOT_BUTTON`,
127
   SET_STACK_ROOT_BUTTON: `SET_STACK_ROOT_BUTTON`,
128
+  SET_ROOT:'SET_ROOT',
128
 
129
 
129
   // Elements
130
   // Elements
130
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,
131
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,