Skip to content

Commit c8ff900

Browse files
authored
feat: add methods to update, delete, and manage custom items in calls
[CLNP-7606] feat/implement-custom-item and android 16kb support
2 parents 04c34a4 + d4e4fee commit c8ff900

File tree

20 files changed

+780
-60
lines changed

20 files changed

+780
-60
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ dependencies {
9696
// noinspection GradleDynamicVersion
9797
implementation "com.facebook.react:react-native:+"
9898
implementation "org.jetbrains.kotlin:kotlin-stdlib:${ReactNative.ext.getVersion("android", "kotlin")}"
99-
implementation("com.sendbird.sdk:sendbird-calls:1.12.1")
99+
implementation("com.sendbird.sdk:sendbird-calls:1.12.3")
100100
}
101101

102102
ReactNative.shared.applyPackageVersion()

android/src/main/java/com/sendbird/calls/reactnative/module/CallsCommonModule.kt

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.sendbird.calls.reactnative.module
22

33
import com.facebook.react.bridge.Promise
4+
import com.facebook.react.bridge.ReadableArray
45
import com.facebook.react.bridge.ReadableMap
6+
import com.facebook.react.bridge.WritableNativeMap
57
import com.sendbird.calls.*
8+
import com.sendbird.calls.internal.PushTokenType
69
import com.sendbird.calls.reactnative.RNCallsInternalError
710
import com.sendbird.calls.reactnative.extension.rejectCalls
811
import com.sendbird.calls.reactnative.module.listener.CallsDirectCallListener
@@ -104,7 +107,7 @@ class CallsCommonModule(private val root: CallsModule): CommonModule {
104107

105108
override fun registerPushToken(token: String, unique: Boolean, promise: Promise) {
106109
RNCallsLogger.d("[CommonModule] registerPushToken()")
107-
SendBirdCall.registerPushToken(token, unique) { error ->
110+
SendBirdCall.registerPushToken(token, PushTokenType.FCM_VOIP, unique) { error ->
108111
error
109112
?.let {
110113
promise.rejectCalls(it)
@@ -117,7 +120,7 @@ class CallsCommonModule(private val root: CallsModule): CommonModule {
117120

118121
override fun unregisterPushToken(token: String, promise: Promise) {
119122
RNCallsLogger.d("[CommonModule] unregisterPushToken()")
120-
SendBirdCall.unregisterPushToken(token) { error ->
123+
SendBirdCall.unregisterPushToken(token, PushTokenType.FCM_VOIP) { error ->
121124
error
122125
?.let {
123126
promise.rejectCalls(it)
@@ -219,4 +222,50 @@ class CallsCommonModule(private val root: CallsModule): CommonModule {
219222
promise.resolve(null)
220223
}
221224
}
225+
226+
override fun updateCustomItems(callId: String, customItems: ReadableMap, promise: Promise) {
227+
RNCallsLogger.d("[CommonModule] updateCustomItems($callId)")
228+
val items = CallsUtils.convertMapToHashMap(customItems)
229+
230+
SendBirdCall.updateCustomItems(callId, items) { updatedItems, affectedKeys, error ->
231+
error?.let {
232+
promise.rejectCalls(it)
233+
} ?: run {
234+
val result = WritableNativeMap()
235+
result.putMap("updatedItems", CallsUtils.convertToJsMap(updatedItems as? Map<*, *> ?: emptyMap<String, String>()))
236+
result.putArray("affectedKeys", CallsUtils.convertToJsArray(affectedKeys as? List<*> ?: emptyList<String>()))
237+
promise.resolve(result)
238+
}
239+
}
240+
}
241+
242+
override fun deleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise) {
243+
RNCallsLogger.d("[CommonModule] deleteCustomItems($callId)")
244+
val keys = CallsUtils.convertArrayToSet(customItemKeys)
245+
246+
SendBirdCall.deleteCustomItems(callId, keys) { updatedItems, affectedKeys, error ->
247+
error?.let {
248+
promise.rejectCalls(it)
249+
} ?: run {
250+
val result = WritableNativeMap()
251+
result.putMap("updatedItems", CallsUtils.convertToJsMap(updatedItems as? Map<*, *> ?: emptyMap<String, String>()))
252+
result.putArray("affectedKeys", CallsUtils.convertToJsArray(affectedKeys as? List<*> ?: emptyList<String>()))
253+
promise.resolve(result)
254+
}
255+
}
256+
}
257+
258+
override fun deleteAllCustomItems(callId: String, promise: Promise) {
259+
RNCallsLogger.d("[CommonModule] deleteAllCustomItems($callId)")
260+
SendBirdCall.deleteAllCustomItems(callId) { updatedItems, affectedKeys, error ->
261+
error?.let {
262+
promise.rejectCalls(it)
263+
} ?: run {
264+
val result = WritableNativeMap()
265+
result.putMap("updatedItems", CallsUtils.convertToJsMap(updatedItems as? Map<*, *> ?: emptyMap<String, String>()))
266+
result.putArray("affectedKeys", CallsUtils.convertToJsArray(affectedKeys as? List<*> ?: emptyList<String>()))
267+
promise.resolve(result)
268+
}
269+
}
270+
}
222271
}

android/src/main/java/com/sendbird/calls/reactnative/module/CallsDirectCallModule.kt

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sendbird.calls.reactnative.module
22

33
import com.facebook.react.bridge.Promise
4+
import com.facebook.react.bridge.ReadableArray
45
import com.facebook.react.bridge.ReadableMap
56
import com.sendbird.calls.AcceptParams
67
import com.sendbird.calls.AudioDevice
@@ -83,7 +84,7 @@ class CallsDirectCallModule(private val root: CallsModule): DirectCallModule {
8384
call.setRemoteVideoView(view.getSurface())
8485
}
8586
}
86-
87+
8788
override fun muteMicrophone(type: String, identifier: String) {
8889
val from = "directCall/muteMicrophone"
8990
RNCallsLogger.d("[DirectCallModule] $from ($identifier)")
@@ -200,4 +201,69 @@ class CallsDirectCallModule(private val root: CallsModule): DirectCallModule {
200201
CallsUtils.findDirectCall(identifier, from).resumeAudioTrack()
201202
}
202203
}
204+
205+
override fun directCallUpdateCustomItems(callId: String, customItems: ReadableMap, promise: Promise) {
206+
val from = "directCall/updateCustomItems"
207+
RNCallsLogger.d("[DirectCallModule] $from ($callId)")
208+
209+
CallsUtils.safeRun(promise) {
210+
val call = CallsUtils.findDirectCall(callId, from)
211+
val items = CallsUtils.convertMapToHashMap(customItems)
212+
213+
call.updateCustomItems(items) { updatedItems, affectedKeys, error ->
214+
if (error != null) {
215+
promise.rejectCalls(error)
216+
} else {
217+
val result = CallsUtils.createMap().apply {
218+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: hashMapOf()))
219+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
220+
}
221+
promise.resolve(result)
222+
}
223+
}
224+
}
225+
}
226+
227+
override fun directCallDeleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise) {
228+
val from = "directCall/deleteCustomItems"
229+
RNCallsLogger.d("[DirectCallModule] $from ($callId)")
230+
231+
CallsUtils.safeRun(promise) {
232+
val call = CallsUtils.findDirectCall(callId, from)
233+
val keys = CallsUtils.convertArrayToSet(customItemKeys)
234+
235+
call.deleteCustomItems(keys) { updatedItems, affectedKeys, error ->
236+
if (error != null) {
237+
promise.rejectCalls(error)
238+
} else {
239+
val result = CallsUtils.createMap().apply {
240+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: hashMapOf()))
241+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
242+
}
243+
promise.resolve(result)
244+
}
245+
}
246+
}
247+
}
248+
249+
override fun directCallDeleteAllCustomItems(callId: String, promise: Promise) {
250+
val from = "directCall/deleteAllCustomItems"
251+
RNCallsLogger.d("[DirectCallModule] $from ($callId)")
252+
253+
CallsUtils.safeRun(promise) {
254+
val call = CallsUtils.findDirectCall(callId, from)
255+
256+
call.deleteAllCustomItems { updatedItems, affectedKeys, error ->
257+
if (error != null) {
258+
promise.rejectCalls(error)
259+
} else {
260+
val result = CallsUtils.createMap().apply {
261+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: hashMapOf()))
262+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
263+
}
264+
promise.resolve(result)
265+
}
266+
}
267+
}
268+
}
203269
}

