Просмотр исходного кода

[RN] Add an example how to consume the public SDK invite API

master
Lyubo Marinov 7 лет назад
Родитель
Сommit
7ffdaf59c7

+ 125
- 16
android/app/src/main/java/org/jitsi/meet/MainActivity.java Просмотреть файл

23
 import org.jitsi.meet.sdk.JitsiMeetView;
23
 import org.jitsi.meet.sdk.JitsiMeetView;
24
 import org.jitsi.meet.sdk.JitsiMeetViewListener;
24
 import org.jitsi.meet.sdk.JitsiMeetViewListener;
25
 import org.jitsi.meet.sdk.invite.AddPeopleController;
25
 import org.jitsi.meet.sdk.invite.AddPeopleController;
26
+import org.jitsi.meet.sdk.invite.AddPeopleControllerListener;
27
+import org.jitsi.meet.sdk.invite.InviteController;
26
 import org.jitsi.meet.sdk.invite.InviteControllerListener;
28
 import org.jitsi.meet.sdk.invite.InviteControllerListener;
27
 
29
 
28
 import com.calendarevents.CalendarEventsPackage;
30
 import com.calendarevents.CalendarEventsPackage;
29
 
31
 
32
+import java.util.ArrayList;
30
 import java.util.HashMap;
33
 import java.util.HashMap;
34
+import java.util.List;
31
 import java.util.Map;
35
 import java.util.Map;
32
 
36
 
33
 /**
37
 /**
43
  * {@code react-native run-android}.
47
  * {@code react-native run-android}.
44
  */
48
  */
45
 public class MainActivity extends JitsiMeetActivity {
49
 public class MainActivity extends JitsiMeetActivity {
50
+    /**
51
+     * The query to perform through {@link AddPeopleController} when the
52
+     * {@code InviteButton} is tapped in order to exercise the public API of the
53
+     * feature invite. If {@code null}, the {@code InviteButton} will not be
54
+     * rendered.
55
+     */
56
+    private static final String ADD_PEOPLE_CONTROLLER_QUERY = null;
57
+
46
     @Override
58
     @Override
47
     protected JitsiMeetView initializeView() {
59
     protected JitsiMeetView initializeView() {
48
         JitsiMeetView view = super.initializeView();
60
         JitsiMeetView view = super.initializeView();
93
                 }
105
                 }
94
             });
106
             });
95
 
107
 
96
-            view.getInviteController().setListener(
97
-                new InviteControllerListener() {
98
-                    public void beginAddPeople(
99
-                            AddPeopleController addPeopleController) {
100
-                        // Log with the tag "ReactNative" in order to have the
101
-                        // log visible in react-native log-android as well.
102
-                        Log.d(
103
-                            "ReactNative",
104
-                            InviteControllerListener.class.getSimpleName()
105
-                                + ".beginAddPeople");
106
-                    }
107
-                });
108
+            // inviteController
109
+            final InviteController inviteController
110
+                = view.getInviteController();
111
+
112
+            inviteController.setListener(new InviteControllerListener() {
113
+                public void beginAddPeople(
114
+                        AddPeopleController addPeopleController) {
115
+                    onInviteControllerBeginAddPeople(
116
+                        inviteController,
117
+                        addPeopleController);
118
+                }
119
+            });
120
+            inviteController.setAddPeopleEnabled(
121
+                ADD_PEOPLE_CONTROLLER_QUERY != null);
122
+            inviteController.setDialOutEnabled(
123
+                inviteController.isAddPeopleEnabled());
108
         }
124
         }
109
 
125
 
110
         return view;
126
         return view;
111
     }
127
     }
112
 
128
 
