Browse Source

Remove support from popping specific screens in a stack

While arguable being convenient, this is behaviour goes against the Stack api.

Some commands, such as push and pop, can be applied on stacks by passing the
stack's componentId.
This commit also fixes those stack commands which were always applied on parent stacks.
Guy Carmeli 5 years ago
parent
commit
2e80068e59

+ 0
- 11
e2e/ScreenStack.test.js View File

@@ -23,17 +23,6 @@ describe('screen stack', () => {
23 23
     await expect(elementById(testIDs.WELCOME_SCREEN_HEADER)).toBeVisible();
24 24
   });
25 25
 
26
-  test('pop screen deep in the stack', async () => {
27
-    await elementById(testIDs.PUSH_BUTTON).tap();
28
-    await expect(elementByLabel('Stack Position: 1')).toBeVisible();
29
-    await elementById(testIDs.PUSH_BUTTON).tap();
30
-    await expect(elementByLabel('Stack Position: 2')).toBeVisible();
31
-    await elementById(testIDs.POP_PREVIOUS_BUTTON).tap();
32
-    await expect(elementByLabel('Stack Position: 2')).toBeVisible();
33
-    await elementById(testIDs.POP_BUTTON).tap();
34
-    await expect(elementById(testIDs.WELCOME_SCREEN_HEADER)).toBeVisible();
35
-  });
36
-
37 26
   test('pop to specific id', async () => {
38 27
     await elementById(testIDs.PUSH_BUTTON).tap();
39 28
     await elementById(testIDs.PUSH_BUTTON).tap();

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java View File

@@ -98,8 +98,8 @@ public class NavigationModule extends ReactContextBaseJavaModule {
98 98
     }
99 99
 
100 100
 	@ReactMethod
101
-	public void pop(String commandId, String onComponentId, ReadableMap options, Promise promise) {
102
-		handle(() -> navigator().popSpecific(onComponentId, new NativeCommandListener(commandId, promise, eventEmitter, now)));
101
+	public void pop(String commandId, String componentId, ReadableMap options, Promise promise) {
102
+		handle(() -> navigator().pop(componentId, new NativeCommandListener(commandId, promise, eventEmitter, now)));
103 103
 	}
104 104
 
105 105
 	@ReactMethod

+ 23
- 43
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

@@ -15,6 +15,7 @@ import com.reactnativenavigation.presentation.OverlayManager;
15 15
 import com.reactnativenavigation.react.EventEmitter;
16 16
 import com.reactnativenavigation.utils.CommandListener;
17 17
 import com.reactnativenavigation.utils.CompatUtils;
18
+import com.reactnativenavigation.utils.Task;
18 19
 import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
19 20
 import com.reactnativenavigation.viewcontrollers.stack.StackController;
20 21
 import com.reactnativenavigation.views.element.ElementTransitionManager;
@@ -147,54 +148,28 @@ public class Navigator extends ParentController {
147 148
         }
148 149
     }
149 150
 
150
-    public void push(final String fromId, final ViewController viewController, CommandListener listener) {
151
-        ViewController from = findControllerById(fromId);
152
-        if (from != null) {
153
-            from.performOnParentStack(
154
-                    stack -> ((StackController) stack).push(viewController, listener),
155
-                    () -> rejectPush(fromId, viewController, listener)
156
-            );
157
-        } else {
158
-            rejectPush(fromId, viewController, listener);
159
-        }
151
+    public void push(final String id, final ViewController viewController, CommandListener listener) {
152
+        applyOnStack(id, listener, stack -> stack.push(viewController, listener));
160 153
     }
161 154
 
162
-    public void setStackRoot(String fromId, ViewController viewController, CommandListener listener) {
163
-        ViewController from = findControllerById(fromId);
164
-        if (from != null) {
165
-            from.performOnParentStack(stack -> ((StackController) stack).setRoot(viewController, listener));
166
-        }
167
-    }
168
-
169
-    public void pop(final String fromId, CommandListener listener) {
170
-        ViewController from = findControllerById(fromId);
171
-        if (from != null) {
172
-            from.performOnParentStack(stack -> ((StackController) stack).pop(listener));
173
-        }
155
+    public void setStackRoot(String id, ViewController viewController, CommandListener listener) {
156
+        applyOnStack(id, listener, stack -> stack.setRoot(viewController, listener));
174 157
     }
175 158
 
176
-    public void popSpecific(final String id, CommandListener listener) {
177
-        ViewController from = findControllerById(id);
178
-        if (from != null) {
179
-            from.performOnParentStack(stack -> ((StackController) stack).popSpecific(from, listener), () -> listener.onError("Nothing to pop"));
180
-        } else {
181
-            listener.onError("Nothing to pop");
182
-        }
159
+    public void pop(String id, CommandListener listener) {
160
+        applyOnStack(id, listener, stack -> stack.pop(listener));
183 161
     }
184 162
 
185 163
     public void popToRoot(final String id, CommandListener listener) {
186
-        ViewController from = findControllerById(id);
187
-        if (from != null) {
188
-            from.performOnParentStack(stack -> ((StackController) stack).popToRoot(listener));
189
-        }
164
+        applyOnStack(id, listener, stack -> stack.popToRoot(listener));
190 165
     }
191 166
 
192
-    public void popTo(final String componentId, CommandListener listener) {
193
-        ViewController target = findControllerById(componentId);
167
+    public void popTo(final String id, CommandListener listener) {
168
+        ViewController target = findControllerById(id);
194 169
         if (target != null) {
195
-            target.performOnParentStack(stack -> ((StackController) stack).popTo(target, listener), () -> listener.onError("Nothing to pop"));
170
+            target.performOnParentStack(stack -> ((StackController) stack).popTo(target, listener));
196 171
         } else {
197
-            listener.onError("Nothing to pop");
172
+            listener.onError("Failed to execute stack command. Stack by " + id + " not found.");
198 173
         }
199 174
     }
200 175
 
@@ -229,12 +204,17 @@ public class Navigator extends ParentController {
229 204
         return controllerById != null ? controllerById : modalStack.findControllerById(id);
230 205
     }
231 206
 
232
-    private void rejectPush(String fromId, ViewController viewController, CommandListener listener) {
233
-        listener.onError("Could not push component: " +
234
-                         viewController.getId() +
235
-                         ". Stack with id " +
236
-                         fromId +
237
-                         " was not found.");
207
+    private void applyOnStack(String fromId, CommandListener listener, Task<StackController> task) {
208
+        ViewController from = findControllerById(fromId);
209
+        if (from != null) {
210
+            if (from instanceof StackController) {
211
+                task.run((StackController) from);
212
+            } else {
213
+                from.performOnParentStack(stack -> task.run((StackController) stack) );
214
+            }
215
+        } else {
216
+            listener.onError("Failed to execute stack command. Stack " + fromId + " not found.");
217
+        }
238 218
     }
239 219
 
240 220
     private boolean isRootNotCreated() {

+ 1
- 13
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java View File

@@ -19,7 +19,6 @@ import com.reactnativenavigation.utils.CommandListenerAdapter;
19 19
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
20 20
 import com.reactnativenavigation.viewcontrollers.IdStack;
21 21
 import com.reactnativenavigation.viewcontrollers.ParentController;
22
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
23 22
 import com.reactnativenavigation.viewcontrollers.ViewController;
24 23
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
25 24
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
@@ -38,16 +37,14 @@ public class StackController extends ParentController<StackLayout> {
38 37
 
39 38
     private final IdStack<ViewController> stack = new IdStack<>();
40 39
     private final NavigationAnimator animator;
41
-    private final ReactViewCreator topBarButtonCreator;
42 40
     private TopBarBackgroundViewController topBarBackgroundViewController;
43 41
     private TopBarController topBarController;
44 42
     private BackButtonHelper backButtonHelper;
45 43
     private final StackOptionsPresenter presenter;
46 44
 
47
-    public StackController(Activity activity, List<ViewController> children, ChildControllersRegistry childRegistry, ReactViewCreator topBarButtonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController, NavigationAnimator animator, String id, Options initialOptions, BackButtonHelper backButtonHelper, StackOptionsPresenter stackPresenter, OptionsPresenter presenter) {
45
+    public StackController(Activity activity, List<ViewController> children, ChildControllersRegistry childRegistry, TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController, NavigationAnimator animator, String id, Options initialOptions, BackButtonHelper backButtonHelper, StackOptionsPresenter stackPresenter, OptionsPresenter presenter) {
48 46
         super(activity, childRegistry, id, presenter, initialOptions);
49 47
         this.topBarController = topBarController;
50
-        this.topBarButtonCreator = topBarButtonCreator;
51 48
         this.topBarBackgroundViewController = topBarBackgroundViewController;
52 49
         this.animator = animator;
53 50
         this.backButtonHelper = backButtonHelper;
@@ -224,15 +221,6 @@ public class StackController extends ParentController<StackLayout> {
224 221
         listener.onSuccess(disappearing.getId());
225 222
     }
226 223
 
227
-    public void popSpecific(ViewController childController, CommandListener listener) {
228
-        if (stack.isTop(childController.getId())) {
229
-            pop(listener);
230
-        } else {
231
-            removeAndDestroyController(childController);
232
-            listener.onSuccess(childController.getId());
233
-        }
234
-    }
235
-
236 224
     public void popTo(final ViewController viewController, CommandListener listener) {
237 225
         if (!stack.containsId(viewController.getId())) {
238 226
             listener.onError("Nothing to pop");

+ 0
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerBuilder.java View File

@@ -95,7 +95,6 @@ public class StackControllerBuilder {
95 95
         return new StackController(activity,
96 96
                 children,
97 97
                 childRegistry,
98
-                topBarButtonCreator,
99 98
                 topBarBackgroundViewController,
100 99
                 topBarController,
101 100
                 animator,

+ 24
- 15
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java View File

@@ -24,6 +24,7 @@ import com.reactnativenavigation.utils.CommandListenerAdapter;
24 24
 import com.reactnativenavigation.utils.CompatUtils;
25 25
 import com.reactnativenavigation.utils.ImageLoader;
26 26
 import com.reactnativenavigation.utils.OptionHelper;
27
+import com.reactnativenavigation.utils.ViewUtils;
27 28
 import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsController;
28 29
 import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
29 30
 import com.reactnativenavigation.viewcontrollers.stack.StackController;
@@ -217,20 +218,16 @@ public class NavigatorTest extends BaseTest {
217 218
     }
218 219
 
219 220
     @Test
220
-    public void popSpecific() {
221
-        disablePushAnimation(child1, child2, child3, child4);
222
-        StackController stack1 = newStack(); stack1.ensureViewIsCreated();
223
-        StackController stack2 = newStack(); stack2.ensureViewIsCreated();
224
-        stack1.push(child1, new CommandListenerAdapter());
225
-        stack2.push(child2, new CommandListenerAdapter());
226
-        stack2.push(child3, new CommandListenerAdapter());
227
-        stack2.push(child4, new CommandListenerAdapter());
228
-        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
229
-        uut.setRoot(bottomTabsController, new CommandListenerAdapter());
230
-
231
-        uut.popSpecific(child2.getId(), new CommandListenerAdapter());
221
+    public void pop_byStackId() {
222
+        disablePushAnimation(child1, child2);
223
+        disablePopAnimation(child2, child1);
224
+        StackController stack = newStack(); stack.ensureViewIsCreated();
225
+        uut.setRoot(stack, new CommandListenerAdapter());
226
+        stack.push(child1, new CommandListenerAdapter());
227
+        stack.push(child2, new CommandListenerAdapter());
232 228
 
233
-        assertThat(stack2.getChildControllers()).containsOnly(child4, child3);
229
+        uut.pop(stack.getId(), new CommandListenerAdapter());
230
+        assertThat(stack.getChildControllers()).containsOnly(child1);
234 231
     }
235 232
 
236 233
     @Test
@@ -434,8 +431,8 @@ public class NavigatorTest extends BaseTest {
434 431
                 assertThat(spy.getChildControllers().size()).isEqualTo(1);
435 432
             }
436 433
         };
437
-        uut.popSpecific("child2", listener);
438
-        verify(spy, times(1)).popSpecific(child2, listener);
434
+        uut.pop("child2", listener);
435
+        verify(spy, times(1)).pop(listener);
439 436
     }
440 437
 
441 438
     @Test
@@ -474,6 +471,18 @@ public class NavigatorTest extends BaseTest {
474 471
         verify(parentVisibilityListener, times(2)).onViewAppeared(parentController.getView());
475 472
     }
476 473
 
474
+    @Test
475
+    public void dismissModal_reattachedToRoot() {
476
+        disableModalAnimations(child1);
477
+
478
+        uut.setRoot(parentController, new CommandListenerAdapter());
479
+        assertThat(ViewUtils.isChildOf(uut.getRootLayout(), parentController.getView()));
480
+        uut.showModal(child1, new CommandListenerAdapter());
481
+
482
+        uut.dismissModal(child1.getId(), new CommandListenerAdapter());
483
+        assertThat(ViewUtils.isChildOf(uut.getRootLayout(), parentController.getView()));
484
+    }
485
+
477 486
     @Test
478 487
     public void dismissModal_rejectIfRootIsNotSetAndSingleModalIsDisplayed() {
479 488
         disableModalAnimations(child1, child2);

+ 0
- 41
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java View File

@@ -424,23 +424,6 @@ public class StackControllerTest extends BaseTest {
424 424
         });
425 425
     }
426 426
 
427
-    @Test
428
-    public void pop_specificWhenTopIsRegularPop() {
429
-        uut.push(child1, new CommandListenerAdapter());
430
-        uut.push(child2, new CommandListenerAdapter() {
431
-            @Override
432
-            public void onSuccess(String childId) {
433
-                uut.popSpecific(child2, new CommandListenerAdapter() {
434
-                    @Override
435
-                    public void onSuccess(String childId) {
436
-                        assertContainsOnlyId(child1.getId());
437
-                        assertIsChild(uut.getView(), child1.getView());
438
-                    }
439
-                });
440
-            }
441
-        });
442
-    }
443
-
444 427
     @Test
445 428
     public void pop_appearingChildHasCorrectLayoutParams() {
446 429
         child2.options.animations.pop.enable = new Bool(false);
@@ -460,16 +443,6 @@ public class StackControllerTest extends BaseTest {
460 443
                 .getHeight());
461 444
     }
462 445
 
463
-    @Test
464
-    public void popSpecific_deepInStack() {
465
-        uut.push(child1, new CommandListenerAdapter());
466
-        uut.push(child2, new CommandListenerAdapter());
467
-        assertIsChild(uut.getView(), child2.getView());
468
-        uut.popSpecific(child1, new CommandListenerAdapter());
469
-        assertContainsOnlyId(child2.getId());
470
-        assertIsChild(uut.getView(), child2.getView());
471
-    }
472
-
473 446
     @Test
474 447
     public void popTo_PopsTopUntilControllerIsNewTop() {
475 448
         uut.push(child1, new CommandListenerAdapter());
@@ -687,20 +660,6 @@ public class StackControllerTest extends BaseTest {
687 660
         });
688 661
     }
689 662
 
690
-    @Test
691
-    public void popSpecific_CallsDestroyOnPoppedChild() {
692
-        child1 = spy(child1);
693
-        child2 = spy(child2);
694
-        child3 = spy(child3);
695
-        uut.push(child1, new CommandListenerAdapter());
696
-        uut.push(child2, new CommandListenerAdapter());
697
-        uut.push(child3, new CommandListenerAdapter());
698
-
699
-        verify(child2, times(0)).destroy();
700
-        uut.popSpecific(child2, new CommandListenerAdapter());
701
-        verify(child2, times(1)).destroy();
702
-    }
703
-
704 663
     @Test
705 664
     public void popTo_CallsDestroyOnPoppedChild() {
706 665
         child1 = spy(child1);