@firstlogicmetalab/react-native
v1.0.2
Published
First-class VACT voice and video calling for React Native, built on react-native-webrtc.
Maintainers
Readme
@firstlogicmetalab/react-native
First-class VACT voice & video calling for React Native.
New to VACT? Create a free account at vact.online — ₹100 of calling credit to build with, no card required. Full guides and API reference: vact.online/docs.html.
It wraps @firstlogicmetalab/client
with react-native-webrtc
and adds a useVact hook. The protocol, error codes and billing are identical
to web.
Install
npm install @firstlogicmetalab/react-native react-native-webrtc
cd ios && pod install # iOSPermissions
Ask for camera & microphone on a screen before the first call.
Android — android/build.gradle needs minSdkVersion = 24. In
android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>import { PermissionsAndroid } from 'react-native';
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
]);iOS — minimum deployment target 13.0. In ios/YourApp/Info.plist:
<key>NSCameraUsageDescription</key><string>Used for video calls</string>
<key>NSMicrophoneUsageDescription</key><string>Used for calls</string>The Simulator has no camera — test video on a real device.
Use the hook
import { useVact } from '@firstlogicmetalab/react-native';
import { RTCView } from 'react-native-webrtc';
export default function CallScreen({ accessToken }) {
const { status, userId, incomingCall, activeCall, callState,
call, accept, decline, hangup } =
useVact({ appId: 'vact_app_xxx', accessToken });
if (activeCall) {
return (
<>
<RTCView streamURL={activeCall.remoteStream.toURL()} style={{ flex: 1 }} objectFit="cover" />
<RTCView streamURL={activeCall.localStream.toURL()} style={{ width: 110, height: 160 }} mirror />
<Button title="Hang up" onPress={hangup} />
</>
);
}
if (incomingCall) {
return (
<View>
<Text>{incomingCall.fromUserId} is calling</Text>
<Button title="Answer" onPress={() => accept()} />
<Button title="Decline" onPress={decline} />
</View>
);
}
return <Button title="Call bob" disabled={status !== 'ready'} onPress={() => call('bob', { video: true })} />;
}accessToken is the one-time vact_at_ token your backend mints — never ship
your App Secret in the app.
Or drive the client yourself
import { createVactClient, registerVactGlobals } from '@firstlogicmetalab/react-native';
registerVactGlobals(); // optional
const vact = createVactClient('vact_app_xxx');
await vact.connect(accessToken);
const call = await vact.call('bob', { video: true });createVactClient returns the same VactClient as the web package, already
wired to react-native-webrtc.
Notes
- Screen sharing (
call.startScreenShare()) needsgetDisplayMedia, which react-native-webrtc does not provide — it throwsscreen_share_unsupportedon React Native. Screen capture on mobile needs a native module. - Backends and full protocol: https://vact.online/docs.html.
