@fishjam-cloud/react-native-client 0.2.2 → 0.2.3

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.
Files changed (89) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +1 -0
  3. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +13 -0
  4. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +2 -1
  5. package/build/RNFishjamClientModule.d.ts +2 -0
  6. package/build/RNFishjamClientModule.d.ts.map +1 -1
  7. package/build/RNFishjamClientModule.js +2 -1
  8. package/build/RNFishjamClientModule.js.map +1 -1
  9. package/build/common/client.d.ts +4 -1
  10. package/build/common/client.d.ts.map +1 -1
  11. package/build/common/client.js +4 -1
  12. package/build/common/client.js.map +1 -1
  13. package/build/common/metadata.d.ts +1 -0
  14. package/build/common/metadata.d.ts.map +1 -1
  15. package/build/common/metadata.js +1 -0
  16. package/build/common/metadata.js.map +1 -1
  17. package/build/common/webRTC.d.ts +2 -0
  18. package/build/common/webRTC.d.ts.map +1 -1
  19. package/build/common/webRTC.js +2 -0
  20. package/build/common/webRTC.js.map +1 -1
  21. package/build/components/VideoPreviewView.d.ts +6 -3
  22. package/build/components/VideoPreviewView.d.ts.map +1 -1
  23. package/build/components/VideoPreviewView.js +5 -0
  24. package/build/components/VideoPreviewView.js.map +1 -1
  25. package/build/components/VideoRendererView.d.ts +5 -3
  26. package/build/components/VideoRendererView.d.ts.map +1 -1
  27. package/build/components/VideoRendererView.js +4 -0
  28. package/build/components/VideoRendererView.js.map +1 -1
  29. package/build/hooks/useAudioSettings.d.ts +15 -0
  30. package/build/hooks/useAudioSettings.d.ts.map +1 -1
  31. package/build/hooks/useAudioSettings.js +15 -13
  32. package/build/hooks/useAudioSettings.js.map +1 -1
  33. package/build/hooks/useBandwidthEstimation.d.ts +2 -0
  34. package/build/hooks/useBandwidthEstimation.d.ts.map +1 -1
  35. package/build/hooks/useBandwidthEstimation.js +2 -0
  36. package/build/hooks/useBandwidthEstimation.js.map +1 -1
  37. package/build/hooks/useCamera.d.ts +45 -1
  38. package/build/hooks/useCamera.d.ts.map +1 -1
  39. package/build/hooks/useCamera.js +45 -37
  40. package/build/hooks/useCamera.js.map +1 -1
  41. package/build/hooks/useFishjamEvent.d.ts +1 -0
  42. package/build/hooks/useFishjamEvent.d.ts.map +1 -1
  43. package/build/hooks/useFishjamEvent.js +3 -4
  44. package/build/hooks/useFishjamEvent.js.map +1 -1
  45. package/build/hooks/useMicrophone.d.ts +4 -0
  46. package/build/hooks/useMicrophone.d.ts.map +1 -1
  47. package/build/hooks/useMicrophone.js +8 -4
  48. package/build/hooks/useMicrophone.js.map +1 -1
  49. package/build/hooks/useParticipants.d.ts +2 -0
  50. package/build/hooks/useParticipants.d.ts.map +1 -1
  51. package/build/hooks/useParticipants.js +2 -0
  52. package/build/hooks/useParticipants.js.map +1 -1
  53. package/build/hooks/useReconnection.d.ts +6 -0
  54. package/build/hooks/useReconnection.d.ts.map +1 -1
  55. package/build/hooks/useReconnection.js +6 -0
  56. package/build/hooks/useReconnection.js.map +1 -1
  57. package/build/hooks/useScreencast.d.ts +22 -3
  58. package/build/hooks/useScreencast.d.ts.map +1 -1
  59. package/build/hooks/useScreencast.js +30 -22
  60. package/build/hooks/useScreencast.js.map +1 -1
  61. package/build/index.d.ts +1 -1
  62. package/build/index.d.ts.map +1 -1
  63. package/build/index.js +2 -0
  64. package/build/index.js.map +1 -1
  65. package/build/stats/useRTCStatistics.d.ts +1 -0
  66. package/build/stats/useRTCStatistics.d.ts.map +1 -1
  67. package/build/stats/useRTCStatistics.js +1 -0
  68. package/build/stats/useRTCStatistics.js.map +1 -1
  69. package/build/types.d.ts +6 -0
  70. package/build/types.d.ts.map +1 -1
  71. package/build/types.js.map +1 -1
  72. package/build/utils/errorListener.d.ts +2 -0
  73. package/build/utils/errorListener.d.ts.map +1 -0
  74. package/build/utils/errorListener.js +16 -0
  75. package/build/utils/errorListener.js.map +1 -0
  76. package/build/utils/foregroundService.d.ts +2 -0
  77. package/build/utils/foregroundService.d.ts.map +1 -1
  78. package/build/utils/foregroundService.js +2 -0
  79. package/build/utils/foregroundService.js.map +1 -1
  80. package/ios/Events.swift +1 -0
  81. package/ios/RNFishjamClient.podspec +1 -1
  82. package/ios/RNFishjamClient.swift +14 -0
  83. package/package.json +4 -3
  84. package/plugin/broadcastExtensionFiles/FishjamBroadcastSampleHandler.swift +50 -0
  85. package/plugin/broadcastExtensionFiles/FishjamScreenBroadcastExtension.entitlements +10 -0
  86. package/plugin/broadcastExtensionFiles/Info.plist +27 -0
  87. package/plugin/build/types.d.ts +5 -5
  88. package/plugin/build/withFishjamAndroid.js +2 -2
  89. package/plugin/build/withFishjamIos.js +3 -3
