瀏覽代碼

feat(mobile) adds ability to retrieve participantsInfo array

j8
tmoldovan8x8 4 年之前
父節點
當前提交
d2568b874b
No account linked to committer's email address

+ 1
- 0
android/sdk/build.gradle 查看文件

47
     implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
47
     implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
48
     implementation 'com.jakewharton.timber:timber:4.7.1'
48
     implementation 'com.jakewharton.timber:timber:4.7.1'
49
     implementation 'com.squareup.duktape:duktape-android:1.3.0'
49
     implementation 'com.squareup.duktape:duktape-android:1.3.0'
50
+    implementation 'com.google.code.gson:gson:2.8.6'
50
 
51
 
51
     if (rootProject.ext.libreBuild) {
52
     if (rootProject.ext.libreBuild) {
52
         implementation(project(':react-native-device-info')) {
53
         implementation(project(':react-native-device-info')) {

+ 2
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastAction.java 查看文件

62
         SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
62
         SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
63
         HANG_UP("org.jitsi.meet.HANG_UP"),
63
         HANG_UP("org.jitsi.meet.HANG_UP"),
64
         SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE"),
64
         SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE"),
65
-        TOGGLE_SCREEN_SHARE("org.jitsi.meet.TOGGLE_SCREEN_SHARE");
65
+        TOGGLE_SCREEN_SHARE("org.jitsi.meet.TOGGLE_SCREEN_SHARE"),
66
+        RETRIEVE_PARTICIPANTS_INFO("org.jitsi.meet.RETRIEVE_PARTICIPANTS_INFO");
66
 
67
 
67
         private final String action;
68
         private final String action;
68
 
69
 

+ 6
- 2
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastEvent.java 查看文件

82
         PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
82
         PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
83
         PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
83
         PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
84
         ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED"),
84
         ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED"),
85
-        SCREEN_SHARE_TOGGLED("org.jitsi.meet.SCREEN_SHARE_TOGGLED");
85
+        SCREEN_SHARE_TOGGLED("org.jitsi.meet.SCREEN_SHARE_TOGGLED"),
86
+        PARTICIPANTS_INFO_RETRIEVED("org.jitsi.meet.PARTICIPANTS_INFO_RETRIEVED");
86
 
87
 
87
         private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
88
         private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
88
         private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
89
         private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
91
         private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
92
         private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
92
         private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
93
         private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
93
         private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
94
         private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
94
-        private static final String SCREEN_SHARE_TOGGLED_NAME= "SCREEN_SHARE_TOGGLED";
95
+        private static final String SCREEN_SHARE_TOGGLED_NAME = "SCREEN_SHARE_TOGGLED";
96
+        private static final String PARTICIPANTS_INFO_RETRIEVED_NAME = "PARTICIPANTS_INFO_RETRIEVED";
95
 
97
 
96
         private final String action;
98
         private final String action;
97
 
99
 
130
                     return ENDPOINT_TEXT_MESSAGE_RECEIVED;
132
                     return ENDPOINT_TEXT_MESSAGE_RECEIVED;
131
                 case SCREEN_SHARE_TOGGLED_NAME:
133
                 case SCREEN_SHARE_TOGGLED_NAME:
132
                     return SCREEN_SHARE_TOGGLED;
134
                     return SCREEN_SHARE_TOGGLED;
135
+                case PARTICIPANTS_INFO_RETRIEVED_NAME:
136
+                    return PARTICIPANTS_INFO_RETRIEVED;
133
             }
137
             }
134
 
138
 
135
             return null;
139
             return null;

+ 3
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/ExternalAPIModule.java 查看文件

53
 
53
 
54
         broadcastEmitter = new BroadcastEmitter(reactContext);
54
         broadcastEmitter = new BroadcastEmitter(reactContext);
55
         broadcastReceiver = new BroadcastReceiver(reactContext);
55
         broadcastReceiver = new BroadcastReceiver(reactContext);
56
+
57
+        ParticipantsService.init(reactContext);
56
     }
58
     }
57
 
59
 
