|
|
@@ -32,56 +32,58 @@ import com.facebook.react.common.LifecycleState;
|
|
32
|
32
|
import java.net.URL;
|
|
33
|
33
|
import java.util.HashMap;
|
|
34
|
34
|
|
|
35
|
|
-
|
|
36
|
35
|
public class JitsiMeetView extends FrameLayout {
|
|
37
|
36
|
/**
|
|
38
|
|
- * Background color used by this view and the React Native root view.
|
|
|
37
|
+ * Background color used by {@code JitsiMeetView} and the React Native root
|
|
|
38
|
+ * view.
|
|
39
|
39
|
*/
|
|
40
|
40
|
private static final int BACKGROUND_COLOR = 0xFF111111;
|
|
41
|
41
|
|
|
42
|
42
|
/**
|
|
43
|
|
- * {@JitsiMeetView.Listener} instance for reporting events occurring in Jitsi Meet.
|
|
|
43
|
+ * Reference to the single instance of this class we currently allow. It's
|
|
|
44
|
+ * currently used for fetching the instance from the listener's callbacks.
|
|
|
45
|
+ *
|
|
|
46
|
+ * TODO: lift this limitation.
|
|
44
|
47
|
*/
|
|
45
|
|
- private JitsiMeetView.Listener listener;
|
|
|
48
|
+ private static JitsiMeetView instance;
|
|
46
|
49
|
|
|
47
|
50
|
/**
|
|
48
|
|
- * Reference to the single instance of this class we currently allow. It's currently used for
|
|
49
|
|
- * fetching the instance from the listener's callbacks.
|
|
50
|
|
- *
|
|
51
|
|
- * TODO: lift this limitation.
|
|
|
51
|
+ * React Native bridge. The instance manager allows embedding applications
|
|
|
52
|
+ * to create multiple root views off the same JavaScript bundle.
|
|
52
|
53
|
*/
|
|
53
|
|
- private static JitsiMeetView mInstance;
|
|
|
54
|
+ private static ReactInstanceManager reactInstanceManager;
|
|
54
|
55
|
|
|
55
|
56
|
/**
|
|
56
|
|
- * React Native bridge. The instance manager allows embedding applications to create multiple
|
|
57
|
|
- * root views off the same JavaScript bundle.
|
|
|
57
|
+ * {@JitsiMeetView.Listener} instance for reporting events occurring in
|
|
|
58
|
+ * Jitsi Meet.
|
|
58
|
59
|
*/
|
|
59
|
|
- private static ReactInstanceManager mReactInstanceManager;
|
|
|
60
|
+ private JitsiMeetView.Listener listener;
|
|
60
|
61
|
|
|
61
|
62
|
/**
|
|
62
|
63
|
* React Native root view.
|
|
63
|
64
|
*/
|
|
64
|
|
- private ReactRootView mReactRootView;
|
|
|
65
|
+ private ReactRootView reactRootView;
|
|
65
|
66
|
|
|
66
|
67
|
public JitsiMeetView(@NonNull Context context) {
|
|
67
|
68
|
super(context);
|
|
68
|
69
|
|
|
69
|
|
- if (mInstance != null) {
|
|
70
|
|
- throw new RuntimeException("Only a single instance is currently allowed");
|
|
|
70
|
+ if (instance != null) {
|
|
|
71
|
+ throw new RuntimeException(
|
|
|
72
|
+ "Only a single instance is currently allowed");
|
|
71
|
73
|
}
|
|
72
|
74
|
|
|
73
|
75
|
/*
|
|
74
|
|
- * TODO: Only allow a single instance for now. All React Native modules are
|
|
75
|
|
- * kinda singletons so global state would be broken since we have a single
|
|
76
|
|
- * bridge. Once we have that sorted out multiple instances of JitsiMeetView
|
|
77
|
|
- * will be allowed.
|
|
|
76
|
+ * TODO: Only allow a single instance for now. All React Native modules
|
|
|
77
|
+ * are kinda singletons so global state would be broken since we have a
|
|
|
78
|
+ * single bridge. Once we have that sorted out multiple instances of
|
|
|
79
|
+ * JitsiMeetView will be allowed.
|
|
78
|
80
|
*/
|
|
79
|
|
- mInstance = this;
|
|
|
81
|
+ instance = this;
|
|
80
|
82
|
|
|
81
|
83
|
setBackgroundColor(BACKGROUND_COLOR);
|
|
82
|
84
|
|
|
83
|
|
- if (mReactInstanceManager == null) {
|
|
84
|
|
- initReactInstanceManager(((Activity)context).getApplication());
|
|
|
85
|
+ if (reactInstanceManager == null) {
|
|
|
86
|
+ initReactInstanceManager(((Activity) context).getApplication());
|
|
85
|
87
|
}
|
|
86
|
88
|
}
|
|
87
|
89
|
|
|
|
@@ -91,7 +93,7 @@ public class JitsiMeetView extends FrameLayout {
|
|
91
|
93
|
* @returns The {@JitsiMeetView} instance.
|
|
92
|
94
|
*/
|
|
93
|
95
|
public static JitsiMeetView getInstance() {
|
|
94
|
|
- return mInstance;
|
|
|
96
|
+ return instance;
|
|
95
|
97
|
}
|
|
96
|
98
|
|
|
97
|
99
|
/**
|
|
|
@@ -104,14 +106,15 @@ public class JitsiMeetView extends FrameLayout {
|
|
104
|
106
|
}
|
|
105
|
107
|
|
|
106
|
108
|
/**
|
|
107
|
|
- * Internal method to initialize the React Native instance manager. We create a single instance
|
|
108
|
|
- * in order to load the JavaScript bundle a single time. All <tt>ReactRootView</tt> instances
|
|
109
|
|
- * will be tied to the one and only <tt>ReactInstanceManager</tt>.
|
|
|
109
|
+ * Internal method to initialize the React Native instance manager. We
|
|
|
110
|
+ * create a single instance in order to load the JavaScript bundle a single
|
|
|
111
|
+ * time. All <tt>ReactRootView</tt> instances will be tied to the one and
|
|
|
112
|
+ * only <tt>ReactInstanceManager</tt>.
|
|
110
|
113
|
*
|
|
111
|
114
|
* @param application - <tt>Application</tt> instance which is running.
|
|
112
|
115
|
*/
|
|
113
|
116
|
private static void initReactInstanceManager(Application application) {
|
|
114
|
|
- mReactInstanceManager = ReactInstanceManager.builder()
|
|
|
117
|
+ reactInstanceManager = ReactInstanceManager.builder()
|
|
115
|
118
|
.setApplication(application)
|
|
116
|
119
|
.setBundleAssetName("index.android.bundle")
|
|
117
|
120
|
.setJSMainModuleName("index.android")
|
|
|
@@ -130,8 +133,8 @@ public class JitsiMeetView extends FrameLayout {
|
|
130
|
133
|
}
|
|
131
|
134
|
|
|
132
|
135
|
/**
|
|
133
|
|
- * Loads the given URL and displays the conference. If the specified URL is null, the welcome
|
|
134
|
|
- * page is displayed instead.
|
|
|
136
|
+ * Loads the given URL and displays the conference. If the specified URL is
|
|
|
137
|
+ * null, the welcome page is displayed instead.
|
|
135
|
138
|
*
|
|
136
|
139
|
* @param url - The conference URL.
|
|
137
|
140
|
*/
|
|
|
@@ -142,17 +145,18 @@ public class JitsiMeetView extends FrameLayout {
|
|
142
|
145
|
props.putString("url", url.toString());
|
|
143
|
146
|
}
|
|
144
|
147
|
|
|
145
|
|
- // TODO: ReactRootView#setAppProperties is only available on React Native 0.45, so destroy
|
|
146
|
|
- // the current root view and create a new one.
|
|
147
|
|
- if (mReactRootView != null) {
|
|
148
|
|
- removeView(mReactRootView);
|
|
149
|
|
- mReactRootView = null;
|
|
|
148
|
+ // TODO: ReactRootView#setAppProperties is only available on React
|
|
|
149
|
+ // Native 0.45, so destroy the current root view and create a new one.
|
|
|
150
|
+ if (reactRootView != null) {
|
|
|
151
|
+ removeView(reactRootView);
|
|
|
152
|
+ reactRootView = null;
|
|
150
|
153
|
}
|
|
151
|
154
|
|
|
152
|
|
- mReactRootView = new ReactRootView(getContext());
|
|
153
|
|
- mReactRootView.startReactApplication(mReactInstanceManager, "App", props);
|
|
154
|
|
- mReactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
|
155
|
|
- addView(mReactRootView);
|
|
|
155
|
+ reactRootView = new ReactRootView(getContext());
|
|
|
156
|
+ reactRootView
|
|
|
157
|
+ .startReactApplication(reactInstanceManager, "App", props);
|
|
|
158
|
+ reactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
|
|
159
|
+ addView(reactRootView);
|
|
156
|
160
|
}
|
|
157
|
161
|
|
|
158
|
162
|
/**
|
|
|
@@ -165,15 +169,17 @@ public class JitsiMeetView extends FrameLayout {
|
|
165
|
169
|
}
|
|
166
|
170
|
|
|
167
|
171
|
/**
|
|
168
|
|
- * Activity lifecycle method which should be called from <tt>Activity.onBackPressed</tt> so
|
|
169
|
|
- * we can do the required internal processing.
|
|
|
172
|
+ * Activity lifecycle method which should be called from
|
|
|
173
|
+ * <tt>Activity.onBackPressed</tt> so we can do the required internal
|
|
|
174
|
+ * processing.
|
|
170
|
175
|
*
|
|
171
|
|
- * @return - true if the back-press was processed, false otherwise. In case false is returned
|
|
172
|
|
- * the application should call the parent's implementation.
|
|
|
176
|
+ * @return - true if the back-press was processed, false otherwise. In case
|
|
|
177
|
+ * false is returned the application should call the parent's
|
|
|
178
|
+ * implementation.
|
|
173
|
179
|
*/
|
|
174
|
180
|
public static boolean onBackPressed() {
|
|
175
|
|
- if (mReactInstanceManager != null) {
|
|
176
|
|
- mReactInstanceManager.onBackPressed();
|
|
|
181
|
+ if (reactInstanceManager != null) {
|
|
|
182
|
+ reactInstanceManager.onBackPressed();
|
|
177
|
183
|
return true;
|
|
178
|
184
|
} else {
|
|
179
|
185
|
return false;
|
|
|
@@ -181,52 +187,54 @@ public class JitsiMeetView extends FrameLayout {
|
|
181
|
187
|
}
|
|
182
|
188
|
|
|
183
|
189
|
/**
|
|
184
|
|
- * Activity lifecycle method which should be called from <tt>Activity.onDestroy</tt> so
|
|
185
|
|
- * we can do the required internal processing.
|
|
|
190
|
+ * Activity lifecycle method which should be called from
|
|
|
191
|
+ * <tt>Activity.onDestroy</tt> so we can do the required internal
|
|
|
192
|
+ * processing.
|
|
186
|
193
|
*
|
|
187
|
194
|
* @param activity - <tt>Activity</tt> being destroyed.
|
|
188
|
195
|
*/
|
|
189
|
196
|
public static void onHostDestroy(Activity activity) {
|
|
190
|
|
- if (mReactInstanceManager != null) {
|
|
191
|
|
- mReactInstanceManager.onHostDestroy(activity);
|
|
|
197
|
+ if (reactInstanceManager != null) {
|
|
|
198
|
+ reactInstanceManager.onHostDestroy(activity);
|
|
192
|
199
|
}
|
|
193
|
200
|
}
|
|
194
|
201
|
|
|
195
|
202
|
/**
|
|
196
|
|
- * Activity lifecycle method which should be called from <tt>Activity.onPause</tt> so
|
|
197
|
|
- * we can do the required internal processing.
|
|
|
203
|
+ * Activity lifecycle method which should be called from
|
|
|
204
|
+ * <tt>Activity.onPause</tt> so we can do the required internal processing.
|
|
198
|
205
|
*
|
|
199
|
206
|
* @param activity - <tt>Activity</tt> being paused.
|
|
200
|
207
|
*/
|
|
201
|
208
|
public static void onHostPause(Activity activity) {
|
|
202
|
|
- if (mReactInstanceManager != null) {
|
|
203
|
|
- mReactInstanceManager.onHostPause(activity);
|
|
|
209
|
+ if (reactInstanceManager != null) {
|
|
|
210
|
+ reactInstanceManager.onHostPause(activity);
|
|
204
|
211
|
}
|
|
205
|
212
|
}
|
|
206
|
213
|
|
|
207
|
214
|
/**
|
|
208
|
|
- * Activity lifecycle method which should be called from <tt>Activity.onResume</tt> so
|
|
209
|
|
- * we can do the required internal processing.
|
|
|
215
|
+ * Activity lifecycle method which should be called from
|
|
|
216
|
+ * <tt>Activity.onResume</tt> so we can do the required internal processing.
|
|
210
|
217
|
*
|
|
211
|
218
|
* @param activity - <tt>Activity</tt> being resumed.
|
|
212
|
219
|
*/
|
|
213
|
220
|
public static void onHostResume(Activity activity) {
|
|
214
|
|
- if (mReactInstanceManager != null) {
|
|
215
|
|
- mReactInstanceManager.onHostResume(activity, null);
|
|
|
221
|
+ if (reactInstanceManager != null) {
|
|
|
222
|
+ reactInstanceManager.onHostResume(activity, null);
|
|
216
|
223
|
}
|
|
217
|
224
|
}
|
|
218
|
225
|
|
|
219
|
226
|
/**
|
|
220
|
|
- * Activity lifecycle method which should be called from <tt>Activity.onNewIntent</tt> so
|
|
221
|
|
- * we can do the required internal processing. Note that this is only needed if the activity's
|
|
222
|
|
- * "launchMode" was set to "singleTask". This is required for deep linking to work once the
|
|
223
|
|
- * application is already running.
|
|
|
227
|
+ * Activity lifecycle method which should be called from
|
|
|
228
|
+ * <tt>Activity.onNewIntent</tt> so we can do the required internal
|
|
|
229
|
+ * processing. Note that this is only needed if the activity's "launchMode"
|
|
|
230
|
+ * was set to "singleTask". This is required for deep linking to work once
|
|
|
231
|
+ * the application is already running.
|
|
224
|
232
|
*
|
|
225
|
233
|
* @param intent - <tt>Intent</tt> instance which was received.
|
|
226
|
234
|
*/
|
|
227
|
235
|
public static void onNewIntent(Intent intent) {
|
|
228
|
|
- if (mReactInstanceManager != null) {
|
|
229
|
|
- mReactInstanceManager.onNewIntent(intent);
|
|
|
236
|
+ if (reactInstanceManager != null) {
|
|
|
237
|
+ reactInstanceManager.onNewIntent(intent);
|
|
230
|
238
|
}
|
|
231
|
239
|
}
|
|
232
|
240
|
|
|
|
@@ -235,33 +243,38 @@ public class JitsiMeetView extends FrameLayout {
|
|
235
|
243
|
*/
|
|
236
|
244
|
public interface Listener {
|
|
237
|
245
|
/**
|
|
238
|
|
- * Called when joining a conference fails or an ongoing conference is interrupted due to a
|
|
239
|
|
- * failure.
|
|
240
|
|
- * @param data - HashMap with an "error" key describing the problem, and a "url" key with
|
|
241
|
|
- * the conference URL.
|
|
|
246
|
+ * Called when joining a conference fails or an ongoing conference is
|
|
|
247
|
+ * interrupted due to a failure.
|
|
|
248
|
+ *
|
|
|
249
|
+ * @param data - HashMap with an "error" key describing the problem, and
|
|
|
250
|
+ * a "url" key with the conference URL.
|
|
242
|
251
|
*/
|
|
243
|
252
|
void onConferenceFailed(HashMap<String, Object> data);
|
|
244
|
253
|
|
|
245
|
254
|
/**
|
|
246
|
255
|
* Called when a conference was joined.
|
|
|
256
|
+ *
|
|
247
|
257
|
* @param data - HashMap with a "url" key with the conference URL.
|
|
248
|
258
|
*/
|
|
249
|
259
|
void onConferenceJoined(HashMap<String, Object> data);
|
|
250
|
260
|
|
|
251
|
261
|
/**
|
|
252
|
262
|
* Called when the conference was left, typically after hanging up.
|
|
|
263
|
+ *
|
|
253
|
264
|
* @param data - HashMap with a "url" key with the conference URL.
|
|
254
|
265
|
*/
|
|
255
|
266
|
void onConferenceLeft(HashMap<String, Object> data);
|
|
256
|
267
|
|
|
257
|
268
|
/**
|
|
258
|
269
|
* Called before the conference is joined.
|
|
|
270
|
+ *
|
|
259
|
271
|
* @param data - HashMap with a "url" key with the conference URL.
|
|
260
|
272
|
*/
|
|
261
|
273
|
void onConferenceWillJoin(HashMap<String, Object> data);
|
|
262
|
274
|
|
|
263
|
275
|
/**
|
|
264
|
276
|
* Called before the conference is left.
|
|
|
277
|
+ *
|
|
265
|
278
|
* @param data - HashMap with a "url" key with the conference URL.
|
|
266
|
279
|
*/
|
|
267
|
280
|
void onConferenceWillLeave(HashMap<String, Object> data);
|