capacitor-jitsi-meet 6.1.0 → 6.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
 
2
2
  Pod::Spec.new do |s|
3
3
  s.name = 'CapacitorJitsiMeet'
4
- s.version = '6.1.0'
4
+ s.version = '6.2.0'
5
5
  s.summary = 'This plugin is used to make video calls using Jitsi video platform (https://meet.jit.si) on iOS and Android using Capacitor. Since the current implementation of Ionic/PWA apps on iOS run on top of WKWebView, and as of today (24/01/2019), Apple does not support WebRTC on WKWebView, the only way to work with Jitsi Video on this platform is to build it natively.'
6
6
  s.license = 'MIT'
7
7
  s.homepage = 'https://github.com/calvinckho/capacitor-jitsi-meet'
@@ -15,5 +15,5 @@
15
15
  }
16
16
  s.ios.deployment_target = '13.4'
17
17
  s.dependency 'Capacitor'
18
- s.dependency 'JitsiMeetSDK', '10.0.0'
18
+ s.dependency 'JitsiMeetSDK', '10.1.2'
19
19
  end
package/README.md CHANGED
@@ -149,6 +149,14 @@ window.addEventListener('onConferenceTerminated', () => {
149
149
  window.addEventListener('onConferenceLeft', () => {
150
150
  // do things here
151
151
  });
152
+ window.addEventListener('onChatMessageReceived', (data: any) => {
153
+ // console.log("message", JSON.stringify(data))
154
+ // {"isTrusted":false,"senderId":"00b50123","isPrivate":"false","message":"this is the message","timestamp":"2024-09-16T18:53:34Z"}
155
+ });
156
+ window.addEventListener('onParticipantsInfoRetrieved', (data: any) => {
157
+ // console.log("participant info", JSON.stringify(data));
158
+ //{"isTrusted":false,"participantsInfo":"[{participantId=00b50123, name=My Name, role=moderator, avatarUrl=https://xxx.png, isLocal=true}
159
+ });
152
160
 
153
161
  const result = await Jitsi.leaveConference()
154
162
  console.log(result) // { success: true }
@@ -52,7 +52,7 @@ repositories {
52
52
  dependencies {
53
53
  implementation fileTree(dir: 'libs', include: ['*.jar'])
54
54
  implementation project(':capacitor-android')
55
- implementation ('org.jitsi.react:jitsi-meet-sdk:10.0.0') { transitive = true }
55
+ implementation ('org.jitsi.react:jitsi-meet-sdk:10.1.2') { transitive = true }
56
56
  implementation 'androidx.activity:activity:1.2.3'
57
57
 
58
58
  // Firebase
@@ -16,28 +16,26 @@ import android.content.Intent;
16
16
  import android.Manifest;
17
17
  import android.os.Build;
18
18
 
19
- import androidx.annotation.RequiresApi;
20
19
  import androidx.localbroadcastmanager.content.LocalBroadcastManager;
21
20
  import timber.log.Timber;
22
21
 
23
22
  import org.jitsi.meet.sdk.*;
24
23
  import org.json.JSONException;
25
24
 
26
- import static android.content.Context.RECEIVER_EXPORTED;
25
+ import static android.content.Context.RECEIVER_NOT_EXPORTED;
27
26
 
28
27
  @CapacitorPlugin(
29
- name= "Jitsi",
30
- permissions={
31
- @Permission(strings = {Manifest.permission.RECORD_AUDIO}),
32
- @Permission(strings = {Manifest.permission.CAMERA}),
33
- }
34
- )
28
+ name= "Jitsi",
29
+ permissions={
30
+ @Permission(strings = {Manifest.permission.RECORD_AUDIO}),
31
+ @Permission(strings = {Manifest.permission.CAMERA}),
32
+ }
33
+ )
35
34
  public class Jitsi extends Plugin {
36
35
  private static final String TAG = "CapacitorJitsiMeet";
37
36
  private JitsiBroadcastReceiver receiver;
38
37
  private JitsiMeetUserInfo userInfo;
39
38
 
40
- @RequiresApi(api = Build.VERSION_CODES.N)
41
39
  @PluginMethod()
42
40
  public void joinConference(PluginCall call) throws JSONException {
43
41
  URL url = null;
@@ -63,12 +61,14 @@ public class Jitsi extends Plugin {
63
61
  filter.addAction("onConferenceWillJoin");
64
62
  filter.addAction("onConferenceJoined");
65
63
  filter.addAction("onConferenceLeft"); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
64
+ filter.addAction("onChatMessageReceived");
65
+ filter.addAction("onParticipantsInfoRetrieved");
66
+
66
67
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
67
- getContext().registerReceiver(receiver, filter, RECEIVER_EXPORTED);
68
+ getContext().registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED);
68
69
  } else {
69
70
  getContext().registerReceiver(receiver, filter);
70
71
  }
71
-
72
72
  if(roomName == null) {
73
73
  call.reject("Must provide an conference room name");
74
74
  return;
@@ -171,9 +171,12 @@ public class Jitsi extends Plugin {
171
171
  call.resolve(ret);
172
172
  }
173
173
 
174
- public void onEventReceived(String eventName) {
175
- bridge.triggerWindowJSEvent(eventName);
176
- Timber.tag(TAG).d(eventName);
174
+ public void onEventReceived(String eventName, String data) {
175
+ bridge.triggerWindowJSEvent(eventName, data);
176
+ if(eventName.equals("onConferenceJoined")) {
177
+ Intent retrieveParticipantsIntent = BroadcastIntentHelper.buildRetrieveParticipantsInfo("retrieveSelfInfo");
178
+ LocalBroadcastManager.getInstance(getContext()).sendBroadcast(retrieveParticipantsIntent);
179
+ }
177
180
  if(eventName.equals("onConferenceLeft")) {
178
181
  if (receiver != null) {
179
182
  getContext().unregisterReceiver(receiver);
@@ -12,8 +12,8 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
12
12
  import timber.log.Timber;
13
13
 
14
14
  import com.facebook.react.bridge.UiThreadUtil;
15
-
16
15
  import org.jitsi.meet.sdk.*;
16
+ import org.json.JSONObject;
17
17
 
18
18
  public class JitsiActivity extends JitsiMeetActivity {
19
19
  private BroadcastReceiver broadcastReceiver;
@@ -61,35 +61,40 @@ public class JitsiActivity extends JitsiMeetActivity {
61
61
  BroadcastEvent event = new BroadcastEvent(intent);
62
62
  switch (event.getType()) {
63
63
  case CONFERENCE_JOINED:
64
- on("onConferenceJoined");
64
+ on("onConferenceJoined", null);
65
65
  break;
66
66
  case CONFERENCE_WILL_JOIN:
67
- on("onConferenceWillJoin");
68
- break;
69
- case CONFERENCE_TERMINATED:
70
- finish();
71
- on("onConferenceLeft"); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
67
+ on("onConferenceWillJoin", null);
72
68
  break;
73
- case READY_TO_CLOSE:
69
+ case CONFERENCE_TERMINATED, READY_TO_CLOSE:
74
70
  finish();
75
- on("onConferenceLeft"); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
71
+ on("onConferenceLeft", null); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
76
72
  break;
77
73
  case PARTICIPANT_JOINED:
78
- on("onParticipantJoined");
74
+ on("onParticipantJoined", null);
79
75
  break;
80
76
  case PARTICIPANT_LEFT:
81
- on("onParticipantLeft");
77
+ on("onParticipantLeft", null);
78
+ break;
79
+ case CHAT_MESSAGE_RECEIVED:
80
+ on("onChatMessageReceived", event);
81
+ break;
82
+ case PARTICIPANTS_INFO_RETRIEVED:
83
+ on("onParticipantsInfoRetrieved", event);
82
84
  break;
83
85
  }
84
86
  }
85
87
  }
86
88
 
87
- private void on(String name) {
89
+ private void on(String eventName, BroadcastEvent event) {
88
90
  UiThreadUtil.assertOnUiThread();
89
- Timber.tag(TAG).d(JitsiMeetView.class.getSimpleName() + ": " + name);
90
-
91
- Intent intent = new Intent(name);
92
- intent.putExtra("eventName", name);
91
+ Intent intent = new Intent(eventName);
92
+ intent.putExtra("eventName", eventName);
93
+ if (event != null) {
94
+ JSONObject json = new JSONObject(event.getData());
95
+ intent.putExtra("data", json.toString());
96
+ Timber.tag(TAG).d(JitsiMeetView.class.getSimpleName() + ": " + eventName + ", " + json);
97
+ }
93
98
  sendBroadcast(intent);
94
99
  }
95
100
 
@@ -101,11 +106,28 @@ public class JitsiActivity extends JitsiMeetActivity {
101
106
  Timber.tag(TAG).d("onStop %s", session_options.getFeatureFlags().getBoolean("pip.enabled"));
102
107
  if (session_options.getFeatureFlags().getBoolean("pip.enabled")) { //TODO: also check the CapacitorJitsiMeet's AndroidManifest.xml file and ensure android:supportsPictureInPicture="true"
103
108
  finish();
104
- on("onConferenceLeft"); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
109
+ on("onConferenceLeft", null); // intentionally uses the obsolete onConferenceLeft in order to be consistent with iOS deployment and broadcast to JS listeners
105
110
  }
106
111
  super.onStop();
107
112
  }
108
113
 
114
+ @Override
115
+ public void onDestroy() {
116
+ // Here we are trying to handle the following corner case: an application using the SDK
117
+ // is using this Activity for displaying meetings, but there is another "main" Activity
118
+ // with other content. If this Activity is "swiped out" from the recent list we will get
119
+ // Activity#onDestroy() called without warning. At this point we can try to leave the
120
+ // current meeting, but when our view is detached from React the JS <-> Native bridge won't
121
+ // be operational so the external API won't be able to notify the native side that the
122
+ // conference terminated. Thus, try our best to clean up.
123
+ leave();
124
+ finish();
125
+ JitsiMeetOngoingConferenceService.abort(this);
126
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
127
+ JitsiMeetActivityDelegate.onHostDestroy(this);
128
+ super.onDestroy();
129
+ }
130
+
109
131
  // for logging entering and leaving PIP only
110
132
  @Override
111
133
  public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
@@ -4,6 +4,8 @@ import android.content.BroadcastReceiver;
4
4
  import android.content.Context;
5
5
  import android.content.Intent;
6
6
 
7
+ import timber.log.Timber;
8
+
7
9
  public class JitsiBroadcastReceiver extends BroadcastReceiver {
8
10
 
9
11
  private static final String TAG = "JitsiBroadcastReceiver";
@@ -14,9 +16,11 @@ public class JitsiBroadcastReceiver extends BroadcastReceiver {
14
16
  }
15
17
 
16
18
  public void onReceive(Context context, Intent intent) {
17
- String eventName = (String) intent.getSerializableExtra("eventName");
19
+ String actionName = (String) intent.getSerializableExtra("eventName");
20
+ String data = (String) intent.getSerializableExtra("data");
21
+ // Timber.tag(TAG).d("JitsiMeetView: " + actionName + ", " + data);
18
22
  if (jitsi != null) {
19
- jitsi.onEventReceived(eventName);
23
+ jitsi.onEventReceived(actionName, data);
20
24
  }
21
25
  }
22
- }
26
+ }
@@ -1 +1,2 @@
1
+ export {};
1
2
  //# sourceMappingURL=definitions.js.map
package/dist/esm/index.js CHANGED
@@ -2,5 +2,6 @@ import { registerPlugin } from '@capacitor/core';
2
2
  const Jitsi = registerPlugin('Jitsi', {
3
3
  web: () => import('./web').then(m => new m.JitsiWeb()),
4
4
  });
5
+ export * from './definitions';
5
6
  export { Jitsi };
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,KAAK,GAAG,cAAc,CAAc,OAAO,EAAE;IAC/C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;CACzD,CAAC,CAAC;AAGH,OAAO,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,KAAK,GAAG,cAAc,CAAc,OAAO,EAAE;IAC/C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;CACzD,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,CAAC"}
@@ -74,16 +74,33 @@ public class JitsiMeetViewController: UIViewController, UIGestureRecognizerDeleg
74
74
 
75
75
  protocol JitsiMeetViewControllerDelegate: AnyObject {
76
76
  func onConferenceJoined()
77
-
78
77
  func onConferenceLeft()
78
+ func onChatMessageReceived(_ dataString: String)
79
+ func onParticipantsInfoRetrieved(_ dataString: String)
79
80
  }
80
81
 
81
82
  // MARK: JitsiMeetViewDelegate
82
83
  extension JitsiMeetViewController: JitsiMeetViewDelegate {
83
84
 
84
- @objc public func conferenceJoined(_ data: [AnyHashable : Any]!) {
85
+ @objc public func conferenceJoined(_ data: NSDictionary) {
86
+ print("[Jitsi Plugin Native iOS]: JitsiMeetViewController::conference joined");
85
87
  delegate?.onConferenceJoined()
86
- print("[Jitsi Plugin Native iOS]: JitsiMeetViewController::conference joined.");
88
+ Task {
89
+ // print("[Jitsi Plugin Native iOS]: JitsiMeetViewController::retrieveParticipantsInfo");
90
+ let jitsiMeetView = JitsiMeetView()
91
+ self.jitsiMeetView = jitsiMeetView
92
+ await jitsiMeetView.retrieveParticipantsInfo({ (_ data: Any) -> Void in
93
+ if let theJSONData = try? JSONSerialization.data(
94
+ withJSONObject: data,
95
+ options: .prettyPrinted
96
+ ),
97
+ let theJSONText = String(data: theJSONData,
98
+ encoding: String.Encoding.ascii) {
99
+ print("JSON string = \n\(theJSONText)")
100
+ self.delegate?.onParticipantsInfoRetrieved(theJSONText)
101
+ }
102
+ });
103
+ }
87
104
  }
88
105
 
89
106
  @objc public func ready(toClose: [AnyHashable : Any]!) {
@@ -94,11 +111,25 @@ extension JitsiMeetViewController: JitsiMeetViewDelegate {
94
111
  self.dismiss(animated: true, completion: nil); // e.g. user ends the call. This is preferred over conferenceLeft to shorten the white screen while exiting the room
95
112
  }
96
113
 
97
- @objc public func conferenceTerminated(_ data: [AnyHashable : Any]!) {
114
+ @objc public func conferenceTerminated(_ data: NSDictionary) {
98
115
  print("[Jitsi Plugin Native iOS]: JitsiMeetViewController::conference terminated");
99
116
  delegate?.onConferenceLeft()
100
117
  self.cleanUp()
101
118
 
102
119
  self.dismiss(animated: true, completion: nil); // e.g. user ends the call. This is preferred over conferenceLeft to shorten the white screen while exiting the room
103
120
  }
121
+
122
+ @objc public func chatMessageReceived(_ data: NSDictionary) {
123
+ print("[Jitsi Plugin Native iOS]: JitsiMeetViewController::chat message received");
124
+ if let theJSONData = try? JSONSerialization.data(
125
+ withJSONObject: data,
126
+ options: .prettyPrinted
127
+ ),
128
+ let theJSONText = String(data: theJSONData,
129
+ encoding: String.Encoding.ascii) {
130
+ print("JSON string = \n\(theJSONText)")
131
+ delegate?.onChatMessageReceived(theJSONText)
132
+ }
133
+ }
134
+
104
135
  }
@@ -119,10 +119,18 @@ public class Jitsi: CAPPlugin {
119
119
 
120
120
  extension Jitsi: JitsiMeetViewControllerDelegate {
121
121
  @objc func onConferenceJoined() {
122
- self.bridge?.triggerJSEvent(eventName: "onConferenceJoined", target: "window");
122
+ self.bridge?.triggerWindowJSEvent(eventName: "onConferenceJoined");
123
123
  }
124
124
 
125
125
  @objc func onConferenceLeft() {
126
- self.bridge?.triggerJSEvent(eventName: "onConferenceLeft", target: "window");
126
+ self.bridge?.triggerWindowJSEvent(eventName: "onConferenceLeft");
127
+ }
128
+
129
+ @objc func onChatMessageReceived(_ dataString: String) {
130
+ self.bridge?.triggerWindowJSEvent(eventName: "onChatMessageReceived", data: dataString);
131
+ }
132
+
133
+ @objc func onParticipantsInfoRetrieved(_ dataString: String) {
134
+ self.bridge?.triggerWindowJSEvent(eventName: "onParticipantsInfoRetrieved", data: dataString);
127
135
  }
128
136
  }
@@ -7,7 +7,7 @@ target 'Plugin' do
7
7
 
8
8
  # Pods for IonicRunner
9
9
  pod 'Capacitor'
10
- pod 'JitsiMeetSDK', '10.0.0'
10
+ pod 'JitsiMeetSDK', '10.1.2'
11
11
  end
12
12
 
13
13
  post_install do |installer|
@@ -22,5 +22,5 @@ target 'PluginTests' do
22
22
  use_frameworks!
23
23
 
24
24
  pod 'Capacitor'
25
- pod 'JitsiMeetSDK', '10.0.0'
25
+ pod 'JitsiMeetSDK', '10.1.2'
26
26
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-jitsi-meet",
3
- "version": "6.1.0",
3
+ "version": "6.2.0-beta.0",
4
4
  "description": "This Ionic Capacitor plugin is created to make video calls through the free, open-sourced Jitsi video platform (https://meet.jit.si) on iOS and Android.",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -23,11 +23,11 @@
23
23
  "@capacitor/ios": "^6.0.0",
24
24
  "@ionic/prettier-config": "^1.0.0",
25
25
  "@ionic/swiftlint-config": "^1.0.0",
26
- "@rollup/plugin-node-resolve": "^8.1.0",
26
+ "@rollup/plugin-node-resolve": "^15.3.0",
27
27
  "prettier": "^2.7.1",
28
28
  "prettier-plugin-java": "^1.6.2",
29
29
  "rimraf": "^3.0.0",
30
- "rollup": "^2.79.1",
30
+ "rollup": "^4.22.4",
31
31
  "swiftlint": "^1.0.1",
32
32
  "typescript": "~4.8.4"
33
33
  },