58
     /**
60
     /**
79
         constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
81
         constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
80
         constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
82
         constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
81
         constants.put("TOGGLE_SCREEN_SHARE", BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
83
         constants.put("TOGGLE_SCREEN_SHARE", BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
84
+        constants.put("RETRIEVE_PARTICIPANTS_INFO", BroadcastAction.Type.RETRIEVE_PARTICIPANTS_INFO.getAction());
82
 
85
 
83
         return constants;
86
         return constants;
84
     }
87
     }

+ 27
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/ParticipantInfo.java 查看文件

1
+package org.jitsi.meet.sdk;
2
+
3
+import com.google.gson.annotations.SerializedName;
4
+
5
+public class ParticipantInfo {
6
+
7
+    @SerializedName("participantId")
8
+    public String id;
9
+
10
+    @SerializedName("displayName")
11
+    public String displayName;
12
+
13
+    @SerializedName("avatarUrl")
14
+    public String avatarUrl;
15
+
16
+    @SerializedName("email")
17
+    public String email;
18
+
19
+    @SerializedName("name")
20
+    public String name;
21
+
22
+    @SerializedName("isLocal")
23
+    public boolean isLocal;
24
+
25
+    @SerializedName("role")
26
+    public String role;
27
+}

+ 90
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/ParticipantsService.java 查看文件

1
+package org.jitsi.meet.sdk;
2
+
3
+import android.content.Context;
4
+import android.content.Intent;
5
+import android.content.IntentFilter;
6
+
7
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
8
+
9
+import com.facebook.react.bridge.Arguments;
10
+import com.facebook.react.bridge.WritableMap;
11
+import com.google.gson.Gson;
12
+import com.google.gson.reflect.TypeToken;
13
+
14
+import org.jitsi.meet.sdk.log.JitsiMeetLogger;
15
+
16
+import java.lang.ref.WeakReference;
17
+import java.util.ArrayList;
18
+import java.util.HashMap;
19
+import java.util.List;
20
+import java.util.Map;
21
+import java.util.UUID;
22
+
23
+import javax.annotation.Nullable;
24
+
25
+public class ParticipantsService extends android.content.BroadcastReceiver {
26
+
27
+    private static final String TAG = ParticipantsService.class.getSimpleName();
28
+    private static final String REQUEST_ID = "requestId";
29
+
30
+    private final Map<String, WeakReference<ParticipantsInfoCallback>> participantsInfoCallbackMap = new HashMap<>();
31
+
32
+    private static ParticipantsService instance;
33
+
34
+    @Nullable
35
+    public static ParticipantsService getInstance() {
36
+        return instance;
37
+    }
38
+
39
+    private ParticipantsService(Context context) {
40
+        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
41
+
42
+        IntentFilter intentFilter = new IntentFilter();
43
+        intentFilter.addAction(BroadcastEvent.Type.PARTICIPANTS_INFO_RETRIEVED.getAction());
44
+        localBroadcastManager.registerReceiver(this, intentFilter);
45
+    }
46
+
47
+    static void init(Context context) {
48
+        instance = new ParticipantsService(context);
49
+    }
50
+
51
+    public void retrieveParticipantsInfo(ParticipantsInfoCallback participantsInfoCallback) {
52
+        String callbackKey = UUID.randomUUID().toString();
53
+        this.participantsInfoCallbackMap.put(callbackKey, new WeakReference<>(participantsInfoCallback));
54
+
55
+        String actionName = BroadcastAction.Type.RETRIEVE_PARTICIPANTS_INFO.getAction();
56
+        WritableMap data = Arguments.createMap();
57
+        data.putString(REQUEST_ID, callbackKey);
58
+        ReactInstanceManagerHolder.emitEvent(actionName, data);
59
+    }
60
+
61
+    @Override
62
+    public void onReceive(Context context, Intent intent) {
63
+        BroadcastEvent event = new BroadcastEvent(intent);
64
+
65
+        switch (event.getType()) {
66
+            case PARTICIPANTS_INFO_RETRIEVED:
67
+                try {
68
+                    List<ParticipantInfo> participantInfoList = new Gson().fromJson(
69
+                        event.getData().get("participantsInfo").toString(),
70
+                        new TypeToken<ArrayList<ParticipantInfo>>() {
71
+                        }.getType());
72
+
73
+                    ParticipantsInfoCallback participantsInfoCallback = this.participantsInfoCallbackMap.get(event.getData().get(REQUEST_ID).toString()).get();
74
+
75
+                    if (participantsInfoCallback != null) {
76
+                        participantsInfoCallback.onReceived(participantInfoList);
77
+                        this.participantsInfoCallbackMap.remove(participantsInfoCallback);
78
+                    }
79
+                } catch (Exception e) {
80
+                    JitsiMeetLogger.w(TAG + "error parsing participantsList", e);
81
+                }
82
+
83
+                break;
84
+        }
85
+    }
86
+
87
+    public interface ParticipantsInfoCallback {
88
+        void onReceived(List<ParticipantInfo> participantInfoList);
89
+    }
90
+}

+ 1
- 0
ios/sdk/src/ExternalAPI.h 查看文件

22
 - (void)sendSetAudioMuted: (BOOL)muted;
22
 - (void)sendSetAudioMuted: (BOOL)muted;
23
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
23
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
24
 - (void)toggleScreenShare;
24
 - (void)toggleScreenShare;
25
+- (void)retrieveParticipantsInfo:(void (^)(NSArray*))completion;
25
 
26
 
26
 @end
27
 @end

+ 37
- 2
ios/sdk/src/ExternalAPI.m 查看文件

22
 static NSString * const setAudioMutedAction = @"org.jitsi.meet.SET_AUDIO_MUTED";
22
 static NSString * const setAudioMutedAction = @"org.jitsi.meet.SET_AUDIO_MUTED";
23
 static NSString * const sendEndpointTextMessageAction = @"org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE";
23
 static NSString * const sendEndpointTextMessageAction = @"org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE";
24
 static NSString * const toggleScreenShareAction = @"org.jitsi.meet.TOGGLE_SCREEN_SHARE";
24
 static NSString * const toggleScreenShareAction = @"org.jitsi.meet.TOGGLE_SCREEN_SHARE";
25
+static NSString * const retrieveParticipantsInfoAction = @"org.jitsi.meet.RETRIEVE_PARTICIPANTS_INFO";
25
 
26
 
26
 @implementation ExternalAPI
27
 @implementation ExternalAPI
27
 
28
 
29
+static NSMapTable<NSString*, void (^)(NSArray* participantsInfo)> *participantInfoCompletionHandlers;
30
+
31
+__attribute__((constructor))
32
+static void initializeViewsMap() {
33
+    participantInfoCompletionHandlers = [NSMapTable strongToWeakObjectsMapTable];
34
+}
35
+
28
 RCT_EXPORT_MODULE();
36
 RCT_EXPORT_MODULE();
29
 
37
 
30
 - (NSDictionary *)constantsToExport {
38
 - (NSDictionary *)constantsToExport {
32
         @"HANG_UP": hangUpAction,
40
         @"HANG_UP": hangUpAction,
33
         @"SET_AUDIO_MUTED" : setAudioMutedAction,
41
         @"SET_AUDIO_MUTED" : setAudioMutedAction,
34
         @"SEND_ENDPOINT_TEXT_MESSAGE": sendEndpointTextMessageAction,
42
         @"SEND_ENDPOINT_TEXT_MESSAGE": sendEndpointTextMessageAction,
35
-        @"TOGGLE_SCREEN_SHARE": toggleScreenShareAction
43
+        @"TOGGLE_SCREEN_SHARE": toggleScreenShareAction,
44
+        @"RETRIEVE_PARTICIPANTS_INFO": retrieveParticipantsInfoAction
36
     };
45
     };
37
 };
46
 };
38
 
47
 
48
 }
57
 }
49
 
58
 
50
 - (NSArray<NSString *> *)supportedEvents {
59
 - (NSArray<NSString *> *)supportedEvents {
51
-    return @[ hangUpAction, setAudioMutedAction, sendEndpointTextMessageAction, toggleScreenShareAction ];
60
+    return @[ hangUpAction,
61
+              setAudioMutedAction,
62
+              sendEndpointTextMessageAction,
63
+              toggleScreenShareAction,
64
+              retrieveParticipantsInfoAction];
52
 }
65
 }
53
 
66
 
54
 /**
67
 /**
76
     if (!delegate) {
89
     if (!delegate) {
77
         return;
90
         return;
78
     }
91
     }
92
+    
93
+    if ([name isEqual: @"PARTICIPANTS_INFO_RETRIEVED"]) {
94
+        [self onParticipantsInfoRetrieved: data];
95
+        return;
96
+    }
79
 
97
 
80
     SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
98
     SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
81
 
99
 
84
     }
102
     }
85
 }
103
 }
86
 
104
 
105
+- (void) onParticipantsInfoRetrieved:(NSDictionary *)data {
106
+    NSArray *participantsInfoArray = [data objectForKey:@"participantsInfo"];
107
+    NSString *completionHandlerId = [data objectForKey:@"requestId"];
108
+    
109
+    void (^completionHandler)(NSArray*) = [participantInfoCompletionHandlers objectForKey:completionHandlerId];
110
+    completionHandler(participantsInfoArray);
111
+    [participantInfoCompletionHandlers removeObjectForKey:completionHandlerId];
112
+}
113
+
87
 /**
114
 /**
88
  * Converts a specific event name i.e. redux action type description to a
115
  * Converts a specific event name i.e. redux action type description to a
89
  * method name.
116
  * method name.
129
     [self sendEventWithName:toggleScreenShareAction body:nil];
156
     [self sendEventWithName:toggleScreenShareAction body:nil];
130
 }
157
 }
131
 
158
 
159
+- (void)retrieveParticipantsInfo:(void (^)(NSArray*))completionHandler {
160
+    NSString *completionHandlerId = [[NSUUID UUID] UUIDString];
161
+    NSDictionary *data = @{ @"requestId": completionHandlerId};
162
+    
163
+    [participantInfoCompletionHandlers setObject:completionHandler forKey:completionHandlerId];
164
+    
165
+    [self sendEventWithName:retrieveParticipantsInfoAction body:data];
166
+}
132
 @end
167
 @end

+ 2
- 0
ios/sdk/src/JitsiMeetView.h 查看文件

45
 
45
 
46
 - (void)toggleScreenShare;
46
 - (void)toggleScreenShare;
47
 
47
 
48
+- (void)retrieveParticipantsInfo:(void (^)(NSArray*))completionHandler;
49
+
48
 @end
50
 @end

+ 5
- 0
ios/sdk/src/JitsiMeetView.m 查看文件

135
     [externalAPI toggleScreenShare];
135
     [externalAPI toggleScreenShare];
136
 }
136
 }
137
 
137
 
138
+- (void)retrieveParticipantsInfo:(void (^)(NSArray*))completionHandler {
139
+    ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
140
+    [externalAPI retrieveParticipantsInfo:completionHandler];
141
+}
142
+
138
 #pragma mark Private methods
143
 #pragma mark Private methods
139
 
144
 
140
 /**
145
 /**

+ 34
- 2
react/features/mobile/external-api/middleware.js 查看文件

27
 } from '../../base/connection';
27
 } from '../../base/connection';
28
 import { JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
28
 import { JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
29
 import { SET_AUDIO_MUTED } from '../../base/media/actionTypes';
29
 import { SET_AUDIO_MUTED } from '../../base/media/actionTypes';
30
-import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../../base/participants';
30
+import { PARTICIPANT_JOINED, PARTICIPANT_LEFT, getParticipants } from '../../base/participants';
31
 import { MiddlewareRegistry, StateListenerRegistry } from '../../base/redux';
31
 import { MiddlewareRegistry, StateListenerRegistry } from '../../base/redux';
32
 import { toggleScreensharing } from '../../base/tracks';
32
 import { toggleScreensharing } from '../../base/tracks';
33
 import { muteLocal } from '../../remote-video-menu/actions';
33
 import { muteLocal } from '../../remote-video-menu/actions';
55
  */
