@fishjam-cloud/react-native-client 0.18.0 → 0.19.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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +40 -0
  3. package/build/RNFishjamClientModule.d.ts +6 -1
  4. package/build/RNFishjamClientModule.d.ts.map +1 -1
  5. package/build/RNFishjamClientModule.js.map +1 -1
  6. package/build/components/FishjamRoom/index.d.ts +6 -0
  7. package/build/components/FishjamRoom/index.d.ts.map +1 -1
  8. package/build/components/FishjamRoom/index.js +6 -0
  9. package/build/components/FishjamRoom/index.js.map +1 -1
  10. package/build/components/LivestreamView.d.ts +46 -1
  11. package/build/components/LivestreamView.d.ts.map +1 -1
  12. package/build/components/LivestreamView.js +8 -1
  13. package/build/components/LivestreamView.js.map +1 -1
  14. package/build/components/VideoPreviewView.d.ts +1 -1
  15. package/build/components/VideoPreviewView.js +1 -0
  16. package/build/components/VideoPreviewView.js.map +1 -1
  17. package/build/components/VideoRendererView.d.ts +2 -2
  18. package/build/components/VideoRendererView.js +3 -2
  19. package/build/components/VideoRendererView.js.map +1 -1
  20. package/build/debug/stats/useRTCStatistics.js.map +1 -1
  21. package/build/hooks/useCamera.d.ts +5 -5
  22. package/build/hooks/useCamera.js.map +1 -1
  23. package/build/hooks/usePeers.js.map +1 -1
  24. package/build/hooks/usePermissions.d.ts +24 -0
  25. package/build/hooks/usePermissions.d.ts.map +1 -0
  26. package/build/hooks/usePermissions.js +61 -0
  27. package/build/hooks/usePermissions.js.map +1 -0
  28. package/build/hooks/useScreenShare.d.ts +1 -1
  29. package/build/hooks/useScreenShare.js.map +1 -1
  30. package/build/index.d.ts +2 -1
  31. package/build/index.d.ts.map +1 -1
  32. package/build/index.js +2 -0
  33. package/build/index.js.map +1 -1
  34. package/build/utils/errorListener.d.ts.map +1 -1
  35. package/build/utils/errorListener.js +1 -1
  36. package/build/utils/errorListener.js.map +1 -1
  37. package/ios/CameraPermissionsRequester.swift +117 -0
  38. package/ios/RNFishjamClientModule.swift +168 -119
  39. package/package.json +21 -15
  40. package/plugin/build/types.d.ts +2 -0
  41. package/plugin/build/withFishjamAndroid.js +16 -4
  42. package/plugin/build/withFishjamIos.js +58 -13
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePermissions.js","sourceRoot":"","sources":["../../src/hooks/usePermissions.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAsB,MAAM,mBAAmB,CAAC;AAE7E;;;GAGG;AACH,KAAK,UAAU,yBAAyB;IACtC,OAAO,eAAe,CAAC,yBAAyB,EAAE,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,6BAA6B;IAC1C,OAAO,eAAe,CAAC,6BAA6B,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;IACvD,SAAS,EAAE,yBAAyB;IACpC,aAAa,EAAE,6BAA6B;CAC7C,CAAC,CAAC;AAEH;;;GAGG;AACH,KAAK,UAAU,6BAA6B;IAC1C,OAAO,eAAe,CAAC,6BAA6B,EAAE,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,iCAAiC;IAC9C,OAAO,eAAe,CAAC,iCAAiC,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;IAC3D,SAAS,EAAE,6BAA6B;IACxC,aAAa,EAAE,iCAAiC;CACjD,CAAC,CAAC","sourcesContent":["import RNFishjamClient from '../RNFishjamClientModule';\nimport { createPermissionHook, PermissionResponse } from 'expo-modules-core';\n\n/**\n * Checks user's permissions for accessing camera.\n * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).\n */\nasync function getCameraPermissionsAsync(): Promise<PermissionResponse> {\n return RNFishjamClient.getCameraPermissionsAsync();\n}\n\n/**\n * Asks the user to grant permissions for accessing camera.\n * On iOS this will require apps to specify an `NSCameraUsageDescription` entry in the **Info.plist**.\n * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).\n */\nasync function requestCameraPermissionsAsync(): Promise<PermissionResponse> {\n return RNFishjamClient.requestCameraPermissionsAsync();\n}\n\n/**\n * Check or request permissions to access the camera.\n * This uses both `requestCameraPermissionsAsync` and `getCameraPermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * import { useCameraPermissions } from '@fishjam-cloud/react-native-client';\n * const [status, requestPermission] = useCameraPermissions();\n * ```\n */\nexport const useCameraPermissions = createPermissionHook({\n getMethod: getCameraPermissionsAsync,\n requestMethod: requestCameraPermissionsAsync,\n});\n\n/**\n * Checks user's permissions for accessing microphone.\n * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).\n */\nasync function getMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n return RNFishjamClient.getMicrophonePermissionsAsync();\n}\n\n/**\n * Asks the user to grant permissions for accessing the microphone.\n * On iOS this will require apps to specify an `NSMicrophoneUsageDescription` entry in the **Info.plist**.\n * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).\n */\nasync function requestMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n return RNFishjamClient.requestMicrophonePermissionsAsync();\n}\n\n/**\n * Check or request permissions to access the microphone.\n * This uses both `requestMicrophonePermissionsAsync` and `getMicrophonePermissionsAsync` to interact with the permissions.\n *\n * @example\n * ```ts\n * import { useMicrophonePermissions } from '@fishjam-cloud/react-native-client';\n * const [status, requestPermission] = useMicrophonePermissions();\n * ```\n */\nexport const useMicrophonePermissions = createPermissionHook({\n getMethod: getMicrophonePermissionsAsync,\n requestMethod: requestMicrophonePermissionsAsync,\n});\n"]}
@@ -5,7 +5,7 @@ export type ScreenShareOptions = {
5
5
  * Resolution + fps of screen share track, one of: `VGA`, `HD5`, `HD15`, `FHD15`, `FHD30`.
6
6
  * Note that quality might be worse than specified due to device capabilities, internet
7
7
  * connection etc.
8
- * @default `HD15``
8
+ * @default `HD15`
9
9
  */
10
10
  quality: ScreenShareQuality;
11
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useScreenShare.js","sourceRoot":"","sources":["../../src/hooks/useScreenShare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGpC,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAqBvE,MAAM,sBAAsB,GAAG,GAAG,EAAE,CAClC,CAAC;IACC,OAAO,EAAE,KAAK;CACf,CAA2B,CAAC;AAE/B,IAAI,0BAA0B,GAAoB,sBAAsB,EAAE,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,eAAe,GAAG,oBAAoB,CAC1C,gBAAgB,CAAC,eAAe,EAChC,qBAAqB,CAAC,eAAe,CACtC,CAAC;IAEF,MAAM,eAAe,GAAG,oBAAoB,CAC1C,gBAAgB,CAAC,qBAAqB,EACtC,0BAA0B,CAC3B,CAAC;IAEF,MAAM,2BAA2B,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,MAAM,qBAAqB,CAAC,2BAA2B,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,WAAW,CACnC,KAAK,EAAE,qBAAkD,EAAE,EAAE,EAAE;QAC7D,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,eAAe,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,2BAA2B,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;gBACxD,OAAO;YACT,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG;YACd,GAAG,kBAAkB;YACrB,mBAAmB,EAAE;gBACnB,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,kBAA2B;gBACjC,MAAM,EAAE,CAAC,eAAe;aACzB;SACF,CAAC;QACF,MAAM,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACvD,0BAA0B,GAAG,sBAAsB,EAAE,CAAC,CAAC,kCAAkC;IAC3F,CAAC,EACD,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAC/C,CAAC;IAEF,OAAO;QACL,eAAe;QACf,eAAe;QAEf;;;WAGG;QACH,iBAAiB;QACjB,2BAA2B;KAC5B,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\n\nimport { SimulcastConfig, TrackMetadata } from '../types';\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { Platform } from 'react-native';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\n\nexport type ScreenShareQuality = 'VGA' | 'HD5' | 'HD15' | 'FHD15' | 'FHD30';\n\nexport type ScreenShareOptions = {\n /**\n * Resolution + fps of screen share track, one of: `VGA`, `HD5`, `HD15`, `FHD15`, `FHD30`.\n * Note that quality might be worse than specified due to device capabilities, internet\n * connection etc.\n * @default `HD15``\n */\n quality: ScreenShareQuality;\n};\nexport type ScreenShareOptionsInternal = {\n screenShareMetadata: TrackMetadata & { displayName?: string };\n /**\n * SimulcastConfig of a screen share track. By default simulcast is disabled.\n */\n simulcastConfig: SimulcastConfig;\n};\n\nconst defaultSimulcastConfig = () =>\n ({\n enabled: false,\n }) satisfies SimulcastConfig;\n\nlet screenShareSimulcastConfig: SimulcastConfig = defaultSimulcastConfig();\n\n/**\n * This hook can toggle screen sharing on/off and provides current screen share state.\n * @returns An object with functions to manage screen share.\n * @category Connection\n * @group Hooks\n */\nexport function useScreenShare() {\n const isScreenShareOn = useFishjamEventState(\n ReceivableEvents.IsScreenShareOn,\n RNFishjamClientModule.isScreenShareOn,\n );\n\n const simulcastConfig = useFishjamEventState(\n ReceivableEvents.SimulcastConfigUpdate,\n screenShareSimulcastConfig,\n );\n\n const handleScreenSharePermission = useCallback(async () => {\n if (Platform.OS === 'android') {\n return await RNFishjamClientModule.handleScreenSharePermission();\n }\n return 'denied';\n }, []);\n\n const toggleScreenShare = useCallback(\n async (screenShareOptions: Partial<ScreenShareOptions> = {}) => {\n if (Platform.OS === 'android' && !isScreenShareOn) {\n if ((await handleScreenSharePermission()) !== 'granted') {\n return;\n }\n }\n const options = {\n ...screenShareOptions,\n screenShareMetadata: {\n displayName: 'presenting',\n type: 'screenShareVideo' as const,\n active: !isScreenShareOn,\n },\n };\n await RNFishjamClientModule.toggleScreenShare(options);\n screenShareSimulcastConfig = defaultSimulcastConfig(); //to do: sync with camera settings\n },\n [isScreenShareOn, handleScreenSharePermission],\n );\n\n return {\n isScreenShareOn,\n simulcastConfig,\n\n /**\n * Toggles the screen share on/off\n * Emits warning on ios when user is screensharing app screen.\n */\n toggleScreenShare,\n handleScreenSharePermission,\n };\n}\n"]}
1
+ {"version":3,"file":"useScreenShare.js","sourceRoot":"","sources":["../../src/hooks/useScreenShare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGpC,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAqBvE,MAAM,sBAAsB,GAAG,GAAG,EAAE,CAClC,CAAC;IACC,OAAO,EAAE,KAAK;CACf,CAA2B,CAAC;AAE/B,IAAI,0BAA0B,GAAoB,sBAAsB,EAAE,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,eAAe,GAAG,oBAAoB,CAC1C,gBAAgB,CAAC,eAAe,EAChC,qBAAqB,CAAC,eAAe,CACtC,CAAC;IAEF,MAAM,eAAe,GAAG,oBAAoB,CAC1C,gBAAgB,CAAC,qBAAqB,EACtC,0BAA0B,CAC3B,CAAC;IAEF,MAAM,2BAA2B,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,MAAM,qBAAqB,CAAC,2BAA2B,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,WAAW,CACnC,KAAK,EAAE,qBAAkD,EAAE,EAAE,EAAE;QAC7D,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,eAAe,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,2BAA2B,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;gBACxD,OAAO;YACT,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG;YACd,GAAG,kBAAkB;YACrB,mBAAmB,EAAE;gBACnB,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,kBAA2B;gBACjC,MAAM,EAAE,CAAC,eAAe;aACzB;SACF,CAAC;QACF,MAAM,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACvD,0BAA0B,GAAG,sBAAsB,EAAE,CAAC,CAAC,kCAAkC;IAC3F,CAAC,EACD,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAC/C,CAAC;IAEF,OAAO;QACL,eAAe;QACf,eAAe;QAEf;;;WAGG;QACH,iBAAiB;QACjB,2BAA2B;KAC5B,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\n\nimport { SimulcastConfig, TrackMetadata } from '../types';\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { Platform } from 'react-native';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\n\nexport type ScreenShareQuality = 'VGA' | 'HD5' | 'HD15' | 'FHD15' | 'FHD30';\n\nexport type ScreenShareOptions = {\n /**\n * Resolution + fps of screen share track, one of: `VGA`, `HD5`, `HD15`, `FHD15`, `FHD30`.\n * Note that quality might be worse than specified due to device capabilities, internet\n * connection etc.\n * @default `HD15`\n */\n quality: ScreenShareQuality;\n};\nexport type ScreenShareOptionsInternal = {\n screenShareMetadata: TrackMetadata & { displayName?: string };\n /**\n * SimulcastConfig of a screen share track. By default simulcast is disabled.\n */\n simulcastConfig: SimulcastConfig;\n};\n\nconst defaultSimulcastConfig = () =>\n ({\n enabled: false,\n }) satisfies SimulcastConfig;\n\nlet screenShareSimulcastConfig: SimulcastConfig = defaultSimulcastConfig();\n\n/**\n * This hook can toggle screen sharing on/off and provides current screen share state.\n * @returns An object with functions to manage screen share.\n * @category Connection\n * @group Hooks\n */\nexport function useScreenShare() {\n const isScreenShareOn = useFishjamEventState(\n ReceivableEvents.IsScreenShareOn,\n RNFishjamClientModule.isScreenShareOn,\n );\n\n const simulcastConfig = useFishjamEventState(\n ReceivableEvents.SimulcastConfigUpdate,\n screenShareSimulcastConfig,\n );\n\n const handleScreenSharePermission = useCallback(async () => {\n if (Platform.OS === 'android') {\n return await RNFishjamClientModule.handleScreenSharePermission();\n }\n return 'denied';\n }, []);\n\n const toggleScreenShare = useCallback(\n async (screenShareOptions: Partial<ScreenShareOptions> = {}) => {\n if (Platform.OS === 'android' && !isScreenShareOn) {\n if ((await handleScreenSharePermission()) !== 'granted') {\n return;\n }\n }\n const options = {\n ...screenShareOptions,\n screenShareMetadata: {\n displayName: 'presenting',\n type: 'screenShareVideo' as const,\n active: !isScreenShareOn,\n },\n };\n await RNFishjamClientModule.toggleScreenShare(options);\n screenShareSimulcastConfig = defaultSimulcastConfig(); //to do: sync with camera settings\n },\n [isScreenShareOn, handleScreenSharePermission],\n );\n\n return {\n isScreenShareOn,\n simulcastConfig,\n\n /**\n * Toggles the screen share on/off\n * Emits warning on ios when user is screensharing app screen.\n */\n toggleScreenShare,\n handleScreenSharePermission,\n };\n}\n"]}
package/build/index.d.ts CHANGED
@@ -8,7 +8,7 @@ joinRoom,
8
8
  leaveRoom, } from './common/client';
9
9
  export type { VideoPreviewViewProps } from './components/VideoPreviewView';
10
10
  export type { VideoRendererProps } from './components/VideoRendererView';
11
- export type { LivestreamViewProps } from './components/LivestreamView';
11
+ export type { LivestreamViewProps, LivestreamViewRef, } from './components/LivestreamView';
12
12
  export { VideoPreviewView } from './components/VideoPreviewView';
13
13
  export { VideoRendererView } from './components/VideoRendererView';
14
14
  export { LivestreamView } from './components/LivestreamView';
@@ -33,6 +33,7 @@ export { useForegroundService } from './hooks/useForegroundService';
33
33
  export { useConnection } from './hooks/useConnection';
34
34
  export { useUpdatePeerMetadata } from './hooks/useUpdatePeerMetadata';
35
35
  export { useLivestream } from './hooks/useLivestream';
36
+ export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
36
37
  export type { FishjamRoomProps } from './components/FishjamRoom';
37
38
  export { FishjamRoom } from './components/FishjamRoom';
38
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,KAAK,GACN,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO;AACL,kBAAkB;AAClB,QAAQ;AACR,kBAAkB;AAClB,SAAS,GACV,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,YAAY,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,YAAY,EACV,IAAI,EACJ,MAAM,EACN,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAIjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,WAAW,EACX,eAAe,EACf,aAAa,EACb,KAAK,GACN,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO;AACL,kBAAkB;AAClB,QAAQ;AACR,kBAAkB;AAClB,SAAS,GACV,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,YAAY,EACV,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAI7D,YAAY,EACV,IAAI,EACJ,MAAM,EACN,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAIjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
package/build/index.js CHANGED
@@ -25,6 +25,8 @@ export { useForegroundService } from './hooks/useForegroundService';
25
25
  export { useConnection } from './hooks/useConnection';
26
26
  export { useUpdatePeerMetadata } from './hooks/useUpdatePeerMetadata';
27
27
  export { useLivestream } from './hooks/useLivestream';
28
+ // #endregion
29
+ export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
28
30
  export { FishjamRoom } from './components/FishjamRoom';
29
31
  initializeWarningListener();
30
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAWlE,aAAa;AAEb,kBAAkB;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO;AACL,kBAAkB;AAClB,QAAQ;AACR,kBAAkB;AAClB,SAAS,GACV,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAgD7D,aAAa;AAEb,gBAAgB;AAChB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,yBAAyB,EAAE,CAAC","sourcesContent":["import { initializeWarningListener } from './utils/errorListener';\n\n// #region types\nexport type {\n SimulcastConfig,\n VideoLayout,\n GenericMetadata,\n TrackMetadata,\n Brand,\n} from './types';\nexport type { ConnectionConfig } from './common/client';\n// #endregion\n\n// #region methods\nexport { updatePeerMetadata } from './common/metadata';\nexport {\n /** @deprecated */\n joinRoom,\n /** @deprecated */\n leaveRoom,\n} from './common/client';\n// #endregion\n\n// #region components\nexport type { VideoPreviewViewProps } from './components/VideoPreviewView';\nexport type { VideoRendererProps } from './components/VideoRendererView';\nexport type { LivestreamViewProps } from './components/LivestreamView';\n\nexport { VideoPreviewView } from './components/VideoPreviewView';\nexport { VideoRendererView } from './components/VideoRendererView';\nexport { LivestreamView } from './components/LivestreamView';\n// #endregion\n\n// #region types for hooks\nexport type {\n Peer,\n PeerId,\n Track,\n TrackId,\n TrackType,\n VadStatus,\n EncodingReason,\n TrackBase,\n AudioTrack,\n VideoTrack,\n UsePeersResult,\n PeerWithTracks,\n PeerTrackMetadata,\n DistinguishedTracks,\n} from './hooks/usePeers';\n\nexport type {\n AudioOutputDevice,\n AudioOutputDeviceType,\n AudioSessionMode,\n} from './hooks/useAudioSettings';\n\nexport type {\n CameraId,\n Camera,\n CameraConfig,\n VideoQuality,\n CameraFacingDirection,\n CameraConfigBase,\n} from './hooks/useCamera';\n\nexport type {\n ScreenShareOptions,\n ScreenShareQuality,\n} from './hooks/useScreenShare';\nexport type { ForegroundServiceConfig } from './hooks/useForegroundService';\nexport type {\n JoinRoomConfig,\n ReconnectionStatus,\n PeerStatus,\n} from './hooks/useConnection';\nexport type { AppScreenShareData } from './hooks/useAppScreenShare';\nexport type { UseLivestreamResult } from './hooks/useLivestream';\n// #endregion\n\n// #region hooks\nexport { useAudioSettings } from './hooks/useAudioSettings';\nexport { useBandwidthEstimation } from './hooks/useBandwidthEstimation';\nexport { useCamera } from './hooks/useCamera';\nexport { useMicrophone } from './hooks/useMicrophone';\nexport { useScreenShare } from './hooks/useScreenShare';\nexport { useAppScreenShare } from './hooks/useAppScreenShare';\nexport { useReconnection } from './hooks/useReconnection';\nexport { usePeerStatus } from './hooks/usePeerStatus';\nexport { usePeers } from './hooks/usePeers';\nexport { useForegroundService } from './hooks/useForegroundService';\nexport { useConnection } from './hooks/useConnection';\nexport { useUpdatePeerMetadata } from './hooks/useUpdatePeerMetadata';\nexport { useLivestream } from './hooks/useLivestream';\n// #endregion\n\nexport type { FishjamRoomProps } from './components/FishjamRoom';\nexport { FishjamRoom } from './components/FishjamRoom';\n\ninitializeWarningListener();\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAWlE,aAAa;AAEb,kBAAkB;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO;AACL,kBAAkB;AAClB,QAAQ;AACR,kBAAkB;AAClB,SAAS,GACV,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAgD7D,aAAa;AAEb,gBAAgB;AAChB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,aAAa;AAEb,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,yBAAyB,EAAE,CAAC","sourcesContent":["import { initializeWarningListener } from './utils/errorListener';\n\n// #region types\nexport type {\n SimulcastConfig,\n VideoLayout,\n GenericMetadata,\n TrackMetadata,\n Brand,\n} from './types';\nexport type { ConnectionConfig } from './common/client';\n// #endregion\n\n// #region methods\nexport { updatePeerMetadata } from './common/metadata';\nexport {\n /** @deprecated */\n joinRoom,\n /** @deprecated */\n leaveRoom,\n} from './common/client';\n// #endregion\n\n// #region components\nexport type { VideoPreviewViewProps } from './components/VideoPreviewView';\nexport type { VideoRendererProps } from './components/VideoRendererView';\nexport type {\n LivestreamViewProps,\n LivestreamViewRef,\n} from './components/LivestreamView';\n\nexport { VideoPreviewView } from './components/VideoPreviewView';\nexport { VideoRendererView } from './components/VideoRendererView';\nexport { LivestreamView } from './components/LivestreamView';\n// #endregion\n\n// #region types for hooks\nexport type {\n Peer,\n PeerId,\n Track,\n TrackId,\n TrackType,\n VadStatus,\n EncodingReason,\n TrackBase,\n AudioTrack,\n VideoTrack,\n UsePeersResult,\n PeerWithTracks,\n PeerTrackMetadata,\n DistinguishedTracks,\n} from './hooks/usePeers';\n\nexport type {\n AudioOutputDevice,\n AudioOutputDeviceType,\n AudioSessionMode,\n} from './hooks/useAudioSettings';\n\nexport type {\n CameraId,\n Camera,\n CameraConfig,\n VideoQuality,\n CameraFacingDirection,\n CameraConfigBase,\n} from './hooks/useCamera';\n\nexport type {\n ScreenShareOptions,\n ScreenShareQuality,\n} from './hooks/useScreenShare';\nexport type { ForegroundServiceConfig } from './hooks/useForegroundService';\nexport type {\n JoinRoomConfig,\n ReconnectionStatus,\n PeerStatus,\n} from './hooks/useConnection';\nexport type { AppScreenShareData } from './hooks/useAppScreenShare';\nexport type { UseLivestreamResult } from './hooks/useLivestream';\n// #endregion\n\n// #region hooks\nexport { useAudioSettings } from './hooks/useAudioSettings';\nexport { useBandwidthEstimation } from './hooks/useBandwidthEstimation';\nexport { useCamera } from './hooks/useCamera';\nexport { useMicrophone } from './hooks/useMicrophone';\nexport { useScreenShare } from './hooks/useScreenShare';\nexport { useAppScreenShare } from './hooks/useAppScreenShare';\nexport { useReconnection } from './hooks/useReconnection';\nexport { usePeerStatus } from './hooks/usePeerStatus';\nexport { usePeers } from './hooks/usePeers';\nexport { useForegroundService } from './hooks/useForegroundService';\nexport { useConnection } from './hooks/useConnection';\nexport { useUpdatePeerMetadata } from './hooks/useUpdatePeerMetadata';\nexport { useLivestream } from './hooks/useLivestream';\n// #endregion\n\nexport {\n useCameraPermissions,\n useMicrophonePermissions,\n} from './hooks/usePermissions';\n\nexport type { FishjamRoomProps } from './components/FishjamRoom';\nexport { FishjamRoom } from './components/FishjamRoom';\n\ninitializeWarningListener();\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"errorListener.d.ts","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,YAWrC,CAAC"}
1
+ {"version":3,"file":"errorListener.d.ts","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,YAarC,CAAC"}
@@ -9,7 +9,7 @@ export const initializeWarningListener = () => {
9
9
  });
10
10
  }