@@ -1,6 +1,7 @@
1
1
  import type { RTCStats } from './types';
2
2
  /**
3
3
  * This hook provides access to current rtc statistics data.
4
+ * @category Debugging
4
5
  */
5
6
  export declare function useRTCStatistics(refreshInterval: number): {
6
7
  statistics: RTCStats[];
@@ -1 +1 @@
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;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM;;EAuFvD"}
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"}
@@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
3
3
  import RNFishjamClientModule from '../RNFishjamClientModule';
4
4
  /**
5
5
  * This hook provides access to current rtc statistics data.
6
+ * @category Debugging
6
7
  */
7
8
  export function useRTCStatistics(refreshInterval) {
8
9
  const MAX_SIZE = 120;
@@ -1 +1 @@
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 */\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"]}
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"]}
package/build/types.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * `FILL` or `FIT` - it works just like RN Image component. `FILL` fills the whole view
3
+ * with video and it may cut some parts of the video. `FIT` scales the video so the whole
4
+ * video is visible, but it may leave some empty space in the view.
5
+ * @category Components
6
+ */
1
7
  export type VideoLayout = 'FILL' | 'FIT';
2
8
  export type TrackEncoding = 'l' | 'm' | 'h';
3
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,eAAe,EAAE,aAAa,EAAE,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAE5E;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,uBAAuB,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGtD,OAAO,CAAC,MAAM,KAAK,EAAE,OAAO,MAAM,CAAC;AACnC,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,MAAM,SAAS,MAAM,IAAI,CAAC,GAAG;IAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;GAGG;AACH,oBAAY,4BAA4B;IACtC,8BAA8B,KAAK;IACnC,wCAAwC,KAAK;IAC7C,kCAAkC,MAAM;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,4BAA4B,EAAE,CAAC;CACxD,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,eAAe,EAAE,aAAa,EAAE,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAE5E;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,uBAAuB,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGtD,OAAO,CAAC,MAAM,KAAK,EAAE,OAAO,MAAM,CAAC;AACnC,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,MAAM,SAAS,MAAM,IAAI,CAAC,GAAG;IAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;GAGG;AACH,oBAAY,4BAA4B;IACtC,8BAA8B,KAAK;IACnC,wCAAwC,KAAK;IAC7C,kCAAkC,MAAM;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,4BAA4B,EAAE,CAAC;CACxD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkDA;;;GAGG;AACH,MAAM,CAAN,IAAY,4BAIX;AAJD,WAAY,4BAA4B;IACtC,oIAAmC,CAAA;IACnC,wJAA6C,CAAA;IAC7C,6IAAwC,CAAA;AAC1C,CAAC,EAJW,4BAA4B,KAA5B,4BAA4B,QAIvC","sourcesContent":["// global\nexport type VideoLayout = 'FILL' | 'FIT';\n\nexport type TrackEncoding = 'l' | 'm' | 'h';\n\n/**\n * A type describing simulcast configuration.\n *\n * At the moment, simulcast track is initialized in three versions - low, medium and high.\n * High resolution is the original track resolution, while medium and low resolutions are\n * the original track resolution scaled down by 2 and 4 respectively.\n */\nexport type SimulcastConfig = {\n /**\n * whether to simulcast track or not. By default simulcast is disabled.\n */\n enabled: boolean;\n /**\n * list of active encodings. Encoding can be one of `\"h\"` (original encoding), `\"m\"` (scaled down x2), `\"l\"` (scaled down x4).\n */\n activeEncodings: TrackEncoding[];\n};\n\n/**\n * Type describing maximal bandwidth that can be used, in kbps. 0 is interpreted as unlimited bandwidth.\n */\nexport type BandwidthLimit = number;\n\n/**\n * Type describing bandwidth limit for simulcast track. It is a mapping `encoding -> BandwidthLimit`. If encoding isn't present in this mapping,\n * it will be assumed that this particular encoding shouldn't have any bandwidth limit.\n */\nexport type SimulcastBandwidthLimit = Record<TrackEncoding, BandwidthLimit>;\n\n/**\n * A type describing bandwidth limitation of a track, including simulcast and non-simulcast tracks. Can be `BandwidthLimit` or `SimulcastBandwidthLimit`.\n */\nexport type TrackBandwidthLimit = BandwidthLimit | SimulcastBandwidthLimit;\n\nexport type TrackMetadata = {\n active: boolean;\n type: 'audio' | 'camera' | 'screensharing';\n};\n\nexport type GenericMetadata = Record<string, unknown>;\n\n// branded types are useful for restricting where given value can be passed\ndeclare const brand: unique symbol;\nexport type Brand<T, TBrand extends string> = T & { [brand]: TBrand };\n\n/**\n * Enum used to set the foreground service types identifying the work done by the service.\n * See Android's [foreground service types](https://developer.android.com/develop/background-work/services/fg-service-types) documentation.\n */\nexport enum AndroidForegroundServiceType {\n FOREGROUND_SERVICE_TYPE_CAMERA = 64,\n FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32,\n FOREGROUND_SERVICE_TYPE_MICROPHONE = 128,\n}\n\n/**\n * A type representing the options required for configuring the foreground service.\n *\n * @param channelId The id of the channel. Must be unique per package.\n * @param channelName The user visible name of the channel.\n * @param notificationTitle The title (first row) of the notification, in a standard notification.\n * @param notificationContent The text (second row) of the notification, in a standard notification.\n * @param foregroundServiceTypes The type of foreground service to launch.\n */\nexport type ForegroundServiceOptions = {\n channelId: string;\n channelName: string;\n notificationTitle: string;\n notificationContent: string;\n foregroundServiceTypes: AndroidForegroundServiceType[];\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAuDA;;;GAGG;AACH,MAAM,CAAN,IAAY,4BAIX;AAJD,WAAY,4BAA4B;IACtC,oIAAmC,CAAA;IACnC,wJAA6C,CAAA;IAC7C,6IAAwC,CAAA;AAC1C,CAAC,EAJW,4BAA4B,KAA5B,4BAA4B,QAIvC","sourcesContent":["/**\n * `FILL` or `FIT` - it works just like RN Image component. `FILL` fills the whole view\n * with video and it may cut some parts of the video. `FIT` scales the video so the whole\n * video is visible, but it may leave some empty space in the view.\n * @category Components\n */\nexport type VideoLayout = 'FILL' | 'FIT';\n\nexport type TrackEncoding = 'l' | 'm' | 'h';\n\n/**\n * A type describing simulcast configuration.\n *\n * At the moment, simulcast track is initialized in three versions - low, medium and high.\n * High resolution is the original track resolution, while medium and low resolutions are\n * the original track resolution scaled down by 2 and 4 respectively.\n */\nexport type SimulcastConfig = {\n /**\n * whether to simulcast track or not. By default simulcast is disabled.\n */\n enabled: boolean;\n /**\n * list of active encodings. Encoding can be one of `\"h\"` (original encoding), `\"m\"` (scaled down x2), `\"l\"` (scaled down x4).\n */\n activeEncodings: TrackEncoding[];\n};\n\n/**\n * Type describing maximal bandwidth that can be used, in kbps. 0 is interpreted as unlimited bandwidth.\n */\nexport type BandwidthLimit = number;\n\n/**\n * Type describing bandwidth limit for simulcast track. It is a mapping `encoding -> BandwidthLimit`. If encoding isn't present in this mapping,\n * it will be assumed that this particular encoding shouldn't have any bandwidth limit.\n */\nexport type SimulcastBandwidthLimit = Record<TrackEncoding, BandwidthLimit>;\n\n/**\n * A type describing bandwidth limitation of a track, including simulcast and non-simulcast tracks. Can be `BandwidthLimit` or `SimulcastBandwidthLimit`.\n */\nexport type TrackBandwidthLimit = BandwidthLimit | SimulcastBandwidthLimit;\n\nexport type TrackMetadata = {\n active: boolean;\n type: 'audio' | 'camera' | 'screensharing';\n};\n\nexport type GenericMetadata = Record<string, unknown>;\n\n// branded types are useful for restricting where given value can be passed\ndeclare const brand: unique symbol;\nexport type Brand<T, TBrand extends string> = T & { [brand]: TBrand };\n\n/**\n * Enum used to set the foreground service types identifying the work done by the service.\n * See Android's [foreground service types](https://developer.android.com/develop/background-work/services/fg-service-types) documentation.\n */\nexport enum AndroidForegroundServiceType {\n FOREGROUND_SERVICE_TYPE_CAMERA = 64,\n FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 32,\n FOREGROUND_SERVICE_TYPE_MICROPHONE = 128,\n}\n\n/**\n * A type representing the options required for configuring the foreground service.\n *\n * @param channelId The id of the channel. Must be unique per package.\n * @param channelName The user visible name of the channel.\n * @param notificationTitle The title (first row) of the notification, in a standard notification.\n * @param notificationContent The text (second row) of the notification, in a standard notification.\n * @param foregroundServiceTypes The type of foreground service to launch.\n */\nexport type ForegroundServiceOptions = {\n channelId: string;\n channelName: string;\n notificationTitle: string;\n notificationContent: string;\n foregroundServiceTypes: AndroidForegroundServiceType[];\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const initializeWarningListener: () => void;
2
+ //# sourceMappingURL=errorListener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorListener.d.ts","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,YAcrC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { ReceivableEvents } from '../hooks/useFishjamEvent';
2
+ import { nativeModuleEventEmitter } from '../RNFishjamClientModule';
3
+ export const initializeWarningListener = () => {
4
+ if (!__DEV__) {
5
+ return;
6
+ }
7
+ try {
8
+ nativeModuleEventEmitter.addListener(ReceivableEvents.Warning, ({ message }) => {
9
+ console.warn(message);
10
+ });
11
+ }
12
+ catch (error) {
13
+ console.error(`Failed to start warning listener: ${error?.message ?? ''}`);
14
+ }
15
+ };
16
+ //# sourceMappingURL=errorListener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorListener.js","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,wBAAwB,CAAC,WAAW,CAClC,gBAAgB,CAAC,OAAO,EACxB,CAAC,EAAE,OAAO,EAAuB,EAAE,EAAE;YACnC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,KAAK,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { ReceivableEvents } from '../hooks/useFishjamEvent';\nimport { nativeModuleEventEmitter } from '../RNFishjamClientModule';\n\nexport const initializeWarningListener = () => {\n if (!__DEV__) {\n return;\n }\n try {\n nativeModuleEventEmitter.addListener(\n ReceivableEvents.Warning,\n ({ message }: { message: string }) => {\n console.warn(message);\n },\n );\n } catch (error) {\n console.error(`Failed to start warning listener: ${error?.message ?? ''}`);\n }\n};\n"]}
@@ -18,6 +18,7 @@ import { ForegroundServiceOptions } from '../types';
18
18
  ```
19
19
  <service android:name="io.fishjam.reactnative.FishjamForegroundService" android:foregroundServiceType="camera|microphone|mediaProjection"/>
20
20
  ```
21
+ * @category Screenshare
21
22
  */
22
23
  export declare const startForegroundService: (options: ForegroundServiceOptions) => void;
23
24
  /**
@@ -25,6 +26,7 @@ export declare const startForegroundService: (options: ForegroundServiceOptions)
25
26
  * @see {@link startForegroundService} for further information.
26
27
  *
27
28
  * Does nothing on other platforms.
29
+ * @category Screenshare
28
30
  */
29
31
  export declare const stopForegroundService: () => void;
30
32
  //# sourceMappingURL=foregroundService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"foregroundService.d.ts","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;MAmBM;AACN,eAAO,MAAM,sBAAsB,YAAa,wBAAwB,SAKvE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,YAKjC,CAAC"}
1
+ {"version":3,"file":"foregroundService.d.ts","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;MAoBM;AACN,eAAO,MAAM,sBAAsB,YAAa,wBAAwB,SAKvE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,YAKjC,CAAC"}
@@ -19,6 +19,7 @@ import RNFishjamClientModule from '../RNFishjamClientModule';
19
19
  ```
20
20
  <service android:name="io.fishjam.reactnative.FishjamForegroundService" android:foregroundServiceType="camera|microphone|mediaProjection"/>
21
21
  ```
22
+ * @category Screenshare
22
23
  */
23
24
  export const startForegroundService = (options) => {
24
25
  if (Platform.OS !== 'android') {
@@ -31,6 +32,7 @@ export const startForegroundService = (options) => {
31
32
  * @see {@link startForegroundService} for further information.
32
33
  *
33
34
  * Does nothing on other platforms.
35
+ * @category Screenshare
34
36
  */
35
37
  export const stopForegroundService = () => {
36
38
  if (Platform.OS !== 'android') {
@@ -1 +1 @@
1
- {"version":3,"file":"foregroundService.js","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;MAmBM;AACN,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAiC,EAAE,EAAE;IAC1E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,qBAAqB,EAAE,CAAC;AAChD,CAAC,CAAC","sourcesContent":["import { Platform } from 'react-native';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\nimport { ForegroundServiceOptions } from '../types';\n\n/**\n * Launches a foreground service on Android.\n * Does nothing on other platforms.\n * \n * @remarks\n * You must have have the following permissions enabled before calling this function:\n * @example\n ```\n \"android.permission.FOREGROUND_SERVICE\"\n \"android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION\"\n \"android.permission.FOREGROUND_SERVICE_CAMERA\"\n \"android.permission.FOREGROUND_SERVICE_MICROPHONE\"\n \"android.permission.POST_NOTIFICATIONS\"\n *```\n * as well as FishjamForegroundService in your AndroidManifest:\n * @example\n ```\n <service android:name=\"io.fishjam.reactnative.FishjamForegroundService\" android:foregroundServiceType=\"camera|microphone|mediaProjection\"/>\n ```\n */\nexport const startForegroundService = (options: ForegroundServiceOptions) => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.startForegroundService(options);\n};\n\n/**\n * Stops previously launched Android foreground service.\n * @see {@link startForegroundService} for further information.\n *\n * Does nothing on other platforms.\n */\nexport const stopForegroundService = () => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.stopForegroundService();\n};\n"]}
1
+ {"version":3,"file":"foregroundService.js","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;MAoBM;AACN,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAiC,EAAE,EAAE;IAC1E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,qBAAqB,EAAE,CAAC;AAChD,CAAC,CAAC","sourcesContent":["import { Platform } from 'react-native';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\nimport { ForegroundServiceOptions } from '../types';\n\n/**\n * Launches a foreground service on Android.\n * Does nothing on other platforms.\n * \n * @remarks\n * You must have have the following permissions enabled before calling this function:\n * @example\n ```\n \"android.permission.FOREGROUND_SERVICE\"\n \"android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION\"\n \"android.permission.FOREGROUND_SERVICE_CAMERA\"\n \"android.permission.FOREGROUND_SERVICE_MICROPHONE\"\n \"android.permission.POST_NOTIFICATIONS\"\n *```\n * as well as FishjamForegroundService in your AndroidManifest:\n * @example\n ```\n <service android:name=\"io.fishjam.reactnative.FishjamForegroundService\" android:foregroundServiceType=\"camera|microphone|mediaProjection\"/>\n ```\n * @category Screenshare\n */\nexport const startForegroundService = (options: ForegroundServiceOptions) => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.startForegroundService(options);\n};\n\n/**\n * Stops previously launched Android foreground service.\n * @see {@link startForegroundService} for further information.\n *\n * Does nothing on other platforms.\n * @category Screenshare\n */\nexport const stopForegroundService = () => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.stopForegroundService();\n};\n"]}
package/ios/Events.swift CHANGED
@@ -10,4 +10,5 @@ struct EmitableEvents {
10
10
  static let ReconnectionRetriesLimitReached = "ReconnectionRetriesLimitReached"
11
11
  static let ReconnectionStarted = "ReconnectionStarted"
12
12
  static let Reconnected = "Reconnected"
13
+ static let Warning = "Warning"
13
14
  }
@@ -25,6 +25,6 @@ Pod::Spec.new do |s|
25
25
 
26
26
  s.source_files = '**/*.{h,m,swift}'
27
27
 
28
- s.dependency 'FishjamCloudClient', '>= 0.1'
28
+ s.dependency 'FishjamCloudClient', '0.2.3'
29
29
 
30
30
  end
@@ -13,6 +13,8 @@ class RNFishjamClient: FishjamClientListener {
13
13
  var isScreencastOn = false
14
14
  var isConnected = false
15
15
 
16
+ private var isCameraInitialized = false
17
+
16
18
  var connectPromise: Promise? = nil
17
19
 
18
20
  var videoSimulcastConfig: SimulcastConfig = SimulcastConfig()
@@ -211,14 +213,22 @@ class RNFishjamClient: FishjamClientListener {
211
213
  isCameraOn = false
212
214
  isScreencastOn = false
213
215
  isConnected = false
216
+ isCameraInitialized = false
214
217
  RNFishjamClient.fishjamClient?.leave()
215
218
  }
216
219
 
217
220
  func startCamera(config: CameraConfig) throws {
218
221
  try ensureCreated()
222
+
223
+ guard !isCameraInitialized else {
224
+ emit(warning: "Camera already started. You may only call startCamera once before leaveRoom is called.")
225
+ return
226
+ }
227
+
219
228
  let cameraTrack = try createCameraTrack(config: config)
220
229
  setCameraTrackState(cameraTrack, enabled: config.cameraEnabled)
221
230
  emitEndpoints()
231
+ isCameraInitialized = true
222
232
  }
223
233
 
224
234
  private func createCameraTrack(config: CameraConfig) throws -> LocalVideoTrack {
@@ -667,6 +677,10 @@ class RNFishjamClient: FishjamClientListener {
667
677
  sendEvent(name, data)
668
678
  }
669
679
 
680
+ func emit(warning: String) {
681
+ emitEvent(name: EmitableEvents.Warning, data: ["message": warning])
682
+ }
683
+
670
684
  func emitEndpoints() {
671
685
  let eventName = EmitableEvents.PeersUpdate
672
686
  let EndpointsUpdateMap = [eventName: (try? getPeers()) ?? []]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/react-native-client",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A React Native client for Fishjam Cloud",
5
5
  "author": "Fishjam Cloud Team",
6
6
  "license": "Apache-2.0",
@@ -27,7 +27,7 @@
27
27
  "MembraneWebRTC",
28
28
  "fishjam"
29
29
  ],
30
- "repository": "https://github.com/fishjam-cloud/mobile-client-sdk",
30
+ "repository": "github:fishjam-cloud/mobile-client-sdk",
31
31
  "bugs": {
32
32
  "url": "https://github.com/fishjam-cloud/mobile-client-sdk/issues"
33
33
  },
@@ -46,7 +46,7 @@
46
46
  "@types/lodash": "^4.17.7",
47
47
  "@types/phoenix": "^1.6.5",
48
48
  "@types/promise-fs": "^2.1.2",
49
- "@types/react": "^18.3.5",
49
+ "@types/react": "^18.3.7",
50
50
  "expo": "^51.0.32",
51
51
  "expo-module-scripts": "^3.5.2",
52
52
  "expo-modules-core": "^1.12.24",
@@ -84,6 +84,7 @@
84
84
  "ios/*.swift",
85
85
  "ios/RNFishjamClient.podspec",
86
86
  "plugin/build/**",
87
+ "plugin/broadcastExtensionFiles/**",
87
88
  "app.plugin.js",
88
89
  "expo-module.config.json",
89
90
  "README.md",
@@ -0,0 +1,50 @@
1
+ import FishjamCloudClient
2
+ import Foundation
3
+ import ReplayKit
4
+ import WebRTC
5
+ import os.log
6
+
7
+ /// App Group used by the extension to exchange buffers with the target application
8
+ let appGroup = "{{GROUP_IDENTIFIER}}"
9
+
10
+ let logger = OSLog(subsystem: "{{BUNDLE_IDENTIFIER}}.FishjamBroadcastSampleHandler", category: "Broadcaster")
11
+
12
+ /// An example `SampleHandler` utilizing `BroadcastSampleSource` from `MembraneRTC` sending broadcast samples and necessary notification enabling device's screencast.
13
+ class FishjamBroadcastSampleHandler: RPBroadcastSampleHandler {
14
+ let broadcastSource = BroadcastSampleSource(appGroup: appGroup)
15
+ var started: Bool = false
16
+
17
+ override func broadcastStarted(withSetupInfo _: [String: NSObject]?) {
18
+ started = broadcastSource.connect()
19
+
20
+ guard started else {
21
+ os_log("failed to connect with ipc server", log: logger, type: .debug)
22
+
23
+ super.finishBroadcastWithError(NSError(domain: "", code: 0, userInfo: nil))
24
+
25
+ return
26
+ }
27
+
28
+ broadcastSource.started()
29
+ }
30
+
31
+ override func broadcastPaused() {
32
+ broadcastSource.paused()
33
+ }
34
+
35
+ override func broadcastResumed() {
36
+ broadcastSource.resumed()
37
+ }
38
+
39
+ override func broadcastFinished() {
40
+ broadcastSource.finished()
41
+ }
42
+
43
+ override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
44
+ guard started else {
45
+ return
46
+ }
47
+
48
+ broadcastSource.processFrame(sampleBuffer: sampleBuffer, ofType: sampleBufferType)
49
+ }
50
+ }
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>{{GROUP_IDENTIFIER}}</string>
8
+ </array>
9
+ </dict>
10
+ </plist>
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDisplayName</key>
6
+ <string>FishjamScreenBroadcast</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+ <key>CFBundleName</key>
12
+ <string>$(PRODUCT_NAME)</string>
13
+ <key>CFBundlePackageType</key>
14
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
15
+ <key>CFBundleVersion</key>
16
+ <string>$(CURRENT_PROJECT_VERSION)</string>
17
+ <key>NSExtension</key>
18
+ <dict>
19
+ <key>NSExtensionPointIdentifier</key>
20
+ <string>com.apple.broadcast-services-upload</string>
21
+ <key>NSExtensionPrincipalClass</key>
22
+ <string>$(PRODUCT_MODULE_NAME).FishjamBroadcastSampleHandler</string>
23
+ <key>RPBroadcastProcessMode</key>
24
+ <string>RPBroadcastProcessModeSampleBuffer</string>
25
+ </dict>
26
+ </dict>
27
+ </plist>
@@ -1,9 +1,9 @@
1
1
  export type FishjamPluginOptions = {
2
- android: {
3
- enableForegroundService: boolean;
2
+ android?: {
3
+ enableForegroundService?: boolean;
4
4
  };
5
- ios: {
5
+ ios?: {
6
6
  iphoneDeploymentTarget?: string;
7
- enableScreensharing: boolean;
7
+ enableScreensharing?: boolean;
8
8
  };
9
- };
9
+ } | undefined;
@@ -23,8 +23,8 @@ const withFishjamForegroundService = (config) => {
23
23
  return config;
24
24
  });
25
25
  };
26
- const withFishjamAndroid = (config, { android: { enableForegroundService } }) => {
27
- if (enableForegroundService) {
26
+ const withFishjamAndroid = (config, props) => {
27
+ if (props?.android?.enableForegroundService) {
28
28
  config = withFishjamForegroundService(config);
29
29
  }
30
30
  return config;
@@ -186,7 +186,7 @@ const withFishjamSBE = (config, options) => {
186
186
  `"${SBE_TARGET_NAME}"`) {
187
187
  const buildSettingsObj = configurations[key].buildSettings;
188
188
  buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
189
- options.ios.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
189
+ options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
190
190
  buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
191
191
  buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${SBE_TARGET_NAME}/${SBE_TARGET_NAME}.entitlements`;
192
192
  buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
@@ -207,14 +207,14 @@ const withFishjamSBE = (config, options) => {
207
207
  * Allows for dynamically changing deploymentTarget.
208
208
  */
209
209
  const withFishjamIos = (config, props) => {
210
- if (props.ios.enableScreensharing) {
210
+ if (props?.ios?.enableScreensharing) {
211
211
  withAppGroupPermissions(config);
212
212
  withInfoPlistConstants(config);
213
213
  withFishjamSBE(config, props);
214
214
  }
215
215
  (0, config_plugins_1.withPodfileProperties)(config, (config) => {
216
216
  config.modResults['ios.deploymentTarget'] =
217
- props.ios.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
217
+ props?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
218
218
  return config;
219
219
  });
220
220
  return config;