Browse Source

V2 overlay skeleton (#2097) (#2098)

* V2 overlay skeleton (#2097)

* skeleton

* basic test

* remove useless files

* remove useles files

* semicolon

* refactoring

* rm useless files
Roman Kozlov 7 years ago
parent
commit
19c247b7d1
18 changed files with 305 additions and 1 deletions
  1. 20
    0
      AndroidE2E/app/src/androidTest/java/com/reactnativenavigation/e2e/androide2e/OverlayTest.java
  2. 1
    1
      README.md
  3. 30
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/OverlayOptions.java
  4. 26
    0
      lib/android/app/src/main/java/com/reactnativenavigation/presentation/OverlayPresenter.java
  5. 12
    0
      lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java
  6. 6
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java
  7. 35
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/AlertOverlay.java
  8. 20
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/CustomOverlay.java
  9. 21
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/FabOverlay.java
  10. 38
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/OverlayFabric.java
  11. 11
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/OverlayInterface.java
  12. 21
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/SnackbarOverlay.java
  13. 34
    0
      lib/android/app/src/test/java/com/reactnativenavigation/parse/OverlayOptionsTest.java
  14. 4
    0
      lib/src/Navigation.js
  15. 5
    0
      lib/src/adapters/NativeCommandsSender.js
  16. 6
    0
      lib/src/commands/Commands.js
  17. 8
    0
      lib/src/commands/Commands.test.js
  18. 7
    0
      playground/src/containers/OptionsScreen.js

+ 20
- 0
AndroidE2E/app/src/androidTest/java/com/reactnativenavigation/e2e/androide2e/OverlayTest.java View File

@@ -0,0 +1,20 @@
1
+package com.reactnativenavigation.e2e.androide2e;
2
+
3
+import android.support.test.uiautomator.By;
4
+
5
+import org.junit.Test;
6
+
7
+import static org.assertj.core.api.Java6Assertions.assertThat;
8
+
9
+public class OverlayTest extends BaseTest {
10
+
11
+	@Test
12
+	public void testOverlayAlertAppear() throws Exception {
13
+		elementByText("PUSH OPTIONS SCREEN").click();
14
+		elementByText("SHOW ALERT").click();
15
+		assertExists(By.text("test!"));
16
+		elementByText("OK").click();
17
+		assertExists(By.text("Static Title"));
18
+
19
+	}
20
+}

+ 1
- 1
README.md View File

@@ -65,7 +65,7 @@ v2 is written in Test Driven Development. We have a test for every feature inclu
65 65
 | resetTo             |   ✅        |	✅|
66 66
 | showModal              |  ✅        |	✅|
67 67
 | dismissModal           |     ✅       |	✅|
68
-| showOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	[Contribute](/docs/docs/CONTRIBUTING.md) |
68
+| showOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	WIP @cool04ek |
69 69
 | dismissOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	[Contribute](/docs/docs/CONTRIBUTING.md) |
70 70
 | customTransition            |   ✅        |	[Contribute](/docs/docs/CONTRIBUTING.md) |
71 71
 | Screen Visibility        | ✅     |✅|

+ 30
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/OverlayOptions.java View File

@@ -0,0 +1,30 @@
1
+package com.reactnativenavigation.parse;
2
+
3
+
4
+import org.json.JSONObject;
5
+
6
+public class OverlayOptions {
7
+
8
+	public static OverlayOptions parse(JSONObject json) {
9
+		if (json == null) return new OverlayOptions();
10
+
11
+		OverlayOptions options = new OverlayOptions();
12
+
13
+		//TODO: parse
14
+		options.title = json.optString("title");
15
+		options.text = json.optString("text");
16
+
17
+		return options;
18
+	}
19
+
20
+	private String title = "";
21
+	private String text = "";
22
+
23
+	public String getText() {
24
+		return text;
25
+	}
26
+
27
+	public String getTitle() {
28
+		return title;
29
+	}
30
+}

+ 26
- 0
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OverlayPresenter.java View File

@@ -0,0 +1,26 @@
1
+package com.reactnativenavigation.presentation;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+import com.reactnativenavigation.viewcontrollers.overlay.AlertOverlay;
8
+import com.reactnativenavigation.viewcontrollers.overlay.CustomOverlay;
9
+import com.reactnativenavigation.viewcontrollers.overlay.FabOverlay;
10
+import com.reactnativenavigation.viewcontrollers.overlay.OverlayFabric;
11
+import com.reactnativenavigation.viewcontrollers.overlay.OverlayInterface;
12
+import com.reactnativenavigation.viewcontrollers.overlay.SnackbarOverlay;
13
+
14
+public class OverlayPresenter {
15
+
16
+	private OverlayInterface overlay;
17
+
18
+	public OverlayPresenter(Context context, String type, OverlayOptions options) {
19
+		this.overlay = OverlayFabric.create(type, context, options);
20
+	}
21
+
22
+
23
+	public void show() {
24
+		overlay.show();
25
+	}
26
+}

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

@@ -13,6 +13,7 @@ import com.reactnativenavigation.parse.LayoutNode;
13 13
 import com.reactnativenavigation.parse.NavigationOptions;
14 14
 import com.reactnativenavigation.parse.JSONParser;
15 15
 import com.reactnativenavigation.parse.LayoutNodeParser;
16
+import com.reactnativenavigation.parse.OverlayOptions;
16 17
 import com.reactnativenavigation.utils.UiThread;
17 18
 import com.reactnativenavigation.viewcontrollers.Navigator;
18 19
 import com.reactnativenavigation.viewcontrollers.ViewController;
@@ -130,6 +131,17 @@ public class NavigationModule extends ReactContextBaseJavaModule {
130 131
 		});
131 132
 	}
132 133
 
134
+	@ReactMethod
135
+	public void showOverlay(final String type, final ReadableMap options) {
136
+		final OverlayOptions overlayOptions = OverlayOptions.parse(JSONParser.parse(options));
137
+		handle(new Runnable() {
138
+			@Override
139
+			public void run() {
140
+				navigator().showOverlay(type, overlayOptions);
141
+			}
142
+		});
143
+	}
144
+
133 145
 	private NavigationActivity activity() {
134 146
 		return (NavigationActivity) getCurrentActivity();
135 147
 	}

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

@@ -6,6 +6,8 @@ import android.view.ViewGroup;
6 6
 import android.widget.FrameLayout;
7 7
 
8 8
 import com.reactnativenavigation.parse.NavigationOptions;
9
+import com.reactnativenavigation.parse.OverlayOptions;
10
+import com.reactnativenavigation.presentation.OverlayPresenter;
9 11
 import com.reactnativenavigation.utils.CompatUtils;
10 12
 
11 13
 import org.json.JSONObject;
@@ -126,4 +128,8 @@ public class Navigator extends ParentController {
126 128
 	public void dismissAllModals() {
127 129
 		modalStack.dismissAll();
128 130
 	}
131
+
132
+	public void showOverlay(String type, OverlayOptions options) {
133
+		new OverlayPresenter(getActivity(), type, options).show();
134
+	}
129 135
 }

+ 35
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/AlertOverlay.java View File

@@ -0,0 +1,35 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+import android.content.DialogInterface;
6
+import android.support.v7.app.AlertDialog;
7
+
8
+import com.reactnativenavigation.parse.OverlayOptions;
9
+
10
+public class AlertOverlay implements OverlayInterface {
11
+
12
+	private AlertDialog dialog;
13
+
14
+	@Override
15
+	public AlertOverlay create(Context context, OverlayOptions options) {
16
+		AlertDialog.Builder builder = new AlertDialog.Builder(context);
17
+
18
+		builder.setTitle(options.getTitle());
19
+		builder.setMessage(options.getText());
20
+		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
21
+			@Override
22
+			public void onClick(DialogInterface dialog, int which) {
23
+				dialog.dismiss();
24
+			}
25
+		});
26
+		dialog = builder.create();
27
+
28
+		return this;
29
+	}
30
+
31
+	@Override
32
+	public void show() {
33
+		dialog.show();
34
+	}
35
+}

