@glance-networks/reactnative-bridge
v0.1.3
Published
Android/iOS Native modules for hosting the GlanceSDK RN support layer
Downloads
356
Readme
@glance-networks/reactnative-bridge
Android/iOS Native modules for hosting the GlanceSDK RN support layer
Getting started
- Run
yarn install
to install the dependencies. - Run
yarn example <android/ios>
to run the internal app where we test the bridge
PS.: we didn't move all methods to the src/index.tsx
yet, but those that were moved already work. The ones accessed directly by the GlanceBridge
too, but that should change once we publish it to the NPM registry.
Usage
Due to framework/language limitations and also aiming to build a smooth use between platforms, we need to send all the method's arguments as key-value pairs in a single map in all methods. To make it even easier, we have a set of constants available through the GlanceBridge.getConstants()
method where you can get any key name before creating the map, avoiding hardcoded strings. To see the full list, check the appendix.
PS.: the ReadableMap
being received by some methods offers the same flexibility we have in the native calls, by using overloading to provide several method variations with different arguments. Required fields and data type rules are the same.
We also tried to simulate the same data types by creating sub-maps when needed. For example, DisplayParams
in StartParams
would look like:
{
"key" : "1234",
"displayParams" : {
"displayName": "somename",
"scale": 1.0,
...
}
...
}
Here's a list of the available methods (for more details, please check the native docs - Android and iOS):
| Method | Sync? | Android | iOS | ReadableMap structure¹ |
| --- | --- | --- | --- | --- |
| getVersion(Callback callback) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| init(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "timeout": 1000, "attempts": 3, "glanceServer": "www.glance.net", "groupID" : 0000, "visitorID": "someid", "site": "somesite", "token": "sometoken", "name": "some name", "email": "some@email", "phone": "12345678", "allowedCameras": "\"front\"}
|
| addMaskedViewId(Integer reactTag, String label, Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| removeMaskedViewId(Integer viewId) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| getVisitorCallId(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| isInSession(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| isVideoAvailable(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| isAgentVideoEnabled(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| pause(Boolean isPaused) : Boolean
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| togglePause() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| release() : void
| :white_check_mark: | :white_check_mark: | :x: | - |
| updateVisitorVideoSize(int width, int height, String stringMode) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| updateVisitorVideoStatus(boolean isPaused) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| updateWidgetVisibility(String stringVisibility) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| updateWidgetLocation(String stringVisibility) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| setUserState(String state, String value) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| sendUserMessage(String messageType, String value) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| startSession(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "groupID" : 0000, "maskKeyboard": true, "timeout": 1000, "attempts": 3,"skipDialog": false, "displayParams" : {"displayName": "somename", "scale": 1.0, "displayCaptureWidth": 0, "displayCaptureHeight": 0, "displayVideo": false }, "key": "1234", "videoMode": "smallmultiway", "captureEntireScreen": false, "mediaProjectionEnabled": false, "mainCallId": 0, "maxGuests": 0, "show": false, "guestInfoFlags": 0, "encrypt": false, "requestRC": false, "instantJoin": false, "forceTunnel": false, "viewerCloseable": false, "reportErrors": false, "persist": false, "showTerms": true, "presenceStart": false, "paused": false, "termsUrl": null }
|
| endSession() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| addVisitorVideo(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "videoMode": "smallmultiway", "invokeShowWidget": true}
|
| getVisitorId(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| getVisitorStartParams(Callback callback) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| setPresenceStartParams(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "displayParams" : {"displayName": "somename", "scale": 1.0, "displayCaptureWidth": 0, "displayCaptureHeight": 0, "displayVideo": false }, "key": null, "videoMode": "smallmultiway", "captureEntireScreen": false, "mediaProjectionEnabled": false, "mainCallId": 0, "maxGuests": 0, "show": false, "guestInfoFlags": 0, "encrypt": false, "requestRC": false, "instantJoin": false, "forceTunnel": false, "viewerCloseable": false, "reportErrors": false, "persist": false, "showTerms": true, "presenceStart": false, "paused": false, "termsUrl": null }
|
| getPresenceVideoMode(Callback callback) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| arePresenceTermsDisplayed(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| connectToPresence(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "timeout": 1000, "attempts": 3, "registerNotifications": false }
|
| sendToPresenceSession(ReadableMap readableMap) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | { "presenceEvent": "presence", "presenceDataMap": { "url": "someurl"}}
|
| sendPresenceTermsAccepted(boolean isAccepted) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| disconnectPresence() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| sendPresenceTermsDisplayed() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| isPresenceConnected(Promise promise) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| getApplicationName() : String
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| maskKeyboard(boolean maskKeyboard) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| restartAgentVideo() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| getCapturedScreenSize(Callback callback) : void
| :x: | :white_check_mark: | :white_check_mark: | - |
| openWebView() : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| setGlanceGroupID(String groupID) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
| setGlanceServer(String server) : void
| :white_check_mark: | :white_check_mark: | :white_check_mark: | - |
¹ This represents what the method can expect to have in its ReadbableMap
argument. This doesn't mean that you need to always send everything. For more details, please refer to the native docs.
Masking
To achieve masking we use react tags to identify the views in the native level so we can remove the mask later. Basic steps to make it work:
- Create a variable to hold a react tag reference that will be used later:
import React from 'react';
...
constructor(props: any) {
super(props);
this.viewRef = React.createRef();
....
}
...
- Once the component is loaded, find the native view reference and save it in the state so we can use it to call
GlanceBridge.addMaskedViewId
:
import { findNodeHandle } from 'react-native';
...
async componentDidMount() {
const reactTag = findNodeHandle(this.vewRef.current);
this.setState({logoViewId : await GlanceBridge.addMaskedViewId(reactTag, "MASKED 1")});
....
}
...
- Use the
viewRef
in the desired view.
render() {
return (
<View style={styles.container}>
<Text style={styles.text} ref={this.viewRef}>Some view to be masked</Text>
</View>
);
}
Examples
Sync methods
const dataMap = {
groupID: <YOUR GROUP ID>,
visitorID: "",
site: "",
token: "",
name: "",
email: "",
phone: "",
allowedCameras: '"front","back"'
};
dataMap[VISITOR_ID_MAP_KEY] = visitorID;
GlanceBridge.init(dataMap);
Async methods
const callId = await GlanceBridge.getVisitorCallId();
console.log('Call ID:', `${callId}`);
How to listen to Events
import { NativeModules, NativeEventEmitter } from 'react-native';
const { GlanceBridge } = NativeModules;
const eventEmitter = new NativeEventEmitter(GlanceBridge);
const GlanceBridge = NativeModules.GlanceBridge;
const {
GLANCE_EVENT_LISTENER_KEY,
SESSION_KEY_MAP_KEY,
EventVisitorInitialized,
EventConnectedToSession,
EventSessionEnded
} = GlanceBridge.getConstants();
export default class MyComponent extends Component {
...
onGlanceEvent = eventEmitter.addListener(GLANCE_EVENT_LISTENER_KEY, async (event) => {
console.log("RECEIVED EVENT >>>", event);
if (event.code == EventConnectedToSession) {
// update any status view/variable/etc
Alert.alert(
`Session key:`,
event[SESSION_KEY_MAP_KEY]
);
} else if (event.code == EventSessionEnded) {
// update any status view/variable/etc
}
});
componentWillUnmount() {
this.onGlanceEvent.remove(); // don't forget to unregister it
}
....
}
Constants
In order to make things easier, we reused the same variable names/constants from the native code as much as possible. Along with the following list, you'll also have access to the VideoMode
and EventCode
constant values.
---------------TODO: maybe those are different for Android and iOS
| Key | Value |
| --- | --- |
| SDK_VERSION_MAP_KEY
| "version" |
| SESSION_KEY_MAP_KEY
| "sessionkey" |
| MASK_KEYBOARD_MAP_KEY
| "maskKeyboard" |
| VIDEO_MODE_MAP_KEY
| "videoMode" |
| GLANCE_TIMEOUT_MAP_KEY
| "timeout" |
| GLANCE_ATTEMPTS_MAP_KEY
| "attempts" |
| GROUP_ID_MAP_KEY
| "groupID" |
| VISITOR_ID_MAP_KEY
| "visitorID" |
| GLANCE_SERVER_MAP_KEY
| "glanceServer" |
| TOKEN_MAP_KEY
| "token" |
| NAME_MAP_KEY
| "name" |
| EMAIL_MAP_KEY
| "email" |
| PHONE_MAP_KEY
| "phone" |
| SKIP_DIALOG_MAP_KEY
| "skipDialog" |
| INVOKE_SHOW_WIDGET_MAP_KEY
| "invokeShowWidget" |
| SITE_MAP_KEY
| "site" |
| ALLOWED_CAMERAS_MAP_KEY
| "allowedCameras" |
| REGISTER_PRESENCE_NOTIFICATIONS_MAP_KEY
| "registerNotifications" |
| SCREEN_X_VALUE
| "screenX" |
| SCREEN_Y_VALUE
| "screenY" |
| DISPLAY_PARAMS_MAP_KEY
| "displayParams" |
| DISPLAY_PARAMS_NAME_MAP_KEY
| "displayName" |
| DISPLAY_PARAMS_SCALE_MAP_KEY
| "displayScale" |
| DISPLAY_PARAMS_WIDTH_MAP_KEY
| "displayCaptureWidth" |
| DISPLAY_PARAMS_HEIGHT_MAP_KEY
| "displayCaptureHeight" |
| DISPLAY_PARAMS_VIDEO_MAP_KEY
| "displayVideo" |
| START_PARAMS_CAPTURE_ENTIRE_SCREEN_MAP_KEY
| "captureEntireScreen" |
| START_PARAMS_MEDIA_PROJECTION_MAP_KEY
| "mediaProjectionEnabled" |
| START_PARAMS_MAIN_CALL_ID_MAP_KEY
| "mainCallId" |
| START_PARAMS_MAX_GUESTS_MAP_KEY
| "maxGuests" |
| START_PARAMS_SHOW_MAP_KEY
| "show" |
| START_PARAMS_GUEST_INFO_FLAGS_MAP_KEY
| "guestInfoFlags" |
| START_PARAMS_ENCRYPT_MAP_KEY
| "encrypt" |
| START_PARAMS_REQUEST_RC_MAP_KEY
| "requestRC" |
| START_PARAMS_INSTANT_JOIN_MAP_KEY
| "instantJoin" |
| START_PARAMS_FORCE_TUNNEL_MAP_KEY
| "forceTunnel" |
| START_PARAMS_VIEWER_CLOSEABLE_MAP_KEY
| "viewerCloseable" |
| START_PARAMS_REPORT_ERRORS_MAP_KEY
| "reportErrors" |
| START_PARAMS_PERSIST_MAP_KEY
| "persist" |
| START_PARAMS_SHOW_TERMS_MAP_KEY
| "showTerms" |
| START_PARAMS_PRESENCE_START_MAP_KEY
| "presenceStart" |
| START_PARAMS_PAUSED_MAP_KEY
| "paused" |
| START_PARAMS_TERMS_URL_MAP_KEY
| "termsUrl" |
| GLANCE_EVENT_LISTENER_KEY
| "GlanceEvent" |
| GUEST_COUNT_MAP_KEY
| "guestCount" |
| EVENT_RECEIVED_MESSAGE_MAP_KEY
| "receivedMessage" |
| EVENT_RECEIVED_MESSAGE_VALUE_MAP_KEY
| "receivedMessageValue" |
| EVENT_WARNING_MESSAGE_MAP_KEY
| "warningMsg" |
| EVENT_CODE_MAP_KEY
| "code" |
| EVENT_TYPE_MAP_KEY
| "type" |
| PRESENCE_EVENT_MAP_KEY
| "presenceEvent" |
| PRESENCE_DATA_MAP_KEY
| "presenceDataMap" |
License
See License file and https://ww2.glance.net/terms/ for Glance terms of service.