android/src/main/java/com/sendbird/calls/reactnative/module/CallsGroupCallModule.kt

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sendbird.calls.reactnative.module
22

33
import com.facebook.react.bridge.Promise
4+
import com.facebook.react.bridge.ReadableArray
45
import com.facebook.react.bridge.ReadableMap
56
import com.sendbird.calls.*
67
import com.sendbird.calls.reactnative.RNCallsInternalError
@@ -147,4 +148,69 @@ class CallsGroupCallModule: GroupCallModule {
147148
CallsUtils.findRoom(identifier, from).localParticipant?.resumeAudioTrack()
148149
}
149150
}
151+
152+
override fun groupCallUpdateCustomItems(roomId: String, customItems: ReadableMap, promise: Promise) {
153+
val from = "groupCall/updateCustomItems"
154+
RNCallsLogger.d("[GroupCallModule] $from ($roomId)")
155+
156+
CallsUtils.safeRun(promise) {
157+
val room = CallsUtils.findRoom(roomId, from)
158+
val items = CallsUtils.convertMapToHashMap(customItems)
159+
160+
room.updateCustomItems(items) { updatedItems, affectedKeys, error ->
161+
if (error != null) {
162+
promise.rejectCalls(error)
163+
} else {
164+
val result = CallsUtils.createMap().apply {
165+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: hashMapOf()))
166+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
167+
}
168+
promise.resolve(result)
169+
}
170+
}
171+
}
172+
}
173+
174+
override fun groupCallDeleteCustomItems(roomId: String, customItemKeys: ReadableArray, promise: Promise) {
175+
val from = "groupCall/deleteCustomItems"
176+
RNCallsLogger.d("[GroupCallModule] $from ($roomId)")
177+
178+
CallsUtils.safeRun(promise) {
179+
val room = CallsUtils.findRoom(roomId, from)
180+
val keys = CallsUtils.convertArrayToSet(customItemKeys)
181+
182+
room.deleteCustomItems(keys) { updatedItems, affectedKeys, error ->
183+
if (error != null) {
184+
promise.rejectCalls(error)
185+
} else {
186+
val result = CallsUtils.createMap().apply {
187+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: hashMapOf()))
188+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
189+
}
190+
promise.resolve(result)
191+
}
192+
}
193+
}
194+
}
195+
196+
override fun groupCallDeleteAllCustomItems(roomId: String, promise: Promise) {
197+
val from = "groupCall/deleteAllCustomItems"
198+
RNCallsLogger.d("[GroupCallModule] $from ($roomId)")
199+
200+
CallsUtils.safeRun(promise) {
201+
val room = CallsUtils.findRoom(roomId, from)
202+
// There is no deleteAllCustomItems API in Android native, so handled with deleteCustomItems.
203+
room.deleteCustomItems(null) { updatedItems, affectedKeys, error ->
204+
if (error != null) {
205+
promise.rejectCalls(error)
206+
} else {
207+
val result = CallsUtils.createMap().apply {
208+
putMap("updatedItems", CallsUtils.convertHashMapToMap(updatedItems ?: emptyMap()))
209+
putArray("affectedKeys", CallsUtils.convertListToArray(affectedKeys ?: listOf()))
210+
}
211+
promise.resolve(result)
212+
}
213+
}
214+
}
215+
}
150216
}

