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

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
 | resetTo             |   ✅        |	✅|
65
 | resetTo             |   ✅        |	✅|
66
 | showModal              |  ✅        |	✅|
66
 | showModal              |  ✅        |	✅|
67
 | dismissModal           |     ✅       |	✅|
67
 | dismissModal           |     ✅       |	✅|
68
-| showOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	[Contribute](/docs/docs/CONTRIBUTING.md) |
68
+| showOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	WIP @cool04ek |
69
 | dismissOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	[Contribute](/docs/docs/CONTRIBUTING.md) |
69
 | dismissOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	[Contribute](/docs/docs/CONTRIBUTING.md) |
70
 | customTransition            |   ✅        |	[Contribute](/docs/docs/CONTRIBUTING.md) |
70
 | customTransition            |   ✅        |	[Contribute](/docs/docs/CONTRIBUTING.md) |
71
 | Screen Visibility        | ✅     |✅|
71
 | Screen Visibility        | ✅     |✅|

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

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

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
 import com.reactnativenavigation.parse.NavigationOptions;
13
 import com.reactnativenavigation.parse.NavigationOptions;
14
 import com.reactnativenavigation.parse.JSONParser;
14
 import com.reactnativenavigation.parse.JSONParser;
15
 import com.reactnativenavigation.parse.LayoutNodeParser;
15
 import com.reactnativenavigation.parse.LayoutNodeParser;
16
+import com.reactnativenavigation.parse.OverlayOptions;
16
 import com.reactnativenavigation.utils.UiThread;
17
 import com.reactnativenavigation.utils.UiThread;
17
 import com.reactnativenavigation.viewcontrollers.Navigator;
18
 import com.reactnativenavigation.viewcontrollers.Navigator;
18
 import com.reactnativenavigation.viewcontrollers.ViewController;
19
 import com.reactnativenavigation.viewcontrollers.ViewController;
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
 	private NavigationActivity activity() {
145
 	private NavigationActivity activity() {
134
 		return (NavigationActivity) getCurrentActivity();
146
 		return (NavigationActivity) getCurrentActivity();
135
 	}
147
 	}

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

6
 import android.widget.FrameLayout;
6
 import android.widget.FrameLayout;
7
 
7
 
8
 import com.reactnativenavigation.parse.NavigationOptions;
8
 import com.reactnativenavigation.parse.NavigationOptions;
9
+import com.reactnativenavigation.parse.OverlayOptions;
10
+import com.reactnativenavigation.presentation.OverlayPresenter;
9
 import com.reactnativenavigation.utils.CompatUtils;
11
 import com.reactnativenavigation.utils.CompatUtils;
10
 
12
 
11
 import org.json.JSONObject;
13
 import org.json.JSONObject;
126
 	public void dismissAllModals() {
128
 	public void dismissAllModals() {
127
 		modalStack.dismissAll();
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

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

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

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

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

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

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

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
   events() {
71
   events() {
72
     return this.publicEventsRegistry;
72
     return this.publicEventsRegistry;
73
   }
73
   }
74
+
75
+  showOverlay(type, options) {
76
+    return this.commands.showOverlay(type, options);
77
+  }
74
 }
78
 }
75
 
79
 
76
 const singleton = new Navigation();
80
 const singleton = new Navigation();

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

53
     this.nativeCommandsModule.switchToTab(containerId, tabIndex);
53
     this.nativeCommandsModule.switchToTab(containerId, tabIndex);
54
     return Promise.resolve(containerId);
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
 module.exports = NativeCommandsSender;
63
 module.exports = NativeCommandsSender;

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

58
   switchToTab(containerId, tabIndex) {
58
   switchToTab(containerId, tabIndex) {
59
     return this.nativeCommandsSender.switchToTab(containerId, tabIndex);
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
 module.exports = Commands;
69
 module.exports = Commands;

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

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