@fishjam-cloud/react-native-client 0.19.0 → 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.
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +25 -15
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +12 -0
- package/build/consts/index.d.ts +3 -0
- package/build/consts/index.d.ts.map +1 -0
- package/build/consts/index.js +4 -0
- package/build/consts/index.js.map +1 -0
- package/build/hooks/useConnection.d.ts +18 -7
- package/build/hooks/useConnection.d.ts.map +1 -1
- package/build/hooks/useConnection.js +10 -2
- package/build/hooks/useConnection.js.map +1 -1
- package/build/hooks/useMicrophone.d.ts +6 -2
- package/build/hooks/useMicrophone.d.ts.map +1 -1
- package/build/hooks/useMicrophone.js +12 -2
- package/build/hooks/useMicrophone.js.map +1 -1
- package/build/hooks/useSandbox.d.ts +13 -0
- package/build/hooks/useSandbox.d.ts.map +1 -0
- package/build/hooks/useSandbox.js +42 -0
- package/build/hooks/useSandbox.js.map +1 -0
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/types.d.ts +1 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/ios/RNFishjamClient.swift +31 -20
- package/ios/RNFishjamClientModule.swift +8 -0
- package/package.json +1 -1
- package/plugin/build/types.d.ts +3 -0
- package/plugin/build/withFishjamIos.d.ts +1 -1
- package/plugin/build/withFishjamIos.js +53 -40
|
@@ -392,15 +392,26 @@ class RNFishjamClient(
|
|
|
392
392
|
localTracksSwitchListenerManager.notifySwitched()
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
395
|
+
suspend fun startMicrophone() {
|
|
396
|
+
// If microphone track already exist, just enable it
|
|
397
|
+
if (getLocalAudioTrack() != null) {
|
|
398
|
+
getLocalAudioTrack()?.let { setMicrophoneTrackState(it, true) }
|
|
399
|
+
} else {
|
|
400
|
+
if (!PermissionUtils.requestMicrophonePermission(appContext)) {
|
|
401
|
+
emitEvent(EmitableEvent.warning("Microphone permission not granted."))
|
|
402
|
+
return
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
val microphoneTrack = fishjamClient.createAudioTrack(getMicrophoneTrackMetadata(true))
|
|
406
|
+
setMicrophoneTrackState(microphoneTrack, true)
|
|
407
|
+
emitEndpoints()
|
|
399
408
|
}
|
|
409
|
+
}
|
|
400
410
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
411
|
+
fun stopMicrophone() {
|
|
412
|
+
if (getLocalAudioTrack() != null) {
|
|
413
|
+
getLocalAudioTrack()?.let { setMicrophoneTrackState(it, false) }
|
|
414
|
+
}
|
|
404
415
|
}
|
|
405
416
|
|
|
406
417
|
private fun setMicrophoneTrackState(
|
|
@@ -409,25 +420,24 @@ class RNFishjamClient(
|
|
|
409
420
|
) {
|
|
410
421
|
microphoneTrack.setEnabled(isEnabled)
|
|
411
422
|
isMicrophoneOn = isEnabled
|
|
423
|
+
updateLocalAudioTrackMetadata(getMicrophoneTrackMetadata(isEnabled))
|
|
412
424
|
emitEvent(EmitableEvent.isMicrophoneOn(isEnabled))
|
|
413
425
|
}
|
|
414
426
|
|
|
415
427
|
suspend fun toggleMicrophone(): Boolean {
|
|
416
|
-
if (
|
|
417
|
-
|
|
428
|
+
if (isMicrophoneOn) {
|
|
429
|
+
stopMicrophone()
|
|
418
430
|
} else {
|
|
419
|
-
|
|
431
|
+
startMicrophone()
|
|
420
432
|
}
|
|
421
433
|
|
|
422
|
-
updateLocalAudioTrackMetadata(getMicrophoneTrackMetadata())
|
|
423
|
-
|
|
424
434
|
return isMicrophoneOn
|
|
425
435
|
}
|
|
426
436
|
|
|
427
|
-
private fun getMicrophoneTrackMetadata(): Map<String, Any> =
|
|
437
|
+
private fun getMicrophoneTrackMetadata(isEnabled: Boolean): Map<String, Any> =
|
|
428
438
|
mapOf(
|
|
429
|
-
"active" to
|
|
430
|
-
"paused" to !
|
|
439
|
+
"active" to isEnabled,
|
|
440
|
+
"paused" to !isEnabled, // TODO: FCE-711,
|
|
431
441
|
"type" to "microphone"
|
|
432
442
|
)
|
|
433
443
|
|
|
@@ -182,6 +182,18 @@ class RNFishjamClientModule : Module() {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
AsyncFunction("startMicrophone") Coroutine { ->
|
|
186
|
+
withContext(Dispatchers.Main) {
|
|
187
|
+
rnFishjamClient.startMicrophone()
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
AsyncFunction("stopMicrophone") Coroutine { ->
|
|
192
|
+
withContext(Dispatchers.Main) {
|
|
193
|
+
rnFishjamClient.stopMicrophone()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
185
197
|
AsyncFunction("toggleCamera") Coroutine { ->
|
|
186
198
|
withContext(Dispatchers.Main) {
|
|
187
199
|
rnFishjamClient.toggleCamera()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consts/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,sCAAoC,CAAC;AAC1E,eAAO,MAAM,sBAAsB,oCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consts/index.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAEzD,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,oBAAoB,EAAE,CAAC;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,oBAAoB,EAAE,CAAC","sourcesContent":["const FISHJAM_CONNECT_PATH = 'fishjam.io/api/v1/connect';\n\nexport const FISHJAM_HTTP_CONNECT_URL = `https://${FISHJAM_CONNECT_PATH}`;\nexport const FISHJAM_WS_CONNECT_URL = `wss://${FISHJAM_CONNECT_PATH}`;\n"]}
|
|
@@ -18,10 +18,6 @@ export type ReconnectionStatus = 'idle' | 'reconnecting' | 'error';
|
|
|
18
18
|
*/
|
|
19
19
|
export type PeerStatus = 'connecting' | 'connected' | 'error' | 'idle';
|
|
20
20
|
export type JoinRoomConfig<PeerMetadata extends GenericMetadata = GenericMetadata> = {
|
|
21
|
-
/**
|
|
22
|
-
* Fishjam URL
|
|
23
|
-
*/
|
|
24
|
-
url: string;
|
|
25
21
|
/**
|
|
26
22
|
* Token received from server (or Room Manager)
|
|
27
23
|
*/
|
|
@@ -31,10 +27,25 @@ export type JoinRoomConfig<PeerMetadata extends GenericMetadata = GenericMetadat
|
|
|
31
27
|
*/
|
|
32
28
|
peerMetadata?: PeerMetadata;
|
|
33
29
|
/**
|
|
34
|
-
*
|
|
30
|
+
* Additional connection configuration
|
|
35
31
|
*/
|
|
36
32
|
config?: ConnectionConfig;
|
|
37
|
-
}
|
|
33
|
+
} & ({
|
|
34
|
+
/**
|
|
35
|
+
* Fishjam ID, which is used to connect to the room.
|
|
36
|
+
* Only use in sandbox.
|
|
37
|
+
* If provided, `url` must not be set.
|
|
38
|
+
*/
|
|
39
|
+
fishjamId: string;
|
|
40
|
+
url?: never;
|
|
41
|
+
} | {
|
|
42
|
+
/**
|
|
43
|
+
* Fishjam URL, used to connect to the room.
|
|
44
|
+
* If provided, `fishjamId` must not be set.
|
|
45
|
+
*/
|
|
46
|
+
url: string;
|
|
47
|
+
fishjamId?: never;
|
|
48
|
+
});
|
|
38
49
|
/**
|
|
39
50
|
* Connect/leave room. And get connection status.
|
|
40
51
|
* @group Hooks
|
|
@@ -46,7 +57,7 @@ export declare function useConnection(): {
|
|
|
46
57
|
*
|
|
47
58
|
* See {@link JoinRoomConfig} for parameter list
|
|
48
59
|
*/
|
|
49
|
-
joinRoom: <PeerMetadata extends GenericMetadata = GenericMetadata>({ url, peerToken, peerMetadata, config, }: JoinRoomConfig<PeerMetadata>) => Promise<void>;
|
|
60
|
+
joinRoom: <PeerMetadata extends GenericMetadata = GenericMetadata>({ url, peerToken, peerMetadata, config, fishjamId, }: JoinRoomConfig<PeerMetadata>) => Promise<void>;
|
|
50
61
|
/**
|
|
51
62
|
* Leave room and stop streaming
|
|
52
63
|
* @type function
|
|
@@ -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;
|
|
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
|
-
|
|
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;
|
|
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
|
|
7
|
+
/** Informs if microphone audio track is active */
|
|
8
8
|
isMicrophoneOn: boolean;
|
|
9
|
-
/**
|
|
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":"
|
|
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
|
|
21
|
+
/** Informs if microphone audio track is active */
|
|
16
22
|
isMicrophoneOn,
|
|
17
|
-
/**
|
|
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;
|
|
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"]}
|
|
@@ -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"]}
|
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 {
|
|
@@ -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,7 @@ 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';
|
|
36
38
|
export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
|
|
37
39
|
export type { FishjamRoomProps } from './components/FishjamRoom';
|
|
38
40
|
export { FishjamRoom } from './components/FishjamRoom';
|
package/build/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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,7 @@ 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';
|
|
28
29
|
// #endregion
|
|
29
30
|
export { useCameraPermissions, useMicrophonePermissions, } from './hooks/usePermissions';
|
|
30
31
|
export { FishjamRoom } from './components/FishjamRoom';
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;
|
|
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
package/build/types.d.ts.map
CHANGED
|
@@ -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"}
|
package/build/types.js.map
CHANGED
|
@@ -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"]}
|
|
@@ -328,40 +328,51 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
func toggleMicrophone() async throws -> Bool {
|
|
331
|
-
if
|
|
332
|
-
|
|
331
|
+
if isMicrophoneOn {
|
|
332
|
+
try stopMicrophone()
|
|
333
333
|
} else {
|
|
334
|
-
|
|
334
|
+
try await startMicrophone()
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
try updateLocalAudioTrackMetadata(metadata: getMicrophoneTrackMetadata())
|
|
338
|
-
|
|
339
337
|
return isMicrophoneOn
|
|
340
338
|
}
|
|
341
339
|
|
|
342
340
|
func startMicrophone() async throws {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
341
|
+
// If microphone track already exist, just enable it
|
|
342
|
+
if let microphoneTrack = getLocalAudioTrack() {
|
|
343
|
+
try setMicrophoneTrackState(microphoneTrack, enabled: true)
|
|
344
|
+
} else {
|
|
345
|
+
guard await PermissionUtils.requestMicrophonePermission() else {
|
|
346
|
+
emit(event: .warning(message: "Microphone permission not granted."))
|
|
347
|
+
return
|
|
348
|
+
}
|
|
349
|
+
let microphoneTrack = RNFishjamClient.fishjamClient!.createAudioTrack(
|
|
350
|
+
metadata: getMicrophoneTrackMetadata(isEnabled: true).toMetadata())
|
|
351
|
+
setAudioSessionMode()
|
|
352
|
+
try setMicrophoneTrackState(microphoneTrack, enabled: true)
|
|
353
|
+
emitEndpoints()
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
func stopMicrophone() throws {
|
|
358
|
+
guard let microphoneTrack = getLocalAudioTrack() else {
|
|
359
|
+
return
|
|
360
|
+
}
|
|
361
|
+
try setMicrophoneTrackState(microphoneTrack, enabled: false)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
private func getMicrophoneTrackMetadata(isEnabled: Bool) -> [String: Any] {
|
|
355
365
|
return [
|
|
356
|
-
"active":
|
|
357
|
-
"paused": !
|
|
366
|
+
"active": isEnabled,
|
|
367
|
+
"paused": !isEnabled, //TODO: FCE-711
|
|
358
368
|
"type": "microphone",
|
|
359
369
|
]
|
|
360
370
|
}
|
|
361
371
|
|
|
362
|
-
private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, enabled: Bool) {
|
|
372
|
+
private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, enabled: Bool) throws {
|
|
363
373
|
microphoneTrack.enabled = enabled
|
|
364
374
|
isMicrophoneOn = enabled
|
|
375
|
+
try updateLocalAudioTrackMetadata(metadata: getMicrophoneTrackMetadata(isEnabled: enabled))
|
|
365
376
|
emit(event: .isMicrophoneOn(enabled: enabled))
|
|
366
377
|
}
|
|
367
378
|
|
|
@@ -146,6 +146,14 @@ public class RNFishjamClientModule: Module {
|
|
|
146
146
|
AsyncFunction("toggleMicrophone") {
|
|
147
147
|
try await rnFishjamClient.toggleMicrophone()
|
|
148
148
|
}
|
|
149
|
+
|
|
150
|
+
AsyncFunction("startMicrophone") {
|
|
151
|
+
try await rnFishjamClient.startMicrophone()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
AsyncFunction("stopMicrophone") {
|
|
155
|
+
try rnFishjamClient.stopMicrophone()
|
|
156
|
+
}
|
|
149
157
|
|
|
150
158
|
AsyncFunction("toggleCamera") {
|
|
151
159
|
try rnFishjamClient.toggleCamera()
|
package/package.json
CHANGED
package/plugin/build/types.d.ts
CHANGED
|
@@ -7,5 +7,8 @@ export type FishjamPluginOptions = {
|
|
|
7
7
|
iphoneDeploymentTarget?: string;
|
|
8
8
|
enableScreensharing?: boolean;
|
|
9
9
|
supportsPictureInPicture?: boolean;
|
|
10
|
+
appGroupContainerId?: string;
|
|
11
|
+
mainTargetName?: string;
|
|
12
|
+
broadcastExtensionTargetName?: string;
|
|
10
13
|
};
|
|
11
14
|
} | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
2
|
import { FishjamPluginOptions } from './types';
|
|
3
|
-
export declare
|
|
3
|
+
export declare function getSbePodfileSnippet(props: FishjamPluginOptions): string;
|
|
4
4
|
/**
|
|
5
5
|
* Applies screen sharing plugin if enabled. In order for screensharing to work, we need to copy extension files to your iOS project.
|
|
6
6
|
* Allows for dynamically changing deploymentTarget.
|
|
@@ -33,16 +33,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.getSbePodfileSnippet = getSbePodfileSnippet;
|
|
37
37
|
// ios-related code was mostly copied from OneSignal expo plugin: https://github.com/OneSignal/onesignal-expo-plugin/blob/main/onesignal/withOneSignalIos.ts
|
|
38
38
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
39
39
|
const fs = __importStar(require("promise-fs"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
function getSbeTargetName(props) {
|
|
42
|
+
return (props?.ios?.broadcastExtensionTargetName ||
|
|
43
|
+
'FishjamScreenBroadcastExtension');
|
|
44
|
+
}
|
|
45
|
+
function getSbePodfileSnippet(props) {
|
|
46
|
+
const targetName = getSbeTargetName(props);
|
|
47
|
+
return `\ntarget '${targetName}' do\n pod 'FishjamCloudClient/Broadcast'\nend`;
|
|
48
|
+
}
|
|
46
49
|
const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
47
50
|
const IPHONEOS_DEPLOYMENT_TARGET = '15.1';
|
|
48
51
|
const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
@@ -50,8 +53,9 @@ const BUNDLE_IDENTIFIER_TEMPLATE_REGEX = /{{BUNDLE_IDENTIFIER}}/gm;
|
|
|
50
53
|
/**
|
|
51
54
|
* A helper function for updating a value in a file for given regex
|
|
52
55
|
*/
|
|
53
|
-
async function updateFileWithRegex(iosPath, fileName, regex, value) {
|
|
54
|
-
const
|
|
56
|
+
async function updateFileWithRegex(iosPath, fileName, regex, value, props) {
|
|
57
|
+
const targetName = getSbeTargetName(props);
|
|
58
|
+
const filePath = `${iosPath}/${targetName}/${fileName}`;
|
|
55
59
|
let file = await fs.readFile(filePath, { encoding: 'utf-8' });
|
|
56
60
|
file = file.replace(regex, value);
|
|
57
61
|
await fs.writeFile(filePath, file);
|
|
@@ -60,23 +64,24 @@ async function updateFileWithRegex(iosPath, fileName, regex, value) {
|
|
|
60
64
|
* Inserts a required target to Podfile.
|
|
61
65
|
* This is needed to provide the dependency of FishjamCloudClient/Broadcast to the extension.
|
|
62
66
|
*/
|
|
63
|
-
async function updatePodfile(iosPath) {
|
|
67
|
+
async function updatePodfile(iosPath, props) {
|
|
68
|
+
const podfileSnippet = getSbePodfileSnippet(props);
|
|
64
69
|
let matches;
|
|
65
70
|
try {
|
|
66
71
|
const podfile = await fs.readFile(`${iosPath}/Podfile`, {
|
|
67
72
|
encoding: 'utf-8',
|
|
68
73
|
});
|
|
69
|
-
matches = podfile.match(
|
|
74
|
+
matches = podfile.match(podfileSnippet);
|
|
70
75
|
}
|
|
71
76
|
catch (e) {
|
|
72
77
|
console.error('Error reading from Podfile: ', e);
|
|
73
78
|
}
|
|
74
79
|
if (matches) {
|
|
75
|
-
console.log(`${
|
|
80
|
+
console.log(`${getSbeTargetName(props)} target already added to Podfile. Skipping...`);
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
78
83
|
try {
|
|
79
|
-
fs.appendFile(`${iosPath}/Podfile`,
|
|
84
|
+
fs.appendFile(`${iosPath}/Podfile`, podfileSnippet);
|
|
80
85
|
}
|
|
81
86
|
catch (e) {
|
|
82
87
|
console.error('Error writing to Podfile: ', e);
|
|
@@ -86,10 +91,11 @@ async function updatePodfile(iosPath) {
|
|
|
86
91
|
* Adds "App Group" permission
|
|
87
92
|
* App Group allow your app and the FishjamScreenBroadcastExtension to communicate with each other.
|
|
88
93
|
*/
|
|
89
|
-
const withAppGroupPermissions = (config) => {
|
|
94
|
+
const withAppGroupPermissions = (config, props) => {
|
|
90
95
|
const APP_GROUP_KEY = 'com.apple.security.application-groups';
|
|
91
96
|
const bundleIdentifier = config.ios?.bundleIdentifier || '';
|
|
92
|
-
const groupIdentifier = `group.${bundleIdentifier}`;
|
|
97
|
+
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
98
|
+
const mainTarget = props?.ios?.mainTargetName || '';
|
|
93
99
|
config.ios ??= {};
|
|
94
100
|
config.ios.entitlements ??= {};
|
|
95
101
|
config.ios.entitlements[APP_GROUP_KEY] ??= [];
|
|
@@ -123,11 +129,12 @@ const withAppGroupPermissions = (config) => {
|
|
|
123
129
|
projectObj.attributes.TargetAttributes[targetUuid].SystemCapabilities['com.apple.ApplicationGroups.iOS'] = {
|
|
124
130
|
enabled: 1,
|
|
125
131
|
};
|
|
126
|
-
const
|
|
132
|
+
const mainTargetName = mainTarget || props.modRequest.projectName;
|
|
133
|
+
const entitlementsFilePath = `${mainTargetName}/${mainTargetName}.entitlements`;
|
|
127
134
|
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
128
135
|
Object.keys(configurations).forEach((key) => {
|
|
129
136
|
const config = configurations[key];
|
|
130
|
-
if (config.buildSettings?.PRODUCT_NAME?.includes(
|
|
137
|
+
if (config.buildSettings?.PRODUCT_NAME?.includes(mainTargetName)) {
|
|
131
138
|
if (!config.buildSettings.CODE_SIGN_ENTITLEMENTS) {
|
|
132
139
|
config.buildSettings.CODE_SIGN_ENTITLEMENTS = entitlementsFilePath;
|
|
133
140
|
}
|
|
@@ -141,11 +148,12 @@ const withAppGroupPermissions = (config) => {
|
|
|
141
148
|
* Adds constants to Info.plist
|
|
142
149
|
* In other to dynamically retreive extension's bundleId and group name we need to store it in Info.plist.
|
|
143
150
|
*/
|
|
144
|
-
const withInfoPlistConstants = (config) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
|
|
151
|
+
const withInfoPlistConstants = (config, props) => (0, config_plugins_1.withInfoPlist)(config, (configuration) => {
|
|
145
152
|
const bundleIdentifier = configuration.ios?.bundleIdentifier || '';
|
|
146
|
-
|
|
153
|
+
const groupIdentifier = props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
154
|
+
configuration.modResults['AppGroupName'] = groupIdentifier;
|
|
147
155
|
configuration.modResults['ScreenShareExtensionBundleId'] =
|
|
148
|
-
`${bundleIdentifier}.${
|
|
156
|
+
`${bundleIdentifier}.${getSbeTargetName(props)}`;
|
|
149
157
|
return configuration;
|
|
150
158
|
});
|
|
151
159
|
/**
|
|
@@ -156,14 +164,22 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
156
164
|
const appName = props.modRequest.projectName || '';
|
|
157
165
|
const iosPath = props.modRequest.platformProjectRoot;
|
|
158
166
|
const bundleIdentifier = props.ios?.bundleIdentifier;
|
|
167
|
+
const groupIdentifier = options?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
|
|
159
168
|
const xcodeProject = props.modResults;
|
|
169
|
+
const targetName = getSbeTargetName(options);
|
|
160
170
|
const pluginDir = require.resolve('@fishjam-cloud/react-native-client/package.json');
|
|
161
171
|
const extensionSourceDir = path.join(pluginDir, '../plugin/broadcastExtensionFiles/');
|
|
162
|
-
await updatePodfile(iosPath);
|
|
172
|
+
await updatePodfile(iosPath, options);
|
|
163
173
|
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
174
|
+
const templateTargetName = 'FishjamScreenBroadcastExtension';
|
|
164
175
|
const extFiles = [
|
|
165
176
|
'FishjamBroadcastSampleHandler.swift',
|
|
166
|
-
`${
|
|
177
|
+
`${templateTargetName}.entitlements`,
|
|
178
|
+
`Info.plist`,
|
|
179
|
+
];
|
|
180
|
+
const destFiles = [
|
|
181
|
+
'FishjamBroadcastSampleHandler.swift',
|
|
182
|
+
`${targetName}.entitlements`,
|
|
167
183
|
`Info.plist`,
|
|
168
184
|
];
|
|
169
185
|
await xcodeProject.parse(async function (err) {
|
|
@@ -171,28 +187,26 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
171
187
|
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
172
188
|
return;
|
|
173
189
|
}
|
|
174
|
-
if (xcodeProject.pbxTargetByName(
|
|
175
|
-
console.log(`${
|
|
190
|
+
if (xcodeProject.pbxTargetByName(targetName)) {
|
|
191
|
+
console.log(`${targetName} already exists in project. Skipping...`);
|
|
176
192
|
return;
|
|
177
193
|
}
|
|
178
194
|
try {
|
|
179
|
-
|
|
180
|
-
await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
|
|
195
|
+
await fs.mkdir(`${iosPath}/${targetName}`, { recursive: true });
|
|
181
196
|
for (let i = 0; i < extFiles.length; i++) {
|
|
182
|
-
const
|
|
183
|
-
const
|
|
184
|
-
await fs.copyFile(
|
|
197
|
+
const srcFile = `${extensionSourceDir}${extFiles[i]}`;
|
|
198
|
+
const destFile = `${iosPath}/${targetName}/${destFiles[i]}`;
|
|
199
|
+
await fs.copyFile(srcFile, destFile);
|
|
185
200
|
}
|
|
186
201
|
}
|
|
187
202
|
catch (e) {
|
|
188
203
|
console.error('Error copying extension files: ', e);
|
|
189
204
|
}
|
|
190
|
-
|
|
191
|
-
await updateFileWithRegex(iosPath,
|
|
192
|
-
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift',
|
|
193
|
-
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '');
|
|
205
|
+
await updateFileWithRegex(iosPath, `${targetName}.entitlements`, GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier, options);
|
|
206
|
+
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier, options);
|
|
207
|
+
await updateFileWithRegex(iosPath, 'FishjamBroadcastSampleHandler.swift', BUNDLE_IDENTIFIER_TEMPLATE_REGEX, bundleIdentifier || '', options);
|
|
194
208
|
// Create new PBXGroup for the extension
|
|
195
|
-
const extGroup = xcodeProject.addPbxGroup(extFiles,
|
|
209
|
+
const extGroup = xcodeProject.addPbxGroup(extFiles, targetName, targetName);
|
|
196
210
|
// Add the new PBXGroup to the top level group. This makes the
|
|
197
211
|
// files / folder appear in the file explorer in Xcode.
|
|
198
212
|
const groups = xcodeProject.hash.project.objects['PBXGroup'];
|
|
@@ -212,7 +226,7 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
212
226
|
projObjects['PBXTargetDependency'] || {};
|
|
213
227
|
// Add the SBE target
|
|
214
228
|
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
215
|
-
const sbeTarget = xcodeProject.addTarget(
|
|
229
|
+
const sbeTarget = xcodeProject.addTarget(targetName, 'app_extension', targetName, `${bundleIdentifier}.${targetName}`);
|
|
216
230
|
// Add build phases to the new target
|
|
217
231
|
xcodeProject.addBuildPhase(['FishjamBroadcastSampleHandler.swift'], 'PBXSourcesBuildPhase', 'Sources', sbeTarget.uuid);
|
|
218
232
|
xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', sbeTarget.uuid);
|
|
@@ -225,15 +239,14 @@ const withFishjamSBE = (config, options) => (0, config_plugins_1.withXcodeProjec
|
|
|
225
239
|
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
226
240
|
for (const key in configurations) {
|
|
227
241
|
if (typeof configurations[key].buildSettings !== 'undefined' &&
|
|
228
|
-
configurations[key].buildSettings.PRODUCT_NAME ===
|
|
229
|
-
`"${SBE_TARGET_NAME}"`) {
|
|
242
|
+
configurations[key].buildSettings.PRODUCT_NAME === `"${targetName}"`) {
|
|
230
243
|
const buildSettingsObj = configurations[key].buildSettings;
|
|
231
244
|
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
|
|
232
245
|
options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
233
246
|
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
234
|
-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${
|
|
247
|
+
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
|
|
235
248
|
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
|
|
236
|
-
buildSettingsObj.INFOPLIST_FILE = `${
|
|
249
|
+
buildSettingsObj.INFOPLIST_FILE = `${targetName}/Info.plist`;
|
|
237
250
|
buildSettingsObj.SWIFT_VERSION = '5.0';
|
|
238
251
|
buildSettingsObj.MARKETING_VERSION = '1.0.0';
|
|
239
252
|
buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
|
|
@@ -258,8 +271,8 @@ const withFishjamPictureInPicture = (config, props) => (0, config_plugins_1.with
|
|
|
258
271
|
*/
|
|
259
272
|
const withFishjamIos = (config, props) => {
|
|
260
273
|
if (props?.ios?.enableScreensharing) {
|
|
261
|
-
config = withAppGroupPermissions(config);
|
|
262
|
-
config = withInfoPlistConstants(config);
|
|
274
|
+
config = withAppGroupPermissions(config, props);
|
|
275
|
+
config = withInfoPlistConstants(config, props);
|
|
263
276
|
config = withFishjamSBE(config, props);
|
|
264
277
|
}
|
|
265
278
|
config = (0, config_plugins_1.withPodfileProperties)(config, (configuration) => {
|