android/src/main/java/com/sendbird/calls/reactnative/module/CallsModule.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.sendbird.calls.reactnative.module
22

33
import com.facebook.react.bridge.Promise
44
import com.facebook.react.bridge.ReactApplicationContext
5+
import com.facebook.react.bridge.ReadableArray
56
import com.facebook.react.bridge.ReadableMap
67
import com.sendbird.calls.DirectCall
78
import com.sendbird.calls.RoomInvitation
@@ -76,6 +77,9 @@ class CallsModule(val reactContext: ReactApplicationContext) : CallsModuleStruct
7677
override fun createRoom(params: ReadableMap, promise: Promise) = commonModule.createRoom(params, promise)
7778
override fun fetchRoomById(roomId: String, promise: Promise) = commonModule.fetchRoomById(roomId, promise)
7879
override fun getCachedRoomById(roomId: String, promise: Promise) = commonModule.getCachedRoomById(roomId, promise)
80+
override fun updateCustomItems(callId: String, customItems: ReadableMap, promise: Promise) = commonModule.updateCustomItems(callId, customItems, promise)
81+
override fun deleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise) = commonModule.deleteCustomItems(callId, customItemKeys, promise)
82+
override fun deleteAllCustomItems(callId: String, promise: Promise) = commonModule.deleteAllCustomItems(callId, promise)
7983

