@fishjam-cloud/react-native-client 0.18.1 → 0.19.1

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 (61) hide show
  1. package/README.md +1 -1
  2. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +25 -15
  3. package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +52 -0
  4. package/build/RNFishjamClientModule.d.ts +6 -1
  5. package/build/RNFishjamClientModule.d.ts.map +1 -1
  6. package/build/RNFishjamClientModule.js.map +1 -1
  7. package/build/components/FishjamRoom/index.d.ts +6 -0
  8. package/build/components/FishjamRoom/index.d.ts.map +1 -1
  9. package/build/components/FishjamRoom/index.js +6 -0
  10. package/build/components/FishjamRoom/index.js.map +1 -1
  11. package/build/components/LivestreamView.d.ts +33 -1
  12. package/build/components/LivestreamView.d.ts.map +1 -1
  13. package/build/components/LivestreamView.js +1 -1
  14. package/build/components/LivestreamView.js.map +1 -1
  15. package/build/components/VideoPreviewView.d.ts +1 -1
  16. package/build/components/VideoPreviewView.js +1 -0
  17. package/build/components/VideoPreviewView.js.map +1 -1
  18. package/build/components/VideoRendererView.d.ts +2 -2
  19. package/build/components/VideoRendererView.js +3 -2
  20. package/build/components/VideoRendererView.js.map +1 -1
  21. package/build/consts/index.d.ts +3 -0
  22. package/build/consts/index.d.ts.map +1 -0
  23. package/build/consts/index.js +4 -0
  24. package/build/consts/index.js.map +1 -0
  25. package/build/debug/stats/useRTCStatistics.js.map +1 -1
  26. package/build/hooks/useCamera.d.ts +5 -5
  27. package/build/hooks/useCamera.js.map +1 -1
  28. package/build/hooks/useConnection.d.ts +18 -7
  29. package/build/hooks/useConnection.d.ts.map +1 -1
  30. package/build/hooks/useConnection.js +10 -2
  31. package/build/hooks/useConnection.js.map +1 -1
  32. package/build/hooks/useMicrophone.d.ts +6 -2
  33. package/build/hooks/useMicrophone.d.ts.map +1 -1
  34. package/build/hooks/useMicrophone.js +12 -2
  35. package/build/hooks/useMicrophone.js.map +1 -1
  36. package/build/hooks/usePeers.js.map +1 -1
  37. package/build/hooks/usePermissions.d.ts +24 -0
  38. package/build/hooks/usePermissions.d.ts.map +1 -0
  39. package/build/hooks/usePermissions.js +61 -0
  40. package/build/hooks/usePermissions.js.map +1 -0
  41. package/build/hooks/useSandbox.d.ts +13 -0
  42. package/build/hooks/useSandbox.d.ts.map +1 -0
  43. package/build/hooks/useSandbox.js +42 -0
  44. package/build/hooks/useSandbox.js.map +1 -0
  45. package/build/hooks/useScreenShare.d.ts +1 -1
  46. package/build/hooks/useScreenShare.js.map +1 -1
  47. package/build/index.d.ts +5 -2
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +3 -0
  50. package/build/index.js.map +1 -1
  51. package/build/types.d.ts +1 -0
  52. package/build/types.d.ts.map +1 -1
  53. package/build/types.js.map +1 -1
  54. package/ios/CameraPermissionsRequester.swift +117 -0
  55. package/ios/RNFishjamClient.swift +31 -20
  56. package/ios/RNFishjamClientModule.swift +176 -119
  57. package/package.json +16 -11
  58. package/plugin/build/types.d.ts +5 -0
  59. package/plugin/build/withFishjamAndroid.js +16 -4
  60. package/plugin/build/withFishjamIos.d.ts +1 -1
  61. package/plugin/build/withFishjamIos.js +106 -48
@@ -1 +1 @@
1
- {"version":3,"file":"useConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAGjB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAevE,MAAM,MAAM,cAAc,CACxB,YAAY,SAAS,eAAe,GAAG,eAAe,IACpD;IACF;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa;IAoBzB;;;;OAIG;eApBI,YAAY,SAAS,eAAe,+DAKxC,cAAc,CAAC,YAAY,CAAC;IAiB/B;;;OAGG;;;;EAKN"}
1
+ {"version":3,"file":"useConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAGjB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAevE,MAAM,MAAM,cAAc,CACxB,YAAY,SAAS,eAAe,GAAG,eAAe,IACpD;IACF;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,GAAG,CACA;IACE;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,KAAK,CAAC;CACb,GACD;IACE;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,CACJ,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa;IAiCzB;;;;OAIG;eAjCI,YAAY,SAAS,eAAe,0EAMxC,cAAc,CAAC,YAAY,CAAC;IA6B/B;;;OAGG;;;;EAKN"}
@@ -2,6 +2,7 @@ import { useCallback } from 'react';
2
2
  import { joinRoom as joinRoomClient, leaveRoom as leaveRoomClient, } from '../common/client';
3
3
  import RNFishjamClientModule, { ReceivableEvents, } from '../RNFishjamClientModule';
4
4
  import { useFishjamEventState } from './internal/useFishjamEventState';
