Browse Source

Destroy modals on setRoot (#5302)

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

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

@@ -118,6 +118,12 @@ describe('modal', () => {
118 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 127
   it(':android: override hardware back button in modal with stack', async () => {
122 128
     await elementById(TestIDs.PUSH_BTN).tap();
123 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,7 +50,7 @@ public class Navigator extends ParentController {
50 50
         return defaultOptions;
51 51
     }
52 52
 
53
-    public FrameLayout getRootLayout() {
53
+    FrameLayout getRootLayout() {
54 54
         return rootLayout;
55 55
     }
56 56
 
@@ -129,6 +129,7 @@ public class Navigator extends ParentController {
129 129
 
130 130
     public void setRoot(final ViewController viewController, CommandListener commandListener, ReactInstanceManager reactInstanceManager) {
131 131
         destroyRoot();
132
+        modalStack.destroy();
132 133
         final boolean removeSplashView = isRootNotCreated();
133 134
         if (isRootNotCreated()) getView();
134 135
         root = viewController;
@@ -138,11 +139,11 @@ public class Navigator extends ParentController {
138 139
                 if (removeSplashView) removePreviousContentView();
139 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 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,6 +47,7 @@ import java.util.Collections;
47 47
 import java.util.List;
48 48
 
49 49
 import static org.assertj.core.api.Java6Assertions.assertThat;
50
+import static org.junit.Assert.assertTrue;
50 51
 import static org.mockito.ArgumentMatchers.any;
51 52
 import static org.mockito.ArgumentMatchers.eq;
52 53
 import static org.mockito.Mockito.spy;
@@ -166,6 +167,13 @@ public class NavigatorTest extends BaseTest {
166 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 177
     @Test
170 178
     public void hasUniqueId() {
171 179
         assertThat(uut.getId()).startsWith("navigator");

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

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

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

@@ -27,7 +27,9 @@ const popToRoot = (self) => Navigation.popToRoot(self.props.componentId);
27 27
 
28 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 34
 const compId = (selfOrCompId) => {
33 35
   return get(selfOrCompId, 'props.componentId', selfOrCompId);
@@ -49,7 +51,7 @@ module.exports = {
49 51
   events: Navigation.events.bind(Navigation),
50 52
   popTo: Navigation.popTo.bind(Navigation),
51 53
   setDefaultOptions: Navigation.setDefaultOptions.bind(Navigation),
52
-  setRoot: Navigation.setRoot.bind(Navigation),
54
+  setRoot,
53 55
   TouchablePreview: Navigation.TouchablePreview,
54 56
   setStackRoot,
55 57
   constants

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

@@ -125,6 +125,7 @@ module.exports = {
125 125
   SET_INTERCEPT_TOUCH: `SET_INTERCEPT_TOUCH`,
126 126
   PUSH_BOTTOM_TABS_BUTTON: `PUSH_BOTTOM_TABS_BUTTON`,
127 127
   SET_STACK_ROOT_BUTTON: `SET_STACK_ROOT_BUTTON`,
128
+  SET_ROOT:'SET_ROOT',
128 129
 
129 130
   // Elements
130 131
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,