1.7.2 • Published 9 months ago

react-native-meeting-sdk v1.7.2

Weekly downloads
-
License
-
Repository
-
Last release
9 months ago

React Native Meeting SDK

A simple few steps to integrate our React Native SDK and enjoy the seamless meetings in your app.

Installation

Install @dell-emc/react-native-meeting-sdk with npm

  1. Run => npm i @dell-emc/react-native-meeting-sdk

  2. Dependency conflicts may occur between RNSDK and your app.
     If that is the case, please run npm i @dell-emc/react-native-meeting-sdk --force.

  3. add this script to your package.json scripts =>
  "update-deps": "node node_modules/@dell-emc/react-native-meeting-sdk/update_dependencies.js"

  4.To check if some dependencies need to be added, please run the following script 
  => npm run update-deps.
  
  This will sync all of our peer dependencies with your dependencies.
  Next you will need to do npm install.

A few more steps...

For Android

  • In android/app/src/debug/AndroidManifest.xml and android/app/src/main/AndroidManifest.xml, please include:
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" android:minSdkVersion="34"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" android:minSdkVersion="34" />
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application>
         // ... 
        <activity>
          <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <action android:name="android.intent.action.SEND_MULTIPLE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*" />
            <data android:mimeType="video/*" />
            <data android:mimeType="audio/*" />
            <data android:mimeType="application/*" /> 
            <data android:mimeType="text/plain" />
            <!-- Add the mime types you want to support -->
          </intent-filter>
        </activity>
        // ...
        <service android:name="io.wazo.callkeep.VoiceConnectionService" android:exported="true" android:label="Wazo" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" android:foregroundServiceType="camera|microphone">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService" />
            </intent-filter>
        </service>
    
        <service android:name="io.wazo.callkeep.RNCallKeepBackgroundMessagingService" />
        // ....
    </application>
  • For icons to work, you should add these lines to app/build.gradle
project.ext.vectoricons = [
 iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf', 'AntDesign.ttf', 'Entypo.ttf',  'Feather.ttf', 'FontAwesome.ttf', 'FontAwesome5_Brands.ttf', 'FontAwesome5_Regular.ttf', 'FontAwesome5_Solid.ttf', 'Foundation.ttf', 'Ionicons.ttf', 'MaterialCommunityIcons.ttf', 'SimpleLineIcons.ttf', 'Octicons.ttf', 'Zocial.ttf' ]
]

apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
  • For GIF to work, you should add these lines to app/build.gradle under dependencies
// For animated gif support
implementation 'com.facebook.fresco:animated-gif:3.1.3'

// For webp support
implementation 'com.facebook.fresco:animated-webp:3.1.3'

// Animated webp support
implementation 'com.facebook.fresco:webpsupport:3.1.3'

For IOS

  • Add these lines to your AppDelegate.mm file
#import "RNCallKeep.h"
#import <WebRTC/RTCAudioSession.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....

  RTCAudioSession *session = [RTCAudioSession sharedInstance];
  session.useManualAudio = true;
  session.isAudioEnabled = false;

....
}

- (BOOL)application:(UIApplication *)application
 continueUserActivity:(NSUserActivity *)userActivity
   restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
 {
   return [RNCallKeep application:application
            continueUserActivity:userActivity
              restorationHandler:restorationHandler];
 }
  • SDK requests some permissions, make sure to include the required entries in your Info.plist file.
<key>NSCameraUsageDescription</key>
<string>The App would like access your camera to make video calls in chats or to takes photos for the profile, chat, and group pictures.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSMicrophoneUsageDescription</key>
<string>The App would like access your microphone to make and receive calls and record voice messages in chats.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The App would like access your gallery to upload and download pictures in chats or for profile and group pictures.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>The App would like access your gallery to upload and download pictures in chats or for profile and group pictures.</string>
  • Allow voip background on IOS.

    Open Info.plist file and add voip in UIBackgroundModes.

<key>UIBackgroundModes</key>
<array>
 <string>voip</string>
