|
@@ -26,11 +26,10 @@ import android.util.Log;
|
26
|
26
|
import com.facebook.react.bridge.ReadableMap;
|
27
|
27
|
|
28
|
28
|
import java.lang.reflect.Method;
|
29
|
|
-import java.net.URL;
|
30
|
29
|
import java.util.Map;
|
31
|
30
|
|
32
|
|
-public class JitsiMeetView
|
33
|
|
- extends BaseReactView<JitsiMeetViewListener> {
|
|
31
|
+
|
|
32
|
+public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener> {
|
34
|
33
|
|
35
|
34
|
/**
|
36
|
35
|
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
|
@@ -45,25 +44,6 @@ public class JitsiMeetView
|
45
|
44
|
*/
|
46
|
45
|
private static final String TAG = JitsiMeetView.class.getSimpleName();
|
47
|
46
|
|
48
|
|
- /**
|
49
|
|
- * A color scheme object to override the default color is the SDK.
|
50
|
|
- */
|
51
|
|
- private Bundle colorScheme;
|
52
|
|
-
|
53
|
|
- /**
|
54
|
|
- * The default base {@code URL} used to join a conference when a partial URL
|
55
|
|
- * (e.g. a room name only) is specified to {@link #loadURLString(String)} or
|
56
|
|
- * {@link #loadURLObject(Bundle)}.
|
57
|
|
- */
|
58
|
|
- private URL defaultURL;
|
59
|
|
-
|
60
|
|
- /**
|
61
|
|
- * Whether Picture-in-Picture is enabled. If {@code null}, defaults to
|
62
|
|
- * {@code true} iff the Android platform supports Picture-in-Picture
|
63
|
|
- * natively.
|
64
|
|
- */
|
65
|
|
- private Boolean pictureInPictureEnabled;
|
66
|
|
-
|
67
|
47
|
/**
|
68
|
48
|
* The URL of the current conference.
|
69
|
49
|
*/
|
|
@@ -71,10 +51,45 @@ public class JitsiMeetView
|
71
|
51
|
// fine to have this field volatile without additional synchronization.
|
72
|
52
|
private volatile String url;
|
73
|
53
|
|
74
|
|
- /**
|
75
|
|
- * Whether the Welcome page is enabled.
|
76
|
|
- */
|
77
|
|
- private boolean welcomePageEnabled;
|
|
54
|
+ private static Bundle mergeProps(@Nullable Bundle a, @Nullable Bundle b) {
|
|
55
|
+ Bundle result = new Bundle();
|
|
56
|
+
|
|
57
|
+ if (a == null) {
|
|
58
|
+ if (b != null) {
|
|
59
|
+ result.putAll(b);
|
|
60
|
+ }
|
|
61
|
+
|
|
62
|
+ return result;
|
|
63
|
+ }
|
|
64
|
+
|
|
65
|
+ if (b == null) {
|
|
66
|
+ result.putAll(a);
|
|
67
|
+
|
|
68
|
+ return result;
|
|
69
|
+ }
|
|
70
|
+
|
|
71
|
+ // Start by putting all of a in the result.
|
|
72
|
+ result.putAll(a);
|
|
73
|
+
|
|
74
|
+ // Iterate over each key in b and override if appropriate.
|
|
75
|
+ for (String key : b.keySet()) {
|
|
76
|
+ Object bValue = b.get(key);
|
|
77
|
+ Object aValue = a.get(key);
|
|
78
|
+ String valueType = bValue.getClass().getSimpleName();
|
|
79
|
+
|
|
80
|
+ if (valueType.contentEquals("Boolean")) {
|
|
81
|
+ result.putBoolean(key, (Boolean)bValue);
|
|
82
|
+ } else if (valueType.contentEquals("String")) {
|
|
83
|
+ result.putString(key, (String)bValue);
|
|
84
|
+ } else if (valueType.contentEquals("Bundle")) {
|
|
85
|
+ result.putBundle(key, mergeProps((Bundle)aValue, (Bundle)bValue));
|
|
86
|
+ }
|
|
87
|
+
|
|
88
|
+ // TODO: handle string arrays when the need arises.
|
|
89
|
+ }
|
|
90
|
+
|
|
91
|
+ return result;
|
|
92
|
+ }
|
78
|
93
|
|
79
|
94
|
public JitsiMeetView(@NonNull Context context) {
|
80
|
95
|
super(context);
|
|
@@ -96,134 +111,31 @@ public class JitsiMeetView
|
96
|
111
|
* page.
|
97
|
112
|
*/
|
98
|
113
|
public void enterPictureInPicture() {
|
99
|
|
- if (isPictureInPictureEnabled() && getURL() != null) {
|
100
|
|
- PictureInPictureModule pipModule
|
101
|
|
- = ReactInstanceManagerHolder.getNativeModule(
|
|
114
|
+ PictureInPictureModule pipModule
|
|
115
|
+ = ReactInstanceManagerHolder.getNativeModule(
|
102
|
116
|
PictureInPictureModule.class);
|
103
|
|
-
|
104
|
|
- if (pipModule != null) {
|
105
|
|
- try {
|
106
|
|
- pipModule.enterPictureInPicture();
|
107
|
|
- } catch (RuntimeException re) {
|
108
|
|
- Log.e(TAG, "onUserLeaveHint: failed to enter PiP mode", re);
|
109
|
|
- }
|
|
117
|
+ if (pipModule != null
|
|
118
|
+ && PictureInPictureModule.isPictureInPictureSupported()
|
|
119
|
+ && this.url != null) {
|
|
120
|
+ try {
|
|
121
|
+ pipModule.enterPictureInPicture();
|
|
122
|
+ } catch (RuntimeException re) {
|
|
123
|
+ Log.e(TAG, "failed to enter PiP mode", re);
|
110
|
124
|
}
|
111
|
125
|
}
|
112
|
126
|
}
|
113
|
127
|
|
114
|
|
- /**
|
115
|
|
- * Gets the color scheme used in the SDK.
|
116
|
|
- *
|
117
|
|
- * @return The color scheme map.
|
118
|
|
- */
|
119
|
|
- public Bundle getColorScheme() {
|
120
|
|
- return colorScheme;
|
121
|
|
- }
|
122
|
|
-
|
123
|
|
- /**
|
124
|
|
- * Gets the default base {@code URL} used to join a conference when a
|
125
|
|
- * partial URL (e.g. a room name only) is specified to
|
126
|
|
- * {@link #loadURLString(String)} or {@link #loadURLObject(Bundle)}. If not
|
127
|
|
- * set or if set to {@code null}, the default built in JavaScript is used:
|
128
|
|
- * https://meet.jit.si
|
129
|
|
- *
|
130
|
|
- * @return The default base {@code URL} or {@code null}.
|
131
|
|
- */
|
132
|
|
- public URL getDefaultURL() {
|
133
|
|
- return defaultURL;
|
134
|
|
- }
|
135
|
|
-
|
136
|
|
- /**
|
137
|
|
- * Gets the URL of the current conference.
|
138
|
|
- *
|
139
|
|
- * XXX The method is meant for internal purposes only at the time of this
|
140
|
|
- * writing because there is no equivalent API on iOS.
|
141
|
|
- *
|
142
|
|
- * @return the URL {@code String} of the current conference if any;
|
143
|
|
- * otherwise, {@code null}.
|
144
|
|
- */
|
145
|
|
- String getURL() {
|
146
|
|
- return url;
|
147
|
|
- }
|
148
|
|
-
|
149
|
|
- /**
|
150
|
|
- * Gets whether Picture-in-Picture is enabled. Picture-in-Picture is
|
151
|
|
- * natively supported on Android API >= 26 (Oreo), so it should not be
|
152
|
|
- * enabled on older platform versions.
|
153
|
|
- *
|
154
|
|
- * @return If Picture-in-Picture is enabled, {@code true}; {@code false},
|
155
|
|
- * otherwise.
|
156
|
|
- */
|
157
|
|
- public boolean isPictureInPictureEnabled() {
|
158
|
|
- return
|
159
|
|
- PictureInPictureModule.isPictureInPictureSupported()
|
160
|
|
- && (pictureInPictureEnabled == null
|
161
|
|
- || pictureInPictureEnabled);
|
162
|
|
- }
|
163
|
|
-
|
164
|
|
- /**
|
165
|
|
- * Gets whether the Welcome page is enabled. If {@code true}, the Welcome
|
166
|
|
- * page is rendered when this {@code JitsiMeetView} is not at a URL
|
167
|
|
- * identifying a Jitsi Meet conference/room.
|
168
|
|
- *
|
169
|
|
- * @return {@code true} if the Welcome page is enabled; otherwise,
|
170
|
|
- * {@code false}.
|
171
|
|
- */
|
172
|
|
- public boolean isWelcomePageEnabled() {
|
173
|
|
- return welcomePageEnabled;
|
174
|
|
- }
|
175
|
|
-
|
176
|
|
- public void join(@Nullable String url) {
|
177
|
|
- Bundle urlObject;
|
178
|
|
-
|
179
|
|
- if (url == null) {
|
180
|
|
- urlObject = null;
|
181
|
|
- } else {
|
182
|
|
- urlObject = new Bundle();
|
183
|
|
- urlObject.putString("url", url);
|
184
|
|
- }
|
185
|
|
- loadURL(urlObject);
|
|
128
|
+ public void join(@Nullable JitsiMeetConferenceOptions options) {
|
|
129
|
+ setProps(options != null ? options.asProps() : new Bundle());
|
186
|
130
|
}
|
187
|
131
|
|
188
|
132
|
public void leave() {
|
189
|
|
- loadURL(null);
|
|
133
|
+ setProps(new Bundle());
|
190
|
134
|
}
|
191
|
135
|
|
192
|
|
- /**
|
193
|
|
- * Loads a specific URL which may identify a conference to join. The URL is
|
194
|
|
- * specified in the form of a {@link Bundle} of properties which (1)
|
195
|
|
- * internally are sufficient to construct a URL {@code String} while (2)
|
196
|
|
- * abstracting the specifics of constructing the URL away from API
|
197
|
|
- * clients/consumers. If the specified URL is {@code null} and the Welcome
|
198
|
|
- * page is enabled, the Welcome page is displayed instead.
|
199
|
|
- *
|
200
|
|
- * @param urlObject The URL to load which may identify a conference to join.
|
201
|
|
- */
|
202
|
|
- private void loadURL(@Nullable Bundle urlObject) {
|
203
|
|
- Bundle props = new Bundle();
|
204
|
|
-
|
205
|
|
- // color scheme
|
206
|
|
- if (colorScheme != null) {
|
207
|
|
- props.putBundle("colorScheme", colorScheme);
|
208
|
|
- }
|
209
|
|
-
|
210
|
|
- // defaultURL
|
211
|
|
- if (defaultURL != null) {
|
212
|
|
- props.putString("defaultURL", defaultURL.toString());
|
213
|
|
- }
|
214
|
|
-
|
215
|
|
- // pictureInPictureEnabled
|
216
|
|
- props.putBoolean(
|
217
|
|
- "pictureInPictureEnabled",
|
218
|
|
- isPictureInPictureEnabled());
|
219
|
|
-
|
220
|
|
- // url
|
221
|
|
- if (urlObject != null) {
|
222
|
|
- props.putBundle("url", urlObject);
|
223
|
|
- }
|
224
|
|
-
|
225
|
|
- // welcomePageEnabled
|
226
|
|
- props.putBoolean("welcomePageEnabled", welcomePageEnabled);
|
|
136
|
+ private void setProps(@NonNull Bundle newProps) {
|
|
137
|
+ // Merge the default options with the newly provided ones.
|
|
138
|
+ Bundle props = mergeProps(JitsiMeet.getDefaultProps(), newProps);
|
227
|
139
|
|
228
|
140
|
// XXX The method loadURLObject: is supposed to be imperative i.e.
|
229
|
141
|
// a second invocation with one and the same URL is expected to join
|
|
@@ -248,18 +160,18 @@ public class JitsiMeetView
|
248
|
160
|
* by/associated with the specified {@code eventName}.
|
249
|
161
|
*/
|
250
|
162
|
private void maybeSetViewURL(String eventName, ReadableMap eventData) {
|
|
163
|
+ String url = eventData.getString("url");
|
|
164
|
+
|
251
|
165
|
switch(eventName) {
|
252
|
166
|
case "CONFERENCE_WILL_JOIN":
|
253
|
|
- setURL(eventData.getString("url"));
|
|
167
|
+ this.url = url;
|
254
|
168
|
break;
|
255
|
169
|
|
256
|
170
|
case "CONFERENCE_FAILED":
|
257
|
171
|
case "CONFERENCE_WILL_LEAVE":
|
258
|
172
|
case "LOAD_CONFIG_ERROR":
|
259
|
|
- String url = eventData.getString("url");
|
260
|
|
-
|
261
|
|
- if (url != null && url.equals(getURL())) {
|
262
|
|
- setURL(null);
|
|
173
|
+ if (url != null && url.equals(this.url)) {
|
|
174
|
+ this.url = null;
|
263
|
175
|
}
|
264
|
176
|
break;
|
265
|
177
|
}
|
|
@@ -283,62 +195,4 @@ public class JitsiMeetView
|
283
|
195
|
|
284
|
196
|
onExternalAPIEvent(LISTENER_METHODS, name, data);
|
285
|
197
|
}
|
286
|
|
-
|
287
|
|
- /**
|
288
|
|
- * Sets the color scheme to override the default colors of the SDK.
|
289
|
|
- *
|
290
|
|
- * @param colorScheme The color scheme map.
|
291
|
|
- */
|
292
|
|
- public void setColorScheme(Bundle colorScheme) {
|
293
|
|
- this.colorScheme = colorScheme;
|
294
|
|
- }
|
295
|
|
-
|
296
|
|
- /**
|
297
|
|
- * Sets the default base {@code URL} used to join a conference when a
|
298
|
|
- * partial URL (e.g. a room name only) is specified to
|
299
|
|
- * {@link #loadURLString(String)} or {@link #loadURLObject(Bundle)}. Must be
|
300
|
|
- * called before {@link #loadURL(URL)} for it to take effect.
|
301
|
|
- *
|
302
|
|
- * @param defaultURL The {@code URL} to be set as the default base URL.
|
303
|
|
- * @see #getDefaultURL()
|
304
|
|
- */
|
305
|
|
- public void setDefaultURL(URL defaultURL) {
|
306
|
|
- this.defaultURL = defaultURL;
|
307
|
|
- }
|
308
|
|
-
|
309
|
|
- /**
|
310
|
|
- * Sets whether Picture-in-Picture is enabled. Because Picture-in-Picture is
|
311
|
|
- * natively supported only since certain platform versions, specifying
|
312
|
|
- * {@code true} will have no effect on unsupported platform versions.
|
313
|
|
- *
|
314
|
|
- * @param pictureInPictureEnabled To enable Picture-in-Picture,
|
315
|
|
- * {@code true}; otherwise, {@code false}.
|
316
|
|
- */
|
317
|
|
- public void setPictureInPictureEnabled(boolean pictureInPictureEnabled) {
|
318
|
|
- this.pictureInPictureEnabled = pictureInPictureEnabled;
|
319
|
|
- }
|
320
|
|
-
|
321
|
|
- /**
|
322
|
|
- * Sets the URL of the current conference.
|
323
|
|
- *
|
324
|
|
- * XXX The method is meant for internal purposes only. It does not
|
325
|
|
- * {@code loadURL}, it merely remembers the specified URL.
|
326
|
|
- *
|
327
|
|
- * @param url the URL {@code String} which to be set as the URL of the
|
328
|
|
- * current conference.
|
329
|
|
- */
|
330
|
|
- void setURL(String url) {
|
331
|
|
- this.url = url;
|
332
|
|
- }
|
333
|
|
-
|
334
|
|
- /**
|
335
|
|
- * Sets whether the Welcome page is enabled. Must be called before
|
336
|
|
- * {@link #loadURL(URL)} for it to take effect.
|
337
|
|
- *
|
338
|
|
- * @param welcomePageEnabled {@code true} to enable the Welcome page;
|
339
|
|
- * otherwise, {@code false}.
|
340
|
|
- */
|
341
|
|
- public void setWelcomePageEnabled(boolean welcomePageEnabled) {
|
342
|
|
- this.welcomePageEnabled = welcomePageEnabled;
|
343
|
|
- }
|
344
|
198
|
}
|