+ 20
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/CustomOverlay.java View File

@@ -0,0 +1,20 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+
8
+public class CustomOverlay implements OverlayInterface {
9
+
10
+	@Override
11
+	public CustomOverlay create(Context context, OverlayOptions options) {
12
+		//TODO; implement
13
+		return this;
14
+	}
15
+
16
+	@Override
17
+	public void show() {
18
+		//TODO; implement
19
+	}
20
+}

+ 21
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/FabOverlay.java View File

@@ -0,0 +1,21 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+
8
+public class FabOverlay implements OverlayInterface {
9
+
10
+
11
+	@Override
12
+	public FabOverlay create(Context context, OverlayOptions options) {
13
+		//TODO; implement
14
+		return this;
15
+	}
16
+
17
+	@Override
18
+	public void show() {
19
+		//TODO; implement
20
+	}
21
+}

+ 38
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/OverlayFabric.java View File

@@ -0,0 +1,38 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+
8
+public class OverlayFabric {
9
+
10
+	private enum Overlay {
11
+		AlertDialog("alert", new AlertOverlay()),
12
+		Snackbar("snackbar", new SnackbarOverlay()),
13
+		Fab("fab", new FabOverlay()),
14
+		CustomDialog("custom", new CustomOverlay());
15
+
16
+		private String name;
17
+		private OverlayInterface overlayInstance;
18
+
19
+		Overlay(String name, OverlayInterface overlayInstance) {
20
+			this.name = name;
21
+			this.overlayInstance = overlayInstance;
22
+		}
23
+
24
+		public static Overlay create(String type) {
25
+			for (Overlay overlay : values()) {
26
+				if (overlay.name.equals(type)) {
27
+					return overlay;
28
+				}
29
+			}
30
+			return CustomDialog;
31
+		}
32
+	}
33
+
34
+	public static OverlayInterface create(String type, Context context, OverlayOptions options) {
35
+		return Overlay.create(type).overlayInstance.create(context, options);
36
+	}
37
+
38
+}

+ 11
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/OverlayInterface.java View File

@@ -0,0 +1,11 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+
8
+public interface OverlayInterface {
9
+	OverlayInterface create(Context context, OverlayOptions options);
10
+	void show();
11
+}

+ 21
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/overlay/SnackbarOverlay.java View File

@@ -0,0 +1,21 @@
1
+package com.reactnativenavigation.viewcontrollers.overlay;
2
+
3
+
4
+import android.content.Context;
5
+
6
+import com.reactnativenavigation.parse.OverlayOptions;
7
+
8
+public class SnackbarOverlay implements OverlayInterface {
9
+
10
+
11
+	@Override
12
+	public SnackbarOverlay create(Context context, OverlayOptions options) {
13
+		//TODO; implement
14
+		return this;
15
+	}
16
+
17
+	@Override
18
+	public void show() {
19
+		//TODO; implement
20
+	}
21
+}

+ 34
- 0
lib/android/app/src/test/java/com/reactnativenavigation/parse/OverlayOptionsTest.java View File