5
+ import { FISHJAM_WS_CONNECT_URL } from '../consts';
5
6
  function useConnectionStatus() {
6
7
  const peerStatus = useFishjamEventState(ReceivableEvents.PeerStatusChanged, RNFishjamClientModule.peerStatus);
7
8
  const reconnectionStatus = useFishjamEventState(ReceivableEvents.ReconnectionStatusChanged, RNFishjamClientModule.reconnectionStatus);
@@ -14,8 +15,15 @@ function useConnectionStatus() {
14
15
  */
15
16
  export function useConnection() {
16
17
  const { peerStatus, reconnectionStatus } = useConnectionStatus();
17
- const joinRoom = useCallback(async ({ url, peerToken, peerMetadata, config, }) => {
18
- await joinRoomClient(url, peerToken, peerMetadata, config);
18
+ const joinRoom = useCallback(async ({ url, peerToken, peerMetadata, config, fishjamId, }) => {
19
+ const connectUrl = fishjamId
20
+ ? `${FISHJAM_WS_CONNECT_URL}/${fishjamId}`
21
+ : undefined;
22
+ const fishjamUrl = fishjamId ? connectUrl : url;
23
+ if (!fishjamUrl) {
24
+ throw new Error('Either fishjamId or url must be provided to join the room.');
25
+ }
26
+ await joinRoomClient(fishjamUrl, peerToken, peerMetadata, config);
19
27
  }, []);
20
28
  const leaveRoom = useCallback(() => {
21
29
  leaveRoomClient();
@@ -1 +1 @@
1
- {"version":3,"file":"useConnection.js","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAEL,QAAQ,IAAI,cAAc,EAC1B,SAAS,IAAI,eAAe,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAsBvE,SAAS,mBAAmB;IAC1B,MAAM,UAAU,GAAG,oBAAoB,CACrC,gBAAgB,CAAC,iBAAiB,EAClC,qBAAqB,CAAC,UAAU,CACjC,CAAC;IAEF,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,gBAAgB,CAAC,yBAAyB,EAC1C,qBAAqB,CAAC,kBAAkB,CACzC,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;AAC5C,CAAC;AAsBD;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAAG,mBAAmB,EAAE,CAAC;IAEjE,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAA0D,EAC7D,GAAG,EACH,SAAS,EACT,YAAY,EACZ,MAAM,GACuB,EAAE,EAAE;QACjC,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,eAAe,EAAE,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL;;;;WAIG;QACH,QAAQ;QACR;;;WAGG;QACH,SAAS;QACT,UAAU;QACV,kBAAkB;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\nimport {\n ConnectionConfig,\n joinRoom as joinRoomClient,\n leaveRoom as leaveRoomClient,\n} from '../common/client';\n\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\nimport { GenericMetadata } from '../types';\n\n/**\n * Represents the possible statuses of a peer while reconnecting to room\n *\n * - `idle` - No reconnection in progress. See {@link PeerStatus} for more details\n * - `reconnecting` - Peer is in the process of reconnecting.\n * - `error` - There was an error in the reconnection process.\n */\nexport type ReconnectionStatus = 'idle' | 'reconnecting' | 'error';\n\n/**\n * Represents the possible statuses of a peer connection to a room (websocket state).\n *\n * - `idle` - Peer is not connected, either never connected or successfully disconnected.\n * - `connecting` - Peer is in the process of connecting.\n * - `connected` - Peer has successfully connected.\n * - `error` - There was an error in the connection process.\n */\nexport type PeerStatus = 'connecting' | 'connected' | 'error' | 'idle';\n\nfunction useConnectionStatus() {\n const peerStatus = useFishjamEventState(\n ReceivableEvents.PeerStatusChanged,\n RNFishjamClientModule.peerStatus,\n );\n\n const reconnectionStatus = useFishjamEventState(\n ReceivableEvents.ReconnectionStatusChanged,\n RNFishjamClientModule.reconnectionStatus,\n );\n\n return { peerStatus, reconnectionStatus };\n}\nexport type JoinRoomConfig<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n /**\n * Fishjam URL\n */\n url: string;\n /**\n * Token received from server (or Room Manager)\n */\n peerToken: string;\n /**\n * String indexed record with metadata, that will be available to all other peers\n */\n peerMetadata?: PeerMetadata;\n /**\n * Additional connection configuration\n */\n config?: ConnectionConfig;\n};\n\n/**\n * Connect/leave room. And get connection status.\n * @group Hooks\n * @category Connection\n */\nexport function useConnection() {\n const { peerStatus, reconnectionStatus } = useConnectionStatus();\n\n const joinRoom = useCallback(\n async <PeerMetadata extends GenericMetadata = GenericMetadata>({\n url,\n peerToken,\n peerMetadata,\n config,\n }: JoinRoomConfig<PeerMetadata>) => {\n await joinRoomClient(url, peerToken, peerMetadata, config);\n },\n [],\n );\n\n const leaveRoom = useCallback(() => {\n leaveRoomClient();\n }, []);\n\n return {\n /**\n * Join room and start streaming camera and microphone\n *\n * See {@link JoinRoomConfig} for parameter list\n */\n joinRoom,\n /**\n * Leave room and stop streaming\n * @type function\n */\n leaveRoom,\n peerStatus,\n reconnectionStatus,\n };\n}\n"]}
1
+ {"version":3,"file":"useConnection.js","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAEL,QAAQ,IAAI,cAAc,EAC1B,SAAS,IAAI,eAAe,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAqBnD,SAAS,mBAAmB;IAC1B,MAAM,UAAU,GAAG,oBAAoB,CACrC,gBAAgB,CAAC,iBAAiB,EAClC,qBAAqB,CAAC,UAAU,CACjC,CAAC;IAEF,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,gBAAgB,CAAC,yBAAyB,EAC1C,qBAAqB,CAAC,kBAAkB,CACzC,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;AAC5C,CAAC;AAoCD;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAAG,mBAAmB,EAAE,CAAC;IAEjE,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAA0D,EAC7D,GAAG,EACH,SAAS,EACT,YAAY,EACZ,MAAM,EACN,SAAS,GACoB,EAAE,EAAE;QACjC,MAAM,UAAU,GAAG,SAAS;YAC1B,CAAC,CAAC,GAAG,sBAAsB,IAAI,SAAS,EAAE;YAC1C,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;QAEhD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QAED,MAAM,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IACpE,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,eAAe,EAAE,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL;;;;WAIG;QACH,QAAQ;QACR;;;WAGG;QACH,SAAS;QACT,UAAU;QACV,kBAAkB;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\nimport {\n ConnectionConfig,\n joinRoom as joinRoomClient,\n leaveRoom as leaveRoomClient,\n} from '../common/client';\n\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\nimport { GenericMetadata } from '../types';\nimport { FISHJAM_WS_CONNECT_URL } from '../consts';\n\n/**\n * Represents the possible statuses of a peer while reconnecting to room\n *\n * - `idle` - No reconnection in progress. See {@link PeerStatus} for more details\n * - `reconnecting` - Peer is in the process of reconnecting.\n * - `error` - There was an error in the reconnection process.\n */\nexport type ReconnectionStatus = 'idle' | 'reconnecting' | 'error';\n\n/**\n * Represents the possible statuses of a peer connection to a room (websocket state).\n *\n * - `idle` - Peer is not connected, either never connected or successfully disconnected.\n * - `connecting` - Peer is in the process of connecting.\n * - `connected` - Peer has successfully connected.\n * - `error` - There was an error in the connection process.\n */\nexport type PeerStatus = 'connecting' | 'connected' | 'error' | 'idle';\n\nfunction useConnectionStatus() {\n const peerStatus = useFishjamEventState(\n ReceivableEvents.PeerStatusChanged,\n RNFishjamClientModule.peerStatus,\n );\n\n const reconnectionStatus = useFishjamEventState(\n ReceivableEvents.ReconnectionStatusChanged,\n RNFishjamClientModule.reconnectionStatus,\n );\n\n return { peerStatus, reconnectionStatus };\n}\nexport type JoinRoomConfig<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n /**\n * Token received from server (or Room Manager)\n */\n peerToken: string;\n /**\n * String indexed record with metadata, that will be available to all other peers\n */\n peerMetadata?: PeerMetadata;\n /**\n * Additional connection configuration\n */\n config?: ConnectionConfig;\n} & (\n | {\n /**\n * Fishjam ID, which is used to connect to the room.\n * Only use in sandbox.\n * If provided, `url` must not be set.\n */\n fishjamId: string;\n url?: never;\n }\n | {\n /**\n * Fishjam URL, used to connect to the room.\n * If provided, `fishjamId` must not be set.\n */\n url: string;\n fishjamId?: never;\n }\n);\n\n/**\n * Connect/leave room. And get connection status.\n * @group Hooks\n * @category Connection\n */\nexport function useConnection() {\n const { peerStatus, reconnectionStatus } = useConnectionStatus();\n\n const joinRoom = useCallback(\n async <PeerMetadata extends GenericMetadata = GenericMetadata>({\n url,\n peerToken,\n peerMetadata,\n config,\n fishjamId,\n }: JoinRoomConfig<PeerMetadata>) => {\n const connectUrl = fishjamId\n ? `${FISHJAM_WS_CONNECT_URL}/${fishjamId}`\n : undefined;\n\n const fishjamUrl = fishjamId ? connectUrl : url;\n\n if (!fishjamUrl) {\n throw new Error(\n 'Either fishjamId or url must be provided to join the room.',\n );\n }\n\n await joinRoomClient(fishjamUrl, peerToken, peerMetadata, config);\n },\n [],\n );\n\n const leaveRoom = useCallback(() => {\n leaveRoomClient();\n }, []);\n\n return {\n /**\n * Join room and start streaming camera and microphone\n *\n * See {@link JoinRoomConfig} for parameter list\n */\n joinRoom,\n /**\n * Leave room and stop streaming\n * @type function\n */\n leaveRoom,\n peerStatus,\n reconnectionStatus,\n };\n}\n"]}
@@ -4,9 +4,13 @@
4
4
  * @group Hooks
5
5
  */
6
6
  export declare function useMicrophone(): {
7
- /** Informs if microphone is streaming audio */
7
+ /** Informs if microphone audio track is active */
8
8
  isMicrophoneOn: boolean;
9
- /** Function to toggle microphone on/off */
9
+ /** Toggles microphone on/off based on the value of `isMicrophoneOn` */
10
10
  toggleMicrophone: () => Promise<void>;
11
+ /** Starts microphone and requests permission if needed */
12
+ startMicrophone: () => Promise<void>;
13
+ /** Stops microphone (mutes the track without removing it) */
14
+ stopMicrophone: () => Promise<void>;
11
15
  };
12
16
  //# sourceMappingURL=useMicrophone.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMicrophone.d.ts","sourceRoot":"","sources":["../../src/hooks/useMicrophone.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,aAAa;IAWzB,+CAA+C;;IAE/C,2CAA2C;;EAG9C"}
1
+ {"version":3,"file":"useMicrophone.d.ts","sourceRoot":"","sources":["../../src/hooks/useMicrophone.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,aAAa;IAmBzB,kDAAkD;;IAElD,uEAAuE;;IAEvE,0DAA0D;;IAE1D,6DAA6D;;EAGhE"}
@@ -11,11 +11,21 @@ export function useMicrophone() {
11
11
  const toggleMicrophone = useCallback(async () => {
12
12
  await RNFishjamClientModule.toggleMicrophone();
13
13
  }, []);
14
+ const startMicrophone = useCallback(async () => {
15
+ await RNFishjamClientModule.startMicrophone();
16
+ }, []);
17
+ const stopMicrophone = useCallback(async () => {
18
+ await RNFishjamClientModule.stopMicrophone();
19
+ }, []);
14
20
  return {
15
- /** Informs if microphone is streaming audio */
21
+ /** Informs if microphone audio track is active */
16
22
  isMicrophoneOn,
17
- /** Function to toggle microphone on/off */
23
+ /** Toggles microphone on/off based on the value of `isMicrophoneOn` */
18
24
  toggleMicrophone,
25
+ /** Starts microphone and requests permission if needed */
26
+ startMicrophone,
27
+ /** Stops microphone (mutes the track without removing it) */
28
+ stopMicrophone,
19
29
  };
20
30
  }
21
31
  //# sourceMappingURL=useMicrophone.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMicrophone.js","sourceRoot":"","sources":["../../src/hooks/useMicrophone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,cAAc,GAAG,oBAAoB,CACzC,gBAAgB,CAAC,cAAc,EAC/B,qBAAqB,CAAC,cAAc,CACrC,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC9C,MAAM,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;IACjD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,+CAA+C;QAC/C,cAAc;QACd,2CAA2C;QAC3C,gBAAgB;KACjB,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\n\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\n\n/**\n * This hook can toggle microphone on/off and provides current microphone state.\n * @category Devices\n * @group Hooks\n */\nexport function useMicrophone() {\n const isMicrophoneOn = useFishjamEventState(\n ReceivableEvents.IsMicrophoneOn,\n RNFishjamClientModule.isMicrophoneOn,\n );\n\n const toggleMicrophone = useCallback(async () => {\n await RNFishjamClientModule.toggleMicrophone();\n }, []);\n\n return {\n /** Informs if microphone is streaming audio */\n isMicrophoneOn,\n /** Function to toggle microphone on/off */\n toggleMicrophone,\n };\n}\n"]}
1
+ {"version":3,"file":"useMicrophone.js","sourceRoot":"","sources":["../../src/hooks/useMicrophone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,cAAc,GAAG,oBAAoB,CACzC,gBAAgB,CAAC,cAAc,EAC/B,qBAAqB,CAAC,cAAc,CACrC,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC9C,MAAM,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;IACjD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,qBAAqB,CAAC,eAAe,EAAE,CAAC;IAChD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC5C,MAAM,qBAAqB,CAAC,cAAc,EAAE,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,kDAAkD;QAClD,cAAc;QACd,uEAAuE;QACvE,gBAAgB;QAChB,0DAA0D;QAC1D,eAAe;QACf,6DAA6D;QAC7D,cAAc;KACf,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from 'react';\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEventState } from './internal/useFishjamEventState';\n\n/**\n * This hook can toggle microphone on/off and provides current microphone state.\n * @category Devices\n * @group Hooks\n */\nexport function useMicrophone() {\n const isMicrophoneOn = useFishjamEventState(\n ReceivableEvents.IsMicrophoneOn,\n RNFishjamClientModule.isMicrophoneOn,\n );\n\n const toggleMicrophone = useCallback(async () => {\n await RNFishjamClientModule.toggleMicrophone();\n }, []);\n\n const startMicrophone = useCallback(async () => {\n await RNFishjamClientModule.startMicrophone();\n }, []);\n\n const stopMicrophone = useCallback(async () => {\n await RNFishjamClientModule.stopMicrophone();\n }, []);\n\n return {\n /** Informs if microphone audio track is active */\n isMicrophoneOn,\n /** Toggles microphone on/off based on the value of `isMicrophoneOn` */\n toggleMicrophone,\n /** Starts microphone and requests permission if needed */\n startMicrophone,\n /** Stops microphone (mutes the track without removing it) */\n stopMicrophone,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"usePeers.js","sourceRoot":"","sources":["../../src/hooks/usePeers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,qBAAqB,EAAE,EAC5B,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAiF7D,mGAAmG;AACnG,SAAS,mBAAmB,CAI1B,KAAwD;IAExD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,GAAG,IAAI;QACP,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAClC,GAAG,KAAK;YACR,QAAQ,EACL,KAAsC,EAAE,QAAQ,EAAE,MAAM,IAAI,IAAI;SACpE,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,8BAA8B,CAIrC,IAAwC;IAExC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAEpC,MAAM,mBAAmB,GAAwB,EAAE,CAAC;IAEpD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;QAEvC,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,QAAQ;gBACX,mBAAmB,CAAC,WAAW,GAAG,KAAmB,CAAC;gBACtD,MAAM;YACR,KAAK,YAAY;gBACf,mBAAmB,CAAC,eAAe,GAAG,KAAmB,CAAC;gBAC1D,MAAM;YACR,KAAK,kBAAkB;gBACrB,mBAAmB,CAAC,qBAAqB,GAAG,KAAmB,CAAC;gBAChE,MAAM;YACR,KAAK,kBAAkB;gBACrB,mBAAmB,CAAC,qBAAqB,GAAG,KAAmB,CAAC;gBAChE,MAAM;QACV,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,IAAI;QACP,GAAG,mBAAmB;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,kBAAkB,GAAG,GAGvB,EAAE;IACJ,MAAM,mBAAmB,GAAG,WAAW,CACrC,GAAG,EAAE,CACH,mBAAmB,CACjB,qBAAqB,CAAC,QAAQ,EAAgC,CAC/D,EACH,EAAE,CACH,CAAC;IAEF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAClC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAE1B,eAAe,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACvD,eAAe,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IACnE,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAkBF;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ;IAItB,MAAM,KAAK,GAAG,kBAAkB,EAAgC,CAAC;IAEjE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzD,OAAO,aAAa,CAAC,CAAC,CAAC,8BAA8B,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EAAE,CACH,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,8BAA8B,CAAC,EAC3E,CAAC,KAAK,CAAC,CACR,CAAC;IAEF,OAAO;QACL;;;WAGG;QACH,SAAS;QACT;;WAEG;QACH,WAAW;QACX;;;;WAIG;QACH,KAAK;KACN,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback, useMemo, useState } from 'react';\n\nimport { Brand, GenericMetadata, TrackMetadata } from '../types';\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEvent } from './internal/useFishjamEvent';\n\nexport type PeerId = Brand<string, 'PeerId'>;\nexport type TrackId = Brand<string, 'TrackId'>;\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\nexport type PeerTrackMetadata<PeerMetadata, ServerMetadata> = {\n peer: PeerMetadata;\n server: ServerMetadata;\n};\n\nexport type TrackBase = {\n id: TrackId;\n type: TrackType;\n isActive: boolean;\n metadata?: TrackMetadata;\n};\n\nexport type AudioTrack = TrackBase & {\n type: 'Audio';\n vadStatus: VadStatus | undefined;\n};\n\nexport type VideoTrack = TrackBase & {\n type: 'Video';\n aspectRatio: number;\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 DistinguishedTracks = {\n cameraTrack?: VideoTrack;\n microphoneTrack?: AudioTrack;\n screenShareVideoTrack?: VideoTrack;\n screenShareAudioTrack?: AudioTrack;\n};\n\nexport type PeerWithTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = Peer<PeerMetadata, ServerMetadata> & DistinguishedTracks;\n\nexport type Peer<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n /**\n * id used to identify a peer\n */\n id: PeerId;\n /**\n * whether the peer is local or remote\n */\n isLocal: boolean;\n /**\n * a type containing peer and server metadata\n */\n metadata: PeerTrackMetadata<PeerMetadata, ServerMetadata>;\n /**\n * a list of peer's video and audio tracks\n */\n tracks: Track[];\n};\n\n// TODO: This should return a different metadata type if it's requiring it to have a certain field.\nfunction addIsActiveToTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>(\n peers: ReadonlyArray<Peer<PeerMetadata, ServerMetadata>>,\n): Peer<PeerMetadata, ServerMetadata>[] {\n return peers.map((peer) => ({\n ...peer,\n tracks: peer.tracks.map((track) => ({\n ...track,\n isActive:\n (track as { metadata?: TrackMetadata })?.metadata?.active ?? true,\n })),\n }));\n}\n\nfunction getPeerWithDistinguishedTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>(\n peer: Peer<PeerMetadata, ServerMetadata>,\n): PeerWithTracks<PeerMetadata, ServerMetadata> {\n const { tracks: peerTracks } = peer;\n\n const distinguishedTracks: DistinguishedTracks = {};\n\n for (const track of peerTracks) {\n const trackType = track.metadata?.type;\n\n switch (trackType) {\n case 'camera':\n distinguishedTracks.cameraTrack = track as VideoTrack;\n break;\n case 'microphone':\n distinguishedTracks.microphoneTrack = track as AudioTrack;\n break;\n case 'screenShareVideo':\n distinguishedTracks.screenShareVideoTrack = track as VideoTrack;\n break;\n case 'screenShareAudio':\n distinguishedTracks.screenShareAudioTrack = track as AudioTrack;\n break;\n }\n }\n\n return {\n ...peer,\n ...distinguishedTracks,\n };\n}\n\nconst usePeersEventState = <\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>() => {\n const getTransformedPeers = useCallback(\n () =>\n addIsActiveToTracks(\n RNFishjamClientModule.getPeers<PeerMetadata, ServerMetadata>(),\n ),\n [],\n );\n\n const [value, setValue] = useState(getTransformedPeers());\n\n const onEvent = useCallback(() => {\n setValue(getTransformedPeers());\n }, [getTransformedPeers]);\n\n useFishjamEvent(ReceivableEvents.PeersUpdate, onEvent);\n useFishjamEvent(ReceivableEvents.TrackAspectRatioUpdated, onEvent);\n return value;\n};\n\n/**\n * Result type for the usePeers hook.\n * @template PeerMetadata - Type for peer-specific metadata\n * @template ServerMetadata - Type for server-specific metadata\n */\nexport type UsePeersResult<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n localPeer: PeerWithTracks<PeerMetadata, ServerMetadata> | null;\n\n remotePeers: PeerWithTracks<PeerMetadata, ServerMetadata>[];\n\n peers: Peer<PeerMetadata, ServerMetadata>[];\n};\n\n/**\n * Hook that provides live updates of room peers.\n * @template PeerMetadata - Type for peer-specific metadata\n * @template ServerMetadata - Type for server-specific metadata\n * @category Connection\n * @group Hooks\n */\nexport function usePeers<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>() {\n const peers = usePeersEventState<PeerMetadata, ServerMetadata>();\n\n const localPeer = useMemo(() => {\n const localPeerData = peers.find((peer) => peer.isLocal);\n return localPeerData ? getPeerWithDistinguishedTracks(localPeerData) : null;\n }, [peers]);\n\n const remotePeers = useMemo(\n () =>\n peers.filter((peer) => !peer.isLocal).map(getPeerWithDistinguishedTracks),\n [peers],\n );\n\n return {\n /**\n * The local peer with distinguished tracks (camera, microphone, screen share).\n * Will be null if the local peer is not found.\n */\n localPeer,\n /**\n * Array of remote peers with distinguished tracks (camera, microphone, screen share).\n */\n remotePeers,\n /**\n * @deprecated Use localPeer and remotePeers instead\n * Legacy array containing all peers (both local and remote) without distinguished tracks.\n * This property will be removed in future versions.\n */\n peers,\n };\n}\n"]}
1
+ {"version":3,"file":"usePeers.js","sourceRoot":"","sources":["../../src/hooks/usePeers.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useMemo, useState } from 'react';\n\nimport { Brand, GenericMetadata, TrackMetadata } from '../types';\nimport RNFishjamClientModule, {\n ReceivableEvents,\n} from '../RNFishjamClientModule';\nimport { useFishjamEvent } from './internal/useFishjamEvent';\n\nexport type PeerId = Brand<string, 'PeerId'>;\nexport type TrackId = Brand<string, 'TrackId'>;\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\nexport type PeerTrackMetadata<PeerMetadata, ServerMetadata> = {\n peer: PeerMetadata;\n server: ServerMetadata;\n};\n\nexport type TrackBase = {\n id: TrackId;\n type: TrackType;\n isActive: boolean;\n metadata?: TrackMetadata;\n};\n\nexport type AudioTrack = TrackBase & {\n type: 'Audio';\n vadStatus: VadStatus | undefined;\n};\n\nexport type VideoTrack = TrackBase & {\n type: 'Video';\n aspectRatio: number;\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 DistinguishedTracks = {\n cameraTrack?: VideoTrack;\n microphoneTrack?: AudioTrack;\n screenShareVideoTrack?: VideoTrack;\n screenShareAudioTrack?: AudioTrack;\n};\n\nexport type PeerWithTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = Peer<PeerMetadata, ServerMetadata> & DistinguishedTracks;\n\nexport type Peer<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n /**\n * id used to identify a peer\n */\n id: PeerId;\n /**\n * whether the peer is local or remote\n */\n isLocal: boolean;\n /**\n * a type containing peer and server metadata\n */\n metadata: PeerTrackMetadata<PeerMetadata, ServerMetadata>;\n /**\n * a list of peer's video and audio tracks\n */\n tracks: Track[];\n};\n\n// TODO: This should return a different metadata type if it's requiring it to have a certain field.\nfunction addIsActiveToTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>(\n peers: readonly Peer<PeerMetadata, ServerMetadata>[],\n): Peer<PeerMetadata, ServerMetadata>[] {\n return peers.map((peer) => ({\n ...peer,\n tracks: peer.tracks.map((track) => ({\n ...track,\n isActive:\n (track as { metadata?: TrackMetadata })?.metadata?.active ?? true,\n })),\n }));\n}\n\nfunction getPeerWithDistinguishedTracks<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>(\n peer: Peer<PeerMetadata, ServerMetadata>,\n): PeerWithTracks<PeerMetadata, ServerMetadata> {\n const { tracks: peerTracks } = peer;\n\n const distinguishedTracks: DistinguishedTracks = {};\n\n for (const track of peerTracks) {\n const trackType = track.metadata?.type;\n\n switch (trackType) {\n case 'camera':\n distinguishedTracks.cameraTrack = track as VideoTrack;\n break;\n case 'microphone':\n distinguishedTracks.microphoneTrack = track as AudioTrack;\n break;\n case 'screenShareVideo':\n distinguishedTracks.screenShareVideoTrack = track as VideoTrack;\n break;\n case 'screenShareAudio':\n distinguishedTracks.screenShareAudioTrack = track as AudioTrack;\n break;\n }\n }\n\n return {\n ...peer,\n ...distinguishedTracks,\n };\n}\n\nconst usePeersEventState = <\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>() => {\n const getTransformedPeers = useCallback(\n () =>\n addIsActiveToTracks(\n RNFishjamClientModule.getPeers<PeerMetadata, ServerMetadata>(),\n ),\n [],\n );\n\n const [value, setValue] = useState(getTransformedPeers());\n\n const onEvent = useCallback(() => {\n setValue(getTransformedPeers());\n }, [getTransformedPeers]);\n\n useFishjamEvent(ReceivableEvents.PeersUpdate, onEvent);\n useFishjamEvent(ReceivableEvents.TrackAspectRatioUpdated, onEvent);\n return value;\n};\n\n/**\n * Result type for the usePeers hook.\n * @template PeerMetadata - Type for peer-specific metadata\n * @template ServerMetadata - Type for server-specific metadata\n */\nexport type UsePeersResult<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n> = {\n localPeer: PeerWithTracks<PeerMetadata, ServerMetadata> | null;\n\n remotePeers: PeerWithTracks<PeerMetadata, ServerMetadata>[];\n\n peers: Peer<PeerMetadata, ServerMetadata>[];\n};\n\n/**\n * Hook that provides live updates of room peers.\n * @template PeerMetadata - Type for peer-specific metadata\n * @template ServerMetadata - Type for server-specific metadata\n * @category Connection\n * @group Hooks\n */\nexport function usePeers<\n PeerMetadata extends GenericMetadata = GenericMetadata,\n ServerMetadata extends GenericMetadata = GenericMetadata,\n>() {\n const peers = usePeersEventState<PeerMetadata, ServerMetadata>();\n\n const localPeer = useMemo(() => {\n const localPeerData = peers.find((peer) => peer.isLocal);\n return localPeerData ? getPeerWithDistinguishedTracks(localPeerData) : null;\n }, [peers]);\n\n const remotePeers = useMemo(\n () =>\n peers.filter((peer) => !peer.isLocal).map(getPeerWithDistinguishedTracks),\n [peers],\n );\n\n return {\n /**\n * The local peer with distinguished tracks (camera, microphone, screen share).\n * Will be null if the local peer is not found.\n */\n localPeer,\n /**\n * Array of remote peers with distinguished tracks (camera, microphone, screen share).\n */\n remotePeers,\n /**\n * @deprecated Use localPeer and remotePeers instead\n * Legacy array containing all peers (both local and remote) without distinguished tracks.\n * This property will be removed in future versions.\n */\n peers,\n };\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { PermissionResponse } from 'expo-modules-core';
2
+ /**
3
+ * Check or request permissions to access the camera.
4
+ * This uses both `requestCameraPermissionsAsync` and `getCameraPermissionsAsync` to interact with the permissions.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { useCameraPermissions } from '@fishjam-cloud/react-native-client';
9
+ * const [status, requestPermission] = useCameraPermissions();
10
+ * ```
11
+ */
12
+ export declare const useCameraPermissions: (options?: import("expo-modules-core").PermissionHookOptions<object> | undefined) => [PermissionResponse | null, () => Promise<PermissionResponse>, () => Promise<PermissionResponse>];
13
+ /**
14
+ * Check or request permissions to access the microphone.
15
+ * This uses both `requestMicrophonePermissionsAsync` and `getMicrophonePermissionsAsync` to interact with the permissions.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { useMicrophonePermissions } from '@fishjam-cloud/react-native-client';
20
+ * const [status, requestPermission] = useMicrophonePermissions();
21
+ * ```
22
+ */
23
+ export declare const useMicrophonePermissions: (options?: import("expo-modules-core").PermissionHookOptions<object> | undefined) => [PermissionResponse | null, () => Promise<PermissionResponse>, () => Promise<PermissionResponse>];
24
+ //# sourceMappingURL=usePermissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePermissions.d.ts","sourceRoot":"","sources":["../../src/hooks/usePermissions.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAmB7E;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,wLAG/B,CAAC;AAmBH;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,wLAGnC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import RNFishjamClient from '../RNFishjamClientModule';
2
+ import { createPermissionHook } from 'expo-modules-core';
3
+ /**
4
+ * Checks user's permissions for accessing camera.
5
+ * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).
6
+ */
7
+ async function getCameraPermissionsAsync() {
8
+ return RNFishjamClient.getCameraPermissionsAsync();
9
+ }
10
+ /**
11
+ * Asks the user to grant permissions for accessing camera.
12
+ * On iOS this will require apps to specify an `NSCameraUsageDescription` entry in the **Info.plist**.
13
+ * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).
14
+ */
15
+ async function requestCameraPermissionsAsync() {
16
+ return RNFishjamClient.requestCameraPermissionsAsync();
17
+ }
18
+ /**
19
+ * Check or request permissions to access the camera.
20
+ * This uses both `requestCameraPermissionsAsync` and `getCameraPermissionsAsync` to interact with the permissions.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { useCameraPermissions } from '@fishjam-cloud/react-native-client';
25
+ * const [status, requestPermission] = useCameraPermissions();
26
+ * ```
27
+ */
28
+ export const useCameraPermissions = createPermissionHook({
29
+ getMethod: getCameraPermissionsAsync,
30
+ requestMethod: requestCameraPermissionsAsync,
31
+ });
32
+ /**
33
+ * Checks user's permissions for accessing microphone.
34
+ * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).
35
+ */
36
+ async function getMicrophonePermissionsAsync() {
37
+ return RNFishjamClient.getMicrophonePermissionsAsync();
38
+ }
39
+ /**
40
+ * Asks the user to grant permissions for accessing the microphone.
41
+ * On iOS this will require apps to specify an `NSMicrophoneUsageDescription` entry in the **Info.plist**.
42
+ * @return A promise that resolves to an object of type [PermissionResponse](#permissionresponse).
43
+ */
44
+ async function requestMicrophonePermissionsAsync() {
45
+ return RNFishjamClient.requestMicrophonePermissionsAsync();
46
+ }
47
+ /**
48
+ * Check or request permissions to access the microphone.
49
+ * This uses both `requestMicrophonePermissionsAsync` and `getMicrophonePermissionsAsync` to interact with the permissions.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * import { useMicrophonePermissions } from '@fishjam-cloud/react-native-client';
54
+ * const [status, requestPermission] = useMicrophonePermissions();
55
+ * ```
56
+ */
57
+ export const useMicrophonePermissions = createPermissionHook({
58
+ getMethod: getMicrophonePermissionsAsync,
59
+ requestMethod: requestMicrophonePermissionsAsync,
60
+ });
61
+ //# sourceMappingURL=usePermissions.js.map
@@ -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"]}
@@ -0,0 +1,13 @@
1
+ import { RoomType } from '../types';
2
+ export type UseSandboxProps = {
3
+ fishjamId: string;
4
+ fishjamUrl?: never;
5
+ } | {
6
+ fishjamId?: never;
7
+ fishjamUrl: string;
8
+ };
9
+ export declare const useSandbox: ({ fishjamId, fishjamUrl }: UseSandboxProps) => {
10
+ getSandboxPeerToken: (roomName: string, peerName: string, roomType?: RoomType) => Promise<string>;
11
+ getSandboxViewerToken: (roomName: string) => Promise<string>;
12
+ };
13
+ //# sourceMappingURL=useSandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSandbox.d.ts","sourceRoot":"","sources":["../../src/hooks/useSandbox.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAUpC,MAAM,MAAM,eAAe,GACvB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GACzC;IAAE,SAAS,CAAC,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C,eAAO,MAAM,UAAU,GAAI,2BAA2B,eAAe;oCAMvD,MAAM,YACN,MAAM,aACN,QAAQ;sCA0B2B,MAAM;CA2BtD,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { FISHJAM_HTTP_CONNECT_URL } from '../consts';
2
+ export const useSandbox = ({ fishjamId, fishjamUrl }) => {
3
+ const managerUrl = fishjamUrl
4
+ ? `${fishjamUrl}/room-manager`
5
+ : `${FISHJAM_HTTP_CONNECT_URL}/${fishjamId}/room-manager`;
6
+ const getSandboxPeerToken = async (roomName, peerName, roomType = 'conference') => {
7
+ try {
8
+ const url = new URL(managerUrl);
9
+ url.searchParams.set('roomName', roomName);
10
+ url.searchParams.set('peerName', peerName);
11
+ url.searchParams.set('roomType', roomType);
12
+ const res = await fetch(url.toString());
13
+ if (!res.ok) {
14
+ throw new Error(`Room '${roomName}' or peer '${peerName}' does not exist or cannot retrieve peer token.`);
15
+ }
16
+ const data = await res.json();
17
+ return data.peerToken;
18
+ }
19
+ catch (error) {
20
+ throw new Error(`Failed to get peer token for room '${roomName}', peer '${peerName}': ${error instanceof Error ? error.message : String(error)}`);
21
+ }
22
+ };
23
+ const getSandboxViewerToken = async (roomName) => {
24
+ try {
25
+ const url = new URL(`${managerUrl}/${roomName}/livestream-viewer-token`);
26
+ const res = await fetch(url);
27
+ if (!res.ok) {
28
+ throw new Error(`Room '${roomName}' does not exist or cannot retrieve viewer token.`);
29
+ }
30
+ const data = await res.json();
31
+ return data.token;
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Failed to get viewer token for room '${roomName}': ${error instanceof Error ? error.message : String(error)}`);
35
+ }
36
+ };
37
+ return {
38
+ getSandboxPeerToken,
39
+ getSandboxViewerToken,
40
+ };
41
+ };
42
+ //# sourceMappingURL=useSandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSandbox.js","sourceRoot":"","sources":["../../src/hooks/useSandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAerD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAE,SAAS,EAAE,UAAU,EAAmB,EAAE,EAAE;IACvE,MAAM,UAAU,GAAG,UAAU;QAC3B,CAAC,CAAC,GAAG,UAAU,eAAe;QAC9B,CAAC,CAAC,GAAG,wBAAwB,IAAI,SAAS,eAAe,CAAC;IAE5D,MAAM,mBAAmB,GAAG,KAAK,EAC/B,QAAgB,EAChB,QAAgB,EAChB,WAAqB,YAAY,EACjC,EAAE;QACF,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;YAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAE3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAExC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,SAAS,QAAQ,cAAc,QAAQ,iDAAiD,CACzF,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,GAAwB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,sCAAsC,QAAQ,YAAY,QAAQ,MAChE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;QACvD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,UAAU,IAAI,QAAQ,0BAA0B,CAAC,CAAC;YACzE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAE7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,SAAS,QAAQ,mDAAmD,CACrE,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAsB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAEjD,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,wCAAwC,QAAQ,MAC9C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,mBAAmB;QACnB,qBAAqB;KACtB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FISHJAM_HTTP_CONNECT_URL } from '../consts';\nimport { RoomType } from '../types';\n\ntype BasicInfo = { id: string; name: string };\ntype RoomManagerResponse = {\n peerToken: string;\n url: string;\n room: BasicInfo;\n peer: BasicInfo;\n};\n\nexport type UseSandboxProps =\n | { fishjamId: string; fishjamUrl?: never }\n | { fishjamId?: never; fishjamUrl: string };\n\nexport const useSandbox = ({ fishjamId, fishjamUrl }: UseSandboxProps) => {\n const managerUrl = fishjamUrl\n ? `${fishjamUrl}/room-manager`\n : `${FISHJAM_HTTP_CONNECT_URL}/${fishjamId}/room-manager`;\n\n const getSandboxPeerToken = async (\n roomName: string,\n peerName: string,\n roomType: RoomType = 'conference',\n ) => {\n try {\n const url = new URL(managerUrl);\n url.searchParams.set('roomName', roomName);\n url.searchParams.set('peerName', peerName);\n url.searchParams.set('roomType', roomType);\n\n const res = await fetch(url.toString());\n\n if (!res.ok) {\n throw new Error(\n `Room '${roomName}' or peer '${peerName}' does not exist or cannot retrieve peer token.`,\n );\n }\n const data: RoomManagerResponse = await res.json();\n return data.peerToken;\n } catch (error) {\n throw new Error(\n `Failed to get peer token for room '${roomName}', peer '${peerName}': ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n };\n\n const getSandboxViewerToken = async (roomName: string) => {\n try {\n const url = new URL(`${managerUrl}/${roomName}/livestream-viewer-token`);\n const res = await fetch(url);\n\n if (!res.ok) {\n throw new Error(\n `Room '${roomName}' does not exist or cannot retrieve viewer token.`,\n );\n }\n\n const data: { token: string } = await res.json();\n\n return data.token;\n } catch (error) {\n throw new Error(\n `Failed to get viewer token for room '${roomName}': ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n };\n\n return {\n getSandboxPeerToken,\n getSandboxViewerToken,\n };\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
@@ -1,4 +1,4 @@
1
- export type { SimulcastConfig, VideoLayout, GenericMetadata, TrackMetadata, Brand, } from './types';
1
+ export type { SimulcastConfig, VideoLayout, GenericMetadata, TrackMetadata, Brand, RoomType, } from './types';
2
2
  export type { ConnectionConfig } from './common/client';
3
3
  export { updatePeerMetadata } from './common/metadata';
4
4
  export {
@@ -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';
@@ -20,6 +20,7 @@ export type { ForegroundServiceConfig } from './hooks/useForegroundService';
20
20
  export type { JoinRoomConfig, ReconnectionStatus, PeerStatus, } from './hooks/useConnection';
21
21
  export type { AppScreenShareData } from './hooks/useAppScreenShare';
22
22
  export type { UseLivestreamResult } from './hooks/useLivestream';
23
+ export type { UseSandboxProps } from './hooks/useSandbox';
23
24
  export { useAudioSettings } from './hooks/useAudioSettings';
24
25
  export { useBandwidthEstimation } from './hooks/useBandwidthEstimation';
25
26
  export { useCamera } from './hooks/useCamera';
@@ -33,6 +34,8 @@ export { useForegroundService } from './hooks/useForegroundService';
33
34
  export { useConnection } from './hooks/useConnection';
34
35
  export { useUpdatePeerMetadata } from './hooks/useUpdatePeerMetadata';
35
36
  export { useLivestream } from './hooks/useLivestream';
37
+ export { useSandbox } from './hooks/useSandbox';
38
+ export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
36
39
  export type { FishjamRoomProps } from './components/FishjamRoom';
37
40
  export { FishjamRoom } from './components/FishjamRoom';
38
41
  //# 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,EACL,QAAQ,GACT,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;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1D,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,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,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,9 @@ 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
+ export { useSandbox } from './hooks/useSandbox';
29
+ // #endregion
30
+ export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
28
31
  export { FishjamRoom } from './components/FishjamRoom';
29
32
  initializeWarningListener();
30
33
  //# 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;AAYlE,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;AAiD7D,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,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,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 RoomType,\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';\nexport type { UseSandboxProps } from './hooks/useSandbox';\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';\nexport { useSandbox } from './hooks/useSandbox';\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"]}
package/build/types.d.ts CHANGED
@@ -29,5 +29,6 @@ declare const brand: unique symbol;
29
29
  export type Brand<T, TBrand extends string> = T & {
30
30
  [brand]: TBrand;
31
31
  };
32
+ export type RoomType = 'conference' | 'audio-only' | 'livestream';
32
33
  export {};
33
34
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGtD,OAAO,CAAC,MAAM,KAAK,EAAE,OAAO,MAAM,CAAC;AACnC;;GAEG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,MAAM,SAAS,MAAM,IAAI,CAAC,GAAG;IAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGtD,OAAO,CAAC,MAAM,KAAK,EAAE,OAAO,MAAM,CAAC;AACnC;;GAEG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,MAAM,SAAS,MAAM,IAAI,CAAC,GAAG;IAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","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 */\nexport type VideoLayout = 'FILL' | 'FIT';\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\nexport type TrackMetadata = {\n active: boolean;\n type: 'microphone' | 'camera' | 'screenShareVideo' | 'screenShareAudio';\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;\n/**\n * Branded type\n */\nexport type Brand<T, TBrand extends string> = T & { [brand]: TBrand };\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","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 */\nexport type VideoLayout = 'FILL' | 'FIT';\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\nexport type TrackMetadata = {\n active: boolean;\n type: 'microphone' | 'camera' | 'screenShareVideo' | 'screenShareAudio';\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;\n/**\n * Branded type\n */\nexport type Brand<T, TBrand extends string> = T & { [brand]: TBrand };\n\nexport type RoomType = 'conference' | 'audio-only' | 'livestream';\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
+ }