Browse Source

Fix YellowBox handling in TopBar components on RN >= 0.56

This commit includes two fixes to YellowBox handling:

1. RN started throwing exceptions when views added in JSX were removed from hierarchy.
    We could probably use UiManager to fiddle around with the yellow box, either removing it or making
    it hidden and allow touch events to pass through it. For now, we continue removing yellow boxes from hierarchy
    and we replace the removed yellow boxed with dummy views.
2. A “Dismiss All” button was recently added, we remove that as well.

Fixes #4035
Guy Carmeli 6 years ago
parent
commit
fee8d1966d

+ 1
- 1
e2e/ScreenStyle.test.js View File

184
     await expect(elementById(testIDs.TOP_BAR_BUTTON)).toBeVisible();
184
     await expect(elementById(testIDs.TOP_BAR_BUTTON)).toBeVisible();
185
   });
185
   });
186
 
186
 
187
-  test(':android: Popping screen with yellow box in button, title and background components should not crash', async () => {
187
+  test('Popping screen with yellow box in button, title and background components should not crash', async () => {
188
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
188
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
189
     await elementById(testIDs.SHOW_YELLOW_BOX).tap();
189
     await elementById(testIDs.SHOW_YELLOW_BOX).tap();
190
     Android.pressBack();
190
     Android.pressBack();

+ 26
- 17
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/YellowBoxDelegate.java View File

4
 import android.view.View;
4
 import android.view.View;
5
 import android.view.ViewGroup;
5
 import android.view.ViewGroup;
6
 
6
 
7
+import java.util.ArrayList;
8
+import java.util.List;
9
+
7
 public class YellowBoxDelegate {
10
 public class YellowBoxDelegate {
8
     private ViewGroup parent;
11
     private ViewGroup parent;
9
-    private View yellowBox;
10
     private YellowBoxHelper yellowBoxHelper;
12
     private YellowBoxHelper yellowBoxHelper;
11
     private boolean isDestroyed;
13
     private boolean isDestroyed;
14
+    private ArrayList<View> yellowBoxViews = new ArrayList<>();
12
 
15
 
13
     public YellowBoxDelegate() {
16
     public YellowBoxDelegate() {
14
         this.yellowBoxHelper = new YellowBoxHelper();
17
         this.yellowBoxHelper = new YellowBoxHelper();
18
         this.yellowBoxHelper = yellowBoxHelper;
21
         this.yellowBoxHelper = yellowBoxHelper;
19
     }
22
     }
20
 
23
 
21
-    @RestrictTo(RestrictTo.Scope.TESTS)
22
-    public ViewGroup getParent() {
23
-        return parent;
24
-    }
25
-
26
-    @RestrictTo(RestrictTo.Scope.TESTS)
27
-    public View getYellowBox() {
28
-        return yellowBox;
29
-    }
30
-
31
     public void onChildViewAdded(View parent, View child) {
24
     public void onChildViewAdded(View parent, View child) {
32
         if (yellowBoxHelper.isYellowBox(parent, child)) {
25
         if (yellowBoxHelper.isYellowBox(parent, child)) {
33
-            onYellowBoxAdded(parent, child);
26
+            onYellowBoxAdded(parent);
34
         }
27
         }
35
     }
28
     }
36
 
29
 
37
-    protected void onYellowBoxAdded(View parent, View yellowBox) {
30
+    void onYellowBoxAdded(View parent) {
38
         if (isDestroyed) return;
31
         if (isDestroyed) return;
39
-        this.yellowBox = yellowBox;
40
         this.parent = (ViewGroup) parent;
32
         this.parent = (ViewGroup) parent;
41
-        this.parent.removeView(yellowBox);
33
+
34
+        for (int i = 1; i < this.parent.getChildCount(); i++) {
35
+            yellowBoxViews.add(this.parent.getChildAt(i));
36
+            this.parent.removeView(this.parent.getChildAt(i));
37
+            this.parent.addView(new View(parent.getContext()), i);
38
+        }
42
     }
39
     }
43
 
40
 
44
     public void destroy() {
41
     public void destroy() {
45
         isDestroyed = true;
42
         isDestroyed = true;
46
-        if (yellowBox != null) {
47
-            parent.addView(yellowBox);
43
+        if (!yellowBoxViews.isEmpty()) {
44
+            for (View view : yellowBoxViews) {
45
+                parent.addView(view);
46
+            }
48
         }
47
         }
49
     }
48
     }
49
+
50
+    @RestrictTo(RestrictTo.Scope.TESTS)
51
+    public ViewGroup getParent() {
52
+        return parent;
53
+    }
54
+
55
+    @RestrictTo(RestrictTo.Scope.TESTS)
56
+    public List<View> getYellowBoxes() {
57
+        return yellowBoxViews;
58
+    }
50
 }
59
 }

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/YellowBoxHelper.java View File

13
     public boolean isYellowBox(View parent, View child) {
13
     public boolean isYellowBox(View parent, View child) {
14
         return parent instanceof ViewGroup &&
14
         return parent instanceof ViewGroup &&
15
                child instanceof ViewGroup &&
15
                child instanceof ViewGroup &&
16
-                ((ViewGroup) parent).getChildCount() > 1 &&
17
-               !ViewUtils.findChildrenByClassRecursive(((ViewGroup) child), View.class, YellowBackgroundMather()).isEmpty();
16
+               ((ViewGroup) parent).getChildCount() > 1 &&
17
+               !ViewUtils.findChildrenByClassRecursive((ViewGroup) child, View.class, YellowBackgroundMather()).isEmpty();
18
     }
18
     }
19
 
19
 
20
     @NonNull
20
     @NonNull

+ 0
- 1
lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/NavigationReactNativeHost.java View File

35
         }
35
         }
36
     };
36
     };