@@ -0,0 +1,34 @@
1
+package com.reactnativenavigation.parse;
2
+
3
+import com.reactnativenavigation.BaseTest;
4
+
5
+import org.json.JSONObject;
6
+import org.junit.Test;
7
+
8
+import static com.reactnativenavigation.parse.NavigationOptions.BooleanOptions.True;
9
+import static org.assertj.core.api.Java6Assertions.assertThat;
10
+
11
+public class OverlayOptionsTest extends BaseTest {
12
+
13
+	@Test
14
+	public void parsesNullAsDefaultEmptyOptions() throws Exception {
15
+		assertThat(OverlayOptions.parse(null)).isNotNull();
16
+	}
17
+
18
+	@Test
19
+	public void parsesJson() throws Exception {
20
+		JSONObject json = new JSONObject();
21
+		json.put("title", "the title");
22
+		json.put("text", "the text");
23
+
24
+		OverlayOptions result = OverlayOptions.parse(json);
25
+		assertThat(result.getTitle()).isEqualTo("the title");
26
+		assertThat(result.getText()).isEqualTo("the text");
27
+	}
28
+
29
+	@Test
30
+	public void defaultEmptyOptions() throws Exception {
31
+		OverlayOptions uut = new OverlayOptions();
32
+		assertThat(uut.getTitle()).isEmpty();
33
+	}
34
+}

+ 4
- 0
lib/src/Navigation.js View File

@@ -71,6 +71,10 @@ class Navigation {
71 71
   events() {
72 72
     return this.publicEventsRegistry;
73 73
   }
74
+
75
+  showOverlay(type, options) {
76
+    return this.commands.showOverlay(type, options);
77
+  }
74 78
 }
75 79
 
76 80
 const singleton = new Navigation();

+ 5
- 0
lib/src/adapters/NativeCommandsSender.js View File

@@ -53,6 +53,11 @@ class NativeCommandsSender {
53 53
     this.nativeCommandsModule.switchToTab(containerId, tabIndex);
54 54
     return Promise.resolve(containerId);
55 55
   }
56
+
57
+  showOverlay(type, options) {
58
+    this.nativeCommandsModule.showOverlay(type, options);
59
+    return Promise.resolve(type);
60
+  }
56 61
 }
57 62
 
58 63
 module.exports = NativeCommandsSender;

+ 6
- 0
lib/src/commands/Commands.js View File

@@ -58,6 +58,12 @@ class Commands {
58 58
   switchToTab(containerId, tabIndex) {
59 59
     return this.nativeCommandsSender.switchToTab(containerId, tabIndex);
60 60
   }
61
+
62
+  showOverlay(type, options) {
63
+    const input = _.cloneDeep(options);
64
+    OptionsProcessor.processOptions(input);
65
+    return this.nativeCommandsSender.showOverlay(type, input);
66
+  }
61 67
 }
62 68
 
63 69
 module.exports = Commands;

+ 8
- 0
lib/src/commands/Commands.test.js View File

@@ -237,4 +237,12 @@ describe('Commands', () => {
237 237
       expect(result).toEqual('theContainerId');
238 238
     });
239 239
   });
240
+
241
+  describe('showOverlay', () => {
242
+    it('deep clones input to avoid mutation errors', () => {
243
+      const obj = { title: 'test' };
244
+      uut.showOverlay('alert', obj);
245
+      expect(mockCommandsSender.showOverlay.mock.calls[0][1]).not.toBe(obj);
246
+    });
247
+  });
240 248
 });

+ 7
- 0
playground/src/containers/OptionsScreen.js View File

@@ -48,6 +48,7 @@ class OptionsScreen extends Component {
48 48
         <Button title="Show Top Bar" onPress={this.onClickShowTopBar} />
49 49
         <Button title="Hide Top Bar" onPress={this.onClickHideTopBar} />
50 50
         <Button title="scrollView Screen" onPress={this.onClickScrollViewScreen} />
51
+        <Button title="Show alert" onPress={this.onClickAlert} />
51 52
         <Text style={styles.footer}>{`this.props.containerId = ${this.props.containerId}`}</Text>
52 53
       </View>
53 54
     );
@@ -111,6 +112,12 @@ class OptionsScreen extends Component {
111 112
       animateTopBarHide: true
112 113
     });
113 114
   }
115
+
116
+  onClickAlert() {
117
+    Navigation.showOverlay('alert', {
118
+      text: 'test!'
119
+    });
120
+  }
114 121
 }
115 122
 
116 123
 const styles = {