129
+    private void onAddPeopleControllerInviteSettled(
130
+            AddPeopleController addPeopleController,
131
+            List<Map<String, Object>> failedInvitees) {
132
+        // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise,
133
+        // it is going to be memory-leaked in the associated InviteController
134
+        // and no subsequent InviteButton clicks/taps will be delivered.
135
+        // Technically, endAddPeople will automatically be invoked if there are
136
+        // no failedInviteees i.e. the invite succeeeded for all specified
137
+        // invitees.
138
+        addPeopleController.endAddPeople();
139
+    }
140
+
141
+    private void onAddPeopleControllerReceivedResults(
142
+            AddPeopleController addPeopleController,
143
+            List<Map<String, Object>> results,
144
+            String query) {
145
+        int size = results.size();
146
+
147
+        if (size > 0) {
148
+            // Exercise AddPeopleController's inviteById implementation.
149
+            List<String> ids = new ArrayList<>(size);
150
+
151
+            for (Map<String, Object> result : results) {
152
+                Object id = result.get("id");
153
+
154
+                if (id != null) {
155
+                    ids.add(id.toString());
156
+                }
157
+            }
158
+
159
+            addPeopleController.inviteById(ids);
160
+
161
+            return;
162
+        }
163
+
164
+        // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise,
165
+        // it is going to be memory-leaked in the associated InviteController
166
+        // and no subsequent InviteButton clicks/taps will be delivered.
167
+        addPeopleController.endAddPeople();
168
+    }
169
+
113
     @Override
170
     @Override
114
     protected void onCreate(Bundle savedInstanceState) {
171
     protected void onCreate(Bundle savedInstanceState) {
115
         // As this is the Jitsi Meet app (i.e. not the Jitsi Meet SDK), we do
172
         // As this is the Jitsi Meet app (i.e. not the Jitsi Meet SDK), we do
122
         super.onCreate(savedInstanceState);
179
         super.onCreate(savedInstanceState);
123
     }
180
     }
124
 
181
 
182
+    private void onInviteControllerBeginAddPeople(
183
+            InviteController inviteController,
184
+            AddPeopleController addPeopleController) {
185
+        // Log with the tag "ReactNative" in order to have the log visible in
186
+        // react-native log-android as well.
187
+        Log.d(
188
+            "ReactNative",
189
+            InviteControllerListener.class.getSimpleName() + ".beginAddPeople");
190
+
191
+        String query = ADD_PEOPLE_CONTROLLER_QUERY;
192
+    
193
+        if (query != null
194
+                && (inviteController.isAddPeopleEnabled()
195
+                    || inviteController.isDialOutEnabled())) {
196
+            addPeopleController.setListener(new AddPeopleControllerListener() {
197
+                public void onInviteSettled(
198
+                        AddPeopleController addPeopleController,
199
+                        List<Map<String, Object>> failedInvitees) {
200
+                    onAddPeopleControllerInviteSettled(
201
+                        addPeopleController,
202
+                        failedInvitees);
203
+                }
204
+
205
+                public void onReceivedResults(
206
+                        AddPeopleController addPeopleController,
207
+                        List<Map<String, Object>> results,
208
+                        String query) {
209
+                    onAddPeopleControllerReceivedResults(
210
+                        addPeopleController,
211
+                        results, query);
212
+                }
213
+            });
214
+            addPeopleController.performQuery(query);
215
+        } else {
216
+            // XXX Explicitly invoke endAddPeople on addPeopleController;
217
+            // otherwise, it is going to be memory-leaked in the associated
218
+            // InviteController and no subsequent InviteButton clicks/taps will
219
+            // be delivered.
220
+            addPeopleController.endAddPeople();
221
+        }
222
+    }
223
+
125
     @Override
224
     @Override
126
-  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
127
-      CalendarEventsPackage.onRequestPermissionsResult(requestCode, permissions, grantResults);
128
-      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
129
-  }
225
+    public void onRequestPermissionsResult(
226
+            int requestCode,
227
+            String[] permissions,
228
+            int[] grantResults) {
229
+        CalendarEventsPackage.onRequestPermissionsResult(
230
+            requestCode,
231
+            permissions,
232
+            grantResults);
233
+
234
+        super.onRequestPermissionsResult(
235
+            requestCode,
236
+            permissions,
237
+            grantResults);
238
+    }
130
 }
239
 }

+ 5
- 2
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetActivity.java Просмотреть файл

