@fishjam-cloud/react-native-client 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +7 -6
- package/android/build.gradle +3 -3
- package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +25 -12
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +50 -33
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +7 -16
- package/android/src/main/java/io/fishjam/reactnative/VideoPreviewView.kt +13 -3
- package/build/RNFishjamClientModule.d.ts +10 -8
- package/build/RNFishjamClientModule.d.ts.map +1 -1
- package/build/RNFishjamClientModule.js.map +1 -1
- package/build/common/client.d.ts +3 -3
- package/build/common/client.d.ts.map +1 -1
- package/build/common/client.js +4 -4
- package/build/common/client.js.map +1 -1
- package/build/common/metadata.d.ts +3 -3
- package/build/common/metadata.d.ts.map +1 -1
- package/build/common/metadata.js +4 -4
- package/build/common/metadata.js.map +1 -1
- package/build/common/webRTC.d.ts +0 -8
- package/build/common/webRTC.d.ts.map +1 -1
- package/build/common/webRTC.js +0 -9
- package/build/common/webRTC.js.map +1 -1
- package/build/components/VideoRendererView.d.ts +1 -1
- package/build/components/VideoRendererView.js +1 -1
- package/build/components/VideoRendererView.js.map +1 -1
- package/build/debug/common/webRTC.d.ts +9 -0
- package/build/debug/common/webRTC.d.ts.map +1 -0
- package/build/debug/common/webRTC.js +11 -0
- package/build/debug/common/webRTC.js.map +1 -0
- package/build/debug/index.d.ts +4 -0
- package/build/debug/index.d.ts.map +1 -0
- package/build/debug/index.js +3 -0
- package/build/debug/index.js.map +1 -0
- package/build/debug/stats/types.d.ts.map +1 -0
- package/build/debug/stats/types.js.map +1 -0
- package/build/debug/stats/useRTCStatistics.d.ts.map +1 -0
- package/build/{stats → debug/stats}/useRTCStatistics.js +1 -1
- package/build/debug/stats/useRTCStatistics.js.map +1 -0
- package/build/hooks/useFishjamEvent.d.ts +1 -0
- package/build/hooks/useFishjamEvent.d.ts.map +1 -1
- package/build/hooks/useFishjamEvent.js +1 -0
- package/build/hooks/useFishjamEvent.js.map +1 -1
- package/build/hooks/usePeerStatus.d.ts +19 -0
- package/build/hooks/usePeerStatus.d.ts.map +1 -0
- package/build/hooks/usePeerStatus.js +18 -0
- package/build/hooks/usePeerStatus.js.map +1 -0
- package/build/hooks/{useParticipants.d.ts → usePeers.d.ts} +11 -11
- package/build/hooks/usePeers.d.ts.map +1 -0
- package/build/hooks/usePeers.js +34 -0
- package/build/hooks/usePeers.js.map +1 -0
- package/build/index.d.ts +5 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/debug/package.json +4 -0
- package/ios/Events.swift +29 -13
- package/ios/RNFishjamClient.podspec +1 -1
- package/ios/RNFishjamClient.swift +58 -55
- package/ios/RNFishjamClientModule.swift +7 -15
- package/ios/VideoPreviewView.swift +27 -9
- package/package.json +4 -3
- package/plugin/build/withFishjamIos.js +2 -2
- package/build/hooks/useParticipants.d.ts.map +0 -1
- package/build/hooks/useParticipants.js +0 -34
- package/build/hooks/useParticipants.js.map +0 -1
- package/build/stats/types.d.ts.map +0 -1
- package/build/stats/types.js.map +0 -1
- package/build/stats/useRTCStatistics.d.ts.map +0 -1
- package/build/stats/useRTCStatistics.js.map +0 -1
- /package/build/{stats → debug/stats}/types.d.ts +0 -0
- /package/build/{stats → debug/stats}/types.js +0 -0
- /package/build/{stats → debug/stats}/useRTCStatistics.d.ts +0 -0
package/ios/Events.swift
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
enum PeerStatus: String {
|
|
2
|
+
case connecting
|
|
3
|
+
case connected
|
|
4
|
+
case error
|
|
5
|
+
case idle
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
enum EmitableEvents: String, CaseIterable {
|
|
9
|
+
case IsCameraOn
|
|
10
|
+
case IsMicrophoneOn
|
|
11
|
+
case IsScreenShareOn
|
|
12
|
+
case SimulcastConfigUpdate
|
|
13
|
+
case PeersUpdate
|
|
14
|
+
case AudioDeviceUpdate
|
|
15
|
+
case SendMediaEvent
|
|
16
|
+
case BandwidthEstimation
|
|
17
|
+
case ReconnectionRetriesLimitReached
|
|
18
|
+
case ReconnectionStarted
|
|
19
|
+
case Reconnected
|
|
20
|
+
case Warning
|
|
21
|
+
case PeerStatusChanged
|
|
22
|
+
|
|
23
|
+
var name: String {
|
|
24
|
+
rawValue
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static var allEvents: [String] {
|
|
28
|
+
EmitableEvents.allCases.map(\.name)
|
|
29
|
+
}
|
|
14
30
|
}
|
|
@@ -28,9 +28,17 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
28
28
|
var audioSessionMode: AVAudioSession.Mode = AVAudioSession.Mode.videoChat
|
|
29
29
|
var errorMessage: String?
|
|
30
30
|
|
|
31
|
+
private(set) var peerStatus: PeerStatus = .idle {
|
|
32
|
+
didSet {
|
|
33
|
+
let event = EmitableEvents.PeerStatusChanged
|
|
34
|
+
emit(event: event, data: [event.name: peerStatus.rawValue])
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
let sendEvent: (_ eventName: String, _ data: [String: Any]) -> Void
|
|
32
39
|
|
|
33
40
|
static var onTracksUpdateListeners: [OnTrackUpdateListener] = []
|
|
41
|
+
static var localCameraTrackListeners: [OnLocalCameraTrackChangedListener] = []
|
|
34
42
|
|
|
35
43
|
init(sendEvent: @escaping (_ eventName: String, _ data: [String: Any]) -> Void) {
|
|
36
44
|
self.sendEvent = sendEvent
|
|
@@ -172,18 +180,16 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
172
180
|
connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error")
|
|
173
181
|
}
|
|
174
182
|
connectPromise = nil
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
func onAuthSuccess() {
|
|
178
|
-
join()
|
|
183
|
+
peerStatus = .error
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
func joinRoom(
|
|
182
|
-
url: String,
|
|
187
|
+
url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
|
|
183
188
|
promise: Promise
|
|
184
189
|
) {
|
|
190
|
+
peerStatus = .connecting
|
|
185
191
|
connectPromise = promise
|
|
186
|
-
localUserMetadata =
|
|
192
|
+
localUserMetadata = peerMetadata.toMetadata()
|
|
187
193
|
|
|
188
194
|
let reconnectConfig = FishjamCloudClient.ReconnectConfig(
|
|
189
195
|
maxAttempts: config.reconnectConfig.maxAttempts, initialDelayMs: config.reconnectConfig.initialDelayMs,
|
|
@@ -191,16 +197,12 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
191
197
|
|
|
192
198
|
RNFishjamClient.fishjamClient?.connect(
|
|
193
199
|
config: FishjamCloudClient.ConnectConfig(
|
|
194
|
-
websocketUrl: url, token:
|
|
200
|
+
websocketUrl: url, token: peerToken, peerMetadata: .init(peerMetadata),
|
|
195
201
|
reconnectConfig: reconnectConfig
|
|
196
202
|
))
|
|
197
203
|
|
|
198
204
|
}
|
|
199
205
|
|
|
200
|
-
func join() {
|
|
201
|
-
RNFishjamClient.fishjamClient?.join(peerMetadata: localUserMetadata)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
206
|
func leaveRoom() {
|
|
205
207
|
if isScreenShareOn {
|
|
206
208
|
let screenShareExtensionBundleId =
|
|
@@ -214,7 +216,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
214
216
|
isScreenShareOn = false
|
|
215
217
|
isConnected = false
|
|
216
218
|
isCameraInitialized = false
|
|
217
|
-
RNFishjamClient.fishjamClient?.leave
|
|
219
|
+
RNFishjamClient.fishjamClient?.leave { [weak self] in
|
|
220
|
+
self?.emitEndpoints()
|
|
221
|
+
}
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
func startCamera(config: CameraConfig) throws {
|
|
@@ -245,9 +249,10 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
245
249
|
private func setCameraTrackState(_ cameraTrack: LocalVideoTrack, enabled: Bool) {
|
|
246
250
|
cameraTrack.enabled = enabled
|
|
247
251
|
isCameraOn = enabled
|
|
248
|
-
let
|
|
249
|
-
let isCameraEnabledMap = [
|
|
250
|
-
|
|
252
|
+
let event = EmitableEvents.IsCameraOn
|
|
253
|
+
let isCameraEnabledMap = [event.name: enabled]
|
|
254
|
+
emit(event: event, data: isCameraEnabledMap)
|
|
255
|
+
RNFishjamClient.localCameraTrackListeners.forEach { $0.onLocalCameraTrackChanged() }
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
func toggleCamera() throws -> Bool {
|
|
@@ -277,8 +282,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
277
282
|
}
|
|
278
283
|
|
|
279
284
|
func startMicrophone() throws {
|
|
280
|
-
let microphoneTrack = RNFishjamClient.fishjamClient!.createAudioTrack(
|
|
281
|
-
metadata: Metadata())
|
|
285
|
+
let microphoneTrack = RNFishjamClient.fishjamClient!.createAudioTrack(metadata: Metadata())
|
|
282
286
|
setAudioSessionMode()
|
|
283
287
|
setMicrophoneTrackState(microphoneTrack, enabled: true)
|
|
284
288
|
emitEndpoints()
|
|
@@ -287,10 +291,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
287
291
|
private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, enabled: Bool) {
|
|
288
292
|
microphoneTrack.enabled = enabled
|
|
289
293
|
isMicrophoneOn = enabled
|
|
290
|
-
let
|
|
291
|
-
let isMicrophoneOnMap = [
|
|
292
|
-
|
|
293
|
-
emitEvent(name: eventName, data: isMicrophoneOnMap)
|
|
294
|
+
let event = EmitableEvents.IsMicrophoneOn
|
|
295
|
+
let isMicrophoneOnMap = [event.name: enabled]
|
|
296
|
+
emit(event: event, data: isMicrophoneOnMap)
|
|
294
297
|
}
|
|
295
298
|
|
|
296
299
|
func setAudioSessionMode() {
|
|
@@ -343,16 +346,15 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
343
346
|
maxBandwidth: screenShareOptions.maxBandwidth)
|
|
344
347
|
let screenShareMetadata = screenShareOptions.screenShareMetadata.toMetadata()
|
|
345
348
|
let videoParameters = getScreenShareVideoParameters(options: screenShareOptions)
|
|
346
|
-
RNFishjamClient.fishjamClient!.
|
|
349
|
+
RNFishjamClient.fishjamClient!.prepareForScreenSharing(
|
|
347
350
|
appGroup: appGroupName,
|
|
348
351
|
videoParameters: videoParameters,
|
|
349
352
|
metadata: screenShareMetadata,
|
|
350
|
-
onStart: { [weak self]
|
|
351
|
-
guard let self
|
|
353
|
+
onStart: { [weak self] in
|
|
354
|
+
guard let self else { return }
|
|
352
355
|
|
|
353
356
|
do {
|
|
354
|
-
|
|
355
|
-
try setScreenShareTrackState(screenShareTrack, enabled: true)
|
|
357
|
+
try setScreenShareTrackState(enabled: true)
|
|
356
358
|
} catch {
|
|
357
359
|
os_log(
|
|
358
360
|
"Error starting screen share: %{public}s", log: log, type: .error,
|
|
@@ -361,11 +363,10 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
361
363
|
}
|
|
362
364
|
|
|
363
365
|
},
|
|
364
|
-
onStop: { [weak self]
|
|
365
|
-
guard let self
|
|
366
|
+
onStop: { [weak self] in
|
|
367
|
+
guard let self else { return }
|
|
366
368
|
do {
|
|
367
|
-
|
|
368
|
-
try setScreenShareTrackState(screenShareTrack, enabled: false)
|
|
369
|
+
try setScreenShareTrackState(enabled: false)
|
|
369
370
|
} catch {
|
|
370
371
|
os_log(
|
|
371
372
|
"Error stopping screen share: %{public}s", log: log, type: .error,
|
|
@@ -379,13 +380,11 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
379
380
|
}
|
|
380
381
|
}
|
|
381
382
|
|
|
382
|
-
private func setScreenShareTrackState(
|
|
383
|
-
//was not present before, test and maybe delete?
|
|
384
|
-
screenShareTrack.enabled = enabled
|
|
383
|
+
private func setScreenShareTrackState(enabled: Bool) throws {
|
|
385
384
|
isScreenShareOn = enabled
|
|
386
|
-
let
|
|
387
|
-
let isScreenShareEnabled = [
|
|
388
|
-
|
|
385
|
+
let event = EmitableEvents.IsScreenShareOn
|
|
386
|
+
let isScreenShareEnabled = [event.name: enabled]
|
|
387
|
+
emit(event: event, data: isScreenShareEnabled)
|
|
389
388
|
}
|
|
390
389
|
|
|
391
390
|
//returns local endpoint and remote endpoints
|
|
@@ -402,7 +401,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
402
401
|
"id": endpoint.id,
|
|
403
402
|
"isLocal": endpoint.id == RNFishjamClient.fishjamClient!.getLocalEndpoint().id,
|
|
404
403
|
"type": endpoint.type,
|
|
405
|
-
"metadata": endpoint.metadata,
|
|
404
|
+
"metadata": endpoint.metadata.toDict(),
|
|
406
405
|
"tracks": endpoint.tracks.values.compactMap { track -> [String: Any?]? in
|
|
407
406
|
switch track {
|
|
408
407
|
case let track as RemoteVideoTrack:
|
|
@@ -556,9 +555,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
556
555
|
videoSimulcastConfig = try toggleTrackEncoding(
|
|
557
556
|
encoding: encoding, trackId: track.id, simulcastConfig: videoSimulcastConfig)
|
|
558
557
|
|
|
559
|
-
let
|
|
558
|
+
let event = EmitableEvents.SimulcastConfigUpdate
|
|
560
559
|
let simulcastConfigAsRNMap = getSimulcastConfigAsRNMap(videoSimulcastConfig)
|
|
561
|
-
|
|
560
|
+
emit(event: event, data: simulcastConfigAsRNMap)
|
|
562
561
|
|
|
563
562
|
return simulcastConfigAsRNMap
|
|
564
563
|
}
|
|
@@ -673,18 +672,18 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
673
672
|
)
|
|
674
673
|
}
|
|
675
674
|
|
|
676
|
-
func
|
|
677
|
-
sendEvent(name, data)
|
|
675
|
+
func emit(event: EmitableEvents, data: [String: Any] = [:]) {
|
|
676
|
+
sendEvent(event.name, data)
|
|
678
677
|
}
|
|
679
678
|
|
|
680
679
|
func emit(warning: String) {
|
|
681
|
-
|
|
680
|
+
emit(event: .Warning, data: ["message": warning])
|
|
682
681
|
}
|
|
683
682
|
|
|
684
683
|
func emitEndpoints() {
|
|
685
|
-
let
|
|
686
|
-
let EndpointsUpdateMap = [
|
|
687
|
-
|
|
684
|
+
let event = EmitableEvents.PeersUpdate
|
|
685
|
+
let EndpointsUpdateMap = [event.name: (try? getPeers()) ?? []]
|
|
686
|
+
emit(event: event, data: EndpointsUpdateMap)
|
|
688
687
|
}
|
|
689
688
|
|
|
690
689
|
func onJoined(peerID: String, peersInRoom: [String: Endpoint]) {
|
|
@@ -692,6 +691,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
692
691
|
connectPromise?.resolve(nil)
|
|
693
692
|
connectPromise = nil
|
|
694
693
|
emitEndpoints()
|
|
694
|
+
peerStatus = .connected
|
|
695
695
|
}
|
|
696
696
|
|
|
697
697
|
func onJoinError(metadata: Any) {
|
|
@@ -753,6 +753,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
753
753
|
"E_MEMBRANE_CONNECT", "Failed to connect: socket close, code: \(code), reason: \(reason)")
|
|
754
754
|
}
|
|
755
755
|
connectPromise = nil
|
|
756
|
+
peerStatus = .error
|
|
756
757
|
}
|
|
757
758
|
|
|
758
759
|
func onSocketError() {
|
|
@@ -764,7 +765,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
764
765
|
|
|
765
766
|
func onSocketOpen() {}
|
|
766
767
|
|
|
767
|
-
func onDisconnected() {
|
|
768
|
+
func onDisconnected() {
|
|
769
|
+
peerStatus = .idle
|
|
770
|
+
}
|
|
768
771
|
|
|
769
772
|
func getSimulcastConfigAsRNMap(_ simulcastConfig: SimulcastConfig) -> [String: Any] {
|
|
770
773
|
return [
|
|
@@ -826,11 +829,11 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
826
829
|
default:
|
|
827
830
|
deviceTypeString = deviceType.rawValue
|
|
828
831
|
}
|
|
829
|
-
let
|
|
830
|
-
|
|
831
|
-
|
|
832
|
+
let event = EmitableEvents.AudioDeviceUpdate
|
|
833
|
+
emit(
|
|
834
|
+
event: event,
|
|
832
835
|
data: [
|
|
833
|
-
|
|
836
|
+
event.name: [
|
|
834
837
|
"selectedDevice": ["name": output.portName, "type": deviceTypeString],
|
|
835
838
|
"availableDevices": [],
|
|
836
839
|
]
|
|
@@ -838,20 +841,20 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
838
841
|
}
|
|
839
842
|
|
|
840
843
|
func onBandwidthEstimationChanged(estimation: Int) {
|
|
841
|
-
let
|
|
842
|
-
|
|
844
|
+
let event = EmitableEvents.BandwidthEstimation
|
|
845
|
+
emit(event: event, data: [event.name: estimation])
|
|
843
846
|
}
|
|
844
847
|
|
|
845
848
|
func onReconnectionStarted() {
|
|
846
|
-
|
|
849
|
+
emit(event: .ReconnectionStarted)
|
|
847
850
|
}
|
|
848
851
|
|
|
849
852
|
func onReconnected() {
|
|
850
|
-
|
|
853
|
+
emit(event: .Reconnected)
|
|
851
854
|
}
|
|
852
855
|
|
|
853
856
|
func onReconnectionRetriesLimitReached() {
|
|
854
|
-
|
|
857
|
+
emit(event: .ReconnectionRetriesLimitReached)
|
|
855
858
|
}
|
|
856
859
|
|
|
857
860
|
}
|
|
@@ -75,19 +75,7 @@ public class RNFishjamClientModule: Module {
|
|
|
75
75
|
public func definition() -> ModuleDefinition {
|
|
76
76
|
Name("RNFishjamClient")
|
|
77
77
|
|
|
78
|
-
Events(
|
|
79
|
-
"IsCameraOn",
|
|
80
|
-
"IsMicrophoneOn",
|
|
81
|
-
"IsScreenShareOn",
|
|
82
|
-
"SimulcastConfigUpdate",
|
|
83
|
-
"PeersUpdate",
|
|
84
|
-
"AudioDeviceUpdate",
|
|
85
|
-
"SendMediaEvent",
|
|
86
|
-
"BandwidthEstimation",
|
|
87
|
-
"ReconnectionRetriesLimitReached",
|
|
88
|
-
"ReconnectionStarted",
|
|
89
|
-
"Reconnected",
|
|
90
|
-
"Warning")
|
|
78
|
+
Events(EmitableEvents.allEvents)
|
|
91
79
|
|
|
92
80
|
let rnFishjamClient: RNFishjamClient = {
|
|
93
81
|
let client = RNFishjamClient {
|
|
@@ -100,11 +88,11 @@ public class RNFishjamClientModule: Module {
|
|
|
100
88
|
|
|
101
89
|
AsyncFunction("joinRoom") {
|
|
102
90
|
(
|
|
103
|
-
url: String,
|
|
91
|
+
url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
|
|
104
92
|
promise: Promise
|
|
105
93
|
) in
|
|
106
94
|
rnFishjamClient.joinRoom(
|
|
107
|
-
url: url,
|
|
95
|
+
url: url, peerToken: peerToken, peerMetadata: peerMetadata, config: config,
|
|
108
96
|
promise: promise)
|
|
109
97
|
}
|
|
110
98
|
|
|
@@ -221,5 +209,9 @@ public class RNFishjamClientModule: Module {
|
|
|
221
209
|
AsyncFunction("startAudioSwitcher") {
|
|
222
210
|
rnFishjamClient.startAudioSwitcher()
|
|
223
211
|
}
|
|
212
|
+
|
|
213
|
+
Property("peerStatus") {
|
|
214
|
+
return rnFishjamClient.peerStatus.rawValue
|
|
215
|
+
}
|
|
224
216
|
}
|
|
225
217
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
import FishjamCloudClient
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
protocol OnLocalCameraTrackChangedListener: AnyObject {
|
|
5
|
+
func onLocalCameraTrackChanged()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class VideoPreviewView: ExpoView, OnLocalCameraTrackChangedListener {
|
|
5
9
|
var videoView: VideoView? = nil
|
|
6
10
|
private var localVideoTrack: LocalVideoTrack? = nil
|
|
7
11
|
|
|
@@ -13,11 +17,9 @@ class VideoPreviewView: ExpoView {
|
|
|
13
17
|
addSubview(videoView!)
|
|
14
18
|
}
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
localVideoTrack?.stop()
|
|
20
|
-
} else {
|
|
20
|
+
private func trySetLocalCameraTrack() {
|
|
21
|
+
DispatchQueue.main.async { [weak self] in
|
|
22
|
+
guard let self else { return }
|
|
21
23
|
guard let tracks = RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks else {
|
|
22
24
|
os_log(
|
|
23
25
|
"Error moving VideoPreviewView: %{public}s", log: log, type: .error,
|
|
@@ -26,12 +28,23 @@ class VideoPreviewView: ExpoView {
|
|
|
26
28
|
return
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
localVideoTrack =
|
|
31
|
+
self.localVideoTrack =
|
|
30
32
|
tracks.first(where: { (key, track) in
|
|
31
33
|
track is LocalVideoTrack
|
|
32
34
|
})?.value as? LocalVideoTrack
|
|
33
|
-
localVideoTrack?.start()
|
|
34
|
-
videoView?.track = localVideoTrack
|
|
35
|
+
self.localVideoTrack?.start()
|
|
36
|
+
self.videoView?.track = self.localVideoTrack
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override func willMove(toSuperview newSuperview: UIView?) {
|
|
41
|
+
super.willMove(toSuperview: newSuperview)
|
|
42
|
+
if newSuperview == nil {
|
|
43
|
+
RNFishjamClient.localCameraTrackListeners.removeAll(where: { $0 === self })
|
|
44
|
+
localVideoTrack?.stop()
|
|
45
|
+
} else {
|
|
46
|
+
RNFishjamClient.localCameraTrackListeners.append(self)
|
|
47
|
+
trySetLocalCameraTrack()
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -61,4 +74,9 @@ class VideoPreviewView: ExpoView {
|
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
76
|
}
|
|
77
|
+
|
|
78
|
+
func onLocalCameraTrackChanged() {
|
|
79
|
+
guard localVideoTrack == nil else { return }
|
|
80
|
+
trySetLocalCameraTrack()
|
|
81
|
+
}
|
|
64
82
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/react-native-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A React Native client for Fishjam Cloud",
|
|
5
5
|
"author": "Fishjam Cloud Team",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@testing-library/react": "^15.0.7",
|
|
48
|
-
"@types/lodash": "^4.17.
|
|
48
|
+
"@types/lodash": "^4.17.9",
|
|
49
49
|
"@types/phoenix": "^1.6.5",
|
|
50
50
|
"@types/promise-fs": "^2.1.2",
|
|
51
|
-
"@types/react": "^18.3.
|
|
51
|
+
"@types/react": "^18.3.9",
|
|
52
52
|
"expo": "^51.0.32",
|
|
53
53
|
"expo-module-scripts": "^3.5.2",
|
|
54
54
|
"expo-modules-core": "^1.12.24",
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"files": [
|
|
83
83
|
"build/**",
|
|
84
|
+
"debug",
|
|
84
85
|
"android/build.gradle",
|
|
85
86
|
"android/src/**",
|
|
86
87
|
"ios/*.swift",
|
|
@@ -106,7 +106,7 @@ const withInfoPlistConstants = (config) => {
|
|
|
106
106
|
};
|
|
107
107
|
/**
|
|
108
108
|
* Updates and copies required extension files.
|
|
109
|
-
* Our extension needs to be properly setup inside the
|
|
109
|
+
* Our extension needs to be properly setup inside the Xcode project. In order to do that we need to copy the files and update the pbxproj.
|
|
110
110
|
*/
|
|
111
111
|
const withFishjamSBE = (config, options) => {
|
|
112
112
|
return (0, config_plugins_1.withXcodeProject)(config, async (props) => {
|
|
@@ -128,7 +128,7 @@ const withFishjamSBE = (config, options) => {
|
|
|
128
128
|
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
|
-
if (xcodeProject.pbxTargetByName(
|
|
131
|
+
if (xcodeProject.pbxTargetByName(SBE_TARGET_NAME)) {
|
|
132
132
|
console.log(`${SBE_TARGET_NAME} already exists in project. Skipping...`);
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useParticipants.d.ts","sourceRoot":"","sources":["../../src/hooks/useParticipants.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAIzE,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7C,KAAK,SAAS,GAAG;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IAEd,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAE/B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;AAC5C;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAE7E,MAAM,MAAM,WAAW,CACrB,mBAAmB,SAAS,eAAe,GAAG,eAAe,IAC3D;IACF;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,QAAQ,EAAE,mBAAmB,CAAC;IAC9B;;OAEG;IACH,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB,CAAC;AAgBF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,mBAAmB,SAAS,eAAe,GAAG,eAAe;;EA0B9D"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import RNFishjamClientModule from '../RNFishjamClientModule';
|
|
3
|
-
import { ReceivableEvents, useFishjamEvent } from './useFishjamEvent';
|
|
4
|
-
function addIsActiveToTracks(participants) {
|
|
5
|
-
return participants.map((participant) => ({
|
|
6
|
-
...participant,
|
|
7
|
-
tracks: participant.tracks.map((track) => ({
|
|
8
|
-
...track,
|
|
9
|
-
isActive: track?.metadata?.active ?? true,
|
|
10
|
-
})),
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* This hook provides live updates of room participants.
|
|
15
|
-
* @returns An array of room participants.
|
|
16
|
-
* @category Connection
|
|
17
|
-
* @group Hooks
|
|
18
|
-
*/
|
|
19
|
-
export function useParticipants() {
|
|
20
|
-
const [participants, setParticipants] = useState([]);
|
|
21
|
-
const updateActiveParticipants = useCallback((participants) => {
|
|
22
|
-
setParticipants(addIsActiveToTracks(participants));
|
|
23
|
-
}, []);
|
|
24
|
-
useFishjamEvent(ReceivableEvents.PeersUpdate, updateActiveParticipants);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
async function updateParticipants() {
|
|
27
|
-
const participants = await RNFishjamClientModule.getPeers();
|
|
28
|
-
setParticipants(addIsActiveToTracks(participants));
|
|
29
|
-
}
|
|
30
|
-
updateParticipants();
|
|
31
|
-
}, []);
|
|
32
|
-
return { participants };
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=useParticipants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useParticipants.js","sourceRoot":"","sources":["../../src/hooks/useParticipants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA8DtE,SAAS,mBAAmB,CAG1B,YAA6D;IAE7D,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACxC,GAAG,WAAW;QACd,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzC,GAAG,KAAK;YACR,QAAQ,EACL,KAAsC,EAAE,QAAQ,EAAE,MAAM,IAAI,IAAI;SACpE,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;AACN,CAAC;AACD;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAG7B,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAE9C,EAAE,CAAC,CAAC;IAEN,MAAM,wBAAwB,GAAG,WAAW,CAC1C,CAAC,YAAgD,EAAE,EAAE;QACnD,eAAe,CAAC,mBAAmB,CAAsB,YAAY,CAAC,CAAC,CAAC;IAC1E,CAAC,EACD,EAAE,CACH,CAAC;IAEF,eAAe,CAAC,gBAAgB,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;IAExE,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,UAAU,kBAAkB;YAC/B,MAAM,YAAY,GAChB,MAAM,qBAAqB,CAAC,QAAQ,EAAuB,CAAC;YAC9D,eAAe,CAAC,mBAAmB,CAAsB,YAAY,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,kBAAkB,EAAE,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,YAAY,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\nimport { GenericMetadata, TrackEncoding, TrackMetadata } from '../types';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\nimport { ReceivableEvents, useFishjamEvent } from './useFishjamEvent';\n\nexport type TrackType = 'Audio' | 'Video';\n\n/**\n * Type describing Voice Activity Detection statuses.\n *\n * speech - voice activity has been detected\n * silence - lack of voice activity has been detected\n */\nexport type VadStatus = 'silence' | 'speech';\n\ntype TrackBase = {\n id: string;\n type: TrackType;\n isActive: boolean;\n};\n\nexport type AudioTrack = TrackBase & {\n type: 'Audio';\n vadStatus: VadStatus | undefined;\n};\n\nexport type VideoTrack = TrackBase & {\n type: 'Video';\n // Encoding that is currently received. Only present for remote tracks.\n encoding: TrackEncoding | null;\n // The reason of currently selected encoding. Only present for remote tracks.\n encodingReason: EncodingReason | null;\n};\n\nexport type Track = VideoTrack | AudioTrack;\n/**\n * Type describing possible reasons of currently selected encoding.\n *\n * - other - the exact reason couldn't be determined\n * - encoding_inactive - previously selected encoding became inactive\n * - low_bandwidth - there is no longer enough bandwidth to maintain previously selected encoding\n */\nexport type EncodingReason = 'other' | 'encoding_inactive' | 'low_bandwidth';\n\nexport type Participant<\n ParticipantMetadata extends GenericMetadata = GenericMetadata,\n> = {\n /**\n * id used to identify a participant\n */\n id: string;\n /**\n * whether the participant is local or remote\n */\n isLocal: boolean;\n /**\n * a map indexed by strings, containing participant metadata from the server\n */\n metadata: ParticipantMetadata;\n /**\n * a list of participants's video and audio tracks\n */\n tracks: Track[];\n};\n\nfunction addIsActiveToTracks<\n ParticipantMetadata extends GenericMetadata = GenericMetadata,\n>(\n participants: ReadonlyArray<Participant<ParticipantMetadata>>,\n): Participant<ParticipantMetadata>[] {\n return participants.map((participant) => ({\n ...participant,\n tracks: participant.tracks.map((track) => ({\n ...track,\n isActive:\n (track as { metadata?: TrackMetadata })?.metadata?.active ?? true,\n })),\n }));\n}\n/**\n * This hook provides live updates of room participants.\n * @returns An array of room participants.\n * @category Connection\n * @group Hooks\n */\nexport function useParticipants<\n ParticipantMetadata extends GenericMetadata = GenericMetadata,\n>() {\n const [participants, setParticipants] = useState<\n Participant<ParticipantMetadata>[]\n >([]);\n\n const updateActiveParticipants = useCallback(\n (participants: Participant<ParticipantMetadata>[]) => {\n setParticipants(addIsActiveToTracks<ParticipantMetadata>(participants));\n },\n [],\n );\n\n useFishjamEvent(ReceivableEvents.PeersUpdate, updateActiveParticipants);\n\n useEffect(() => {\n async function updateParticipants() {\n const participants =\n await RNFishjamClientModule.getPeers<ParticipantMetadata>();\n setParticipants(addIsActiveToTracks<ParticipantMetadata>(participants));\n }\n\n updateParticipants();\n }, []);\n\n return { participants };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stats/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B,EAAE,0BAA0B,CAAC;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC"}
|
package/build/stats/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stats/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A record of the total time, in seconds,\n * that this stream has spent in each quality limitation state.\n * none: The resolution and/or framerate is not limited.\n * bandwidth: The resolution and/or framerate is primarily limited due to\n * congestion cues during bandwidth estimation.\n * Typical, congestion control algorithms use inter-arrival time,\n * round-trip time, packet or other congestion cues to perform bandwidth estimation.\n * cpu: The resolution and/or framerate is primarily limited due to CPU load.\n * other: The resolution and/or framerate is primarily limited\n * for a reason other than the above.\n */\nexport type QualityLimitationDurations = {\n bandwidth: number;\n cpu: number;\n none: number;\n other: number;\n};\n\nexport type RTCOutboundStats = {\n 'kind': string;\n 'rid': string;\n 'bytesSent': number;\n 'targetBitrate': number;\n 'packetsSent': number;\n 'framesEncoded': number;\n 'framesPerSecond': number;\n 'frameWidth': number;\n 'frameHeight': number;\n 'qualityLimitationDurations': QualityLimitationDurations;\n 'bytesSent/s': number;\n 'packetsSent/s': number;\n 'framesEncoded/s': number;\n};\n\nexport type RTCInboundStats = {\n 'kind': number;\n 'jitter': number;\n 'packetsLost': number;\n 'packetsReceived': number;\n 'bytesReceived': number;\n 'framesReceived': number;\n 'frameWidth': number;\n 'frameHeight': number;\n 'framesPerSecond': number;\n 'framesDropped': number;\n 'packetsLost/s': number;\n 'packetsReceived/s': number;\n 'bytesReceived/s': number;\n 'framesReceived/s': number;\n 'framesDropped/s': number;\n};\n\nexport type RTCTrackStats = RTCOutboundStats | RTCInboundStats;\n\nexport type RTCStats = { [key: string]: RTCTrackStats };\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useRTCStatistics.d.ts","sourceRoot":"","sources":["../../src/stats/useRTCStatistics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAqC,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG3E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM;;EAuFvD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useRTCStatistics.js","sourceRoot":"","sources":["../../src/stats/useRTCStatistics.ts"],"names":[],"mappings":"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","sourcesContent":["import { takeRight } from 'lodash';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport type { RTCInboundStats, RTCOutboundStats, RTCStats } from './types';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\n\n/**\n * This hook provides access to current rtc statistics data.\n * @category Debugging\n */\nexport function useRTCStatistics(refreshInterval: number) {\n const MAX_SIZE = 120;\n const [statistics, setStatistics] = useState<RTCStats[]>([]);\n\n // Calculates diff between pervious and current stats,\n // providing end users with a per second metric.\n const processIncomingStats = useCallback(\n (statistics: ReadonlyArray<RTCStats>, stats: Readonly<RTCStats>) => {\n Object.keys(stats).forEach((obj) => {\n if (obj.includes('Inbound')) {\n const rtcStats = stats[obj] as RTCInboundStats;\n\n if (\n statistics.length > 0 &&\n Object.keys(statistics[statistics.length - 1]).includes(obj)\n ) {\n const prevRtcStats = statistics[statistics.length - 1][\n obj\n ] as RTCInboundStats;\n\n rtcStats['packetsLost/s'] =\n rtcStats['packetsLost'] - prevRtcStats['packetsLost'];\n rtcStats['packetsReceived/s'] =\n rtcStats['packetsReceived'] - prevRtcStats['packetsReceived'];\n rtcStats['bytesReceived/s'] =\n rtcStats['bytesReceived'] - prevRtcStats['bytesReceived'];\n rtcStats['framesReceived/s'] =\n rtcStats['framesReceived'] - prevRtcStats['framesReceived'];\n rtcStats['framesDropped/s'] =\n rtcStats['framesDropped'] - prevRtcStats['framesDropped'];\n } else {\n rtcStats['packetsLost/s'] = 0;\n rtcStats['packetsReceived/s'] = 0;\n rtcStats['bytesReceived/s'] = 0;\n rtcStats['framesReceived/s'] = 0;\n rtcStats['framesDropped/s'] = 0;\n }\n return stats;\n }\n // Outbound\n const rtcStats = stats[obj] as RTCOutboundStats;\n\n if (\n statistics.length > 0 &&\n Object.keys(statistics[statistics.length - 1]).includes(obj)\n ) {\n const prevRtcStats = statistics[statistics.length - 1][\n obj\n ] as RTCOutboundStats;\n\n rtcStats['bytesSent/s'] =\n rtcStats['bytesSent'] - prevRtcStats['bytesSent'];\n rtcStats['packetsSent/s'] =\n rtcStats['packetsSent'] - prevRtcStats['packetsSent'];\n rtcStats['framesEncoded/s'] =\n rtcStats['framesEncoded'] - prevRtcStats['framesEncoded'];\n } else {\n rtcStats['bytesSent/s'] = 0;\n rtcStats['packetsSent/s'] = 0;\n rtcStats['framesEncoded/s'] = 0;\n }\n return stats;\n });\n return stats;\n },\n [],\n );\n\n // Gets stats from the native libraries.\n const getStatistics = useCallback(async () => {\n const stats = await RNFishjamClientModule.getStatistics();\n setStatistics((prev) => {\n const newStats = [...prev, processIncomingStats(prev, stats)];\n takeRight(newStats, MAX_SIZE);\n return newStats;\n });\n }, [processIncomingStats]);\n\n useEffect(() => {\n const intervalId = setInterval(getStatistics, refreshInterval);\n return () => {\n clearInterval(intervalId);\n setStatistics([]);\n };\n }, [getStatistics, refreshInterval]);\n\n return { statistics };\n}\n"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|