瀏覽代碼

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

master
Lyubo Marinov 7 年之前
父節點
當前提交
7ffdaf59c7

+ 125
- 16
android/app/src/main/java/org/jitsi/meet/MainActivity.java 查看文件

@@ -23,11 +23,15 @@ import org.jitsi.meet.sdk.JitsiMeetActivity;
23 23
 import org.jitsi.meet.sdk.JitsiMeetView;
24 24
 import org.jitsi.meet.sdk.JitsiMeetViewListener;
25 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 28
 import org.jitsi.meet.sdk.invite.InviteControllerListener;
27 29
 
28 30
 import com.calendarevents.CalendarEventsPackage;
29 31
 
32
+import java.util.ArrayList;
30 33
 import java.util.HashMap;
34
+import java.util.List;
31 35
 import java.util.Map;
32 36
 
33 37
 /**
@@ -43,6 +47,14 @@ import java.util.Map;
43 47
  * {@code react-native run-android}.
44 48
  */
45 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 58
     @Override
47 59
     protected JitsiMeetView initializeView() {
48 60
         JitsiMeetView view = super.initializeView();
@@ -93,23 +105,68 @@ public class MainActivity extends JitsiMeetActivity {
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 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 170
     @Override
114 171
     protected void onCreate(Bundle savedInstanceState) {
115 172
         // As this is the Jitsi Meet app (i.e. not the Jitsi Meet SDK), we do
@@ -122,9 +179,61 @@ public class MainActivity extends JitsiMeetActivity {
122 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 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,6 +122,11 @@ public class JitsiMeetActivity extends AppCompatActivity {
122 122
         JitsiMeetView view = initializeView();
123 123
 
124 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 130
             this.view = view;
126 131
             setContentView(this.view);
127 132
         }
@@ -144,8 +149,6 @@ public class JitsiMeetActivity extends AppCompatActivity {
144 149
         }
145 150
         view.setWelcomePageEnabled(welcomePageEnabled);
146 151
 
147
-        view.loadURL(null);
148
-
149 152
         return view;
150 153
     }
151 154
 

+ 4
- 4
android/sdk/src/main/java/org/jitsi/meet/sdk/invite/AddPeopleController.java 查看文件

@@ -116,7 +116,7 @@ public class AddPeopleController {
116 116
 
117 117
                 if(items.containsKey(id)) {
118 118
                     WritableNativeMap map = new WritableNativeMap();
119
-                    map.merge(items.get(ids));
119
+                    map.merge(items.get(id));
120 120
                     invitees.pushMap(map);
121 121
                 } else {
122 122
                     // If the id doesn't exist in the map, we can't do anything,
@@ -138,14 +138,14 @@ public class AddPeopleController {
138 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 146
      * Start a search for entities to invite with the given query. Results will
147 147
      * be returned through the associated AddPeopleControllerListener's
148
-     * onReceiveResults method.
148
+     * onReceivedResults method.
149 149
      *
150 150
      * @param query
151 151
      */
@@ -188,7 +188,7 @@ public class AddPeopleController {
188 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,29 +21,36 @@ import java.util.Map;
21 21
 
22 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,10 +61,6 @@ public class InviteController {
61 61
         this.externalAPIScope = externalAPIScope;
62 62
     }
63 63
 
64
-    public InviteControllerListener getListener() {
65
-        return listener;
66
-    }
67
-
68 64
     void beginAddPeople(ReactApplicationContext reactContext) {
69 65
         InviteControllerListener listener = getListener();
70 66
 
@@ -102,6 +98,10 @@ public class InviteController {
102 98
         }
103 99
     }
104 100
 
101
+    public InviteControllerListener getListener() {
102
+        return listener;
103
+    }
104
+
105 105
     /**
106 106
      * Sends JavaScript event to submit invitations to the given item ids
107 107
      *
@@ -203,7 +203,7 @@ public class InviteController {
203 203
 
204 204
     /**
205 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 207
      * method.
208 208
      *
209 209
      * @param query {@code String} to use for the query
@@ -211,8 +211,8 @@ public class InviteController {
211 211
     void performQuery(AddPeopleController addPeopleController, String query) {
212 212
         WritableNativeMap params = new WritableNativeMap();
213 213
 
214
-        params.putString("externalAPIScope", externalAPIScope);
215 214
         params.putString("addPeopleControllerScope", addPeopleController.getUuid());
215
+        params.putString("externalAPIScope", externalAPIScope);
216 216
         params.putString("query", query);
217 217
         ReactContextUtils.emitEvent(
218 218
             addPeopleController.getReactApplicationContext(),

+ 5
- 1
ios/app/src/ViewController.h 查看文件

@@ -18,6 +18,10 @@
18 18
 
19 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 27
 @end

+ 73
- 1
ios/app/src/ViewController.m 查看文件

@@ -16,6 +16,13 @@
16 16
 
17 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 26
 @interface ViewController ()
20 27
 
21 28
 @end
@@ -31,7 +38,12 @@
31 38
 
32 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 48
 #endif // #ifdef DEBUG
37 49
 
@@ -46,6 +58,8 @@
46 58
 
47 59
 #if DEBUG
48 60
 
61
+// JitsiMeetViewDelegate
62
+
49 63
 void _onJitsiMeetViewDelegateEvent(NSString *name, NSDictionary *data) {
50 64
     NSLog(
51 65
         @"[%s:%d] JitsiMeetViewDelegate %@ %@",
@@ -76,14 +90,72 @@ void _onJitsiMeetViewDelegateEvent(NSString *name, NSDictionary *data) {
76 90
     _onJitsiMeetViewDelegateEvent(@"LOAD_CONFIG_ERROR", data);
77 91
 }
78 92
 
93
+// JMInviteControllerDelegate
94
+
79 95
 - (void)beginAddPeople:(JMAddPeopleController *)addPeopleController {
80 96
     NSLog(
81 97
         @"[%s:%d] JMInviteControllerDelegate %s",
82 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 146
     // XXX Explicitly invoke endAddPeople on addPeopleController; otherwise, it
85 147
     // is going to be memory-leaked in the associated JMInviteController and no
86 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 159
     [addPeopleController endAddPeople];
88 160
 }
89 161
 

+ 6
- 6
react/features/invite/components/InviteButton.native.js 查看文件

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

Loading…
取消
儲存