122
         JitsiMeetView view = initializeView();
122
         JitsiMeetView view = initializeView();
123
 
123
 
124
         if (view != null) {
124
         if (view != null) {
125
+            // XXX Allow extenders who override initializeView() to configure
126
+            // the view before the first loadURL(). Probably works around a
127
+            // problem related to ReactRootView#setAppProperties().
128
+            view.loadURL(null);
129
+
125
             this.view = view;
130
             this.view = view;
126
             setContentView(this.view);
131
             setContentView(this.view);
127
         }
132
         }
144
         }
149
         }
145
         view.setWelcomePageEnabled(welcomePageEnabled);
150
         view.setWelcomePageEnabled(welcomePageEnabled);
146
 
151
 
147
-        view.loadURL(null);
148
-
149
         return view;
152
         return view;
150
     }
153
     }
151
 
154
 

+ 4
- 4
android/sdk/src/main/java/org/jitsi/meet/sdk/invite/AddPeopleController.java Просмотреть файл

116
 
116
 
117
                 if(items.containsKey(id)) {
117
                 if(items.containsKey(id)) {
118
                     WritableNativeMap map = new WritableNativeMap();
118
                     WritableNativeMap map = new WritableNativeMap();
119
-                    map.merge(items.get(ids));
119
+                    map.merge(items.get(id));
120
                     invitees.pushMap(map);
120
                     invitees.pushMap(map);
121
                 } else {
121
                 } else {
122
                     // If the id doesn't exist in the map, we can't do anything,
122
                     // If the id doesn't exist in the map, we can't do anything,
138
                 jFailedInvitees.add(failedInvitees.getMap(i).toHashMap());
138
                 jFailedInvitees.add(failedInvitees.getMap(i).toHashMap());
139
             }
139
             }
140
 
140
 
141
-            listener.inviteSettled(this, jFailedInvitees);
141
+            listener.onInviteSettled(this, jFailedInvitees);
142
         }
142
         }
143
     }
143
     }
144
 
144
 
145
     /**
145
     /**
146
      * Start a search for entities to invite with the given query. Results will
146
      * Start a search for entities to invite with the given query. Results will
147
      * be returned through the associated AddPeopleControllerListener's
147
      * be returned through the associated AddPeopleControllerListener's
148
-     * onReceiveResults method.
148
+     * onReceivedResults method.
149
      *
149
      *
150
      * @param query
150
      * @param query
151
      */
151
      */
188
                 jvmResults.add(map.toHashMap());
188
                 jvmResults.add(map.toHashMap());
189
             }
189
             }
190
 
190
 
191
-            listener.onReceiveResults(this, jvmResults, query);
191
+            listener.onReceivedResults(this, jvmResults, query);
192
         }
192
         }
193
     }
193
     }
194
 
194
 

+ 26
- 19
android/sdk/src/main/java/org/jitsi/meet/sdk/invite/AddPeopleControllerListener.java Просмотреть файл

21
 
21
 
