@purplecallio/react-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -0
- package/dist/components/VideoView.d.ts +31 -0
- package/dist/components/VideoView.d.ts.map +1 -0
- package/dist/components/VideoView.js +45 -0
- package/dist/components/VideoView.js.map +1 -0
- package/dist/context.d.ts +79 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +247 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +13 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -0
- package/dist/hooks.d.ts +53 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +98 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/optional/inCallManager.d.ts +46 -0
- package/dist/optional/inCallManager.d.ts.map +1 -0
- package/dist/optional/inCallManager.js +79 -0
- package/dist/optional/inCallManager.js.map +1 -0
- package/dist/optional/netInfo.d.ts +38 -0
- package/dist/optional/netInfo.d.ts.map +1 -0
- package/dist/optional/netInfo.js +69 -0
- package/dist/optional/netInfo.js.map +1 -0
- package/dist/permissions.d.ts +29 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +41 -0
- package/dist/permissions.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Defensive bridge to the *optional* peer dependency
|
|
4
|
+
* `react-native-incall-manager`, which manages call audio routing
|
|
5
|
+
* (speaker / earpiece / Bluetooth) — something `react-native-webrtc` does
|
|
6
|
+
* not handle on its own.
|
|
7
|
+
*
|
|
8
|
+
* It is listed in package.json as an optional peerDependency
|
|
9
|
+
* (`peerDependenciesMeta.react-native-incall-manager.optional = true`), so
|
|
10
|
+
* consumers who don't need custom audio routing behavior can skip
|
|
11
|
+
* installing it entirely. We load it with `require()` inside a try/catch so
|
|
12
|
+
* a missing install never crashes module evaluation — it just disables
|
|
13
|
+
* automatic audio routing and logs a one-time warning.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.inCallManager = exports.InCallManagerBridge = void 0;
|
|
17
|
+
exports.loadInCallManager = loadInCallManager;
|
|
18
|
+
let warnedMissing = false;
|
|
19
|
+
function warnMissingOnce() {
|
|
20
|
+
if (warnedMissing)
|
|
21
|
+
return;
|
|
22
|
+
warnedMissing = true;
|
|
23
|
+
// eslint-disable-next-line no-console
|
|
24
|
+
console.warn('[@purplecallio/react-native] react-native-incall-manager is not installed. ' +
|
|
25
|
+
'Call audio routing (speaker/earpiece switching on join/leave, setSpeakerphoneOn()) ' +
|
|
26
|
+
'will not be managed automatically. Install it for production call UX: ' +
|
|
27
|
+
'npm install react-native-incall-manager');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Default loader: defensively requires the real optional native module.
|
|
31
|
+
* Kept as a plain function (rather than inlined) so `InCallManagerBridge`
|
|
32
|
+
* can be constructed with a fake loader in tests, without needing the real
|
|
33
|
+
* native package installed or mocked at the module resolution level.
|
|
34
|
+
*/
|
|
35
|
+
function loadInCallManager() {
|
|
36
|
+
try {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
38
|
+
const mod = require('react-native-incall-manager');
|
|
39
|
+
return (mod && mod.default ? mod.default : mod);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class InCallManagerBridge {
|
|
46
|
+
constructor(load = loadInCallManager) {
|
|
47
|
+
this.load = load;
|
|
48
|
+
}
|
|
49
|
+
resolve() {
|
|
50
|
+
const mgr = this.load();
|
|
51
|
+
if (!mgr)
|
|
52
|
+
warnMissingOnce();
|
|
53
|
+
return mgr;
|
|
54
|
+
}
|
|
55
|
+
/** Called automatically by `<PurpleCallioProvider>` on `join()`. */
|
|
56
|
+
start(media) {
|
|
57
|
+
this.resolve()?.start({ media, auto: true });
|
|
58
|
+
}
|
|
59
|
+
/** Called automatically by `<PurpleCallioProvider>` on `leave()`/unmount. */
|
|
60
|
+
stop() {
|
|
61
|
+
this.resolve()?.stop();
|
|
62
|
+
}
|
|
63
|
+
/** Force call audio to the loudspeaker (true) or earpiece/default route (false). */
|
|
64
|
+
setSpeakerphoneOn(enabled) {
|
|
65
|
+
const mgr = this.resolve();
|
|
66
|
+
if (!mgr)
|
|
67
|
+
return;
|
|
68
|
+
if (typeof mgr.setForceSpeakerphoneOn === 'function') {
|
|
69
|
+
mgr.setForceSpeakerphoneOn(enabled);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
mgr.setSpeakerphoneOn?.(enabled);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.InCallManagerBridge = InCallManagerBridge;
|
|
77
|
+
/** Shared default instance used by the provider and the standalone `setSpeakerphoneOn` export. */
|
|
78
|
+
exports.inCallManager = new InCallManagerBridge();
|
|
79
|
+
//# sourceMappingURL=inCallManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inCallManager.js","sourceRoot":"","sources":["../../src/optional/inCallManager.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AA4BH,8CAQC;AA3BD,IAAI,aAAa,GAAG,KAAK,CAAC;AAC1B,SAAS,eAAe;IACtB,IAAI,aAAa;QAAE,OAAO;IAC1B,aAAa,GAAG,IAAI,CAAC;IACrB,sCAAsC;IACtC,OAAO,CAAC,IAAI,CACV,6EAA6E;QAC3E,qFAAqF;QACrF,wEAAwE;QACxE,yCAAyC,CAC5C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB;IAC/B,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAsB,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAa,mBAAmB;IAC9B,YAA6B,OAAuC,iBAAiB;QAAxD,SAAI,GAAJ,IAAI,CAAoD;IAAG,CAAC;IAEjF,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG;YAAE,eAAe,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,KAAwB;QAC5B,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,6EAA6E;IAC7E,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,oFAAoF;IACpF,iBAAiB,CAAC,OAAgB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,IAAI,OAAO,GAAG,CAAC,sBAAsB,KAAK,UAAU,EAAE,CAAC;YACrD,GAAG,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;CACF;AA7BD,kDA6BC;AAED,kGAAkG;AACrF,QAAA,aAAa,GAAG,IAAI,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defensive bridge to the *optional* peer dependency
|
|
3
|
+
* `@react-native-community/netinfo`.
|
|
4
|
+
*
|
|
5
|
+
* This package deliberately does NOT invent any reconnection logic on top
|
|
6
|
+
* of network state — that's core-SDK territory (see README "Known
|
|
7
|
+
* Limitations" re: the `'reconnecting'` connection state). All this bridge
|
|
8
|
+
* does is surface raw connectivity info so a consuming app can show its own
|
|
9
|
+
* "you're offline" UI via `useNetworkState()`.
|
|
10
|
+
*/
|
|
11
|
+
export type NetInfoStateTypeLike = string;
|
|
12
|
+
export interface NetInfoStateLike {
|
|
13
|
+
type: NetInfoStateTypeLike;
|
|
14
|
+
isConnected: boolean | null;
|
|
15
|
+
isInternetReachable: boolean | null;
|
|
16
|
+
}
|
|
17
|
+
export type NetInfoUnsubscribe = () => void;
|
|
18
|
+
export interface NetInfoLike {
|
|
19
|
+
addEventListener(listener: (state: NetInfoStateLike) => void): NetInfoUnsubscribe;
|
|
20
|
+
fetch(): Promise<NetInfoStateLike>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Default loader: defensively requires the real optional native module.
|
|
24
|
+
* Kept as a plain function so `NetInfoBridge` can be constructed with a
|
|
25
|
+
* fake loader in tests, without needing the real native package installed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadNetInfo(): NetInfoLike | null;
|
|
28
|
+
export declare class NetInfoBridge {
|
|
29
|
+
private readonly load;
|
|
30
|
+
constructor(load?: () => NetInfoLike | null);
|
|
31
|
+
private resolve;
|
|
32
|
+
isSupported(): boolean;
|
|
33
|
+
subscribe(listener: (state: NetInfoStateLike) => void): NetInfoUnsubscribe;
|
|
34
|
+
fetch(): Promise<NetInfoStateLike | null>;
|
|
35
|
+
}
|
|
36
|
+
/** Shared default instance used by `useNetworkState()`. */
|
|
37
|
+
export declare const netInfo: NetInfoBridge;
|
|
38
|
+
//# sourceMappingURL=netInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"netInfo.d.ts","sourceRoot":"","sources":["../../src/optional/netInfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,kBAAkB,CAAC;IAClF,KAAK,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpC;AAcD;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,WAAW,GAAG,IAAI,CAQhD;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,GAAE,MAAM,WAAW,GAAG,IAAkB;IAEzE,OAAO,CAAC,OAAO;IAMf,WAAW,IAAI,OAAO;IAItB,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,kBAAkB;IAM1E,KAAK,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAK1C;AAED,2DAA2D;AAC3D,eAAO,MAAM,OAAO,eAAsB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Defensive bridge to the *optional* peer dependency
|
|
4
|
+
* `@react-native-community/netinfo`.
|
|
5
|
+
*
|
|
6
|
+
* This package deliberately does NOT invent any reconnection logic on top
|
|
7
|
+
* of network state — that's core-SDK territory (see README "Known
|
|
8
|
+
* Limitations" re: the `'reconnecting'` connection state). All this bridge
|
|
9
|
+
* does is surface raw connectivity info so a consuming app can show its own
|
|
10
|
+
* "you're offline" UI via `useNetworkState()`.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.netInfo = exports.NetInfoBridge = void 0;
|
|
14
|
+
exports.loadNetInfo = loadNetInfo;
|
|
15
|
+
let warnedMissing = false;
|
|
16
|
+
function warnMissingOnce() {
|
|
17
|
+
if (warnedMissing)
|
|
18
|
+
return;
|
|
19
|
+
warnedMissing = true;
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.warn('[@purplecallio/react-native] @react-native-community/netinfo is not installed. ' +
|
|
22
|
+
'useNetworkState() will report { supported: false } and never update. Install it ' +
|
|
23
|
+
'to surface real connectivity state: npm install @react-native-community/netinfo');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Default loader: defensively requires the real optional native module.
|
|
27
|
+
* Kept as a plain function so `NetInfoBridge` can be constructed with a
|
|
28
|
+
* fake loader in tests, without needing the real native package installed.
|
|
29
|
+
*/
|
|
30
|
+
function loadNetInfo() {
|
|
31
|
+
try {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
33
|
+
const mod = require('@react-native-community/netinfo');
|
|
34
|
+
return (mod && mod.default ? mod.default : mod);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
class NetInfoBridge {
|
|
41
|
+
constructor(load = loadNetInfo) {
|
|
42
|
+
this.load = load;
|
|
43
|
+
}
|
|
44
|
+
resolve() {
|
|
45
|
+
const mod = this.load();
|
|
46
|
+
if (!mod)
|
|
47
|
+
warnMissingOnce();
|
|
48
|
+
return mod;
|
|
49
|
+
}
|
|
50
|
+
isSupported() {
|
|
51
|
+
return this.resolve() !== null;
|
|
52
|
+
}
|
|
53
|
+
subscribe(listener) {
|
|
54
|
+
const mod = this.resolve();
|
|
55
|
+
if (!mod)
|
|
56
|
+
return () => { };
|
|
57
|
+
return mod.addEventListener(listener);
|
|
58
|
+
}
|
|
59
|
+
fetch() {
|
|
60
|
+
const mod = this.resolve();
|
|
61
|
+
if (!mod)
|
|
62
|
+
return Promise.resolve(null);
|
|
63
|
+
return mod.fetch();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.NetInfoBridge = NetInfoBridge;
|
|
67
|
+
/** Shared default instance used by `useNetworkState()`. */
|
|
68
|
+
exports.netInfo = new NetInfoBridge();
|
|
69
|
+
//# sourceMappingURL=netInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"netInfo.js","sourceRoot":"","sources":["../../src/optional/netInfo.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAkCH,kCAQC;AAzBD,IAAI,aAAa,GAAG,KAAK,CAAC;AAC1B,SAAS,eAAe;IACtB,IAAI,aAAa;QAAE,OAAO;IAC1B,aAAa,GAAG,IAAI,CAAC;IACrB,sCAAsC;IACtC,OAAO,CAAC,IAAI,CACV,iFAAiF;QAC/E,kFAAkF;QAClF,iFAAiF,CACpF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,WAAW;IACzB,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAgB,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAa,aAAa;IACxB,YAA6B,OAAiC,WAAW;QAA5C,SAAI,GAAJ,IAAI,CAAwC;IAAG,CAAC;IAErE,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG;YAAE,eAAe,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC;IACjC,CAAC;IAED,SAAS,CAAC,QAA2C;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,GAAG,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AAxBD,sCAwBC;AAED,2DAA2D;AAC9C,QAAA,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface RequestMediaPermissionsOptions {
|
|
2
|
+
/** Request microphone (RECORD_AUDIO) access. Default: true. */
|
|
3
|
+
audio?: boolean;
|
|
4
|
+
/** Request camera access. Default: true. */
|
|
5
|
+
video?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Requests the runtime OS permissions needed for `getUserMedia()` to
|
|
9
|
+
* succeed on-device.
|
|
10
|
+
*
|
|
11
|
+
* - **Android** requires an explicit runtime permission request before
|
|
12
|
+
* camera/microphone access (`PermissionsAndroid.requestMultiple`), on top
|
|
13
|
+
* of declaring the permissions in AndroidManifest.xml (see README).
|
|
14
|
+
* - **iOS** has no equivalent upfront JS-level permission API: the system
|
|
15
|
+
* prompt appears automatically the first time `getUserMedia()` is called,
|
|
16
|
+
* *provided* the app's Info.plist declares `NSCameraUsageDescription`
|
|
17
|
+
* and/or `NSMicrophoneUsageDescription` (an app-level native config this
|
|
18
|
+
* package cannot inject — see README). So on iOS this function is a
|
|
19
|
+
* deliberate no-op that resolves `true`; if Info.plist is missing the
|
|
20
|
+
* required keys, `getUserMedia()` itself will reject when called, not
|
|
21
|
+
* this function.
|
|
22
|
+
*
|
|
23
|
+
* `<PurpleCallioProvider>` calls this automatically before `join()` for
|
|
24
|
+
* whichever of `audio`/`video` are requested, but it's also exported
|
|
25
|
+
* standalone for apps that want to prompt earlier (e.g. on a "join call"
|
|
26
|
+
* button) for better UX.
|
|
27
|
+
*/
|
|
28
|
+
export declare function requestMediaPermissions(options?: RequestMediaPermissionsOptions): Promise<boolean>;
|
|
29
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,8BAA8B;IAC7C,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,OAAO,CAAC,CAelB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requestMediaPermissions = requestMediaPermissions;
|
|
4
|
+
const react_native_1 = require("react-native");
|
|
5
|
+
/**
|
|
6
|
+
* Requests the runtime OS permissions needed for `getUserMedia()` to
|
|
7
|
+
* succeed on-device.
|
|
8
|
+
*
|
|
9
|
+
* - **Android** requires an explicit runtime permission request before
|
|
10
|
+
* camera/microphone access (`PermissionsAndroid.requestMultiple`), on top
|
|
11
|
+
* of declaring the permissions in AndroidManifest.xml (see README).
|
|
12
|
+
* - **iOS** has no equivalent upfront JS-level permission API: the system
|
|
13
|
+
* prompt appears automatically the first time `getUserMedia()` is called,
|
|
14
|
+
* *provided* the app's Info.plist declares `NSCameraUsageDescription`
|
|
15
|
+
* and/or `NSMicrophoneUsageDescription` (an app-level native config this
|
|
16
|
+
* package cannot inject — see README). So on iOS this function is a
|
|
17
|
+
* deliberate no-op that resolves `true`; if Info.plist is missing the
|
|
18
|
+
* required keys, `getUserMedia()` itself will reject when called, not
|
|
19
|
+
* this function.
|
|
20
|
+
*
|
|
21
|
+
* `<PurpleCallioProvider>` calls this automatically before `join()` for
|
|
22
|
+
* whichever of `audio`/`video` are requested, but it's also exported
|
|
23
|
+
* standalone for apps that want to prompt earlier (e.g. on a "join call"
|
|
24
|
+
* button) for better UX.
|
|
25
|
+
*/
|
|
26
|
+
async function requestMediaPermissions(options = {}) {
|
|
27
|
+
const { audio = true, video = true } = options;
|
|
28
|
+
if (react_native_1.Platform.OS !== 'android') {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const permissions = [];
|
|
32
|
+
if (audio)
|
|
33
|
+
permissions.push(react_native_1.PermissionsAndroid.PERMISSIONS.RECORD_AUDIO);
|
|
34
|
+
if (video)
|
|
35
|
+
permissions.push(react_native_1.PermissionsAndroid.PERMISSIONS.CAMERA);
|
|
36
|
+
if (permissions.length === 0)
|
|
37
|
+
return true;
|
|
38
|
+
const results = await react_native_1.PermissionsAndroid.requestMultiple(permissions);
|
|
39
|
+
return permissions.every((permission) => results[permission] === react_native_1.PermissionsAndroid.RESULTS.GRANTED);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":";;AA8BA,0DAiBC;AA/CD,+CAA4D;AAS5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACI,KAAK,UAAU,uBAAuB,CAC3C,UAA0C,EAAE;IAE5C,MAAM,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAE/C,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAgG,EAAE,CAAC;IACpH,IAAI,KAAK;QAAE,WAAW,CAAC,IAAI,CAAC,iCAAkB,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACzE,IAAI,KAAK;QAAE,WAAW,CAAC,IAAI,CAAC,iCAAkB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAEnE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,OAAO,GAAG,MAAM,iCAAkB,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACtE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,iCAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACvG,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@purplecallio/react-native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official React Native components and hooks for PurpleCallio, a developer-first real-time communication platform for integrating voice, video and WebRTC communication into applications.",
|
|
5
|
+
"homepage": "https://purplecallio.com",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"react-native": "./dist/index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"purplecallio",
|
|
26
|
+
"react-native",
|
|
27
|
+
"mobile",
|
|
28
|
+
"video",
|
|
29
|
+
"webrtc",
|
|
30
|
+
"voice",
|
|
31
|
+
"real-time",
|
|
32
|
+
"sdk",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"react": ">=18.0.0",
|
|
38
|
+
"react-native": ">=0.70.0",
|
|
39
|
+
"react-native-webrtc": ">=1.100.0",
|
|
40
|
+
"react-native-incall-manager": ">=4.0.0",
|
|
41
|
+
"@react-native-community/netinfo": ">=9.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"react-native-incall-manager": {
|
|
45
|
+
"optional": true
|
|
46
|
+
},
|
|
47
|
+
"@react-native-community/netinfo": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@purplecallio/sdk": "^0.1.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^22.10.5",
|
|
56
|
+
"@types/react": "^19.2.17",
|
|
57
|
+
"@types/react-test-renderer": "^19.2.0",
|
|
58
|
+
"react": "^19.2.0",
|
|
59
|
+
"react-native": "^0.87.1",
|
|
60
|
+
"react-native-webrtc": "^124.0.8",
|
|
61
|
+
"react-test-renderer": "^19.2.0",
|
|
62
|
+
"typescript": "^5.7.3",
|
|
63
|
+
"vitest": "^2.1.9"
|
|
64
|
+
}
|
|
65
|
+
}
|