Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.reactnativenavigation.options;

import android.app.Activity;
import android.content.Context;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.reactnativenavigation.NavigationApplication;
import com.reactnativenavigation.options.parsers.TypefaceLoader;
import com.reactnativenavigation.react.events.EventEmitter;
import com.reactnativenavigation.utils.Assertions;
Expand Down Expand Up @@ -45,6 +47,8 @@
import static com.reactnativenavigation.options.Options.parse;
import static com.reactnativenavigation.utils.CollectionUtils.*;

import org.json.JSONObject;

public class LayoutFactory {
private Activity activity;
private ChildControllersRegistry childRegistry;
Expand Down Expand Up @@ -75,33 +79,33 @@ public ViewController<?> create(final LayoutNode node) {
final ReactContext context = reactInstanceManager.getCurrentReactContext();
switch (node.type) {
case Component:
return createComponent(context, node);
return createComponent(node);
case ExternalComponent:
return createExternalComponent(context, node);
case Stack:
return createStack(context, node);
return createStack(node);
case BottomTabs:
return createBottomTabs(context, node);
return createBottomTabs(node);
case SideMenuRoot:
return createSideMenuRoot(context, node);
return createSideMenuRoot(node);
case SideMenuCenter:
return createSideMenuContent(node);
case SideMenuLeft:
return createSideMenuLeft(node);
case SideMenuRight:
return createSideMenuRight(node);
case TopTabs:
return createTopTabs(context, node);
return createTopTabs(node);
default:
throw new IllegalArgumentException("Invalid node type: " + node.type);
}
}

private ViewController<?> createSideMenuRoot(ReactContext context, LayoutNode node) {
private ViewController<?> createSideMenuRoot(LayoutNode node) {
SideMenuController sideMenuController = new SideMenuController(activity,
childRegistry,
node.id,
parse(context, typefaceManager, node.getOptions()),
parseOptions( node.getOptions()),
new SideMenuPresenter(),
new Presenter(activity, defaultOptions)
);
Expand Down Expand Up @@ -153,15 +157,15 @@ private ViewController<?> createSideMenuRight(LayoutNode node) {
return create(node.children.get(0));
}

private ViewController<?> createComponent(ReactContext context, LayoutNode node) {
private ViewController<?> createComponent(LayoutNode node) {
String id = node.id;
String name = node.data.optString("name");
return new ComponentViewController(activity,
childRegistry,
id,
name,
new ComponentViewCreator(reactInstanceManager),
parse(context, typefaceManager, node.getOptions()),
parseOptions(node.getOptions()),
new Presenter(activity, defaultOptions),
new ComponentPresenter(defaultOptions)
);
Expand All @@ -178,17 +182,17 @@ private ViewController<?> createExternalComponent(ReactContext context, LayoutNo
reactInstanceManager,
new EventEmitter(context),
new ExternalComponentPresenter(),
parse(context, typefaceManager, node.getOptions())
parseOptions(node.getOptions())
);
}

private ViewController<?> createStack(ReactContext context, LayoutNode node) {
private ViewController<?> createStack(LayoutNode node) {
return new StackControllerBuilder(activity, eventEmitter)
.setChildren(createChildren(node.children))
.setChildRegistry(childRegistry)
.setTopBarController(new TopBarController())
.setId(node.id)
.setInitialOptions(parse(context, typefaceManager, node.getOptions()))
.setInitialOptions(parseOptions(node.getOptions()))
.setStackPresenter(new StackPresenter(activity,
new TitleBarReactViewCreator(reactInstanceManager),
new TopBarBackgroundViewCreator(reactInstanceManager),
Expand All @@ -210,7 +214,7 @@ private List<ViewController<?>> createChildren(List<LayoutNode> children) {
return result;
}

private ViewController<?> createBottomTabs(ReactContext context, LayoutNode node) {
private ViewController<?> createBottomTabs(LayoutNode node) {
List<ViewController<?>> tabs = map(node.children, this::create);
BottomTabsPresenter bottomTabsPresenter = new BottomTabsPresenter(tabs, defaultOptions, new BottomTabsAnimator());
return new BottomTabsController(activity,
Expand All @@ -219,24 +223,35 @@ private ViewController<?> createBottomTabs(ReactContext context, LayoutNode node
eventEmitter,
new ImageLoader(),
node.id,
parse(context, typefaceManager, node.getOptions()),
parseOptions( node.getOptions()),
new Presenter(activity, defaultOptions),
new BottomTabsAttacher(tabs, bottomTabsPresenter, defaultOptions),
bottomTabsPresenter,
new BottomTabPresenter(activity, tabs, new ImageLoader(), new TypefaceLoader(activity), defaultOptions));
}

private ViewController<?> createTopTabs(ReactContext context, LayoutNode node) {
private ViewController<?> createTopTabs(LayoutNode node) {
final List<ViewController<?>> tabs = new ArrayList<>();
for (int i = 0; i < node.children.size(); i++) {
ViewController<?> tabController = create(node.children.get(i));
Options options = parse(context, typefaceManager, node.children.get(i).getOptions());
Options options = parseOptions(node.children.get(i).getOptions());
options.setTopTabIndex(i);
tabs.add(tabController);
}
return new TopTabsController(activity, childRegistry, node.id, tabs, new TopTabsLayoutCreator(activity, tabs), parse(context, typefaceManager, node.getOptions()), new Presenter(activity, defaultOptions));
return new TopTabsController(activity, childRegistry, node.id, tabs, new TopTabsLayoutCreator(activity, tabs)
, parseOptions(node.getOptions()), new Presenter(activity, defaultOptions));
}

private Options parseOptions(JSONObject jsonOptions) {
Context context = reactInstanceManager.getCurrentReactContext();
if (context == null) {
context = activity == null ? NavigationApplication.instance : activity;
}
if (typefaceManager == null) {
typefaceManager = new TypefaceLoader(context);
}
return parse(context, typefaceManager, jsonOptions);
}
@NonNull
@RestrictTo(RestrictTo.Scope.TESTS)
public Options getDefaultOptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Options {
public static final Options EMPTY = new Options();

@NonNull
public static Options parse(Context context, TypefaceLoader typefaceManager, JSONObject json) {
public static Options parse(@NonNull Context context, TypefaceLoader typefaceManager, JSONObject json) {
Options result = new Options();
if (json == null) return result;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,19 @@
import java.util.HashMap;

import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.assertj.core.api.Java6Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class LayoutFactoryTest extends BaseTest {
private LayoutFactory uut;
private ReactInstanceManager mockReactInstanceManager;

@Override
public void beforeEach() {
uut = new LayoutFactory(mock(ReactInstanceManager.class));
super.beforeEach();
mockReactInstanceManager = mock(ReactInstanceManager.class);
uut = new LayoutFactory(mockReactInstanceManager);
uut.init(
newActivity(),
Mockito.mock(EventEmitter.class),
Expand All @@ -36,6 +41,16 @@ public void sanity() throws JSONException {
assertThat(uut.create(component())).isNotNull();
}

@Test
public void shouldParseOptionsWhenReactContextIsNull() {
when(mockReactInstanceManager.getCurrentReactContext()).thenReturn(null);
try {
uut.create(component());
} catch (Exception e) {
fail("Create should not fail! when react instance has null context");
}
}

@Test
public void defaultOptionsAreNotNull() {
assertThat(uut.getDefaultOptions()).isNotNull();
Expand All @@ -50,6 +65,14 @@ public void defaultOptionsAreNotNull() {
}

private LayoutNode component() throws JSONException {
return new LayoutNode("Component1", LayoutNode.Type.Component, new JSONObject().put("name", "com.component"), null);
final JSONObject component = new JSONObject();
final JSONObject layout = new JSONObject();
final JSONObject backgroundColor = new JSONObject();
backgroundColor.put("dark",0);
backgroundColor.put("light",1);
layout.put("backgroundColor",backgroundColor );
component.put("name", "com.component");
component.put("options",new JSONObject().put("layout", layout));
return new LayoutNode("Component1", LayoutNode.Type.Component, component, null);
}
}