22
 public interface AddPeopleControllerListener {
22
 public interface AddPeopleControllerListener {
23
     /**
23
     /**
24
-     * Called when results are received for a query called through AddPeopleController.query()
24
+     * Called when the call to {@link AddPeopleController#inviteById(List)}
25
+     * completes.
25
      *
26
      *
26
-     * @param addPeopleController
27
-     * @param results a List of Map<String, Object> objects that represent items returned by the query.
28
-     *                The object at key "type" describes the type of item: "user", "videosipgw" (conference room), or "phone".
29
-     *                "user" types have properties at "id", "name", and "avatar"
30
-     *                "videosipgw" types have properties at "id" and "name"
31
-     *                "phone" types have properties at "number", "title", "and "subtitle"
32
-     * @param query the query that generated the given results
27
+     * @param addPeopleController the active {@link AddPeopleController} for
28
+     * this invite flow.  This object should be cleaned up by calling
29
+     * {@link AddPeopleController#endAddPeople()} if the user exits the invite
30
+     * flow. Otherwise, it can stay active if the user will attempt to invite
31
+     * @param failedInvitees a {@code List} of {@code Map<String, Object>}
32
+     * dictionaries that represent the invitations that failed. The data type of
33
+     * the objects is identical to the results returned in onReceivedResuls.
33
      */
34
      */
34
-    void onReceiveResults(AddPeopleController addPeopleController, List<Map<String, Object>> results, String query);
35
+    void onInviteSettled(
36
+        AddPeopleController addPeopleController,
37
+        List<Map<String, Object>> failedInvitees);
35
 
38
 
36
     /**
39
     /**
37
-     * Called when the call to {@link AddPeopleController#inviteById(List)} completes, but the
38
-     * invitation fails for one or more of the selected items.
40
+     * Called when results are received for a query called through
41
+     * AddPeopleController.query().
39
      *
42
      *
40
-     * @param addPeopleController the active {@link AddPeopleController} for this invite flow.  This object
41
-     *                         should be cleaned up by calling {@link AddPeopleController#endAddPeople()} if
42
-     *                         the user exits the invite flow.  Otherwise, it can stay active if the user
43
-     *                         will attempt to invite
44
-     * @param failedInvitees a {@code List} of {@code Map<String, Object>} dictionaries that represent the
45
-     *                          invitations that failed.  The data type of the objects is identical to the results
46
-     *                          returned in onReceiveResuls.
43
+     * @param addPeopleController
44
+     * @param results a List of Map<String, Object> objects that represent items
45
+     * returned by the query. The object at key "type" describes the type of
46
+     * item: "user", "videosipgw" (conference room), or "phone". "user" types
47
+     * have properties at "id", "name", and "avatar". "videosipgw" types have
48
+     * properties at "id" and "name". "phone" types have properties at "number",
49
+     * "title", "and "subtitle"
50
+     * @param query the query that generated the given results
47
      */
51
      */
48
-    void inviteSettled(AddPeopleController addPeopleController, List<Map<String, Object>> failedInvitees);
52
+    void onReceivedResults(
53
+        AddPeopleController addPeopleController,
54
+        List<Map<String, Object>> results,
55
+        String query);
49
 }
56
 }

+ 6
- 6
android/sdk/src/main/java/org/jitsi/meet/sdk/invite/InviteController.java Просмотреть файл

61
         this.externalAPIScope = externalAPIScope;
61
         this.externalAPIScope = externalAPIScope;
62
     }
62
     }
63
 
63
 
64
-    public InviteControllerListener getListener() {
65
-        return listener;
66
-    }
67
-
68
     void beginAddPeople(ReactApplicationContext reactContext) {
64
     void beginAddPeople(ReactApplicationContext reactContext) {
69
         InviteControllerListener listener = getListener();
65
         InviteControllerListener listener = getListener();
70
 
66
 
102
         }
98
         }
103
     }
99
     }
104
 
100
 
