Browse Source

Add previous controller to screen only when dismissing top modal

Guy Carmeli 6 years ago
parent
commit
4202f8643d

+ 6
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java View File

2
 
2
 
3
 import android.animation.Animator;
3
 import android.animation.Animator;
4
 import android.animation.AnimatorListenerAdapter;
4
 import android.animation.AnimatorListenerAdapter;
5
+import android.support.annotation.NonNull;
5
 import android.view.ViewGroup;
6
 import android.view.ViewGroup;
6
 
7
 
7
 import com.reactnativenavigation.anim.ModalAnimator;
8
 import com.reactnativenavigation.anim.ModalAnimator;
43
         listener.onSuccess(toAdd.getId());
44
         listener.onSuccess(toAdd.getId());
44
     }
45
     }
45
 
46
 
46
-    public void dismissModal(ViewController toDismiss, ViewController toAdd, CommandListener listener) {
47
+    public void dismissTopModal(ViewController toDismiss, @NonNull ViewController toAdd, CommandListener listener) {
47
         toAdd.attachView(content, 0);
48
         toAdd.attachView(content, 0);
49
+        dismissModal(toDismiss, listener);
50
+    }
51
+
52
+    public void dismissModal(ViewController toDismiss, CommandListener listener) {
48
         if (toDismiss.options.animations.dismissModal.enable.isTrueOrUndefined()) {
53
         if (toDismiss.options.animations.dismissModal.enable.isTrueOrUndefined()) {
49
             animator.dismiss(toDismiss.getView(), new AnimatorListenerAdapter() {
54
             animator.dismiss(toDismiss.getView(), new AnimatorListenerAdapter() {
50
                 @Override
55
                 @Override

+ 8
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack.java View File

32
     public void dismissModal(String componentId, ViewController root, CommandListener listener) {
32
     public void dismissModal(String componentId, ViewController root, CommandListener listener) {
33
         ViewController toDismiss = findModalByComponentId(componentId);
33
         ViewController toDismiss = findModalByComponentId(componentId);
34
         if (toDismiss != null) {
34
         if (toDismiss != null) {
35
-            ViewController toAdd = isTop(toDismiss) ? get(size() - 2) : root;
35
+            boolean isTop = isTop(toDismiss);
36
             modals.remove(toDismiss);
36
             modals.remove(toDismiss);
37
-            presenter.dismissModal(toDismiss, toAdd, listener);
37
+            ViewController toAdd = isEmpty() ? root : isTop ? get(size() - 1) : null;
38
+            if (isTop) {
39
+                presenter.dismissTopModal(toDismiss, toAdd, listener);
40
+            } else {
41
+                presenter.dismissModal(toDismiss, listener);
42
+            }
38
         } else {
43
         } else {
39
             listener.onError("Nothing to dismiss");
44
             listener.onError("Nothing to dismiss");
40
         }
45
         }
83
     }
88
     }
84
 
89
 
85
     private boolean isTop(ViewController modal) {
90
     private boolean isTop(ViewController modal) {
86
-        return size() > 1 && peek().equals(modal);
91
+        return !isEmpty() && peek().equals(modal);
87
     }
92
     }
88
 
93
 
89
     @Nullable
94
     @Nullable

+ 24
- 25
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java View File

1
 package com.reactnativenavigation.viewcontrollers.modal;
1
 package com.reactnativenavigation.viewcontrollers.modal;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
-import android.view.ViewGroup;
5
 import android.widget.FrameLayout;
4
 import android.widget.FrameLayout;
6
 
5
 
7
 import com.reactnativenavigation.BaseTest;
6
 import com.reactnativenavigation.BaseTest;
13
 import com.reactnativenavigation.utils.CommandListenerAdapter;
12
 import com.reactnativenavigation.utils.CommandListenerAdapter;
14
 import com.reactnativenavigation.viewcontrollers.ChildController;
13
 import com.reactnativenavigation.viewcontrollers.ChildController;
15
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
14
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
16
-import com.reactnativenavigation.viewcontrollers.ParentController;
17
 import com.reactnativenavigation.viewcontrollers.ViewController;
15
 import com.reactnativenavigation.viewcontrollers.ViewController;
18
 
16
 
19
 import org.junit.Test;
17
 import org.junit.Test;
20
-import org.mockito.Mockito;
21
 
18
 
22
 import static org.assertj.core.api.Java6Assertions.assertThat;
19
 import static org.assertj.core.api.Java6Assertions.assertThat;
23
 import static org.mockito.ArgumentMatchers.any;
20
 import static org.mockito.ArgumentMatchers.any;
25
 import static org.mockito.Mockito.spy;
22
 import static org.mockito.Mockito.spy;
26
 import static org.mockito.Mockito.times;
23
 import static org.mockito.Mockito.times;
27
 import static org.mockito.Mockito.verify;
24
 import static org.mockito.Mockito.verify;
28
-import static org.mockito.Mockito.when;
29
 
25
 
30
 public class ModalPresenterTest extends BaseTest {
26
 public class ModalPresenterTest extends BaseTest {
31
     private static final String MODAL_ID_1 = "modalId1";
27
     private static final String MODAL_ID_1 = "modalId1";
37
     private FrameLayout contentLayout;
33
     private FrameLayout contentLayout;
38
     private ModalAnimator animator;
34
     private ModalAnimator animator;
39
     private ViewController rootController;
35
     private ViewController rootController;
40
-    private ChildControllersRegistry childRegistry;
41
 
36
 
42
     @Override
37
     @Override
43
     public void beforeEach() {
38
     public void beforeEach() {
44
         Activity activity = newActivity();
39
         Activity activity = newActivity();
45
-        childRegistry = new ChildControllersRegistry();
40
+        ChildControllersRegistry childRegistry = new ChildControllersRegistry();
46
 
41
 
47
-        ViewGroup root = new FrameLayout(activity);
48
-        rootController = Mockito.mock(ParentController.class);
49
-        when(this.rootController.getView()).then(invocation -> root);
42
+        rootController = spy(new SimpleViewController(activity, childRegistry, "root", new Options()));
50
         contentLayout = new FrameLayout(activity);
43
         contentLayout = new FrameLayout(activity);
51
-        contentLayout.addView(root);
44
+        contentLayout.addView(rootController.getView());
52
         activity.setContentView(contentLayout);
45
         activity.setContentView(contentLayout);
53
 
46
 
54
         animator = spy(new ModalAnimator(activity));
47
         animator = spy(new ModalAnimator(activity));
114
         disableShowModalAnimation(modal1);
107
         disableShowModalAnimation(modal1);
115
 
108
 
116
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
109
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
117
-        uut.dismissModal(modal1, rootController, new CommandListenerAdapter() {
110
+        uut.dismissTopModal(modal1, rootController, new CommandListenerAdapter() {
118
             @Override
111
             @Override
119
             public void onSuccess(String childId) {
112
             public void onSuccess(String childId) {
120
                 verify(modal1, times(1)).onViewDisappear();
113
                 verify(modal1, times(1)).onViewDisappear();
130
         modal2.ensureViewIsCreated();
123
         modal2.ensureViewIsCreated();
131
         FrameLayout spy = spy(new FrameLayout(newActivity()));
124
         FrameLayout spy = spy(new FrameLayout(newActivity()));
132
         uut.setContentLayout(spy);
125
         uut.setContentLayout(spy);
133
-        uut.dismissModal(modal1, modal2, new CommandListenerAdapter());
126
+        uut.dismissTopModal(modal1, modal2, new CommandListenerAdapter());
134
         verify(spy, times(1)).addView(modal2.getView(), 0);
127
         verify(spy, times(1)).addView(modal2.getView(), 0);
135
     }
128
     }
136
 
129
 
137
-    @Test
138
-    public void dismissModal_onViewBroughtToFront_invokedOnPreviousView() {
139
-        disableShowModalAnimation(modal1, modal2);
140
-        disableDismissModalAnimation(modal1, modal2);
141
-
142
-        uut.showModal(modal1, rootController, new CommandListenerAdapter());
143
-        uut.showModal(modal2, rootController, new CommandListenerAdapter());
144
-        uut.dismissModal(modal2, modal1, new CommandListenerAdapter());
145
-        verify(modal1, times(1)).onViewBroughtToFront();
146
-    }
147
-
148
     @Test
130
     @Test
149
     public void dismissModal_noAnimation() {
131
     public void dismissModal_noAnimation() {
150
         disableShowModalAnimation(modal1);
132
         disableShowModalAnimation(modal1);
151
         disableDismissModalAnimation(modal1);
133
         disableDismissModalAnimation(modal1);
152
 
134
 
153
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
135
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
154
-        uut.dismissModal(modal1, rootController, new CommandListenerAdapter());
136
+        uut.dismissTopModal(modal1, rootController, new CommandListenerAdapter());
155
         verify(modal1, times(1)).onViewDisappear();
137
         verify(modal1, times(1)).onViewDisappear();
156
         verify(modal1, times(1)).destroy();
138
         verify(modal1, times(1)).destroy();
157
         verify(animator, times(0)).dismiss(any(), any());
139
         verify(animator, times(0)).dismiss(any(), any());
164
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
146
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
165
         uut.showModal(modal2, modal1, new CommandListenerAdapter());
147
         uut.showModal(modal2, modal1, new CommandListenerAdapter());
166
         assertThat(modal1.getView().getParent()).isNull();
148
         assertThat(modal1.getView().getParent()).isNull();
167
-        uut.dismissModal(modal2, modal1, new CommandListenerAdapter());
149
+        uut.dismissTopModal(modal2, modal1, new CommandListenerAdapter());
168
         verify(modal1, times(2)).onViewAppeared();
150
         verify(modal1, times(2)).onViewAppeared();
169
     }
151
     }
170
 
152
 
153
+    @Test
154
+    public void dismissModal_previousControllerIsNotAddedIfDismissedModalIsNotTop() {
155
+        disableShowModalAnimation(modal1, modal2);
156
+        disableDismissModalAnimation(modal1, modal2);
157
+
158
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
159
+        uut.showModal(modal2, modal1, new CommandListenerAdapter());
160
+        assertThat(modal1.getView().getParent()).isNull();
161
+        assertThat(rootController.getView().getParent()).isNull();
162
+
163
+        uut.dismissModal(modal1, new CommandListenerAdapter());
164
+        assertThat(rootController.getView().getParent()).isNull();
165
+
166
+        uut.dismissTopModal(modal2, rootController, new CommandListenerAdapter());
167
+        assertThat(rootController.getView().getParent()).isNotNull();
168
+    }
169
+
171
     @Test
170
     @Test
172
     public void dismissModal_previousViewIsNotDetachedIfOverCurrentContext() {
171
     public void dismissModal_previousViewIsNotDetachedIfOverCurrentContext() {
173
         modal1.options.modal.presentationStyle = ModalPresentationStyle.OverCurrentContext;
172
         modal1.options.modal.presentationStyle = ModalPresentationStyle.OverCurrentContext;

+ 23
- 9
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java View File

11
 import com.reactnativenavigation.utils.CommandListener;
11
 import com.reactnativenavigation.utils.CommandListener;
12
 import com.reactnativenavigation.utils.CommandListenerAdapter;
12
 import com.reactnativenavigation.utils.CommandListenerAdapter;
13
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
13
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
14
-import com.reactnativenavigation.viewcontrollers.ParentController;
15
 import com.reactnativenavigation.viewcontrollers.ViewController;
14
 import com.reactnativenavigation.viewcontrollers.ViewController;
16
 
15
 
17
 import org.junit.Test;
16
 import org.junit.Test;
18
-import org.mockito.Mockito;
19
 
17
 
20
 import java.util.EmptyStackException;
18
 import java.util.EmptyStackException;
21
 
19
 
28
 import static org.mockito.Mockito.times;
26
 import static org.mockito.Mockito.times;
29
 import static org.mockito.Mockito.verify;
27
 import static org.mockito.Mockito.verify;
30
 import static org.mockito.Mockito.verifyZeroInteractions;
28
 import static org.mockito.Mockito.verifyZeroInteractions;
31
-import static org.mockito.Mockito.when;
32
 
29
 
33
 public class ModalStackTest extends BaseTest {
30
 public class ModalStackTest extends BaseTest {
34
     private static final String MODAL_ID_1 = "modalId1";
31
     private static final String MODAL_ID_1 = "modalId1";
50
         activity = newActivity();
47
         activity = newActivity();
51
         childRegistry = new ChildControllersRegistry();
48
         childRegistry = new ChildControllersRegistry();
52
 
49
 
53
-        ViewGroup root = new FrameLayout(activity);
54
-        rootController = Mockito.mock(ParentController.class);
55
-        when(this.rootController.getView()).then(invocation -> root);
50
+        this.rootController = new SimpleViewController(activity, childRegistry, "root", new Options());
56
         FrameLayout activityContentView = new FrameLayout(activity);
51
         FrameLayout activityContentView = new FrameLayout(activity);
57
-        activityContentView.addView(root);
52
+        activityContentView.addView(rootController.getView());
58
         activity.setContentView(activityContentView);
53
         activity.setContentView(activityContentView);
59
 
54
 
60
         animator = spy(new ModalAnimatorMock(activity));
55
         animator = spy(new ModalAnimatorMock(activity));
92
         CommandListener listener = new CommandListenerAdapter();
87
         CommandListener listener = new CommandListenerAdapter();
93
         uut.dismissModal(modal1.getId(), rootController, listener);
88
         uut.dismissModal(modal1.getId(), rootController, listener);
94
         assertThat(findModal(modal1.getId())).isNull();
89
         assertThat(findModal(modal1.getId())).isNull();
95
-        verify(presenter, times(1)).dismissModal(modal1, rootController, listener);
90
+        verify(presenter, times(1)).dismissTopModal(modal1, rootController, listener);
96
     }
91
     }
97
 
92
 
98
     @SuppressWarnings("Convert2Lambda")
93
     @SuppressWarnings("Convert2Lambda")
111
         verifyZeroInteractions(listener);
106
         verifyZeroInteractions(listener);
112
     }
107
     }
113
 
108
 
109
+    @Test
110
+    public void dismissModal_dismissDeepModal() {
111
+        disableShowModalAnimation(modal1, modal2, modal3);
112
+        disableDismissModalAnimation(modal1, modal2, modal3);
113
+
114
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
115
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
116
+        uut.showModal(modal3, rootController, new CommandListenerAdapter());
117
+
118
+        assertThat(rootController.getView().getParent()).isNull();
119
+        uut.dismissModal(modal1.getId(), rootController, new CommandListenerAdapter());
120
+        assertThat(rootController.getView().getParent()).isNull();
121
+
122
+        uut.dismissModal(modal3.getId(), rootController, new CommandListenerAdapter());
123
+        uut.dismissModal(modal2.getId(), rootController, new CommandListenerAdapter());
124
+        assertThat(rootController.getView().getParent()).isNotNull();
125
+        assertThat(rootController.getView().isShown()).isTrue();
126
+    }
127
+
114
     @Test
128
     @Test
115
     public void dismissAllModals() {
129
     public void dismissAllModals() {
116
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
130
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
145
         ViewGroup view2 = modal2.getView();
159
         ViewGroup view2 = modal2.getView();
146
         CommandListener listener = spy(new CommandListenerAdapter());
160
         CommandListener listener = spy(new CommandListenerAdapter());
147
         uut.dismissAllModals(listener, rootController);
161
         uut.dismissAllModals(listener, rootController);
148
-        verify(presenter, times(1)).dismissModal(modal2, rootController, listener);
162
+        verify(presenter, times(1)).dismissTopModal(modal2, rootController, listener);
149
         verify(animator, times(0)).dismiss(eq(view1), any());
163
         verify(animator, times(0)).dismiss(eq(view1), any());
150
         verify(animator, times(1)).dismiss(eq(view2), any());
164
         verify(animator, times(1)).dismiss(eq(view2), any());
151
         assertThat(uut.size()).isEqualTo(0);
165
         assertThat(uut.size()).isEqualTo(0);