55
  */
56
 const SCREEN_SHARE_TOGGLED = 'SCREEN_SHARE_TOGGLED';
56
 const SCREEN_SHARE_TOGGLED = 'SCREEN_SHARE_TOGGLED';
57
 
57
 
58
+/**
59
+ * Event which will be emitted on the native side with the participant info array.
60
+ */
61
+const PARTICIPANTS_INFO_RETRIEVED = 'PARTICIPANTS_INFO_RETRIEVED';
62
+
58
 const { ExternalAPI } = NativeModules;
63
 const { ExternalAPI } = NativeModules;
59
 const eventEmitter = new NativeEventEmitter(ExternalAPI);
64
 const eventEmitter = new NativeEventEmitter(ExternalAPI);
60
 
65
 
158
                 isLocal: participant.local,
163
                 isLocal: participant.local,
159
                 email: participant.email,
164
                 email: participant.email,
160
                 name: participant.name,
165
                 name: participant.name,
161
-                participantId: participant.id
166
+                participantId: participant.id,
167
+                displayName: participant.displayName,
168
+                avatarUrl: participant.avatarURL,
169
+                role: participant.role
162
             });
170
             });
163
         break;
171
         break;
164
     }
172
     }
254
     eventEmitter.addListener(ExternalAPI.TOGGLE_SCREEN_SHARE, () => {
262
     eventEmitter.addListener(ExternalAPI.TOGGLE_SCREEN_SHARE, () => {
255
         dispatch(toggleScreensharing());
263
         dispatch(toggleScreensharing());
256
     });
264
     });
265
+
266
+    eventEmitter.addListener(ExternalAPI.RETRIEVE_PARTICIPANTS_INFO, ({ requestId }) => {
267
+        const store = getState();
268
+
269
+        const participantsInfo = getParticipants(store).map(participant => {
270
+            return {
271
+                isLocal: participant.local,
272
+                email: participant.email,
273
+                name: participant.name,
274
+                participantId: participant.id,
275
+                displayName: participant.displayName,
276
+                avatarUrl: participant.avatarURL,
277
+                role: participant.role
278
+            };
279
+        });
280
+
281
+        sendEvent(
282
+            store,
283
+            PARTICIPANTS_INFO_RETRIEVED,
284
+            /* data */ {
285
+                participantsInfo,
286
+                requestId
287
+            });
288
+    });
257
 }
289
 }
258
 
290
 
259
 /**
291
 /**

Loading…
取消
儲存