8084
/** Media Device control interface **/
8185
override fun stopVideo(type: String, identifier: String) = getControllableModule(type).stopVideo(type, identifier)
@@ -93,10 +97,16 @@ class CallsModule(val reactContext: ReactApplicationContext) : CallsModuleStruct
9397
override fun end(callId: String, promise: Promise)= directCallModule.end(callId, promise)
9498
override fun updateLocalVideoView(callId: String, videoViewId: Int)= directCallModule.updateLocalVideoView(callId, videoViewId)
9599
override fun updateRemoteVideoView(callId: String, videoViewId: Int)= directCallModule.updateRemoteVideoView(callId, videoViewId)
100+
override fun directCallUpdateCustomItems(callId: String, customItems: ReadableMap, promise: Promise) = directCallModule.directCallUpdateCustomItems(callId, customItems, promise)
101+
override fun directCallDeleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise) = directCallModule.directCallDeleteCustomItems(callId, customItemKeys, promise)
102+
override fun directCallDeleteAllCustomItems(callId: String, promise: Promise) = directCallModule.directCallDeleteAllCustomItems(callId, promise)
96103

97104
/** GroupCall module interface**/
98105
override fun enter(roomId: String, options: ReadableMap, promise: Promise) = groupCallModule.enter(roomId, options, promise)
99106
override fun exit(roomId: String) = groupCallModule.exit(roomId)
107+
override fun groupCallUpdateCustomItems(roomId: String, customItems: ReadableMap, promise: Promise) = groupCallModule.groupCallUpdateCustomItems(roomId, customItems, promise)
108+
override fun groupCallDeleteCustomItems(roomId: String, customItemKeys: ReadableArray, promise: Promise) = groupCallModule.groupCallDeleteCustomItems(roomId, customItemKeys, promise)
109+
override fun groupCallDeleteAllCustomItems(roomId: String, promise: Promise) = groupCallModule.groupCallDeleteAllCustomItems(roomId, promise)
100110

101111
/** Queries **/
102112
fun createDirectCallLogListQuery(params: ReadableMap, promise: Promise) = queries.createDirectCallLogListQuery(params, promise)

android/src/main/java/com/sendbird/calls/reactnative/module/CallsModuleStruct.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sendbird.calls.reactnative.module
22

33
import com.facebook.react.bridge.Promise
4+
import com.facebook.react.bridge.ReadableArray
45
import com.facebook.react.bridge.ReadableMap
56