11
11
  catch (error) {
12
- console.error(`Failed to start warning listener: ${error?.message ?? ''}`);
12
+ console.error(`Failed to start warning listener: ${error instanceof Error ? error.message : ''}`);
13
13
  }
14
14
  };
15
15
  //# sourceMappingURL=errorListener.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorListener.js","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,EAAE,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,YAAY,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,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 nativeModule, { ReceivableEvents } from '../RNFishjamClientModule';\n\nexport const initializeWarningListener = () => {\n if (!__DEV__) {\n return;\n }\n try {\n nativeModule.addListener(ReceivableEvents.Warning, (event) => {\n console.warn(event[ReceivableEvents.Warning]);\n });\n } catch (error) {\n console.error(`Failed to start warning listener: ${error?.message ?? ''}`);\n }\n};\n"]}
1
+ {"version":3,"file":"errorListener.js","sourceRoot":"","sources":["../../src/utils/errorListener.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,EAAE,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,YAAY,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CACX,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACnF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC","sourcesContent":["import nativeModule, { ReceivableEvents } from '../RNFishjamClientModule';\n\nexport const initializeWarningListener = () => {\n if (!__DEV__) {\n return;\n }\n try {\n nativeModule.addListener(ReceivableEvents.Warning, (event) => {\n console.warn(event[ReceivableEvents.Warning]);\n });\n } catch (error: unknown) {\n console.error(\n `Failed to start warning listener: ${error instanceof Error ? error.message : ''}`,\n );\n }\n};\n"]}
@@ -0,0 +1,117 @@
1
+ import ExpoModulesCore
2
+ import AVFoundation
3
+
4
+ let cameraKey = "NSCameraUsageDescription"
5
+ let microphoneKey = "NSMicrophoneUsageDescription"
6
+
7
+ protocol BaseCameraRequester {
8
+ var mediaType: AVMediaType { get }
9
+ func permissionWith(status systemStatus: AVAuthorizationStatus) -> [AnyHashable: Any]
10
+ func permissions(for key: String, service: String) -> [AnyHashable: Any]
11
+ func requestAccess(handler: @escaping (Bool) -> Void)
12
+ }
13
+
14
+ extension BaseCameraRequester {
15
+ public func permissions(for key: String, service: String) -> [AnyHashable: Any] {
16
+ var systemStatus: AVAuthorizationStatus
17
+ let description = Bundle.main.infoDictionary?[key] as? String
18
+
19
+ if description != nil {
20
+ systemStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
21
+ } else {
22
+ RNFishjamClient.sendEvent?(EmitableEvent.warning(message: "Camera permission not granted."))
23
+ systemStatus = .denied
24
+ }
25
+
26
+ return permissionWith(status: systemStatus)
27
+ }
28
+
29
+ public func permissionWith(status systemStatus: AVAuthorizationStatus) -> [AnyHashable: Any] {
30
+ var status: EXPermissionStatus
31
+
32
+ switch systemStatus {
33
+ case .authorized:
34
+ status = EXPermissionStatusGranted
35
+ case .denied, .restricted:
36
+ status = EXPermissionStatusDenied
37
+ case .notDetermined:
38
+ fallthrough
39
+ @unknown default:
40
+ status = EXPermissionStatusUndetermined
41
+ }
42
+
43
+ return [
44
+ "status": status.rawValue
45
+ ]
46
+ }
47
+
48
+ public func requestAccess(handler: @escaping (Bool) -> Void) {
49
+ AVCaptureDevice.requestAccess(for: mediaType, completionHandler: handler)
50
+ }
51
+ }
52
+
53
+ public class CameraOnlyPermissionRequester: NSObject, EXPermissionsRequester, BaseCameraRequester {
54
+ let mediaType: AVMediaType = .video
55
+
56
+ public static func permissionType() -> String {
57
+ "camera"
58
+ }
59
+
60
+ public func getPermissions() -> [AnyHashable: Any] {
61
+ return permissions(for: cameraKey, service: "video")
62
+ }
63
+
64
+ public func requestPermissions(resolver resolve: @escaping EXPromiseResolveBlock, rejecter reject: EXPromiseRejectBlock) {
65
+ requestAccess { [weak self] _ in
66
+ resolve(self?.getPermissions())
67
+ }
68
+ }
69
+ }
70
+
71
+ public class CameraPermissionRequester: NSObject, EXPermissionsRequester, BaseCameraRequester {
72
+ let mediaType: AVMediaType = .video
73
+
74
+ public static func permissionType() -> String {
75
+ "camera"
76
+ }
77
+
78
+ public func getPermissions() -> [AnyHashable: Any] {
79
+ var systemStatus: AVAuthorizationStatus
80
+
81
+ let cameraUsuageDescription = Bundle.main.infoDictionary?[cameraKey] as? String
82
+ let microphoneUsuageDescription = Bundle.main.infoDictionary?[microphoneKey] as? String
83
+
84
+ if let cameraUsuageDescription, let microphoneUsuageDescription {
85
+ systemStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
86
+ } else {
87
+ RNFishjamClient.sendEvent?(EmitableEvent.warning(message: "Camera permission not granted."))
88
+ systemStatus = .denied
89
+ }
90
+
91
+ return permissionWith(status: systemStatus)
92
+ }
93
+
94
+ public func requestPermissions(resolver resolve: @escaping EXPromiseResolveBlock, rejecter reject: EXPromiseRejectBlock) {
95
+ requestAccess { [weak self] _ in
96
+ resolve(self?.getPermissions())
97
+ }
98
+ }
99
+ }
100
+
101
+ public class CameraMicrophonePermissionRequester: NSObject, EXPermissionsRequester, BaseCameraRequester {
102
+ let mediaType: AVMediaType = .audio
103
+
104
+ public static func permissionType() -> String {
105
+ "microphone"
106
+ }
107
+
108
+ public func getPermissions() -> [AnyHashable: Any] {
109
+ return permissions(for: microphoneKey, service: "audio")
110
+ }
111
+
112
+ public func requestPermissions(resolver resolve: @escaping EXPromiseResolveBlock, rejecter reject: EXPromiseRejectBlock) {
113
+ requestAccess { [weak self] _ in
114
+ resolve(self?.getPermissions())
115
+ }
116
+ }
117
+ }
@@ -63,159 +63,208 @@ struct ConnectConfig: Record {
63
63
  typealias RNTrackBandwidthLimit = Either<Int, [String: Int]>
64
64
 
65
65
  public class RNFishjamClientModule: Module {
66
- public func definition() -> ModuleDefinition {
67
- let rnFishjamClient: RNFishjamClient = {
68
- let client = RNFishjamClient(sendEvent)
69
- client.create()
70
- return client
71
- }()
66
+ public func definition() -> ModuleDefinition {
67
+ let rnFishjamClient: RNFishjamClient = {
68
+ let client = RNFishjamClient(sendEvent)
69
+ client.create()
70
+ return client
71
+ }()
72
+
73
+ Name("RNFishjamClient")
74
+
75
+ Events(EmitableEvent.allEvents)
76
+
77
+ OnCreate {
78
+ let permissionsManager = self.appContext?.permissions
79
+ EXPermissionsMethodsDelegate.register(
80
+ [
81
+ CameraOnlyPermissionRequester(),
82
+ CameraMicrophonePermissionRequester()
83
+ ],
84
+ withPermissionsManager: permissionsManager
85
+ )
86
+ }
87
+
88
+ Property("peerStatus") {
89
+ return rnFishjamClient.peerStatus.rawValue
90
+ }
72
91
 
73
- Name("RNFishjamClient")
92
+ Property("reconnectionStatus") {
93
+ return rnFishjamClient.reconnectionStatus.rawValue
94
+ }
74
95
 
75
- Events(EmitableEvent.allEvents)
96
+ Property("isMicrophoneOn") {
97
+ return rnFishjamClient.isMicrophoneOn
98
+ }
76
99
 
77
- Property("peerStatus") {
78
- return rnFishjamClient.peerStatus.rawValue
79
- }
100
+ Property("isCameraOn") {
101
+ return rnFishjamClient.isCameraOn
102
+ }
80
103
 
81
- Property("reconnectionStatus") {
82
- return rnFishjamClient.reconnectionStatus.rawValue
83
- }
104
+ Property("cameras") {
105
+ return rnFishjamClient.getCaptureDevices()
106
+ }
84
107
 
85
- Property("isMicrophoneOn") {
86
- return rnFishjamClient.isMicrophoneOn
87
- }
108
+ Property("currentCamera") {
109
+ return rnFishjamClient.currentCamera
110
+ }
88
111
 
89
- Property("isCameraOn") {
90
- return rnFishjamClient.isCameraOn
91
- }
112
+ Property("isScreenShareOn") {
113
+ return rnFishjamClient.isScreenShareOn
114
+ }
92
115
 
93
- Property("cameras") {
94
- return rnFishjamClient.getCaptureDevices()
95
- }
116
+ Property("isAppScreenShareOn") {
117
+ return rnFishjamClient.isAppScreenShareOn
118
+ }
96
119
 
97
- Property("currentCamera") {
98
- return rnFishjamClient.currentCamera
99
- }
120
+ Property("isCameraInitialized") {
121
+ return rnFishjamClient.isCameraInitialized
122
+ }
100
123
 
101
- Property("isScreenShareOn") {
102
- return rnFishjamClient.isScreenShareOn
103
- }
124
+ Function("getPeers") {
125
+ return rnFishjamClient.getPeers()
126
+ }
104
127
 
105
- Property("isAppScreenShareOn") {
106
- return rnFishjamClient.isAppScreenShareOn
107
- }
128
+ AsyncFunction("joinRoom") {
129
+ (
130
+ url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
131
+ promise: Promise
132
+ ) in
133
+ rnFishjamClient.joinRoom(
134
+ url: url, peerToken: peerToken, peerMetadata: peerMetadata, config: config,
135
+ promise: promise)
136
+ }
108
137
 
109
- Property("isCameraInitialized") {
110
- return rnFishjamClient.isCameraInitialized
111
- }
138
+ AsyncFunction("leaveRoom") {
139
+ rnFishjamClient.leaveRoom()
140
+ }
112
141
 
113
- Function("getPeers") {
114
- return rnFishjamClient.getPeers()
115
- }
142
+ AsyncFunction("startCamera") { (config: CameraConfig) in
143
+ try await rnFishjamClient.startCamera(config: config)
144
+ }
116
145
 
117
- AsyncFunction("joinRoom") {
118
- (
119
- url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
120
- promise: Promise
121
- ) in
122
- rnFishjamClient.joinRoom(
123
- url: url, peerToken: peerToken, peerMetadata: peerMetadata, config: config,
124
- promise: promise)
125
- }
146
+ AsyncFunction("toggleMicrophone") {
147
+ try await rnFishjamClient.toggleMicrophone()
148
+ }
126
149
 
127
- AsyncFunction("leaveRoom") {
128
- rnFishjamClient.leaveRoom()
129
- }
150
+ AsyncFunction("toggleCamera") {
151
+ try rnFishjamClient.toggleCamera()
152
+ }
130
153
 
131
- AsyncFunction("startCamera") { (config: CameraConfig) in
132
- try await rnFishjamClient.startCamera(config: config)
133
- }
154
+ AsyncFunction("flipCamera") {
155
+ try rnFishjamClient.flipCamera()
156
+ }
134
157
 
135
- AsyncFunction("toggleMicrophone") {
136
- try await rnFishjamClient.toggleMicrophone()
137
- }
158
+ AsyncFunction("switchCamera") { (cameraId: String) in
159
+ try rnFishjamClient.switchCamera(cameraId: cameraId)
160
+ }
138
161
 
139
- AsyncFunction("toggleCamera") {
140
- try rnFishjamClient.toggleCamera()
141
- }
162
+ AsyncFunction("toggleScreenShare") { (screenShareOptions: ScreenShareOptions) in
163
+ try rnFishjamClient.toggleScreenShare(screenShareOptions: screenShareOptions)
164
+ }
142
165
 
143
- AsyncFunction("flipCamera") {
144
- try rnFishjamClient.flipCamera()
145
- }
166
+ AsyncFunction("toggleAppScreenShare") { (screenShareOptions: ScreenShareOptions) in
167
+ try rnFishjamClient.toggleAppScreenShare(screenShareOptions: screenShareOptions)
168
+ }
146
169
 
147
- AsyncFunction("switchCamera") { (cameraId: String) in
148
- try rnFishjamClient.switchCamera(cameraId: cameraId)
149
- }
170
+ AsyncFunction("updatePeerMetadata") { (metadata: [String: Any]) in
171
+ try rnFishjamClient.updatePeerMetadata(metadata: metadata)
172
+ }
150
173
 
151
- AsyncFunction("toggleScreenShare") { (screenShareOptions: ScreenShareOptions) in
152
- try rnFishjamClient.toggleScreenShare(screenShareOptions: screenShareOptions)
153
- }
174
+ AsyncFunction("updateVideoTrackMetadata") { (metadata: [String: Any]) in
175
+ try rnFishjamClient.updateLocalVideoTrackMetadata(metadata: metadata)
176
+ }
154
177
 
155
- AsyncFunction("toggleAppScreenShare") { (screenShareOptions: ScreenShareOptions) in
156
- try rnFishjamClient.toggleAppScreenShare(screenShareOptions: screenShareOptions)
157
- }
178
+ AsyncFunction("updateScreenShareTrackMetadata") { (metadata: [String: Any]) in
179
+ try rnFishjamClient.updateLocalScreenShareTrackMetadata(metadata: metadata)
180
+ }
158
181
 
159
- AsyncFunction("updatePeerMetadata") { (metadata: [String: Any]) in
160
- try rnFishjamClient.updatePeerMetadata(metadata: metadata)
161
- }
182
+ AsyncFunction("toggleScreenShareTrackEncoding") { (encoding: String) in
183
+ try rnFishjamClient.toggleScreenShareTrackEncoding(encoding: encoding)
184
+ }
162
185
 
163
- AsyncFunction("updateVideoTrackMetadata") { (metadata: [String: Any]) in
164
- try rnFishjamClient.updateLocalVideoTrackMetadata(metadata: metadata)
165
- }
186
+ AsyncFunction("setScreenShareTrackBandwidth") { (bandwidth: Int) in
187
+ try rnFishjamClient.setScreenShareTrackBandwidth(bandwidth: bandwidth)
188
+ }
166
189
 
167
- AsyncFunction("updateScreenShareTrackMetadata") { (metadata: [String: Any]) in
168
- try rnFishjamClient.updateLocalScreenShareTrackMetadata(metadata: metadata)
169
- }
190
+ AsyncFunction("setScreenShareTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
191
+ try rnFishjamClient.setScreenShareTrackEncodingBandwidth(
192
+ encoding: encoding, bandwidth: bandwidth)
193
+ }
170
194
 
171
- AsyncFunction("toggleScreenShareTrackEncoding") { (encoding: String) in
172
- try rnFishjamClient.toggleScreenShareTrackEncoding(encoding: encoding)
173
- }
195
+ AsyncFunction("setTargetTrackEncoding") { (trackId: String, encoding: String) in
196
+ try rnFishjamClient.setTargetTrackEncoding(trackId: trackId, encoding: encoding)
197
+ }
174
198
 
175
- AsyncFunction("setScreenShareTrackBandwidth") { (bandwidth: Int) in
176
- try rnFishjamClient.setScreenShareTrackBandwidth(bandwidth: bandwidth)
177
- }
199
+ AsyncFunction("toggleVideoTrackEncoding") { (encoding: String) in
200
+ try rnFishjamClient.toggleVideoTrackEncoding(encoding: encoding)
201
+ }
178
202
 
179
- AsyncFunction("setScreenShareTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
180
- try rnFishjamClient.setScreenShareTrackEncodingBandwidth(
181
- encoding: encoding, bandwidth: bandwidth)
182
- }
203
+ AsyncFunction("setVideoTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
204
+ try rnFishjamClient.setVideoTrackEncodingBandwidth(
205
+ encoding: encoding, bandwidth: bandwidth)
206
+ }
183
207
 
184
- AsyncFunction("setTargetTrackEncoding") { (trackId: String, encoding: String) in
185
- try rnFishjamClient.setTargetTrackEncoding(trackId: trackId, encoding: encoding)
186
- }
208
+ AsyncFunction("setVideoTrackBandwidth") { (bandwidth: Int) in
209
+ try rnFishjamClient.setVideoTrackBandwidth(bandwidth: bandwidth)
210
+ }
187
211
 
188
- AsyncFunction("toggleVideoTrackEncoding") { (encoding: String) in
189
- try rnFishjamClient.toggleVideoTrackEncoding(encoding: encoding)
190
- }
212
+ AsyncFunction("changeWebRTCLoggingSeverity") { (severity: String) in
213
+ try rnFishjamClient.changeWebRTCLoggingSeverity(severity: severity)
214
+ }
191
215
 
192
- AsyncFunction("setVideoTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
193
- try rnFishjamClient.setVideoTrackEncodingBandwidth(
194
- encoding: encoding, bandwidth: bandwidth)
195
- }
216
+ AsyncFunction("getStatistics") {
217
+ try await rnFishjamClient.getStatistics()
218
+ }
196
219
 
197
- AsyncFunction("setVideoTrackBandwidth") { (bandwidth: Int) in
198
- try rnFishjamClient.setVideoTrackBandwidth(bandwidth: bandwidth)
199
- }
220
+ AsyncFunction("selectAudioSessionMode") { (sessionMode: String) in
221
+ try rnFishjamClient.selectAudioSessionMode(sessionMode: sessionMode)
222
+ }
200
223
 
201
- AsyncFunction("changeWebRTCLoggingSeverity") { (severity: String) in
202
- try rnFishjamClient.changeWebRTCLoggingSeverity(severity: severity)
203
- }
224
+ AsyncFunction("showAudioRoutePicker") {
225
+ rnFishjamClient.showAudioRoutePicker()
226
+ }
204
227
 
205
- AsyncFunction("getStatistics") {
206
- try await rnFishjamClient.getStatistics()
207
- }
228
+ AsyncFunction("startAudioSwitcher") {
229
+ rnFishjamClient.startAudioSwitcher()
230
+ }
208
231
 
209
- AsyncFunction("selectAudioSessionMode") { (sessionMode: String) in
210
- try rnFishjamClient.selectAudioSessionMode(sessionMode: sessionMode)
211
- }
232
+ AsyncFunction("getCameraPermissionsAsync") { (promise: Promise) in
233
+ EXPermissionsMethodsDelegate.getPermissionWithPermissionsManager(
234
+ self.appContext?.permissions,
235
+ withRequester: CameraOnlyPermissionRequester.self,
236
+ resolve: promise.resolver,
237
+ reject: promise.legacyRejecter
238
+ )
239
+ }
212
240
 
213
- AsyncFunction("showAudioRoutePicker") {
214
- rnFishjamClient.showAudioRoutePicker()
215
- }
241
+ AsyncFunction("requestCameraPermissionsAsync") { (promise: Promise) in
242
+ EXPermissionsMethodsDelegate.askForPermission(
243
+ withPermissionsManager: self.appContext?.permissions,
244
+ withRequester: CameraOnlyPermissionRequester.self,
245
+ resolve: promise.resolver,
246
+ reject: promise.legacyRejecter
247
+ )
248
+ }
216
249
 
217
- AsyncFunction("startAudioSwitcher") {
218
- rnFishjamClient.startAudioSwitcher()
219
- }
250
+ AsyncFunction("getMicrophonePermissionsAsync") { (promise: Promise) in
251
+ EXPermissionsMethodsDelegate.getPermissionWithPermissionsManager(
252
+ self.appContext?.permissions,
253
+ withRequester: CameraMicrophonePermissionRequester.self,
254
+ resolve: promise.resolver,
255
+ reject: promise.legacyRejecter
256
+ )
220
257
  }
221
- }
258
+
259
+ AsyncFunction("requestMicrophonePermissionsAsync") { (promise: Promise) in
260
+ EXPermissionsMethodsDelegate.askForPermission(
261
+ withPermissionsManager: self.appContext?.permissions,
262
+ withRequester: CameraMicrophonePermissionRequester.self,
263
+ resolve: promise.resolver,
264
+ reject: promise.legacyRejecter
265
+ )
266
+ }
267
+
268
+ }
269
+ }
270
+