diff --git a/packages/react-native-hms/android/build.gradle b/packages/react-native-hms/android/build.gradle index e77b03ab3..07a6de4ec 100644 --- a/packages/react-native-hms/android/build.gradle +++ b/packages/react-native-hms/android/build.gradle @@ -12,7 +12,14 @@ buildscript { if (ext.has("kotlinVersion")) { ext.kotlinVersion() } else { - ext.safeExtGet("kotlinVersion", "1.6.0") + ext.safeExtGet("kotlinVersion", "1.7.20") + } + } + ext.getKotlinGradlePluginVersion = { + if (ext.has("kotlinGradlePluginVersion")) { + ext.kotlinGradlePluginVersion() + } else { + ext.safeExtGet("kotlinGradlePluginVersion", "1.8.0") } } if (project == rootProject) { @@ -30,7 +37,7 @@ buildscript { mavenCentral() } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinGradlePluginVersion()}" } } diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt index 9f8cc8b5b..738c94836 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt @@ -344,6 +344,14 @@ object HMSDecoder { permissions.putBoolean("changeRole", hmsPermissions.changeRole) permissions.putBoolean("pollRead", hmsPermissions.pollRead) permissions.putBoolean("pollWrite", hmsPermissions.pollWrite) + + val whiteboardPermissionMap: WritableMap = Arguments.createMap() + hmsPermissions.whiteboard.let { whiteBoardPermission -> + whiteboardPermissionMap.putBoolean("admin", whiteBoardPermission.admin) + whiteboardPermissionMap.putBoolean("read", whiteBoardPermission.read) + whiteboardPermissionMap.putBoolean("write", whiteBoardPermission.write) + } + permissions.putMap("whiteboard", whiteboardPermissionMap) } return permissions } diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSManager.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSManager.kt index 9762a5cdc..23af37b03 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSManager.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSManager.kt @@ -1458,6 +1458,44 @@ class HMSManager(reactContext: ReactApplicationContext) : } // endregion + //region Whiteboard + @ReactMethod + fun startWhiteboard( + data: ReadableMap, + promise: Promise?, + ) { + val rnSDK = HMSHelper.getHms(data, hmsCollection) + rnSDK?.let { sdk -> + sdk.interactivityCenter?.let { center -> + center.startWhiteboard(data, promise) + return + } + } + promise?.reject( + "6004", + "HMS SDK not initialized", + ) + } + + @ReactMethod + fun stopWhiteboard( + data: ReadableMap, + promise: Promise?, + ) { + val rnSDK = HMSHelper.getHms(data, hmsCollection) + rnSDK?.let { sdk -> + sdk.interactivityCenter?.let { center -> + center.stopWhiteboard(promise) + return + } + } + promise?.reject( + "6004", + "HMS SDK not initialized", + ) + } + //endregion + // region Noise Cancellation Plugin @ReactMethod fun enableNoiseCancellationPlugin( diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt index 8e95fa09e..77691f212 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt @@ -256,9 +256,11 @@ class HMSRNSDK( delegate.emitEvent("ON_PREVIEW", data) } - /* - override fun peerListUpdated(addedPeers: ArrayList?, removedPeers: ArrayList?) { - + override fun peerListUpdated( + addedPeers: ArrayList?, + removedPeers: ArrayList?, + ) { + super.peerListUpdated(addedPeers, removedPeers) if (eventsEnableStatus["ON_PEER_LIST_UPDATED"] != true) { return } @@ -278,11 +280,11 @@ class HMSRNSDK( } } + data.putString("id", id) data.putArray("addedPeers", addedPeersArray) data.putArray("removedPeers", removedPeersArray) delegate.emitEvent("ON_PEER_LIST_UPDATED", data) } - */ }, ) } else { diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSInteractivityDecoder.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSInteractivityDecoder.kt index a707de736..40a5f293e 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSInteractivityDecoder.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSInteractivityDecoder.kt @@ -17,8 +17,12 @@ import live.hms.video.polls.network.HMSPollLeaderboardEntry import live.hms.video.polls.network.HMSPollLeaderboardSummary import live.hms.video.polls.network.PollLeaderboardResponse import live.hms.video.polls.network.PollResultsDisplay +import live.hms.video.whiteboard.HMSWhiteboard +import live.hms.video.whiteboard.HMSWhiteboardUpdate +import live.hms.video.whiteboard.State object HMSInteractivityDecoder { + //region poll methods fun getPollUpdateType(hmsPollUpdateType: HMSPollUpdateType): Int { return when (hmsPollUpdateType) { HMSPollUpdateType.started -> 0 @@ -280,31 +284,6 @@ object HMSInteractivityDecoder { return readableArray } -/* - - static func getHMSPollQuestionResponseResults(_ hmsPollQuestionResponseResults: [HMSPollQuestionResponseResult]) -> [[String: AnyHashable]] { - var results = [[String: AnyHashable]]() - - hmsPollQuestionResponseResults.forEach { result in - results.append(getHMSPollQuestionResponseResult(result)) - } - return results - } - - static func getHMSPollQuestionResponseResult(_ hmsPollQuestionResponseResult: HMSPollQuestionResponseResult) -> [String: AnyHashable] { - var result: [String: AnyHashable] = [ - "question": hmsPollQuestionResponseResult.question - ] - if let correct = hmsPollQuestionResponseResult.correct { - result["correct"] = correct - } - if let error = hmsPollQuestionResponseResult.error { - result["error"] = error.localizedDescription - } - return result - } - - */ fun getHMSPollQuestionResponseResults(hmsPollQuestionResponseResults: PollAnswerResponse): WritableArray { val results = Arguments.createArray() @@ -410,4 +389,50 @@ object HMSInteractivityDecoder { return result } + //endregion + + //region whiteboard methods + fun getHMSWhiteboard(hmsWhiteboard: HMSWhiteboard): WritableMap { + val data: WritableMap = Arguments.createMap() + + data.putString("id", hmsWhiteboard.id) + data.putBoolean("isOwner", hmsWhiteboard.isOwner) + data.putString("state", getWhiteboardState(hmsWhiteboard.state)) + hmsWhiteboard.title?.let { title -> + data.putString("title", title) + } + hmsWhiteboard.owner?.let { owner -> + data.putMap("owner", HMSDecoder.getHmsPeerSubset(owner)) + } + data.putString("url", hmsWhiteboard.url) + return data + } + + enum class JSWhiteboardState(val label: String) { + Start("STARTED"), + Stop("STOPPED"), + } + + private fun getWhiteboardState(hmsWhiteboardState: State): String { + return when (hmsWhiteboardState) { + State.Started -> { + JSWhiteboardState.Start.label + } + State.Stopped -> { + JSWhiteboardState.Stop.label + } + } + } + + fun getWhiteboardUpdateType(hmsWhiteboardUpdate: HMSWhiteboardUpdate): String { + return when (hmsWhiteboardUpdate) { + is HMSWhiteboardUpdate.Start -> { + JSWhiteboardState.Start.label + } + is HMSWhiteboardUpdate.Stop -> { + JSWhiteboardState.Stop.label + } + } + } + //endregion } diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSRNInteractivityCenter.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSRNInteractivityCenter.kt index b2bb03e56..9dde7799e 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSRNInteractivityCenter.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/Interactivity/HMSRNInteractivityCenter.kt @@ -13,10 +13,12 @@ import live.hms.video.polls.network.PollLeaderboardResponse import live.hms.video.sdk.HMSActionResultListener import live.hms.video.sdk.HMSSDK import live.hms.video.sdk.HmsTypedActionResultListener +import live.hms.video.whiteboard.HMSWhiteboardUpdate +import live.hms.video.whiteboard.HMSWhiteboardUpdateListener class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRNSDK) { init { - // Listen for poll updates + //region Listen for poll updates this.sdk.getHmsInteractivityCenter().pollUpdateListener = object : HmsPollUpdateListener { override fun onPollUpdate( @@ -35,8 +37,34 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN rnSDK.delegate.emitEvent("ON_POLL_UPDATE", data) } } + //endregion + + //region Listen for whiteboard updates + this.sdk.getHmsInteractivityCenter().setWhiteboardUpdateListener( + object : HMSWhiteboardUpdateListener { + override fun onUpdate(hmsWhiteboardUpdate: HMSWhiteboardUpdate) { + if (rnSDK.eventsEnableStatus["ON_WHITEBOARD_UPDATE"] != true) { + return + } + val data: WritableMap = Arguments.createMap() + when (hmsWhiteboardUpdate) { + is HMSWhiteboardUpdate.Start -> { + data.putMap("hmsWhiteboard", HMSInteractivityDecoder.getHMSWhiteboard(hmsWhiteboardUpdate.hmsWhiteboard)) + data.putString("updateType", HMSInteractivityDecoder.getWhiteboardUpdateType(hmsWhiteboardUpdate)) + } + is HMSWhiteboardUpdate.Stop -> { + data.putMap("hmsWhiteboard", HMSInteractivityDecoder.getHMSWhiteboard(hmsWhiteboardUpdate.hmsWhiteboard)) + data.putString("updateType", HMSInteractivityDecoder.getWhiteboardUpdateType(hmsWhiteboardUpdate)) + } + } + rnSDK.delegate.emitEvent("ON_WHITEBOARD_UPDATE", data) + } + }, + ) + //endregion } + //region poll methods fun quickStartPoll( data: ReadableMap, promise: Promise?, @@ -159,4 +187,44 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN }, ) } + //endregion + + //region whiteboard methods + fun startWhiteboard( + data: ReadableMap, + promise: Promise?, + ) { + val whiteboardTitle = data.getString("title") + if (whiteboardTitle == null) { + promise?.reject("6004", "whiteboard title is required") + return + } + sdk.getHmsInteractivityCenter().startWhiteboard( + whiteboardTitle, + object : HMSActionResultListener { + override fun onSuccess() { + promise?.resolve(true) + } + + override fun onError(error: HMSException) { + promise?.reject(error.code.toString(), error.description) + } + }, + ) + } + + fun stopWhiteboard(promise: Promise?) { + sdk.getHmsInteractivityCenter().stopWhiteboard( + object : HMSActionResultListener { + override fun onSuccess() { + promise?.resolve(true) + } + + override fun onError(error: HMSException) { + promise?.reject(error.code.toString(), error.description) + } + }, + ) + } + //endregion } diff --git a/packages/react-native-hms/example/android/Gemfile.lock b/packages/react-native-hms/example/android/Gemfile.lock index 6736ac7a5..df508a788 100644 --- a/packages/react-native-hms/example/android/Gemfile.lock +++ b/packages/react-native-hms/example/android/Gemfile.lock @@ -10,17 +10,17 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.916.0) - aws-sdk-core (3.192.1) + aws-partitions (1.921.0) + aws-sdk-core (3.193.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.79.0) - aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-kms (1.80.0) + aws-sdk-core (~> 3, >= 3.193.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.147.0) - aws-sdk-core (~> 3, >= 3.192.0) + aws-sdk-s3 (1.148.0) + aws-sdk-core (~> 3, >= 3.193.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -138,7 +138,7 @@ GEM google-cloud-env (2.1.1) faraday (>= 1.0, < 3.a) google-cloud-errors (1.4.0) - google-cloud-storage (1.50.0) + google-cloud-storage (1.51.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-core (~> 0.13) diff --git a/packages/react-native-hms/example/ios/Gemfile.lock b/packages/react-native-hms/example/ios/Gemfile.lock index dc3eefeed..aab715f7c 100644 --- a/packages/react-native-hms/example/ios/Gemfile.lock +++ b/packages/react-native-hms/example/ios/Gemfile.lock @@ -10,17 +10,17 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.916.0) - aws-sdk-core (3.192.1) + aws-partitions (1.921.0) + aws-sdk-core (3.193.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.79.0) - aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-kms (1.80.0) + aws-sdk-core (~> 3, >= 3.193.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.147.0) - aws-sdk-core (~> 3, >= 3.192.0) + aws-sdk-s3 (1.148.0) + aws-sdk-core (~> 3, >= 3.193.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -131,7 +131,7 @@ GEM google-cloud-env (2.1.1) faraday (>= 1.0, < 3.a) google-cloud-errors (1.4.0) - google-cloud-storage (1.50.0) + google-cloud-storage (1.51.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-core (~> 0.13) diff --git a/packages/react-native-hms/example/ios/Podfile.lock b/packages/react-native-hms/example/ios/Podfile.lock index 8383830cf..0550c7a4f 100644 --- a/packages/react-native-hms/example/ios/Podfile.lock +++ b/packages/react-native-hms/example/ios/Podfile.lock @@ -63,10 +63,10 @@ PODS: - HMSHLSPlayerSDK (0.0.2): - HMSAnalyticsSDK (= 0.0.2) - HMSNoiseCancellationModels (1.0.0) - - HMSSDK (1.8.0): + - HMSSDK (1.9.0): - HMSAnalyticsSDK (= 0.0.2) - - HMSWebRTC (= 1.0.5118) - - HMSWebRTC (1.0.5118) + - HMSWebRTC (= 1.0.6168) + - HMSWebRTC (1.0.6168) - libevent (2.1.12) - OpenSSL-Universal (1.1.180) - Permission-Camera (3.4.0): @@ -293,11 +293,11 @@ PODS: - React-Core - react-native-document-picker (8.2.2): - React-Core - - react-native-hms (1.10.4): + - react-native-hms (1.10.5): - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) - HMSNoiseCancellationModels (= 1.0.0) - - HMSSDK (= 1.8.0) + - HMSSDK (= 1.9.0) - React-Core - react-native-safe-area-context (3.4.1): - React-Core @@ -409,7 +409,7 @@ PODS: - React-RCTText - ReactCommon/turbomodule/core - Yoga - - RNScreens (3.30.1): + - RNScreens (3.31.1): - React-Core - React-RCTImage - RNShare (8.2.2): @@ -633,8 +633,8 @@ SPEC CHECKSUMS: HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 HMSNoiseCancellationModels: a3bda1405a16015632f4bcabd46ce48f35103b02 - HMSSDK: c893d1381a47ed02760ef6d06625b9aa5251f998 - HMSWebRTC: 4487c7200f1e9358412c1d8cd974edd2766467dc + HMSSDK: 96bdafc1c610aabfecd1155ad7e3c1bc45b3a6cb + HMSWebRTC: a302f0d6c94f7bee94f3265adb7bb1c6569e7ee5 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b Permission-Camera: 40f43388fa8a648dc6ced73f145ef329ab3ff3fe @@ -653,7 +653,7 @@ SPEC CHECKSUMS: react-native-avoid-softinput: 71a692888f0c1d426ad9045dc8325773583962cd react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f react-native-document-picker: cd4d6b36a5207ad7a9e599ebb9eb0c2e84fa0b87 - react-native-hms: e930a8af433e469d7f9f5b5dc55a76ad155d787f + react-native-hms: c874b5220b21f950ca692c03815bbcf8c1522fac react-native-safe-area-context: 9e40fb181dac02619414ba1294d6c2a807056ab9 react-native-simple-toast: 8ee5d23f0b92b935ab7434cdb65159ce12dfb4b7 React-perflogger: 5a890ca0911669421b7611661e9b58f91c805f5c @@ -676,7 +676,7 @@ SPEC CHECKSUMS: RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211 RNPermissions: eac721f71748c4472d6e876038270b75397d6ee7 RNReanimated: 39e61976e5b5c8a891ea8916fb264ae176e8765d - RNScreens: 848541d154d2a184131b34e468b10aa33008f357 + RNScreens: b940b46ae5987e138c4fadb6b264d09177932b4d RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 diff --git a/packages/react-native-hms/example/package-lock.json b/packages/react-native-hms/example/package-lock.json index dad37b3e3..7e271b159 100644 --- a/packages/react-native-hms/example/package-lock.json +++ b/packages/react-native-hms/example/package-lock.json @@ -1,12 +1,12 @@ { "name": "RNHMSExample", - "version": "1.10.4", + "version": "1.10.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "RNHMSExample", - "version": "1.10.4", + "version": "1.10.5", "hasInstallScript": true, "dependencies": { "@miblanchard/react-native-slider": "^2.0.2", @@ -52,15 +52,6 @@ "typescript": "^3.8.3" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -212,9 +203,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -4827,12 +4818,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -4852,11 +4843,11 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5191,9 +5182,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", "funding": [ { "type": "opencollective", @@ -5694,9 +5685,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "node_modules/debug": { "version": "4.3.4", @@ -5897,9 +5888,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.745", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.745.tgz", - "integrity": "sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==" + "version": "1.4.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", + "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==" }, "node_modules/emittery": { "version": "0.7.2", @@ -5948,9 +5939,9 @@ } }, "node_modules/envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "bin": { "envinfo": "dist/cli.js" }, @@ -6068,14 +6059,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -6374,9 +6365,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "engines": { "node": ">=10" @@ -10058,9 +10049,9 @@ } }, "node_modules/joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz", + "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -11703,17 +11694,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -11916,9 +11907,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -12508,9 +12499,9 @@ } }, "node_modules/react-native-screens": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.30.1.tgz", - "integrity": "sha512-/muEvjocCtFb+j5J3YmLvB25+f4rIU8hnnxgGTkXcAf2omPBY8uhPjJaaFUlvj64VEoEzJcRpugbXWsjfPPIFg==", + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.31.1.tgz", + "integrity": "sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ==", "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" @@ -15082,20 +15073,20 @@ } }, "node_modules/use-subscription": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.0.tgz", - "integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.2.tgz", + "integrity": "sha512-yC2ShScvQ1lAGRp5Y6pz1MqBIU81REfJ/sQIe16BCgKK9mRlZCnU90uY0alKsN6e/Next0vXTsvH3HbAfdH68w==", "dependencies": { - "use-sync-external-store": "^1.2.0" + "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -15371,6 +15362,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", diff --git a/packages/react-native-hms/example/package.json b/packages/react-native-hms/example/package.json index 2faeba5eb..c9ddb0b0c 100644 --- a/packages/react-native-hms/example/package.json +++ b/packages/react-native-hms/example/package.json @@ -1,6 +1,6 @@ { "name": "RNHMSExample", - "version": "1.10.4", + "version": "1.10.5", "private": true, "scripts": { "preinstall": "cd ../ && npm install && cd ./example", diff --git a/packages/react-native-hms/ios/HMSConstants.swift b/packages/react-native-hms/ios/HMSConstants.swift index 4ebd71cfd..16de57db7 100644 --- a/packages/react-native-hms/ios/HMSConstants.swift +++ b/packages/react-native-hms/ios/HMSConstants.swift @@ -32,4 +32,5 @@ struct HMSConstants { static let ON_SESSION_STORE_AVAILABLE = "ON_SESSION_STORE_AVAILABLE" static let ON_SESSION_STORE_CHANGED = "ON_SESSION_STORE_CHANGED" static let ON_POLL_UPDATE = "ON_POLL_UPDATE" + static let ON_WHITEBOARD_UPDATE = "ON_WHITEBOARD_UPDATE" } diff --git a/packages/react-native-hms/ios/HMSDecoder.swift b/packages/react-native-hms/ios/HMSDecoder.swift index c411ea8a2..955e1a8f5 100644 --- a/packages/react-native-hms/ios/HMSDecoder.swift +++ b/packages/react-native-hms/ios/HMSDecoder.swift @@ -451,7 +451,7 @@ class HMSDecoder: NSObject { } static private func getPermissions (_ permissions: HMSPermissions) -> [String: Any] { - [ + var permissionsDict: [String: Any] = [ "endRoom": permissions.endRoom ?? false, "removeOthers": permissions.removeOthers ?? false, "browserRecording": permissions.browserRecording ?? false, @@ -461,8 +461,16 @@ class HMSDecoder: NSObject { "unmute": permissions.unmute ?? false, "changeRole": permissions.changeRole ?? false, "pollRead": permissions.pollRead ?? false, - "pollWrite": permissions.pollWrite ?? false + "pollWrite": permissions.pollWrite ?? false, ] + if let whiteboardPermissions = permissions.whiteboard { + permissionsDict["whiteboard"] = [ + "admin": whiteboardPermissions.admin, + "read": whiteboardPermissions.read, + "write": whiteboardPermissions.write + ] + } + return permissionsDict } // MARK: - HMSRole Publish Settings and Utility functions diff --git a/packages/react-native-hms/ios/HMSHLSPlayerManager.swift b/packages/react-native-hms/ios/HMSHLSPlayerManager.swift index 0ec9f5df8..7ce7cad9a 100644 --- a/packages/react-native-hms/ios/HMSHLSPlayerManager.swift +++ b/packages/react-native-hms/ios/HMSHLSPlayerManager.swift @@ -339,7 +339,10 @@ class HMSHLSPlayer: UIView { attachPlayerPlaybackListeners() hmsHLSPlayerViewController?.showsPlaybackControls = false - hmsHLSPlayerViewController?.allowsPictureInPicturePlayback = false + hmsHLSPlayerViewController?.allowsPictureInPicturePlayback = true + if #available(iOS 14.2, *) { + hmsHLSPlayerViewController?.canStartPictureInPictureAutomaticallyFromInline = true + } } required init?(coder: NSCoder) { diff --git a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift index 7df6f0120..9acb0e6d9 100644 --- a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift +++ b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift @@ -270,4 +270,45 @@ class HMSInteractivityDecoder { return result } + + static func getHMSWhiteboard(_ hmsWhiteboard: HMSWhiteboard) -> [String: Any] { + var result: [String: Any] = [ + "id": hmsWhiteboard.id, + "state": getWhiteboardState(hmsWhiteboard.state) + ] + if let owner = hmsWhiteboard.owner { + result["owner"] = HMSDecoder.getHmsPeerSubset(owner) + } + if let title = hmsWhiteboard.title { + result["title"] = title + } + if let urlString = hmsWhiteboard.url?.absoluteString { + result["url"] = urlString + } + return result + } + + static func getWhiteboardState(_ state: HMSWhiteboard.WhiteboardState) -> String { + switch state { + case .started: + return "STARTED" + case .stopped: + return "STOPPED" + @unknown default: + print("@unknown default case: Invalid HMSWhiteboardUpdateType") + return "STOPPED" + } + } + + static func getWhiteboardUpdateType(_ type: HMSWhiteboardUpdateType) -> String { + switch type { + case .started: + return "STARTED" + case .stopped: + return "STOPPED" + @unknown default: + print("@unknown default case: Invalid HMSWhiteboardUpdateType") + return "STOPPED" + } + } } diff --git a/packages/react-native-hms/ios/HMSManager.m b/packages/react-native-hms/ios/HMSManager.m index ad0bfd0cb..e111f3f63 100644 --- a/packages/react-native-hms/ios/HMSManager.m +++ b/packages/react-native-hms/ios/HMSManager.m @@ -353,4 +353,16 @@ @interface RCT_EXTERN_MODULE (HMSManager, RCTEventEmitter) : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) +#pragma mark - Interactivity Center - Whiteboard + +RCT_EXTERN_METHOD(startWhiteboard + : (NSDictionary)data + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) + +RCT_EXTERN_METHOD(stopWhiteboard + : (NSDictionary)data + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) + @end diff --git a/packages/react-native-hms/ios/HMSManager.swift b/packages/react-native-hms/ios/HMSManager.swift index 23849d530..598c5802c 100644 --- a/packages/react-native-hms/ios/HMSManager.swift +++ b/packages/react-native-hms/ios/HMSManager.swift @@ -37,7 +37,7 @@ class HMSManager: RCTEventEmitter { } override func supportedEvents() -> [String]! { - return [ON_JOIN, ON_PREVIEW, ON_ROOM_UPDATE, ON_PEER_UPDATE, ON_TRACK_UPDATE, ON_ERROR, ON_MESSAGE, ON_SPEAKER, RECONNECTING, RECONNECTED, ON_ROLE_CHANGE_REQUEST, ON_CHANGE_TRACK_STATE_REQUEST, ON_REMOVED_FROM_ROOM, ON_RTC_STATS, ON_LOCAL_AUDIO_STATS, ON_LOCAL_VIDEO_STATS, ON_REMOTE_AUDIO_STATS, ON_REMOTE_VIDEO_STATS, ON_AUDIO_DEVICE_CHANGED, HMSConstants.ON_SESSION_STORE_AVAILABLE, HMSConstants.ON_SESSION_STORE_CHANGED, HMSConstants.ON_PEER_LIST_UPDATED, HMSConstants.ON_POLL_UPDATE] + return [ON_JOIN, ON_PREVIEW, ON_ROOM_UPDATE, ON_PEER_UPDATE, ON_TRACK_UPDATE, ON_ERROR, ON_MESSAGE, ON_SPEAKER, RECONNECTING, RECONNECTED, ON_ROLE_CHANGE_REQUEST, ON_CHANGE_TRACK_STATE_REQUEST, ON_REMOVED_FROM_ROOM, ON_RTC_STATS, ON_LOCAL_AUDIO_STATS, ON_LOCAL_VIDEO_STATS, ON_REMOTE_AUDIO_STATS, ON_REMOTE_VIDEO_STATS, ON_AUDIO_DEVICE_CHANGED, HMSConstants.ON_SESSION_STORE_AVAILABLE, HMSConstants.ON_SESSION_STORE_CHANGED, HMSConstants.ON_PEER_LIST_UPDATED, HMSConstants.ON_POLL_UPDATE, HMSConstants.ON_WHITEBOARD_UPDATE] } // MARK: - HMS SDK Delegate Callbacks @@ -762,4 +762,23 @@ class HMSManager: RCTEventEmitter { } rnsdk.isNoiseCancellationPluginAvailable(data, resolve, reject) } + + // MARK: - Interactivity Center - Whiteboard + @objc + func startWhiteboard(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let rnsdk = HMSHelper.getHms(data, hmsCollection), let interactivity = rnsdk.interactivity else { + reject?("6004", "HMSRNSDK instance not found!", nil) + return + } + interactivity.startWhiteboard(resolve, reject) + } + + @objc + func stopWhiteboard(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let rnsdk = HMSHelper.getHms(data, hmsCollection), let interactivity = rnsdk.interactivity else { + reject?("6004", "HMSRNSDK instance not found!", nil) + return + } + interactivity.stopWhiteboard(resolve, reject) + } } diff --git a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift index abccab8b5..b4f7c4d83 100644 --- a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift +++ b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift @@ -27,8 +27,27 @@ class HMSRNInteractivityCenter { ["update": update.rawValue, "updatedPoll": HMSInteractivityDecoder.getHMSPoll(updatedPoll)] ) } + + hmssdk.interactivityCenter.addWhiteboardUpdateListener { [weak self] hmsWhiteboard, hmsWhiteboardUpdateType in + guard let self = self else { return } + guard let enabledEvents = self.hmsrnsdk?.eventsEnableStatus, enabledEvents[HMSConstants.ON_WHITEBOARD_UPDATE] == true else { + print("HMSConstants.ON_WHITEBOARD_UPDATE event is not enabled") + return + } + var hmsWhiteboardDict = HMSInteractivityDecoder.getHMSWhiteboard(hmsWhiteboard) + hmsWhiteboardDict["isOwner"] = hmsWhiteboard.owner?.peerID == self.hmssdk?.localPeer?.peerID + + self.hmsrnsdk?.delegate?.emitEvent( + HMSConstants.ON_WHITEBOARD_UPDATE, + [ + "hmsWhiteboard": hmsWhiteboardDict, + "updateType": HMSInteractivityDecoder.getWhiteboardUpdateType(hmsWhiteboardUpdateType) + ] + ) + } } + // MARK: Poll Methods func quickStartPoll(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { let pollBuilder = HMSInteractivityHelper.getPollBuilderFromDict(data, sdkRoles: hmssdk?.roles) @@ -117,4 +136,26 @@ class HMSRNInteractivityCenter { } } } + + // MARK: - Whiteboard Methods + + func startWhiteboard(_ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + self.hmssdk?.interactivityCenter.startWhiteboard { success, error in + if let error = error { + reject?("6004", error.localizedDescription, nil) + return + } + resolve?(success) + } + } + + func stopWhiteboard(_ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + self.hmssdk?.interactivityCenter.stopWhiteboard { success, error in + if let error = error { + reject?("6004", error.localizedDescription, nil) + return + } + resolve?(success) + } + } } diff --git a/packages/react-native-hms/package-lock.json b/packages/react-native-hms/package-lock.json index 47cbf74ef..e7f0611fc 100644 --- a/packages/react-native-hms/package-lock.json +++ b/packages/react-native-hms/package-lock.json @@ -1,12 +1,12 @@ { "name": "@100mslive/react-native-hms", - "version": "1.10.4", + "version": "1.10.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@100mslive/react-native-hms", - "version": "1.10.4", + "version": "1.10.5", "license": "MIT", "dependencies": { "zustand": "^4.3.8" @@ -35,15 +35,6 @@ "react-native": "*" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -247,9 +238,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -5655,13 +5646,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -5691,12 +5682,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6063,9 +6054,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", "dev": true, "funding": [ { @@ -6673,9 +6664,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", "dev": true }, "node_modules/debug": { @@ -6963,9 +6954,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.745", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.745.tgz", - "integrity": "sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==", + "version": "1.4.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", + "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==", "dev": true }, "node_modules/emittery": { @@ -7018,9 +7009,9 @@ } }, "node_modules/envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -7142,14 +7133,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -7441,9 +7432,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "engines": { "node": ">=10" @@ -11572,9 +11563,9 @@ } }, "node_modules/joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz", + "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==", "dev": true, "dependencies": { "@hapi/hoek": "^9.3.0", @@ -13434,17 +13425,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -16982,21 +16973,22 @@ } }, "node_modules/use-subscription": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.0.tgz", - "integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.2.tgz", + "integrity": "sha512-yC2ShScvQ1lAGRp5Y6pz1MqBIU81REfJ/sQIe16BCgKK9mRlZCnU90uY0alKsN6e/Next0vXTsvH3HbAfdH68w==", "dev": true, "dependencies": { - "use-sync-external-store": "^1.2.0" + "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "dev": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -17285,6 +17277,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -17588,6 +17589,14 @@ "optional": true } } + }, + "node_modules/zustand/node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } } } } diff --git a/packages/react-native-hms/package.json b/packages/react-native-hms/package.json index 74878d3e4..2c3b3b7fe 100644 --- a/packages/react-native-hms/package.json +++ b/packages/react-native-hms/package.json @@ -1,6 +1,6 @@ { "name": "@100mslive/react-native-hms", - "version": "1.10.4", + "version": "1.10.5", "description": "Integrate Real Time Audio and Video conferencing, Interactive Live Streaming, and Chat in your apps with 100ms React Native SDK. With support for HLS and RTMP Live Streaming and Recording, Picture-in-Picture (PiP), one-to-one Video Call Modes, Audio Rooms, Video Player and much more, add immersive real-time communications to your apps.", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/packages/react-native-hms/sdk-versions.json b/packages/react-native-hms/sdk-versions.json index 0da94f60f..ef75db6c4 100644 --- a/packages/react-native-hms/sdk-versions.json +++ b/packages/react-native-hms/sdk-versions.json @@ -1,7 +1,7 @@ { - "ios": "1.9.0", + "ios": "1.10.0", "iOSBroadcastExtension": "0.0.9", "iOSHMSHLSPlayer": "0.0.2", "iOSNoiseCancellationModels": "1.0.0", - "android": "2.9.54" + "android": "2.9.56" } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts index fb3e39488..1c0ee615a 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts @@ -12,6 +12,14 @@ import { HMSInteractivityEncoder } from './HMSInteractivityEncoder'; import { HMSHelper } from './HMSHelper'; import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; +import type { HMSWhiteboardUpdateType } from './whiteboard/HMSWhiteboardUpdateType'; +import type { HMSWhiteboard } from './whiteboard/HMSWhiteboard'; +import { HMSWhiteboardListenerActions } from './whiteboard/HMSWhiteboardListenerActions'; +import { + WhiteboardUpdateListener, + registerWhiteboardUpdateListener, + unregisterWhiteboardUpdateListener, +} from './whiteboard/registerCallbacks'; type PollUpdateListener = (data: { updatedPoll: HMSPoll; @@ -56,6 +64,26 @@ function unregisterPollUpdateListener() { export class HMSInteractivityCenter { private _eventEmitter = new EventEmitter(); + private onUpdateListenerRemoved(eventType: string) { + if (eventType === HMSPollsListenerActions.ON_POLL_UPDATE) { + unregisterPollUpdateListener(); + } else if ( + eventType === HMSWhiteboardListenerActions.ON_WHITEBOARD_UPDATE + ) { + unregisterWhiteboardUpdateListener(); + } else { + console.warn('Unknown update listener removed: ', eventType); + } + } + + constructor() { + this._eventEmitter.registerOnAllListenersRemoved( + this.onUpdateListenerRemoved + ); + } + + //#region Poll Methods & Listeners + private _pollUpdateListener = (...args: Parameters) => { const { updatedPoll, update } = args[0]; logger?.verbose('#Listener ON_POLL_UPDATE', { @@ -69,16 +97,6 @@ export class HMSInteractivityCenter { ); }; - private _onAllPollUpdateListenerRemoved = () => { - unregisterPollUpdateListener(); - }; - - constructor() { - this._eventEmitter.registerOnAllListenersRemoved( - this._onAllPollUpdateListenerRemoved - ); - } - /** * Adds a listener for poll updates * @param listener - Callback to be called when a poll is updated @@ -164,4 +182,65 @@ export class HMSInteractivityCenter { await HMSManager.fetchLeaderboard(data); return HMSInteractivityEncoder.transformPollLeaderboardResponse(response); } + //#endregion Poll Methods & Listeners + + //#region Whiteboard Methods & Listeners + + private _whiteboardUpdateListener = ( + ...args: Parameters + ) => { + const { hmsWhiteboard, updateType } = args[0]; + logger?.verbose('#Listener ON_WHITEBOARD_UPDATE', { + updateType, + hmsWhiteboard, + }); + this._eventEmitter.emit( + HMSWhiteboardListenerActions.ON_WHITEBOARD_UPDATE, + HMSInteractivityEncoder.transformHMSWhiteboard(hmsWhiteboard), + updateType + ); + }; + + /** + * Adds a listener for Whiteboard updates + * @param listener - Callback to be called when whiteboard is updated + * @returns HMSEventSubscription + */ + addWhiteboardUpdateListener( + listener: ( + hmsWhiteboard: HMSWhiteboard, + updateType: HMSWhiteboardUpdateType + ) => void + ) { + registerWhiteboardUpdateListener(this._whiteboardUpdateListener); + return this._eventEmitter.addListener( + HMSWhiteboardListenerActions.ON_WHITEBOARD_UPDATE, + listener, + null + ); + } + + /** + * Starts Whiteboard + */ + async startWhiteboard(title: string) { + const data = { + id: HMSConstants.DEFAULT_SDK_ID, + title, + }; + logger?.verbose('#Function startWhiteboard', data); + return HMSManager.startWhiteboard(data); + } + + /** + * Stops Whiteboard + */ + async stopWhiteboard() { + const data = { + id: HMSConstants.DEFAULT_SDK_ID, + }; + logger?.verbose('#Function stopWhiteboard', data); + return HMSManager.stopWhiteboard(data); + } + //#endregion Whiteboard Methods & Listeners } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts index d45ccc667..f531138ad 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts @@ -2,6 +2,7 @@ import { HMSEncoder } from './HMSEncoder'; import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; import type { HMSPoll } from './polls/HMSPoll'; import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; +import type { HMSWhiteboard } from './whiteboard/HMSWhiteboard'; export class HMSInteractivityEncoder { static transformPoll(poll: HMSPoll): HMSPoll { @@ -81,4 +82,11 @@ export class HMSInteractivityEncoder { return decodedPollLeaderboardResponse as PollLeaderboardResponse; } + + static transformHMSWhiteboard(hmsWhiteboard: HMSWhiteboard): HMSWhiteboard { + if (hmsWhiteboard.owner) { + hmsWhiteboard.owner = HMSEncoder.encodeHmsPeer(hmsWhiteboard.owner); + } + return hmsWhiteboard; + } } diff --git a/packages/react-native-hms/src/classes/HMSPermissions.ts b/packages/react-native-hms/src/classes/HMSPermissions.ts index e6277f8dc..7c995f30f 100644 --- a/packages/react-native-hms/src/classes/HMSPermissions.ts +++ b/packages/react-native-hms/src/classes/HMSPermissions.ts @@ -1,3 +1,9 @@ +export interface HMSWhiteboardPermission { + admin?: boolean; + write?: boolean; + read?: boolean; +} + export class HMSPermissions { endRoom?: boolean; removeOthers?: boolean; @@ -9,6 +15,7 @@ export class HMSPermissions { rtmpStreaming?: boolean; pollRead?: boolean; pollWrite?: boolean; + whiteboard?: HMSWhiteboardPermission; constructor(params?: { endRoom?: boolean; @@ -21,6 +28,7 @@ export class HMSPermissions { rtmpStreaming?: boolean; pollRead?: boolean; pollWrite?: boolean; + whiteboard?: HMSWhiteboardPermission; }) { if (params) { this.endRoom = params.endRoom; @@ -33,6 +41,7 @@ export class HMSPermissions { this.rtmpStreaming = params.rtmpStreaming; this.pollRead = params.pollRead; this.pollWrite = params.pollWrite; + this.whiteboard = params.whiteboard; } } } diff --git a/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboard.tsx b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboard.tsx new file mode 100644 index 000000000..13139cf6d --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboard.tsx @@ -0,0 +1,16 @@ +import type { HMSPeer } from '../HMSPeer'; +import type { HMSWhiteboardState } from './HMSWhiteboardState'; + +export interface HMSWhiteboard { + id: string; + + title?: string; + + state: HMSWhiteboardState; + + isOwner: boolean; + + owner?: HMSPeer; + + url?: string; +} diff --git a/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardListenerActions.ts b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardListenerActions.ts new file mode 100644 index 000000000..b28037dfe --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardListenerActions.ts @@ -0,0 +1,3 @@ +export enum HMSWhiteboardListenerActions { + ON_WHITEBOARD_UPDATE = 'ON_WHITEBOARD_UPDATE', +} diff --git a/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardState.tsx b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardState.tsx new file mode 100644 index 000000000..eb9f12a47 --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardState.tsx @@ -0,0 +1,4 @@ +export enum HMSWhiteboardState { + STARTED = 'STARTED', + STOPPED = 'STOPPED', +} diff --git a/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardUpdateType.tsx b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardUpdateType.tsx new file mode 100644 index 000000000..f0285212a --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/HMSWhiteboardUpdateType.tsx @@ -0,0 +1,4 @@ +export enum HMSWhiteboardUpdateType { + STARTED = 'STARTED', + STOPPED = 'STOPPED', +} diff --git a/packages/react-native-hms/src/classes/whiteboard/index.ts b/packages/react-native-hms/src/classes/whiteboard/index.ts new file mode 100644 index 000000000..43b7cd4d3 --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/index.ts @@ -0,0 +1,3 @@ +export * from './HMSWhiteboard'; +export * from './HMSWhiteboardUpdateType'; +export * from './HMSWhiteboardListenerActions'; diff --git a/packages/react-native-hms/src/classes/whiteboard/registerCallbacks.ts b/packages/react-native-hms/src/classes/whiteboard/registerCallbacks.ts new file mode 100644 index 000000000..ff12c124b --- /dev/null +++ b/packages/react-native-hms/src/classes/whiteboard/registerCallbacks.ts @@ -0,0 +1,34 @@ +import { HMSConstants } from '../HMSConstants'; +import type { HMSEventSubscription } from '../HMSNativeEventEmitter'; +import HMSNativeEventListener from '../HMSNativeEventListener'; +import type { HMSWhiteboard } from './HMSWhiteboard'; +import { HMSWhiteboardListenerActions } from './HMSWhiteboardListenerActions'; +import type { HMSWhiteboardUpdateType } from './HMSWhiteboardUpdateType'; + +export type WhiteboardUpdateListener = (data: { + hmsWhiteboard: HMSWhiteboard; + updateType: HMSWhiteboardUpdateType; +}) => void; + +let whiteboardUpdateSubscription: null | HMSEventSubscription = null; + +export function registerWhiteboardUpdateListener( + listener: WhiteboardUpdateListener +) { + if (whiteboardUpdateSubscription !== null) { + return; + } + whiteboardUpdateSubscription = HMSNativeEventListener.addListener( + HMSConstants.DEFAULT_SDK_ID, + HMSWhiteboardListenerActions.ON_WHITEBOARD_UPDATE, + listener + ); +} + +export function unregisterWhiteboardUpdateListener() { + if (whiteboardUpdateSubscription === null) { + return; + } + whiteboardUpdateSubscription.remove(); + whiteboardUpdateSubscription = null; +} diff --git a/packages/react-native-hms/src/index.ts b/packages/react-native-hms/src/index.ts index 6242ba40c..92b58afa7 100644 --- a/packages/react-native-hms/src/index.ts +++ b/packages/react-native-hms/src/index.ts @@ -99,6 +99,7 @@ export type { HMSPIPConfig } from './classes/HMSPIPConfig'; export { HMSRecordingState } from './classes/HMSRecordingState'; export type { HMSPoll } from './classes/polls/HMSPoll'; export * from './classes/HMSNoiseCancellationPlugin'; +export * from './classes/whiteboard'; export { HMSPollQuestionType } from './classes/polls/HMSPollQuestionType'; export { HMSPollType } from './classes/polls/HMSPollType'; diff --git a/packages/react-native-room-kit/example/ExampleAppChangelog.txt b/packages/react-native-room-kit/example/ExampleAppChangelog.txt index 77bf7e5e8..a9605b3d4 100644 --- a/packages/react-native-room-kit/example/ExampleAppChangelog.txt +++ b/packages/react-native-room-kit/example/ExampleAppChangelog.txt @@ -1,18 +1,15 @@ Board: https://100ms.atlassian.net/jira/software/projects/RN/boards/33 -- Captions in HLS Player -https://100ms.atlassian.net/browse/RN-267 +- Handle PIP for HLS viewer +https://100ms.atlassian.net/browse/RN-296 -- Header + Description from Layout API in Description Pane -https://100ms.atlassian.net/browse/RN-273 +- Whiteboard Base SDK changes +https://100ms.atlassian.net/browse/RN-306 -- Chat Messages starting from the Top -https://100ms.atlassian.net/browse/RN-275 +- Tile content cutting off from bottom in WebRTC layout +https://100ms.atlassian.net/browse/RN-316 -- New Chat Messages design for HLS Player -https://100ms.atlassian.net/browse/RN-276 - -Room Kit: 1.1.7 -React Native SDK: 1.10.4 -Android SDK: 2.9.53 -iOS SDK: 1.8.0 +Room Kit: 1.1.8 +React Native SDK: 1.10.5 +Android SDK: 2.9.55 +iOS SDK: 1.9.0 diff --git a/packages/react-native-room-kit/example/android/app/build.gradle b/packages/react-native-room-kit/example/android/app/build.gradle index b66165b76..ee295e4cf 100644 --- a/packages/react-native-room-kit/example/android/app/build.gradle +++ b/packages/react-native-room-kit/example/android/app/build.gradle @@ -136,8 +136,8 @@ android { applicationId "live.hms.rn" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 470 - versionName "2.4.20" + versionCode 489 + versionName "2.4.39" missingDimensionStrategy 'react-native-camera', 'general' } diff --git a/packages/react-native-room-kit/example/ios/Podfile.lock b/packages/react-native-room-kit/example/ios/Podfile.lock index cfc28ff88..10a3242e8 100644 --- a/packages/react-native-room-kit/example/ios/Podfile.lock +++ b/packages/react-native-room-kit/example/ios/Podfile.lock @@ -80,10 +80,10 @@ PODS: - HMSHLSPlayerSDK (0.0.2): - HMSAnalyticsSDK (= 0.0.2) - HMSNoiseCancellationModels (1.0.0) - - HMSSDK (1.9.0): + - HMSSDK (1.10.0): - HMSAnalyticsSDK (= 0.0.2) - - HMSWebRTC (= 1.0.6168) - - HMSWebRTC (1.0.6168) + - HMSWebRTC (= 1.0.6169) + - HMSWebRTC (1.0.6169) - libevent (2.1.12) - lottie-ios (3.4.4) - lottie-react-native (5.1.6): @@ -319,11 +319,11 @@ PODS: - React-Core - react-native-camera/RN (4.2.1): - React-Core - - react-native-hms (1.10.4): + - react-native-hms (1.10.5): - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) - HMSNoiseCancellationModels (= 1.0.0) - - HMSSDK (= 1.9.0) + - HMSSDK (= 1.10.0) - React-Core - react-native-lottie-splash-screen (1.1.1): - React @@ -332,6 +332,8 @@ PODS: - react-native-simple-toast (1.1.3): - React-Core - Toast (~> 4.0.0) + - react-native-webview (13.8.7): + - React-Core - React-perflogger (0.67.4) - React-RCTActionSheet (0.67.4): - React-Core/RCTActionSheetHeaders (= 0.67.4) @@ -500,6 +502,7 @@ DEPENDENCIES: - react-native-lottie-splash-screen (from `../node_modules/react-native-lottie-splash-screen`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-simple-toast (from `../node_modules/react-native-simple-toast`) + - react-native-webview (from `../node_modules/react-native-webview`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -605,6 +608,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safe-area-context" react-native-simple-toast: :path: "../node_modules/react-native-simple-toast" + react-native-webview: + :path: "../node_modules/react-native-webview" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -671,8 +676,8 @@ SPEC CHECKSUMS: HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 HMSNoiseCancellationModels: a3bda1405a16015632f4bcabd46ce48f35103b02 - HMSSDK: 96bdafc1c610aabfecd1155ad7e3c1bc45b3a6cb - HMSWebRTC: a302f0d6c94f7bee94f3265adb7bb1c6569e7ee5 + HMSSDK: fbbdebf673baba7f98f3fa13241b4249929ad681 + HMSWebRTC: 8f51ba33a0e505e17ebf3d7b37bcdca266751a13 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 lottie-ios: 8f97d3271e155c2d688875c29cd3c74908aef5f8 lottie-react-native: 8f9d4be452e23f6e5ca0fdc11669dc99ab52be81 @@ -694,10 +699,11 @@ SPEC CHECKSUMS: React-logger: a1f028f6d8639a3f364ef80419e5e862e1115250 react-native-blur: 172abeaa2de2d3ba4dc586fa23488d01c533818f react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f - react-native-hms: 1acd9c4961304f0508551898aee37dd6d5f877b8 + react-native-hms: 028c8232d459fe2cb25826d4313a8e3d918b503d react-native-lottie-splash-screen: 015423265bac5f46016dff2e31c97b9590808856 react-native-safe-area-context: 61c8c484a3a9e7d1fda19f7b1794b35bbfd2262a react-native-simple-toast: bf002828cf816775a6809f7a9ec3907509bce11f + react-native-webview: abfd4e89ab3f5c2cc2acaeb54633795b0d9a4ab0 React-perflogger: 0afaf2f01a47fd0fc368a93bfbb5bd3b26db6e7f React-RCTActionSheet: 59f35c4029e0b532fc42114241a06e170b7431a2 React-RCTAnimation: aae4f4bed122e78bdab72f7118d291d70a932ce2 diff --git a/packages/react-native-room-kit/example/ios/RNExample.xcodeproj/project.pbxproj b/packages/react-native-room-kit/example/ios/RNExample.xcodeproj/project.pbxproj index b901af484..3e6a3652e 100644 --- a/packages/react-native-room-kit/example/ios/RNExample.xcodeproj/project.pbxproj +++ b/packages/react-native-room-kit/example/ios/RNExample.xcodeproj/project.pbxproj @@ -502,7 +502,7 @@ CODE_SIGN_ENTITLEMENTS = RNExample/RNExample.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 470; + CURRENT_PROJECT_VERSION = 482; DEVELOPMENT_TEAM = 5N85PP82A9; ENABLE_BITCODE = NO; INFOPLIST_FILE = RNExample/Info.plist; @@ -540,7 +540,7 @@ CODE_SIGN_ENTITLEMENTS = RNExample/RNExample.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 470; + CURRENT_PROJECT_VERSION = 482; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5N85PP82A9; INFOPLIST_FILE = RNExample/Info.plist; @@ -703,7 +703,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = RNExampleBroadcastUpload/RNExampleBroadcastUpload.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 470; + CURRENT_PROJECT_VERSION = 482; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 5N85PP82A9; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -745,7 +745,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 470; + CURRENT_PROJECT_VERSION = 482; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5N85PP82A9; diff --git a/packages/react-native-room-kit/example/ios/RNExample/Info.plist b/packages/react-native-room-kit/example/ios/RNExample/Info.plist index 425dc25bd..99499d869 100644 --- a/packages/react-native-room-kit/example/ios/RNExample/Info.plist +++ b/packages/react-native-room-kit/example/ios/RNExample/Info.plist @@ -21,11 +21,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.4.20 + 2.4.32 CFBundleSignature ???? CFBundleVersion - 470 + 482 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/packages/react-native-room-kit/example/package-lock.json b/packages/react-native-room-kit/example/package-lock.json index db985b4e7..b4590b899 100644 --- a/packages/react-native-room-kit/example/package-lock.json +++ b/packages/react-native-room-kit/example/package-lock.json @@ -1,12 +1,12 @@ { "name": "RNExample", - "version": "1.1.7", + "version": "1.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "RNExample", - "version": "1.1.7", + "version": "1.1.8", "dependencies": { "@react-native-async-storage/async-storage": "1.17.11", "@react-native-community/blur": "^4.3.2", @@ -30,6 +30,7 @@ "react-native-safe-area-context": "3.3.0", "react-native-screens": "3.25.0", "react-native-simple-toast": "1.1.3", + "react-native-webview": "^13.8.7", "react-redux": "8.1.1", "redux": "4.2.1" }, @@ -51,15 +52,6 @@ "typescript": "^4.4.4" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -211,9 +203,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -5495,12 +5487,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -5520,11 +5512,11 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5854,9 +5846,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", "funding": [ { "type": "opencollective", @@ -6349,9 +6341,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "node_modules/debug": { "version": "4.3.4", @@ -6569,9 +6561,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.745", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.745.tgz", - "integrity": "sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==" + "version": "1.4.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", + "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==" }, "node_modules/emittery": { "version": "0.7.2", @@ -6620,9 +6612,9 @@ } }, "node_modules/envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "bin": { "envinfo": "dist/cli.js" }, @@ -6740,14 +6732,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -7037,9 +7029,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "engines": { "node": ">=10" @@ -10835,9 +10827,9 @@ } }, "node_modules/joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz", + "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -12550,17 +12542,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -12763,9 +12755,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -13421,6 +13413,27 @@ "resolved": "https://registry.npmjs.org/react-native-simple-toast/-/react-native-simple-toast-1.1.3.tgz", "integrity": "sha512-bkZy25axqlU4L6IoTysSl5KOQA7qdxzivbXz/L/yAw9g9fENxjzYvUUtv5wWtgq7mzOe5HiJ7GCQrOl3MhIevQ==" }, + "node_modules/react-native-webview": { + "version": "13.8.7", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.8.7.tgz", + "integrity": "sha512-r8y+qlyh2+mtuPhOvgPB9Ccn2itDXacvaVFuB61AYTfisz1YhJ57iFEE8j32DfDpvl6NhaaFIzzHsumwJk92bQ==", + "dependencies": { + "escape-string-regexp": "2.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-webview/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/react-native/node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -13473,9 +13486,9 @@ } }, "node_modules/react-redux/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-refresh": { "version": "0.4.3", @@ -15876,20 +15889,20 @@ } }, "node_modules/use-subscription": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.0.tgz", - "integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.2.tgz", + "integrity": "sha512-yC2ShScvQ1lAGRp5Y6pz1MqBIU81REfJ/sQIe16BCgKK9mRlZCnU90uY0alKsN6e/Next0vXTsvH3HbAfdH68w==", "dependencies": { - "use-sync-external-store": "^1.2.0" + "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -16160,6 +16173,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", diff --git a/packages/react-native-room-kit/example/package.json b/packages/react-native-room-kit/example/package.json index c866fca67..bb7ffb520 100644 --- a/packages/react-native-room-kit/example/package.json +++ b/packages/react-native-room-kit/example/package.json @@ -1,6 +1,6 @@ { "name": "RNExample", - "version": "1.1.7", + "version": "1.1.8", "private": true, "scripts": { "android": "react-native run-android", @@ -32,6 +32,7 @@ "react-native-safe-area-context": "3.3.0", "react-native-screens": "3.25.0", "react-native-simple-toast": "1.1.3", + "react-native-webview": "^13.8.7", "react-redux": "8.1.1", "redux": "4.2.1" }, diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index bce0d9b78..5e5e2be4a 100644 --- a/packages/react-native-room-kit/package-lock.json +++ b/packages/react-native-room-kit/package-lock.json @@ -1,12 +1,12 @@ { "name": "@100mslive/react-native-room-kit", - "version": "1.1.7", + "version": "1.1.8", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@100mslive/react-native-room-kit", - "version": "1.1.7", + "version": "1.1.8", "license": "MIT", "dependencies": { "@100mslive/types-prebuilt": "^0.12.8", @@ -40,7 +40,7 @@ "node": ">= 16.0.0" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.10.4", + "@100mslive/react-native-hms": "1.10.5", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3", @@ -52,13 +52,14 @@ "react-native-modal": "^12.1.0", "react-native-reanimated": ">=2.17.0", "react-native-safe-area-context": "^3.3.0", - "react-native-simple-toast": "^1.1.3" + "react-native-simple-toast": "^1.1.3", + "react-native-webview": "^13.8.7" } }, "node_modules/@100mslive/react-native-hms": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.4.tgz", - "integrity": "sha512-nCf+0Y+1cSSUBIACviSkjdwBgBElmoD+4QpGv0wHE9PNsdeO8QHWj9ceFlVcPvjQVCTM/5S3STpeM540DWGuZw==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.5.tgz", + "integrity": "sha512-yBV2Y/FRY8bfZI+32TIgWokIEp0sAXoR6gbXK1zMPqgSXqvwJ8vLvbGTXVuJpwZ9TvCaje8CO5pCC891KmQoDg==", "peer": true, "dependencies": { "zustand": "^4.3.8" @@ -73,15 +74,6 @@ "resolved": "https://registry.npmjs.org/@100mslive/types-prebuilt/-/types-prebuilt-0.12.8.tgz", "integrity": "sha512-W1ISh3Mk8/wkomeFiBte7HZLk1gJocnN5U0N8rzZ9WFdDlAW7q/hKgnh+X1/9QxVcv3USfuZyKotbZ7AXmvCiQ==" }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -251,9 +243,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -6579,12 +6571,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -6604,11 +6596,11 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -7178,9 +7170,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==", "funding": [ { "type": "opencollective", @@ -7259,9 +7251,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, "node_modules/class-utils": { @@ -8213,9 +8205,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "node_modules/debug": { "version": "4.3.4", @@ -8926,9 +8918,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.745", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.745.tgz", - "integrity": "sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==" + "version": "1.4.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", + "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==" }, "node_modules/emittery": { "version": "0.10.2", @@ -8964,9 +8956,9 @@ } }, "node_modules/envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "bin": { "envinfo": "dist/cli.js" }, @@ -9110,14 +9102,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -9494,9 +9486,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "engines": { "node": ">=10" @@ -14304,9 +14296,9 @@ } }, "node_modules/joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz", + "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -17184,17 +17176,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -17723,9 +17715,9 @@ } }, "node_modules/pretty-format/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "node_modules/process-nextick-args": { @@ -18328,9 +18320,9 @@ } }, "node_modules/react-native-reanimated": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.8.1.tgz", - "integrity": "sha512-EdM0vr3JEaNtqvstqESaPfOBy0gjYBkr1iEolWJ82Ax7io8y9OVUIphgsLKTB36CtR1XtmBw0RZVj7KArc7ZVA==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.9.0.tgz", + "integrity": "sha512-OMZV2BVmxZvm8UhlXBrESO0y/ODGTRpQRQUO7U9QXysOF9RaR8FbO6KS0x99MH19zfFTV8cLGN/vYW1dFia9Rw==", "peer": true, "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", @@ -18382,6 +18374,29 @@ "integrity": "sha512-7D8o8L445XDz7Rdh0pMgCIWuevv1FnGyuD7F8Nz/XhzMInmU4jL5VFJI25VVqQ2uGTaUSuo2ogXSgKnv6p9NJg==", "peer": true }, + "node_modules/react-native-webview": { + "version": "13.8.7", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.8.7.tgz", + "integrity": "sha512-r8y+qlyh2+mtuPhOvgPB9Ccn2itDXacvaVFuB61AYTfisz1YhJ57iFEE8j32DfDpvl6NhaaFIzzHsumwJk92bQ==", + "peer": true, + "dependencies": { + "escape-string-regexp": "2.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-webview/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/react-native/node_modules/@jest/types": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", @@ -21802,20 +21817,20 @@ } }, "node_modules/use-subscription": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.0.tgz", - "integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.2.tgz", + "integrity": "sha512-yC2ShScvQ1lAGRp5Y6pz1MqBIU81REfJ/sQIe16BCgKK9mRlZCnU90uY0alKsN6e/Next0vXTsvH3HbAfdH68w==", "dependencies": { - "use-sync-external-store": "^1.2.0" + "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -22370,13 +22385,22 @@ "optional": true } } + }, + "node_modules/zustand/node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } } }, "dependencies": { "@100mslive/react-native-hms": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.4.tgz", - "integrity": "sha512-nCf+0Y+1cSSUBIACviSkjdwBgBElmoD+4QpGv0wHE9PNsdeO8QHWj9ceFlVcPvjQVCTM/5S3STpeM540DWGuZw==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.5.tgz", + "integrity": "sha512-yBV2Y/FRY8bfZI+32TIgWokIEp0sAXoR6gbXK1zMPqgSXqvwJ8vLvbGTXVuJpwZ9TvCaje8CO5pCC891KmQoDg==", "peer": true, "requires": { "zustand": "^4.3.8" @@ -22387,12 +22411,6 @@ "resolved": "https://registry.npmjs.org/@100mslive/types-prebuilt/-/types-prebuilt-0.12.8.tgz", "integrity": "sha512-W1ISh3Mk8/wkomeFiBte7HZLk1gJocnN5U0N8rzZ9WFdDlAW7q/hKgnh+X1/9QxVcv3USfuZyKotbZ7AXmvCiQ==" }, - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -22515,9 +22533,9 @@ } }, "@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "requires": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -27164,12 +27182,12 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "requires": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" } }, @@ -27183,11 +27201,11 @@ } }, "babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "requires": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" } }, "babel-plugin-syntax-trailing-function-commas": { @@ -27583,9 +27601,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==" + "version": "1.0.30001614", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz", + "integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==" }, "capture-exit": { "version": "2.0.0", @@ -27631,9 +27649,9 @@ "dev": true }, "cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", "dev": true }, "class-utils": { @@ -28353,9 +28371,9 @@ "dev": true }, "dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "debug": { "version": "4.3.4", @@ -28833,9 +28851,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.745", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.745.tgz", - "integrity": "sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==" + "version": "1.4.750", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", + "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==" }, "emittery": { "version": "0.10.2", @@ -28862,9 +28880,9 @@ } }, "envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==" + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==" }, "error-ex": { "version": "1.3.2", @@ -28984,14 +29002,14 @@ } }, "es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -29369,9 +29387,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "requires": {} }, @@ -32739,9 +32757,9 @@ "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==" }, "joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.0.tgz", + "integrity": "sha512-9qcrTyoBmFZRNHeVP4edKqIUEgFzq7MHvTNSDuHSqkpOPtiBkgNgcmTSqmiw1kw9tdKaiddvIDv/eCJDxmqWCA==", "requires": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -35001,17 +35019,17 @@ } }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" } }, "options": { @@ -35381,9 +35399,9 @@ "dev": true }, "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true } } @@ -35923,9 +35941,9 @@ } }, "react-native-reanimated": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.8.1.tgz", - "integrity": "sha512-EdM0vr3JEaNtqvstqESaPfOBy0gjYBkr1iEolWJ82Ax7io8y9OVUIphgsLKTB36CtR1XtmBw0RZVj7KArc7ZVA==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.9.0.tgz", + "integrity": "sha512-OMZV2BVmxZvm8UhlXBrESO0y/ODGTRpQRQUO7U9QXysOF9RaR8FbO6KS0x99MH19zfFTV8cLGN/vYW1dFia9Rw==", "peer": true, "requires": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", @@ -35968,6 +35986,24 @@ "integrity": "sha512-7D8o8L445XDz7Rdh0pMgCIWuevv1FnGyuD7F8Nz/XhzMInmU4jL5VFJI25VVqQ2uGTaUSuo2ogXSgKnv6p9NJg==", "peer": true }, + "react-native-webview": { + "version": "13.8.7", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.8.7.tgz", + "integrity": "sha512-r8y+qlyh2+mtuPhOvgPB9Ccn2itDXacvaVFuB61AYTfisz1YhJ57iFEE8j32DfDpvl6NhaaFIzzHsumwJk92bQ==", + "peer": true, + "requires": { + "escape-string-regexp": "2.0.0", + "invariant": "2.2.4" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "peer": true + } + } + }, "react-redux": { "version": "7.2.9", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", @@ -38401,17 +38437,17 @@ "requires": {} }, "use-subscription": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.0.tgz", - "integrity": "sha512-LISuG0/TmmoDoCRmV5XAqYkd3UCBNM0ML3gGBndze65WITcsExCD3DTvXXTLyNcOC0heFQZzluW88bN/oC1DQQ==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.8.2.tgz", + "integrity": "sha512-yC2ShScvQ1lAGRp5Y6pz1MqBIU81REfJ/sQIe16BCgKK9mRlZCnU90uY0alKsN6e/Next0vXTsvH3HbAfdH68w==", "requires": { - "use-sync-external-store": "^1.2.0" + "use-sync-external-store": "^1.2.2" } }, "use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", "requires": {} }, "util-deprecate": { @@ -38813,6 +38849,15 @@ "peer": true, "requires": { "use-sync-external-store": "1.2.0" + }, + "dependencies": { + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peer": true, + "requires": {} + } } } } diff --git a/packages/react-native-room-kit/package.json b/packages/react-native-room-kit/package.json index 553f40a42..d6d7204bd 100644 --- a/packages/react-native-room-kit/package.json +++ b/packages/react-native-room-kit/package.json @@ -1,6 +1,6 @@ { "name": "@100mslive/react-native-room-kit", - "version": "1.1.7", + "version": "1.1.8", "description": "100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.", "main": "lib/commonjs/index", "module": "lib/module/index", @@ -140,7 +140,7 @@ "typescript": "^5.0.2" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.10.4", + "@100mslive/react-native-hms": "1.10.5", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3", @@ -152,7 +152,8 @@ "react-native-modal": "^12.1.0", "react-native-reanimated": ">=2.17.0", "react-native-safe-area-context": "^3.3.0", - "react-native-simple-toast": "^1.1.3" + "react-native-simple-toast": "^1.1.3", + "react-native-webview": "^13.8.7" }, "resolutions": { "@types/react": "17.0.21" diff --git a/packages/react-native-room-kit/src/HMSRoomSetup.tsx b/packages/react-native-room-kit/src/HMSRoomSetup.tsx index e89607189..7648e0549 100644 --- a/packages/react-native-room-kit/src/HMSRoomSetup.tsx +++ b/packages/react-native-room-kit/src/HMSRoomSetup.tsx @@ -4,6 +4,7 @@ import { HMSRoom, HMSTrack, HMSUpdateListenerActions, + HMSWhiteboardUpdateType, } from '@100mslive/react-native-hms'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Alert, Keyboard, StatusBar, StyleSheet, View } from 'react-native'; @@ -22,6 +23,7 @@ import { setInitialRole, setLocalPeerTrackNode, setMiniViewPeerTrackNode, + setWhiteboard, updateLocalPeerTrackNode, } from './redux/actions'; import { createPeerTrackNode, getRandomUserId } from './utils/functions'; @@ -482,6 +484,25 @@ export const HMSRoomSetup = () => { }; }, [isHLSViewer]); + useEffect(() => { + const subscription = + hmsInstance.interactivityCenter.addWhiteboardUpdateListener( + async (hmsWhiteboard, updateType) => { + dispatch( + setWhiteboard( + updateType === HMSWhiteboardUpdateType.STARTED + ? hmsWhiteboard + : null + ) + ); + } + ); + + return () => { + subscription.remove(); + }; + }, []); + // Syncs showing Polls with HLS Player onCue event useHLSCuedPolls(); diff --git a/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board.png b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board.png new file mode 100644 index 000000000..b1a36a219 Binary files /dev/null and b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board.png differ diff --git a/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@2x.png b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@2x.png new file mode 100644 index 000000000..ea0de6915 Binary files /dev/null and b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@2x.png differ diff --git a/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@3x.png b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@3x.png new file mode 100644 index 000000000..6546a9552 Binary files /dev/null and b/packages/react-native-room-kit/src/Icons/Pencil/assets/pencil-board@3x.png differ diff --git a/packages/react-native-room-kit/src/Icons/Pencil/index.tsx b/packages/react-native-room-kit/src/Icons/Pencil/index.tsx index 1382f3e5f..a179f68fa 100644 --- a/packages/react-native-room-kit/src/Icons/Pencil/index.tsx +++ b/packages/react-native-room-kit/src/Icons/Pencil/index.tsx @@ -4,10 +4,13 @@ import type { ImageProps } from 'react-native'; import { useHMSRoomStyle } from '../../hooks-util'; -interface PencilIconProps extends Omit {} +interface PencilIconProps extends Omit { + type?: 'normal' | 'board'; +} export const PencilIcon: React.FC = ({ style, + type = 'normal', ...restProps }) => { const iconStyles = useHMSRoomStyle((theme) => ({ @@ -16,7 +19,11 @@ export const PencilIcon: React.FC = ({ return ( diff --git a/packages/react-native-room-kit/src/components/DisplayView.tsx b/packages/react-native-room-kit/src/components/DisplayView.tsx index 04c4f258d..833e5f78e 100644 --- a/packages/react-native-room-kit/src/components/DisplayView.tsx +++ b/packages/react-native-room-kit/src/components/DisplayView.tsx @@ -31,6 +31,7 @@ import { PreviewForRoleChangeModal } from './PreviewForRoleChangeModal'; import { ChatAndParticipantsBottomSheet } from './ChatAndParticipants'; import { LeaveRoomBottomSheet } from './LeaveRoomBottomSheet'; import { EndRoomModal } from './EndRoomModal'; +import { FullScreenWhiteboard } from './FullScreenWhiteboard'; type CapturedImagePath = { uri: string } | null; @@ -143,6 +144,8 @@ export const DisplayView: React.FC = ({ + + { const { bottom } = useSafeAreaInsets(); return ( - (excludeSafeArea ? 0 : bottom) + (Platform.OS === 'android' ? 16 : 0) + 40 - ); // bottomSafeArea + marginBottom + content + (excludeSafeArea ? 0 : bottom) + + (Platform.OS === 'android' ? 16 : 0) + + 42 + + 16 + ); // bottomSafeArea + marginBottom + content + contentTopPadding }; const styles = StyleSheet.create({ diff --git a/packages/react-native-room-kit/src/components/FullScreenWhiteboard.tsx b/packages/react-native-room-kit/src/components/FullScreenWhiteboard.tsx new file mode 100644 index 000000000..b18cc9705 --- /dev/null +++ b/packages/react-native-room-kit/src/components/FullScreenWhiteboard.tsx @@ -0,0 +1,59 @@ +import * as React from 'react'; +import Modal from 'react-native-modal'; +import { StyleSheet } from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; +import { SafeAreaView } from 'react-native-safe-area-context'; + +import type { RootState } from '../redux'; +import { useHMSRoomColorPalette, useHMSRoomStyle } from '../hooks-util'; +import { setFullScreenWhiteboard } from '../redux/actions'; +import { Whiteboard } from './Whiteboard'; + +export const FullScreenWhiteboard = () => { + const dispatch = useDispatch(); + const fullScreenWhiteboard = useSelector( + (state: RootState) => state.app.fullScreenWhiteboard + ); + + const { background_dim: backgroundDimColor } = useHMSRoomColorPalette(); + + const contentContainerStyles = useHMSRoomStyle((theme) => ({ + backgroundColor: theme.palette.background_dim, + })); + + const handleClosingFullScreenView = () => { + dispatch(setFullScreenWhiteboard(false)); + }; + + return ( + + + + + + ); +}; + +const styles = StyleSheet.create({ + modal: { + margin: 0, + }, + container: { + flexGrow: 1, + }, +}); diff --git a/packages/react-native-room-kit/src/components/GridView.tsx b/packages/react-native-room-kit/src/components/GridView.tsx index ee3b47376..aa1f18ba1 100644 --- a/packages/react-native-room-kit/src/components/GridView.tsx +++ b/packages/react-native-room-kit/src/components/GridView.tsx @@ -16,6 +16,7 @@ import { PaginationDots } from './PaginationDots'; import { setGridViewActivePage } from '../redux/actions'; import { Tile } from './Tile'; import { useIsLandscapeOrientation } from '../utils/dimension'; +import { WhiteboardContainer } from './WhiteboardContainer'; export type GridViewProps = { onPeerTileMorePress(peerTrackNode: PeerTrackNode): void; @@ -52,6 +53,9 @@ export const GridView = React.forwardRef( const screenshareTilesAvailable = useSelector( (state: RootState) => state.app.screensharePeerTrackNodes.length > 0 ); + const whiteboardActive = useSelector( + (state: RootState) => !!state.hmsStates.whiteboard + ); const regularTilesAvailable = pairedPeers.length > 0; const isLandscapeOrientation = useIsLandscapeOrientation(); @@ -147,9 +151,12 @@ export const GridView = React.forwardRef( setHmsViewRefs={setHmsViewRefs} onPeerTileMorePress={onPeerTileMorePress} /> + ) : whiteboardActive ? ( + ) : null} - {screenshareTilesAvailable && isLandscapeOrientation ? null : ( + {(whiteboardActive || screenshareTilesAvailable) && + isLandscapeOrientation ? null : ( state.app.screensharePeerTrackNodes.length > 0 + const screenshareTilesOrWhiteboardActive = useSelector( + (state: RootState) => + state.app.screensharePeerTrackNodes.length > 0 || + !!state.hmsStates.whiteboard ); const activeIndex = useSelector( (state: RootState) => state.app.gridViewActivePage @@ -248,7 +257,7 @@ const RegularTiles = React.forwardRef< ); return ( - + { const isLandscapeOrientation = useIsLandscapeOrientation(); const { chatWrapperConstraints } = useHLSViewsConstraints(); - const hlsFullScreen = useSelector( - (state: RootState) => state.app.hlsFullScreen - ); + const fullScreenMode = useSelector((state: RootState) => { + const hlsFullScreen = state.app.hlsFullScreen; + const isPipModeActive = state.app.pipModeStatus === PipModes.ACTIVE; + return hlsFullScreen || isPipModeActive; + }); const hmsRoomStyles = useHMSRoomStyleSheet((theme) => ({ wrapper: { @@ -24,7 +27,7 @@ export const HLSChatView = () => { }, })); - if (hlsFullScreen) { + if (fullScreenMode) { return null; } diff --git a/packages/react-native-room-kit/src/components/HLSPlayerContainer.tsx b/packages/react-native-room-kit/src/components/HLSPlayerContainer.tsx index 8b9593032..b67ed105d 100644 --- a/packages/react-native-room-kit/src/components/HLSPlayerContainer.tsx +++ b/packages/react-native-room-kit/src/components/HLSPlayerContainer.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; +import { useSelector } from 'react-redux'; import type { HMSHLSPlayer } from '@100mslive/react-native-hms'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { @@ -13,11 +14,16 @@ import { import { useHLSViewsConstraints } from '../hooks-util'; import { HLSPlayer } from './HLSPlayer'; import { HLSPlayerControls } from './HLSPlayerControls'; +import { PipModes } from '../utils/types'; +import type { RootState } from '../redux'; export const _HLSPlayerContainer: React.FC = () => { const hlsPlayerRef = React.useRef>(null); const { playerWrapperConstraints } = useHLSViewsConstraints(); + const isPipModeActive = useSelector( + (state: RootState) => state.app.pipModeStatus === PipModes.ACTIVE + ); const animatedValue = useSharedValue(1); @@ -82,13 +88,15 @@ export const _HLSPlayerContainer: React.FC = () => { > - + {isPipModeActive ? null : ( + + )} ); diff --git a/packages/react-native-room-kit/src/components/MeetingScreenContent.tsx b/packages/react-native-room-kit/src/components/MeetingScreenContent.tsx index 683c8cc8a..beef8b0b9 100644 --- a/packages/react-native-room-kit/src/components/MeetingScreenContent.tsx +++ b/packages/react-native-room-kit/src/components/MeetingScreenContent.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useRef, useState, useEffect } from 'react'; -import { StyleSheet, View, Keyboard } from 'react-native'; +import { StyleSheet, View, Keyboard, Platform } from 'react-native'; import { useSelector } from 'react-redux'; import { Easing, @@ -21,6 +21,7 @@ import { useKeyboardState } from '../hooks-util'; import { HMSStatusBar } from './StatusBar'; import { AnimatedFooter } from './AnimatedFooter'; import { AnimatedHeader } from './AnimatedHeader'; +import { useIsLandscapeOrientation } from '../utils/dimension'; // import { ReconnectionView } from './ReconnectionView'; interface MeetingScreenContentProps { @@ -33,9 +34,14 @@ export const MeetingScreenContent: React.FC = ({ const offset = useSharedValue(1); const timerIdRef = useRef(null); const [controlsHidden, setControlsHidden] = useState(false); + const isLandscapeOrientation = useIsLandscapeOrientation(); const isPipModeActive = useSelector( (state: RootState) => state.app.pipModeStatus === PipModes.ACTIVE ); + const whiteboardActive = + Platform.OS === 'android' + ? useSelector((state: RootState) => !!state.hmsStates.whiteboard) + : null; const { keyboardState } = useKeyboardState(); const dismissKeyboard = useCallback(() => { @@ -75,9 +81,28 @@ export const MeetingScreenContent: React.FC = ({ [dismissKeyboard, clearTimer] ); + if ( + !!whiteboardActive && + (isLandscapeOrientation ? offset.value === 1 : offset.value < 1) + ) { + cancelAnimation(offset); + offset.value = withTiming( + isLandscapeOrientation ? 0 : 1, + { duration: 200, easing: Easing.ease }, + (finished) => { + if (finished) { + runOnJS(setControlsHidden)(offset.value === 0); + } + } + ); + } + // Handles Auto hiding the controls for the first time // to make this feature discoverable useEffect(() => { + if (!!whiteboardActive) { + return; + } clearTimer(); timerIdRef.current = setTimeout(() => { timerIdRef.current = null; @@ -85,9 +110,10 @@ export const MeetingScreenContent: React.FC = ({ }, HeaderFooterHideDelayMs); return clearTimer; - }, [clearTimer, toggleControls]); + }, [clearTimer, toggleControls, !!whiteboardActive]); const tapGesture = Gesture.Tap() + .enabled(Platform.select({ android: !whiteboardActive, default: true })) .onEnd(() => toggleControls()) .requireExternalGestureToFail(); diff --git a/packages/react-native-room-kit/src/components/RoomSettingsModalContent.tsx b/packages/react-native-room-kit/src/components/RoomSettingsModalContent.tsx index 622d31d58..f83813391 100644 --- a/packages/react-native-room-kit/src/components/RoomSettingsModalContent.tsx +++ b/packages/react-native-room-kit/src/components/RoomSettingsModalContent.tsx @@ -3,7 +3,7 @@ import { View, StyleSheet, Text, TouchableOpacity } from 'react-native'; import type { TouchableOpacityProps } from 'react-native'; import type { HMSAudioMixingMode } from '@100mslive/react-native-hms'; import { HMSRecordingState } from '@100mslive/react-native-hms'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import type { RootState } from '../redux'; import { ModalTypes } from '../utils/types'; @@ -22,6 +22,7 @@ import { BottomSheet, useBottomSheetActions } from './BottomSheet'; import { isPublishingAllowed, useHMSConferencingScreenConfig, + useHMSInstance, useHMSLayoutConfig, useHMSRoomColorPalette, useHMSRoomStyleSheet, @@ -38,6 +39,8 @@ import { RoomSettingsModalDebugModeContent } from './RoomSettingsModalDebugModeC import { ParticipantsCount } from './ParticipantsCount'; import { selectAllowedTracksToPublish } from '../hooks-sdk-selectors'; import { TestIds } from '../utils/constants'; +import { addNotification } from '../redux/actions'; +import { NotificationTypes } from '../types'; interface RoomSettingsModalContentProps { newAudioMixingMode: HMSAudioMixingMode; @@ -56,6 +59,8 @@ export const RoomSettingsModalContent: React.FC< > = (props) => { const { closeRoomSettingsModal, setModalVisible } = props; + const hmsInstance = useHMSInstance(); + const dispatch = useDispatch(); const debugMode = useSelector((state: RootState) => state.user.debugMode); const hmsActions = useHMSActions(); @@ -76,6 +81,10 @@ export const RoomSettingsModalContent: React.FC< return permissions?.pollRead || permissions?.pollWrite; }); + const whiteboardAdminPermission = useSelector((state: RootState) => { + return !!state.hmsStates.localPeer?.role?.permissions?.whiteboard?.admin; + }); + const { registerOnModalHideAction } = useBottomSheetActions(); const { canShowParticipants, show } = useShowChatAndParticipants(); @@ -271,6 +280,61 @@ export const RoomSettingsModalContent: React.FC< closeRoomSettingsModal(); }; + const whiteboard = useSelector( + (state: RootState) => state.hmsStates.whiteboard + ); + const screenShareNodesAvailable = useSelector( + (state: RootState) => state.app.screensharePeerTrackNodes.length > 0 + ); + + const toggleWhiteboard = async () => { + if (!whiteboardAdminPermission) return; + + if (whiteboard && whiteboard.isOwner) { + hmsInstance.interactivityCenter + .stopWhiteboard() + .then((success) => { + console.log('#stopWhiteboard stopped whiteboard ', success); + }) + .catch((error) => { + console.log('#stopWhiteboard error ', error); + }); + } else if (whiteboard && !whiteboard.isOwner) { + const uid = Math.random().toString(16).slice(2); + dispatch( + addNotification({ + id: uid, + type: NotificationTypes.ERROR, + title: + 'Only the peer who started the whiteboard has the ability to close it!', + }) + ); + } else if (isLocalScreenShared || screenShareNodesAvailable) { + const uid = Math.random().toString(16).slice(2); + dispatch( + addNotification({ + id: uid, + type: NotificationTypes.ERROR, + title: isLocalScreenShared + ? 'Discontinue screenshare to open the whiteboard!' + : "Can't open whiteboard while screenshare is happening!", + }) + ); + } else { + hmsInstance.interactivityCenter + .startWhiteboard('Interactive Session') + .then((success) => { + console.log('#startWhiteboard started whiteboard ', success); + }) + .catch((error) => { + console.log('#startWhiteboard error ', error); + }); + } + + // Close the current bottom sheet + closeRoomSettingsModal(); + }; + const canShowBRB = useHMSLayoutConfig( (layoutConfig) => !!layoutConfig?.screens?.conferencing?.default?.elements?.brb @@ -394,6 +458,17 @@ export const RoomSettingsModalContent: React.FC< isActive: false, hide: !canReadOrWritePoll, }, + { + id: 'whiteboard', + icon: ( + + ), + label: whiteboard ? 'Close Whiteboard' : 'Open Whiteboard', + pressHandler: toggleWhiteboard, + isActive: !!whiteboard && whiteboard.isOwner, + disabled: !!whiteboard && !whiteboard.isOwner, + hide: !whiteboardAdminPermission, + }, { id: 'noise-cancellation', icon: , @@ -458,7 +533,7 @@ type SettingItemProps = { onPress(): void; disabled?: TouchableOpacityProps['disabled']; testID?: TouchableOpacityProps['testID']; - isActive?: boolean; + isActive?: boolean | null; }; const SettingItem: React.FC = ({ diff --git a/packages/react-native-room-kit/src/components/TilesContainer.tsx b/packages/react-native-room-kit/src/components/TilesContainer.tsx index 94205dcdd..44b15baa2 100644 --- a/packages/react-native-room-kit/src/components/TilesContainer.tsx +++ b/packages/react-native-room-kit/src/components/TilesContainer.tsx @@ -25,13 +25,15 @@ const _TilesContainer: React.FC = ({ const { width: safeWidth } = useSafeAreaFrame(); const isLandscapeOrientation = useIsLandscapeOrientation(); - const screenshareTilesAvailable = useSelector( - (state: RootState) => state.app.screensharePeerTrackNodes.length > 0 + const screenshareTilesOrWhiteboardAcive = useSelector( + (state: RootState) => + state.app.screensharePeerTrackNodes.length > 0 || + !!state.hmsStates.whiteboard ); const stylesConfig = computeTileWidthAndHeight(peerTrackNodes.length, { isLandscapeOrientation, - type: screenshareTilesAvailable ? 'row' : 'default', + type: screenshareTilesOrWhiteboardAcive ? 'row' : 'default', }); // In this layout, Tile will take as much height and width as possible @@ -44,12 +46,12 @@ const _TilesContainer: React.FC = ({ // If tile are growable, then we want whatever remaining space to be between them { justifyContent: - screenshareTilesAvailable && peerTrackNodes.length === 1 + screenshareTilesOrWhiteboardAcive && peerTrackNodes.length === 1 ? 'center' : growableTileLayout ? 'space-between' : 'center', - flexDirection: screenshareTilesAvailable + flexDirection: screenshareTilesOrWhiteboardAcive ? 'row' : isLandscapeOrientation ? 'row' diff --git a/packages/react-native-room-kit/src/components/WebrtcView.tsx b/packages/react-native-room-kit/src/components/WebrtcView.tsx index 3a5cbcc5f..8fe684d8b 100644 --- a/packages/react-native-room-kit/src/components/WebrtcView.tsx +++ b/packages/react-native-room-kit/src/components/WebrtcView.tsx @@ -49,8 +49,10 @@ export const WebrtcView = React.forwardRef( (state: RootState) => state.user.spotlightTrackId ); - const screenshareTilesAvailable = useSelector( - (state: RootState) => state.app.screensharePeerTrackNodes.length > 0 + const screenshareTilesOrWhiteboardAcive = useSelector( + (state: RootState) => + state.app.screensharePeerTrackNodes.length > 0 || + !!state.hmsStates.whiteboard ); const pairedPeers = useMemo( @@ -58,13 +60,18 @@ export const WebrtcView = React.forwardRef( pairData( peerTrackNodes, isPortrait - ? screenshareTilesAvailable + ? screenshareTilesOrWhiteboardAcive ? MaxTilesInOnePage.IN_PORTRAIT_WITH_SCREENSHARES : MaxTilesInOnePage.IN_PORTRAIT : MaxTilesInOnePage.IN_LANDSCAPE, spotlightTrackId ), - [peerTrackNodes, screenshareTilesAvailable, spotlightTrackId, isPortrait] + [ + peerTrackNodes, + screenshareTilesOrWhiteboardAcive, + spotlightTrackId, + isPortrait, + ] ); const showWelcomeBanner = useSelector( diff --git a/packages/react-native-room-kit/src/components/Whiteboard.tsx b/packages/react-native-room-kit/src/components/Whiteboard.tsx new file mode 100644 index 000000000..5212ae7b4 --- /dev/null +++ b/packages/react-native-room-kit/src/components/Whiteboard.tsx @@ -0,0 +1,101 @@ +import * as React from 'react'; +import { Platform, View } from 'react-native'; +import { useSelector } from 'react-redux'; +import { WebView } from 'react-native-webview'; +import type { WebViewProps } from 'react-native-webview'; + +import type { RootState } from '../redux'; +import { PipModes } from '../utils/types'; +import { useIsLandscapeOrientation } from '../utils/dimension'; +import { WhiteboardFullScreenButton } from './WhiteboardFullScreenButton'; +import type { + WebViewError, + WebViewErrorEvent, +} from 'react-native-webview/lib/WebViewTypes'; + +export type WhiteboardProps = {}; + +export const _Whiteboard = React.forwardRef< + React.Ref | null>, + WhiteboardProps +>((_props, webviewRef) => { + const localWebviewRef = React.useRef>( + null + ); + React.useImperativeHandle(webviewRef, () => localWebviewRef, []); + + const whiteboardUrl = useSelector( + (state: RootState) => state.hmsStates.whiteboard?.url + ); + + //#region reconnection handling + let webviewError = React.useRef(null); + const webviewErrorHandler = React.useCallback((e: WebViewErrorEvent) => { + webviewError.current = e.nativeEvent; + }, []); + + if (Platform.OS === 'ios') { + const prevReconnecting = React.useRef(null); + const reconnecting = useSelector( + (state: RootState) => state.hmsStates.reconnecting + ); + if ( + whiteboardUrl && + localWebviewRef.current !== null && + webviewError.current !== null && + prevReconnecting.current === true && + reconnecting === false + ) { + localWebviewRef.current.reload(); + } + prevReconnecting.current = reconnecting; + } + //#endregion reconnection handling + + const isPipModeActive = useSelector( + (state: RootState) => state.app.pipModeStatus === PipModes.ACTIVE + ); + const isLandscapeOrientation = useIsLandscapeOrientation(); + + if (!whiteboardUrl) return null; + + return ( + + + + {isPipModeActive || isLandscapeOrientation ? null : ( + + )} + + ); +}); + +export const Whiteboard = React.memo(_Whiteboard); + +//# Memoized Webview + +interface HMSWebViewProps extends WebViewProps { + url: string; +} + +const _HMSWebView = React.forwardRef< + React.ElementRef, + HMSWebViewProps +>((props, webviewRef) => { + return ( + + ); +}); + +const HMSWebView = React.memo(_HMSWebView); diff --git a/packages/react-native-room-kit/src/components/WhiteboardContainer.tsx b/packages/react-native-room-kit/src/components/WhiteboardContainer.tsx new file mode 100644 index 000000000..e3d127940 --- /dev/null +++ b/packages/react-native-room-kit/src/components/WhiteboardContainer.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { Platform, View } from 'react-native'; +import { useSelector } from 'react-redux'; +import { WebView } from 'react-native-webview'; +import { GestureDetector, Gesture } from 'react-native-gesture-handler'; + +import type { RootState } from '../redux'; +import { Whiteboard } from './Whiteboard'; + +export type WhiteboardContainerProps = {}; + +export const _WhiteboardContainer = React.forwardRef< + React.RefObject | null>, + WhiteboardContainerProps +>((_props, webviewRef) => { + const fullScreenWhiteboard = useSelector( + (state: RootState) => state.app.fullScreenWhiteboard + ); + + return ( + + {fullScreenWhiteboard ? null : Platform.OS === 'ios' ? ( + + + + + + ) : ( + + )} + + ); +}); + +export const WhiteboardContainer = React.memo(_WhiteboardContainer); diff --git a/packages/react-native-room-kit/src/components/WhiteboardFullScreenButton.tsx b/packages/react-native-room-kit/src/components/WhiteboardFullScreenButton.tsx new file mode 100644 index 000000000..645266026 --- /dev/null +++ b/packages/react-native-room-kit/src/components/WhiteboardFullScreenButton.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { StyleSheet } from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; + +import { PressableIcon } from './PressableIcon'; +import { MaximizeIcon, MinimizeIcon } from '../Icons'; +import { useHMSRoomStyle } from '../hooks-util'; +import { hexToRgbA } from '../utils/theme'; +import type { RootState } from '../redux'; +import { setFullScreenWhiteboard } from '../redux/actions'; + +export interface WhiteboardFullScreenButtonProps {} + +export const WhiteboardFullScreenButton: React.FC< + WhiteboardFullScreenButtonProps +> = () => { + const dispatch = useDispatch(); + const fullScreenWhiteboard = useSelector( + (state: RootState) => state.app.fullScreenWhiteboard + ); + + const buttonStyles = useHMSRoomStyle((theme) => ({ + backgroundColor: + theme.palette.background_dim && + hexToRgbA(theme.palette.background_dim, 0.64), + })); + + const maximizeAction = !fullScreenWhiteboard; + + const handleFullScreenPress = () => { + dispatch(setFullScreenWhiteboard(!fullScreenWhiteboard)); + }; + + return ( + + {maximizeAction ? : } + + ); +}; + +const styles = StyleSheet.create({ + container: { + position: 'absolute', + top: 8, + right: 8, + padding: 8, + }, +}); diff --git a/packages/react-native-room-kit/src/hooks-util.ts b/packages/react-native-room-kit/src/hooks-util.ts index 1a9ca24de..03bcfbc58 100644 --- a/packages/react-native-room-kit/src/hooks-util.ts +++ b/packages/react-native-room-kit/src/hooks-util.ts @@ -601,9 +601,11 @@ const useHMSTrackUpdate = ( const miniviewPeerTrackNode = reduxState.app.miniviewPeerTrackNode; const localPeerTrackNode = reduxState.app.localPeerTrackNode; + const localPeerRole = reduxState.hmsStates.localPeer?.role ?? null; + const currentLayoutConfig = selectLayoutConfigForRole( reduxState.hmsStates.layoutConfig, - reduxState.hmsStates.localPeer?.role ?? null + localPeerRole ); const localTileInsetEnabled = @@ -617,6 +619,26 @@ const useHMSTrackUpdate = ( if (!peer.isLocal && track.type === HMSTrackType.VIDEO) { dispatch(addScreenshareTile(newPeerTrackNode)); } + if (track.type === HMSTrackType.VIDEO) { + const whiteboard = reduxState.hmsStates.whiteboard; + // If white board is open and local peer is owner, close whiteboard + if ( + whiteboard && + // Is local peer has whiteboard admin permission + !!localPeerRole?.permissions?.whiteboard?.admin && + // Is local peer owner of whiteboard + whiteboard.isOwner + ) { + hmsInstance.interactivityCenter + .stopWhiteboard() + .then((success) => { + console.log('StopWhiteboard on Screenshare: ', success); + }) + .catch((error) => { + console.log('StopWhiteboard error: ', error); + }); + } + } } else { setPeerTrackNodes((prevPeerTrackNodes) => { if ( @@ -3100,6 +3122,11 @@ export const useCanShowRoomOptionsButton = () => { return permissions?.pollRead || permissions?.pollWrite; }); + const canStartStopWhiteboard = useSelector((state: RootState) => { + const permissions = state.hmsStates.localPeer?.role?.permissions; + return permissions?.whiteboard?.admin; + }); + const { canShowParticipants } = useShowChatAndParticipants(); const canEditUsernameFromRoomModal = isViewer && !editUsernameDisabled; @@ -3111,15 +3138,18 @@ export const useCanShowRoomOptionsButton = () => { canStartRecording || canEditUsernameFromRoomModal || canReadOrWritePoll || + canStartStopWhiteboard || isNoiseCancellationAvailable; return canShowOptions; }; export const useHLSViewsConstraints = () => { - const hlsFullScreen = useSelector( - (state: RootState) => state.app.hlsFullScreen - ); + const fullScreenMode = useSelector((state: RootState) => { + const hlsFullScreen = state.app.hlsFullScreen; + const isPipModeActive = state.app.pipModeStatus === PipModes.ACTIVE; + return hlsFullScreen || isPipModeActive; + }); const isLandscapeOrientation = useIsLandscapeOrientation(); const { width: safeAreaWidthFrame, height: safeAreaHeightFrame } = useSafeAreaFrame(); @@ -3130,7 +3160,7 @@ export const useHLSViewsConstraints = () => { right: rightInset, } = useSafeAreaInsets(); - const playerWrapperConstraints = hlsFullScreen + const playerWrapperConstraints = fullScreenMode ? { width: safeAreaWidthFrame - leftInset - rightInset, height: isLandscapeOrientation @@ -3165,9 +3195,11 @@ export const useHLSViewsConstraints = () => { }; export const useHLSPlayerConstraints = () => { - const hlsFullScreen = useSelector( - (state: RootState) => state.app.hlsFullScreen - ); + const fullScreenMode = useSelector((state: RootState) => { + const hlsFullScreen = state.app.hlsFullScreen; + const isPipModeActive = state.app.pipModeStatus === PipModes.ACTIVE; + return hlsFullScreen || isPipModeActive; + }); const isLandscapeOrientation = useIsLandscapeOrientation(); const resolution = useHMSHLSPlayerResolution(); @@ -3205,7 +3237,7 @@ export const useHLSPlayerConstraints = () => { /** * Handling Portrait Orientation */ - if (hlsFullScreen) { + if (fullScreenMode) { return { width: sr > wr ? wrapperWidth : wrapperHeight * sr, height: sr > wr ? wrapperWidth / sr : wrapperHeight, diff --git a/packages/react-native-room-kit/src/redux/actionTypes.ts b/packages/react-native-room-kit/src/redux/actionTypes.ts index 4d8979422..a2458010b 100644 --- a/packages/react-native-room-kit/src/redux/actionTypes.ts +++ b/packages/react-native-room-kit/src/redux/actionTypes.ts @@ -66,6 +66,8 @@ const UPDATE_MINI_VIEW_PEERTRACKNODE = 'UPDATE_MINI_VIEW_PEERTRACKNODE'; const SET_FULLSCREEN_PEERTRACKNODE = 'SET_FULLSCREEN_PEERTRACKNODE'; +const SET_FULLSCREEN_WHITEBOARD = 'SET_FULLSCREEN_WHITEBOARD'; + const UPDATE_FULLSCREEN_PEERTRACKNODE = 'UPDATE_FULLSCREEN_PEERTRACKNODE'; const SET_LOCAL_PEERTRACKNODE = 'SET_LOCAL_PEERTRACKNODE'; @@ -143,6 +145,7 @@ export default { SET_MINI_VIEW_PEERTRACKNODE, UPDATE_MINI_VIEW_PEERTRACKNODE, SET_FULLSCREEN_PEERTRACKNODE, + SET_FULLSCREEN_WHITEBOARD, UPDATE_FULLSCREEN_PEERTRACKNODE, SET_LOCAL_PEERTRACKNODE, UPDATE_LOCAL_PEERTRACKNODE, @@ -195,6 +198,7 @@ export enum HmsStateActionTypes { SET_ACTIVE_SPEAKERS = 'SET_ACTIVE_SPEAKERS', SET_RECONNECTING = 'SET_RECONNECTING', SET_NOISE_CANCELLATION_PLUGIN = 'SET_NOISE_CANCELLATION_PLUGIN', + SET_WHITEBOARD = 'SET_WHITEBOARD', SET_INITIAL_ROLE = 'SET_INITIAL_ROLE', } diff --git a/packages/react-native-room-kit/src/redux/actions/index.ts b/packages/react-native-room-kit/src/redux/actions/index.ts index 9aa7bfd4e..9beac5328 100644 --- a/packages/react-native-room-kit/src/redux/actions/index.ts +++ b/packages/react-native-room-kit/src/redux/actions/index.ts @@ -14,6 +14,7 @@ import type { HMSSDK, HMSSessionStore, HMSSpeaker, + HMSWhiteboard, } from '@100mslive/react-native-hms'; import type { Layout } from '@100mslive/types-prebuilt'; @@ -285,6 +286,11 @@ export const setFullScreenPeerTrackNode = ( payload: { fullScreenPeerTrackNode }, }); +export const setFullScreenWhiteboard = (fullScreenWhiteboard: boolean) => ({ + type: actionTypes.SET_FULLSCREEN_WHITEBOARD, + payload: { fullScreenWhiteboard }, +}); + export const updateFullScreenPeerTrackNode = ( data: Partial> ) => ({ @@ -439,6 +445,11 @@ export const setNoiseCancellationPlugin = ( noiseCancellationPlugin, }); +export const setWhiteboard = (whiteboard: HMSWhiteboard | null) => ({ + type: HmsStateActionTypes.SET_WHITEBOARD, + whiteboard, +}); + export const setHandleBackButton = (handleBackButton?: boolean) => ({ type: actionTypes.SET_HANDLE_BACK_BUTTON, payload: { handleBackButton }, diff --git a/packages/react-native-room-kit/src/redux/reducers/appState.ts b/packages/react-native-room-kit/src/redux/reducers/appState.ts index 58111e484..9e26e05ca 100644 --- a/packages/react-native-room-kit/src/redux/reducers/appState.ts +++ b/packages/react-native-room-kit/src/redux/reducers/appState.ts @@ -50,6 +50,7 @@ type IntialStateType = { gridViewActivePage: number; startingOrStoppingRecording: boolean; fullScreenPeerTrackNode: null | PeerTrackNode; + fullScreenWhiteboard: boolean; screensharePeerTrackNodes: PeerTrackNode[]; notifications: Notification[]; activeChatBottomSheetTab: (typeof ChatBottomSheetTabs)[number]; @@ -90,6 +91,7 @@ const INITIAL_STATE: IntialStateType = { gridViewActivePage: 0, startingOrStoppingRecording: false, fullScreenPeerTrackNode: null, + fullScreenWhiteboard: false, screensharePeerTrackNodes: [], notifications: [], activeChatBottomSheetTab: ChatBottomSheetTabs[0], @@ -242,6 +244,12 @@ const appReducer = ( }, }; } + case ActionTypes.SET_FULLSCREEN_WHITEBOARD: { + return { + ...state, + fullScreenWhiteboard: action.payload.fullScreenWhiteboard, + }; + } case ActionTypes.SET_STARTING_HLS_STREAM: return { ...state, startingHLSStream: action.payload.startingHLSStream }; case ActionTypes.SET_GRID_VIEW_ACTIVE_PAGE: diff --git a/packages/react-native-room-kit/src/redux/reducers/hmsStates.ts b/packages/react-native-room-kit/src/redux/reducers/hmsStates.ts index e0ac8d8e7..147cc180b 100644 --- a/packages/react-native-room-kit/src/redux/reducers/hmsStates.ts +++ b/packages/react-native-room-kit/src/redux/reducers/hmsStates.ts @@ -6,6 +6,7 @@ import type { HMSRoleChangeRequest, HMSRoom, HMSSpeaker, + HMSWhiteboard, } from '@100mslive/react-native-hms'; import type { Layout } from '@100mslive/types-prebuilt'; import { HmsStateActionTypes } from '../actionTypes'; @@ -31,7 +32,8 @@ type ActionType = | ReplaceParticipantsList | SetActiveSpeakers | SetReconnecting - | SetNoiseCancellationPlugin; + | SetNoiseCancellationPlugin + | SetWhiteboard; type SetRoomAction = { type: HmsStateActionTypes.SET_ROOM_STATE; @@ -138,6 +140,11 @@ type SetNoiseCancellationPlugin = { noiseCancellationPlugin: HMSNoiseCancellationPlugin; }; +type SetWhiteboard = { + type: HmsStateActionTypes.SET_WHITEBOARD; + whiteboard: HMSWhiteboard | null; +}; + type IntialStateType = { isLocalAudioMuted: boolean | undefined; isLocalVideoMuted: boolean | undefined; @@ -153,6 +160,7 @@ type IntialStateType = { layoutConfig: Layout[] | null; roleChangeRequest: HMSRoleChangeRequest | null; noiseCancellationPlugin: HMSNoiseCancellationPlugin | null; + whiteboard: HMSWhiteboard | null; }; const INITIAL_STATE: IntialStateType = { @@ -170,6 +178,7 @@ const INITIAL_STATE: IntialStateType = { layoutConfig: null, roleChangeRequest: null, noiseCancellationPlugin: null, + whiteboard: null, }; const hmsStatesReducer = ( @@ -571,6 +580,11 @@ const hmsStatesReducer = ( ...state, noiseCancellationPlugin: action.noiseCancellationPlugin, }; + case HmsStateActionTypes.SET_WHITEBOARD: + return { + ...state, + whiteboard: action.whiteboard, + }; case HmsStateActionTypes.CLEAR_STATES: return INITIAL_STATE; default: