Browse Source

Side menu works

Guy Carmeli 8 years ago
parent
commit
f2fdac7dde

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/layout/Container.java View File

4
 import android.widget.FrameLayout;
4
 import android.widget.FrameLayout;
5
 
5
 
6
 public class Container extends FrameLayout {
6
 public class Container extends FrameLayout {
7
-    public Container(Context context, LayoutFactory.RootViewCreator rootViewCreator, String id, String name) {
7
+    public Container(Context context, LayoutFactory.ReactRootViewCreator reactRootViewCreator, String id, String name) {
8
         super(context);
8
         super(context);
9
-        addView(rootViewCreator.createRootView(id, name));
9
+        addView(reactRootViewCreator.create(id, name));
10
     }
10
     }
11
 }
11
 }

android/app/src/main/java/com/reactnativenavigation/layout/ContainerStack.java → android/app/src/main/java/com/reactnativenavigation/layout/ContainerStackLayout.java View File

3
 import android.content.Context;
3
 import android.content.Context;
4
 import android.widget.FrameLayout;
4
 import android.widget.FrameLayout;
5
 
5
 
6
-public class ContainerStack extends FrameLayout {
7
-    public ContainerStack(Context context) {
6
+public class ContainerStackLayout extends FrameLayout {
7
+    public ContainerStackLayout(Context context) {
8
         super(context);
8
         super(context);
9
     }
9
     }
10
 }
10
 }

+ 58
- 15
android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java View File

1
 package com.reactnativenavigation.layout;
1
 package com.reactnativenavigation.layout;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
+import android.support.v4.widget.DrawerLayout;
5
+import android.view.Gravity;
4
 import android.view.View;
6
 import android.view.View;
7
+import android.view.ViewGroup.LayoutParams;
5
 
8
 
6
-import com.reactnativenavigation.layout.bottomtabs.BottomTabsContainer;
7
 import com.reactnativenavigation.layout.bottomtabs.BottomTabsCreator;
9
 import com.reactnativenavigation.layout.bottomtabs.BottomTabsCreator;
10
+import com.reactnativenavigation.layout.bottomtabs.BottomTabsLayout;
11
+import com.reactnativenavigation.utils.ViewIdGenerator;
8
 
12
 
9
 import java.util.List;
13
 import java.util.List;
10
 
14
 
11
 public class LayoutFactory {
15
 public class LayoutFactory {
12
 
16
 
13
-    public interface RootViewCreator {
14
-        View createRootView(String id, String name);
17
+    public interface ReactRootViewCreator {
18
+        View create(String id, String name);
15
     }
19
     }
16
 
20
 
17
     private final Activity activity;
21
     private final Activity activity;
18
-    private final RootViewCreator rootViewCreator;
22
+    private final ReactRootViewCreator reactRootViewCreator;
19
     private final BottomTabsCreator bottomTabsCreator; // TODO: revisit this, may not be needed
23
     private final BottomTabsCreator bottomTabsCreator; // TODO: revisit this, may not be needed
20
 
24
 
21
-    public LayoutFactory(Activity activity, RootViewCreator rootViewCreator, BottomTabsCreator bottomTabsCreator) {
25
+    public LayoutFactory(Activity activity, ReactRootViewCreator reactRootViewCreator, BottomTabsCreator bottomTabsCreator) {
22
         this.activity = activity;
26
         this.activity = activity;
23
-        this.rootViewCreator = rootViewCreator;
27
+        this.reactRootViewCreator = reactRootViewCreator;
24
         this.bottomTabsCreator = bottomTabsCreator;
28
         this.bottomTabsCreator = bottomTabsCreator;
25
     }
29
     }
26
 
30
 
32
                 return createContainerStackView(node);
36
                 return createContainerStackView(node);
33
             case "BottomTabs":
37
             case "BottomTabs":
34
                 return createBottomTabs(node);
38
                 return createBottomTabs(node);
39
+            case "SideMenuRoot":
40
+                return createSideMenuRoot(node);
41
+            case "SideMenuCenter":
42
+                return createSideMenuContent(node);
43
+            case "SideMenuLeft":
44
+                return createSideMenuLeft(node);
45
+            case "SideMenuRight":
46
+                return createSideMenuRight(node);
35
             default:
47
             default:
36
                 throw new IllegalArgumentException("Invalid node type: "+node.type);
48
                 throw new IllegalArgumentException("Invalid node type: "+node.type);
37
         }
49
         }