</array>
  • For IOS, for icons to work. Edit Info.plist and add a property called Fonts provided by application
List of all available fonts to copy & paste in Info.plist
<key>UIAppFonts</key>
<array>
  <string>AntDesign.ttf</string>
  <string>Entypo.ttf</string>
  <string>EvilIcons.ttf</string>
  <string>Feather.ttf</string>
  <string>FontAwesome.ttf</string>
  <string>FontAwesome5_Brands.ttf</string>
  <string>FontAwesome5_Regular.ttf</string>
  <string>FontAwesome5_Solid.ttf</string>
  <string>FontAwesome6_Brands.ttf</string>
  <string>FontAwesome6_Regular.ttf</string>
  <string>FontAwesome6_Solid.ttf</string>
  <string>Foundation.ttf</string>
  <string>Ionicons.ttf</string>
  <string>MaterialIcons.ttf</string>
  <string>MaterialCommunityIcons.ttf</string>
  <string>SimpleLineIcons.ttf</string>
  <string>Octicons.ttf</string>
  <string>Zocial.ttf</string>
  <string>Fontisto.ttf</string>
</array>

For Expo sdk > 50

  • React Native uses event-target-shim@5 which is not compatible with react-native-webrtc's dependency on event-target-shim@6. To fix this, you may need to add a redirection in your metro.config.js file:
// metro.config.js

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const resolveFrom = require("resolve-from");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (
    // If the bundle is resolving "event-target-shim" from a module that is part of "react-native-webrtc".
    moduleName.startsWith("event-target-shim") &&
    context.originModulePath.includes("react-native-webrtc")
  ) {
    // Resolve event-target-shim relative to the react-native-webrtc package to use v6.
    // React Native requires v5 which is not compatible with react-native-webrtc.
    const eventTargetShimPath = resolveFrom(
      context.originModulePath,
      moduleName
    );

    return {
      filePath: eventTargetShimPath,
      type: "sourceFile",
    };
  }

  // Ensure you call the default resolver.
  return context.resolveRequest(context, moduleName, platform);
};

module.exports = config;

Listening to Meeting Events

Events supported :

PropDescription
onConferenceWillJoinIf the meeting is loading and its trying to connect
onAudioMutedChangedWhen mic mute status changes
onVideoMutedChangedWhen video status changes
onConferenceJoinedWhen the user joins
onParticipantJoinedWhen a meeting participant joins
onConferenceLeftWhen the user leaves the meeting
onParticipantLeftWhen a meeting participant leaves
onReadyToCloseWhen hangup the meeting
const onReadyToClose = () => {
  console.log("Room Closed");
}

const eventListeners = {
  onReadyToClose : onReadyToClose
};

