From 9da27fc6b595843941e8326f3174edb3166c3d29 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Thu, 22 Feb 2024 16:38:10 +0530 Subject: [PATCH 01/14] feat(sdk): :sparkles: added `fetchLeaderboard` api in js and android sdk --- .../java/com/reactnativehmssdk/HMSManager.kt | 18 ++++ .../Interactivity/HMSInteractivityDecoder.kt | 85 ++++++++++++++++++ .../Interactivity/HMSRNInteractivityCenter.kt | 88 +++++++------------ .../src/classes/HMSInteractivityCenter.ts | 30 +++++++ .../src/classes/HMSInteractivityEncoder.ts | 36 ++++++++ .../polls/DecodedPollLeaderboardResponse.ts | 43 +++++++++ .../classes/polls/HMSPollLeaderboardEntry.ts | 10 +++ .../polls/HMSPollLeaderboardSummary.ts | 7 ++ .../classes/polls/PollLeaderboardResponse.ts | 8 ++ 9 files changed, 270 insertions(+), 55 deletions(-) create mode 100644 packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts create mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts create mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts create mode 100644 packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts 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 77aa2b270..f5b9980f4 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 @@ -1396,6 +1396,24 @@ class HMSManager(reactContext: ReactApplicationContext) : "HMS SDK not initialized", ) } + + @ReactMethod + fun fetchLeaderboard( + data: ReadableMap, + promise: Promise?, + ) { + val rnSDK = HMSHelper.getHms(data, hmsCollection) + rnSDK?.let { sdk -> + sdk.interactivityCenter?.let { center -> + center.fetchLeaderboard(data, promise) + return + } + } + promise?.reject( + "6004", + "HMS SDK not initialized", + ) + } // endregion // region ActivityLifecycleCallbacks 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 6fcc4b813..2feab1755 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 @@ -10,8 +10,12 @@ import live.hms.video.polls.models.answer.HMSPollQuestionAnswer import live.hms.video.polls.models.answer.HmsPollAnswer import live.hms.video.polls.models.answer.PollAnswerItem import live.hms.video.polls.models.answer.PollAnswerResponse +import live.hms.video.polls.models.network.HMSPollResponsePeerInfo import live.hms.video.polls.models.question.HMSPollQuestion import live.hms.video.polls.models.question.HMSPollQuestionOption +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 object HMSInteractivityDecoder { @@ -310,6 +314,87 @@ object HMSInteractivityDecoder { return results } + fun getPollLeaderboardResponse(pollLeaderboardResponse: PollLeaderboardResponse): WritableMap { + val results = Arguments.createMap() + + pollLeaderboardResponse.hasNext?.let { + results.putBoolean("hasNext", it) + } + pollLeaderboardResponse.summary?.let { + results.putMap("summary", getHMSPollLeaderboardSummary(it)) + } + pollLeaderboardResponse.entries?.let { + results.putArray("entries", getHMSPollLeaderboardEntries(it)) + } + return results + } + + private fun getHMSPollLeaderboardSummary(pollLeaderboardSummary: HMSPollLeaderboardSummary): WritableMap { + val summary = Arguments.createMap() + pollLeaderboardSummary.averageScore?.let { + summary.putDouble("averageScore", it.toDouble()) + } + pollLeaderboardSummary.averageTime?.let { + summary.putString("averageTime", it.toString()) + } + pollLeaderboardSummary.totalPeersCount?.let { + summary.putInt("totalPeersCount", it) + } + pollLeaderboardSummary.respondedCorrectlyPeersCount?.let { + summary.putInt("respondedCorrectlyPeersCount", it) + } + pollLeaderboardSummary.respondedPeersCount?.let { + summary.putInt("respondedPeersCount", it) + } + return summary + } + + private fun getHMSPollLeaderboardEntries(pollLeaderboardEntries: List): WritableArray { + val list = Arguments.createArray() + pollLeaderboardEntries.forEach { + list.pushMap(getHMSPollLeaderboardEntry(it)) + } + return list + } + + private fun getHMSPollLeaderboardEntry(pollLeaderboardEntry: HMSPollLeaderboardEntry): WritableMap { + val entry = Arguments.createMap() + pollLeaderboardEntry.duration?.let { + entry.putString("duration", it.toString()) + } + pollLeaderboardEntry.peer?.let { + entry.putMap("peer", getHMSPollResponsePeerInfo(it)) + } + pollLeaderboardEntry.totalResponses?.let { + entry.putString("totalResponses", it.toString()) + } + pollLeaderboardEntry.correctResponses?.let { + entry.putString("correctResponses", it.toString()) + } + pollLeaderboardEntry.position?.let { + entry.putString("position", it.toString()) + } + pollLeaderboardEntry.score?.let { + entry.putString("score", it.toString()) + } + return entry + } + + private fun getHMSPollResponsePeerInfo(pollResponsePeerInfo: HMSPollResponsePeerInfo): WritableMap { + val peerInfo = Arguments.createMap() + peerInfo.putString("userHash", pollResponsePeerInfo.hash) + pollResponsePeerInfo.peerid?.let { + peerInfo.putString("peerId", it) + } + pollResponsePeerInfo.userid?.let { + peerInfo.putString("customerUserId", it) + } + pollResponsePeerInfo.username?.let { + peerInfo.putString("userName", it) + } + return peerInfo + } + private fun getHMSPollQuestionResponseResult(hmsPollQuestionResponseResult: PollAnswerItem): WritableMap { val result = Arguments.createMap() 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 dde1b1cc6..6eb46d17c 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 @@ -1,5 +1,4 @@ package com.reactnativehmssdk -import android.util.Log import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap @@ -10,6 +9,7 @@ import live.hms.video.interactivity.HmsPollUpdateListener import live.hms.video.polls.models.HMSPollUpdateType import live.hms.video.polls.models.HmsPoll import live.hms.video.polls.models.answer.PollAnswerResponse +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 @@ -37,8 +37,6 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN } } - // region Create Polls - fun quickStartPoll( data: ReadableMap, promise: Promise?, @@ -59,41 +57,6 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } - /* - - func add(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { - guard let pollId = data["pollId"] as? String, - let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { - reject?("6004", "Unable to find HMSPoll with given pollId", nil) - return - } - guard let pollQuestionIndex = data["pollQuestionIndex"] as? Int, - let pollQuestion = poll.questions?.first(where: {question in question.index == pollQuestionIndex}) else { - reject?("6004", "Unable to find HMSPollQuestion in poll with given question index", nil) - return - } - guard let responses = data["responses"] as? NSDictionary else { - reject?("6004", "responses field is required", nil) - return - } - - let pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll: poll, pollQuestion: pollQuestion) - - self.hmssdk?.interactivityCenter.add(response: pollResponseBuilder) { pollQuestionResponseResult, error in - if let nonnilError = error { - reject?("6004", nonnilError.localizedDescription, nil) - return - } - if let pollQuestionResponseResult = pollQuestionResponseResult { - resolve?(HMSInteractivityDecoder.getHMSPollQuestionResponseResults(pollQuestionResponseResult)) - } else { - resolve?(nil) - } - } - } - - */ - fun addResponseOnPollQuestion( data: ReadableMap, promise: Promise?, @@ -162,23 +125,38 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } - // endregion - - // region Poll Update Listener - - fun showPollStartedToast() { - // Show toast - Log.e("Interactivity", "showPollStartedToast") - } - - fun loadResultsSummaryIfNeeded() { - // Load results summary - Log.e("Interactivity", "loadResultsSummaryIfNeeded") - } + fun fetchLeaderboard( + data: ReadableMap, + promise: Promise?, + ) { + val pollId = data.getString("pollId") + if (pollId == null) { + promise?.reject("6002", "pollId is required") + return + } + val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } + if (poll == null) { + promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + return + } + val count = data.getInt("count") + val startIndex = data.getInt("startIndex") + val includeCurrentPeer = data.getBoolean("includeCurrentPeer") + + this.sdk.getHmsInteractivityCenter().fetchLeaderboard( + pollId = poll.pollId, + count = count.toLong(), + startIndex = startIndex.toLong(), + includeCurrentPeer = includeCurrentPeer, + object : HmsTypedActionResultListener { + override fun onSuccess(result: PollLeaderboardResponse) { + promise?.resolve(HMSInteractivityDecoder.getPollLeaderboardResponse(result)) + } - fun updateResultsScreen() { - // Update results screen - Log.e("Interactivity", "updateResultsScreen") + override fun onError(error: HMSException) { + promise?.reject(error.code.toString(), error.description) + } + }, + ) } - // endregion } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts index ac10da22f..fb3e39488 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts @@ -10,6 +10,8 @@ import HMSNativeEventListener from './HMSNativeEventListener'; import type { HMSEventSubscription } from './HMSNativeEventEmitter'; import { HMSInteractivityEncoder } from './HMSInteractivityEncoder'; import { HMSHelper } from './HMSHelper'; +import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; +import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; type PollUpdateListener = (data: { updatedPoll: HMSPoll; @@ -134,4 +136,32 @@ export class HMSInteractivityCenter { logger?.verbose('#Function stop', JSON.stringify(data)); return HMSManager.stopPoll(data); } + + /** + * Fetches the leaderboard for a poll + * @param pollId - The id of the poll + * @param count - The number of entries to fetch + * @param startIndex - The index to start fetching from + * @param includeCurrentPeer - Whether to include the current peer in the fetched leaderboard entries + * @returns Promise + */ + async fetchLeaderboard( + pollId: string, + count: number, + startIndex: number, + includeCurrentPeer: boolean + ): Promise { + const data = { + id: HMSConstants.DEFAULT_SDK_ID, + pollId, + count, + startIndex, + includeCurrentPeer, + }; + logger?.verbose('#Function fetchLeaderboard', data); + + const response: DecodedPollLeaderboardResponse = + await HMSManager.fetchLeaderboard(data); + return HMSInteractivityEncoder.transformPollLeaderboardResponse(response); + } } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts index 27d4d14a9..94d216244 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts @@ -1,4 +1,6 @@ +import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; import type { HMSPoll } from './polls/HMSPoll'; +import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; export class HMSInteractivityEncoder { static transformPoll(poll: HMSPoll): HMSPoll { @@ -26,4 +28,38 @@ export class HMSInteractivityEncoder { // --- poll.result: HMSPollResult return poll; } + + static transformPollLeaderboardResponse( + decodedPollLeaderboardResponse: DecodedPollLeaderboardResponse + ): PollLeaderboardResponse { + const summary = decodedPollLeaderboardResponse.summary; + if (summary) { + if (typeof summary.averageTime === 'string') { + summary.averageTime = parseInt(summary.averageTime); + } + } + + const entries = decodedPollLeaderboardResponse.entries; + if (entries) { + entries.forEach((entry) => { + if (typeof entry.duration === 'string') { + entry.duration = parseInt(entry.duration); + } + if (typeof entry.totalResponses === 'string') { + entry.totalResponses = parseInt(entry.totalResponses); + } + if (typeof entry.correctResponses === 'string') { + entry.correctResponses = parseInt(entry.correctResponses); + } + if (typeof entry.position === 'string') { + entry.position = parseInt(entry.position); + } + if (typeof entry.score === 'string') { + entry.score = parseInt(entry.score); + } + }); + } + + return decodedPollLeaderboardResponse as PollLeaderboardResponse; + } } diff --git a/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts new file mode 100644 index 000000000..17a288768 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts @@ -0,0 +1,43 @@ +import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; +import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; +import type { PollLeaderboardResponse } from './PollLeaderboardResponse'; + +type NumberString = string; + +export interface DecodedPollLeaderboardResponse + extends Pick { + entries?: DecodedHMSPollLeaderboardEntry[]; + summary?: DecodedHMSPollLeaderboardSummary; +} + +export interface DecodedHMSPollLeaderboardEntry + extends Pick { + /** + * convert this value to number + */ + duration?: NumberString | number; + /** + * convert this value to number + */ + totalResponses?: NumberString | number; + /** + * convert this value to number + */ + correctResponses?: NumberString | number; + /** + * convert this value to number + */ + position?: NumberString | number; + /** + * convert this value to number + */ + score?: NumberString | number; +} + +export interface DecodedHMSPollLeaderboardSummary + extends Omit { + /** + * convert this value to number + */ + averageTime?: NumberString | number; +} diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts new file mode 100644 index 000000000..5ed159de5 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts @@ -0,0 +1,10 @@ +import type { HMSPollResponsePeerInfo } from './HMSPollResponsePeerInfo'; + +export interface HMSPollLeaderboardEntry { + duration?: number; + totalResponses?: number; + correctResponses?: number; + position?: number; + score?: number; + peer?: HMSPollResponsePeerInfo; +} diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts new file mode 100644 index 000000000..860d22b09 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts @@ -0,0 +1,7 @@ +export interface HMSPollLeaderboardSummary { + averageScore?: number; + averageTime?: number; + respondedCorrectlyPeersCount?: number; + respondedPeersCount?: number; + totalPeersCount?: number; +} diff --git a/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts new file mode 100644 index 000000000..c4b3bd9c7 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts @@ -0,0 +1,8 @@ +import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; +import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; + +export interface PollLeaderboardResponse { + entries?: HMSPollLeaderboardEntry[]; + hasNext?: boolean; + summary?: HMSPollLeaderboardSummary; +} From 962a405ee835f86339e73688fea3651a05e470ef Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Fri, 23 Feb 2024 15:25:28 +0530 Subject: [PATCH 02/14] implemented fetch leaderboard on iOS --- .../Interactivity/HMSRNInteractivityCenter.kt | 16 +++--- .../ios/HMSInteractivityDecoder.swift | 50 +++++++++++++++++++ .../react-native-hms/ios/HMSManager.swift | 9 ++++ .../ios/HMSRNInteractivityCenter.swift | 31 ++++++++++++ 4 files changed, 98 insertions(+), 8 deletions(-) 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 6eb46d17c..b2bb03e56 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 @@ -63,23 +63,23 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6002", "pollId is required") + promise?.reject("6004", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") return } val pollQuestionIndex = data.getInt("pollQuestionIndex") val pollQuestion = poll.questions?.find { it.questionID == pollQuestionIndex } if (pollQuestion == null) { - promise?.reject("6002", "No HMSPollQuestion in poll with given question index") + promise?.reject("6004", "No HMSPollQuestion in poll with given question index") return } val responses = data.getMap("responses") if (responses == null) { - promise?.reject("6002", "responses field is required") + promise?.reject("6004", "responses field is required") return } val pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll, pollQuestion) @@ -103,12 +103,12 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6002", "pollId is required") + promise?.reject("6004", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") return } this.sdk.getHmsInteractivityCenter().stop( @@ -131,12 +131,12 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6002", "pollId is required") + promise?.reject("6004", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") return } val count = data.getInt("count") diff --git a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift index 89d9b84d3..7df6f0120 100644 --- a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift +++ b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift @@ -220,4 +220,54 @@ class HMSInteractivityDecoder { } return result } + + static func getLeaderboardResponse(_ response: HMSPollLeaderboardResponse) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["hasNext"] = response.hasNext + + result["summary"] = getLeaderboardSummary(response.summary) + + result["entries"] = getLeaderboardEntries(response.entries) + + return result + } + + static func getLeaderboardSummary(_ summary: HMSPollLeaderboardSummary) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["averageScore"] = summary.averageScore + result["averageTime"] = summary.averageTime + result["totalPeersCount"] = summary.totalPeersCount + result["respondedCorrectlyPeersCount"] = summary.respondedCorrectlyPeersCount + result["respondedPeersCount"] = summary.respondedPeersCount + + return result + } + + static func getLeaderboardEntries(_ entries: [HMSPollLeaderboardEntry]) -> [[String: AnyHashable]] { + var result = [[String: AnyHashable]]() + + for entry in entries { + result.append(getLeaderboardEntry(entry)) + } + + return result + } + + static func getLeaderboardEntry(_ entry: HMSPollLeaderboardEntry) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["duration"] = entry.duration + result["totalResponses"] = entry.totalResponses + result["correctResponses"] = entry.correctResponses + result["position"] = entry.position + result["score"] = entry.score + + if let peer = entry.peer { + result["peer"] = getHMSPollResponsePeerInfo(peer) + } + + return result + } } diff --git a/packages/react-native-hms/ios/HMSManager.swift b/packages/react-native-hms/ios/HMSManager.swift index 1f99c40be..ab02cbf61 100644 --- a/packages/react-native-hms/ios/HMSManager.swift +++ b/packages/react-native-hms/ios/HMSManager.swift @@ -672,4 +672,13 @@ class HMSManager: RCTEventEmitter { } interactivity.stop(data, resolve, reject) } + + @objc + func fetchLeaderboard(_ 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.fetchLeaderboard(data, resolve, reject) + } } diff --git a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift index 4ca6a6423..abccab8b5 100644 --- a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift +++ b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift @@ -86,4 +86,35 @@ class HMSRNInteractivityCenter { resolve?(success) }) } + + func fetchLeaderboard(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let pollId = data["pollId"] as? String, + let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { + reject?("6004", "Unable to find HMSPoll with given pollId", nil) + return + } + + guard let count = data["count"] as? Int, + let startIndex = data["startIndex"] as? Int + else { + reject?("6004", "Unable to find required parameters", nil) + return + } + + let includeCurrentPeer = data["includeCurrentPeer"] as? Bool ?? false + + self.hmssdk?.interactivityCenter.fetchLeaderboard(for: poll, offset: startIndex, count: count, includeCurrentPeer: includeCurrentPeer) { response, error in + + if let nonnilError = error { + reject?("6004", nonnilError.localizedDescription, nil) + return + } + + if let response = response { + resolve?(HMSInteractivityDecoder.getLeaderboardResponse(response)) + } else { + reject?("6004", "Could not fetch leaderboard response", nil) + } + } + } } From 91c05aa5d1c43f745aeac55d35e742de84b3846e Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Fri, 23 Feb 2024 15:25:57 +0530 Subject: [PATCH 03/14] updated linter --- .trunk/trunk.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index f77141417..28bf6df39 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 1.20.0 + version: 1.20.1 plugins: sources: - id: trunk @@ -13,9 +13,9 @@ lint: - actionlint@1.6.26 - prettier@3.2.5 - swiftlint@0.54.0 - - checkov@3.2.22 + - checkov@3.2.24 - trivy@0.49.1 - - trufflehog@3.67.6 + - trufflehog@3.68.0 - oxipng@9.0.0 - yamllint@1.35.1 - ktlint@1.1.1 From a5b28c5784669fbfecec3befc70ee60a1751fa3e Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Fri, 23 Feb 2024 17:17:20 +0530 Subject: [PATCH 04/14] navigation stack changes in polls modal --- .../src/components/CreatePoll.tsx | 9 +- .../HMSPollsQuizzesNotification.tsx | 4 +- .../src/components/PollAndQuizSheetScreen.tsx | 31 +++ .../src/components/PollAndQuizVoting.tsx | 131 ++++++++++- .../src/components/PollQuestions.tsx | 214 ++++++++++++++---- .../components/PollsAndQuizBottomSheet.tsx | 52 +---- .../src/components/PollsAndQuizzesCard.tsx | 4 +- .../PollsAndQuizzesModalContent.tsx | 186 ++------------- .../src/components/PollsConfigAndList.tsx | 118 +++++++++- .../PreviousPollsAndQuizzesList.tsx | 73 +++--- .../src/redux/actionTypes.ts | 23 +- .../src/redux/actions/index.ts | 25 +- .../src/redux/reducers/polls.ts | 24 +- 13 files changed, 566 insertions(+), 328 deletions(-) create mode 100644 packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx diff --git a/packages/react-native-room-kit/src/components/CreatePoll.tsx b/packages/react-native-room-kit/src/components/CreatePoll.tsx index 90d9886de..a857ee3ac 100644 --- a/packages/react-native-room-kit/src/components/CreatePoll.tsx +++ b/packages/react-native-room-kit/src/components/CreatePoll.tsx @@ -9,7 +9,11 @@ import { HMSTextInput } from './HMSTextInput'; import { HMSPrimaryButton } from './HMSPrimaryButton'; import { COLORS } from '../utils/theme'; import type { RootState } from '../redux'; -import { setPollConfig, setPollName, setPollStage } from '../redux/actions'; +import { + pushToNavigationStack, + setPollConfig, + setPollName, +} from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import type { PollConfig } from '../redux/actionTypes'; import { PollIcon, QuizIcon } from '../Icons'; @@ -67,7 +71,7 @@ export const CreatePoll: React.FC = ({}) => { const addQuestions = () => { if (pollName.trim().length > 0) { - dispatch(setPollStage(CreatePollStages.POLL_QUESTION_CONFIG)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_QUESTION_CONFIG)); } }; @@ -230,6 +234,7 @@ const styles = StyleSheet.create({ }, createPollBtn: { marginTop: 24, + marginBottom: 16, }, contentContainer: { marginHorizontal: 24, diff --git a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx index 52151884c..c29334b82 100644 --- a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx +++ b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx @@ -14,8 +14,8 @@ import { import { HMSNotification } from './HMSNotification'; import { ModalTypes } from '../utils/types'; import { + pushToNavigationStack, removeNotification, - setPollStage, setSelectedPollId, } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; @@ -56,7 +56,7 @@ export const HMSPollsQuizzesNotification: React.FC< // return; // } batch(() => { - dispatch(setPollStage(CreatePollStages.POLL_VOTING)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); handleModalVisibleType(ModalTypes.POLLS_AND_QUIZZES); dispatch(removeNotification(id)); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx b/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx new file mode 100644 index 000000000..3db3d1469 --- /dev/null +++ b/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { StyleSheet } from 'react-native'; + +import Animated, { SlideInRight, SlideOutRight } from 'react-native-reanimated'; + +export interface PollAndQuizSheetScreenProps { + zIndex: number; +} + +export const PollAndQuizSheetScreen: React.FC = ({ + children, + zIndex, +}) => { + return ( + + {children} + + ); +}; + +const styles = StyleSheet.create({ + absolute: { + width: '100%', + height: '100%', + position: 'absolute', + }, +}); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx index 9b20f00e2..8bbf69b3a 100644 --- a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx +++ b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx @@ -6,22 +6,34 @@ import { findNodeHandle, UIManager, View, + Keyboard, + TouchableOpacity, } from 'react-native'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { HMSPollState, HMSPollType } from '@100mslive/react-native-hms'; import { useHMSInstance, useHMSRoomStyleSheet } from '../hooks-util'; import type { RootState } from '../redux'; import { HMSDangerButton } from './HMSDangerButton'; import { PollAndQuizQuestionResponseCards } from './PollAndQuizQuestionResponseCards'; +import { popFromNavigationStack } from '../redux/actions'; +import { BottomSheet } from './BottomSheet'; +import { ChevronIcon, CloseIcon } from '../Icons'; +import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; export interface PollAndQuizVotingProps { + currentIdx: number; dismissModal(): void; } -export const PollAndQuizVoting: React.FC = () => { +export const PollAndQuizVoting: React.FC = ({ + currentIdx, + dismissModal, +}) => { const scrollViewRef = React.useRef(null); const hmsInstance = useHMSInstance(); + const dispatch = useDispatch(); + const selectedPoll = useSelector((state: RootState) => { const pollsData = state.polls; if (pollsData.selectedPollId !== null) { @@ -33,6 +45,13 @@ export const PollAndQuizVoting: React.FC = () => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; }); + const headerTitle = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.selectedPollId !== null) { + return pollsData.polls[pollsData.selectedPollId]?.title || null; + } + return null; + }); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ regularMediumText: { @@ -43,6 +62,13 @@ export const PollAndQuizVoting: React.FC = () => { color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-SemiBold`, }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, })); const endPoll = async () => { @@ -79,8 +105,60 @@ export const PollAndQuizVoting: React.FC = () => { ); }; + const handleBackPress = () => { + Keyboard.dismiss(); + dispatch(popFromNavigationStack()); + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} + + + {headerTitle} + + + {selectedPoll?.state ? ( + + ) : null} + + + + + + + + {/* Divider */} + + + {/* Content */} = ({}) => { +export const PollQuestions: React.FC = ({ + currentIdx, + dismissModal, +}) => { const dispatch = useDispatch(); const hmsInstance = useHMSInstance(); const reduxStore = useStore(); @@ -50,6 +58,7 @@ export const PollQuestions: React.FC = ({}) => { const pollType = useSelector( (state: RootState) => state.polls.pollConfig.type ); + const headerTitle = useSelector((state: RootState) => state.polls.pollName); const questions = useSelector((state: RootState) => state.polls.questions); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ @@ -57,6 +66,13 @@ export const PollQuestions: React.FC = ({}) => { color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-Regular`, }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, })); const disableLaunchPoll = @@ -185,60 +201,113 @@ export const PollQuestions: React.FC = ({}) => { [] ); + const handleBackPress = () => { + Keyboard.dismiss(); + dispatch(popFromNavigationStack()); + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - - {questions.map((pollQuestion, idx, arr) => { - const isFirst = idx === 0; - return ( - - {isFirst ? null : } + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} - - - ); - })} + + {headerTitle} + + - - - - - - Add another question - + - - + {/* Divider */} + + + + {questions.map((pollQuestion, idx, arr) => { + const isFirst = idx === 0; + return ( + + {isFirst ? null : } + + + + ); + })} + + + + + + + + Add another question + + + + + + + + {/* Modal */} + + ); }; @@ -274,4 +343,51 @@ const styles = StyleSheet.create({ marginRight: 8, padding: 8, }, + + // ------- + + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, }); diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx index ca76f70b8..82144ce22 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx @@ -1,20 +1,12 @@ import * as React from 'react'; import { Platform, StyleSheet } from 'react-native'; -import { useSelector } from 'react-redux'; import { BottomSheet } from './BottomSheet'; -import { - useHMSRoomStyleSheet, - useIsHLSViewer, - useModalType, -} from '../hooks-util'; +import { useHMSRoomStyleSheet, useModalType } from '../hooks-util'; import { useHeaderHeight } from './Header'; import { useIsLandscapeOrientation } from '../utils/dimension'; import { PollsAndQuizzesModalContent } from './PollsAndQuizzesModalContent'; import { ModalTypes } from '../utils/types'; -import type { RootState } from '../redux'; -import { CreatePollStages } from '../redux/actionTypes'; -import { visiblePollsSelector } from '../utils/functions'; export const PollsAndQuizBottomSheet = () => { const headerHeight = useHeaderHeight(); @@ -24,20 +16,6 @@ export const PollsAndQuizBottomSheet = () => { handleModalVisibleType: setModalVisible, } = useModalType(); - const isPollQuestionStage = useSelector( - (state: RootState) => - state.polls.stage === CreatePollStages.POLL_QUESTION_CONFIG - ); - const isHLSViewer = useIsHLSViewer(); - const havePolls = useSelector( - (state: RootState) => - visiblePollsSelector( - Object.values(state.polls.polls), - isHLSViewer, - state.polls.cuedPollIds - ).length > 0 - ); - const hmsRoomStyles = useHMSRoomStyleSheet((theme) => ({ contentContainer: { backgroundColor: theme.palette.surface_dim, @@ -46,18 +24,15 @@ export const PollsAndQuizBottomSheet = () => { const dismissModal = () => setModalVisible(ModalTypes.DEFAULT); - const fullHeight = isPollQuestionStage || havePolls; - const containerStyles = fullHeight - ? [ - styles.bottomSheet, - { - marginTop: isLandscapeOrientation - ? 0 - : headerHeight + (Platform.OS === 'android' ? 24 : 0), - }, - hmsRoomStyles.contentContainer, - ] - : [hmsRoomStyles.contentContainer]; + const containerStyles = [ + styles.bottomSheet, + { + marginTop: isLandscapeOrientation + ? 0 + : headerHeight + (Platform.OS === 'android' ? 24 : 0), + }, + hmsRoomStyles.contentContainer, + ]; return ( { isVisible={modalVisible === ModalTypes.POLLS_AND_QUIZZES} avoidKeyboard={true} containerStyle={containerStyles} - bottomOffsetSpace={fullHeight ? 0 : undefined} + bottomOffsetSpace={0} > - + ); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx index 5b5445c42..2a1bbd929 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx @@ -5,7 +5,7 @@ import type { HMSPoll } from '@100mslive/react-native-hms'; import { useHMSRoomStyleSheet } from '../hooks-util'; import { HMSPrimaryButton } from './HMSPrimaryButton'; -import { setPollStage, setSelectedPollId } from '../redux/actions'; +import { pushToNavigationStack, setSelectedPollId } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; @@ -36,7 +36,7 @@ export const PollsAndQuizzesCard: React.FC = ({ const viewPoll = () => { batch(() => { - dispatch(setPollStage(CreatePollStages.POLL_VOTING)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); }); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx index 49d7e2872..dd109825e 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx @@ -1,62 +1,25 @@ import * as React from 'react'; -import { - View, - Text, - StyleSheet, - TouchableOpacity, - Keyboard, -} from 'react-native'; -import { useDispatch, useSelector } from 'react-redux'; +import { View, StyleSheet } from 'react-native'; +import { useSelector } from 'react-redux'; import type { RootState } from '../redux'; -import { useHMSRoomStyleSheet } from '../hooks-util'; -import { BottomSheet } from './BottomSheet'; -import { ChevronIcon, CloseIcon } from '../Icons'; -import { TestIds } from '../utils/constants'; import { PollQuestions } from './PollQuestions'; import { CreatePollStages } from '../redux/actionTypes'; -import { setPollStage } from '../redux/actions'; -import { PollQDeleteConfirmationSheetView } from './PollQDeleteConfirmationSheetView'; import { PollsConfigAndList } from './PollsConfigAndList'; import { PollAndQuizVoting } from './PollAndQuizVoting'; -import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; +import { PollAndQuizSheetScreen } from './PollAndQuizSheetScreen'; export interface PollsAndQuizzesModalContentProps { - fullHeight: boolean; dismissModal(): void; } export const PollsAndQuizzesModalContent: React.FC< PollsAndQuizzesModalContentProps -> = ({ fullHeight, dismissModal }) => { - const dispatch = useDispatch(); - const headerTitle = useSelector((state: RootState) => { - const pollsData = state.polls; - if (pollsData.stage === CreatePollStages.POLL_QUESTION_CONFIG) { - return pollsData.pollName; - } - if ( - pollsData.stage === CreatePollStages.POLL_VOTING && - pollsData.selectedPollId !== null - ) { - return pollsData.polls[pollsData.selectedPollId]?.title || null; - } - return null; - }); - const selectedPoll = useSelector((state: RootState) => { - const pollsData = state.polls; - if ( - pollsData.stage === CreatePollStages.POLL_VOTING && - pollsData.selectedPollId !== null - ) { - return pollsData.polls[pollsData.selectedPollId] || null; - } - return null; - }); - const pollsStage = useSelector((state: RootState) => state.polls.stage); - const launchingPoll = useSelector( - (state: RootState) => state.polls.launchingPoll +> = ({ dismissModal }) => { + const pollsNavigationStack = useSelector( + (state: RootState) => state.polls.navigationStack ); + const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -66,133 +29,30 @@ export const PollsAndQuizzesModalContent: React.FC< return permissions?.pollRead; }); - const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ - headerText: { - color: theme.palette.on_surface_high, - fontFamily: `${typography.font_family}-SemiBold`, - }, - })); - - const handleBackPress = () => { - Keyboard.dismiss(); - dispatch(setPollStage(CreatePollStages.POLL_CONFIG)); - }; - - const handleClosePress = () => { - Keyboard.dismiss(); - dismissModal(); - }; - return ( - - {/* Header */} - - - {headerTitle ? ( - - - + + {pollsNavigationStack.map((stage, index) => ( + + {stage === CreatePollStages.POLL_CONFIG ? ( + + ) : stage === CreatePollStages.POLL_QUESTION_CONFIG && + canCreateOrEndPoll ? ( + + ) : stage === CreatePollStages.POLL_VOTING && + (canVoteOnPoll || canCreateOrEndPoll) ? ( + ) : null} - - - {headerTitle ?? 'Polls and Quizzes'} - - - {selectedPoll?.state ? ( - - ) : null} - - - - - - - - {/* Divider */} - - - {/* Content */} - - {pollsStage === CreatePollStages.POLL_CONFIG ? ( - - ) : pollsStage === CreatePollStages.POLL_QUESTION_CONFIG && - canCreateOrEndPoll ? ( - - ) : pollsStage === CreatePollStages.POLL_VOTING && - (canVoteOnPoll || canCreateOrEndPoll) ? ( - - ) : null} - - - {/* Modal */} - + + ))} ); }; const styles = StyleSheet.create({ - // Utilities + relative: { + position: 'relative', + }, fullView: { flex: 1, }, - // Header - header: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginTop: 24, - marginHorizontal: 24, - }, - headerControls: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1, - }, - headerText: { - fontSize: 20, - lineHeight: 24, - letterSpacing: 0.15, - marginRight: 12, - }, - closeIconHitSlop: { - bottom: 16, - left: 16, - right: 16, - top: 16, - }, - backIcon: { - marginRight: 8, - }, - // Divider - halfDivider: { - marginHorizontal: 24, - marginVertical: 0, - marginTop: 24, - width: undefined, - }, - divider: { - marginHorizontal: 24, - marginVertical: 24, - width: undefined, - }, }); diff --git a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx index fc0e5afd2..f339f705b 100644 --- a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx +++ b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx @@ -1,14 +1,38 @@ import * as React from 'react'; -import { ScrollView } from 'react-native'; +import { + Keyboard, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import { useSelector } from 'react-redux'; import { CreatePoll } from './CreatePoll'; import { PreviousPollsAndQuizzesList } from './PreviousPollsAndQuizzesList'; -import { useSelector } from 'react-redux'; -import type { RootState } from 'src/redux'; +import type { RootState } from '../redux'; +import { BottomSheet } from './BottomSheet'; +import { CloseIcon } from '../Icons'; +import { useHMSRoomStyleSheet } from '../hooks-util'; -export interface PollsConfigAndListProps {} +export interface PollsConfigAndListProps { + dismissModal(): void; +} + +export const PollsConfigAndList: React.FC = ({ + dismissModal, +}) => { + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + container: { + backgroundColor: theme.palette.surface_dim, + }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + })); -export const PollsConfigAndList: React.FC = ({}) => { const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -18,12 +42,84 @@ export const PollsConfigAndList: React.FC = ({}) => { return permissions?.pollRead; }); + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - - {canCreateOrEndPoll ? : null} - {canVoteOnPoll || canCreateOrEndPoll ? ( - - ) : null} - + + {/* Header */} + + + Polls and Quizzes + + + + + + + + {/* Divider */} + + + {/* Content */} + + {canCreateOrEndPoll ? : null} + {canVoteOnPoll || canCreateOrEndPoll ? ( + + ) : null} + + ); }; + +const styles = StyleSheet.create({ + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + // marginVertical: 0, + // marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, +}); diff --git a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx index 3b8895f7a..56ab93d19 100644 --- a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx +++ b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx @@ -18,11 +18,6 @@ export const PreviousPollsAndQuizzesList: React.FC< (state: RootState) => state.polls.cuedPollIds ); - const canCreateOrEndPoll = useSelector((state: RootState) => { - const permissions = state.hmsStates.localPeer?.role?.permissions; - return permissions?.pollWrite; - }); - const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ surfaceHighSemiBoldText: { color: theme.palette.on_surface_high, @@ -40,44 +35,42 @@ export const PreviousPollsAndQuizzesList: React.FC< hlsCuedPollIds ); - if (pollsList.length === 0 && !canCreateOrEndPoll) { - return ( - - - No Polls or Quizzes to show - - - ); - } - return ( - {pollsList.length > 0 && ( - - Previous Polls And Quizzes - - )} + + Previous Polls And Quizzes + - {pollsList - .sort((a, b) => { - return a.state === b.state // If polls have same state, then sort as per startedAt - ? a.startedAt !== undefined && b.startedAt !== undefined - ? b.startedAt.getTime() - a.startedAt.getTime() - : 0 - : // If polls have different state, then sort as per state - a.state !== undefined && b.state !== undefined - ? a.state - b.state - : 0; - }) - .map((poll) => ( - - ))} + {pollsList.length <= 0 ? ( + + + No Polls or Quizzes to show + + + ) : ( + <> + {pollsList + .sort((a, b) => { + return a.state === b.state // If polls have same state, then sort as per startedAt + ? a.startedAt !== undefined && b.startedAt !== undefined + ? b.startedAt.getTime() - a.startedAt.getTime() + : 0 + : // If polls have different state, then sort as per state + a.state !== undefined && b.state !== undefined + ? a.state - b.state + : 0; + }) + .map((poll) => ( + + ))} + + )} ); }; diff --git a/packages/react-native-room-kit/src/redux/actionTypes.ts b/packages/react-native-room-kit/src/redux/actionTypes.ts index 1c6606270..f3a94b1e2 100644 --- a/packages/react-native-room-kit/src/redux/actionTypes.ts +++ b/packages/react-native-room-kit/src/redux/actionTypes.ts @@ -217,7 +217,9 @@ export type PollsActionType = | SetDeleteConfirmationVisible | SetPollNameAction | SetPollConfigAction - | SetPollStageAction + | PushToNavigationStackAction + | PopFromNavigationStackAction + | ReplaceTopOfNavigationStackAction | AddPollQuestionAction | DeletePollQuestionAction | SetSelectedQuestionIndexAction @@ -262,9 +264,18 @@ export type SetPollConfigAction = { pollConfig: Partial; }; -export type SetPollStageAction = { - type: PollsStateActionTypes.SET_POLL_STAGE; - pollStage: CreatePollStages; +export type PushToNavigationStackAction = { + type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK; + screen: CreatePollStages; +}; + +export type PopFromNavigationStackAction = { + type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK; +}; + +export type ReplaceTopOfNavigationStackAction = { + type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK; + screen: CreatePollStages; }; export type AddPollQuestionAction = { @@ -396,7 +407,9 @@ export enum PollsStateActionTypes { SET_DELETE_CONFIRMATION_VISIBLE = 'SET_DELETE_CONFIRMATION_VISIBLE', SET_POLL_NAME = 'SET_POLL_NAME', SET_POLL_CONFIG = 'SET_POLL_CONFIG', - SET_POLL_STAGE = 'SET_POLL_STAGE', + PUSH_TO_NAVIGATION_STACK = 'PUSH_TO_NAVIGATION_STACK', + POP_FROM_NAVIGATION_STACK = 'POP_FROM_NAVIGATION_STACK', + REPLACE_TOP_OF_NAVIGATION_STACK = 'REPLACE_TOP_OF_NAVIGATION_STACK', ADD_POLL_QUESTION = 'ADD_POLL_QUESTION', DELETE_POLL_QUESTION = 'DELETE_POLL_QUESTION', SET_SELECTED_QUESTION_INDEX = 'SET_SELECTED_QUESTION_INDEX', 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 2d5d6ce52..164e54b45 100644 --- a/packages/react-native-room-kit/src/redux/actions/index.ts +++ b/packages/react-native-room-kit/src/redux/actions/index.ts @@ -32,7 +32,6 @@ import type { AddPollQuestionAction, SetPollConfigAction, SetPollNameAction, - SetPollStageAction, DeletePollQuestionAction, SetDeleteConfirmationVisible, SetSelectedQuestionIndexAction, @@ -54,6 +53,9 @@ import type { RemovePollQuestionResponseAction, SetQuestionPointWeightageAction, SetQuestionCorrectOptionAction, + PushToNavigationStackAction, + PopFromNavigationStackAction, + ReplaceTopOfNavigationStackAction, } from '../actionTypes'; import { MeetingState } from '../../types'; import type { ChatState, Notification, PinnedMessage } from '../../types'; @@ -491,11 +493,22 @@ export const setPollConfig = ( pollConfig, }); -export const setPollStage = ( - pollStage: SetPollStageAction['pollStage'] -): SetPollStageAction => ({ - type: PollsStateActionTypes.SET_POLL_STAGE, - pollStage, +export const pushToNavigationStack = ( + screen: PushToNavigationStackAction['screen'] +): PushToNavigationStackAction => ({ + type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK, + screen, +}); + +export const popFromNavigationStack = (): PopFromNavigationStackAction => ({ + type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK, +}); + +export const replaceTopOfNavigationStack = ( + screen: ReplaceTopOfNavigationStackAction['screen'] +): ReplaceTopOfNavigationStackAction => ({ + type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK, + screen, }); export const addPollQuestion = (): AddPollQuestionAction => ({ diff --git a/packages/react-native-room-kit/src/redux/reducers/polls.ts b/packages/react-native-room-kit/src/redux/reducers/polls.ts index 3daedf71d..a1d7573ad 100644 --- a/packages/react-native-room-kit/src/redux/reducers/polls.ts +++ b/packages/react-native-room-kit/src/redux/reducers/polls.ts @@ -30,7 +30,7 @@ function getDefaultQuestionObj(): PollQuestionUI { type IntialStateType = { pollName: string; pollConfig: PollConfig; - stage: CreatePollStages; + navigationStack: CreatePollStages[]; questions: PollQuestionUI[]; deleteConfirmationVisible: boolean; selectedPollQuestionIndex: number | null; @@ -48,7 +48,7 @@ const INITIAL_STATE: IntialStateType = { voteCountHidden: false, resultsAnonymous: false, }, - stage: CreatePollStages.POLL_CONFIG, + navigationStack: [CreatePollStages.POLL_CONFIG], questions: [getDefaultQuestionObj()], deleteConfirmationVisible: false, selectedPollQuestionIndex: null, @@ -87,11 +87,25 @@ const hmsStatesReducer = ( : state.questions, selectedPollQuestionIndex: null, }; - case PollsStateActionTypes.SET_POLL_STAGE: + case PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK: return { ...state, - stage: action.pollStage, - selectedPollQuestionIndex: null, + navigationStack: [...state.navigationStack, action.screen], + }; + case PollsStateActionTypes.POP_FROM_NAVIGATION_STACK: { + const updatedNavigationStack = [...state.navigationStack]; + updatedNavigationStack.pop(); + return { + ...state, + navigationStack: updatedNavigationStack, + }; + } + case PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK: + const updatedNavigationStack = [...state.navigationStack]; + updatedNavigationStack[updatedNavigationStack.length - 1] = action.screen; + return { + ...state, + navigationStack: updatedNavigationStack, }; case PollsStateActionTypes.ADD_POLL_QUESTION: return { From e4ed5de867909bd34b086e1ef5d4751d862aa0db Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Mon, 26 Feb 2024 21:07:07 +0530 Subject: [PATCH 05/14] updated package version --- .../example/android/Gemfile.lock | 28 +- .../react-native-hms/example/ios/Gemfile.lock | 28 +- .../react-native-hms/example/ios/Podfile.lock | 8 +- .../example/package-lock.json | 208 ++++---- .../react-native-hms/example/package.json | 2 +- packages/react-native-hms/package-lock.json | 174 ++++--- packages/react-native-hms/package.json | 2 +- packages/react-native-hms/sdk-versions.json | 2 +- .../example/package-lock.json | 192 ++++---- .../example/package.json | 2 +- .../react-native-room-kit/package-lock.json | 457 ++++++++++-------- packages/react-native-room-kit/package.json | 2 +- 12 files changed, 608 insertions(+), 497 deletions(-) diff --git a/packages/react-native-hms/example/android/Gemfile.lock b/packages/react-native-hms/example/android/Gemfile.lock index a282dd465..788c5cb1d 100644 --- a/packages/react-native-hms/example/android/Gemfile.lock +++ b/packages/react-native-hms/example/android/Gemfile.lock @@ -10,12 +10,11 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.893.0) - aws-sdk-core (3.191.2) + aws-partitions (1.894.0) + aws-sdk-core (3.191.3) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) - base64 jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.77.0) aws-sdk-core (~> 3, >= 3.191.0) @@ -113,9 +112,9 @@ GEM google-apis-firebaseappdistribution_v1 (~> 0.3.0) google-apis-firebaseappdistribution_v1alpha (~> 0.2.0) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.57.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-core (0.13.0) + google-apis-androidpublisher_v3 (0.58.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-core (0.14.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 1.9) httpclient (>= 2.8.1, < 3.a) @@ -127,19 +126,19 @@ GEM google-apis-core (>= 0.11.0, < 2.a) google-apis-firebaseappdistribution_v1alpha (0.2.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-iamcredentials_v1 (0.18.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-playcustomapp_v1 (0.14.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-storage_v1 (0.33.0) - google-apis-core (>= 0.12.0, < 2.a) + google-apis-iamcredentials_v1 (0.19.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-playcustomapp_v1 (0.15.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-storage_v1 (0.34.0) + google-apis-core (>= 0.14.0, < 2.a) google-cloud-core (1.6.1) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (2.1.1) faraday (>= 1.0, < 3.a) google-cloud-errors (1.3.1) - google-cloud-storage (1.48.1) + google-cloud-storage (1.49.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-core (~> 0.13) @@ -161,7 +160,8 @@ GEM httpclient (2.8.3) jmespath (1.6.2) json (2.7.1) - jwt (2.7.1) + jwt (2.8.0) + base64 mini_magick (4.12.0) mini_mime (1.1.5) multi_json (1.15.0) diff --git a/packages/react-native-hms/example/ios/Gemfile.lock b/packages/react-native-hms/example/ios/Gemfile.lock index a015ee1d1..14a5b5b53 100644 --- a/packages/react-native-hms/example/ios/Gemfile.lock +++ b/packages/react-native-hms/example/ios/Gemfile.lock @@ -10,12 +10,11 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.893.0) - aws-sdk-core (3.191.2) + aws-partitions (1.894.0) + aws-sdk-core (3.191.3) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) - base64 jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.77.0) aws-sdk-core (~> 3, >= 3.191.0) @@ -110,9 +109,9 @@ GEM xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.57.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-core (0.13.0) + google-apis-androidpublisher_v3 (0.58.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-core (0.14.0) addressable (~> 2.5, >= 2.5.1) googleauth (~> 1.9) httpclient (>= 2.8.1, < 3.a) @@ -120,19 +119,19 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.a) rexml - google-apis-iamcredentials_v1 (0.18.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-playcustomapp_v1 (0.14.0) - google-apis-core (>= 0.12.0, < 2.a) - google-apis-storage_v1 (0.33.0) - google-apis-core (>= 0.12.0, < 2.a) + google-apis-iamcredentials_v1 (0.19.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-playcustomapp_v1 (0.15.0) + google-apis-core (>= 0.14.0, < 2.a) + google-apis-storage_v1 (0.34.0) + google-apis-core (>= 0.14.0, < 2.a) google-cloud-core (1.6.1) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (2.1.1) faraday (>= 1.0, < 3.a) google-cloud-errors (1.3.1) - google-cloud-storage (1.48.1) + google-cloud-storage (1.49.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-core (~> 0.13) @@ -154,7 +153,8 @@ GEM httpclient (2.8.3) jmespath (1.6.2) json (2.7.1) - jwt (2.7.1) + jwt (2.8.0) + base64 mini_magick (4.12.0) mini_mime (1.1.5) multi_json (1.15.0) diff --git a/packages/react-native-hms/example/ios/Podfile.lock b/packages/react-native-hms/example/ios/Podfile.lock index 26f3d95ca..dfeef626c 100644 --- a/packages/react-native-hms/example/ios/Podfile.lock +++ b/packages/react-native-hms/example/ios/Podfile.lock @@ -292,7 +292,7 @@ PODS: - React-Core - react-native-document-picker (8.2.2): - React-Core - - react-native-hms (1.9.12): + - react-native-hms (1.10.0): - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) - HMSSDK (= 1.5.1) @@ -368,7 +368,7 @@ PODS: - React-perflogger (= 0.64.4) - rn-fetch-blob (0.12.0): - React-Core - - RNCAsyncStorage (1.22.0): + - RNCAsyncStorage (1.22.2): - React-Core - RNDeviceInfo (9.0.2): - React-Core @@ -649,7 +649,7 @@ SPEC CHECKSUMS: react-native-avoid-softinput: 71a692888f0c1d426ad9045dc8325773583962cd react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f react-native-document-picker: cd4d6b36a5207ad7a9e599ebb9eb0c2e84fa0b87 - react-native-hms: fd39afbf329480a7f6c09b6978f0116e90630970 + react-native-hms: 1987174d6b78d691a4a350c28cfed30f3c8756ff react-native-safe-area-context: 9e40fb181dac02619414ba1294d6c2a807056ab9 react-native-simple-toast: 8ee5d23f0b92b935ab7434cdb65159ce12dfb4b7 React-perflogger: 5a890ca0911669421b7611661e9b58f91c805f5c @@ -665,7 +665,7 @@ SPEC CHECKSUMS: React-runtimeexecutor: 5b441857030bb6c3abaa7517f333cb01875ae499 ReactCommon: b4a65d2d6e9eeffd4b32dde1245962b3f43907d0 rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba - RNCAsyncStorage: c43e6d71e13bb4748503797784839e0fbbf89d56 + RNCAsyncStorage: 014a78b2cc8cc107c9e92ee428dc0c1ac3223416 RNDeviceInfo: 1e3f62b9ec32f7754fac60bd06b8f8a27124e7f0 RNFlashList: ade81b4e928ebd585dd492014d40fb8d0e848aab RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 diff --git a/packages/react-native-hms/example/package-lock.json b/packages/react-native-hms/example/package-lock.json index 8636004c2..aed082181 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.9.12", + "version": "1.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "RNHMSExample", - "version": "1.9.12", + "version": "1.10.0", "hasInstallScript": true, "dependencies": { "@miblanchard/react-native-slider": "^2.0.2", @@ -2765,9 +2765,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2799,9 +2799,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2817,9 +2817,9 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.22.0.tgz", - "integrity": "sha512-b5KD010iiZnot86RbAaHpLuHwmPW2qA3SSN/OSZhd1kBoINEQEVBuv+uFtcaTxAhX27bT0wd13GOb2IOSDUXSA==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.22.2.tgz", + "integrity": "sha512-nZpzT4Wz1OkVdQaZP/awpDCTKiPzdmG0PYmRF37ZeJlfwlwOg55in0TP2YUOW0MhOCRiNMomWWLojDLv5j2OIw==", "dependencies": { "merge-options": "^3.0.4" }, @@ -3571,9 +3571,9 @@ "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" }, "node_modules/@react-navigation/core": { - "version": "6.4.10", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", - "integrity": "sha512-oYhqxETRHNHKsipm/BtGL0LI43Hs2VSFoWMbBdHK9OqgQPjTVUitslgLcPpo4zApCcmBWoOLX2qPxhsBda644A==", + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.11.tgz", + "integrity": "sha512-kOCyOc1L0lAl53DbyNl3OkUJwSFKSaVCsV8leJawUXMXJ1FTT3nbS3xMOqbZuchxIbl8T62sZ7YnlWG/21rcMw==", "dependencies": { "@react-navigation/routers": "^6.1.9", "escape-string-regexp": "^4.0.0", @@ -3587,9 +3587,9 @@ } }, "node_modules/@react-navigation/elements": { - "version": "1.3.22", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.22.tgz", - "integrity": "sha512-HYKucs0TwQT8zMvgoZbJsY/3sZfzeP8Dk9IDv4agst3zlA7ReTx4+SROCG6VGC7JKqBCyQykHIwkSwxhapoc+Q==", + "version": "1.3.24", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.24.tgz", + "integrity": "sha512-zgZV50qjlv3/N+MzNV0DIRmtg30IZcR0+LaTQRP/OxLtveQkgUG6wIEKl6SXO2ykC9yF9V82msdCzKl9uPSQCA==", "peerDependencies": { "@react-navigation/native": "^6.0.0", "react": "*", @@ -3598,11 +3598,11 @@ } }, "node_modules/@react-navigation/native": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.10.tgz", - "integrity": "sha512-jDG89TbZItY7W7rIcS1RqT63vWOPD4XuQLNKqZO0DY7mKnKh/CGBd0eg3nDMXUl143Qp//IxJKe2TfBQRDEU4A==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.12.tgz", + "integrity": "sha512-t6y7sDCr0HlMf+5TuVjLjyi0ySs0eNGfreDKcWOMEi5wooNFM4LhcUCdEVylpwCPfjQMW/lNVomNromqZFM6HQ==", "dependencies": { - "@react-navigation/core": "^6.4.10", + "@react-navigation/core": "^6.4.11", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.1.23" @@ -3613,11 +3613,11 @@ } }, "node_modules/@react-navigation/native-stack": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.18.tgz", - "integrity": "sha512-PSe0qjROy8zD78ehW048NSuzWRktioSCJmB8LzWSR65ndgVaC2rO+xvgyjhHjqm01YdyVM1XTct2EorSjDV2Ow==", + "version": "6.9.20", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.20.tgz", + "integrity": "sha512-/QXOVJGLPNGv0RXisyI5ld9oaKAdVzwcF88Q1pOA1Icp8Yce036bcixJXBsVuUhqYCJ5cBtojWt5mW6za3cRBw==", "dependencies": { - "@react-navigation/elements": "^1.3.22", + "@react-navigation/elements": "^1.3.24", "warn-once": "^0.1.0" }, "peerDependencies": { @@ -3802,9 +3802,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", "dependencies": { "undici-types": "~5.26.4" } @@ -4564,10 +4564,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5148,9 +5151,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "funding": [ { "type": "opencollective", @@ -5803,9 +5806,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==" + "version": "1.4.681", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", + "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" }, "node_modules/emittery": { "version": "0.7.2", @@ -5995,14 +5998,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -7062,9 +7065,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/flow-parser": { @@ -7398,9 +7401,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -7749,9 +7752,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" }, "node_modules/is-accessor-descriptor": { "version": "1.0.1", @@ -8015,9 +8018,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -8100,12 +8103,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8323,9 +8329,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -9919,9 +9925,9 @@ } }, "node_modules/joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -11869,6 +11875,15 @@ "node": ">=0.10.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -13442,14 +13457,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14519,12 +14535,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -14533,15 +14549,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -14551,16 +14568,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -14570,14 +14588,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" diff --git a/packages/react-native-hms/example/package.json b/packages/react-native-hms/example/package.json index c4b07b1b7..b4e39cc73 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.9.12", + "version": "1.10.0", "private": true, "scripts": { "preinstall": "cd ../ && npm install && cd ./example", diff --git a/packages/react-native-hms/package-lock.json b/packages/react-native-hms/package-lock.json index 1f1274754..a77624a5b 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.9.12", + "version": "1.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@100mslive/react-native-hms", - "version": "1.9.12", + "version": "1.10.0", "license": "MIT", "dependencies": { "zustand": "^4.3.8" @@ -3417,9 +3417,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -3455,9 +3455,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -4673,9 +4673,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -5421,10 +5421,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -6019,9 +6022,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "dev": true, "funding": [ { @@ -6868,9 +6871,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", + "version": "1.4.681", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", + "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==", "dev": true }, "node_modules/emittery": { @@ -7068,14 +7071,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -8158,9 +8161,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/flow-parser": { @@ -8582,9 +8585,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -9145,9 +9148,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "node_modules/is-absolute": { @@ -9458,9 +9461,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -9585,12 +9588,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9843,9 +9849,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -11429,9 +11435,9 @@ } }, "node_modules/joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", "dev": true, "dependencies": { "@hapi/hoek": "^9.3.0", @@ -13609,6 +13615,15 @@ "node": ">=0.10.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -15234,14 +15249,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16414,12 +16430,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -16428,15 +16444,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -16446,16 +16463,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -16465,14 +16483,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" diff --git a/packages/react-native-hms/package.json b/packages/react-native-hms/package.json index 571affa8a..361526d43 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.9.12", + "version": "1.10.0", "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 08b197f16..4bcdd75d3 100644 --- a/packages/react-native-hms/sdk-versions.json +++ b/packages/react-native-hms/sdk-versions.json @@ -2,5 +2,5 @@ "ios": "1.5.1", "iOSBroadcastExtension": "0.0.9", "iOSHMSHLSPlayer": "0.0.2", - "android": "2.9.3" + "android": "2.9.4" } diff --git a/packages/react-native-room-kit/example/package-lock.json b/packages/react-native-room-kit/example/package-lock.json index c947716f0..c6756b0bc 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.2", + "version": "1.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "RNExample", - "version": "1.1.2", + "version": "1.1.3", "dependencies": { "@react-native-async-storage/async-storage": "1.17.11", "@react-native-community/blur": "^4.3.2", @@ -2901,9 +2901,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2935,9 +2935,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4078,9 +4078,9 @@ "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==" }, "node_modules/@react-navigation/core": { - "version": "6.4.10", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", - "integrity": "sha512-oYhqxETRHNHKsipm/BtGL0LI43Hs2VSFoWMbBdHK9OqgQPjTVUitslgLcPpo4zApCcmBWoOLX2qPxhsBda644A==", + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.11.tgz", + "integrity": "sha512-kOCyOc1L0lAl53DbyNl3OkUJwSFKSaVCsV8leJawUXMXJ1FTT3nbS3xMOqbZuchxIbl8T62sZ7YnlWG/21rcMw==", "dependencies": { "@react-navigation/routers": "^6.1.9", "escape-string-regexp": "^4.0.0", @@ -4094,9 +4094,9 @@ } }, "node_modules/@react-navigation/elements": { - "version": "1.3.22", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.22.tgz", - "integrity": "sha512-HYKucs0TwQT8zMvgoZbJsY/3sZfzeP8Dk9IDv4agst3zlA7ReTx4+SROCG6VGC7JKqBCyQykHIwkSwxhapoc+Q==", + "version": "1.3.24", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.24.tgz", + "integrity": "sha512-zgZV50qjlv3/N+MzNV0DIRmtg30IZcR0+LaTQRP/OxLtveQkgUG6wIEKl6SXO2ykC9yF9V82msdCzKl9uPSQCA==", "peerDependencies": { "@react-navigation/native": "^6.0.0", "react": "*", @@ -4309,9 +4309,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", "dependencies": { "undici-types": "~5.26.4" } @@ -4367,9 +4367,9 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -5265,10 +5265,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5813,9 +5816,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "funding": [ { "type": "opencollective", @@ -6477,9 +6480,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==" + "version": "1.4.681", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", + "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" }, "node_modules/emittery": { "version": "0.7.2", @@ -6669,14 +6672,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -7755,9 +7758,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/flow-parser": { @@ -8138,9 +8141,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -8486,9 +8489,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" }, "node_modules/is-accessor-descriptor": { "version": "1.0.1", @@ -8752,9 +8755,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -8837,12 +8840,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9060,9 +9066,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -10696,9 +10702,9 @@ } }, "node_modules/joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -12725,6 +12731,15 @@ "node": ">=0.10.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -14267,14 +14282,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -15335,12 +15351,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -15349,15 +15365,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -15367,16 +15384,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -15386,14 +15404,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" diff --git a/packages/react-native-room-kit/example/package.json b/packages/react-native-room-kit/example/package.json index eee7202b9..31b06e073 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.2", + "version": "1.1.3", "private": true, "scripts": { "android": "react-native run-android", diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index d439b306c..0ad3aa1ad 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.2", + "version": "1.1.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@100mslive/react-native-room-kit", - "version": "1.1.2", + "version": "1.1.3", "license": "MIT", "dependencies": { "@100mslive/types-prebuilt": "^0.12.4", @@ -2760,18 +2760,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@evilmartians/lefthook": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.1.tgz", - "integrity": "sha512-4E35gOuECaf/+DaA0m1Q1U3BnaQclAUgK2UOYPyQOU0mCnvbMIqNJFiq2ArYuECEUIkTtAjoIzs1xkNFqUaOLQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.2.tgz", + "integrity": "sha512-i+tYp0jAjuoReqfYE3WDEs/dBdx1rOrsq6DH/u2Kf+YZTrf+MXkww0kadSew8merbNkMNt5nqVE5iFNV7q4tjA==", "cpu": [ "x64", "arm64", @@ -3733,9 +3733,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3767,9 +3767,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -5187,9 +5187,9 @@ "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" }, "node_modules/@react-navigation/core": { - "version": "6.4.10", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", - "integrity": "sha512-oYhqxETRHNHKsipm/BtGL0LI43Hs2VSFoWMbBdHK9OqgQPjTVUitslgLcPpo4zApCcmBWoOLX2qPxhsBda644A==", + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.11.tgz", + "integrity": "sha512-kOCyOc1L0lAl53DbyNl3OkUJwSFKSaVCsV8leJawUXMXJ1FTT3nbS3xMOqbZuchxIbl8T62sZ7YnlWG/21rcMw==", "dependencies": { "@react-navigation/routers": "^6.1.9", "escape-string-regexp": "^4.0.0", @@ -5203,11 +5203,11 @@ } }, "node_modules/@react-navigation/native": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.10.tgz", - "integrity": "sha512-jDG89TbZItY7W7rIcS1RqT63vWOPD4XuQLNKqZO0DY7mKnKh/CGBd0eg3nDMXUl143Qp//IxJKe2TfBQRDEU4A==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.12.tgz", + "integrity": "sha512-t6y7sDCr0HlMf+5TuVjLjyi0ySs0eNGfreDKcWOMEi5wooNFM4LhcUCdEVylpwCPfjQMW/lNVomNromqZFM6HQ==", "dependencies": { - "@react-navigation/core": "^6.4.10", + "@react-navigation/core": "^6.4.11", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.1.23" @@ -5558,9 +5558,9 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -6384,10 +6384,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7134,9 +7137,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "funding": [ { "type": "opencollective", @@ -8339,9 +8342,9 @@ } }, "node_modules/default-browser/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -8831,9 +8834,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==" + "version": "1.4.681", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", + "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" }, "node_modules/emittery": { "version": "0.10.2", @@ -9036,14 +9039,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -9194,16 +9197,16 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -10225,9 +10228,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/flow-parser": { @@ -10874,9 +10877,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -11526,9 +11529,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" }, "node_modules/ip-address": { "version": "9.0.5", @@ -12027,9 +12030,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -12164,12 +12167,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12452,9 +12458,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -14161,9 +14167,9 @@ } }, "node_modules/joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -17502,6 +17508,15 @@ "node": ">=0.10.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -18171,9 +18186,9 @@ } }, "node_modules/react-native-reanimated": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.7.0.tgz", - "integrity": "sha512-KM+MKa3CJWqsF4GlOLLKBxTR2NEcrg5/HP9J2b6Dfgvll1sjZPywCOEEIh967SboEU8N9LjYZuoVm2UoXGxp2Q==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.7.1.tgz", + "integrity": "sha512-bapCxhnS58+GZynQmA/f5U8vRlmhXlI/WhYg0dqnNAGXHNIc+38ahRWcG8iK8e0R2v9M8Ky2ZWObEC6bmweofg==", "peer": true, "dependencies": { "@babel/plugin-transform-object-assign": "^7.16.7", @@ -19043,9 +19058,9 @@ } }, "node_modules/release-it/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -20000,14 +20015,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -20311,9 +20327,9 @@ } }, "node_modules/socks": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", - "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", "dev": true, "dependencies": { "ip-address": "^9.0.5", @@ -21175,12 +21191,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -21189,15 +21205,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -21207,16 +21224,17 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -21226,14 +21244,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -24043,15 +24067,15 @@ } }, "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@evilmartians/lefthook": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.1.tgz", - "integrity": "sha512-4E35gOuECaf/+DaA0m1Q1U3BnaQclAUgK2UOYPyQOU0mCnvbMIqNJFiq2ArYuECEUIkTtAjoIzs1xkNFqUaOLQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.2.tgz", + "integrity": "sha512-i+tYp0jAjuoReqfYE3WDEs/dBdx1rOrsq6DH/u2Kf+YZTrf+MXkww0kadSew8merbNkMNt5nqVE5iFNV7q4tjA==", "dev": true }, "@hapi/hoek": { @@ -24773,9 +24797,9 @@ } }, "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -24798,9 +24822,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -25920,9 +25944,9 @@ "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" }, "@react-navigation/core": { - "version": "6.4.10", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.10.tgz", - "integrity": "sha512-oYhqxETRHNHKsipm/BtGL0LI43Hs2VSFoWMbBdHK9OqgQPjTVUitslgLcPpo4zApCcmBWoOLX2qPxhsBda644A==", + "version": "6.4.11", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.11.tgz", + "integrity": "sha512-kOCyOc1L0lAl53DbyNl3OkUJwSFKSaVCsV8leJawUXMXJ1FTT3nbS3xMOqbZuchxIbl8T62sZ7YnlWG/21rcMw==", "requires": { "@react-navigation/routers": "^6.1.9", "escape-string-regexp": "^4.0.0", @@ -25933,11 +25957,11 @@ } }, "@react-navigation/native": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.10.tgz", - "integrity": "sha512-jDG89TbZItY7W7rIcS1RqT63vWOPD4XuQLNKqZO0DY7mKnKh/CGBd0eg3nDMXUl143Qp//IxJKe2TfBQRDEU4A==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.12.tgz", + "integrity": "sha512-t6y7sDCr0HlMf+5TuVjLjyi0ySs0eNGfreDKcWOMEi5wooNFM4LhcUCdEVylpwCPfjQMW/lNVomNromqZFM6HQ==", "requires": { - "@react-navigation/core": "^6.4.10", + "@react-navigation/core": "^6.4.11", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.1.23" @@ -26257,9 +26281,9 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "@types/stack-utils": { @@ -26845,10 +26869,13 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } }, "babel-core": { "version": "7.0.0-bridge.0", @@ -27373,9 +27400,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==" + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==" }, "capture-exit": { "version": "2.0.0", @@ -28239,9 +28266,9 @@ "dev": true }, "npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "requires": { "path-key": "^4.0.0" @@ -28590,9 +28617,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==" + "version": "1.4.681", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", + "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" }, "emittery": { "version": "0.10.2", @@ -28759,14 +28786,14 @@ } }, "es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "requires": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" } }, "es-shim-unscopables": { @@ -28871,16 +28898,16 @@ } }, "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -29619,9 +29646,9 @@ } }, "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "flow-parser": { @@ -30101,9 +30128,9 @@ } }, "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true }, "has-symbols": { @@ -30573,9 +30600,9 @@ } }, "ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" }, "ip-address": { "version": "9.0.5", @@ -30918,9 +30945,9 @@ "dev": true }, "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true }, "is-npm": { @@ -31001,12 +31028,12 @@ "dev": true }, "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" } }, "is-ssh": { @@ -31210,9 +31237,9 @@ } }, "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -32472,9 +32499,9 @@ "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==" }, "joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", "requires": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -35066,6 +35093,12 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -35648,9 +35681,9 @@ } }, "react-native-reanimated": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.7.0.tgz", - "integrity": "sha512-KM+MKa3CJWqsF4GlOLLKBxTR2NEcrg5/HP9J2b6Dfgvll1sjZPywCOEEIh967SboEU8N9LjYZuoVm2UoXGxp2Q==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.7.1.tgz", + "integrity": "sha512-bapCxhnS58+GZynQmA/f5U8vRlmhXlI/WhYg0dqnNAGXHNIc+38ahRWcG8iK8e0R2v9M8Ky2ZWObEC6bmweofg==", "peer": true, "requires": { "@babel/plugin-transform-object-assign": "^7.16.7", @@ -36199,9 +36232,9 @@ } }, "npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "requires": { "path-key": "^4.0.0" @@ -36901,14 +36934,15 @@ } }, "set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "requires": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" } }, "set-value": { @@ -37144,9 +37178,9 @@ } }, "socks": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", - "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", "dev": true, "requires": { "ip-address": "^9.0.5", @@ -37789,50 +37823,55 @@ "dev": true }, "typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "requires": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" } }, "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" } }, "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" } }, "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" } }, "typedarray": { diff --git a/packages/react-native-room-kit/package.json b/packages/react-native-room-kit/package.json index 33084ec29..425f6c888 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.2", + "version": "1.1.3", "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", From 199e43cdacb2bd431dbc152b15a652f77e278f6e Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Mon, 26 Feb 2024 22:13:50 +0530 Subject: [PATCH 06/14] updated react-native-hms peer dependency --- packages/react-native-room-kit/package-lock.json | 14 +++++++------- packages/react-native-room-kit/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index d439b306c..e51abca02 100644 --- a/packages/react-native-room-kit/package-lock.json +++ b/packages/react-native-room-kit/package-lock.json @@ -40,7 +40,7 @@ "node": ">= 16.0.0" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.9.11", + "@100mslive/react-native-hms": "1.9.12", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3", @@ -56,9 +56,9 @@ } }, "node_modules/@100mslive/react-native-hms": { - "version": "1.9.11", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.11.tgz", - "integrity": "sha512-fcPgejZvkwIRoAXazfOBrVzd6jBe093cJg1TkWRKydHHj6cEW1zLHqQbBMwwM5yjjju6MTNvei+qvZEPHjDneg==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.12.tgz", + "integrity": "sha512-eDrgjZkmk6jge4hJq77aOs1RvxKPGvCMbbRctqq6KAEZGNrsp1/GfXEbO+niqPfBZGMoeZSsb4IyZF/sjrm8Rg==", "peer": true, "dependencies": { "zustand": "^4.3.8" @@ -22196,9 +22196,9 @@ }, "dependencies": { "@100mslive/react-native-hms": { - "version": "1.9.11", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.11.tgz", - "integrity": "sha512-fcPgejZvkwIRoAXazfOBrVzd6jBe093cJg1TkWRKydHHj6cEW1zLHqQbBMwwM5yjjju6MTNvei+qvZEPHjDneg==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.12.tgz", + "integrity": "sha512-eDrgjZkmk6jge4hJq77aOs1RvxKPGvCMbbRctqq6KAEZGNrsp1/GfXEbO+niqPfBZGMoeZSsb4IyZF/sjrm8Rg==", "peer": true, "requires": { "zustand": "^4.3.8" diff --git a/packages/react-native-room-kit/package.json b/packages/react-native-room-kit/package.json index 33084ec29..6edf0d2c4 100644 --- a/packages/react-native-room-kit/package.json +++ b/packages/react-native-room-kit/package.json @@ -79,7 +79,7 @@ "typescript": "^5.0.2" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.9.11", + "@100mslive/react-native-hms": "1.9.12", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3", From 19035fdea3e6fdf28df23f5042cfa390a80a791a Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Mon, 26 Feb 2024 22:20:16 +0530 Subject: [PATCH 07/14] Revert "Merge branch 'feat/leaderboard' into develop" This reverts commit b9eae81d20f2c71704ff774f0f279125b35bd8e3, reversing changes made to e43454607c6788cf649cd2f00cfadaeed5a5e83f. --- .trunk/trunk.yaml | 6 +- .../java/com/reactnativehmssdk/HMSManager.kt | 18 -- .../Interactivity/HMSInteractivityDecoder.kt | 85 ------- .../Interactivity/HMSRNInteractivityCenter.kt | 100 ++++---- .../ios/HMSInteractivityDecoder.swift | 50 ---- .../react-native-hms/ios/HMSManager.swift | 9 - .../ios/HMSRNInteractivityCenter.swift | 31 --- .../src/classes/HMSInteractivityCenter.ts | 30 --- .../src/classes/HMSInteractivityEncoder.ts | 36 --- .../polls/DecodedPollLeaderboardResponse.ts | 43 ---- .../classes/polls/HMSPollLeaderboardEntry.ts | 10 - .../polls/HMSPollLeaderboardSummary.ts | 7 - .../classes/polls/PollLeaderboardResponse.ts | 8 - .../src/components/CreatePoll.tsx | 9 +- .../HMSPollsQuizzesNotification.tsx | 4 +- .../src/components/PollAndQuizSheetScreen.tsx | 31 --- .../src/components/PollAndQuizVoting.tsx | 131 +---------- .../src/components/PollQuestions.tsx | 214 ++++-------------- .../components/PollsAndQuizBottomSheet.tsx | 52 ++++- .../src/components/PollsAndQuizzesCard.tsx | 4 +- .../PollsAndQuizzesModalContent.tsx | 186 +++++++++++++-- .../src/components/PollsConfigAndList.tsx | 118 +--------- .../PreviousPollsAndQuizzesList.tsx | 73 +++--- .../src/redux/actionTypes.ts | 23 +- .../src/redux/actions/index.ts | 25 +- .../src/redux/reducers/polls.ts | 24 +- 26 files changed, 392 insertions(+), 935 deletions(-) delete mode 100644 packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts delete mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts delete mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts delete mode 100644 packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts delete mode 100644 packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 28bf6df39..f77141417 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 1.20.1 + version: 1.20.0 plugins: sources: - id: trunk @@ -13,9 +13,9 @@ lint: - actionlint@1.6.26 - prettier@3.2.5 - swiftlint@0.54.0 - - checkov@3.2.24 + - checkov@3.2.22 - trivy@0.49.1 - - trufflehog@3.68.0 + - trufflehog@3.67.6 - oxipng@9.0.0 - yamllint@1.35.1 - ktlint@1.1.1 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 f5b9980f4..77aa2b270 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 @@ -1396,24 +1396,6 @@ class HMSManager(reactContext: ReactApplicationContext) : "HMS SDK not initialized", ) } - - @ReactMethod - fun fetchLeaderboard( - data: ReadableMap, - promise: Promise?, - ) { - val rnSDK = HMSHelper.getHms(data, hmsCollection) - rnSDK?.let { sdk -> - sdk.interactivityCenter?.let { center -> - center.fetchLeaderboard(data, promise) - return - } - } - promise?.reject( - "6004", - "HMS SDK not initialized", - ) - } // endregion // region ActivityLifecycleCallbacks 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 44ecd3c18..83abde377 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 @@ -10,12 +10,8 @@ import live.hms.video.polls.models.answer.HMSPollQuestionAnswer import live.hms.video.polls.models.answer.HmsPollAnswer import live.hms.video.polls.models.answer.PollAnswerItem import live.hms.video.polls.models.answer.PollAnswerResponse -import live.hms.video.polls.models.network.HMSPollResponsePeerInfo import live.hms.video.polls.models.question.HMSPollQuestion import live.hms.video.polls.models.question.HMSPollQuestionOption -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 object HMSInteractivityDecoder { @@ -314,87 +310,6 @@ object HMSInteractivityDecoder { return results } - fun getPollLeaderboardResponse(pollLeaderboardResponse: PollLeaderboardResponse): WritableMap { - val results = Arguments.createMap() - - pollLeaderboardResponse.hasNext?.let { - results.putBoolean("hasNext", it) - } - pollLeaderboardResponse.summary?.let { - results.putMap("summary", getHMSPollLeaderboardSummary(it)) - } - pollLeaderboardResponse.entries?.let { - results.putArray("entries", getHMSPollLeaderboardEntries(it)) - } - return results - } - - private fun getHMSPollLeaderboardSummary(pollLeaderboardSummary: HMSPollLeaderboardSummary): WritableMap { - val summary = Arguments.createMap() - pollLeaderboardSummary.averageScore?.let { - summary.putDouble("averageScore", it.toDouble()) - } - pollLeaderboardSummary.averageTime?.let { - summary.putString("averageTime", it.toString()) - } - pollLeaderboardSummary.totalPeersCount?.let { - summary.putInt("totalPeersCount", it) - } - pollLeaderboardSummary.respondedCorrectlyPeersCount?.let { - summary.putInt("respondedCorrectlyPeersCount", it) - } - pollLeaderboardSummary.respondedPeersCount?.let { - summary.putInt("respondedPeersCount", it) - } - return summary - } - - private fun getHMSPollLeaderboardEntries(pollLeaderboardEntries: List): WritableArray { - val list = Arguments.createArray() - pollLeaderboardEntries.forEach { - list.pushMap(getHMSPollLeaderboardEntry(it)) - } - return list - } - - private fun getHMSPollLeaderboardEntry(pollLeaderboardEntry: HMSPollLeaderboardEntry): WritableMap { - val entry = Arguments.createMap() - pollLeaderboardEntry.duration?.let { - entry.putString("duration", it.toString()) - } - pollLeaderboardEntry.peer?.let { - entry.putMap("peer", getHMSPollResponsePeerInfo(it)) - } - pollLeaderboardEntry.totalResponses?.let { - entry.putString("totalResponses", it.toString()) - } - pollLeaderboardEntry.correctResponses?.let { - entry.putString("correctResponses", it.toString()) - } - pollLeaderboardEntry.position?.let { - entry.putString("position", it.toString()) - } - pollLeaderboardEntry.score?.let { - entry.putString("score", it.toString()) - } - return entry - } - - private fun getHMSPollResponsePeerInfo(pollResponsePeerInfo: HMSPollResponsePeerInfo): WritableMap { - val peerInfo = Arguments.createMap() - peerInfo.putString("userHash", pollResponsePeerInfo.hash) - pollResponsePeerInfo.peerid?.let { - peerInfo.putString("peerId", it) - } - pollResponsePeerInfo.userid?.let { - peerInfo.putString("customerUserId", it) - } - pollResponsePeerInfo.username?.let { - peerInfo.putString("userName", it) - } - return peerInfo - } - private fun getHMSPollQuestionResponseResult(hmsPollQuestionResponseResult: PollAnswerItem): WritableMap { val result = Arguments.createMap() 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..dde1b1cc6 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 @@ -1,4 +1,5 @@ package com.reactnativehmssdk +import android.util.Log import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap @@ -9,7 +10,6 @@ import live.hms.video.interactivity.HmsPollUpdateListener import live.hms.video.polls.models.HMSPollUpdateType import live.hms.video.polls.models.HmsPoll import live.hms.video.polls.models.answer.PollAnswerResponse -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 @@ -37,6 +37,8 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN } } + // region Create Polls + fun quickStartPoll( data: ReadableMap, promise: Promise?, @@ -57,29 +59,64 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } + /* + + func add(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let pollId = data["pollId"] as? String, + let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { + reject?("6004", "Unable to find HMSPoll with given pollId", nil) + return + } + guard let pollQuestionIndex = data["pollQuestionIndex"] as? Int, + let pollQuestion = poll.questions?.first(where: {question in question.index == pollQuestionIndex}) else { + reject?("6004", "Unable to find HMSPollQuestion in poll with given question index", nil) + return + } + guard let responses = data["responses"] as? NSDictionary else { + reject?("6004", "responses field is required", nil) + return + } + + let pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll: poll, pollQuestion: pollQuestion) + + self.hmssdk?.interactivityCenter.add(response: pollResponseBuilder) { pollQuestionResponseResult, error in + if let nonnilError = error { + reject?("6004", nonnilError.localizedDescription, nil) + return + } + if let pollQuestionResponseResult = pollQuestionResponseResult { + resolve?(HMSInteractivityDecoder.getHMSPollQuestionResponseResults(pollQuestionResponseResult)) + } else { + resolve?(nil) + } + } + } + + */ + fun addResponseOnPollQuestion( data: ReadableMap, promise: Promise?, ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6004", "pollId is required") + promise?.reject("6002", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6004", "No HMSPoll with pollId `$pollId`") + promise?.reject("6002", "No HMSPoll with pollId `$pollId`") return } val pollQuestionIndex = data.getInt("pollQuestionIndex") val pollQuestion = poll.questions?.find { it.questionID == pollQuestionIndex } if (pollQuestion == null) { - promise?.reject("6004", "No HMSPollQuestion in poll with given question index") + promise?.reject("6002", "No HMSPollQuestion in poll with given question index") return } val responses = data.getMap("responses") if (responses == null) { - promise?.reject("6004", "responses field is required") + promise?.reject("6002", "responses field is required") return } val pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll, pollQuestion) @@ -103,12 +140,12 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6004", "pollId is required") + promise?.reject("6002", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6004", "No HMSPoll with pollId `$pollId`") + promise?.reject("6002", "No HMSPoll with pollId `$pollId`") return } this.sdk.getHmsInteractivityCenter().stop( @@ -125,38 +162,23 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } - fun fetchLeaderboard( - data: ReadableMap, - promise: Promise?, - ) { - val pollId = data.getString("pollId") - if (pollId == null) { - promise?.reject("6004", "pollId is required") - return - } - val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } - if (poll == null) { - promise?.reject("6004", "No HMSPoll with pollId `$pollId`") - return - } - val count = data.getInt("count") - val startIndex = data.getInt("startIndex") - val includeCurrentPeer = data.getBoolean("includeCurrentPeer") - - this.sdk.getHmsInteractivityCenter().fetchLeaderboard( - pollId = poll.pollId, - count = count.toLong(), - startIndex = startIndex.toLong(), - includeCurrentPeer = includeCurrentPeer, - object : HmsTypedActionResultListener { - override fun onSuccess(result: PollLeaderboardResponse) { - promise?.resolve(HMSInteractivityDecoder.getPollLeaderboardResponse(result)) - } + // endregion - override fun onError(error: HMSException) { - promise?.reject(error.code.toString(), error.description) - } - }, - ) + // region Poll Update Listener + + fun showPollStartedToast() { + // Show toast + Log.e("Interactivity", "showPollStartedToast") + } + + fun loadResultsSummaryIfNeeded() { + // Load results summary + Log.e("Interactivity", "loadResultsSummaryIfNeeded") + } + + fun updateResultsScreen() { + // Update results screen + Log.e("Interactivity", "updateResultsScreen") } + // endregion } diff --git a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift index 7df6f0120..89d9b84d3 100644 --- a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift +++ b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift @@ -220,54 +220,4 @@ class HMSInteractivityDecoder { } return result } - - static func getLeaderboardResponse(_ response: HMSPollLeaderboardResponse) -> [String: AnyHashable] { - var result = [String: AnyHashable]() - - result["hasNext"] = response.hasNext - - result["summary"] = getLeaderboardSummary(response.summary) - - result["entries"] = getLeaderboardEntries(response.entries) - - return result - } - - static func getLeaderboardSummary(_ summary: HMSPollLeaderboardSummary) -> [String: AnyHashable] { - var result = [String: AnyHashable]() - - result["averageScore"] = summary.averageScore - result["averageTime"] = summary.averageTime - result["totalPeersCount"] = summary.totalPeersCount - result["respondedCorrectlyPeersCount"] = summary.respondedCorrectlyPeersCount - result["respondedPeersCount"] = summary.respondedPeersCount - - return result - } - - static func getLeaderboardEntries(_ entries: [HMSPollLeaderboardEntry]) -> [[String: AnyHashable]] { - var result = [[String: AnyHashable]]() - - for entry in entries { - result.append(getLeaderboardEntry(entry)) - } - - return result - } - - static func getLeaderboardEntry(_ entry: HMSPollLeaderboardEntry) -> [String: AnyHashable] { - var result = [String: AnyHashable]() - - result["duration"] = entry.duration - result["totalResponses"] = entry.totalResponses - result["correctResponses"] = entry.correctResponses - result["position"] = entry.position - result["score"] = entry.score - - if let peer = entry.peer { - result["peer"] = getHMSPollResponsePeerInfo(peer) - } - - return result - } } diff --git a/packages/react-native-hms/ios/HMSManager.swift b/packages/react-native-hms/ios/HMSManager.swift index ab02cbf61..1f99c40be 100644 --- a/packages/react-native-hms/ios/HMSManager.swift +++ b/packages/react-native-hms/ios/HMSManager.swift @@ -672,13 +672,4 @@ class HMSManager: RCTEventEmitter { } interactivity.stop(data, resolve, reject) } - - @objc - func fetchLeaderboard(_ 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.fetchLeaderboard(data, resolve, reject) - } } diff --git a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift index abccab8b5..4ca6a6423 100644 --- a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift +++ b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift @@ -86,35 +86,4 @@ class HMSRNInteractivityCenter { resolve?(success) }) } - - func fetchLeaderboard(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { - guard let pollId = data["pollId"] as? String, - let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { - reject?("6004", "Unable to find HMSPoll with given pollId", nil) - return - } - - guard let count = data["count"] as? Int, - let startIndex = data["startIndex"] as? Int - else { - reject?("6004", "Unable to find required parameters", nil) - return - } - - let includeCurrentPeer = data["includeCurrentPeer"] as? Bool ?? false - - self.hmssdk?.interactivityCenter.fetchLeaderboard(for: poll, offset: startIndex, count: count, includeCurrentPeer: includeCurrentPeer) { response, error in - - if let nonnilError = error { - reject?("6004", nonnilError.localizedDescription, nil) - return - } - - if let response = response { - resolve?(HMSInteractivityDecoder.getLeaderboardResponse(response)) - } else { - reject?("6004", "Could not fetch leaderboard response", nil) - } - } - } } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts index fb3e39488..ac10da22f 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts @@ -10,8 +10,6 @@ import HMSNativeEventListener from './HMSNativeEventListener'; import type { HMSEventSubscription } from './HMSNativeEventEmitter'; import { HMSInteractivityEncoder } from './HMSInteractivityEncoder'; import { HMSHelper } from './HMSHelper'; -import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; -import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; type PollUpdateListener = (data: { updatedPoll: HMSPoll; @@ -136,32 +134,4 @@ export class HMSInteractivityCenter { logger?.verbose('#Function stop', JSON.stringify(data)); return HMSManager.stopPoll(data); } - - /** - * Fetches the leaderboard for a poll - * @param pollId - The id of the poll - * @param count - The number of entries to fetch - * @param startIndex - The index to start fetching from - * @param includeCurrentPeer - Whether to include the current peer in the fetched leaderboard entries - * @returns Promise - */ - async fetchLeaderboard( - pollId: string, - count: number, - startIndex: number, - includeCurrentPeer: boolean - ): Promise { - const data = { - id: HMSConstants.DEFAULT_SDK_ID, - pollId, - count, - startIndex, - includeCurrentPeer, - }; - logger?.verbose('#Function fetchLeaderboard', data); - - const response: DecodedPollLeaderboardResponse = - await HMSManager.fetchLeaderboard(data); - return HMSInteractivityEncoder.transformPollLeaderboardResponse(response); - } } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts index 94d216244..27d4d14a9 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts @@ -1,6 +1,4 @@ -import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; import type { HMSPoll } from './polls/HMSPoll'; -import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; export class HMSInteractivityEncoder { static transformPoll(poll: HMSPoll): HMSPoll { @@ -28,38 +26,4 @@ export class HMSInteractivityEncoder { // --- poll.result: HMSPollResult return poll; } - - static transformPollLeaderboardResponse( - decodedPollLeaderboardResponse: DecodedPollLeaderboardResponse - ): PollLeaderboardResponse { - const summary = decodedPollLeaderboardResponse.summary; - if (summary) { - if (typeof summary.averageTime === 'string') { - summary.averageTime = parseInt(summary.averageTime); - } - } - - const entries = decodedPollLeaderboardResponse.entries; - if (entries) { - entries.forEach((entry) => { - if (typeof entry.duration === 'string') { - entry.duration = parseInt(entry.duration); - } - if (typeof entry.totalResponses === 'string') { - entry.totalResponses = parseInt(entry.totalResponses); - } - if (typeof entry.correctResponses === 'string') { - entry.correctResponses = parseInt(entry.correctResponses); - } - if (typeof entry.position === 'string') { - entry.position = parseInt(entry.position); - } - if (typeof entry.score === 'string') { - entry.score = parseInt(entry.score); - } - }); - } - - return decodedPollLeaderboardResponse as PollLeaderboardResponse; - } } diff --git a/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts deleted file mode 100644 index 17a288768..000000000 --- a/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; -import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; -import type { PollLeaderboardResponse } from './PollLeaderboardResponse'; - -type NumberString = string; - -export interface DecodedPollLeaderboardResponse - extends Pick { - entries?: DecodedHMSPollLeaderboardEntry[]; - summary?: DecodedHMSPollLeaderboardSummary; -} - -export interface DecodedHMSPollLeaderboardEntry - extends Pick { - /** - * convert this value to number - */ - duration?: NumberString | number; - /** - * convert this value to number - */ - totalResponses?: NumberString | number; - /** - * convert this value to number - */ - correctResponses?: NumberString | number; - /** - * convert this value to number - */ - position?: NumberString | number; - /** - * convert this value to number - */ - score?: NumberString | number; -} - -export interface DecodedHMSPollLeaderboardSummary - extends Omit { - /** - * convert this value to number - */ - averageTime?: NumberString | number; -} diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts deleted file mode 100644 index 5ed159de5..000000000 --- a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { HMSPollResponsePeerInfo } from './HMSPollResponsePeerInfo'; - -export interface HMSPollLeaderboardEntry { - duration?: number; - totalResponses?: number; - correctResponses?: number; - position?: number; - score?: number; - peer?: HMSPollResponsePeerInfo; -} diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts deleted file mode 100644 index 860d22b09..000000000 --- a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface HMSPollLeaderboardSummary { - averageScore?: number; - averageTime?: number; - respondedCorrectlyPeersCount?: number; - respondedPeersCount?: number; - totalPeersCount?: number; -} diff --git a/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts deleted file mode 100644 index c4b3bd9c7..000000000 --- a/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; -import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; - -export interface PollLeaderboardResponse { - entries?: HMSPollLeaderboardEntry[]; - hasNext?: boolean; - summary?: HMSPollLeaderboardSummary; -} diff --git a/packages/react-native-room-kit/src/components/CreatePoll.tsx b/packages/react-native-room-kit/src/components/CreatePoll.tsx index a857ee3ac..90d9886de 100644 --- a/packages/react-native-room-kit/src/components/CreatePoll.tsx +++ b/packages/react-native-room-kit/src/components/CreatePoll.tsx @@ -9,11 +9,7 @@ import { HMSTextInput } from './HMSTextInput'; import { HMSPrimaryButton } from './HMSPrimaryButton'; import { COLORS } from '../utils/theme'; import type { RootState } from '../redux'; -import { - pushToNavigationStack, - setPollConfig, - setPollName, -} from '../redux/actions'; +import { setPollConfig, setPollName, setPollStage } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import type { PollConfig } from '../redux/actionTypes'; import { PollIcon, QuizIcon } from '../Icons'; @@ -71,7 +67,7 @@ export const CreatePoll: React.FC = ({}) => { const addQuestions = () => { if (pollName.trim().length > 0) { - dispatch(pushToNavigationStack(CreatePollStages.POLL_QUESTION_CONFIG)); + dispatch(setPollStage(CreatePollStages.POLL_QUESTION_CONFIG)); } }; @@ -234,7 +230,6 @@ const styles = StyleSheet.create({ }, createPollBtn: { marginTop: 24, - marginBottom: 16, }, contentContainer: { marginHorizontal: 24, diff --git a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx index c29334b82..52151884c 100644 --- a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx +++ b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx @@ -14,8 +14,8 @@ import { import { HMSNotification } from './HMSNotification'; import { ModalTypes } from '../utils/types'; import { - pushToNavigationStack, removeNotification, + setPollStage, setSelectedPollId, } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; @@ -56,7 +56,7 @@ export const HMSPollsQuizzesNotification: React.FC< // return; // } batch(() => { - dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); + dispatch(setPollStage(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); handleModalVisibleType(ModalTypes.POLLS_AND_QUIZZES); dispatch(removeNotification(id)); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx b/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx deleted file mode 100644 index 3db3d1469..000000000 --- a/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { StyleSheet } from 'react-native'; - -import Animated, { SlideInRight, SlideOutRight } from 'react-native-reanimated'; - -export interface PollAndQuizSheetScreenProps { - zIndex: number; -} - -export const PollAndQuizSheetScreen: React.FC = ({ - children, - zIndex, -}) => { - return ( - - {children} - - ); -}; - -const styles = StyleSheet.create({ - absolute: { - width: '100%', - height: '100%', - position: 'absolute', - }, -}); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx index 8bbf69b3a..9b20f00e2 100644 --- a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx +++ b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx @@ -6,34 +6,22 @@ import { findNodeHandle, UIManager, View, - Keyboard, - TouchableOpacity, } from 'react-native'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import { HMSPollState, HMSPollType } from '@100mslive/react-native-hms'; import { useHMSInstance, useHMSRoomStyleSheet } from '../hooks-util'; import type { RootState } from '../redux'; import { HMSDangerButton } from './HMSDangerButton'; import { PollAndQuizQuestionResponseCards } from './PollAndQuizQuestionResponseCards'; -import { popFromNavigationStack } from '../redux/actions'; -import { BottomSheet } from './BottomSheet'; -import { ChevronIcon, CloseIcon } from '../Icons'; -import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; export interface PollAndQuizVotingProps { - currentIdx: number; dismissModal(): void; } -export const PollAndQuizVoting: React.FC = ({ - currentIdx, - dismissModal, -}) => { +export const PollAndQuizVoting: React.FC = () => { const scrollViewRef = React.useRef(null); const hmsInstance = useHMSInstance(); - const dispatch = useDispatch(); - const selectedPoll = useSelector((state: RootState) => { const pollsData = state.polls; if (pollsData.selectedPollId !== null) { @@ -45,13 +33,6 @@ export const PollAndQuizVoting: React.FC = ({ const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; }); - const headerTitle = useSelector((state: RootState) => { - const pollsData = state.polls; - if (pollsData.selectedPollId !== null) { - return pollsData.polls[pollsData.selectedPollId]?.title || null; - } - return null; - }); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ regularMediumText: { @@ -62,13 +43,6 @@ export const PollAndQuizVoting: React.FC = ({ color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-SemiBold`, }, - headerText: { - color: theme.palette.on_surface_high, - fontFamily: `${typography.font_family}-SemiBold`, - }, - container: { - backgroundColor: theme.palette.surface_dim, - }, })); const endPoll = async () => { @@ -105,60 +79,8 @@ export const PollAndQuizVoting: React.FC = ({ ); }; - const handleBackPress = () => { - Keyboard.dismiss(); - dispatch(popFromNavigationStack()); - }; - - const handleClosePress = () => { - Keyboard.dismiss(); - dismissModal(); - }; - return ( - - {/* Header */} - - - {currentIdx > 0 ? ( - - - - ) : null} - - - {headerTitle} - - - {selectedPoll?.state ? ( - - ) : null} - - - - - - - - {/* Divider */} - - - {/* Content */} + = ({ - currentIdx, - dismissModal, -}) => { +export const PollQuestions: React.FC = ({}) => { const dispatch = useDispatch(); const hmsInstance = useHMSInstance(); const reduxStore = useStore(); @@ -58,7 +50,6 @@ export const PollQuestions: React.FC = ({ const pollType = useSelector( (state: RootState) => state.polls.pollConfig.type ); - const headerTitle = useSelector((state: RootState) => state.polls.pollName); const questions = useSelector((state: RootState) => state.polls.questions); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ @@ -66,13 +57,6 @@ export const PollQuestions: React.FC = ({ color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-Regular`, }, - headerText: { - color: theme.palette.on_surface_high, - fontFamily: `${typography.font_family}-SemiBold`, - }, - container: { - backgroundColor: theme.palette.surface_dim, - }, })); const disableLaunchPoll = @@ -201,113 +185,60 @@ export const PollQuestions: React.FC = ({ [] ); - const handleBackPress = () => { - Keyboard.dismiss(); - dispatch(popFromNavigationStack()); - }; - - const handleClosePress = () => { - Keyboard.dismiss(); - dismissModal(); - }; - return ( - - {/* Header */} - - - {currentIdx > 0 ? ( - - - - ) : null} + + {questions.map((pollQuestion, idx, arr) => { + const isFirst = idx === 0; + return ( + + {isFirst ? null : } - - {headerTitle} - - + + + ); + })} + - + + + + + Add another question + - {/* Divider */} - - - - {questions.map((pollQuestion, idx, arr) => { - const isFirst = idx === 0; - return ( - - {isFirst ? null : } - - - - ); - })} - - - - - - - - Add another question - - - - - - - - {/* Modal */} - - + + ); }; @@ -343,51 +274,4 @@ const styles = StyleSheet.create({ marginRight: 8, padding: 8, }, - - // ------- - - // Utilities - fullView: { - flex: 1, - }, - // Header - header: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginTop: 24, - marginHorizontal: 24, - }, - headerControls: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1, - }, - headerText: { - fontSize: 20, - lineHeight: 24, - letterSpacing: 0.15, - marginRight: 12, - }, - closeIconHitSlop: { - bottom: 16, - left: 16, - right: 16, - top: 16, - }, - backIcon: { - marginRight: 8, - }, - // Divider - halfDivider: { - marginHorizontal: 24, - marginVertical: 0, - marginTop: 24, - width: undefined, - }, - divider: { - marginHorizontal: 24, - marginVertical: 24, - width: undefined, - }, }); diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx index 82144ce22..ca76f70b8 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx @@ -1,12 +1,20 @@ import * as React from 'react'; import { Platform, StyleSheet } from 'react-native'; +import { useSelector } from 'react-redux'; import { BottomSheet } from './BottomSheet'; -import { useHMSRoomStyleSheet, useModalType } from '../hooks-util'; +import { + useHMSRoomStyleSheet, + useIsHLSViewer, + useModalType, +} from '../hooks-util'; import { useHeaderHeight } from './Header'; import { useIsLandscapeOrientation } from '../utils/dimension'; import { PollsAndQuizzesModalContent } from './PollsAndQuizzesModalContent'; import { ModalTypes } from '../utils/types'; +import type { RootState } from '../redux'; +import { CreatePollStages } from '../redux/actionTypes'; +import { visiblePollsSelector } from '../utils/functions'; export const PollsAndQuizBottomSheet = () => { const headerHeight = useHeaderHeight(); @@ -16,6 +24,20 @@ export const PollsAndQuizBottomSheet = () => { handleModalVisibleType: setModalVisible, } = useModalType(); + const isPollQuestionStage = useSelector( + (state: RootState) => + state.polls.stage === CreatePollStages.POLL_QUESTION_CONFIG + ); + const isHLSViewer = useIsHLSViewer(); + const havePolls = useSelector( + (state: RootState) => + visiblePollsSelector( + Object.values(state.polls.polls), + isHLSViewer, + state.polls.cuedPollIds + ).length > 0 + ); + const hmsRoomStyles = useHMSRoomStyleSheet((theme) => ({ contentContainer: { backgroundColor: theme.palette.surface_dim, @@ -24,15 +46,18 @@ export const PollsAndQuizBottomSheet = () => { const dismissModal = () => setModalVisible(ModalTypes.DEFAULT); - const containerStyles = [ - styles.bottomSheet, - { - marginTop: isLandscapeOrientation - ? 0 - : headerHeight + (Platform.OS === 'android' ? 24 : 0), - }, - hmsRoomStyles.contentContainer, - ]; + const fullHeight = isPollQuestionStage || havePolls; + const containerStyles = fullHeight + ? [ + styles.bottomSheet, + { + marginTop: isLandscapeOrientation + ? 0 + : headerHeight + (Platform.OS === 'android' ? 24 : 0), + }, + hmsRoomStyles.contentContainer, + ] + : [hmsRoomStyles.contentContainer]; return ( { isVisible={modalVisible === ModalTypes.POLLS_AND_QUIZZES} avoidKeyboard={true} containerStyle={containerStyles} - bottomOffsetSpace={0} + bottomOffsetSpace={fullHeight ? 0 : undefined} > - + ); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx index 2a1bbd929..5b5445c42 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx @@ -5,7 +5,7 @@ import type { HMSPoll } from '@100mslive/react-native-hms'; import { useHMSRoomStyleSheet } from '../hooks-util'; import { HMSPrimaryButton } from './HMSPrimaryButton'; -import { pushToNavigationStack, setSelectedPollId } from '../redux/actions'; +import { setPollStage, setSelectedPollId } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; @@ -36,7 +36,7 @@ export const PollsAndQuizzesCard: React.FC = ({ const viewPoll = () => { batch(() => { - dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); + dispatch(setPollStage(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); }); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx index dd109825e..49d7e2872 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx @@ -1,25 +1,62 @@ import * as React from 'react'; -import { View, StyleSheet } from 'react-native'; -import { useSelector } from 'react-redux'; +import { + View, + Text, + StyleSheet, + TouchableOpacity, + Keyboard, +} from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; import type { RootState } from '../redux'; +import { useHMSRoomStyleSheet } from '../hooks-util'; +import { BottomSheet } from './BottomSheet'; +import { ChevronIcon, CloseIcon } from '../Icons'; +import { TestIds } from '../utils/constants'; import { PollQuestions } from './PollQuestions'; import { CreatePollStages } from '../redux/actionTypes'; +import { setPollStage } from '../redux/actions'; +import { PollQDeleteConfirmationSheetView } from './PollQDeleteConfirmationSheetView'; import { PollsConfigAndList } from './PollsConfigAndList'; import { PollAndQuizVoting } from './PollAndQuizVoting'; -import { PollAndQuizSheetScreen } from './PollAndQuizSheetScreen'; +import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; export interface PollsAndQuizzesModalContentProps { + fullHeight: boolean; dismissModal(): void; } export const PollsAndQuizzesModalContent: React.FC< PollsAndQuizzesModalContentProps -> = ({ dismissModal }) => { - const pollsNavigationStack = useSelector( - (state: RootState) => state.polls.navigationStack +> = ({ fullHeight, dismissModal }) => { + const dispatch = useDispatch(); + const headerTitle = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.stage === CreatePollStages.POLL_QUESTION_CONFIG) { + return pollsData.pollName; + } + if ( + pollsData.stage === CreatePollStages.POLL_VOTING && + pollsData.selectedPollId !== null + ) { + return pollsData.polls[pollsData.selectedPollId]?.title || null; + } + return null; + }); + const selectedPoll = useSelector((state: RootState) => { + const pollsData = state.polls; + if ( + pollsData.stage === CreatePollStages.POLL_VOTING && + pollsData.selectedPollId !== null + ) { + return pollsData.polls[pollsData.selectedPollId] || null; + } + return null; + }); + const pollsStage = useSelector((state: RootState) => state.polls.stage); + const launchingPoll = useSelector( + (state: RootState) => state.polls.launchingPoll ); - const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -29,30 +66,133 @@ export const PollsAndQuizzesModalContent: React.FC< return permissions?.pollRead; }); + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + })); + + const handleBackPress = () => { + Keyboard.dismiss(); + dispatch(setPollStage(CreatePollStages.POLL_CONFIG)); + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - - {pollsNavigationStack.map((stage, index) => ( - - {stage === CreatePollStages.POLL_CONFIG ? ( - - ) : stage === CreatePollStages.POLL_QUESTION_CONFIG && - canCreateOrEndPoll ? ( - - ) : stage === CreatePollStages.POLL_VOTING && - (canVoteOnPoll || canCreateOrEndPoll) ? ( - + + {/* Header */} + + + {headerTitle ? ( + + + ) : null} - - ))} + + + {headerTitle ?? 'Polls and Quizzes'} + + + {selectedPoll?.state ? ( + + ) : null} + + + + + + + + {/* Divider */} + + + {/* Content */} + + {pollsStage === CreatePollStages.POLL_CONFIG ? ( + + ) : pollsStage === CreatePollStages.POLL_QUESTION_CONFIG && + canCreateOrEndPoll ? ( + + ) : pollsStage === CreatePollStages.POLL_VOTING && + (canVoteOnPoll || canCreateOrEndPoll) ? ( + + ) : null} + + + {/* Modal */} + ); }; const styles = StyleSheet.create({ - relative: { - position: 'relative', - }, + // Utilities fullView: { flex: 1, }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, }); diff --git a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx index f339f705b..fc0e5afd2 100644 --- a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx +++ b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx @@ -1,38 +1,14 @@ import * as React from 'react'; -import { - Keyboard, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from 'react-native'; -import { useSelector } from 'react-redux'; +import { ScrollView } from 'react-native'; import { CreatePoll } from './CreatePoll'; import { PreviousPollsAndQuizzesList } from './PreviousPollsAndQuizzesList'; -import type { RootState } from '../redux'; -import { BottomSheet } from './BottomSheet'; -import { CloseIcon } from '../Icons'; -import { useHMSRoomStyleSheet } from '../hooks-util'; - -export interface PollsConfigAndListProps { - dismissModal(): void; -} +import { useSelector } from 'react-redux'; +import type { RootState } from 'src/redux'; -export const PollsConfigAndList: React.FC = ({ - dismissModal, -}) => { - const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ - container: { - backgroundColor: theme.palette.surface_dim, - }, - headerText: { - color: theme.palette.on_surface_high, - fontFamily: `${typography.font_family}-SemiBold`, - }, - })); +export interface PollsConfigAndListProps {} +export const PollsConfigAndList: React.FC = ({}) => { const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -42,84 +18,12 @@ export const PollsConfigAndList: React.FC = ({ return permissions?.pollRead; }); - const handleClosePress = () => { - Keyboard.dismiss(); - dismissModal(); - }; - return ( - - {/* Header */} - - - Polls and Quizzes - - - - - - - - {/* Divider */} - - - {/* Content */} - - {canCreateOrEndPoll ? : null} - {canVoteOnPoll || canCreateOrEndPoll ? ( - - ) : null} - - + + {canCreateOrEndPoll ? : null} + {canVoteOnPoll || canCreateOrEndPoll ? ( + + ) : null} + ); }; - -const styles = StyleSheet.create({ - // Utilities - fullView: { - flex: 1, - }, - // Header - header: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginTop: 24, - marginHorizontal: 24, - }, - headerControls: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1, - }, - headerText: { - fontSize: 20, - lineHeight: 24, - letterSpacing: 0.15, - }, - closeIconHitSlop: { - bottom: 16, - left: 16, - right: 16, - top: 16, - }, - backIcon: { - marginRight: 8, - }, - // Divider - halfDivider: { - marginHorizontal: 24, - // marginVertical: 0, - // marginTop: 24, - width: undefined, - }, - divider: { - marginHorizontal: 24, - marginVertical: 24, - width: undefined, - }, -}); diff --git a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx index 56ab93d19..3b8895f7a 100644 --- a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx +++ b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx @@ -18,6 +18,11 @@ export const PreviousPollsAndQuizzesList: React.FC< (state: RootState) => state.polls.cuedPollIds ); + const canCreateOrEndPoll = useSelector((state: RootState) => { + const permissions = state.hmsStates.localPeer?.role?.permissions; + return permissions?.pollWrite; + }); + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ surfaceHighSemiBoldText: { color: theme.palette.on_surface_high, @@ -35,42 +40,44 @@ export const PreviousPollsAndQuizzesList: React.FC< hlsCuedPollIds ); + if (pollsList.length === 0 && !canCreateOrEndPoll) { + return ( + + + No Polls or Quizzes to show + + + ); + } + return ( - - Previous Polls And Quizzes - - - {pollsList.length <= 0 ? ( - - - No Polls or Quizzes to show - - - ) : ( - <> - {pollsList - .sort((a, b) => { - return a.state === b.state // If polls have same state, then sort as per startedAt - ? a.startedAt !== undefined && b.startedAt !== undefined - ? b.startedAt.getTime() - a.startedAt.getTime() - : 0 - : // If polls have different state, then sort as per state - a.state !== undefined && b.state !== undefined - ? a.state - b.state - : 0; - }) - .map((poll) => ( - - ))} - + {pollsList.length > 0 && ( + + Previous Polls And Quizzes + )} + + {pollsList + .sort((a, b) => { + return a.state === b.state // If polls have same state, then sort as per startedAt + ? a.startedAt !== undefined && b.startedAt !== undefined + ? b.startedAt.getTime() - a.startedAt.getTime() + : 0 + : // If polls have different state, then sort as per state + a.state !== undefined && b.state !== undefined + ? a.state - b.state + : 0; + }) + .map((poll) => ( + + ))} ); }; diff --git a/packages/react-native-room-kit/src/redux/actionTypes.ts b/packages/react-native-room-kit/src/redux/actionTypes.ts index f3a94b1e2..1c6606270 100644 --- a/packages/react-native-room-kit/src/redux/actionTypes.ts +++ b/packages/react-native-room-kit/src/redux/actionTypes.ts @@ -217,9 +217,7 @@ export type PollsActionType = | SetDeleteConfirmationVisible | SetPollNameAction | SetPollConfigAction - | PushToNavigationStackAction - | PopFromNavigationStackAction - | ReplaceTopOfNavigationStackAction + | SetPollStageAction | AddPollQuestionAction | DeletePollQuestionAction | SetSelectedQuestionIndexAction @@ -264,18 +262,9 @@ export type SetPollConfigAction = { pollConfig: Partial; }; -export type PushToNavigationStackAction = { - type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK; - screen: CreatePollStages; -}; - -export type PopFromNavigationStackAction = { - type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK; -}; - -export type ReplaceTopOfNavigationStackAction = { - type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK; - screen: CreatePollStages; +export type SetPollStageAction = { + type: PollsStateActionTypes.SET_POLL_STAGE; + pollStage: CreatePollStages; }; export type AddPollQuestionAction = { @@ -407,9 +396,7 @@ export enum PollsStateActionTypes { SET_DELETE_CONFIRMATION_VISIBLE = 'SET_DELETE_CONFIRMATION_VISIBLE', SET_POLL_NAME = 'SET_POLL_NAME', SET_POLL_CONFIG = 'SET_POLL_CONFIG', - PUSH_TO_NAVIGATION_STACK = 'PUSH_TO_NAVIGATION_STACK', - POP_FROM_NAVIGATION_STACK = 'POP_FROM_NAVIGATION_STACK', - REPLACE_TOP_OF_NAVIGATION_STACK = 'REPLACE_TOP_OF_NAVIGATION_STACK', + SET_POLL_STAGE = 'SET_POLL_STAGE', ADD_POLL_QUESTION = 'ADD_POLL_QUESTION', DELETE_POLL_QUESTION = 'DELETE_POLL_QUESTION', SET_SELECTED_QUESTION_INDEX = 'SET_SELECTED_QUESTION_INDEX', 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 164e54b45..2d5d6ce52 100644 --- a/packages/react-native-room-kit/src/redux/actions/index.ts +++ b/packages/react-native-room-kit/src/redux/actions/index.ts @@ -32,6 +32,7 @@ import type { AddPollQuestionAction, SetPollConfigAction, SetPollNameAction, + SetPollStageAction, DeletePollQuestionAction, SetDeleteConfirmationVisible, SetSelectedQuestionIndexAction, @@ -53,9 +54,6 @@ import type { RemovePollQuestionResponseAction, SetQuestionPointWeightageAction, SetQuestionCorrectOptionAction, - PushToNavigationStackAction, - PopFromNavigationStackAction, - ReplaceTopOfNavigationStackAction, } from '../actionTypes'; import { MeetingState } from '../../types'; import type { ChatState, Notification, PinnedMessage } from '../../types'; @@ -493,22 +491,11 @@ export const setPollConfig = ( pollConfig, }); -export const pushToNavigationStack = ( - screen: PushToNavigationStackAction['screen'] -): PushToNavigationStackAction => ({ - type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK, - screen, -}); - -export const popFromNavigationStack = (): PopFromNavigationStackAction => ({ - type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK, -}); - -export const replaceTopOfNavigationStack = ( - screen: ReplaceTopOfNavigationStackAction['screen'] -): ReplaceTopOfNavigationStackAction => ({ - type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK, - screen, +export const setPollStage = ( + pollStage: SetPollStageAction['pollStage'] +): SetPollStageAction => ({ + type: PollsStateActionTypes.SET_POLL_STAGE, + pollStage, }); export const addPollQuestion = (): AddPollQuestionAction => ({ diff --git a/packages/react-native-room-kit/src/redux/reducers/polls.ts b/packages/react-native-room-kit/src/redux/reducers/polls.ts index a1d7573ad..3daedf71d 100644 --- a/packages/react-native-room-kit/src/redux/reducers/polls.ts +++ b/packages/react-native-room-kit/src/redux/reducers/polls.ts @@ -30,7 +30,7 @@ function getDefaultQuestionObj(): PollQuestionUI { type IntialStateType = { pollName: string; pollConfig: PollConfig; - navigationStack: CreatePollStages[]; + stage: CreatePollStages; questions: PollQuestionUI[]; deleteConfirmationVisible: boolean; selectedPollQuestionIndex: number | null; @@ -48,7 +48,7 @@ const INITIAL_STATE: IntialStateType = { voteCountHidden: false, resultsAnonymous: false, }, - navigationStack: [CreatePollStages.POLL_CONFIG], + stage: CreatePollStages.POLL_CONFIG, questions: [getDefaultQuestionObj()], deleteConfirmationVisible: false, selectedPollQuestionIndex: null, @@ -87,25 +87,11 @@ const hmsStatesReducer = ( : state.questions, selectedPollQuestionIndex: null, }; - case PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK: + case PollsStateActionTypes.SET_POLL_STAGE: return { ...state, - navigationStack: [...state.navigationStack, action.screen], - }; - case PollsStateActionTypes.POP_FROM_NAVIGATION_STACK: { - const updatedNavigationStack = [...state.navigationStack]; - updatedNavigationStack.pop(); - return { - ...state, - navigationStack: updatedNavigationStack, - }; - } - case PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK: - const updatedNavigationStack = [...state.navigationStack]; - updatedNavigationStack[updatedNavigationStack.length - 1] = action.screen; - return { - ...state, - navigationStack: updatedNavigationStack, + stage: action.pollStage, + selectedPollQuestionIndex: null, }; case PollsStateActionTypes.ADD_POLL_QUESTION: return { From 6ab31c74929e867dc33ccea86d691112235098b3 Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Tue, 27 Feb 2024 13:20:28 +0530 Subject: [PATCH 08/14] updated packages --- .../example/package-lock.json | 24 ++++++------ packages/react-native-hms/package-lock.json | 24 ++++++------ .../example/package-lock.json | 18 ++++----- .../react-native-room-kit/package-lock.json | 38 +++++++++---------- packages/react-native-room-kit/package.json | 2 +- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/packages/react-native-hms/example/package-lock.json b/packages/react-native-hms/example/package-lock.json index aed082181..9b39871d4 100644 --- a/packages/react-native-hms/example/package-lock.json +++ b/packages/react-native-hms/example/package-lock.json @@ -3827,9 +3827,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "17.0.75", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz", - "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==", + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3885,9 +3885,9 @@ } }, "node_modules/@types/react-test-renderer/node_modules/@types/react": { - "version": "16.14.56", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.56.tgz", - "integrity": "sha512-MxuHB7dvVm5yOxRr7hJoonLG0JY8YvqZtaQ9Quirp3Oe4FLFjAgxkxsKE6IspdHPpRVZKo2ZoDEravWO81EeYA==", + "version": "16.14.57", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.57.tgz", + "integrity": "sha512-fuNq/GV1a6GgqSuVuC457vYeTbm4E1CUBQVZwSPxqYnRhIzSXCJ1gGqyv+PKhqLyfbKCga9dXHJDzv+4XE41fw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -5151,9 +5151,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "funding": [ { "type": "opencollective", @@ -5806,9 +5806,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" + "version": "1.4.682", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", + "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==" }, "node_modules/emittery": { "version": "0.7.2", diff --git a/packages/react-native-hms/package-lock.json b/packages/react-native-hms/package-lock.json index a77624a5b..4cc200399 100644 --- a/packages/react-native-hms/package-lock.json +++ b/packages/react-native-hms/package-lock.json @@ -4706,9 +4706,9 @@ "devOptional": true }, "node_modules/@types/react": { - "version": "16.14.56", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.56.tgz", - "integrity": "sha512-MxuHB7dvVm5yOxRr7hJoonLG0JY8YvqZtaQ9Quirp3Oe4FLFjAgxkxsKE6IspdHPpRVZKo2ZoDEravWO81EeYA==", + "version": "16.14.57", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.57.tgz", + "integrity": "sha512-fuNq/GV1a6GgqSuVuC457vYeTbm4E1CUBQVZwSPxqYnRhIzSXCJ1gGqyv+PKhqLyfbKCga9dXHJDzv+4XE41fw==", "devOptional": true, "dependencies": { "@types/prop-types": "*", @@ -4726,9 +4726,9 @@ } }, "node_modules/@types/react-native/node_modules/@types/react": { - "version": "17.0.75", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz", - "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==", + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -6022,9 +6022,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "dev": true, "funding": [ { @@ -6871,9 +6871,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==", + "version": "1.4.682", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", + "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==", "dev": true }, "node_modules/emittery": { diff --git a/packages/react-native-room-kit/example/package-lock.json b/packages/react-native-room-kit/example/package-lock.json index c6756b0bc..41dc8dfef 100644 --- a/packages/react-native-room-kit/example/package-lock.json +++ b/packages/react-native-room-kit/example/package-lock.json @@ -4334,9 +4334,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "17.0.75", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz", - "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==", + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -5816,9 +5816,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "funding": [ { "type": "opencollective", @@ -6480,9 +6480,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" + "version": "1.4.682", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", + "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==" }, "node_modules/emittery": { "version": "0.7.2", diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index e35eb146f..d4a478b11 100644 --- a/packages/react-native-room-kit/package-lock.json +++ b/packages/react-native-room-kit/package-lock.json @@ -9,7 +9,7 @@ "version": "1.1.3", "license": "MIT", "dependencies": { - "@100mslive/types-prebuilt": "^0.12.4", + "@100mslive/types-prebuilt": "^0.12.7", "@react-navigation/native": "^6.0.8", "react-redux": "^7.2.4", "redux": "^4.1.0" @@ -5523,9 +5523,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "17.0.75", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz", - "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==", + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -7137,9 +7137,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "funding": [ { "type": "opencollective", @@ -8834,9 +8834,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" + "version": "1.4.682", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", + "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==" }, "node_modules/emittery": { "version": "0.10.2", @@ -26246,9 +26246,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "@types/react": { - "version": "17.0.75", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.75.tgz", - "integrity": "sha512-MSA+NzEzXnQKrqpO63CYqNstFjsESgvJAdAyyJ1n6ZQq/GLgf6nOfIKwk+Twuz0L1N6xPe+qz5xRCJrbhMaLsw==", + "version": "17.0.76", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.76.tgz", + "integrity": "sha512-w9Aq+qeszGYoQM0hgFcdsAODGJdogadBDiitPm+zjBFJ0mLymvn2qSXsDaLJUndFRqqXk1FQfa9avHUBk1JhJQ==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -27400,9 +27400,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==" + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==" }, "capture-exit": { "version": "2.0.0", @@ -28617,9 +28617,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" + "version": "1.4.682", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", + "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==" }, "emittery": { "version": "0.10.2", diff --git a/packages/react-native-room-kit/package.json b/packages/react-native-room-kit/package.json index 6ba6312fe..a8f23ead8 100644 --- a/packages/react-native-room-kit/package.json +++ b/packages/react-native-room-kit/package.json @@ -51,7 +51,7 @@ "registry": "https://registry.npmjs.org/" }, "dependencies": { - "@100mslive/types-prebuilt": "^0.12.4", + "@100mslive/types-prebuilt": "^0.12.7", "@react-navigation/native": "^6.0.8", "react-redux": "^7.2.4", "redux": "^4.1.0" From 906f65789ebad12369e6a586670f9c229f47c753 Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Tue, 27 Feb 2024 13:39:19 +0530 Subject: [PATCH 09/14] updated iOS SDK --- packages/react-native-hms/example/ios/Podfile.lock | 8 ++++---- packages/react-native-hms/sdk-versions.json | 2 +- .../react-native-room-kit/example/ios/Podfile.lock | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/react-native-hms/example/ios/Podfile.lock b/packages/react-native-hms/example/ios/Podfile.lock index dfeef626c..b5d06d45e 100644 --- a/packages/react-native-hms/example/ios/Podfile.lock +++ b/packages/react-native-hms/example/ios/Podfile.lock @@ -62,7 +62,7 @@ PODS: - HMSBroadcastExtensionSDK (0.0.9) - HMSHLSPlayerSDK (0.0.2): - HMSAnalyticsSDK (= 0.0.2) - - HMSSDK (1.5.1): + - HMSSDK (1.6.0): - HMSAnalyticsSDK (= 0.0.2) - HMSWebRTC (= 1.0.5116) - HMSWebRTC (1.0.5116) @@ -295,7 +295,7 @@ PODS: - react-native-hms (1.10.0): - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) - - HMSSDK (= 1.5.1) + - HMSSDK (= 1.6.0) - React-Core - react-native-safe-area-context (3.4.1): - React-Core @@ -629,7 +629,7 @@ SPEC CHECKSUMS: HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7 HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 - HMSSDK: ab468de17246fcc8d6315ea490e9d9b30431d6b3 + HMSSDK: 8bb7d5c9d593c4c1a15bdd28dbbc6dbc9a46c8e8 HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b @@ -649,7 +649,7 @@ SPEC CHECKSUMS: react-native-avoid-softinput: 71a692888f0c1d426ad9045dc8325773583962cd react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f react-native-document-picker: cd4d6b36a5207ad7a9e599ebb9eb0c2e84fa0b87 - react-native-hms: 1987174d6b78d691a4a350c28cfed30f3c8756ff + react-native-hms: 002adca217cf8c0b1bf28745e4b4c75f44430f58 react-native-safe-area-context: 9e40fb181dac02619414ba1294d6c2a807056ab9 react-native-simple-toast: 8ee5d23f0b92b935ab7434cdb65159ce12dfb4b7 React-perflogger: 5a890ca0911669421b7611661e9b58f91c805f5c diff --git a/packages/react-native-hms/sdk-versions.json b/packages/react-native-hms/sdk-versions.json index 4bcdd75d3..78182f2a4 100644 --- a/packages/react-native-hms/sdk-versions.json +++ b/packages/react-native-hms/sdk-versions.json @@ -1,5 +1,5 @@ { - "ios": "1.5.1", + "ios": "1.6.0", "iOSBroadcastExtension": "0.0.9", "iOSHMSHLSPlayer": "0.0.2", "android": "2.9.4" diff --git a/packages/react-native-room-kit/example/ios/Podfile.lock b/packages/react-native-room-kit/example/ios/Podfile.lock index dfe0b72d6..92cb3d408 100644 --- a/packages/react-native-room-kit/example/ios/Podfile.lock +++ b/packages/react-native-room-kit/example/ios/Podfile.lock @@ -79,7 +79,7 @@ PODS: - HMSBroadcastExtensionSDK (0.0.9) - HMSHLSPlayerSDK (0.0.2): - HMSAnalyticsSDK (= 0.0.2) - - HMSSDK (1.5.1): + - HMSSDK (1.6.0): - HMSAnalyticsSDK (= 0.0.2) - HMSWebRTC (= 1.0.5116) - HMSWebRTC (1.0.5116) @@ -318,10 +318,10 @@ PODS: - React-Core - react-native-camera/RN (4.2.1): - React-Core - - react-native-hms (1.9.12): + - react-native-hms (1.10.0): - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) - - HMSSDK (= 1.5.1) + - HMSSDK (= 1.6.0) - React-Core - react-native-lottie-splash-screen (1.1.1): - React @@ -667,7 +667,7 @@ SPEC CHECKSUMS: HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7 HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 - HMSSDK: ab468de17246fcc8d6315ea490e9d9b30431d6b3 + HMSSDK: 8bb7d5c9d593c4c1a15bdd28dbbc6dbc9a46c8e8 HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 lottie-ios: 8f97d3271e155c2d688875c29cd3c74908aef5f8 @@ -690,7 +690,7 @@ SPEC CHECKSUMS: React-logger: a1f028f6d8639a3f364ef80419e5e862e1115250 react-native-blur: 172abeaa2de2d3ba4dc586fa23488d01c533818f react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f - react-native-hms: fd39afbf329480a7f6c09b6978f0116e90630970 + react-native-hms: 002adca217cf8c0b1bf28745e4b4c75f44430f58 react-native-lottie-splash-screen: 015423265bac5f46016dff2e31c97b9590808856 react-native-safe-area-context: 61c8c484a3a9e7d1fda19f7b1794b35bbfd2262a react-native-simple-toast: bf002828cf816775a6809f7a9ec3907509bce11f From 748942e93fd1d91dc3f0f8d8a9a7fed3dd9d61b1 Mon Sep 17 00:00:00 2001 From: ygit Date: Thu, 29 Feb 2024 17:47:50 +0530 Subject: [PATCH 10/14] RN-238: Added HLS Timed Metadata API (#1346) # Description - RN-238: Added HLS Timed Metadata API ### Pre-launch Checklist - [x] The [Documentation] is updated accordingly, or this PR doesn't require it. - [x] I have updated the `ExampleAppChangelog.txt` file with relevant changes. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making, or this PR is test-exempt. - [x] All existing and new tests are passing. [Documentation]: https://www.100ms.live/docs --------- Co-authored-by: Jatin Nagar --- .trunk/trunk.yaml | 8 ++-- .../java/com/reactnativehmssdk/HMSManager.kt | 20 ++++++++++ .../java/com/reactnativehmssdk/HMSRNSDK.kt | 38 +++++++++++++++++++ packages/react-native-hms/ios/HMSManager.m | 4 ++ .../react-native-hms/ios/HMSManager.swift | 11 +++++- packages/react-native-hms/ios/HMSRNSDK.swift | 34 +++++++++++++++++ .../src/classes/HMSHLSTimedMetadata.ts | 4 ++ .../react-native-hms/src/classes/HMSSDK.tsx | 12 ++++++ .../src/HMSRoomSetup.tsx | 14 ++++++- 9 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 packages/react-native-hms/src/classes/HMSHLSTimedMetadata.ts diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index f77141417..603d2c8c2 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 1.20.0 + version: 1.20.1 plugins: sources: - id: trunk @@ -10,12 +10,12 @@ lint: disabled: - osv-scanner enabled: - - actionlint@1.6.26 + - actionlint@1.6.27 - prettier@3.2.5 - swiftlint@0.54.0 - - checkov@3.2.22 + - checkov@3.2.26 - trivy@0.49.1 - - trufflehog@3.67.6 + - trufflehog@3.68.2 - oxipng@9.0.0 - yamllint@1.35.1 - ktlint@1.1.1 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 77aa2b270..de6822e97 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 @@ -530,6 +530,8 @@ class HMSManager(reactContext: ReactApplicationContext) : hms?.stopRtmpAndRecording(callback) } + // region - HLS Streaming + @ReactMethod fun startHLSStreaming( data: ReadableMap, @@ -550,6 +552,24 @@ class HMSManager(reactContext: ReactApplicationContext) : hms?.stopHLSStreaming(callback) } + @ReactMethod + fun sendHLSTimedMetadata( + data: ReadableMap, + callback: Promise?, + ) { + val rnSDK = HMSHelper.getHms(data, hmsCollection) + rnSDK?.let { sdk -> + sdk.sendHLSTimedMetadata(data, callback) + return + } + callback?.reject( + "6004", + "HMS SDK not initialized", + ) + } + + // endregion + @ReactMethod fun changeName( data: ReadableMap, 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 5081d4f69..90e01e00e 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 @@ -1580,6 +1580,8 @@ class HMSRNSDK( ) } + // region - HLS Streaming + fun startHLSStreaming( data: ReadableMap, callback: Promise?, @@ -1614,6 +1616,42 @@ class HMSRNSDK( ) } + fun sendHLSTimedMetadata( + data: ReadableMap, + callback: Promise?, + ) { + val metadataArrayList = data.getArray("metadata")?.toArrayList() as? ArrayList + + if (metadataArrayList == null) { + val errorMessage = "sendHLSTimedMetadata: INVALID_METADATA" + rejectCallback(callback, errorMessage) + return + } + + val metadata = + metadataArrayList.mapNotNull { map -> + val payload = map.getString("payload") + val duration = map.getInt("duration") + + payload?.let { HMSHLSTimedMetadata(it, duration.toLong()) } + } + + hmsSDK?.setHlsSessionMetadata( + metadata, + object : HMSActionResultListener { + override fun onSuccess() { + callback?.resolve(true) + } + + override fun onError(error: HMSException) { + callback?.reject(error.code.toString(), error.message) + } + }, + ) + } + + // endregion + fun changeName( data: ReadableMap, callback: Promise?, diff --git a/packages/react-native-hms/ios/HMSManager.m b/packages/react-native-hms/ios/HMSManager.m index 223708fad..908bfba42 100644 --- a/packages/react-native-hms/ios/HMSManager.m +++ b/packages/react-native-hms/ios/HMSManager.m @@ -107,6 +107,10 @@ @interface RCT_EXTERN_MODULE (HMSManager, RCTEventEmitter) : (NSDictionary)data : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(sendHLSTimedMetadata + : (NSDictionary)data + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(changeName : (NSDictionary)data : (RCTPromiseResolveBlock)resolve diff --git a/packages/react-native-hms/ios/HMSManager.swift b/packages/react-native-hms/ios/HMSManager.swift index 1f99c40be..a88236d6f 100644 --- a/packages/react-native-hms/ios/HMSManager.swift +++ b/packages/react-native-hms/ios/HMSManager.swift @@ -349,7 +349,7 @@ class HMSManager: RCTEventEmitter { hms?.stopRtmpAndRecording(resolve, reject) } - // MARK: - HLS Streaming & Recording + // MARK: - HLS Streaming @objc func startHLSStreaming(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { @@ -365,6 +365,15 @@ class HMSManager: RCTEventEmitter { hms?.stopHLSStreaming(resolve, reject) } + @objc + func sendHLSTimedMetadata(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let rnsdk = HMSHelper.getHms(data, hmsCollection) else { + reject?("6004", "HMSRNSDK instance not found!", nil) + return + } + rnsdk.sendHLSTimedMetadata(data, resolve, reject) + } + // MARK: - Screen Share @objc diff --git a/packages/react-native-hms/ios/HMSRNSDK.swift b/packages/react-native-hms/ios/HMSRNSDK.swift index bf7dea017..13e7c753c 100644 --- a/packages/react-native-hms/ios/HMSRNSDK.swift +++ b/packages/react-native-hms/ios/HMSRNSDK.swift @@ -797,6 +797,8 @@ class HMSRNSDK: HMSUpdateListener, HMSPreviewListener { }) } + // MARK: - HLS Streaming + func startHLSStreaming(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { let recordConfig = HMSHelper.getHlsRecordingConfig(data.value(forKey: "hlsRecordingConfig") as? NSDictionary) let hlsMeetingUrlVariant = HMSHelper.getHMSHLSMeetingURLVariants(data.value(forKey: "meetingURLVariants") as? [[String: Any]]) @@ -828,6 +830,38 @@ class HMSRNSDK: HMSUpdateListener, HMSPreviewListener { }) } + func sendHLSTimedMetadata(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let metadataArrayList = data["metadata"] as? [NSDictionary] else { + let errorMessage = "\(#function) metadata for sendHLSTimedMetadata was not found" + reject?("6004", errorMessage, nil) + return + } + + let metadata = metadataArrayList.compactMap { (dict: NSDictionary) -> HMSHLSTimedMetadata? in + guard let payload = dict["payload"] as? String else { + return nil + } + if let duration = dict["duration"] as? Int { + return HMSHLSTimedMetadata(payload: payload, duration: duration) + } else { + return HMSHLSTimedMetadata(payload: payload) + } + } + + DispatchQueue.main.async { [weak self] in + self?.hms?.sendHLSTimedMetadata(metadata) { success, error in + if let error = error as? HMSError { + print(#function, "Unable to send metadata: \(error)") + reject?("6004", error.localizedDescription, nil) + } + + resolve?(success) + } + } + } + + // MARK: - + func changeName(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { guard let name = data.value(forKey: "name") as? String else { diff --git a/packages/react-native-hms/src/classes/HMSHLSTimedMetadata.ts b/packages/react-native-hms/src/classes/HMSHLSTimedMetadata.ts new file mode 100644 index 000000000..ceb7ea9c0 --- /dev/null +++ b/packages/react-native-hms/src/classes/HMSHLSTimedMetadata.ts @@ -0,0 +1,4 @@ +export interface HMSHLSTimedMetadata { + payload: string; + duration: number; +} diff --git a/packages/react-native-hms/src/classes/HMSSDK.tsx b/packages/react-native-hms/src/classes/HMSSDK.tsx index dccbebe8e..e735e3835 100644 --- a/packages/react-native-hms/src/classes/HMSSDK.tsx +++ b/packages/react-native-hms/src/classes/HMSSDK.tsx @@ -47,6 +47,7 @@ import type { HMSPeerListIteratorOptions } from './HMSPeerListIteratorOptions'; import { HMSPeerListIterator } from './HMSPeerListIterator'; import type { HMSPIPConfig } from './HMSPIPConfig'; import { HMSInteractivityCenter } from './HMSInteractivityCenter'; +import type { HMSHLSTimedMetadata } from './HMSHLSTimedMetadata'; type HmsViewProps = Omit; @@ -430,6 +431,17 @@ export class HMSSDK { return await HMSManager.stopHLSStreaming({ id: this.id }); }; + /** + * send timed metadata for HLS player + * @param metadata list of {@link HMSHLSTimedMetadata} to be sent + * @returns Promise + */ + sendHLSTimedMetadata = async (metadata: HMSHLSTimedMetadata[]) => { + const data = { metadata, id: this.id }; + logger?.verbose('#Function sendHLSTimedMetadata', data); + return await HMSManager.sendHLSTimedMetadata(data); + }; + /** * @deprecated This function has been deprecated in favor of #Function changeRoleOfPeer * diff --git a/packages/react-native-room-kit/src/HMSRoomSetup.tsx b/packages/react-native-room-kit/src/HMSRoomSetup.tsx index 873bc5eee..aa7589c83 100644 --- a/packages/react-native-room-kit/src/HMSRoomSetup.tsx +++ b/packages/react-native-room-kit/src/HMSRoomSetup.tsx @@ -402,10 +402,22 @@ export const HMSRoomSetup = () => { useEffect(() => { const subscription = hmsInstance.interactivityCenter.addPollUpdateListener( - (poll, pollUpdateType) => { + async (poll, pollUpdateType) => { const reduxState = reduxStore.getState(); const pollsData = reduxState.polls.polls; + // Send HLS Timed Metadata for poll if it is started by local peer + if ( + poll.createdBy && + reduxState.hmsStates.localPeer && + poll.createdBy.peerID === reduxState.hmsStates.localPeer.peerID + ) { + const result = await hmsInstance.sendHLSTimedMetadata([ + { duration: 20, payload: `poll:${poll.pollId}` }, + ]); + console.log('sendHLSTimedMetadata result: ', result); + } + batch(() => { // Update poll object in store dispatch(addPoll(poll)); From 188ae833634c6d008cb8b04c269643d1062e8b83 Mon Sep 17 00:00:00 2001 From: ygit Date: Tue, 5 Mar 2024 13:14:03 +0530 Subject: [PATCH 11/14] Added Quizzes Leaderboard (#1347) # Description - Added Quizzes Leaderboard ### Pre-launch Checklist - [x] The [Documentation] is updated accordingly, or this PR doesn't require it. - [x] I have updated the `ExampleAppChangelog.txt` file with relevant changes. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making, or this PR is test-exempt. - [x] All existing and new tests are passing. [Documentation]: https://www.100ms.live/docs --------- Co-authored-by: Jatin Nagar --- .trunk/trunk.yaml | 8 +- .../com/reactnativehmssdk/HMSHLSPlayer.kt | 15 - .../java/com/reactnativehmssdk/HMSManager.kt | 18 + .../java/com/reactnativehmssdk/HMSRNSDK.kt | 8 +- .../Interactivity/HMSInteractivityDecoder.kt | 85 +++++ .../Interactivity/HMSRNInteractivityCenter.kt | 100 ++--- .../ios/HMSInteractivityDecoder.swift | 50 +++ packages/react-native-hms/ios/HMSManager.m | 5 + .../react-native-hms/ios/HMSManager.swift | 9 + .../ios/HMSRNInteractivityCenter.swift | 31 ++ .../src/classes/HMSInteractivityCenter.ts | 30 ++ .../src/classes/HMSInteractivityEncoder.ts | 59 ++- .../polls/DecodedPollLeaderboardResponse.ts | 43 +++ .../src/classes/polls/HMSPoll.ts | 19 +- .../src/classes/polls/HMSPollCreateParams.ts | 5 +- .../classes/polls/HMSPollLeaderboardEntry.ts | 10 + .../polls/HMSPollLeaderboardSummary.ts | 7 + .../classes/polls/PollLeaderboardResponse.ts | 8 + .../components/HMSHLSPlayer/HMSHLSPlayer.tsx | 17 +- packages/react-native-hms/src/index.ts | 3 + .../example/android/app/build.gradle | 4 +- .../ios/RNExample.xcodeproj/project.pbxproj | 8 +- .../example/ios/RNExample/Info.plist | 4 +- .../example/src/redux/reducers/appState.ts | 8 +- .../react-native-room-kit/package-lock.json | 12 +- .../src/HMSRoomSetup.tsx | 14 +- .../src/Icons/Clock/assets/clock-vector.png | Bin 0 -> 4031 bytes .../Icons/Clock/assets/clock-vector@2x.png | Bin 0 -> 11272 bytes .../Icons/Clock/assets/clock-vector@3x.png | Bin 0 -> 21659 bytes .../src/Icons/Clock/assets/clock.png | Bin 4031 -> 277 bytes .../src/Icons/Clock/assets/clock@2x.png | Bin 11312 -> 533 bytes .../src/Icons/Clock/assets/clock@3x.png | Bin 21659 -> 697 bytes .../src/Icons/Clock/index.tsx | 19 +- .../src/components/CreatePoll.tsx | 9 +- .../src/components/HLSView.tsx | 28 +- .../HMSPollsQuizzesNotification.tsx | 4 +- .../src/components/LeaderboardEntry.tsx | 172 +++++++++ .../src/components/PollAndQuizSheetScreen.tsx | 85 +++++ .../src/components/PollAndQuizVoting.tsx | 188 +++++++++- .../src/components/PollQuestions.tsx | 220 ++++++++--- .../components/PollsAndQuizBottomSheet.tsx | 62 +--- .../src/components/PollsAndQuizzesCard.tsx | 4 +- .../PollsAndQuizzesModalContent.tsx | 203 ++--------- .../src/components/PollsConfigAndList.tsx | 118 +++++- .../PreviousPollsAndQuizzesList.tsx | 73 ++-- .../QuizLeaderboardEntriesScreen.tsx | 323 +++++++++++++++++ .../src/components/QuizLeaderboardScreen.tsx | 342 ++++++++++++++++++ .../src/components/QuizLeaderboardSummary.tsx | 207 +++++++++++ .../components/VoterParticipationSummary.tsx | 67 ++++ .../src/redux/actionTypes.ts | 40 +- .../src/redux/actions/index.ts | 40 +- .../src/redux/reducers/polls.ts | 90 ++++- .../react-native-room-kit/src/utils/hooks.ts | 193 +++++++++- 53 files changed, 2586 insertions(+), 481 deletions(-) create mode 100644 packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts create mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts create mode 100644 packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts create mode 100644 packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts create mode 100644 packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector.png create mode 100644 packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@2x.png create mode 100644 packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@3x.png create mode 100644 packages/react-native-room-kit/src/components/LeaderboardEntry.tsx create mode 100644 packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx create mode 100644 packages/react-native-room-kit/src/components/QuizLeaderboardEntriesScreen.tsx create mode 100644 packages/react-native-room-kit/src/components/QuizLeaderboardScreen.tsx create mode 100644 packages/react-native-room-kit/src/components/QuizLeaderboardSummary.tsx create mode 100644 packages/react-native-room-kit/src/components/VoterParticipationSummary.tsx diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 603d2c8c2..7177e5d65 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -4,7 +4,7 @@ cli: plugins: sources: - id: trunk - ref: v1.4.3 + ref: v1.4.4 uri: https://github.com/trunk-io/plugins lint: disabled: @@ -13,12 +13,12 @@ lint: - actionlint@1.6.27 - prettier@3.2.5 - swiftlint@0.54.0 - - checkov@3.2.26 + - checkov@3.2.30 - trivy@0.49.1 - - trufflehog@3.68.2 + - trufflehog@3.68.4 - oxipng@9.0.0 - yamllint@1.35.1 - - ktlint@1.1.1 + - ktlint@1.2.1 - svgo@3.2.0 - shfmt@3.6.0 - gitleaks@8.18.2 diff --git a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt index 1d037e298..1389eb20b 100644 --- a/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt +++ b/packages/react-native-hms/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt @@ -6,8 +6,6 @@ import android.view.LayoutInflater import android.widget.FrameLayout import androidx.media3.common.Player import androidx.media3.common.VideoSize -import androidx.media3.ui.AspectRatioFrameLayout.RESIZE_MODE_FIT -import androidx.media3.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM import androidx.media3.ui.PlayerView import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactContext @@ -133,13 +131,6 @@ class HMSHLSPlayer(context: ReactContext) : FrameLayout(context) { localPlayerView?.player?.addListener( object : Player.Listener { - override fun onSurfaceSizeChanged( - width: Int, - height: Int, - ) { - super.onSurfaceSizeChanged(width, height) - } - override fun onVideoSizeChanged(videoSize: VideoSize) { super.onVideoSizeChanged(videoSize) @@ -147,12 +138,6 @@ class HMSHLSPlayer(context: ReactContext) : FrameLayout(context) { val width = videoSize.width.toDouble() val height = videoSize.height.toDouble() - if (width >= height) { - playerView?.resizeMode = RESIZE_MODE_FIT - } else { - playerView?.resizeMode = RESIZE_MODE_ZOOM - } - val data = Arguments.createMap() data.putDouble("width", width) data.putDouble("height", height) 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 de6822e97..6f0d27c84 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 @@ -1416,6 +1416,24 @@ class HMSManager(reactContext: ReactApplicationContext) : "HMS SDK not initialized", ) } + + @ReactMethod + fun fetchLeaderboard( + data: ReadableMap, + promise: Promise?, + ) { + val rnSDK = HMSHelper.getHms(data, hmsCollection) + rnSDK?.let { sdk -> + sdk.interactivityCenter?.let { center -> + center.fetchLeaderboard(data, promise) + return + } + } + promise?.reject( + "6004", + "HMS SDK not initialized", + ) + } // endregion // region ActivityLifecycleCallbacks 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 90e01e00e..645fe8190 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 @@ -1620,7 +1620,7 @@ class HMSRNSDK( data: ReadableMap, callback: Promise?, ) { - val metadataArrayList = data.getArray("metadata")?.toArrayList() as? ArrayList + val metadataArrayList = data.getArray("metadata")?.toArrayList() as? ArrayList> if (metadataArrayList == null) { val errorMessage = "sendHLSTimedMetadata: INVALID_METADATA" @@ -1630,10 +1630,10 @@ class HMSRNSDK( val metadata = metadataArrayList.mapNotNull { map -> - val payload = map.getString("payload") - val duration = map.getInt("duration") + val payload = map["payload"] as? String + val duration = map["duration"] as? Double - payload?.let { HMSHLSTimedMetadata(it, duration.toLong()) } + payload?.let { HMSHLSTimedMetadata(it, duration?.toLong() ?: 1) } } hmsSDK?.setHlsSessionMetadata( 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 83abde377..44ecd3c18 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 @@ -10,8 +10,12 @@ import live.hms.video.polls.models.answer.HMSPollQuestionAnswer import live.hms.video.polls.models.answer.HmsPollAnswer import live.hms.video.polls.models.answer.PollAnswerItem import live.hms.video.polls.models.answer.PollAnswerResponse +import live.hms.video.polls.models.network.HMSPollResponsePeerInfo import live.hms.video.polls.models.question.HMSPollQuestion import live.hms.video.polls.models.question.HMSPollQuestionOption +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 object HMSInteractivityDecoder { @@ -310,6 +314,87 @@ object HMSInteractivityDecoder { return results } + fun getPollLeaderboardResponse(pollLeaderboardResponse: PollLeaderboardResponse): WritableMap { + val results = Arguments.createMap() + + pollLeaderboardResponse.hasNext?.let { + results.putBoolean("hasNext", it) + } + pollLeaderboardResponse.summary?.let { + results.putMap("summary", getHMSPollLeaderboardSummary(it)) + } + pollLeaderboardResponse.entries?.let { + results.putArray("entries", getHMSPollLeaderboardEntries(it)) + } + return results + } + + private fun getHMSPollLeaderboardSummary(pollLeaderboardSummary: HMSPollLeaderboardSummary): WritableMap { + val summary = Arguments.createMap() + pollLeaderboardSummary.averageScore?.let { + summary.putDouble("averageScore", it.toDouble()) + } + pollLeaderboardSummary.averageTime?.let { + summary.putString("averageTime", it.toString()) + } + pollLeaderboardSummary.totalPeersCount?.let { + summary.putInt("totalPeersCount", it) + } + pollLeaderboardSummary.respondedCorrectlyPeersCount?.let { + summary.putInt("respondedCorrectlyPeersCount", it) + } + pollLeaderboardSummary.respondedPeersCount?.let { + summary.putInt("respondedPeersCount", it) + } + return summary + } + + private fun getHMSPollLeaderboardEntries(pollLeaderboardEntries: List): WritableArray { + val list = Arguments.createArray() + pollLeaderboardEntries.forEach { + list.pushMap(getHMSPollLeaderboardEntry(it)) + } + return list + } + + private fun getHMSPollLeaderboardEntry(pollLeaderboardEntry: HMSPollLeaderboardEntry): WritableMap { + val entry = Arguments.createMap() + pollLeaderboardEntry.duration?.let { + entry.putString("duration", it.toString()) + } + pollLeaderboardEntry.peer?.let { + entry.putMap("peer", getHMSPollResponsePeerInfo(it)) + } + pollLeaderboardEntry.totalResponses?.let { + entry.putString("totalResponses", it.toString()) + } + pollLeaderboardEntry.correctResponses?.let { + entry.putString("correctResponses", it.toString()) + } + pollLeaderboardEntry.position?.let { + entry.putString("position", it.toString()) + } + pollLeaderboardEntry.score?.let { + entry.putString("score", it.toString()) + } + return entry + } + + private fun getHMSPollResponsePeerInfo(pollResponsePeerInfo: HMSPollResponsePeerInfo): WritableMap { + val peerInfo = Arguments.createMap() + peerInfo.putString("userHash", pollResponsePeerInfo.hash) + pollResponsePeerInfo.peerid?.let { + peerInfo.putString("peerId", it) + } + pollResponsePeerInfo.userid?.let { + peerInfo.putString("customerUserId", it) + } + pollResponsePeerInfo.username?.let { + peerInfo.putString("userName", it) + } + return peerInfo + } + private fun getHMSPollQuestionResponseResult(hmsPollQuestionResponseResult: PollAnswerItem): WritableMap { val result = Arguments.createMap() 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 dde1b1cc6..b2bb03e56 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 @@ -1,5 +1,4 @@ package com.reactnativehmssdk -import android.util.Log import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap @@ -10,6 +9,7 @@ import live.hms.video.interactivity.HmsPollUpdateListener import live.hms.video.polls.models.HMSPollUpdateType import live.hms.video.polls.models.HmsPoll import live.hms.video.polls.models.answer.PollAnswerResponse +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 @@ -37,8 +37,6 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN } } - // region Create Polls - fun quickStartPoll( data: ReadableMap, promise: Promise?, @@ -59,64 +57,29 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } - /* - - func add(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { - guard let pollId = data["pollId"] as? String, - let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { - reject?("6004", "Unable to find HMSPoll with given pollId", nil) - return - } - guard let pollQuestionIndex = data["pollQuestionIndex"] as? Int, - let pollQuestion = poll.questions?.first(where: {question in question.index == pollQuestionIndex}) else { - reject?("6004", "Unable to find HMSPollQuestion in poll with given question index", nil) - return - } - guard let responses = data["responses"] as? NSDictionary else { - reject?("6004", "responses field is required", nil) - return - } - - let pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll: poll, pollQuestion: pollQuestion) - - self.hmssdk?.interactivityCenter.add(response: pollResponseBuilder) { pollQuestionResponseResult, error in - if let nonnilError = error { - reject?("6004", nonnilError.localizedDescription, nil) - return - } - if let pollQuestionResponseResult = pollQuestionResponseResult { - resolve?(HMSInteractivityDecoder.getHMSPollQuestionResponseResults(pollQuestionResponseResult)) - } else { - resolve?(nil) - } - } - } - - */ - fun addResponseOnPollQuestion( data: ReadableMap, promise: Promise?, ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6002", "pollId is required") + promise?.reject("6004", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") return } val pollQuestionIndex = data.getInt("pollQuestionIndex") val pollQuestion = poll.questions?.find { it.questionID == pollQuestionIndex } if (pollQuestion == null) { - promise?.reject("6002", "No HMSPollQuestion in poll with given question index") + promise?.reject("6004", "No HMSPollQuestion in poll with given question index") return } val responses = data.getMap("responses") if (responses == null) { - promise?.reject("6002", "responses field is required") + promise?.reject("6004", "responses field is required") return } val pollResponseBuilder = HMSInteractivityHelper.getPollResponseBuilder(responses, poll, pollQuestion) @@ -140,12 +103,12 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) { val pollId = data.getString("pollId") if (pollId == null) { - promise?.reject("6002", "pollId is required") + promise?.reject("6004", "pollId is required") return } val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } if (poll == null) { - promise?.reject("6002", "No HMSPoll with pollId `$pollId`") + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") return } this.sdk.getHmsInteractivityCenter().stop( @@ -162,23 +125,38 @@ class HMSRNInteractivityCenter(private val sdk: HMSSDK, private val rnSDK: HMSRN ) } - // endregion - - // region Poll Update Listener - - fun showPollStartedToast() { - // Show toast - Log.e("Interactivity", "showPollStartedToast") - } - - fun loadResultsSummaryIfNeeded() { - // Load results summary - Log.e("Interactivity", "loadResultsSummaryIfNeeded") - } + fun fetchLeaderboard( + data: ReadableMap, + promise: Promise?, + ) { + val pollId = data.getString("pollId") + if (pollId == null) { + promise?.reject("6004", "pollId is required") + return + } + val poll = this.sdk.getHmsInteractivityCenter().polls.find { it.pollId == pollId } + if (poll == null) { + promise?.reject("6004", "No HMSPoll with pollId `$pollId`") + return + } + val count = data.getInt("count") + val startIndex = data.getInt("startIndex") + val includeCurrentPeer = data.getBoolean("includeCurrentPeer") + + this.sdk.getHmsInteractivityCenter().fetchLeaderboard( + pollId = poll.pollId, + count = count.toLong(), + startIndex = startIndex.toLong(), + includeCurrentPeer = includeCurrentPeer, + object : HmsTypedActionResultListener { + override fun onSuccess(result: PollLeaderboardResponse) { + promise?.resolve(HMSInteractivityDecoder.getPollLeaderboardResponse(result)) + } - fun updateResultsScreen() { - // Update results screen - Log.e("Interactivity", "updateResultsScreen") + override fun onError(error: HMSException) { + promise?.reject(error.code.toString(), error.description) + } + }, + ) } - // endregion } diff --git a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift index 89d9b84d3..7df6f0120 100644 --- a/packages/react-native-hms/ios/HMSInteractivityDecoder.swift +++ b/packages/react-native-hms/ios/HMSInteractivityDecoder.swift @@ -220,4 +220,54 @@ class HMSInteractivityDecoder { } return result } + + static func getLeaderboardResponse(_ response: HMSPollLeaderboardResponse) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["hasNext"] = response.hasNext + + result["summary"] = getLeaderboardSummary(response.summary) + + result["entries"] = getLeaderboardEntries(response.entries) + + return result + } + + static func getLeaderboardSummary(_ summary: HMSPollLeaderboardSummary) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["averageScore"] = summary.averageScore + result["averageTime"] = summary.averageTime + result["totalPeersCount"] = summary.totalPeersCount + result["respondedCorrectlyPeersCount"] = summary.respondedCorrectlyPeersCount + result["respondedPeersCount"] = summary.respondedPeersCount + + return result + } + + static func getLeaderboardEntries(_ entries: [HMSPollLeaderboardEntry]) -> [[String: AnyHashable]] { + var result = [[String: AnyHashable]]() + + for entry in entries { + result.append(getLeaderboardEntry(entry)) + } + + return result + } + + static func getLeaderboardEntry(_ entry: HMSPollLeaderboardEntry) -> [String: AnyHashable] { + var result = [String: AnyHashable]() + + result["duration"] = entry.duration + result["totalResponses"] = entry.totalResponses + result["correctResponses"] = entry.correctResponses + result["position"] = entry.position + result["score"] = entry.score + + if let peer = entry.peer { + result["peer"] = getHMSPollResponsePeerInfo(peer) + } + + return result + } } diff --git a/packages/react-native-hms/ios/HMSManager.m b/packages/react-native-hms/ios/HMSManager.m index 908bfba42..205eee78c 100644 --- a/packages/react-native-hms/ios/HMSManager.m +++ b/packages/react-native-hms/ios/HMSManager.m @@ -317,4 +317,9 @@ @interface RCT_EXTERN_MODULE (HMSManager, RCTEventEmitter) : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(fetchLeaderboard + : (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 a88236d6f..fa5816d5c 100644 --- a/packages/react-native-hms/ios/HMSManager.swift +++ b/packages/react-native-hms/ios/HMSManager.swift @@ -681,4 +681,13 @@ class HMSManager: RCTEventEmitter { } interactivity.stop(data, resolve, reject) } + + @objc + func fetchLeaderboard(_ 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.fetchLeaderboard(data, resolve, reject) + } } diff --git a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift index 4ca6a6423..abccab8b5 100644 --- a/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift +++ b/packages/react-native-hms/ios/HMSRNInteractivityCenter.swift @@ -86,4 +86,35 @@ class HMSRNInteractivityCenter { resolve?(success) }) } + + func fetchLeaderboard(_ data: NSDictionary, _ resolve: RCTPromiseResolveBlock?, _ reject: RCTPromiseRejectBlock?) { + guard let pollId = data["pollId"] as? String, + let poll = self.hmssdk?.interactivityCenter.polls.first(where: {poll in poll.pollID == pollId}) else { + reject?("6004", "Unable to find HMSPoll with given pollId", nil) + return + } + + guard let count = data["count"] as? Int, + let startIndex = data["startIndex"] as? Int + else { + reject?("6004", "Unable to find required parameters", nil) + return + } + + let includeCurrentPeer = data["includeCurrentPeer"] as? Bool ?? false + + self.hmssdk?.interactivityCenter.fetchLeaderboard(for: poll, offset: startIndex, count: count, includeCurrentPeer: includeCurrentPeer) { response, error in + + if let nonnilError = error { + reject?("6004", nonnilError.localizedDescription, nil) + return + } + + if let response = response { + resolve?(HMSInteractivityDecoder.getLeaderboardResponse(response)) + } else { + reject?("6004", "Could not fetch leaderboard response", nil) + } + } + } } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts index ac10da22f..fb3e39488 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityCenter.ts @@ -10,6 +10,8 @@ import HMSNativeEventListener from './HMSNativeEventListener'; import type { HMSEventSubscription } from './HMSNativeEventEmitter'; import { HMSInteractivityEncoder } from './HMSInteractivityEncoder'; import { HMSHelper } from './HMSHelper'; +import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; +import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; type PollUpdateListener = (data: { updatedPoll: HMSPoll; @@ -134,4 +136,32 @@ export class HMSInteractivityCenter { logger?.verbose('#Function stop', JSON.stringify(data)); return HMSManager.stopPoll(data); } + + /** + * Fetches the leaderboard for a poll + * @param pollId - The id of the poll + * @param count - The number of entries to fetch + * @param startIndex - The index to start fetching from + * @param includeCurrentPeer - Whether to include the current peer in the fetched leaderboard entries + * @returns Promise + */ + async fetchLeaderboard( + pollId: string, + count: number, + startIndex: number, + includeCurrentPeer: boolean + ): Promise { + const data = { + id: HMSConstants.DEFAULT_SDK_ID, + pollId, + count, + startIndex, + includeCurrentPeer, + }; + logger?.verbose('#Function fetchLeaderboard', data); + + const response: DecodedPollLeaderboardResponse = + await HMSManager.fetchLeaderboard(data); + return HMSInteractivityEncoder.transformPollLeaderboardResponse(response); + } } diff --git a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts index 27d4d14a9..d45ccc667 100644 --- a/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts +++ b/packages/react-native-hms/src/classes/HMSInteractivityEncoder.ts @@ -1,4 +1,7 @@ +import { HMSEncoder } from './HMSEncoder'; +import type { DecodedPollLeaderboardResponse } from './polls/DecodedPollLeaderboardResponse'; import type { HMSPoll } from './polls/HMSPoll'; +import type { PollLeaderboardResponse } from './polls/PollLeaderboardResponse'; export class HMSInteractivityEncoder { static transformPoll(poll: HMSPoll): HMSPoll { @@ -20,10 +23,62 @@ export class HMSInteractivityEncoder { poll.stoppedAt = new Date(dateNum); } } - // poll.rolesThatCanVote: HMSRole[]; - // poll.rolesThatCanViewResponses: HMSRole[]; + if (poll.createdBy) { + poll.createdBy = HMSEncoder.encodeHmsPeer(poll.createdBy); + } + if (poll.startedBy) { + poll.startedBy = HMSEncoder.encodeHmsPeer(poll.startedBy); + } + if (poll.stoppedBy) { + poll.stoppedBy = HMSEncoder.encodeHmsPeer(poll.stoppedBy); + } + if (poll.rolesThatCanVote) { + poll.rolesThatCanVote = poll.rolesThatCanVote.map((role) => + HMSEncoder.encodeHmsRole(role) + ); + } + if (poll.rolesThatCanViewResponses) { + poll.rolesThatCanViewResponses = poll.rolesThatCanViewResponses.map( + (role) => HMSEncoder.encodeHmsRole(role) + ); + } + // --- poll.questions: HMSPollQuestion[] // --- poll.result: HMSPollResult return poll; } + + static transformPollLeaderboardResponse( + decodedPollLeaderboardResponse: DecodedPollLeaderboardResponse + ): PollLeaderboardResponse { + const summary = decodedPollLeaderboardResponse.summary; + if (summary) { + if (typeof summary.averageTime === 'string') { + summary.averageTime = parseInt(summary.averageTime); + } + } + + const entries = decodedPollLeaderboardResponse.entries; + if (entries) { + entries.forEach((entry) => { + if (typeof entry.duration === 'string') { + entry.duration = parseInt(entry.duration); + } + if (typeof entry.totalResponses === 'string') { + entry.totalResponses = parseInt(entry.totalResponses); + } + if (typeof entry.correctResponses === 'string') { + entry.correctResponses = parseInt(entry.correctResponses); + } + if (typeof entry.position === 'string') { + entry.position = parseInt(entry.position); + } + if (typeof entry.score === 'string') { + entry.score = parseInt(entry.score); + } + }); + } + + return decodedPollLeaderboardResponse as PollLeaderboardResponse; + } } diff --git a/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts new file mode 100644 index 000000000..17a288768 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/DecodedPollLeaderboardResponse.ts @@ -0,0 +1,43 @@ +import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; +import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; +import type { PollLeaderboardResponse } from './PollLeaderboardResponse'; + +type NumberString = string; + +export interface DecodedPollLeaderboardResponse + extends Pick { + entries?: DecodedHMSPollLeaderboardEntry[]; + summary?: DecodedHMSPollLeaderboardSummary; +} + +export interface DecodedHMSPollLeaderboardEntry + extends Pick { + /** + * convert this value to number + */ + duration?: NumberString | number; + /** + * convert this value to number + */ + totalResponses?: NumberString | number; + /** + * convert this value to number + */ + correctResponses?: NumberString | number; + /** + * convert this value to number + */ + position?: NumberString | number; + /** + * convert this value to number + */ + score?: NumberString | number; +} + +export interface DecodedHMSPollLeaderboardSummary + extends Omit { + /** + * convert this value to number + */ + averageTime?: NumberString | number; +} diff --git a/packages/react-native-hms/src/classes/polls/HMSPoll.ts b/packages/react-native-hms/src/classes/polls/HMSPoll.ts index 56c9f6c04..dc4d8a554 100644 --- a/packages/react-native-hms/src/classes/polls/HMSPoll.ts +++ b/packages/react-native-hms/src/classes/polls/HMSPoll.ts @@ -6,15 +6,6 @@ import type { HMSPollUserTrackingMode } from './HMSPollUserTrackingMode'; import type { HMSPollType } from './HMSPollType'; import type { HMSPeer } from '../HMSPeer'; -type HMSPeerSubset = { - peerID: HMSPeer['peerID']; - name: HMSPeer['name']; -}; - -type HMSRoleSubset = { - name: HMSRole['name']; -}; - export interface HMSPoll { /** The unique identifier of the poll. @@ -44,27 +35,27 @@ export interface HMSPoll { /** The roles that can vote in the poll. */ - rolesThatCanVote?: HMSRoleSubset[]; + rolesThatCanVote?: HMSRole[]; /** The roles that can view the poll responses. */ - rolesThatCanViewResponses?: HMSRoleSubset[]; + rolesThatCanViewResponses?: HMSRole[]; /** The peer who started the poll. */ - startedBy?: HMSPeerSubset; + startedBy?: HMSPeer; /** The peer who stopped the poll. */ - stoppedBy?: HMSPeerSubset; + stoppedBy?: HMSPeer; /** The peer who created the poll. */ - createdBy?: HMSPeerSubset; + createdBy?: HMSPeer; /** The date and time when the poll was started. diff --git a/packages/react-native-hms/src/classes/polls/HMSPollCreateParams.ts b/packages/react-native-hms/src/classes/polls/HMSPollCreateParams.ts index 15f80034d..bbcf51e4d 100644 --- a/packages/react-native-hms/src/classes/polls/HMSPollCreateParams.ts +++ b/packages/react-native-hms/src/classes/polls/HMSPollCreateParams.ts @@ -1,4 +1,3 @@ -import type { HMSRole } from '../HMSRole'; import type { HMSPoll } from './HMSPoll'; import type { HMSPollQuestionCreateParams } from './HMSPollQuestionCreateParams'; @@ -12,9 +11,9 @@ export interface HMSPollCreateParams // | 'visibility' // | 'locked' | 'mode' + | 'rolesThatCanVote' + | 'rolesThatCanViewResponses' > { pollId?: HMSPoll['pollId']; questions?: HMSPollQuestionCreateParams[]; - rolesThatCanVote?: HMSRole[]; - rolesThatCanViewResponses?: HMSRole[]; } diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts new file mode 100644 index 000000000..5ed159de5 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardEntry.ts @@ -0,0 +1,10 @@ +import type { HMSPollResponsePeerInfo } from './HMSPollResponsePeerInfo'; + +export interface HMSPollLeaderboardEntry { + duration?: number; + totalResponses?: number; + correctResponses?: number; + position?: number; + score?: number; + peer?: HMSPollResponsePeerInfo; +} diff --git a/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts new file mode 100644 index 000000000..860d22b09 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/HMSPollLeaderboardSummary.ts @@ -0,0 +1,7 @@ +export interface HMSPollLeaderboardSummary { + averageScore?: number; + averageTime?: number; + respondedCorrectlyPeersCount?: number; + respondedPeersCount?: number; + totalPeersCount?: number; +} diff --git a/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts b/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts new file mode 100644 index 000000000..c4b3bd9c7 --- /dev/null +++ b/packages/react-native-hms/src/classes/polls/PollLeaderboardResponse.ts @@ -0,0 +1,8 @@ +import type { HMSPollLeaderboardEntry } from './HMSPollLeaderboardEntry'; +import type { HMSPollLeaderboardSummary } from './HMSPollLeaderboardSummary'; + +export interface PollLeaderboardResponse { + entries?: HMSPollLeaderboardEntry[]; + hasNext?: boolean; + summary?: HMSPollLeaderboardSummary; +} diff --git a/packages/react-native-hms/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx b/packages/react-native-hms/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx index 5c5abd435..5132f6139 100644 --- a/packages/react-native-hms/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx +++ b/packages/react-native-hms/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx @@ -1,4 +1,4 @@ -import React, { useImperativeHandle, useRef, useState } from 'react'; +import React, { useImperativeHandle, useRef } from 'react'; import { View, StyleSheet, UIManager, findNodeHandle } from 'react-native'; import type { StyleProp, ViewStyle } from 'react-native'; @@ -56,8 +56,6 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction< ) => { const hmsHlsPlayerRef = useRef(null); - const [aspectRatio, setAspectRatio] = useState(16 / 9); - useImperativeHandle( ref, () => ({ @@ -204,12 +202,6 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction< HMSHLSPlayerPlaybackEventTypes.ON_PLAYBACK_RESOLUTION_CHANGE_EVENT ) { setHMSHLSPlayerResolution({ ...data }); - - const aspectRatio = data.width / data.height; - - if (typeof aspectRatio === 'number' && !isNaN(aspectRatio)) { - setAspectRatio(aspectRatio); - } } else { setHMSHLSPlayerPlaybackState(data.state); } @@ -232,10 +224,7 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction< CFBundlePackageType APPL CFBundleShortVersionString - 2.3.177 + 2.3.183 CFBundleSignature ???? CFBundleVersion - 427 + 433 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/packages/react-native-room-kit/example/src/redux/reducers/appState.ts b/packages/react-native-room-kit/example/src/redux/reducers/appState.ts index 9eb527b30..2f196768f 100644 --- a/packages/react-native-room-kit/example/src/redux/reducers/appState.ts +++ b/packages/react-native-room-kit/example/src/redux/reducers/appState.ts @@ -1,8 +1,8 @@ -import { getMeetingUrl } from '../../utils/functions'; +import {getMeetingUrl} from '../../utils/functions'; import ActionTypes from '../actionTypes'; type ActionType = { - payload: { [key: string]: any }; + payload: {[key: string]: any}; type: String; }; @@ -34,13 +34,13 @@ const INITIAL_STATE: InitialStateType = { softwareDecoder: true, // Android only autoResize: false, // Android only autoSimulcast: true, - staticUserId: false, + staticUserId: true, }, }; const appReducer = ( state = INITIAL_STATE, - action: ActionType + action: ActionType, ): InitialStateType => { switch (action.type) { case ActionTypes.RESET_JOIN_CONFIG: diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index d4a478b11..ae9bdfcdd 100644 --- a/packages/react-native-room-kit/package-lock.json +++ b/packages/react-native-room-kit/package-lock.json @@ -2769,9 +2769,9 @@ } }, "node_modules/@evilmartians/lefthook": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.2.tgz", - "integrity": "sha512-i+tYp0jAjuoReqfYE3WDEs/dBdx1rOrsq6DH/u2Kf+YZTrf+MXkww0kadSew8merbNkMNt5nqVE5iFNV7q4tjA==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.3.tgz", + "integrity": "sha512-rNPolIUKmMLzttnJ4tatfWgiwPTn7crdwH+A86LI8SNXnS6/+HeZN8bC6xaUp+4t4deh4hIQWaxpZaxojUZyxw==", "cpu": [ "x64", "arm64", @@ -24073,9 +24073,9 @@ "dev": true }, "@evilmartians/lefthook": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.2.tgz", - "integrity": "sha512-i+tYp0jAjuoReqfYE3WDEs/dBdx1rOrsq6DH/u2Kf+YZTrf+MXkww0kadSew8merbNkMNt5nqVE5iFNV7q4tjA==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.6.3.tgz", + "integrity": "sha512-rNPolIUKmMLzttnJ4tatfWgiwPTn7crdwH+A86LI8SNXnS6/+HeZN8bC6xaUp+4t4deh4hIQWaxpZaxojUZyxw==", "dev": true }, "@hapi/hoek": { diff --git a/packages/react-native-room-kit/src/HMSRoomSetup.tsx b/packages/react-native-room-kit/src/HMSRoomSetup.tsx index aa7589c83..48907887a 100644 --- a/packages/react-native-room-kit/src/HMSRoomSetup.tsx +++ b/packages/react-native-room-kit/src/HMSRoomSetup.tsx @@ -412,10 +412,16 @@ export const HMSRoomSetup = () => { reduxState.hmsStates.localPeer && poll.createdBy.peerID === reduxState.hmsStates.localPeer.peerID ) { - const result = await hmsInstance.sendHLSTimedMetadata([ - { duration: 20, payload: `poll:${poll.pollId}` }, - ]); - console.log('sendHLSTimedMetadata result: ', result); + hmsInstance + .sendHLSTimedMetadata([ + { duration: 20, payload: `poll:${poll.pollId}` }, + ]) + .then((result) => { + console.log('sendHLSTimedMetadata result: ', result); + }) + .catch((error) => { + console.log('sendHLSTimedMetadata error: ', error); + }); } batch(() => { diff --git a/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector.png b/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e70fe5de0e85df7aae54b432db69b878a0b396 GIT binary patch literal 4031 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 literal 0 HcmV?d00001 diff --git a/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@2x.png b/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..19605512af8351a996eebd636ca904a42b780dd7 GIT binary patch literal 11272 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 DzEYpJ literal 0 HcmV?d00001 diff --git a/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@3x.png b/packages/react-native-room-kit/src/Icons/Clock/assets/clock-vector@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b28c93684cd6eb321c613bd0bd6689fccc54b4 GIT binary patch literal 21659 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 My85}Sb4q9e0Ej1Dv;Y7A literal 4031 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 diff --git a/packages/react-native-room-kit/src/Icons/Clock/assets/clock@2x.png b/packages/react-native-room-kit/src/Icons/Clock/assets/clock@2x.png index fc06703585e31a0f9ecc9183f2f51bf7ed1edeac..56889785f1ba5131b71611c96993aaa157608a7b 100644 GIT binary patch literal 533 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 DSt!l| diff --git a/packages/react-native-room-kit/src/Icons/Clock/assets/clock@3x.png b/packages/react-native-room-kit/src/Icons/Clock/assets/clock@3x.png index f1b28c93684cd6eb321c613bd0bd6689fccc54b4..160cc7b6f8cd41651aa301928f782b8ff9a00309 100644 GIT binary patch literal 697 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAifXMsm#F$0651qd^`PBTmZ3NjW4 zxjQkeJ16rJ$Z-wu32_C||0xDRbBhlF4H7E}@(X4VP%v-^h)>8bsBh?>Fn_`N4g1gE zf8U##Cj+$pwWo_?NX4zU)9+4dR^Vx6PKw-`B+mT)|BBt4l8yh#sJ)FVJysm9Bk#$f zcwwpceC6w{Ge57lu(SGZrn+QLAXokdpZT9UZ(Pp)C3L1fz%1|ir*F$^@6Iv#bxg#6 zcG;un8SYwN{kv|v)<*@}YKnZC&sO~Ca~D^Z-xh@$9*+a-6OAjAZ!h@tPFwuv+}?7f z!0Fwq1h>CDkvV;$?~U5HDLRQCPewKG*rn>)^hrpbXOcx}Y4Z#P50UQTWmyxhHmteP z$HUd)aQq_6tMeBXc#Kx&sGWQ1U?tFNvHzeH!;=O1e%p8&KkRBh!(VlwBk1MEnvAas z`rPxML@Z`EJ^iC+(}@?3Y)7ViQfgB8%d+J_L()N00h>m?#xK*P*aBIF6E>`z`e-rN zH=b?tHRgp~V+%dGG9)|Zb^f~{*WPRP5u&F#L+-3Rp!$;G3Yt`8;W*QdneWTG1>bmo z+opc>UZ}TLgYWIHmJi=s<_Sbh%kH0*;i-RKaz$33+*CGa{nNf(%U4XhYMZpN=lKQ8 fT_rD*zcBA#=6gegyY4$MVK8{Q`njxgN@xNAbjey0 literal 21659 zcmbSyXH*m47i|imgrbztMMNpmTR=cC=nq7&07B>xKx(8$nxQ0EP>O)kyYv!5htQ)G zl`bV9HG+T=Is(!k|Mfnpi{yjL+@X z`PgKnKfixZ4kw%&AjbIaZ2)mV@Xz@JleeA)1^~En<9`FFlcazG089|~{?j%IoLn7y zpf9M+Mc&f-Ech`am4Z+a`gHXdqmVsYTx=um$(-ZTB0UBGR=jd09l`iAM??iG$+(x! z(T=pSTSw zt~1tS@(ra;-t8CWqUV5BN{`dBt^m)9K{aPvdp$kCIT{f}dp#}1fh zJ2#3{t6n!>DO!eUI6oVaXQBW3j!YL*kdIeT1YMP9!lgNV9Iq5J06k1N8H7c%L5P<_`te}5NXw3#{X&>K=*(NFYA2!>AN{yT(-l|dPxN6E(KlvT|g!vnY0r4+Ja{ql!T+6Olxd?~f!6yuaJV zmnKd|880=JKCv^Af!%X{e?#R!P$RYTid*G9!+SbbcbIQ4q9u$?-~Q+O2l8fO;X_qs z>Q>*Ahr+>J?0e5DcGug(XoR!bFYg=&)k0mo-2NN{4t`ZV{nMVcOQ_32hu1fLul^}N z7BW&!DgP1N6R)mUzt>LnsagAx(p{Gc*YZP~W* zn?%*8o1c%mkHp_N-ft%OygW8&UdSjbS>~g{e#xAOBnPSQgJdFU7Rc!%cdlA{QNy|~ zyh+|(-A&?gnB!lw_L4r5op66e;7Eai`truO+vQfl_FJzdZ{7Oe z9RKXwTnJw5WE78EnYJ2efz$MH^%6CsX6;PV(_qWBye6O*P5`@bbNue@w^iEu(&k39 zzKJh6zNp)CeN`A&yU}gVya~9G18b@F`Y>}=z&Xf3milV-&tr6dUnq;bILQdn^*L!9 z=Y*5?bv#CH&?rHt+<=HK^<^_mNQ!>+{Od-6@*LBE53t(dPy~OZ;7~VXZFMix--cHp z=J`s1>bM%4+S%_!o04q|Fc1>N+_^c8|+| zfXPecInsOQVz~I?|GsNj^e!#{JY36wPu`JrtWyOm8a~?p9Bz(~0!snAIBfAzD@i`m z%6f0Uu#0N31n>v?&5Bw$f>IGMcDGC{WSLHNCDUr zye5o0cg$4*=IssPz%ExnGpqhIqanIejUeiFjo>GPf>a1VTQ2;X0I$d|UA}O&NKH3& zuhKlP@Mx)DGwDxDI_7CONm3#1;j(SB3iKk4_jNi8iAYK=3_8`C=AgcFT%9vsmCMJj z{m&)7^Sl-KUK9C7i7MnhI5jNNA^Ss^xK|P`SuR9K<=Lu@5JR zbHBALA!k^W=_~~JqK-P7y?i#!xGgYlJ3X}-vJA#H=zMHz9E|2w`O0BJg`26J+G0LM zgC4m{b-@TAxXj1y2?KZ={3EQzc$&=@B<+pKH@wmV046n7mwm=1Ut?Vp@8qxQ-yM3= z$Utb?d4TgNaf~^1Sg>@lUfUJsh7y#jP+BrL&Urzvw?4Ii15Ep-rW9FjN$$BS1Nqzs zCy*W{!rX)`NsGG!Ez$qw7PJYVu%mqAsofYv4AUr7wv+}rAPuVB4N-__(3XsY`FR40 zKDLCzR4u$gvMyEu$>O3!DtCa|6^|kJtRaxR{3BX>@Y&Vz(DjdDwV-2%<2IUj=vjo! z5l9R2i<3}+KFvAVIFGWZ#Uq<1s_2#3lSchFQbI;WmLB1CNfX3ND>ASzmI zD`5HtB2$P;h$Rh4l-UTFx~hS}wWu*y`mea7cmqrDdPGsY-(=Bg?=3rEs6q&^lH*2_ z@ik!3<0C1(lVdBGMOq*?J7yA^x-#jEWX`awJq=}@Jxjz0!>a7VAdZ*Tar#GUMr>PIPN6F4mX{i|dKj#rSzdb$EpiMhSTQ ziSrNP0yJpYiVV?}CMcG`7xB|azOyogH40c!)R^^>{~Vg0T+&i3?VWZgM&@_oxoZ$- zhKt=6hb%qUg9=_Pi3cUkW4Tnj{k!Wh#F>4Eqfhj+FGpElB~I#Rmcs^IeLuiF_J$Gd zilvGFA$oV&muGPC(o*ihkZLoY1Jn4qwLL#LF%qB-Gac9I@}QUxwx&gFFEO?>CUax% z3s(Rxm&Zyx3ukV57N0O*=+vgP6sf@{isxF{k1i{lJ_&UQ+w2+R)|)f2aanRRMpajk z_$6IX&HR>%fISUcgNYo$i*Fodr95jy1}E>l!t)rQE@LgFqu-_%K+@QprkGA`=o(e~p#WBrDQUD&Ymnpz#MS zMfYY_OfToQe7IdB7ii?Lq#E|`I_}*8qnA12c;@m!u=TBSz~yxY@Vs?)Xo_z3p_M3M-D!?S!AclTGQ; zRi8}S3~_F!{yYOAzpmPs_D$!UmJ+CgOvE(OZko7CkrZ>v5jjT$!qrU2Ad@ztY(F*%ZD%0h#&5Sm=DO79~q~Rmg)T zS$~l=QdXKiwydiksU^eLmCSS+Qd=u=CTC)Zr%e3CoB0F9 zvbtRS5Kl=K^1)O=2G~2=G6GnYb1GF7cJwoIxB1krMdi(W&jSkot_<1IN)Q1tgp}$H z116u_JR#E)5ce}#ewfofP_TlL$7MvpehCE^l18GUzXVQyx5v(_+XazGV|zehE?7m$Sj}@ z(FZrao@+wjL#OTp=4h8UZr3~ahUCdJwrQibC~fvLPj zL6fy@2Y(AL&swzeoJM^qyNlZ|1&tqs?v7<#V-*fXcBh(c8uPoRnuI4dQq;s&>4?SB zx8JJKkU8Rk@cQ{+la#_|yt2xPI-yQaUNJF9%Hzu_iA{~SK9y=pnV|lARTd?kgXc#@ zxEs&T3#oQJaK*4z8l!4j(;wNGUk=26Y-b;yF`?Wzdr!b?lnc6;ByE#l;OjsT-z+1O z$ZennLlLSSp5B{&RhTOg{VSSc`rdlEi)?B%g`AoisQ)9< z0RI!GcGi~Nq<(y4cLKKI`=ME}v`CO5HL6S^+<{Uxbmmn37&*2{GRB zGc4o9qmu$?nQGxeQ!%8V){YWBS`lqHwJ_pTi1SIsCw`Az;kC6^d_TA6}4o<0OxP=fignnr*MkoF^}5G}&5~ zl(IvIs-zW5H(@dJ<;y}>M|#$=Ykf2`o&0<1m4})M+};)u*bL0|3ckwR&qp<-=f~Ki zuzP?A;I>0r{y>8izIg4|AJDJ2j+KWB zwX4SVuW^_gq+YvZjAjS|J0WBXV(LuUQ-k~yyNxrv*1W$~S4Vu2nDi<&fUwIiPY$-G z;tM#)$dn7UE%}IuZ(!ovr*@UdxJJ&xoAOIc(koNz0T{UfGJWNXn`LBNX{)bJXU5kW zfNn^XO&l#+r0CwOA7Ll0Jl$LKcmB8EfSb1BOx817{FU5(OSYk63AGFc_W zhdGwYldj-_);@8>_3lSCIj~5BkPQLVi*kvKY5na^2}98PQZTLzO7ug_E!z8|=x>@T zJcp?WZn8Bi`}8(;_PF_3>XBNYu_+Z+SzMlu(<<=m8*F!SIcaNaan;E)u)m#RlJdO= zSi#?EP)Zx($e%xs+I~NNGmX;kp~6Yh@tZNF%*X;Bx5OPC**L9W)i&zI4J&<#b?mz_ zRetZEChAIfp(7lPoF7wNm=q=N&nhk3q-I8dkwBL7XpHlqK6F`p456CLTW=6OcgMF{ z-J*4mlqBrV!|>~7!gu>jNUG*_;&uka2b0`!-w(drH)Z>EpJzv^#WVzXp!nS-)g-C) zBLS@6IJ6fU-<`G){jr-IRYqX<{)T>MG=9gf45abZj-3n|T@PE-VjxxVI08+PGtShE zJ-b`|jx2%ju#*y>n|`6SCiA%9800M%SbYO_CMJv7()8-&IbvN0U@uFJQmn|s4XMb= zNd{Mo&sL^4SWyu9tMSg-o}zfab)e)Dh;-ZP1=66E0BA^Hw){+=sB8MFoec*(Fyr{8 zeUD$lH@u0@32>iUniXPk!IIfLU7So7qyY}o$6a?ZhCj3aZFhtxNQnq1r9TBUyyNdT z^}M8vGw<5}NN(EMUFRo2T>Bs^$9_ftnXYnKWqELIwqH6e!}*9b$cDkW&0GUo_DGQ+ z-n>0%c#8^jUXAHnPPC11wVw&N?-KXs&&QJ_GqN9m#NU-9hS>8q!cW2oe8(5(~D>{?x~J+wyL1 zr-6{fcXVabPCa0O%DTM#=*d~8CogU+w*rr-Kmt_yo&eJ3iR|Buw{Ed&MdWVk6EL4tv+lR?z&_qzt298J^r$Qvo@uC))}16}$qIZ*24uk=?$4_i_t z``iONev2J|K&z1%mB>J&@&1W%(cuh$*JwRMg*@IGB?O`Z)G2DA)F|{0&L!_NZUu?P zI_+G4&sIMDJ1Iw7II51Te(|Oq`;f8S^BZPy{Sr(WYmSMI=-WJnaOnM@9BnE2A5tsm z4W5!=2|}w2S3A(BOy0fgANQ+Jy!J!Uhdh=;S{^p9s_1xkO_kL@DL3%F0rE1x8NW|- z>5276&G^Xz%ZT0n^u$YWX>RKr51ho`o_O$*?ded)}~>-6_yV|$bOekZ6gJNdKDJ0s6$=NMJB zv7fVY=VFC>@TO{bBihKNoO3#3zecVH&4=U#fJ>Ibd6Rz(w6Q&VH6AnY-v2>@t{=O5 zlp?sy3ahPsG&uS)b4N}L#oXCi$U`!?a(V@jaaP`b^ucWS!IGeKN)^AyJ3lZI5aEI9 zSJ>x3y`TVv){e(aW0p<+EtnbFM-$52em$394ZO<;@%uB^m*Md8`Gd~i`)!EKp&s`u zT5CRZvL*4pseJf4MAUXjxQWLCZ$nLrxXk_&%!=H}p-$o1oEd5px zSO|i% zU!eEfk_M+G-x*p*H$>KYB5ho;*Dr%tLtLzLy7c1dP%But;5Wd2H5O55SPm zyZqB$>_N3|I+Mc#a(5OEMy8iue|Ed|#~k3e=|aY3vABJIir1M12@nY#q$iLTx?1?K zYfg0u%YA4lKx5~cJ|X!EH+lNtxi5WWSv-c=(K{&>g+uCF@2^DRkr}wD)uE-fCH_A` zK`F9-i-dP7Et2!w>4*-M3oAlE!)w^r=EB3n|g9V)mBtRkBKXwVf$0Mk*SCst&Sre%;-`Mua9PPMw{Ce$GIS!B zP{7noxwPULcJ_GO0>8r|jWe3~Zu$;RrT=RD1eg&S^=BXeyrbA@Yzr)_oBr+Gq1t-( z4IU-cW_7DAzzWS|P)(1HDV8n3wO-NitjWpr$-Xr2f124Y2?d+Sa9zJPu`0E_>S6<& z+DRYzXH_A6JE(Dg7gH&UrW*|pyyEsE3mKh(zW_v469FbW#-tpL>FE#YEQIMDm99(5 z(CKL_oa&wtYH9Ac4PK;f@(&-X(`jAFZPuidu{Pa1&7s1ZY%*cjZ+5AI!aS}c;WdEA z7|(}XT+pwH-Og>wc!BMPL_OJ&Ty%=~e+ZlT z6#BrvB?~vN@_4TFxYchg4mt?8+1El6IBlQbxO~W$lKYay)-7Z<`o9>rOvlG4-6c@6 zpKi{Klh$Pn-$n7S{DX5Dd%}=D9*Zjj^}8rw;$Ky zXw$j<*PhBFRV{X2e1Kbr7+E7=eQ6A}_P#}&Q~@=zAMFI&0G(#B_UV3LXeuJHm}q3r zwGhm6FQ?l^tfS}ojh)SUKEoZZ$O7GYEoMvf?Yn9@2}s>rWl56PPJuEXjyTw%k4{VER9}yj`V9TTivXd3*Z}j;9Vu& z!SRdNOE39(wEo-`Z%1j$PO8(3rSMu?@o!GuzZ5wMD~sWZC6$uV4r|U8zp$MC=NLPt zu~Y<6h`3^(I1lpa_4AC4z4!Lyo$7dhrZdr#??CMP$4vZ~#rst$9K<@2{`sc6o;Rdw zS<@gW9q1iC@dC+;?1zUg9O+`uKHMQVo;K}k`YbFyj+H##bk(fjyBaba$+WVW_qf0F(Y%IUwtkVqLZ~$vU6Jff%p!N`x>_*wspc5Sn5o~d1Sz@2 z;reYV;Kd#C)XvowgV&}hlybd~V%|ATq>*qRI*sLtW6o?+KOy4O7v!m|vY`GbPs+!< zRn~#XT}jS3k6P`@f*>*oCRGp~sVp!A;#wSY4I1F~co)AboC0x(t}1E-YXC1vuBr$& zFVjDdmdPFVjVW*Xs`0co>Bf;A<6k2GFQo>N6a3$=pkk@YzOv}ABo1;EbXAj3%RoqA zbZ4zCmX$Q1M!u<`(m(wlr$~iPct+%rlPkX4g9E{RbSYf-KxVwcJe>Jyj>QV>%R+7g zWw}d=5lv#1tKeGl1M0}^QD>dwMk_vdbZ%>_)$YUgxle=;%$1scH1Z^;`o$uSXiTh@ z!n^Zys?_p7@zE*eYWqz=<#OXXg-vdUnGMe!Wyezo;_V~y$zkGLyoN?UL2KPf#K`d zqesl|H_~||gA3@L=WWe>pw#a%cN?s}=rw$@>Uhqn&ZWwVmayKwz$0%ds1 zY7=flxRRPtKr87SzW_Di#pe<+2Oq32Gns>VySnJmk5QEL18jTX?&~+kv1WH0@>((i zFrArMVcyZxOX_me!^aX?#Z?wG)lV|KyQ-ESia)C5B_#hBV{7`~hBJ1h2G{$h4q!T1 zuh?*)am)W;a_ejlJHCDxbE|1@r+uerJoIGMOzOYJ(>|}0Z*|S5%a?7B#@qiLjbEm2 z3Gw>%TiS`b1Kd-%ehjpedcy0Az2BL>!jFjzG}=*s5=mHkH;F3B1U5=BLgUh2n|S@L z`W{P^v#x#`3|&#h20vXt#}2H@v<)7=f&!F%rL+`E%pCHS>yLqb z)w8!uhW2NhO6Nd$>FktgNKoMp-r)Uf6Qo$2n;y?q9j2_}pNn`zuPOTu-D7|hG?VCS zt~LdFdb=M!%qRf>ulLQiYD}HRP_y`CKqg5$EhuHX@!;?YVyu{HzhAWez?<*0GM^vR zGkh^ezngq7`6KQ7H+WXqq0$nd*ZTTuY)erT6q^ux_?8Qf$kUl2qW$Wu+fSdd-b1zjBRhJLam%h}WSl`TyXq2s%E_*pV zK=!cxXc{D}UB=&;HbBM+sMtXza2PgHqnQ0d&uQVRtwrbTZF1>n>#`{G1r@7{QZq{i zcP)cvUeWgnsvY$_*yGSHS|fs+t@W`e>a>>A@b zNxTy78L&qw-?wXP-K);M0n91;>~7NeV*~33p{-X_KDZ5zC96>>v@4Gtn2|sUG=~y> z3|TS``x-`bSA9H={WZpeD?;aUWDHxQ4Je2Zsjo6RiWE{$npBD?s@K9?Mei*{v9v5G zAO=49Lvv}>li#`7jqq3em* z2QSr@XW1w~O4j5j$sjN)sD=^jfMzy`@tVjP-};hcN|*OensfvR#R(&0v_>8biwuAR zTC8Di3HHTCJT9b##NyM`!P=?NMY7VGJ2QqIl0M9_|!>dW-( zJL?vgYY*i5_vyX<4=~bFyw=~T6CU5^o8=QPRh;2hvIUt3@Z{k4-m=MSOMRN2c5Yyr z-M^_d$+@-RFgm+Fpc2YHs_$yLz)Z>rp=IR2dYDNm*?3OmWBcg(8|6KEPWUBtuvEOW zZwCBs2#?4>ICt+b`6Q$qa03-;l!=G=(9izBc$z=9N9{R3YwdZ17AafnZzM+QO#;j# zZfGZJL^t2>407~MhR8W0q?lE)preUzGAy1thGpWOjFa-%3Nu6h#a(0VPd!c7E3BG@ z6z{w`*-~J(wulcGb>Z#w-%rOlnYn4U(FZ>HRHr0=j>ac)S__njdl0EErt(rorSTtJ zs>1csQr3$m)(N~kL6&IQMEH24MAcHo+o0QR*mEu}#Ot_o_JZV>AC?`m&KAH5il+8e zkf~oQV2!NDEC_6xe(;|A21s=YC-}O|dUBp6BM8mvwSIxsb+jS6A!K_y9x@Jm$TOKf z$_?f<{xfd|~UWHCl2bx5{17()& zmPoz)a0YklKkUB)5l3Ik>G@jn?>?$LdX2wMq;)ZPJrxNYPJEsJ48pUQ#msr?4&j z#uA8UKb1xLlhg=5uB@z2YkBrdhj9q!WQu_Y=cICpoU9+>5@7jwxzcDxU(@HLH66cqaumnvY(Qc9>mogO z7Sz6-fZIEu*XNt>?(W(C!z`cn4YW#lNtv5RBl6m!zVTlMOep(i07(Ly)$fAj45@u( zb(xsA@?WwN%-0onKpU&UF6nK*OJGAiPM!~bI0{u-NSSvtS?|3r03-oCX!6&kSE70f ztKPAD?hiNh8uJ5b2WlwmvUueSYy!?jB9Kbzi^iA5rZ;B%U%^`f(1yR9r}TdtNy z_5-yF?{k2aq;C|CdNJo(9?lhkHqX*!i1R=jUkv@j>pteU&OG;i-9A4ZnDZyi$dZT{ zg{Q{W!fh9hif+{eJOQ#DeYu5!+qgl>Ck>#Hl4TXJ9x0rkDcw+`Kg?6cr_a#p6S{Fg z0aUw}-&E`imRwD}s6mUx+u2DBGF#Vx-2Z&nS$>DILGy$h(T=4u!?K4Wmk%5A) zjXCeZ^*s}%7_}a+_<2hAGq*YkZO1a2jqK2Jf3CIaxfn}z!1W0MrBI3R-AgMIA_Foj zEaZ~zG{<9=cel2s?9{3O5hqi2haotd>iyp01)CMOf_LxX52|N&`TH~{r6mdo0I3wb zDq-m+*oVnP27I%UNZfG+$^w=HS2eBvG9JiWZuGSt*JW}6t!7?RIC(9?Nvb|}j?((j zdox??n^%2dbunF4KB2m>o>^O}L|)bp%p*!+{_jeKOxF7Xi1F@5a;WE&{$ZF_hBzWyC%jGH-Nle#L`;J;+TfxA{z1r; zHF9pnub`_%*&CE0EfsENnXE{5Ca-Mv(D^)`4#9{F0McpR=^ehAv2PZG1!LPZPUM6p z7d#uTS8JEC=P7SebAuC*c&UC?lt{nzrH_>oijh<6fe_+TSE7<9h6p?u8%e>$*awJ@ zF8up-VdH7<{@Uf%U~#v2uAc&5|4XZ5NbtB&MguFARgN&gBv7Uvy?36_RSZvOW`&!B z0%}|?+9fC!fed2KzJ;A`dz%2+u)Sf2?;8h!%C8P_WsNXN>43QWu=4|u5Jg{X9v%tw zD}@83s-LcCJ}5Nc&MC6ug!bltxWN-?ZX* z^ZC7v4zb4CwLsr;$It6T{X%8d0o^>EdCY{BlE28Xj9~%#DqbK5x|C9Ms1kM3e)`tn zE;qHZ{p6cLxY@xVY2a^twaN`{r>uwx%ej{xl#wie9UUL)UUqG?R3^sJE=P9abVuH0 z7GREwfV7Y^7Mce=2Ct%-d@zX+C3a`(fA)BO(znu;L>>E9VlwTcZGPoh-SGs?WmaBf zkkkhnXGvjQQQNnmE~N_kLKhIPyUpB+zmg#SD36?bJ|?#$N}%P@_(U}ArrSft~= zuGaqm?=%gTv$<3dulQ$(Ld&BkqGZ+;p#+RP*7*0M;Jw(`Yn|Eu`fsUMvdG714m7So zza5#60g#q643qCeU{p(=a8qtk0_XryH}<0*bnH&;4*~e+C>8su6901FJ}$teDC=R1 z^w0qA;)!4lK^hS_1hDkYw90R+U>G|=F3tpumj(Hy1Np{mjDITQ#;`3P$!TZ3*_vse z$}b;Qm;qCW{NSa={%8;{DtWNY*vvQMNH9=g+V#CM&I0|Sk*=I8hl8ZBw82zjy;N(? z&;n9jWA@W(8fl&aZ!y~F7QI#H^iaVW&3-eq=1O7zFge-WitM1_rAz{pwyk1ss-Bk( z($rEokrw#C6tKku%G}@hqIcG(e^c+C{+$d6{(a1-&~wiB+SgSxDg~A`v$Qaa?IsR` z2+_Zlx*K^KQc;QLk@C7nU!9rtQcO>73sdQRT#Z(;cl*kh0gp%Hy(9;bKpk>v27Xt- zeQKbU^sS{(xRPg1VOuroGhmW=yWicr$Hw`Bvzsl@uh|uAWRks8@_oAfXfe;v?)cN$ zZiImh%E%EVW(3YLvH@y-`g5`2cCg4`shDq^+Oj**PdCf)X}pVeNh?kPHDH9`Y|)o5 zsE&3zGY$B1%=`fwTY9`c=;K_Y+bPrbJWxOX%JAua~k2TY-?Vfrga5JMqm^PrV~NE_Zs}Y~6ox zWHtXwFTuj>zlGDMNv2UZ7$!g}-OBy_uO99cW3sUKC_@1bkJIfA_0bIJL&F?j-m4f|Y2PQ8in%i`iE}RT8re=Sr;QNUnP08x z93Y~BG8RZ~vV+`xdFK25d<;~bOglIzqx6_4)025xf8iW1?fdLSe98Yj5nK-w^ER@l z@XBH!NJoTZSKYIFkOJKu4OC5QV4lIx)4_K$_T-Z-aC_N=D*tvPE*bX!H*FUGA z#ZSh&4C+|5=Mdb!vy1-7Iy%WyDSA#osdT|A!?^PtL4Zbxq$$9X*% zFVFqj>@m?eUK-N^ykz8(P#=E(tuVkKGwKkE%*4v9^zreMAAS7Hw9E*nf~qXrwjH!G zm2ySdmKSINY^Sr?qKytYjR$b=zK{S zf6D)c!s7?O;xso*c&@sHOe_kYO71&07mt+IoA)}Jd7qxEmU#!G!&V@qM< zr#u*5337|-AOWPI_rHfX_Rybmpw$&1W4x916Yc&()D&^==2i@9eeW7;H-`oBl5*Ng z_1(>$zDTZ=@%ISrUOj)!$gZSG-_uH5@$Z zbdJ3p42H$Q9sKMrG8KUDcRBh^dv!7{UbzxuL2v=h;@VqzH#cWg4(7I{;|55b6ziW<&)fFk&X+ zRMz&D&Jrom5}l$ zi^0u?8Fs9$C5uiEC!h3sIm^1DH=%LN#a)2pIjPQy=o&9mYI9b-(*N>w_oJLe^}H5b z6tv-)9+aEo=^$yPuJyymHaem*0}9_;$BwnRXG@V|FzEtSE>Pfc#39C)21r8Cg0uzEhi8FrO3F{(*^yQXDAZpm}(Nm9EIhq?czp{Skv`yX*H&Q2V2p8)`!AsJN~Rh zse+BnpL$wZO29YMmjP0O0zL+@w}(&t)bWub&8mT2f8<@v9!6koDhuyDx2*~Iz?CzJ zK{25osB{XEhX;eMm>R=$3R|3I$|N~dS&-9DxcJN!2CF|i`J1H)kL44?Rrl8;=O8kO zN5Woaxe;wvkJc`sgZlmVO!ut?2zFBcNUI9ahK8n=+otm$xHR???`kF{w|{`V~tun z_v~+nulztp+Y@U+$W&xTfD=72w-2zYHaJ;5P-;%4;ffIW!*1GsGu#4>SC7}kPJJQVczew@P-JL!xqcx8?v$2d7|NYJQBZ~ zik-|`HI`>y%TqJR9#~$>r%hwktxp0QCqffe|KS z@SfJ{Zq-tNHu@D)VN+G?)Vc81up}#|jAEF^JFn6c@7%Y@A^SD_7`dvNGp~yswa`rO zz^Qzy{l&^se8OVwQ9OPJ_T;>xOevu4zqHh3jX6O`Emx2>-X|5Thx1%lbeXq))ZUIZ z`5DkP%dK0u+xqiwmqzmuAyQkmnaaI@x^BKc|XL^#L{wET{YYm#guN zmcxry8|5%RWvV2mux&podB>mRvG_?+q}P8VY6Uv| zPr&*Kl*0?RmfKnF!Tef`=ZPd+j<3(v zbd0gUQkFN5O09x5sb<{N9<44pv0luNe67{ z9ZlphwSP{nkCh^C!V?H_*VsRNG38k-k4rO>WlTZ#_UcvBvo9Y2#yH7kbJvY4!-H8+ z5V+`zbFK_rkUNwXF@}-bbnwmIZ8kB-8c)8t8F9}KulnU*$kDJ2>-+^9bx3E*-Y*Vj zPgLU6)9de<%TaPrl#+HC3MQ5Ugp*Bu!V&91gAxj!itEqF8pP$xmllqjN9mJh2f*%D z*>~*A)z+(YQ|AsSJt8sY5Ki;e62$APy$TQYq2B zn=W2VRvTFO`wi(1r#=0vfd6fF^E72=TqmGzhbS_H6KKyPl7=!~a9Rq-Hm()|f~E#L zcCBxgu4j=SEc_T0?8xtt@B~^4%OUyfNdqz!d@xE|xLHYkx!^@n*>m2?ST|*f)H5kZ zQw9=Fm^z=g3t*^;%&eq*UE?^r!Ir*VE1HO#sg4^fwUNlrf36Kn67NJwWs>Vdkr@$2 zKVPP#&2oFJkL%Vc%SZct)&Tay*yRm;)>@heU#HJD8d1$a-V=M-5xX(CEcX1mviw`v z;Vg~sf+!DV*j|&ZNbjmqFv2AUX+u{DRQ@ETu?)gs_eMnecVc4-m|PDn53ss8G`5g5 zM;f(xAuS~`6rM!ncT3mLtxQ38+HhC?t*++y1fi9C1JtNbJoZ~igPu!@Qu73OyJ#_Q z<-9s(eX#++Ctx4?^k}f-ux+;^dA;}>|LHIB6$4K7m~%?^@KVKYL)wExWiz#$r$GZ5 zXnYcOF86csc@pZ@ZrSUh8^e0ui$h-Po1*SUG`MMr(_(%DNJ&ieq*nIK9M(9;^~gR< zHuFLMoq=+zYr6KJ69Rzus`sL^+CX^YWXt^Fj{xJjO2auiGj43an&;r-!ok0n1Z>1FWK8F1@W5a@AaZ^(vjS4oXUaWc zioaws$^&!G#90p0pLec^i5x)}m=Y|DhepREc?f0nUC>z_W0jY{itI3-bQr-E%{xts=c3HXmCE>f7tADG?O%0rVy{#z zyyx~U!1=+GA0Jevy|X*gj&6P~YZd5C>@JwqMAAau%I-Tq3w62{*y|V1P!arY{<%zr z$qiw+D7`DQr5dU9kB1i*6NU93@_|Vo8Y}RX>pCw9XSuXirNE(jvo{ibRTKaDfFd#k z4rosgu>kYnE=@n@UWd0<=YEycD&B1)4IP$~`VjivrW0{T3Ly7r2|0FGe3WU9mx-C> z9OHWG_m+sA_d#jb&bjp17azN$09Hhd(IjXKwLJAkB?6uZ`PF2H4oV%r4OweIUoFs; zZTe=9aj}uouSAP%{EVK2nwyMgpN<~Xm&hNPddM{EW0P#^F4_$Eeu^peebss1h5@a? z)oILzd=mhccY~xTlnq7=tfNkWi;a7)pFb+-**OfH>YI@}%Gb^PthSFxJY{=h)%hca z%7p^UFHbwL8dF7ARx5rf-703sUN9ePM8W!CuJ~r_!QLHlrkd*>pYOj#fu=wvH?`== zn#(_$^$y3rGuncz2@*tWSA>jq>3OH-?WoBnR@0zGEwoUQa62YS=pj~CcK5f?2GgYN z4s(XF-SiUg+HA6tT;ko?y+kFia1H#-cG?3x*xEv_r{c&qhq~D|=l*;qac@))WSms| ziH6^8nQFc(Hng)TdkgVeqrWCwLUuC=^h$noe3@%Wbxd@e&wPLEpfKKJ3}ki^UFP@A zCuu9d9)XsO26`56NX;q`F*lnVFnM8lX<50hpOnfuCchI{rI#N39{x&Fyc47l$;F}9 zEFvi>Et+LO5uSp^VL2Eo-$7YA0W?``Da zoe5s~yoM+f2~Oa~8I8;LdKETzBX{}g_@c_pTfM?^3F;K5ZF+eogosp-Vz zm#j++x|tA9)1S8ahKWgPVsSuZw;Cytevjd+Ja&C#<+)XDD!Y@ehrwU9kM|8n^oHNS z^O705Ppgll%a&2r%g&@e&Xyz7f8DIEjr?{u^3YcxMGmawkEQ=*8(H6P8~}Rqj_U|W z7|k~AA#ZSd46yIqtv8xg2gzOV!WP1I+ZYfAx`{n>bq}w8vAEj9oPkV1CFOv;9t?Xo zsQp~cW69w(k9PK>E9wKN&p0E9?gCh2%M$7D&M!#C6?ap73N&2{Fq=6Cy?1v*_^AQ2 zWMKJe2&PnFQ~xd4dSjt45OrCq;*Y2wN7oqNgpG6K80jm*Dw0D!f%}dhq?CeGWSr@qe_G7A|#($gObMwQ9y>tPctUiU_CyW2)` z))Fg30aYD>?Q+e%DYs74&X5~bygdAsHOY+wOX>my|5J~ZsChPlg`2eT|Jc^IQ&syX z$<_1|$`!PjI%-Ca2UTS^MvX>iOQt6)0tFmTPq#mCeigqw)y6Q==9zr>f@ecmq2uS` zTTaRoEBk9tp8^UIVUACbjfWtGWhz^liTO}rkWm|X4TH%pzx41$vQkAhmKFs~0ctYZ zPCJS8U81y!dyhSn-D^}IwrD7m#nQ{%6R@>^*|?h<4Coet7-OKym1MS}Tbi`vmQ?{;J{lt&FA1$H$&i(ut% z{KZv%LuArI9r1nCvNdHS`1b|R5w-VCc2o~hoYT{a#k@|LUZ^=MHReV!@I zzKVV#B%qnTuCZ?`K*BR1m6kQovG8wV;7}$j=F#Rqf8I!gA*icWn-Ur7JRV20ADtT<5beYe&KOsv*|ZbTE* zy;)MxY|>;RM$pAZKr~<3etEW`?E5M#@6A;(53IaG?A7D{?M%`ltO#!3mBQ`zQB$sse! zGC5S=eg22<<8l9b{dPaD>%Ono>-n+^9)wWMJI=WM`dV%p7WIMTGAG+nV?VBuXAANU z7-%22F9iR$@GL|Co?GTfyYPY!6)~f)vd47YBf@hOw&b(wqyQb1Z37@(< z=-6IuCPz_WL#KZfOo(O!zSO&RY4JI7&ZEw5>`HAqEW-0z;LZFCp+ixFnd@FBdL7qo z>stS5#C}f&hG;~d*G$)9W<`~DolgqX^&WgXc;G9){Yn!4a4-(M#BX8XBPWz?H3*gu zjt1M!OY7x5V5vGbx1nI3d9p)J0X0VJ{I#GX?}f~iF>zU0dQ@Sc4U|7CkAlvb^<7jLtSi{{`#gFpiaPq43{(9&GcxZ!1=gQYH>7E+N z+tR2xp-U|ROnJK;^j?yxDlQat0#ln3Ly6+(i%Cp?%w{A$7rzu8ehu=W=|dnB>kWE$4u<-3zu?q6u$%qVUSKMFBWXGT5oi z*y4dy_OgHE0R;4yd7@ei%4@`2I(Gc?JXH(1vmqOZD=KEx>etdL%c9rHQY3 z9q3R-yKe$1_TS|jQ-%P}(E+(7lod%3mpJj+v4Z?ndQj*@oGkyb?Ob~C4b+4m_Jpog z5Ryg`uXAhTi9~2NsM4xZ8DtlcU&Dudfpq=b!9uQL0l(~h(xL2adjUi2ruTP}WD-6#icxBx9jkIE1IiOgeH*4lc} z+x`*3>{`uqw!+nVMUU4t?SZl_iODsaR1Lo9ylvtB5xkTK$kn z^c|LS+W?PRY@)ZgV!@HTFKb;WweZI_M-^78g%P>ZH1@<82kZ3qJ8y`Q_NKFfhvLsA zA2Ao>q>9dhuiJ~D25AHxCwHVz&^7pzE^t}bh($y1>z-cRn~SmW?-cYW;f zLeV|vsgPcoB;suq;@klza#M@=1R8#5^;Xxtw9Sk|XmIVWM6O4%1Z<ubV|@r(r_FNaVM}D&M`{ynVtreAIWs*K_zYdqY%E4lVMp+)0D)r7|MvUF-JQw+QWmSp!C1H9J zeG)_9ORIJD(cwmn+9JoNa#SqAFQt%d{F1~E%kn#hIiuh7pYtAsA`Vo?R_R&Cp6a{O zXiE=v4!4F(A84wUUOK~&EWm8;8EA)jy75a0HZqz_IB_AFBUN_Y%eWxLom=o9=+W%L zL2iCY;`JS0(=%CX(dFKb6Yk29g*wp2*B4L8Yu!Q^rv2KX%a1CX1q#q*g<7YE&<BKqcP*-35`IMl^qhaRncIK9=|J6LE3!hk}uDxpb{h0-#P(6eR zuGz&i(iw-;mW#RjG3a@zKZli-pJuDB6^?`I$;li3NuKW0LNk37n_L2W=9f1Ar#`pk zT>LAxN+oFepTHnTN8Lr_WRRFbz*S^CO&0~XR)-sKSkaKtm`)3&JX=`P;|R(bRDWR9 zifXqMZaRmaNRi z)EfY^^6blFI9jA_L@h%8MTh<-ezB-*INnQQ0C9AQhs=kg5*X=7=&0T`nI44L0p*WM zl}h>y>dU9cPTeeO?*6yN9<3b#){)#(zyOqYr<(p<<#Ek_Id}YU*ae_`5ln?9c^_Um z<?lRM4q1LaZTb8gYE--dl8TRbMd0{4i?z zT*PK2sde~bQA%D?;k?P>=#E#&J4f4Smx)QtIjuY1`||l=DV~zMmvD(|1KaSmM>}&a zIY*8MgPVdR=0Wd%Q){BJc?l(k?w9?ni;ky*PpEQ})OZPgAltdth4bF25c<6>hD0i5 zg<}P)B;t%2GZ_7j?mK-V6%^O&18q2OfwSKeLp|&6h!>8L+zl6~a52&FceDr=7knh8 z?#D3i!#Fet7#fPCnE@YLT1Eka>e3IM?7O*YLzL7V!D8DQ)M#m}{A*uO#g#9#n_;^aJH@6|cv5?>{ZGBl1vrY;ON1Ic)`XR|DE~_f6^$9(Z!#GO z@sfkpMTR@&@5BjgLR$yn8qSsWS?hhyh-;tS+}%8a>R+~{y6oWNc#664P@|D{_&FVx zO&rivaJtfCf}}Fg(s%HI5{R>UYvPcCVnjuYL2GZDZN}EkRY%6mRs2-KSnuErg_LZ! zgnewjNg3%?ia!3+>OmL>t=UKZUp*hGCMP0Cc071U8&D7 zHmRXVh2;3Xey0h{GFOB#b^7p-N)`HPGn;>m1%`DC(*9L-H$cCJWoM`4XUlgFC#=nV z&>6pBD_m{iRfBnb;;ea7HwBULgCa1Jm%-Abi1K$L6)9|}2pHme4PM9wMY+yBTlA^P z57shX>g}TN5JNpNVdke_4QP<%)@^@IdBq#ll<6$q7i-ug|{B}5Brv5J(-gC zQ6P&8aC}vm<91mnoQ$dsFx$rsi1gRe&?Itl?}Tl^48;W}W zG&jjg{mpUD{G3@g0M!k847o)k-?Ir-Kqm~kKzg7qz}y66U6$ES+xU2S08^_cMg=k& zwW)RMnkV^L+=ya2;oS2(H^OdS_XgI137X8-%_q%g+nQnOv`d|UxVr*P%^SlD9gv0B zZPuCN{?j%WaFkS0MpL!Twu}%Y%U;xzT-O$({t#XUkW{er3l!PO^(PSH_ z9%wp~^hHuTw&;4651($LewRSWH+U2IN;aW=hTOeEN4wiSo12syb&CPzyWk8=u=8L< zA#hJU5WOlj9@(MT6^$U~P*(Q$5I4Mp>@&8E6)qS-;j*M0o5m0>_5YkB^5pB8fzylj znpxwn?H1mT_rAjkZMvkp&q!ej%{{rzcBSTg`xKr_BP1$KuGzfo%=gLSa>4NkbCFI< z%_qqy@U7yGOT&jgp9vt-$fYEO6HQfshE1O_^gnl2WqMs^W}O)<;z_BM@+Rj82v73e)hf@KiOd7w?HS+@#${_ zHae~Wa%#2l(FQ_6p$#fK{3(M^R1XthM&Pg3_vPMdl^gPv(Jm7>XqCN>uR=!Wjd{EJ z_xC?{iU?4VUCO6ztQ;0jk-5Z3r{w-e&nMnTQ&4BI54S&lu;>1CJJ0-P$ z*{56`9T93IRyQl3J09zSQO1)(08A^rYgE-{PrBr+Xbx8`9GD48C@fRf+*8kVnf3$S zitT^fcJ6;S@z=Ss3bTJ5W@8kTw9s5S`ewy^M>EQ^3gMn$?entV8jt(pM1r92=f9H{ z>`KV(F>O7tXzD?8K4R)cf7vKOh8~K`d8-x!3Bn&8KB1BnZ27ltW&pEl6}u?TWdSIf zdf0?6QzoL<_in)<6w-vX5vO#D)ZS;@>`By!5QLWbZ`7GGKdS3o776Ah$Fg@%aR?yB z3=5fuV{PTfRj;w~X}lbZSa$gDYRyO1t6}u_fzMbYm-_c3n%_WM+8ACUjnNOU|G6=( zuOu3tY1O`S135UgNuf!M!b0AqfAR7=UwooqP!wBZ_OXbb_i~WCF}$slL~Kjg9FQHN zZLgf5JwJitZQMPx_o<`$%=zV)rV|>3a+qrMRJ5g1A#Eyi`H)BhDAM`QnfXOY_+L<;qQnc3p7)LR- za4D)lUgOXWe0X6(Xt?7*!C8L1Zw*S@Nl!g&d7N#zon=9*UfZ@j0Zraq{SncS!bfg; z+T*#9Dmjxk-8SrwDxTI!*P*q3#~54%WqYbR^FRrpqBKv7*Qi(t3CA{oL%l5ceNCk( zq)mzMI(r7r5aXNV%wU#g))=us*88)21Aq$}go@8W5Hdbu)scLh^F(@47BAX8F!;+0>>ayD5HQLspGb*gE0? zwVD1yHuC$B6!UmWsU z4i>PBh?}m$PR0Wmj%!I;J8<^&19Nw#vM(p;-^MYO>)S!)?*KZ^T9d{8zwOqU?Y4N% znnt1q-y-(WBl;@E3g+s|)s$$#(g=GdRUUuDCkZ`r@#?Q4hj%5MMWP2PRuy5A4w0N1 z@@o9qPK)Z*-VJ7ZvfZ}wztp6gT7GQ))S*{?V9_r{J7tUo4zgMrZoQWoZ1L#MIO8-J>>p1kUL=IStkb@x?0#~ z65*?#t&;Lu708ONaS0SQ#|QVt-F~;~cg8`dHYPHNARS~w@_=yVxDkyrg_RG9R=B;| z`;O}URo{n@fxpH3m2YJWMO {} +import { useHMSRoomStyle } from '../../hooks-util'; + +interface ClockIconProps extends Omit { + type?: 'vector' | 'normal'; +} export const ClockIcon: React.FC = ({ style, + type = 'vector', ...restProps }) => { + const iconStyles = useHMSRoomStyle((theme) => ({ + tintColor: theme.palette.on_surface_high, + })); + return ( ); diff --git a/packages/react-native-room-kit/src/components/CreatePoll.tsx b/packages/react-native-room-kit/src/components/CreatePoll.tsx index 90d9886de..a857ee3ac 100644 --- a/packages/react-native-room-kit/src/components/CreatePoll.tsx +++ b/packages/react-native-room-kit/src/components/CreatePoll.tsx @@ -9,7 +9,11 @@ import { HMSTextInput } from './HMSTextInput'; import { HMSPrimaryButton } from './HMSPrimaryButton'; import { COLORS } from '../utils/theme'; import type { RootState } from '../redux'; -import { setPollConfig, setPollName, setPollStage } from '../redux/actions'; +import { + pushToNavigationStack, + setPollConfig, + setPollName, +} from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import type { PollConfig } from '../redux/actionTypes'; import { PollIcon, QuizIcon } from '../Icons'; @@ -67,7 +71,7 @@ export const CreatePoll: React.FC = ({}) => { const addQuestions = () => { if (pollName.trim().length > 0) { - dispatch(setPollStage(CreatePollStages.POLL_QUESTION_CONFIG)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_QUESTION_CONFIG)); } }; @@ -230,6 +234,7 @@ const styles = StyleSheet.create({ }, createPollBtn: { marginTop: 24, + marginBottom: 16, }, contentContainer: { marginHorizontal: 24, diff --git a/packages/react-native-room-kit/src/components/HLSView.tsx b/packages/react-native-room-kit/src/components/HLSView.tsx index 8b923048c..44bd61073 100644 --- a/packages/react-native-room-kit/src/components/HLSView.tsx +++ b/packages/react-native-room-kit/src/components/HLSView.tsx @@ -1,11 +1,18 @@ import React, { useRef } from 'react'; import type { ComponentRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { View, Text, StyleSheet, Platform } from 'react-native'; +import { + View, + Text, + StyleSheet, + Platform, + useWindowDimensions, +} from 'react-native'; import { HMSHLSPlayer, HMSHLSPlayerPlaybackState, useHMSHLSPlayerPlaybackState, + useHMSHLSPlayerResolution, } from '@100mslive/react-native-hms'; import type { RootState } from '../redux'; @@ -18,6 +25,7 @@ import { HMSHLSNotStarted } from './HMSHLSNotStarted'; import { CrossCircleIcon } from '../Icons'; import { useHMSRoomStyleSheet } from '../hooks-util'; import { useIsHLSStreamingOn } from '../hooks-sdk'; +import { useIsLandscapeOrientation } from '../utils/dimension'; export const _HLSView: React.FC = () => { const dispatch = useDispatch(); @@ -26,6 +34,7 @@ export const _HLSView: React.FC = () => { (state: RootState) => !!state.hmsStates.room?.hlsStreamingState.variants?.[0]?.hlsStreamUrl ); + const { width, height } = useWindowDimensions(); const hmsHlsPlayerRef = useRef>(null); const showHLSStats = useSelector( (state: RootState) => state.app.joinConfig.showHLSStats @@ -99,6 +108,8 @@ export const _HLSView: React.FC = () => { ); const hlsPlayerPlaybackState = useHMSHLSPlayerPlaybackState(); + const resolution = useHMSHLSPlayerResolution(); + const isLandscapeOrientation = useIsLandscapeOrientation(); const isPlaybackFailed = hlsPlayerPlaybackState === HMSHLSPlayerPlaybackState.FAILED; @@ -141,6 +152,21 @@ export const _HLSView: React.FC = () => { ref={hmsHlsPlayerRef} enableStats={showHLSStats} enableControls={enableHLSPlayerControls} + style={ + isLandscapeOrientation + ? { + height, + width: resolution + ? height * (resolution.width / resolution.height) + : width, + } + : { + width, + height: resolution + ? width / (resolution.width / resolution.height) + : height, + } + } /> diff --git a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx index 52151884c..c29334b82 100644 --- a/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx +++ b/packages/react-native-room-kit/src/components/HMSPollsQuizzesNotification.tsx @@ -14,8 +14,8 @@ import { import { HMSNotification } from './HMSNotification'; import { ModalTypes } from '../utils/types'; import { + pushToNavigationStack, removeNotification, - setPollStage, setSelectedPollId, } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; @@ -56,7 +56,7 @@ export const HMSPollsQuizzesNotification: React.FC< // return; // } batch(() => { - dispatch(setPollStage(CreatePollStages.POLL_VOTING)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); handleModalVisibleType(ModalTypes.POLLS_AND_QUIZZES); dispatch(removeNotification(id)); diff --git a/packages/react-native-room-kit/src/components/LeaderboardEntry.tsx b/packages/react-native-room-kit/src/components/LeaderboardEntry.tsx new file mode 100644 index 000000000..2cecc13c2 --- /dev/null +++ b/packages/react-native-room-kit/src/components/LeaderboardEntry.tsx @@ -0,0 +1,172 @@ +import * as React from 'react'; +import { Text, StyleSheet, View } from 'react-native'; +import type { ViewStyle, StyleProp } from 'react-native'; +import type { HMSPollLeaderboardEntry } from '@100mslive/react-native-hms'; + +import { useHMSRoomStyleSheet } from '../hooks-util'; +import { CheckIcon, ClockIcon } from '../Icons'; + +export interface LeaderboardEntryProps { + entry: HMSPollLeaderboardEntry; + totalPoints: number; + totalQuestions: number; + style?: StyleProp; +} + +export const LeaderboardEntry: React.FC = ({ + entry, + style, + totalPoints, + totalQuestions, +}) => { + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + regularHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-Regular`, + }, + regularMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-Regular`, + }, + semiBoldHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + semiBoldWhiteText: { + color: '#ffffff', + fontFamily: `${typography.font_family}-SemiBold`, + }, + icon: { + tintColor: theme.palette.on_surface_medium, + }, + })); + + return ( + + + + {entry.position} + + + + + {entry.peer?.userName} + + + {entry.score}/{totalPoints} points + + + + + + {entry.position === 1 && + entry.correctResponses && + entry.correctResponses > 0 ? ( + + 🏆 + + ) : null} + + + + + {entry.correctResponses}/{totalQuestions} + + + + {entry.duration ? ( + + + + {(entry.duration / 1000).toFixed(2)}s + + + ) : null} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + namePositionWrapper: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + scoreDurationWrapper: { flexDirection: 'row', alignItems: 'center' }, + flexShrink: { + flexShrink: 1, + }, + smallerText: { + fontSize: 12, + lineHeight: 16, + }, + smallText: { + fontSize: 14, + lineHeight: 20, + }, + normalText: { + fontSize: 16, + lineHeight: 24, + }, + position: { + width: 24, + height: 24, + borderRadius: 12, + textAlign: 'center', + textAlignVertical: 'center', + marginRight: 12, + }, + firstPosition: { + backgroundColor: '#D69516', // '#FFD700' + }, + secondPosition: { + backgroundColor: '#3E3E3E', // '#C0C0C0' + }, + thirdPosition: { + backgroundColor: '#583B0F', // '#CD7F32' + }, + iconWrapper: { + flexDirection: 'row', + alignItems: 'center', + marginLeft: 12, + }, + icon: { + width: 16, + height: 16, + marginRight: 4, + }, +}); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx b/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx new file mode 100644 index 000000000..c0a13a0d6 --- /dev/null +++ b/packages/react-native-room-kit/src/components/PollAndQuizSheetScreen.tsx @@ -0,0 +1,85 @@ +import * as React from 'react'; +import { StyleSheet } from 'react-native'; +import Animated, { + interpolate, + useAnimatedStyle, + useSharedValue, + withTiming, + runOnJS, +} from 'react-native-reanimated'; +import { useSafeAreaFrame } from 'react-native-safe-area-context'; + +import { useIsLandscapeOrientation } from '../utils/dimension'; + +export interface PollAndQuizSheetScreenProps { + children: React.ReactElement | null; + zIndex: number; + disableAnimation?: boolean; +} + +export const PollAndQuizSheetScreen: React.FC = ({ + children, + zIndex, + disableAnimation, +}) => { + const isLandscapeOrientation = useIsLandscapeOrientation(); + const { width } = useSafeAreaFrame(); + const xPosition = useSharedValue(disableAnimation ? 0 : 1); + + const animatedStyle = useAnimatedStyle( + () => ({ + opacity: interpolate(xPosition.value, [0, 1], [1, 0]), + transform: [ + { + translateX: interpolate( + xPosition.value, + [0, 1], + [0, isLandscapeOrientation ? width * 0.6 : width], + 'clamp' + ), + }, + ], + }), + [isLandscapeOrientation] + ); + + React.useEffect(() => { + if (disableAnimation) { + return; + } + xPosition.value = withTiming(0, { duration: 150 }); + return () => { + cancelAnimationFrame(xPosition.value); + }; + }, []); + + const unmountScreenWithAnimation = React.useCallback( + (cb: () => void) => { + if (disableAnimation) { + cb(); + return; + } + xPosition.value = withTiming(1, { duration: 150 }, () => { + runOnJS(cb)(); + }); + }, + [disableAnimation] + ); + + return ( + + {children + ? React.cloneElement(children, { unmountScreenWithAnimation }) + : null} + + ); +}; + +const styles = StyleSheet.create({ + absolute: { + width: '100%', + height: '100%', + position: 'absolute', + overflow: 'hidden', + }, +}); diff --git a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx index 9b20f00e2..62d3bd8dd 100644 --- a/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx +++ b/packages/react-native-room-kit/src/components/PollAndQuizVoting.tsx @@ -6,22 +6,42 @@ import { findNodeHandle, UIManager, View, + Keyboard, + TouchableOpacity, } from 'react-native'; -import { useSelector } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { HMSPollState, HMSPollType } from '@100mslive/react-native-hms'; import { useHMSInstance, useHMSRoomStyleSheet } from '../hooks-util'; import type { RootState } from '../redux'; import { HMSDangerButton } from './HMSDangerButton'; import { PollAndQuizQuestionResponseCards } from './PollAndQuizQuestionResponseCards'; +import { + popFromNavigationStack, + pushToNavigationStack, +} from '../redux/actions'; +import { BottomSheet } from './BottomSheet'; +import { ChevronIcon, CloseIcon } from '../Icons'; +import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; +import { HMSPrimaryButton } from './HMSPrimaryButton'; +import { CreatePollStages } from '../redux/actionTypes'; +import { VoterParticipationSummary } from './VoterParticipationSummary'; export interface PollAndQuizVotingProps { + currentIdx: number; dismissModal(): void; + unmountScreenWithAnimation?(cb: Function): void; } -export const PollAndQuizVoting: React.FC = () => { +export const PollAndQuizVoting: React.FC = ({ + currentIdx, + dismissModal, + unmountScreenWithAnimation, +}) => { const scrollViewRef = React.useRef(null); const hmsInstance = useHMSInstance(); + const dispatch = useDispatch(); + const selectedPoll = useSelector((state: RootState) => { const pollsData = state.polls; if (pollsData.selectedPollId !== null) { @@ -33,16 +53,34 @@ export const PollAndQuizVoting: React.FC = () => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; }); + const headerTitle = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.selectedPollId !== null) { + return pollsData.polls[pollsData.selectedPollId]?.title || null; + } + return null; + }); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ regularMediumText: { color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-Regular`, }, + semiBoldHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, semiBoldMediumText: { color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-SemiBold`, }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, })); const endPoll = async () => { @@ -79,17 +117,90 @@ export const PollAndQuizVoting: React.FC = () => { ); }; + const viewLeaderboard = () => { + dispatch(pushToNavigationStack(CreatePollStages.QUIZ_LEADERBOARD)); + }; + + const handleBackPress = () => { + Keyboard.dismiss(); + if (typeof unmountScreenWithAnimation === 'function') { + unmountScreenWithAnimation(() => dispatch(popFromNavigationStack())); + } else { + dispatch(popFromNavigationStack()); + } + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} + + + {headerTitle} + + + {selectedPoll?.state ? ( + + ) : null} + + + + + + + + {/* Divider */} + + + {/* Content */} - - {selectedPoll?.createdBy?.name} started a{' '} - {selectedPoll?.type === HMSPollType.quiz ? 'quiz' : 'poll'} - + {selectedPoll && + selectedPoll.type === HMSPollType.quiz && + selectedPoll.state === HMSPollState.stopped && + !canCreateOrEndPoll ? ( + + + + + Questions + + + ) : ( + + {selectedPoll?.createdBy?.name} started a{' '} + {selectedPoll?.type === HMSPollType.quiz ? 'quiz' : 'poll'} + + )} {selectedPoll ? ( = () => { }} /> ) : null} + + {selectedPoll && + selectedPoll.state === HMSPollState.stopped && + selectedPoll.type === HMSPollType.quiz ? ( + + ) : null} ); }; @@ -158,4 +285,51 @@ const styles = StyleSheet.create({ marginRight: 8, padding: 8, }, + + // ----------------- + + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, }); diff --git a/packages/react-native-room-kit/src/components/PollQuestions.tsx b/packages/react-native-room-kit/src/components/PollQuestions.tsx index 2cb75411e..06f788916 100644 --- a/packages/react-native-room-kit/src/components/PollQuestions.tsx +++ b/packages/react-native-room-kit/src/components/PollQuestions.tsx @@ -5,14 +5,15 @@ import { StyleSheet, TouchableOpacity, ScrollView, + Keyboard, } from 'react-native'; import { HMSPollQuestionType, HMSPollType } from '@100mslive/react-native-hms'; +import { batch, useDispatch, useSelector, useStore } from 'react-redux'; -import { AddIcon } from '../Icons'; +import { AddIcon, ChevronIcon, CloseIcon } from '../Icons'; import { useHMSInstance, useHMSRoomStyleSheet } from '../hooks-util'; import { HMSPrimaryButton } from './HMSPrimaryButton'; import { PollQuestion } from './PollQuestion'; -import { batch, useDispatch, useSelector, useStore } from 'react-redux'; import type { RootState } from '../redux'; import { addPollQuestion, @@ -20,6 +21,7 @@ import { cleaPollFormState, deletePollQuestionOption, editPollQuestionOption, + popFromNavigationStack, setLaunchingPoll, setPollQDeleteConfirmationVisible, setPollQuestionCorrectOption, @@ -32,12 +34,20 @@ import { setSelectedPollQuestionIndex, } from '../redux/actions'; import type { PollQuestionUI } from '../redux/actionTypes'; +import { PollQDeleteConfirmationSheetView } from './PollQDeleteConfirmationSheetView'; +import { BottomSheet } from './BottomSheet'; export interface PollQuestionsProps { + currentIdx: number; dismissModal(): void; + unmountScreenWithAnimation?: (cb: Function) => void; } -export const PollQuestions: React.FC = ({}) => { +export const PollQuestions: React.FC = ({ + currentIdx, + dismissModal, + unmountScreenWithAnimation, +}) => { const dispatch = useDispatch(); const hmsInstance = useHMSInstance(); const reduxStore = useStore(); @@ -50,6 +60,7 @@ export const PollQuestions: React.FC = ({}) => { const pollType = useSelector( (state: RootState) => state.polls.pollConfig.type ); + const headerTitle = useSelector((state: RootState) => state.polls.pollName); const questions = useSelector((state: RootState) => state.polls.questions); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ @@ -57,6 +68,13 @@ export const PollQuestions: React.FC = ({}) => { color: theme.palette.on_surface_medium, fontFamily: `${typography.font_family}-Regular`, }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, })); const disableLaunchPoll = @@ -185,60 +203,117 @@ export const PollQuestions: React.FC = ({}) => { [] ); + const handleBackPress = () => { + Keyboard.dismiss(); + if (typeof unmountScreenWithAnimation === 'function') { + unmountScreenWithAnimation(() => dispatch(popFromNavigationStack())); + } else { + dispatch(popFromNavigationStack()); + } + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - - {questions.map((pollQuestion, idx, arr) => { - const isFirst = idx === 0; - return ( - - {isFirst ? null : } + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} - - - ); - })} + + {headerTitle} + + - - - - - - Add another question - + - - + {/* Divider */} + + + + {questions.map((pollQuestion, idx, arr) => { + const isFirst = idx === 0; + return ( + + {isFirst ? null : } + + + + ); + })} + + + + + + + + Add another question + + + + + + + + {/* Modal */} + + ); }; @@ -274,4 +349,51 @@ const styles = StyleSheet.create({ marginRight: 8, padding: 8, }, + + // ------- + + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, }); diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx index ca76f70b8..fee891357 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizBottomSheet.tsx @@ -1,22 +1,17 @@ import * as React from 'react'; import { Platform, StyleSheet } from 'react-native'; -import { useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { BottomSheet } from './BottomSheet'; -import { - useHMSRoomStyleSheet, - useIsHLSViewer, - useModalType, -} from '../hooks-util'; +import { useHMSRoomStyleSheet, useModalType } from '../hooks-util'; import { useHeaderHeight } from './Header'; import { useIsLandscapeOrientation } from '../utils/dimension'; import { PollsAndQuizzesModalContent } from './PollsAndQuizzesModalContent'; import { ModalTypes } from '../utils/types'; -import type { RootState } from '../redux'; -import { CreatePollStages } from '../redux/actionTypes'; -import { visiblePollsSelector } from '../utils/functions'; +import { resetNavigationStack } from '../redux/actions'; export const PollsAndQuizBottomSheet = () => { + const dispatch = useDispatch(); const headerHeight = useHeaderHeight(); const isLandscapeOrientation = useIsLandscapeOrientation(); const { @@ -24,40 +19,26 @@ export const PollsAndQuizBottomSheet = () => { handleModalVisibleType: setModalVisible, } = useModalType(); - const isPollQuestionStage = useSelector( - (state: RootState) => - state.polls.stage === CreatePollStages.POLL_QUESTION_CONFIG - ); - const isHLSViewer = useIsHLSViewer(); - const havePolls = useSelector( - (state: RootState) => - visiblePollsSelector( - Object.values(state.polls.polls), - isHLSViewer, - state.polls.cuedPollIds - ).length > 0 - ); - const hmsRoomStyles = useHMSRoomStyleSheet((theme) => ({ contentContainer: { backgroundColor: theme.palette.surface_dim, }, })); - const dismissModal = () => setModalVisible(ModalTypes.DEFAULT); - - const fullHeight = isPollQuestionStage || havePolls; - const containerStyles = fullHeight - ? [ - styles.bottomSheet, - { - marginTop: isLandscapeOrientation - ? 0 - : headerHeight + (Platform.OS === 'android' ? 24 : 0), - }, - hmsRoomStyles.contentContainer, - ] - : [hmsRoomStyles.contentContainer]; + const dismissModal = () => { + setModalVisible(ModalTypes.DEFAULT); + dispatch(resetNavigationStack()); + }; + + const containerStyles = [ + styles.bottomSheet, + { + marginTop: isLandscapeOrientation + ? 0 + : headerHeight + (Platform.OS === 'android' ? 24 : 0), + }, + hmsRoomStyles.contentContainer, + ]; return ( { isVisible={modalVisible === ModalTypes.POLLS_AND_QUIZZES} avoidKeyboard={true} containerStyle={containerStyles} - bottomOffsetSpace={fullHeight ? 0 : undefined} + bottomOffsetSpace={0} > - + ); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx index 5b5445c42..2a1bbd929 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesCard.tsx @@ -5,7 +5,7 @@ import type { HMSPoll } from '@100mslive/react-native-hms'; import { useHMSRoomStyleSheet } from '../hooks-util'; import { HMSPrimaryButton } from './HMSPrimaryButton'; -import { setPollStage, setSelectedPollId } from '../redux/actions'; +import { pushToNavigationStack, setSelectedPollId } from '../redux/actions'; import { CreatePollStages } from '../redux/actionTypes'; import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; @@ -36,7 +36,7 @@ export const PollsAndQuizzesCard: React.FC = ({ const viewPoll = () => { batch(() => { - dispatch(setPollStage(CreatePollStages.POLL_VOTING)); + dispatch(pushToNavigationStack(CreatePollStages.POLL_VOTING)); dispatch(setSelectedPollId(poll.pollId)); }); }; diff --git a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx index 49d7e2872..fc701a42d 100644 --- a/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx +++ b/packages/react-native-room-kit/src/components/PollsAndQuizzesModalContent.tsx @@ -1,62 +1,27 @@ import * as React from 'react'; -import { - View, - Text, - StyleSheet, - TouchableOpacity, - Keyboard, -} from 'react-native'; -import { useDispatch, useSelector } from 'react-redux'; +import { View, StyleSheet } from 'react-native'; +import { useSelector } from 'react-redux'; import type { RootState } from '../redux'; -import { useHMSRoomStyleSheet } from '../hooks-util'; -import { BottomSheet } from './BottomSheet'; -import { ChevronIcon, CloseIcon } from '../Icons'; -import { TestIds } from '../utils/constants'; import { PollQuestions } from './PollQuestions'; import { CreatePollStages } from '../redux/actionTypes'; -import { setPollStage } from '../redux/actions'; -import { PollQDeleteConfirmationSheetView } from './PollQDeleteConfirmationSheetView'; import { PollsConfigAndList } from './PollsConfigAndList'; import { PollAndQuizVoting } from './PollAndQuizVoting'; -import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; +import { PollAndQuizSheetScreen } from './PollAndQuizSheetScreen'; +import { QuizLeaderboardScreen } from './QuizLeaderboardScreen'; +import { QuizLeaderboardEntriesScreen } from './QuizLeaderboardEntriesScreen'; export interface PollsAndQuizzesModalContentProps { - fullHeight: boolean; dismissModal(): void; } export const PollsAndQuizzesModalContent: React.FC< PollsAndQuizzesModalContentProps -> = ({ fullHeight, dismissModal }) => { - const dispatch = useDispatch(); - const headerTitle = useSelector((state: RootState) => { - const pollsData = state.polls; - if (pollsData.stage === CreatePollStages.POLL_QUESTION_CONFIG) { - return pollsData.pollName; - } - if ( - pollsData.stage === CreatePollStages.POLL_VOTING && - pollsData.selectedPollId !== null - ) { - return pollsData.polls[pollsData.selectedPollId]?.title || null; - } - return null; - }); - const selectedPoll = useSelector((state: RootState) => { - const pollsData = state.polls; - if ( - pollsData.stage === CreatePollStages.POLL_VOTING && - pollsData.selectedPollId !== null - ) { - return pollsData.polls[pollsData.selectedPollId] || null; - } - return null; - }); - const pollsStage = useSelector((state: RootState) => state.polls.stage); - const launchingPoll = useSelector( - (state: RootState) => state.polls.launchingPoll +> = ({ dismissModal }) => { + const pollsNavigationStack = useSelector( + (state: RootState) => state.polls.navigationStack ); + const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -66,133 +31,45 @@ export const PollsAndQuizzesModalContent: React.FC< return permissions?.pollRead; }); - const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ - headerText: { - color: theme.palette.on_surface_high, - fontFamily: `${typography.font_family}-SemiBold`, - }, - })); - - const handleBackPress = () => { - Keyboard.dismiss(); - dispatch(setPollStage(CreatePollStages.POLL_CONFIG)); - }; - - const handleClosePress = () => { - Keyboard.dismiss(); - dismissModal(); - }; - return ( - - {/* Header */} - - - {headerTitle ? ( - - - - ) : null} - - - {headerTitle ?? 'Polls and Quizzes'} - - - {selectedPoll?.state ? ( - - ) : null} - - - + {pollsNavigationStack.map((stage, index) => ( + - - - - - {/* Divider */} - - - {/* Content */} - - {pollsStage === CreatePollStages.POLL_CONFIG ? ( - - ) : pollsStage === CreatePollStages.POLL_QUESTION_CONFIG && - canCreateOrEndPoll ? ( - - ) : pollsStage === CreatePollStages.POLL_VOTING && - (canVoteOnPoll || canCreateOrEndPoll) ? ( - - ) : null} - - - {/* Modal */} - + {stage === CreatePollStages.POLL_CONFIG ? ( + + ) : stage === CreatePollStages.POLL_QUESTION_CONFIG && + canCreateOrEndPoll ? ( + + ) : stage === CreatePollStages.POLL_VOTING && + (canVoteOnPoll || canCreateOrEndPoll) ? ( + + ) : stage === CreatePollStages.QUIZ_LEADERBOARD ? ( + + ) : stage === CreatePollStages.QUIZ_LEADERBOARD_ENTRIES ? ( + + ) : null} + + ))} ); }; const styles = StyleSheet.create({ - // Utilities + relative: { + position: 'relative', + overflow: 'hidden', + }, fullView: { flex: 1, }, - // Header - header: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginTop: 24, - marginHorizontal: 24, - }, - headerControls: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1, - }, - headerText: { - fontSize: 20, - lineHeight: 24, - letterSpacing: 0.15, - marginRight: 12, - }, - closeIconHitSlop: { - bottom: 16, - left: 16, - right: 16, - top: 16, - }, - backIcon: { - marginRight: 8, - }, - // Divider - halfDivider: { - marginHorizontal: 24, - marginVertical: 0, - marginTop: 24, - width: undefined, - }, - divider: { - marginHorizontal: 24, - marginVertical: 24, - width: undefined, - }, }); diff --git a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx index fc0e5afd2..f339f705b 100644 --- a/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx +++ b/packages/react-native-room-kit/src/components/PollsConfigAndList.tsx @@ -1,14 +1,38 @@ import * as React from 'react'; -import { ScrollView } from 'react-native'; +import { + Keyboard, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import { useSelector } from 'react-redux'; import { CreatePoll } from './CreatePoll'; import { PreviousPollsAndQuizzesList } from './PreviousPollsAndQuizzesList'; -import { useSelector } from 'react-redux'; -import type { RootState } from 'src/redux'; +import type { RootState } from '../redux'; +import { BottomSheet } from './BottomSheet'; +import { CloseIcon } from '../Icons'; +import { useHMSRoomStyleSheet } from '../hooks-util'; -export interface PollsConfigAndListProps {} +export interface PollsConfigAndListProps { + dismissModal(): void; +} + +export const PollsConfigAndList: React.FC = ({ + dismissModal, +}) => { + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + container: { + backgroundColor: theme.palette.surface_dim, + }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + })); -export const PollsConfigAndList: React.FC = ({}) => { const canCreateOrEndPoll = useSelector((state: RootState) => { const permissions = state.hmsStates.localPeer?.role?.permissions; return permissions?.pollWrite; @@ -18,12 +42,84 @@ export const PollsConfigAndList: React.FC = ({}) => { return permissions?.pollRead; }); + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + return ( - - {canCreateOrEndPoll ? : null} - {canVoteOnPoll || canCreateOrEndPoll ? ( - - ) : null} - + + {/* Header */} + + + Polls and Quizzes + + + + + + + + {/* Divider */} + + + {/* Content */} + + {canCreateOrEndPoll ? : null} + {canVoteOnPoll || canCreateOrEndPoll ? ( + + ) : null} + + ); }; + +const styles = StyleSheet.create({ + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + // marginVertical: 0, + // marginTop: 24, + width: undefined, + }, + divider: { + marginHorizontal: 24, + marginVertical: 24, + width: undefined, + }, +}); diff --git a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx index 3b8895f7a..56ab93d19 100644 --- a/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx +++ b/packages/react-native-room-kit/src/components/PreviousPollsAndQuizzesList.tsx @@ -18,11 +18,6 @@ export const PreviousPollsAndQuizzesList: React.FC< (state: RootState) => state.polls.cuedPollIds ); - const canCreateOrEndPoll = useSelector((state: RootState) => { - const permissions = state.hmsStates.localPeer?.role?.permissions; - return permissions?.pollWrite; - }); - const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ surfaceHighSemiBoldText: { color: theme.palette.on_surface_high, @@ -40,44 +35,42 @@ export const PreviousPollsAndQuizzesList: React.FC< hlsCuedPollIds ); - if (pollsList.length === 0 && !canCreateOrEndPoll) { - return ( - - - No Polls or Quizzes to show - - - ); - } - return ( - {pollsList.length > 0 && ( - - Previous Polls And Quizzes - - )} + + Previous Polls And Quizzes + - {pollsList - .sort((a, b) => { - return a.state === b.state // If polls have same state, then sort as per startedAt - ? a.startedAt !== undefined && b.startedAt !== undefined - ? b.startedAt.getTime() - a.startedAt.getTime() - : 0 - : // If polls have different state, then sort as per state - a.state !== undefined && b.state !== undefined - ? a.state - b.state - : 0; - }) - .map((poll) => ( - - ))} + {pollsList.length <= 0 ? ( + + + No Polls or Quizzes to show + + + ) : ( + <> + {pollsList + .sort((a, b) => { + return a.state === b.state // If polls have same state, then sort as per startedAt + ? a.startedAt !== undefined && b.startedAt !== undefined + ? b.startedAt.getTime() - a.startedAt.getTime() + : 0 + : // If polls have different state, then sort as per state + a.state !== undefined && b.state !== undefined + ? a.state - b.state + : 0; + }) + .map((poll) => ( + + ))} + + )} ); }; diff --git a/packages/react-native-room-kit/src/components/QuizLeaderboardEntriesScreen.tsx b/packages/react-native-room-kit/src/components/QuizLeaderboardEntriesScreen.tsx new file mode 100644 index 000000000..25f5660dd --- /dev/null +++ b/packages/react-native-room-kit/src/components/QuizLeaderboardEntriesScreen.tsx @@ -0,0 +1,323 @@ +import * as React from 'react'; +import { + Text, + StyleSheet, + View, + Keyboard, + TouchableOpacity, + ActivityIndicator, +} from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; +import type { HMSPollLeaderboardEntry } from '@100mslive/react-native-hms'; +import { FlashList } from '@shopify/flash-list'; + +import { + useHMSInstance, + useHMSRoomColorPalette, + useHMSRoomStyleSheet, +} from '../hooks-util'; +import type { RootState } from '../redux'; +import { popFromNavigationStack } from '../redux/actions'; +import { BottomSheet } from './BottomSheet'; +import { ChevronIcon, CloseIcon } from '../Icons'; +import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; +import { LeaderboardEntry } from './LeaderboardEntry'; + +export interface QuizLeaderboardEntriesScreenProps { + currentIdx: number; + dismissModal(): void; + unmountScreenWithAnimation?(cb: Function): void; +} + +export const QuizLeaderboardEntriesScreen: React.FC< + QuizLeaderboardEntriesScreenProps +> = ({ currentIdx, dismissModal, unmountScreenWithAnimation }) => { + const hmsInstance = useHMSInstance(); + const dispatch = useDispatch(); + + const selectedPoll = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.selectedPollId !== null) { + return pollsData.polls[pollsData.selectedPollId] || null; + } + return null; + }); + + const initialLeaderboardEntries = useSelector((state: RootState) => { + return selectedPoll?.pollId + ? state.polls.leaderboards[selectedPoll.pollId]?.entries + : null; + }); + + const [leaderboardEntries, setLeaderboardEntries] = React.useState< + HMSPollLeaderboardEntry[] + >(initialLeaderboardEntries ? [...initialLeaderboardEntries] : []); + + const startIndexRef = React.useRef(leaderboardEntries.length); + + const { primary_default: primaryDefaultColor } = useHMSRoomColorPalette(); + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + regularHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-Regular`, + }, + regularMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-Regular`, + }, + semiBoldMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-SemiBold`, + }, + semiBoldHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, + summaryContainer: { + backgroundColor: theme.palette.surface_default, + }, + entriesCard: { + backgroundColor: theme.palette.surface_default, + }, + divider: { + backgroundColor: theme.palette.border_bright, + }, + })); + + const handleBackPress = () => { + Keyboard.dismiss(); + if (typeof unmountScreenWithAnimation === 'function') { + unmountScreenWithAnimation(() => dispatch(popFromNavigationStack())); + } else { + dispatch(popFromNavigationStack()); + } + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + + const [loading, setLoading] = React.useState(false); + const loadingRef = React.useRef(false); + const mounted = React.useRef(true); + const canFetchMore = React.useRef(true); + + const fetchLeaderboard = React.useCallback(async () => { + if (selectedPoll?.pollId && canFetchMore.current && !loadingRef.current) { + setLoading(true); + loadingRef.current = true; + const response = await hmsInstance.interactivityCenter.fetchLeaderboard( + selectedPoll.pollId, + 50, + startIndexRef.current + 1, // Indexing starts from 1 + false + ); + if (mounted) { + setLoading(false); + loadingRef.current = false; + if (Array.isArray(response.entries)) { + const entries = response.entries; + setLeaderboardEntries((prev) => { + const list = [...prev, ...entries]; + startIndexRef.current = list.length; + return list; + }); + if (entries.length <= 0) { + canFetchMore.current = false; + } + } + if (response.hasNext === false) { + canFetchMore.current = false; + } + } + } + }, [selectedPoll?.pollId]); + + const totalPoints = + selectedPoll?.questions?.reduce((acc, curr) => { + acc += curr.weight; + return acc; + }, 0) ?? 0; + + const totalQuestions = selectedPoll?.questions?.length ?? 0; + + const _keyExtractor = React.useCallback( + (item: HMSPollLeaderboardEntry, index: number) => + item.peer?.peerId ?? index.toString(), + [] + ); + + const _renderItem = React.useCallback( + (data: { item: HMSPollLeaderboardEntry }) => { + return ( + + ); + }, + [totalPoints, totalQuestions] + ); + + return ( + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} + + + {selectedPoll?.title} + + + {selectedPoll?.state ? ( + + ) : null} + + + + + + + + {/* Divider */} + + + {/* Content */} + ( + + + Leaderboard + + + Based on time taken to cast the correct answer + + + )} + ListFooterComponent={() => + loading ? ( + + ) : null + } + estimatedItemSize={56} + onEndReached={() => { + fetchLeaderboard(); + }} + // showsVerticalScrollIndicator={Platform.OS !== 'android'} + contentContainerStyle={{ paddingHorizontal: 24 }} + // keyboardShouldPersistTaps="always" + // ItemSeparatorComponent={() => } // TODO: There is a bug related to this: https://github.com/Shopify/flash-list/issues/638 + renderItem={_renderItem} + keyExtractor={_keyExtractor} + /> + + ); +}; + +const styles = StyleSheet.create({ + tinyText: { + fontSize: 10, + lineHeight: 16, + letterSpacing: 1.5, + }, + smallerText: { + fontSize: 12, + lineHeight: 16, + }, + smallText: { + fontSize: 14, + lineHeight: 20, + }, + normalText: { + fontSize: 16, + lineHeight: 24, + }, + marginBottom16: { + marginBottom: 16, + }, + iconWrapper: { + flexDirection: 'row', + alignItems: 'center', + marginLeft: 12, + }, + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { height: 1, width: '100%' }, + viewAllBtn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + paddingVertical: 12, + paddingHorizontal: 16, + }, + leaderboardEntry: { marginBottom: 16, marginHorizontal: 16 }, + entriesCard: { paddingTop: 12, borderRadius: 8 }, +}); diff --git a/packages/react-native-room-kit/src/components/QuizLeaderboardScreen.tsx b/packages/react-native-room-kit/src/components/QuizLeaderboardScreen.tsx new file mode 100644 index 000000000..430a1a8d1 --- /dev/null +++ b/packages/react-native-room-kit/src/components/QuizLeaderboardScreen.tsx @@ -0,0 +1,342 @@ +import * as React from 'react'; +import { + Text, + StyleSheet, + ScrollView, + View, + Keyboard, + TouchableOpacity, +} from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; + +import { useHMSRoomStyleSheet } from '../hooks-util'; +import type { RootState } from '../redux'; +import { + popFromNavigationStack, + pushToNavigationStack, +} from '../redux/actions'; +import { BottomSheet } from './BottomSheet'; +import { ChevronIcon, CloseIcon } from '../Icons'; +import { PollAndQuizzStateLabel } from './PollAndQuizzStateLabel'; +import { LeaderboardEntry } from './LeaderboardEntry'; +import { CreatePollStages } from '../redux/actionTypes'; +import { QuizLeaderboardSummary } from './QuizLeaderboardSummary'; +import { + useFetchLeaderboardResponse, + useLeaderboardSummaryData, +} from '../utils/hooks'; + +export interface QuizLeaderboardScreenProps { + currentIdx: number; + dismissModal(): void; + unmountScreenWithAnimation?(cb: Function): void; +} + +export const QuizLeaderboardScreen: React.FC = ({ + currentIdx, + dismissModal, + unmountScreenWithAnimation, +}) => { + const dispatch = useDispatch(); + + const selectedPoll = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.selectedPollId !== null) { + return pollsData.polls[pollsData.selectedPollId] || null; + } + return null; + }); + const headerTitle = useSelector((state: RootState) => { + const pollsData = state.polls; + if (pollsData.selectedPollId !== null) { + return pollsData.polls[pollsData.selectedPollId]?.title || null; + } + return null; + }); + + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + regularHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-Regular`, + }, + regularMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-Regular`, + }, + semiBoldMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-SemiBold`, + }, + semiBoldHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, + summaryContainer: { + backgroundColor: theme.palette.surface_default, + }, + entriesCard: { + backgroundColor: theme.palette.surface_default, + }, + divider: { + backgroundColor: theme.palette.border_bright, + }, + })); + + const handleBackPress = () => { + Keyboard.dismiss(); + if (typeof unmountScreenWithAnimation === 'function') { + unmountScreenWithAnimation(() => dispatch(popFromNavigationStack())); + } else { + dispatch(popFromNavigationStack()); + } + }; + + const handleClosePress = () => { + Keyboard.dismiss(); + dismissModal(); + }; + + const viewAllLeaderboardEntries = () => { + dispatch(pushToNavigationStack(CreatePollStages.QUIZ_LEADERBOARD_ENTRIES)); + }; + + const leaderboardData = useFetchLeaderboardResponse(selectedPoll?.pollId); + + const leaderboardEntries = leaderboardData?.entries; + + const summaryData = useLeaderboardSummaryData(selectedPoll?.pollId); + + const totalPoints = + selectedPoll?.questions?.reduce((acc, curr) => { + acc += curr.weight; + return acc; + }, 0) ?? 0; + + return ( + + {/* Header */} + + + {currentIdx > 0 ? ( + + + + ) : null} + + + {headerTitle} + + + {selectedPoll?.state ? ( + + ) : null} + + + + + + + + {/* Divider */} + + + {/* Content */} + + {summaryData ? : null} + + {selectedPoll && + Array.isArray(selectedPoll.questions) && + Array.isArray(leaderboardEntries) && + leaderboardEntries.length > 0 ? ( + + + Leaderboard + + + Based on time taken to cast the correct answer + + + + {leaderboardEntries.map((entry, index) => { + return ( + + ); + })} + + {leaderboardData?.hasNext && leaderboardEntries.length <= 5 ? ( + + + + + + View All + + + + + + ) : null} + + + ) : null} + + + ); +}; + +const styles = StyleSheet.create({ + tinyText: { + fontSize: 10, + lineHeight: 16, + letterSpacing: 1.5, + }, + smallerText: { + fontSize: 12, + lineHeight: 16, + }, + smallText: { + fontSize: 14, + lineHeight: 20, + }, + normalText: { + fontSize: 16, + lineHeight: 24, + }, + marginBottom8: { + marginBottom: 8, + }, + marginBottom16: { + marginBottom: 16, + }, + contentContainer: { + paddingHorizontal: 24, + }, + scrollViewContentContainer: { + flexGrow: 1, + paddingVertical: 24, + }, + summaryWrapper: { + flexBasis: '50%', + flexGrow: 1, + flexShrink: 1, + padding: 16, + borderRadius: 12, + }, + position: { + width: 24, + height: 24, + borderRadius: 12, + textAlign: 'center', + textAlignVertical: 'center', + marginRight: 12, + }, + firstPosition: { + backgroundColor: '#D69516', // '#FFD700' + }, + secondPosition: { + backgroundColor: '#3E3E3E', // '#C0C0C0' + }, + thirdPosition: { + backgroundColor: '#583B0F', // '#CD7F32' + }, + iconWrapper: { + flexDirection: 'row', + alignItems: 'center', + marginLeft: 12, + }, + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { height: 1, width: '100%' }, + viewAllBtn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + paddingVertical: 12, + paddingHorizontal: 16, + }, + leaderboardEntry: { marginBottom: 16, marginHorizontal: 16 }, + entriesCard: { paddingTop: 12, borderRadius: 8 }, +}); diff --git a/packages/react-native-room-kit/src/components/QuizLeaderboardSummary.tsx b/packages/react-native-room-kit/src/components/QuizLeaderboardSummary.tsx new file mode 100644 index 000000000..674fccc45 --- /dev/null +++ b/packages/react-native-room-kit/src/components/QuizLeaderboardSummary.tsx @@ -0,0 +1,207 @@ +import * as React from 'react'; +import { Text, StyleSheet, View } from 'react-native'; + +import { useHMSRoomStyleSheet } from '../hooks-util'; + +export interface QuizLeaderboardSummaryProps { + data: { label: string; value: any }[][]; +} + +export const QuizLeaderboardSummary: React.FC = ({ + data, +}) => { + const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ + regularHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-Regular`, + }, + regularMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-Regular`, + }, + semiBoldMediumText: { + color: theme.palette.on_surface_medium, + fontFamily: `${typography.font_family}-SemiBold`, + }, + semiBoldHighText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + headerText: { + color: theme.palette.on_surface_high, + fontFamily: `${typography.font_family}-SemiBold`, + }, + container: { + backgroundColor: theme.palette.surface_dim, + }, + summaryContainer: { + backgroundColor: theme.palette.surface_default, + }, + entriesCard: { + backgroundColor: theme.palette.surface_default, + }, + divider: { + backgroundColor: theme.palette.border_bright, + }, + })); + + return ( + + + Participation Summary + + + + {data.map((summaryMap, index) => ( + + {summaryMap.map((summary, index) => ( + + {index > 0 ? : null} + + + + {summary.label} + + + + {summary.value} + + + + ))} + + ))} + + + ); +}; + +const styles = StyleSheet.create({ + tinyText: { + fontSize: 10, + lineHeight: 16, + letterSpacing: 1.5, + }, + smallerText: { + fontSize: 12, + lineHeight: 16, + }, + smallText: { + fontSize: 14, + lineHeight: 20, + }, + normalText: { + fontSize: 16, + lineHeight: 24, + }, + marginBottom8: { + marginBottom: 8, + }, + marginBottom16: { + marginBottom: 16, + }, + contentContainer: { + paddingHorizontal: 24, + }, + scrollViewContentContainer: { + flexGrow: 1, + paddingVertical: 24, + }, + summaryWrapper: { + flexBasis: '50%', + flexGrow: 1, + flexShrink: 1, + padding: 16, + borderRadius: 12, + }, + position: { + width: 24, + height: 24, + borderRadius: 12, + textAlign: 'center', + textAlignVertical: 'center', + marginRight: 12, + }, + firstPosition: { + backgroundColor: '#D69516', // '#FFD700' + }, + secondPosition: { + backgroundColor: '#3E3E3E', // '#C0C0C0' + }, + thirdPosition: { + backgroundColor: '#583B0F', // '#CD7F32' + }, + iconWrapper: { + flexDirection: 'row', + alignItems: 'center', + marginLeft: 12, + }, + // Utilities + fullView: { + flex: 1, + }, + // Header + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: 24, + marginHorizontal: 24, + }, + headerControls: { + flexDirection: 'row', + alignItems: 'center', + flexShrink: 1, + }, + headerText: { + fontSize: 20, + lineHeight: 24, + letterSpacing: 0.15, + marginRight: 12, + }, + closeIconHitSlop: { + bottom: 16, + left: 16, + right: 16, + top: 16, + }, + backIcon: { + marginRight: 8, + }, + // Divider + halfDivider: { + marginHorizontal: 24, + marginVertical: 0, + marginTop: 24, + width: undefined, + }, + divider: { height: 1, width: '100%' }, + viewAllBtn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + paddingVertical: 12, + paddingHorizontal: 16, + }, + leaderboardEntry: { marginBottom: 16, marginHorizontal: 16 }, + entriesCard: { paddingTop: 12, borderRadius: 8 }, +}); diff --git a/packages/react-native-room-kit/src/components/VoterParticipationSummary.tsx b/packages/react-native-room-kit/src/components/VoterParticipationSummary.tsx new file mode 100644 index 000000000..cb08c9fca --- /dev/null +++ b/packages/react-native-room-kit/src/components/VoterParticipationSummary.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; +import type { HMSPoll } from '@100mslive/react-native-hms'; +import { useSelector } from 'react-redux'; + +import type { RootState } from '../redux'; +import { QuizLeaderboardSummary } from './QuizLeaderboardSummary'; +import { useFetchLeaderboardResponse } from '../utils/hooks'; + +export interface VoterParticipationSummaryProps { + pollId: HMSPoll['pollId']; +} + +export const VoterParticipationSummary: React.FC< + VoterParticipationSummaryProps +> = ({ pollId }) => { + const localPeerUserId = useSelector( + (state: RootState) => state.hmsStates.localPeer?.customerUserID + ); + const leaderboardData = useFetchLeaderboardResponse(pollId); + const totalQuestions = useSelector( + (state: RootState) => state.polls.polls[pollId]?.questions?.length + ); + + const localLeaderboardEntry = + localPeerUserId && leaderboardData && Array.isArray(leaderboardData.entries) + ? leaderboardData.entries.find( + (entry) => entry.peer?.customerUserId === localPeerUserId + ) + : null; + + const data = React.useMemo(() => { + return [ + [ + { + label: 'ANSWERED', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.totalResponses === 'number' && + typeof totalQuestions === 'number' + ? `${Math.round((localLeaderboardEntry.totalResponses / totalQuestions) * 100)}% (${localLeaderboardEntry.totalResponses}/${totalQuestions})` + : '-', + }, + { + label: 'CORRECT ANSWERS', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.correctResponses === 'number' && + typeof totalQuestions === 'number' + ? `${Math.round((localLeaderboardEntry.correctResponses / totalQuestions) * 100)}% (${localLeaderboardEntry.correctResponses}/${totalQuestions})` + : '-', + }, + ], + [ + { + label: 'TIME TAKEN', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.duration === 'number' + ? `${(localLeaderboardEntry.duration / 1000).toFixed(2)}s` + : '-', + }, + ], + ]; + }, [localLeaderboardEntry]); + + return ; +}; diff --git a/packages/react-native-room-kit/src/redux/actionTypes.ts b/packages/react-native-room-kit/src/redux/actionTypes.ts index 1c6606270..39734e7d7 100644 --- a/packages/react-native-room-kit/src/redux/actionTypes.ts +++ b/packages/react-native-room-kit/src/redux/actionTypes.ts @@ -3,6 +3,7 @@ import type { HMSPollQuestion, HMSPollQuestionType, HMSPollType, + PollLeaderboardResponse, } from '@100mslive/react-native-hms'; const createRequests = (base: String) => { @@ -195,6 +196,8 @@ export enum CreatePollStages { POLL_CONFIG, POLL_QUESTION_CONFIG, POLL_VOTING, + QUIZ_LEADERBOARD, + QUIZ_LEADERBOARD_ENTRIES, } export type PollConfig = { @@ -217,7 +220,10 @@ export type PollsActionType = | SetDeleteConfirmationVisible | SetPollNameAction | SetPollConfigAction - | SetPollStageAction + | PushToNavigationStackAction + | ResetNavigationStackAction + | PopFromNavigationStackAction + | ReplaceTopOfNavigationStackAction | AddPollQuestionAction | DeletePollQuestionAction | SetSelectedQuestionIndexAction @@ -241,6 +247,7 @@ export type PollsActionType = | AddPollQuestionResponseAction | RemovePollQuestionResponseAction | AddCuedPollIdAction + | AddLeaderboardAction | { type: HmsStateActionTypes.CLEAR_STATES }; export type ClearPollFormStateAction = { @@ -262,9 +269,22 @@ export type SetPollConfigAction = { pollConfig: Partial; }; -export type SetPollStageAction = { - type: PollsStateActionTypes.SET_POLL_STAGE; - pollStage: CreatePollStages; +export type PushToNavigationStackAction = { + type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK; + screen: CreatePollStages; +}; + +export type ResetNavigationStackAction = { + type: PollsStateActionTypes.RESET_NAVIGATION_STACK; +}; + +export type PopFromNavigationStackAction = { + type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK; +}; + +export type ReplaceTopOfNavigationStackAction = { + type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK; + screen: CreatePollStages; }; export type AddPollQuestionAction = { @@ -391,12 +411,21 @@ export type AddCuedPollIdAction = { pollId: HMSPoll['pollId']; }; +export type AddLeaderboardAction = { + type: PollsStateActionTypes.ADD_LEADERBOARD; + pollId: HMSPoll['pollId']; + leaderboard: PollLeaderboardResponse; +}; + export enum PollsStateActionTypes { CLEAR_POLL_FORM_STATE = 'CLEAR_POLL_FORM_STATE', SET_DELETE_CONFIRMATION_VISIBLE = 'SET_DELETE_CONFIRMATION_VISIBLE', SET_POLL_NAME = 'SET_POLL_NAME', SET_POLL_CONFIG = 'SET_POLL_CONFIG', - SET_POLL_STAGE = 'SET_POLL_STAGE', + PUSH_TO_NAVIGATION_STACK = 'PUSH_TO_NAVIGATION_STACK', + RESET_NAVIGATION_STACK = 'RESET_NAVIGATION_STACK', + POP_FROM_NAVIGATION_STACK = 'POP_FROM_NAVIGATION_STACK', + REPLACE_TOP_OF_NAVIGATION_STACK = 'REPLACE_TOP_OF_NAVIGATION_STACK', ADD_POLL_QUESTION = 'ADD_POLL_QUESTION', DELETE_POLL_QUESTION = 'DELETE_POLL_QUESTION', SET_SELECTED_QUESTION_INDEX = 'SET_SELECTED_QUESTION_INDEX', @@ -419,4 +448,5 @@ export enum PollsStateActionTypes { REMOVE_POLL_QUESTION_RESPONSE = 'REMOVE_POLL_QUESTION_RESPONSE', ADD_POLL_QUESTION_RESPONSE = 'ADD_POLL_QUESTION_RESPONSE', ADD_CUED_POLL_ID = 'ADD_CUED_POLL_ID', + ADD_LEADERBOARD = 'ADD_LEADERBOARD', } 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 2d5d6ce52..ad80bce3c 100644 --- a/packages/react-native-room-kit/src/redux/actions/index.ts +++ b/packages/react-native-room-kit/src/redux/actions/index.ts @@ -32,7 +32,6 @@ import type { AddPollQuestionAction, SetPollConfigAction, SetPollNameAction, - SetPollStageAction, DeletePollQuestionAction, SetDeleteConfirmationVisible, SetSelectedQuestionIndexAction, @@ -54,6 +53,11 @@ import type { RemovePollQuestionResponseAction, SetQuestionPointWeightageAction, SetQuestionCorrectOptionAction, + PushToNavigationStackAction, + PopFromNavigationStackAction, + ReplaceTopOfNavigationStackAction, + AddLeaderboardAction, + ResetNavigationStackAction, } from '../actionTypes'; import { MeetingState } from '../../types'; import type { ChatState, Notification, PinnedMessage } from '../../types'; @@ -491,11 +495,26 @@ export const setPollConfig = ( pollConfig, }); -export const setPollStage = ( - pollStage: SetPollStageAction['pollStage'] -): SetPollStageAction => ({ - type: PollsStateActionTypes.SET_POLL_STAGE, - pollStage, +export const pushToNavigationStack = ( + screen: PushToNavigationStackAction['screen'] +): PushToNavigationStackAction => ({ + type: PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK, + screen, +}); + +export const resetNavigationStack = (): ResetNavigationStackAction => ({ + type: PollsStateActionTypes.RESET_NAVIGATION_STACK, +}); + +export const popFromNavigationStack = (): PopFromNavigationStackAction => ({ + type: PollsStateActionTypes.POP_FROM_NAVIGATION_STACK, +}); + +export const replaceTopOfNavigationStack = ( + screen: ReplaceTopOfNavigationStackAction['screen'] +): ReplaceTopOfNavigationStackAction => ({ + type: PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK, + screen, }); export const addPollQuestion = (): AddPollQuestionAction => ({ @@ -672,3 +691,12 @@ export const addCuedPollId = (pollId: string) => ({ type: PollsStateActionTypes.ADD_CUED_POLL_ID, pollId, }); + +export const addLeaderboard = ( + pollId: AddLeaderboardAction['pollId'], + leaderboard: AddLeaderboardAction['leaderboard'] +): AddLeaderboardAction => ({ + type: PollsStateActionTypes.ADD_LEADERBOARD, + pollId, + leaderboard, +}); diff --git a/packages/react-native-room-kit/src/redux/reducers/polls.ts b/packages/react-native-room-kit/src/redux/reducers/polls.ts index 3daedf71d..d34a1fd55 100644 --- a/packages/react-native-room-kit/src/redux/reducers/polls.ts +++ b/packages/react-native-room-kit/src/redux/reducers/polls.ts @@ -1,5 +1,8 @@ import { HMSPollQuestionType, HMSPollType } from '@100mslive/react-native-hms'; -import type { HMSPoll } from '@100mslive/react-native-hms'; +import type { + HMSPoll, + PollLeaderboardResponse, +} from '@100mslive/react-native-hms'; import { PollsStateActionTypes, @@ -30,7 +33,7 @@ function getDefaultQuestionObj(): PollQuestionUI { type IntialStateType = { pollName: string; pollConfig: PollConfig; - stage: CreatePollStages; + navigationStack: CreatePollStages[]; questions: PollQuestionUI[]; deleteConfirmationVisible: boolean; selectedPollQuestionIndex: number | null; @@ -39,6 +42,7 @@ type IntialStateType = { cuedPollIds: HMSPoll['pollId'][]; // In case of HLSViewer, pollIds should be aligned with onCue event polls: Record; pollsResponses: Record>; + leaderboards: Record; }; const INITIAL_STATE: IntialStateType = { @@ -48,7 +52,7 @@ const INITIAL_STATE: IntialStateType = { voteCountHidden: false, resultsAnonymous: false, }, - stage: CreatePollStages.POLL_CONFIG, + navigationStack: [CreatePollStages.POLL_CONFIG], questions: [getDefaultQuestionObj()], deleteConfirmationVisible: false, selectedPollQuestionIndex: null, @@ -57,6 +61,7 @@ const INITIAL_STATE: IntialStateType = { cuedPollIds: [], polls: {}, pollsResponses: {}, + leaderboards: {}, }; const hmsStatesReducer = ( @@ -87,11 +92,30 @@ const hmsStatesReducer = ( : state.questions, selectedPollQuestionIndex: null, }; - case PollsStateActionTypes.SET_POLL_STAGE: + case PollsStateActionTypes.PUSH_TO_NAVIGATION_STACK: return { ...state, - stage: action.pollStage, - selectedPollQuestionIndex: null, + navigationStack: [...state.navigationStack, action.screen], + }; + case PollsStateActionTypes.RESET_NAVIGATION_STACK: + return { + ...state, + navigationStack: INITIAL_STATE.navigationStack, + }; + case PollsStateActionTypes.POP_FROM_NAVIGATION_STACK: { + const updatedNavigationStack = [...state.navigationStack]; + updatedNavigationStack.pop(); + return { + ...state, + navigationStack: updatedNavigationStack, + }; + } + case PollsStateActionTypes.REPLACE_TOP_OF_NAVIGATION_STACK: + const updatedNavigationStack = [...state.navigationStack]; + updatedNavigationStack[updatedNavigationStack.length - 1] = action.screen; + return { + ...state, + navigationStack: updatedNavigationStack, }; case PollsStateActionTypes.ADD_POLL_QUESTION: return { @@ -286,6 +310,51 @@ const hmsStatesReducer = ( selectedPollId: action.pollId, }; case PollsStateActionTypes.ADD_POLL: + const prevPoll = state.polls[action.poll.pollId]; + + // Hack: Restore previous state of poll if current poll has missing myResponses and voteCount + if ( + prevPoll && + Array.isArray(prevPoll.questions) && + prevPoll.questions.length > 0 + ) { + action.poll.questions?.forEach((question) => { + const prevQuestion = prevPoll.questions?.find( + (prevQuestion) => prevQuestion.index === question.index + ); + + //#region Restore previous responses on question if current question has no responses + const prevResponsesOnQuestion = prevQuestion?.myResponses; + if ( + Array.isArray(prevResponsesOnQuestion) && + prevResponsesOnQuestion.length > 0 && + (!question.myResponses || question.myResponses.length <= 0) + ) { + question.myResponses = prevResponsesOnQuestion; + } + //#endregion + + //#region Restore previous voteCount on question options if current question options has no voteCount + const prevOptions = prevQuestion?.options; + + question.options?.forEach((option) => { + const prevOption = prevOptions?.find( + (prevOption) => prevOption.index === option.index + ); + + // Edge Case: User changes response on question, due to which new vountCount becomes 0, and we are treating as invalid value + if ( + option.voteCount <= 0 && + prevOption && + prevOption?.voteCount > 0 + ) { + option.voteCount = prevOption.voteCount; + } + }); + //#endregion + }); + } + return { ...state, polls: { @@ -360,6 +429,15 @@ const hmsStatesReducer = ( cuedPollIds: [...state.cuedPollIds, action.pollId], }; } + case PollsStateActionTypes.ADD_LEADERBOARD: { + return { + ...state, + leaderboards: { + ...state.leaderboards, + [action.pollId]: action.leaderboard, + }, + }; + } case PollsStateActionTypes.CLEAR_POLL_FORM_STATE: { return { ...INITIAL_STATE, diff --git a/packages/react-native-room-kit/src/utils/hooks.ts b/packages/react-native-room-kit/src/utils/hooks.ts index 0333da1ea..48ea7f436 100644 --- a/packages/react-native-room-kit/src/utils/hooks.ts +++ b/packages/react-native-room-kit/src/utils/hooks.ts @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { HMSLocalAudioStats, @@ -13,10 +13,12 @@ import { HMSTrackSource, HMSUpdateListenerActions, } from '@100mslive/react-native-hms'; +import type { HMSPoll } from '@100mslive/react-native-hms'; -import type { RootState } from '../redux'; -import { setRTCStats } from '../redux/actions'; import { ModalTypes } from './types'; +import type { RootState } from '../redux'; +import { addLeaderboard, setRTCStats } from '../redux/actions'; +import { useHMSInstance } from '../hooks-util'; export const useRTCStatsListeners = () => { const dispatch = useDispatch(); @@ -102,3 +104,188 @@ export const useRTCStatsListeners = () => { } }, [hmsInstance, addListeners]); }; + +export const useFetchLeaderboardResponse = ( + pollId: HMSPoll['pollId'] | undefined +) => { + const dispatch = useDispatch(); + const hmsInstance = useHMSInstance(); + + const hasPollWritePermission = useSelector((state: RootState) => { + const permissions = state.hmsStates.localPeer?.role?.permissions; + return permissions?.pollWrite; + }); + + const leaderboardData = useSelector((state: RootState) => { + if (!pollId) return null; + return state.polls.leaderboards[pollId] || null; + }); + + const leaderboardDataExist = !!leaderboardData; + + useEffect(() => { + if (!!leaderboardData) return; + + let mounted = true; + + async function fetchLeaderboard() { + if (pollId) { + const response = await hmsInstance.interactivityCenter.fetchLeaderboard( + pollId, + 5, + 1, // Indexing starts from 1 + !hasPollWritePermission // fetchCurrentUser only if user has only pollRead permission + ); + if (mounted) { + dispatch(addLeaderboard(pollId, response)); + } + } + } + fetchLeaderboard(); + + return () => { + mounted = false; + }; + }, [pollId, leaderboardDataExist, hasPollWritePermission]); + + return leaderboardData; +}; + +export const useLeaderboardSummaryData = ( + pollId: HMSPoll['pollId'] | undefined +): { label: string; value: any }[][] | null => { + const localPeerUserId = useSelector( + (state: RootState) => state.hmsStates.localPeer?.customerUserID + ); + const localPeerPollInitiator = useSelector((state: RootState) => { + if (!pollId) return null; + const pollInitiatorUserID = + state.polls.polls[pollId]?.createdBy?.customerUserID; + return ( + localPeerUserId && + pollInitiatorUserID && + localPeerUserId === pollInitiatorUserID + ); + }); + const canCreateOrEndPoll = useSelector((state: RootState) => { + const permissions = state.hmsStates.localPeer?.role?.permissions; + return permissions?.pollWrite; + }); + + const leaderboardData = useSelector((state: RootState) => { + if (!pollId) return null; + return state.polls.leaderboards[pollId] || null; + }); + const pollQuestionsLength = useSelector((state: RootState) => { + if (!pollId) return null; + return state.polls.polls[pollId]?.questions?.length; + }); + const leaderboardSummary = leaderboardData?.summary; + + const pollInitiatorSummaryData = useMemo(() => { + if (!localPeerPollInitiator) { + return null; + } + return [ + [ + { + label: 'ANSWERED', + value: + leaderboardSummary && + typeof leaderboardSummary.respondedPeersCount === 'number' && + typeof leaderboardSummary.totalPeersCount === 'number' + ? `${Math.round((leaderboardSummary.respondedPeersCount / leaderboardSummary.totalPeersCount) * 100)}% (${leaderboardSummary.respondedPeersCount}/${leaderboardSummary.totalPeersCount})` + : '-', + }, + { + label: 'CORRECT ANSWERS', + value: + leaderboardSummary && + typeof leaderboardSummary.respondedCorrectlyPeersCount === + 'number' && + typeof leaderboardSummary.totalPeersCount === 'number' + ? `${Math.round((leaderboardSummary.respondedCorrectlyPeersCount / leaderboardSummary?.totalPeersCount) * 100)}% (${leaderboardSummary.respondedCorrectlyPeersCount}/${leaderboardSummary.totalPeersCount})` + : '-', + }, + ], + [ + { + label: 'AVG. TIME TAKEN', + value: + leaderboardSummary && + typeof leaderboardSummary.averageTime === 'number' + ? `${(leaderboardSummary.averageTime / 1000).toFixed(2)}s` + : '-', // averageTime is in milliseconds + }, + { + label: 'AVG. SCORE', + value: + leaderboardSummary && + typeof leaderboardSummary.averageScore === 'number' + ? leaderboardSummary.averageScore.toFixed(2) + : '-', + }, + ], + ]; + }, [leaderboardSummary, localPeerPollInitiator]); + + const localLeaderboardEntry = + localPeerUserId && leaderboardData && Array.isArray(leaderboardData.entries) + ? leaderboardData.entries.find( + (entry) => entry.peer?.customerUserId === localPeerUserId + ) + : null; + + const voterSummaryData = useMemo(() => { + if (!localLeaderboardEntry || canCreateOrEndPoll) { + return null; + } + return [ + [ + { + label: 'YOUR RANK', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.totalResponses === 'number' && + leaderboardSummary && + typeof leaderboardSummary.totalPeersCount === 'number' + ? `${localLeaderboardEntry.position}/${leaderboardSummary.totalPeersCount}` + : '-', + }, + { + label: 'CORRECT ANSWERS', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.correctResponses === 'number' && + typeof pollQuestionsLength === 'number' + ? `${Math.round((localLeaderboardEntry.correctResponses / pollQuestionsLength) * 100)}% (${localLeaderboardEntry.correctResponses}/${pollQuestionsLength})` + : '-', + }, + ], + [ + { + label: 'TIME TAKEN', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.duration === 'number' + ? `${(localLeaderboardEntry.duration / 1000).toFixed(2)}s` + : '-', + }, + { + label: 'YOUR POINTS', + value: + localLeaderboardEntry && + typeof localLeaderboardEntry.score === 'number' + ? localLeaderboardEntry.score + : '-', + }, + ], + ]; + }, [localLeaderboardEntry, leaderboardSummary?.totalPeersCount]); + + return localPeerPollInitiator + ? pollInitiatorSummaryData + : voterSummaryData + ? voterSummaryData + : null; +}; From 254b8e10c669d6e3568e4d2455fcf649002a1e3c Mon Sep 17 00:00:00 2001 From: Yogesh Singh Date: Tue, 5 Mar 2024 13:41:58 +0530 Subject: [PATCH 12/14] resolved lint warnings --- .../example/src/redux/reducers/appState.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-native-room-kit/example/src/redux/reducers/appState.ts b/packages/react-native-room-kit/example/src/redux/reducers/appState.ts index 2f196768f..1ec46a88b 100644 --- a/packages/react-native-room-kit/example/src/redux/reducers/appState.ts +++ b/packages/react-native-room-kit/example/src/redux/reducers/appState.ts @@ -1,8 +1,7 @@ -import {getMeetingUrl} from '../../utils/functions'; import ActionTypes from '../actionTypes'; type ActionType = { - payload: {[key: string]: any}; + payload: { [key: string]: any }; type: String; }; @@ -40,7 +39,7 @@ const INITIAL_STATE: InitialStateType = { const appReducer = ( state = INITIAL_STATE, - action: ActionType, + action: ActionType ): InitialStateType => { switch (action.type) { case ActionTypes.RESET_JOIN_CONFIG: From 70a85e778b7a8e42755d99e519a7a34c4c0c3a6e Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Tue, 5 Mar 2024 19:17:22 +0530 Subject: [PATCH 13/14] refactor(sdk): added return type in `sendHLSTimedMetadata` method --- packages/react-native-hms/src/classes/HMSSDK.tsx | 4 +++- packages/react-native-room-kit/src/HMSRoomSetup.tsx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-native-hms/src/classes/HMSSDK.tsx b/packages/react-native-hms/src/classes/HMSSDK.tsx index e735e3835..5316c65b0 100644 --- a/packages/react-native-hms/src/classes/HMSSDK.tsx +++ b/packages/react-native-hms/src/classes/HMSSDK.tsx @@ -436,7 +436,9 @@ export class HMSSDK { * @param metadata list of {@link HMSHLSTimedMetadata} to be sent * @returns Promise */ - sendHLSTimedMetadata = async (metadata: HMSHLSTimedMetadata[]) => { + sendHLSTimedMetadata = async ( + metadata: HMSHLSTimedMetadata[] + ): Promise => { const data = { metadata, id: this.id }; logger?.verbose('#Function sendHLSTimedMetadata', data); return await HMSManager.sendHLSTimedMetadata(data); diff --git a/packages/react-native-room-kit/src/HMSRoomSetup.tsx b/packages/react-native-room-kit/src/HMSRoomSetup.tsx index 48907887a..3ab56ae43 100644 --- a/packages/react-native-room-kit/src/HMSRoomSetup.tsx +++ b/packages/react-native-room-kit/src/HMSRoomSetup.tsx @@ -419,7 +419,7 @@ export const HMSRoomSetup = () => { .then((result) => { console.log('sendHLSTimedMetadata result: ', result); }) - .catch((error) => { + .catch((error: any) => { console.log('sendHLSTimedMetadata error: ', error); }); } From d80b480f6d91492bbdf472ff7303240492cee1db Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Tue, 5 Mar 2024 19:46:57 +0530 Subject: [PATCH 14/14] updated peerDependency version --- packages/react-native-room-kit/package-lock.json | 14 +++++++------- packages/react-native-room-kit/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-native-room-kit/package-lock.json b/packages/react-native-room-kit/package-lock.json index ae9bdfcdd..3e68fc1b5 100644 --- a/packages/react-native-room-kit/package-lock.json +++ b/packages/react-native-room-kit/package-lock.json @@ -40,7 +40,7 @@ "node": ">= 16.0.0" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.9.12", + "@100mslive/react-native-hms": "1.10.0", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3", @@ -56,9 +56,9 @@ } }, "node_modules/@100mslive/react-native-hms": { - "version": "1.9.12", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.12.tgz", - "integrity": "sha512-eDrgjZkmk6jge4hJq77aOs1RvxKPGvCMbbRctqq6KAEZGNrsp1/GfXEbO+niqPfBZGMoeZSsb4IyZF/sjrm8Rg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.0.tgz", + "integrity": "sha512-Bb7PWTDNJPpRjgZCT7w6kzsfTnK+Js3Pu6VLJQNtYa5IRVHxuHhRdgY07oysX15nRadlUGWoqQkpCRFHKnahQQ==", "peer": true, "dependencies": { "zustand": "^4.3.8" @@ -22220,9 +22220,9 @@ }, "dependencies": { "@100mslive/react-native-hms": { - "version": "1.9.12", - "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.9.12.tgz", - "integrity": "sha512-eDrgjZkmk6jge4hJq77aOs1RvxKPGvCMbbRctqq6KAEZGNrsp1/GfXEbO+niqPfBZGMoeZSsb4IyZF/sjrm8Rg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@100mslive/react-native-hms/-/react-native-hms-1.10.0.tgz", + "integrity": "sha512-Bb7PWTDNJPpRjgZCT7w6kzsfTnK+Js3Pu6VLJQNtYa5IRVHxuHhRdgY07oysX15nRadlUGWoqQkpCRFHKnahQQ==", "peer": true, "requires": { "zustand": "^4.3.8" diff --git a/packages/react-native-room-kit/package.json b/packages/react-native-room-kit/package.json index a8f23ead8..00d6ef3d7 100644 --- a/packages/react-native-room-kit/package.json +++ b/packages/react-native-room-kit/package.json @@ -79,7 +79,7 @@ "typescript": "^5.0.2" }, "peerDependencies": { - "@100mslive/react-native-hms": "1.9.12", + "@100mslive/react-native-hms": "1.10.0", "@react-native-community/blur": "^4.3.2", "@react-native-masked-view/masked-view": "^0.2.9", "@shopify/flash-list": "^1.4.3",