38
     }
50
     }
39
 
51
 
52
+    private View createSideMenuRoot(LayoutNode node) {
53
+        SideMenuLayout sideMenuLayout = new SideMenuLayout(activity);
54
+        for (LayoutNode child : node.children) {
55
+            sideMenuLayout.addView(create(child));
56
+        }
57
+        return sideMenuLayout;
58
+    }
59
+
60
+    private View createSideMenuContent(LayoutNode node) {
61
+        return create(node.children.get(0));
62
+    }
63
+
64
+    private View createSideMenuLeft(LayoutNode node) {
65
+        View view = create(node.children.get(0));
66
+        view.setId(ViewIdGenerator.generate());
67
+        DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
68
+        lp.gravity = Gravity.LEFT;
69
+        view.setLayoutParams(lp);
70
+        return view;
71
+    }
72
+
73
+    private View createSideMenuRight(LayoutNode node) {
74
+        View view = create(node.children.get(0));
75
+        view.setId(ViewIdGenerator.generate());
76
+        DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
77
+        lp.gravity = Gravity.RIGHT;
78
+        view.setLayoutParams(lp);
79
+        return view;
80
+    }
81
+
40
     private View createContainerView(LayoutNode node) {
82
     private View createContainerView(LayoutNode node) {
41
         final String name = (String) node.data.get("name");
83
         final String name = (String) node.data.get("name");
42
-        return new Container(activity, rootViewCreator, node.id, name);
84
+        Container container = new Container(activity, reactRootViewCreator, node.id, name);
85
+        container.setId(ViewIdGenerator.generate());
86
+        return container;
87
+
43
     }
88
     }
44
 
89
 
45
     private View createContainerStackView(LayoutNode node) {
90
     private View createContainerStackView(LayoutNode node) {
46
-        final ContainerStack containerStack = new ContainerStack(activity);
91
+        final ContainerStackLayout containerStack = new ContainerStackLayout(activity);
92
+        containerStack.setId(ViewIdGenerator.generate());
47
         addChildrenNodes(containerStack, node.children);
93
         addChildrenNodes(containerStack, node.children);
48
         return containerStack;
94
         return containerStack;
49
     }
95
     }
50
 
96
 
51
     private View createBottomTabs(LayoutNode node) {
97
     private View createBottomTabs(LayoutNode node) {
52
-        final BottomTabsContainer tabsContainer = new BottomTabsContainer(activity, bottomTabsCreator.create());
53
-
54
-        int i = 0;
55
-        for (LayoutNode child : node.children) {
56
-            final View tabContent = create(child);
98
+        final BottomTabsLayout tabsContainer = new BottomTabsLayout(activity, bottomTabsCreator.create());
99
+        for (int i = 0; i < node.children.size(); i++) {
100
+            final View tabContent = create(node.children.get(i));
57
             tabsContainer.addTabContent("#" + i, tabContent);
101
             tabsContainer.addTabContent("#" + i, tabContent);
58
-            i++;
59
         }
102
         }
60
         return tabsContainer;
103
         return tabsContainer;
61
     }
104
     }
62
 
105
 
63
-    private void addChildrenNodes(ContainerStack containerStack, List<LayoutNode> children) {
106
+    private void addChildrenNodes(ContainerStackLayout containerStack, List<LayoutNode> children) {
64
         for (LayoutNode child : children) {
107
         for (LayoutNode child : children) {
65
             containerStack.addView(create(child));
108
             containerStack.addView(create(child));
66
         }
109
         }

+ 5
- 0
android/app/src/main/java/com/reactnativenavigation/layout/LayoutNode.java View File

12
     public LayoutNode() {
12
     public LayoutNode() {
13
     }
13
     }
14
 
14
 
15
+    public LayoutNode(String type, List<LayoutNode> children) {
16
+        this.type = type;
17
+        this.children = children;
18
+    }
19
+
15
     public LayoutNode(String id, String type, Map<String, Object> data) {
20
     public LayoutNode(String id, String type, Map<String, Object> data) {
16
         this.id = id;
21
         this.id = id;
17
         this.type = type;
22
         this.type = type;

+ 10
- 0
android/app/src/main/java/com/reactnativenavigation/layout/SideMenuLayout.java View File

1
+package com.reactnativenavigation.layout;
2
+
3
+import android.content.Context;
4
+import android.support.v4.widget.DrawerLayout;
5
+
6
+public class SideMenuLayout extends DrawerLayout {
7
+    public SideMenuLayout(Context context) {
8
+        super(context);
9
+    }
10
+}

+ 3
- 28
android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabs.java View File

1
 package com.reactnativenavigation.layout.bottomtabs;
1
 package com.reactnativenavigation.layout.bottomtabs;
2
 
2
 
3
 import android.graphics.Color;
3
 import android.graphics.Color;
4
-import android.os.Build;
5
 import android.support.annotation.NonNull;
4
 import android.support.annotation.NonNull;
6
 import android.support.design.widget.BottomNavigationView;
5
 import android.support.design.widget.BottomNavigationView;
7
 import android.view.Menu;
6
 import android.view.Menu;
8
 import android.view.MenuItem;
7
 import android.view.MenuItem;
9
-import android.view.View;
10
 import android.widget.RelativeLayout;
8
 import android.widget.RelativeLayout;
11
 import android.widget.RelativeLayout.LayoutParams;
9
 import android.widget.RelativeLayout.LayoutParams;
12
 
10
 
13
-import java.util.concurrent.atomic.AtomicInteger;
14
-
11
+import static android.view.View.generateViewId;
15
 import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
12
 import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
16
 
13
 
17
 public class BottomTabs implements BottomNavigationView.OnNavigationItemSelectedListener {
14
 public class BottomTabs implements BottomNavigationView.OnNavigationItemSelectedListener {
20
         void onTabSelected(int index);
17
         void onTabSelected(int index);
21
     }
18
     }
22
 
19
 
23
-    private static final AtomicInteger viewId = new AtomicInteger(1);
24
-
25
     private BottomNavigationView bottomNavigationView;
20
     private BottomNavigationView bottomNavigationView;
26
     private BottomTabsSelectionListener listener;
21
     private BottomTabsSelectionListener listener;
27
 
22
 
28
     public void attach(RelativeLayout parentLayout) {
23
     public void attach(RelativeLayout parentLayout) {
29
         createBottomNavigation(parentLayout);
24
         createBottomNavigation(parentLayout);
30
-        addButtomNavigationToParent(parentLayout);
25
+        addBottomNavigationToParent(parentLayout);
31
     }
26
     }
32
 
27
 
33
     public void setSelectionListener(BottomTabsSelectionListener listener) {
28
     public void setSelectionListener(BottomTabsSelectionListener listener) {
60
         bottomNavigationView.setOnNavigationItemSelectedListener(this);
55
         bottomNavigationView.setOnNavigationItemSelectedListener(this);
61
     }
56
     }
62
 
57
 
63
-    private void addButtomNavigationToParent(RelativeLayout parentLayout) {
58
+    private void addBottomNavigationToParent(RelativeLayout parentLayout) {
64
         LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
59
         LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
65
         lp.addRule(ALIGN_PARENT_BOTTOM);
60
         lp.addRule(ALIGN_PARENT_BOTTOM);
66
         bottomNavigationView.setLayoutParams(lp);
61
         bottomNavigationView.setLayoutParams(lp);
67
         parentLayout.addView(bottomNavigationView, lp);
62
         parentLayout.addView(bottomNavigationView, lp);
68
     }
63
     }
69
-
70
-    private int generateViewId() {
71
-        if (Build.VERSION.SDK_INT >= 17) {
72
-            return View.generateViewId();
73
-        } else {
74
-            return compatGenerateViewId();
75
-        }
76
-    }
77
-
78
-    private int compatGenerateViewId() {
79
-        while(true) {
80
-            final int result = viewId.get();
81
-            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
82
-            int newValue = result + 1;
83
-            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
84
-            if (viewId.compareAndSet(result, newValue)) {
85
-                return result;
86
-            }
87
-        }
88
-    }
89
 }
64
 }

android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsContainer.java → android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsLayout.java View File

7
 import java.util.ArrayList;
7
 import java.util.ArrayList;
8
 import java.util.List;
8
 import java.util.List;
9
 
9
 
10
-public class BottomTabsContainer extends RelativeLayout implements BottomTabs.BottomTabsSelectionListener {
10
+public class BottomTabsLayout extends RelativeLayout implements BottomTabs.BottomTabsSelectionListener {
11
 
11
 
12
     private List<View> tabsContent;
12
     private List<View> tabsContent;
13
     private BottomTabs bottomTabs;
13
     private BottomTabs bottomTabs;
14
     private int currentTab;
14
     private int currentTab;
15
 
15
 
16
-    public BottomTabsContainer(Activity activity, BottomTabs bottomTabs) {
16
+    public BottomTabsLayout(Activity activity, BottomTabs bottomTabs) {
17
         super(activity);
17
         super(activity);
18
         initBottomTabs(bottomTabs);
18
         initBottomTabs(bottomTabs);
19
     }
19
     }

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

36
         NavigationActivity.instance.runOnUiThread(new Runnable() {
36
         NavigationActivity.instance.runOnUiThread(new Runnable() {
37
             @Override
37
             @Override
38
             public void run() {
38
             public void run() {
39
-                LayoutFactory factory = new LayoutFactory(NavigationActivity.instance, new LayoutFactory.RootViewCreator() {
39
+                LayoutFactory factory = new LayoutFactory(NavigationActivity.instance, new LayoutFactory.ReactRootViewCreator() {
40
                     @Override
40
                     @Override
41
-                    public View createRootView(String id, String name) {
41
+                    public View create(String id, String name) {
42
                         ReactRootView rootView = new ReactRootView(NavigationActivity.instance);
42
                         ReactRootView rootView = new ReactRootView(NavigationActivity.instance);
43
                         Bundle opts = new Bundle();
43
                         Bundle opts = new Bundle();
44
                         opts.putString("id", id);
44
                         opts.putString("id", id);

+ 30
- 0
android/app/src/main/java/com/reactnativenavigation/utils/ViewIdGenerator.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+import android.os.Build;
4
+import android.view.View;
5
+
6
+import java.util.concurrent.atomic.AtomicInteger;
7
+
8
+public class ViewIdGenerator {
9
+    private static final AtomicInteger viewId = new AtomicInteger(1);
10
+
11
+    public static int generate() {
12
+        if (Build.VERSION.SDK_INT >= 17) {
13
+            return View.generateViewId();
14
+        } else {
15
+            return compatGenerateViewId();
16
+        }
17
+    }
18
+
19
+    private static int compatGenerateViewId() {
20
+        while(true) {
21
+            final int result = viewId.get();
22
+            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
23
+            int newValue = result + 1;
24
+            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
25
+            if (viewId.compareAndSet(result, newValue)) {
26
+                return result;
27
+            }
28
+        }
29
+    }
30
+}

+ 12
- 12
android/app/src/test/java/com/reactnativenavigation/BottomTabsContainerTest.java View File

4
 import android.view.View;
4
 import android.view.View;
5
 
5
 
6
 import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
6
 import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
7
-import com.reactnativenavigation.layout.bottomtabs.BottomTabsContainer;
7
+import com.reactnativenavigation.layout.bottomtabs.BottomTabsLayout;
8
 import com.reactnativenavigation.layout.bottomtabs.TooManyTabsException;
8
 import com.reactnativenavigation.layout.bottomtabs.TooManyTabsException;
9
 
9
 
10
 import org.junit.Before;
10
 import org.junit.Before;
36
     public void addsTabToBottomTabs() throws Exception {
36
     public void addsTabToBottomTabs() throws Exception {
37
         View tabContent = new View(activity);
37
         View tabContent = new View(activity);
38
 
38
 
39
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
39
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
40
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
40
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
41
 
41
 
42
         verify(bottomTabs).add(TAB_NAME);
42
         verify(bottomTabs).add(TAB_NAME);
46
     public void addsTabContentToLayout() throws Exception {
46
     public void addsTabContentToLayout() throws Exception {
47
         View tabContent = new View(activity);
47
         View tabContent = new View(activity);
48
 
48
 
49
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
49
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
50
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
50
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
51
 
51
 
52
         verify(bottomTabs).attach(bottomTabsContainer);
52
         verify(bottomTabs).attach(bottomTabsContainer);
58
         View tabContent = new View(activity);
58
         View tabContent = new View(activity);
59
         View otherTabContent = new View(activity);
59
         View otherTabContent = new View(activity);
60
 
60
 
61
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
61
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
62
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
62
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
63
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
63
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
64
 
64
 
67
 
67
 
68
     @Test (expected = TooManyTabsException.class)
68
     @Test (expected = TooManyTabsException.class)
69
     public void throwsExceptionWhenMoreThenFiveTabs() throws Exception {
69
     public void throwsExceptionWhenMoreThenFiveTabs() throws Exception {
70
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
70
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
71
         for (int i = 0; i < 6; i++) {
71
         for (int i = 0; i < 6; i++) {
72
             View content = new View(activity);
72
             View content = new View(activity);
73
             bottomTabsContainer.addTabContent("#" + i, content);
73
             bottomTabsContainer.addTabContent("#" + i, content);
76
 
76
 
77
     @Test
77
     @Test
78
     public void addFiveTabs() throws Exception {
78
     public void addFiveTabs() throws Exception {
79
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
79
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
80
         for (int i = 0; i < 5; i++) {
80
         for (int i = 0; i < 5; i++) {
81
             View content = new View(activity);
81
             View content = new View(activity);
82
             bottomTabsContainer.addTabContent("#" + i, content);
82
             bottomTabsContainer.addTabContent("#" + i, content);
88
         View tabContent = new View(activity);
88
         View tabContent = new View(activity);
89
         View otherTabContent = new View(activity);
89
         View otherTabContent = new View(activity);
90
 
90
 
91
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
91
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
92
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
92
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
93
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
93
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
94
 
94
 
98
 
98
 
99
     @Test
99
     @Test
100
     public void listensToTabsSwitchingEvents() throws Exception {
100
     public void listensToTabsSwitchingEvents() throws Exception {
101
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
101
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
102
         verify(bottomTabs).setSelectionListener(bottomTabsContainer);
102
         verify(bottomTabs).setSelectionListener(bottomTabsContainer);
103
     }
103
     }
104
 
104
 
107
         View tabContent = new View(activity);
107
         View tabContent = new View(activity);
108
         View otherTabContent = new View(activity);
108
         View otherTabContent = new View(activity);
109
 
109
 
110
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
110
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
111
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
111
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
112
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
112
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
113
         bottomTabsContainer.onTabSelected(1);
113
         bottomTabsContainer.onTabSelected(1);
121
         View tabContent = new View(activity);
121
         View tabContent = new View(activity);
122
         View otherTabContent = new View(activity);
122
         View otherTabContent = new View(activity);
123
 
123
 
124
-        BottomTabsContainer bottomTabsContainer = createBottomTabsContainer();
124
+        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
125
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
125
         bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
126
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
126
         bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
127
         bottomTabsContainer.onTabSelected(1);
127
         bottomTabsContainer.onTabSelected(1);
131
         assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
131
         assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
132
     }
132
     }
133
 
133
 
134
-    private BottomTabsContainer createBottomTabsContainer() {
135
-        return new BottomTabsContainer(activity, bottomTabs);
134
+    private BottomTabsLayout createBottomTabsContainer() {
135
+        return new BottomTabsLayout(activity, bottomTabs);
136
     }
136
     }
137
 }
137
 }

+ 69
- 39
android/app/src/test/java/com/reactnativenavigation/LayoutFactoryTest.java View File

6
 import android.view.ViewGroup;
6
 import android.view.ViewGroup;
7
 
7
 
8
 import com.reactnativenavigation.layout.Container;
8
 import com.reactnativenavigation.layout.Container;
9
-import com.reactnativenavigation.layout.ContainerStack;
9
+import com.reactnativenavigation.layout.ContainerStackLayout;
10
 import com.reactnativenavigation.layout.LayoutFactory;
10
 import com.reactnativenavigation.layout.LayoutFactory;
11
 import com.reactnativenavigation.layout.LayoutNode;
11
 import com.reactnativenavigation.layout.LayoutNode;
12
+import com.reactnativenavigation.layout.SideMenuLayout;
12
 import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
13
 import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
13
-import com.reactnativenavigation.layout.bottomtabs.BottomTabsContainer;
14
 import com.reactnativenavigation.layout.bottomtabs.BottomTabsCreator;
14
 import com.reactnativenavigation.layout.bottomtabs.BottomTabsCreator;
15
+import com.reactnativenavigation.layout.bottomtabs.BottomTabsLayout;
15
 
16
 
16
 import org.junit.Before;
17
 import org.junit.Before;
17
 import org.junit.Test;
18
 import org.junit.Test;
33
 @RunWith(RobolectricTestRunner.class)
34
 @RunWith(RobolectricTestRunner.class)
34
 public class LayoutFactoryTest {
35
 public class LayoutFactoryTest {
35
 
36
 
36
-    private final static String VIEW_ID = "myUniqueId";
37
-    private final static String VIEW_NAME = "myName";
37
+    private final static String NODE_ID = "myUniqueId";
38
+    private final static String REACT_ROOT_VIEW_KEY = "myName";
38
 
39
 
39
-    private final static String OTHER_VIEW_ID = "anotherUniqueId";
40
-    private final static String OTHER_VIEW_NAME = "anotherName";
40
+    private final static String OTHER_NODE_ID = "anotherUniqueId";
41
+    private final static String OTHER_REACT_ROOT_VIEW_KEY = "anotherName";
41
 
42
 
42
     private Activity activity;
43
     private Activity activity;
43
     private View mockView;
44
     private View mockView;
44
     private View otherMockView;
45
     private View otherMockView;
45
-    private LayoutFactory.RootViewCreator rootViewCreator;
46
+    private LayoutFactory.ReactRootViewCreator reactRootViewCreator;
46
 
47
 
47
     @Before
48
     @Before
48
     public void setUp() {
49
     public void setUp() {
49
         activity = Robolectric.buildActivity(AppCompatActivity.class).get();
50
         activity = Robolectric.buildActivity(AppCompatActivity.class).get();
50
         mockView = new View(activity);
51
         mockView = new View(activity);
51
         otherMockView = new View(activity);
52
         otherMockView = new View(activity);
52
-        rootViewCreator = mock(LayoutFactory.RootViewCreator.class);
53
+        reactRootViewCreator = mock(LayoutFactory.ReactRootViewCreator.class);
53
     }
54
     }
54
 
55
 
55
     @Test
56
     @Test
56
     public void returnsContainerThatHoldsTheRootView() throws Exception {
57
     public void returnsContainerThatHoldsTheRootView() throws Exception {
57
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
58
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
58
         final LayoutNode node = createContainerNode();
59
         final LayoutNode node = createContainerNode();
59
 
60
 
60
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
61
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
65
 
66
 
66
     @Test
67
     @Test
67
     public void returnsContainerStack() throws Exception {
68
     public void returnsContainerStack() throws Exception {
68
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
69
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
69
         final LayoutNode containerNode = createContainerNode();
70
         final LayoutNode containerNode = createContainerNode();
70
         final LayoutNode stackNode = createContainerStackNode(containerNode);
71
         final LayoutNode stackNode = createContainerStackNode(containerNode);
71
 
72
 
72
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
73
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
73
 
74
 
74
-        assertThat(result).isInstanceOf(ContainerStack.class);
75
+        assertThat(result).isInstanceOf(ContainerStackLayout.class);
75
         ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(result, 1).get(0);
76
         ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(result, 1).get(0);
76
         TestUtils.assertViewChildren(container, mockView);
77
         TestUtils.assertViewChildren(container, mockView);
77
     }
78
     }
80
     public void returnsContainerStackWithMultipleViews() throws Exception {
81
     public void returnsContainerStackWithMultipleViews() throws Exception {
81
         final View mockView1 = mock(View.class);
82
         final View mockView1 = mock(View.class);
82
         final View mockView2 = mock(View.class);
83
         final View mockView2 = mock(View.class);
83
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView1);
84
-        when(rootViewCreator.createRootView(eq(OTHER_VIEW_ID), eq(OTHER_VIEW_NAME))).thenReturn(mockView2);
84
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView1);
85
+        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(mockView2);
85
 
86
 
86
-        final LayoutNode containerNode1 = createContainerNode(VIEW_ID, VIEW_NAME);
87
-        final LayoutNode containerNode2 = createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME);
87
+        final LayoutNode containerNode1 = createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
88
+        final LayoutNode containerNode2 = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
88
         final LayoutNode stackNode = createContainerStackNode(containerNode1, containerNode2);
89
         final LayoutNode stackNode = createContainerStackNode(containerNode1, containerNode2);
89
 
90
 
90
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
91
         final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
91
 
92
 
92
-        assertThat(result).isInstanceOf(ContainerStack.class);
93
+        assertThat(result).isInstanceOf(ContainerStackLayout.class);
93
         List<View> containers = TestUtils.assertViewChildrenCount(result, 2);
94
         List<View> containers = TestUtils.assertViewChildrenCount(result, 2);
94
         ViewGroup container1 = (ViewGroup) containers.get(0);
95
         ViewGroup container1 = (ViewGroup) containers.get(0);
95
         ViewGroup container2 = (ViewGroup) containers.get(1);
96
         ViewGroup container2 = (ViewGroup) containers.get(1);
97
         TestUtils.assertViewChildren(container2, mockView2);
98
         TestUtils.assertViewChildren(container2, mockView2);
98
     }
99
     }
99
 
100
 
101
+    @Test
102
+    public void returnsSideMenuRoot() throws Exception {
103
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
104
+        final LayoutNode containerNode = createSideMenuContainerNode(Arrays.asList(createContainerNode()));
105
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(containerNode);
106
+        assertThat(result).isInstanceOf(SideMenuLayout.class);
107
+    }
108
+
109
+    @Test
110
+    public void hasContentContainer() throws Exception {
111
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
112
+        LayoutNode contentContainer = createContainerNode();
113
+        final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(contentContainer));
114
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
115
+        assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
116
+    }
117
+
118
+    @Test
119
+    public void hasLeftMenu() throws Exception {
120
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
121
+        LayoutNode sideMenuLeft = createSideMenuLeftNode();
122
+        final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(sideMenuLeft));
123
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
124
+        assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
125
+    }
126
+
100
     @Test
127
     @Test
101
     public void returnsSingleTabContent() throws Exception {
128
     public void returnsSingleTabContent() throws Exception {
102
         BottomTabs bottomTabsMock = mock(BottomTabs.class);
129
         BottomTabs bottomTabsMock = mock(BottomTabs.class);
103
         when(bottomTabsMock.size()).thenReturn(0);
130
         when(bottomTabsMock.size()).thenReturn(0);
104
 
131
 
105
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
132
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
106
         final LayoutNode containerNode = createContainerNode();
133
         final LayoutNode containerNode = createContainerNode();
107
-        final LayoutNode tabNode = createTabNode(containerNode);
134
+        final LayoutNode tabNode = createBottomTabNode(containerNode);
108
 
135
 
109
         final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
136
         final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
110
 
137
 
111
         verify(bottomTabsMock).add("#0");
138
         verify(bottomTabsMock).add("#0");
112
 
139
 
113
-        assertThat(result).isInstanceOf(BottomTabsContainer.class);
114
-        Container container = (Container) TestUtils.assertViewChildrenCount((BottomTabsContainer) result, 1).get(0);
140
+        assertThat(result).isInstanceOf(BottomTabsLayout.class);
141
+        Container container = (Container) TestUtils.assertViewChildrenCount((BottomTabsLayout) result, 1).get(0);
115
         View view = TestUtils.assertViewChildrenCount(container, 1).get(0);
142
         View view = TestUtils.assertViewChildrenCount(container, 1).get(0);
116
         assertThat(view).isEqualTo(mockView);
143
         assertThat(view).isEqualTo(mockView);
117
     }
144
     }
121
         BottomTabs bottomTabsMock = mock(BottomTabs.class);
148
         BottomTabs bottomTabsMock = mock(BottomTabs.class);
122
         when(bottomTabsMock.size()).thenReturn(0, 1);
149
         when(bottomTabsMock.size()).thenReturn(0, 1);
123
 
150
 
124
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
125
-        final LayoutNode firstTabRootNode = createContainerNode(VIEW_ID, VIEW_NAME);
151
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
152
+        final LayoutNode firstTabRootNode = createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
126
 
153
 
127
-        when(rootViewCreator.createRootView(eq(OTHER_VIEW_ID), eq(OTHER_VIEW_NAME))).thenReturn(otherMockView);
128
-        final LayoutNode secondTabRootNode = createContainerStackNode(createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME));
154
+        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
155
+        final LayoutNode secondTabRootNode = createContainerStackNode(createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY));
129
 
156
 
130
-        final LayoutNode tabNode = createTabNode(firstTabRootNode, secondTabRootNode);
157
+        final LayoutNode tabNode = createBottomTabNode(firstTabRootNode, secondTabRootNode);
131
 
158
 
132
         final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
159
         final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
133
 
160
 
134
-        assertThat(result).isInstanceOf(BottomTabsContainer.class);
161
+        assertThat(result).isInstanceOf(BottomTabsLayout.class);
135
         verify(bottomTabsMock).add(eq("#0"));
162
         verify(bottomTabsMock).add(eq("#0"));
136
         verify(bottomTabsMock).add(eq("#1"));
163
         verify(bottomTabsMock).add(eq("#1"));
137
     }
164
     }
139
 
166
 
140
     @Test(expected = IllegalArgumentException.class)
167
     @Test(expected = IllegalArgumentException.class)
141
     public void throwsExceptionForUnknownType() throws Exception {
168
     public void throwsExceptionForUnknownType() throws Exception {
142
-        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
143
-        final LayoutNode node = new LayoutNode(VIEW_ID, "***unknownType***", Collections.<String, Object>emptyMap());
169
+        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
170
+        final LayoutNode node = new LayoutNode(NODE_ID, "***unknownType***", Collections.<String, Object>emptyMap());
144
 
171
 
145
         createLayoutFactory().create(node);
172
         createLayoutFactory().create(node);
146
     }
173
     }
156
             when(bottomTabsCreator.create()).thenReturn(bottomTabs);
183
             when(bottomTabsCreator.create()).thenReturn(bottomTabs);
157
         }
184
         }
158
 
185
 
159
-        return new LayoutFactory(activity, rootViewCreator, bottomTabsCreator);
186
+        return new LayoutFactory(activity, reactRootViewCreator, bottomTabsCreator);
160
     }
187
     }
161
 
188
 
162
     private LayoutNode createContainerNode() {
189
     private LayoutNode createContainerNode() {
163
-        return createContainerNode(VIEW_ID, VIEW_NAME);
190
+        return createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
191
+    }
192
+
193
+    private LayoutNode createSideMenuLeftNode() {
194
+        List<LayoutNode> children = Arrays.asList(createContainerNode());
195
+        return new LayoutNode("SideMenuLeft", children);
164
     }
196
     }
165
 
197
 
166
     private LayoutNode createContainerNode(final String id, final String name) {
198
     private LayoutNode createContainerNode(final String id, final String name) {
167
         return new LayoutNode(id, "Container", new HashMap<String, Object>() {{ put("name", name); }});
199
         return new LayoutNode(id, "Container", new HashMap<String, Object>() {{ put("name", name); }});
168
     }
200
     }
169
 
201
 
202
+    private LayoutNode createSideMenuContainerNode(List<LayoutNode> children) {
203
+        return new LayoutNode("SideMenuRoot", children);
204
+    }
205
+
170
     private LayoutNode createContainerStackNode(LayoutNode... children) {
206
     private LayoutNode createContainerStackNode(LayoutNode... children) {
171
-        LayoutNode node = new LayoutNode();
172
-        node.type = "ContainerStack";
173
-        node.children = Arrays.asList(children);
174
-        return node;
207
+        return new LayoutNode("ContainerStack", Arrays.asList(children));
175
     }
208
     }
176
 
209
 
177
-    private LayoutNode createTabNode(LayoutNode... children) {
178
-        LayoutNode node = new LayoutNode();
179
-        node.type = "BottomTabs";
180
-        node.children = Arrays.asList(children);
181
-        return node;
210
+    private LayoutNode createBottomTabNode(LayoutNode... children) {
211
+        return new LayoutNode("BottomTabs", Arrays.asList(children));
182
     }
212
     }
183
 }
213
 }