67
interface CallsModuleStruct: CommonModule, DirectCallModule, GroupCallModule { }
@@ -29,18 +30,28 @@ interface CommonModule {
2930
fun createRoom(params: ReadableMap, promise: Promise)
3031
fun fetchRoomById(roomId: String, promise: Promise)
3132
fun getCachedRoomById(roomId: String, promise: Promise)
33+
34+
fun updateCustomItems(callId: String, customItems: ReadableMap, promise: Promise)
35+
fun deleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise)
36+
fun deleteAllCustomItems(callId: String, promise: Promise)
3237
}
3338

3439
interface DirectCallModule: MediaDeviceControl {
3540
fun accept(callId: String, options: ReadableMap, holdActiveCall: Boolean, promise: Promise)
3641
fun end(callId: String, promise: Promise)
3742
fun updateLocalVideoView(callId: String, videoViewId: Int)
3843
fun updateRemoteVideoView(callId: String, videoViewId: Int)
44+
fun directCallUpdateCustomItems(callId: String, customItems: ReadableMap, promise: Promise)
45+
fun directCallDeleteCustomItems(callId: String, customItemKeys: ReadableArray, promise: Promise)
46+
fun directCallDeleteAllCustomItems(callId: String, promise: Promise)
3947
}
4048

4149
interface GroupCallModule: MediaDeviceControl {
4250
fun enter(roomId: String, options: ReadableMap, promise: Promise)
4351
fun exit(roomId: String)
52+
fun groupCallUpdateCustomItems(roomId: String, customItems: ReadableMap, promise: Promise)
53+
fun groupCallDeleteCustomItems(roomId: String, customItemKeys: ReadableArray, promise: Promise)
54+
fun groupCallDeleteAllCustomItems(roomId: String, promise: Promise)
4455
}
4556

4657
enum class ControllableModuleType {
@@ -58,4 +69,4 @@ interface MediaDeviceControl {
5869
fun selectVideoDevice(type: String, identifier: String, device: ReadableMap, promise: Promise)
5970
fun resumeVideoCapturer(type: String, identifier: String)
6071
fun resumeAudioTrack(type: String, identifier: String)
61-
}
72+
}

android/src/main/java/com/sendbird/calls/reactnative/utils/CallsUtils.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,4 +252,50 @@ object CallsUtils {
252252
return SendBirdCall.getCachedRoomById(roomId) ?: throw RNCallsInternalError(from, RNCallsInternalError.Type.NOT_FOUND_ROOM)
253253
}
254254

255+
fun createMap(): WritableNativeMap {
256+
return WritableNativeMap()
257+
}
258+
259+
fun convertMapToHashMap(map: ReadableMap): HashMap<String, String> {
260+
val hashMap = HashMap<String, String>()
261+
val iterator = map.keySetIterator()
262+
while (iterator.hasNextKey()) {
263+
val key = iterator.nextKey()
264+
hashMap[key] = map.getString(key) ?: ""
265+
}
266+
return hashMap
267+
}
268+
269+
fun convertHashMapToMap(hashMap: Map<String, String>): WritableNativeMap {
270+
val map = WritableNativeMap()
271+
for ((key, value) in hashMap) {
272+
map.putString(key, value)
273+
}
274+
return map
275+
}
276+
277+
fun convertArrayToSet(array: ReadableArray): Set<String> {
278+
val set = mutableSetOf<String>()
279+
for (i in 0 until array.size()) {
280+
set.add(array.getString(i))
281+
}
282+
return set
283+
}
284+
285+
fun convertArrayToList(array: ReadableArray): List<String> {
286+
val list = mutableListOf<String>()
287+
for (i in 0 until array.size()) {
288+
list.add(array.getString(i))
289+
}
290+
return list
291+
}
292+
293+
fun convertListToArray(list: List<String>): WritableNativeArray {
294+
val array = WritableNativeArray()
295+
for (item in list) {
296+
array.pushString(item)
297+
}
298+
return array
299+
}
300+
255301
}

0 commit comments

Comments
 (0)