37
 
37
 
38
-
39
     public NavigationReactNativeHost(NavigationApplication application) {
38
     public NavigationReactNativeHost(NavigationApplication application) {
40
         this(application, application.isDebug(), application.createAdditionalReactPackages());
39
         this(application, application.isDebug(), application.createAdditionalReactPackages());
41
     }
40
     }

+ 7
- 6
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/YellowBoxDelegateTest.java View File

26
         parent = new FrameLayout(context);
26
         parent = new FrameLayout(context);
27
         yellowBoxHelper = Mockito.mock(YellowBoxHelper.class);
27
         yellowBoxHelper = Mockito.mock(YellowBoxHelper.class);
28
         uut = new YellowBoxDelegate(yellowBoxHelper);
28
         uut = new YellowBoxDelegate(yellowBoxHelper);
29
+        parent.addView(new View(context)); // We assume view at index 0 is not a yellow box
29
         parent.addView(yellowBox);
30
         parent.addView(yellowBox);
30
     }
31
     }
31
 
32
 
32
     @Test
33
     @Test
33
     public void onYellowBoxAdded_removedFromParent() {
34
     public void onYellowBoxAdded_removedFromParent() {
34
-        uut.onYellowBoxAdded(parent, yellowBox);
35
+        uut.onYellowBoxAdded(parent);
35
         assertThat(yellowBox.getParent()).isNull();
36
         assertThat(yellowBox.getParent()).isNull();
36
     }
37
     }
37
 
38
 
38
     @Test
39
     @Test
39
     public void onYellowBoxAdded_storesRefToYellowBoxAndParent() {
40
     public void onYellowBoxAdded_storesRefToYellowBoxAndParent() {
40
-        uut.onYellowBoxAdded(parent, yellowBox);
41
-        assertThat(uut.getYellowBox()).isEqualTo(yellowBox);
41
+        uut.onYellowBoxAdded(parent);
42
+        assertThat(uut.getYellowBoxes()).contains(yellowBox);
42
         assertThat(uut.getParent()).isEqualTo(parent);
43
         assertThat(uut.getParent()).isEqualTo(parent);
43
     }
44
     }
44
 
45
 
45
     @Test
46
     @Test
46
     public void onReactViewDestroy_yellowBoxIsAddedBackToParent() {
47
     public void onReactViewDestroy_yellowBoxIsAddedBackToParent() {
47
-        uut.onYellowBoxAdded(parent, yellowBox);
48
+        uut.onYellowBoxAdded(parent);
48
         uut.destroy();
49
         uut.destroy();
49
         assertThat(yellowBox.getParent()).isEqualTo(parent);
50
         assertThat(yellowBox.getParent()).isEqualTo(parent);
50
     }
51
     }
57
 
58
 
58
     @Test
59
     @Test
59
     public void onYellowBoxAdded_notHandledIfDelegateIsDestroyed() {
60
     public void onYellowBoxAdded_notHandledIfDelegateIsDestroyed() {
60
-        uut.onYellowBoxAdded(parent, yellowBox);
61
+        uut.onYellowBoxAdded(parent);
61
         uut.destroy();
62
         uut.destroy();
62
 
63
 
63
-        uut.onYellowBoxAdded(parent, yellowBox);
64
+        uut.onYellowBoxAdded(parent);
64
         assertThat(yellowBox.getParent()).isEqualTo(parent);
65
         assertThat(yellowBox.getParent()).isEqualTo(parent);
65
     }
66
     }
66
 }
67
 }