101
+    public InviteControllerListener getListener() {
102
+        return listener;
103
+    }
104
+
105
     /**
105
     /**
106
      * Sends JavaScript event to submit invitations to the given item ids
106
      * Sends JavaScript event to submit invitations to the given item ids
107
      *
107
      *
203
 
203
 
204
     /**
204
     /**
205
      * Starts a query for users to invite to the conference.  Results will be
205
      * Starts a query for users to invite to the conference.  Results will be
206
-     * returned through the {@link AddPeopleControllerListener#onReceiveResults(AddPeopleController, List, String)}
206
+     * returned through the {@link AddPeopleControllerListener#onReceivedResults(AddPeopleController, List, String)}
207
      * method.
207
      * method.
208
      *
208
      *
209
      * @param query {@code String} to use for the query
209
      * @param query {@code String} to use for the query
211
     void performQuery(AddPeopleController addPeopleController, String query) {
211
     void performQuery(AddPeopleController addPeopleController, String query) {
212
         WritableNativeMap params = new WritableNativeMap();
212
         WritableNativeMap params = new WritableNativeMap();
213
 
213
 
214
-        params.putString("externalAPIScope", externalAPIScope);
215
         params.putString("addPeopleControllerScope", addPeopleController.getUuid());
214
         params.putString("addPeopleControllerScope", addPeopleController.getUuid());
215
+        params.putString("externalAPIScope", externalAPIScope);
216
         params.putString("query", query);
216
         params.putString("query", query);
217
         ReactContextUtils.emitEvent(
217
         ReactContextUtils.emitEvent(
218
             addPeopleController.getReactApplicationContext(),
218
             addPeopleController.getReactApplicationContext(),

+ 5
- 1
ios/app/src/ViewController.h Просмотреть файл

18
 
18
 
19
 #import <JitsiMeet/JitsiMeet.h>
19
 #import <JitsiMeet/JitsiMeet.h>
20
 
20
 
21
-@interface ViewController : UIViewController<JitsiMeetViewDelegate, JMInviteControllerDelegate>
21
+@interface ViewController
22
+    : UIViewController<
23
+        JitsiMeetViewDelegate,
24
+        JMAddPeopleControllerDelegate,
25
+        JMInviteControllerDelegate>
22
 
26
 
23
 @end
27
 @end

+ 73
- 1
ios/app/src/ViewController.m Просмотреть файл

16
 
16
 
17
 #import "ViewController.h"
17
 #import "ViewController.h"
18
 
18
 
19
+/**
20
+ * The query to perform through JMAddPeopleController when the InviteButton is
21
+ * tapped in order to exercise the public API of the feature invite. If nil, the
22
+ * InviteButton will not be rendered.
23
+ */
24
+static NSString * const ADD_PEOPLE_CONTROLLER_QUERY = nil;
25
+
19
 @interface ViewController ()
26
 @interface ViewController ()
20
 
27
 
21
 @end
28
 @end
31
 
38
 
32
     view.delegate = self;
39
     view.delegate = self;
33
 
40
 
34
-    view.inviteController.delegate = self;
41
+    // inviteController
42
+    JMInviteController *inviteController = view.inviteController;
43
+    inviteController.delegate = self;
44
+    inviteController.addPeopleEnabled
45
+        = inviteController.dialOutEnabled
46
+        = ADD_PEOPLE_CONTROLLER_QUERY != nil;
35
 
47
 
36
 #endif // #ifdef DEBUG
48
 #endif // #ifdef DEBUG
37
 
49
 
46
 
58
 
47
 #if DEBUG
59
 #if DEBUG
48
 
60
 