return(
 <MeetingSDK
    ...
    eventListeners={eventListeners}
    
...   

Theme

PropDescriptionDefault
themeModeChange between light and dark modesdark
themeSet of custom props to customize the coloring o the apppreset of colors defined internally

Allowed theme props are:

Note: you can provide all colors or only a few of them.

PropDescription
primaryColorMain color of the screens
secondaryColorFor buttons, icons (not icon buttons)
accentColorFor bottom sheets
primaryTextColorMain text color used in most of the app
secondaryTextColorFor buttons text, icon buttons text, secondary text
    <MeetingSDK
      ...
      themeMode={"light"} // "light", "dark"
      theme={{ // default colors will be used if theme is not provided
        dark:{
          primaryColor:"#232323",
          secondaryColor: "#b5986b",
          accentColor:"#141414",
          primaryTextColor: "#ffffff",
          secondaryTextColor: "#ffffff",
        },
        light:{
          primaryColor:"#eeeeee",
          secondaryColor: "#b5986b",
          accentColor:"#d1d1d1",
          primaryTextColor: "#000000",
          secondaryTextColor: "#ffffff",
        }
      }}
    />

Dynamic Actions in Meeting SDK

The dynamicActions feature in the MeetingSDK allows users to define and include custom actions within the meeting environment. These actions can be triggered by users during the meeting session, providing additional functionality and interactivity.

Usage:

The dynamicActions property is passed to the MeetingSDK component as an array of action objects. Each action object contains the following properties:

  • text: A string representing the label or text associated with the action.

  • iconProps: An object specifying the properties of the icon to be displayed alongside the action text. This object includes:

    • type: The type of icon library to be used ('fontisto' | 'material' | 'evil' | 'feather' | 'ant' | 'simpleLine' | 'zocial' | 'foundation' | 'fa5' | 'fa' | 'ionicon' | 'materialCommunity' | 'entypo' | 'octicon').
    • name: The name or identifier of the icon within the specified icon library (check react-native-vector-icons).
    • color (optional): The color of the icon.
  • onClick: A function that defines the behavior to be executed when the action is triggered. This function should handle the desired functionality or interaction associated with the action. .

...
const handleAction=(externalMeetingRef : string)=>{
       ````your action functionality ````
       const meetingRefId =  externalMeetingRef 
}

const dynamicActions : IDynamicActions [] = [
  {
    text :"Test dynamic action",
    iconProps :{type :'material' , name :'sos' , color :'white'},
    onClick : handleAction
  }
]

return(
  <MeetingSDK
    ...
    dynamicActions={dynamicActions}
    ...
    

API


FunctionReturn Type
endMeeting()void

endMeeting

triggers the necessary functionality to gracefully end your meeting, handling tasks such as disconnecting from the meeting, cleaning up resources, and notifying other participants.

When you're ready to end your meeting, Import endMeeting in your code then simply call endMeeting()

import { endMeeting } from "@dell-emc/react-native-meeting-sdk";

endMeeting();

Potential issues

Usage/Examples

import {MeetingSDK , endMeeting} from '@dell-emc/react-native-meeting-sdk';

function App() {
  
  const accountId = "ACCOUNT ID";
  const serverURL = "SERVER URL";
  const jwtToken = "MEETING TOKEN";
  const authCode = "AUTH CODE RECENTLY GENERATED"
  const meetingId = "EXTERNAL MEETING REF"
  const socketDomain = "https://example.com";
  /* Optional: socket path is the name of the path that is captured on the server side.*/
  const socketPath = "/my-custom-path/socket.io/"

  const onReadyToClose= () => {
    console.log("Room Closed");
  }

  const eventListeners = {
    onReadyToClose :onReadyToClose
  };

  const handleAction=()=>{
    console.log("handle dynamic action click")
  }
  
  const dynamicActions : IDynamicActions [] = [
    {
      text :"Test dynamic action",
      iconProps :{type :'material' , name :'sos' , color :'white'},
      onClick : handleAction
    }
  ]

  const endMeeting = () => {
    endMeeting()
  }

  return ( 
    <MeetingSDK
      appName={appName}
      serverURL={serverURL}
      socketURL={socketURL}
      accountId={accountId}
      jwtToken={jwtToken}
      authCode={authCode}
      meetingId={meetingId} // Required when using authCode
      /* please create your own gifApiKey for your app  ( https://developers.giphy.com/dashboard/ )
      if you don't send gifApiKey, gif on chat  will be disabled */
      gifApiKey={gifApiKey} 
      eventListeners={eventListeners}
      dynamicActions={dynamicActions}
      locale={"en"} // "en", "ar"
      themeMode={"light"} // "light", "dark"
      theme={{ // default colors will be used if theme is not provided
        dark:{
          primaryColor:"#232323",
          secondaryColor: "#b5986b",
          accentColor:"#141414",
          primaryTextColor: "#ffffff",
          secondaryTextColor: "#ffffff",
        },
        light:{
          primaryColor:"#eeeeee",
          secondaryColor: "#b5986b",
          accentColor:"#d1d1d1",
          primaryTextColor: "#000000",
          secondaryTextColor: "#ffffff",
        }
      }}
    />
  );
}