61
+// JitsiMeetViewDelegate
62
+
49
 void _onJitsiMeetViewDelegateEvent(NSString *name, NSDictionary *data) {
63
 void _onJitsiMeetViewDelegateEvent(NSString *name, NSDictionary *data) {
50
     NSLog(
64
     NSLog(
51
         @"[%s:%d] JitsiMeetViewDelegate %@ %@",
65
         @"[%s:%d] JitsiMeetViewDelegate %@ %@",
76
     _onJitsiMeetViewDelegateEvent(@"LOAD_CONFIG_ERROR", data);
90
     _onJitsiMeetViewDelegateEvent(@"LOAD_CONFIG_ERROR", data);
77
 }
91
 }
78
 
92
 
93
+// JMInviteControllerDelegate
94
+
79
 - (void)beginAddPeople:(JMAddPeopleController *)addPeopleController {
95
 - (void)beginAddPeople:(JMAddPeopleController *)addPeopleController {
80
     NSLog(
96
     NSLog(
81
         @"[%s:%d] JMInviteControllerDelegate %s",
97
         @"[%s:%d] JMInviteControllerDelegate %s",
82
         __FILE__, __LINE__, __FUNCTION__);
98
         __FILE__, __LINE__, __FUNCTION__);
83
 
99
 
100
+    NSString *query = ADD_PEOPLE_CONTROLLER_QUERY;
101
+    JitsiMeetView *view = (JitsiMeetView *) self.view;
102
+    JMInviteController *inviteController = view.inviteController;
103
+
104
+    if (query
105
+            && (inviteController.addPeopleEnabled
106
+                || inviteController.dialOutEnabled)) {
107
+        addPeopleController.delegate = self;
108
+        [addPeopleController performQuery:query];
109
+    } else {
110
+        // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise,
111
+        // it is going to be memory-leaked in the associated JMInviteController
112
+        // and no subsequent InviteButton clicks/taps will be delivered.
113
+        [addPeopleController endAddPeople];
114
+    }
115
+}
116
+
117
+// JMAddPeopleControllerDelegate
118
+
119
+- (void)addPeopleController:(JMAddPeopleController * _Nonnull)controller
120
+          didReceiveResults:(NSArray<NSDictionary *> * _Nonnull)results
121
+                   forQuery:(NSString * _Nonnull)query {
122
+    NSUInteger count = results.count;
123
+
124
+    if (count) {
125
+        // Exercise JMAddPeopleController's inviteById: implementation.
126
+        NSMutableArray *ids = [NSMutableArray arrayWithCapacity:count];
127
+
128
+        for (NSUInteger i = 0; i < count; ++i) {
129
+            ids[i] = results[i][@"id"];
130
+        }
131
+
132
+        [controller inviteById:ids];
133
+
134
+        // Exercise JMInviteController's invite:withCompletion: implementation.
135
+        //
136
+        // XXX Technically, only at most one of the two exercises will result in
137
+        // an actual invitation eventually.
138
+        JitsiMeetView *view = (JitsiMeetView *) self.view;
139
+        JMInviteController *inviteController = view.inviteController;
140
+
141
+        [inviteController invite:results withCompletion:nil];
142
+
143
+        return;
144
+    }
145
+
84
     // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise, it
146
     // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise, it
85
     // is going to be memory-leaked in the associated JMInviteController and no
147
     // is going to be memory-leaked in the associated JMInviteController and no
86
     // subsequent InviteButton clicks/taps will be delivered.
148
     // subsequent InviteButton clicks/taps will be delivered.
149
+    [controller endAddPeople];
150
+}
151
+
152
+- (void) inviteSettled:(NSArray<NSDictionary *> * _Nonnull)failedInvitees
153
+  fromSearchController:(JMAddPeopleController * _Nonnull)addPeopleController {
154
+    // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise, it
155
+    // is going to be memory-leaked in the associated JMInviteController and no
156
+    // subsequent InviteButton clicks/taps will be delivered. Technically,
157
+    // endAddPeople will automatically be invoked if there are no
158
+    // failedInviteees i.e. the invite succeeeded for all specified invitees.
87
     [addPeopleController endAddPeople];
159
     [addPeopleController endAddPeople];
88
 }
160
 }
89
 
161
 

+ 6
- 6
react/features/invite/components/InviteButton.native.js Просмотреть файл

70
             ...props
70
             ...props
71
         } = this.props;
71
         } = this.props;
72
 
72
 
73
-        if (_SHARE_ROOM_TOOLBAR_BUTTON) {
73
+        if (_addPeopleEnabled || _dialOutEnabled) {
74
             return (
74
             return (
75
                 <ToolbarButton
75
                 <ToolbarButton
76
-                    iconName = 'link'
77
-                    onClick = { _onShareRoom }
76
+                    iconName = { 'link' }
77
+                    onClick = { _onAddPeople }
78
                     { ...props } />
78
                     { ...props } />
79
             );
79
             );
80
         }
80
         }
81
 
81
 
82
-        if (_addPeopleEnabled || _dialOutEnabled) {
82
+        if (_SHARE_ROOM_TOOLBAR_BUTTON) {
83
             return (
83
             return (
84
                 <ToolbarButton
84
                 <ToolbarButton
85
-                    iconName = { 'link' }
86
-                    onClick = { _onAddPeople }
85
+                    iconName = 'link'
86
+                    onClick = { _onShareRoom }
87
                     { ...props } />
87
                     { ...props } />
88
             );
88
             );
89
         }
89
         }

Загрузка…
Отмена
Сохранить