@daily-co/react-native-daily-js 0.58.0 → 0.60.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
CHANGED
|
@@ -15,7 +15,7 @@ Install `react-native-daily-js` along with its peer dependencies:
|
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
npm i @daily-co/react-native-daily-js @react-native-async-storage/async-storage@^1.15.7 react-native-background-timer@^2.3.1 react-native-get-random-values@^1.9.0
|
|
18
|
-
npm i --save-exact @daily-co/react-native-webrtc@
|
|
18
|
+
npm i --save-exact @daily-co/react-native-webrtc@118.0.3-daily.1
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Then, follow the below steps to set up your native project on each platform. **Note that these steps assume you're using a version of React Native that supports autolinking (>= 60).**
|
|
@@ -93,15 +93,20 @@ Add the following to `AndroidManifest.xml`:
|
|
|
93
93
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
94
94
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
95
95
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
96
|
+
|
|
96
97
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
|
98
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
|
|
99
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
|
|
100
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>
|
|
101
|
+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
|
97
102
|
|
|
98
103
|
<application>
|
|
99
104
|
// ...
|
|
100
|
-
<service android:name="com.daily.reactlibrary.DailyOngoingMeetingForegroundService" android:foregroundServiceType="
|
|
105
|
+
<service android:name="com.daily.reactlibrary.DailyOngoingMeetingForegroundService" android:foregroundServiceType="camera|microphone"/>
|
|
101
106
|
</application>
|
|
102
107
|
```
|
|
103
108
|
|
|
104
|
-
> Note: above, `
|
|
109
|
+
> Note: above, `android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION` is only needed if you wish to do screen sharing.
|
|
105
110
|
|
|
106
111
|
Update your `minSdkVersion` in your top-level `build.gradle` file:
|
|
107
112
|
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
def DEFAULT_COMPILE_SDK_VERSION =
|
|
2
|
-
def DEFAULT_BUILD_TOOLS_VERSION = '
|
|
1
|
+
def DEFAULT_COMPILE_SDK_VERSION = 34
|
|
2
|
+
def DEFAULT_BUILD_TOOLS_VERSION = '34.0.0'
|
|
3
3
|
def DEFAULT_MIN_SDK_VERSION = 24
|
|
4
|
-
def DEFAULT_TARGET_SDK_VERSION =
|
|
4
|
+
def DEFAULT_TARGET_SDK_VERSION = 34
|
|
5
5
|
|
|
6
6
|
def safeExtGet(prop, fallback) {
|
|
7
7
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
@@ -26,7 +26,7 @@ buildscript {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
android {
|
|
29
|
-
|
|
29
|
+
compileSdk safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
|
|
30
30
|
buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
|
|
31
31
|
defaultConfig {
|
|
32
32
|
minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
|
|
@@ -1,26 +1,48 @@
|
|
|
1
1
|
package com.daily.reactlibrary;
|
|
2
2
|
|
|
3
|
+
import android.Manifest;
|
|
3
4
|
import android.app.Activity;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
import android.content.pm.PackageManager;
|
|
7
|
+
import android.os.Build;
|
|
4
8
|
import android.os.Process;
|
|
5
9
|
import android.view.Window;
|
|
6
10
|
import android.view.WindowManager;
|
|
7
11
|
|
|
12
|
+
import androidx.core.app.ActivityCompat;
|
|
13
|
+
import androidx.core.content.ContextCompat;
|
|
14
|
+
import androidx.fragment.app.FragmentActivity;
|
|
15
|
+
|
|
16
|
+
import com.facebook.react.bridge.Arguments;
|
|
17
|
+
import com.facebook.react.bridge.BaseActivityEventListener;
|
|
8
18
|
import com.facebook.react.bridge.LifecycleEventListener;
|
|
9
19
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
10
20
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
11
21
|
import com.facebook.react.bridge.ReactMethod;
|
|
22
|
+
import com.facebook.react.bridge.WritableMap;
|
|
23
|
+
import com.facebook.react.modules.core.PermissionAwareActivity;
|
|
24
|
+
import com.facebook.react.modules.core.PermissionListener;
|
|
12
25
|
|
|
26
|
+
import java.util.ArrayList;
|
|
27
|
+
import java.util.Arrays;
|
|
13
28
|
import java.util.HashSet;
|
|
29
|
+
import java.util.List;
|
|
14
30
|
import java.util.Set;
|
|
15
31
|
|
|
16
|
-
public class DailyNativeUtils extends ReactContextBaseJavaModule {
|
|
32
|
+
public class DailyNativeUtils extends ReactContextBaseJavaModule implements PermissionListener {
|
|
17
33
|
|
|
18
34
|
private static final String TAG = DailyNativeUtils.class.getName();
|
|
35
|
+
private static int PERMISSION_REQUEST_CODE = 666;
|
|
19
36
|
|
|
20
37
|
private final ReactApplicationContext reactContext;
|
|
21
38
|
private Set<String> requestersKeepingDeviceAwake = new HashSet<>();
|
|
22
39
|
private Set<String> requestersShowingOngoingMeetingNotification = new HashSet<>();
|
|
23
40
|
|
|
41
|
+
// Info's received to crete the notification
|
|
42
|
+
private String title;
|
|
43
|
+
private String subtitle;
|
|
44
|
+
private String iconName;
|
|
45
|
+
|
|
24
46
|
public DailyNativeUtils(ReactApplicationContext reactContext) {
|
|
25
47
|
super(reactContext);
|
|
26
48
|
this.reactContext = reactContext;
|
|
@@ -74,7 +96,10 @@ public class DailyNativeUtils extends ReactContextBaseJavaModule {
|
|
|
74
96
|
} else {
|
|
75
97
|
requestersShowingOngoingMeetingNotification.remove(requesterId);
|
|
76
98
|
}
|
|
77
|
-
|
|
99
|
+
this.title = title;
|
|
100
|
+
this.subtitle = subtitle;
|
|
101
|
+
this.iconName = iconName;
|
|
102
|
+
updateOngoingMeetingForegroundService();
|
|
78
103
|
});
|
|
79
104
|
}
|
|
80
105
|
}
|
|
@@ -88,9 +113,57 @@ public class DailyNativeUtils extends ReactContextBaseJavaModule {
|
|
|
88
113
|
}
|
|
89
114
|
}
|
|
90
115
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
116
|
+
@Override
|
|
117
|
+
public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
|
118
|
+
if (requestCode == PERMISSION_REQUEST_CODE &&
|
|
119
|
+
Arrays.stream(grantResults).allMatch(result -> result == PackageManager.PERMISSION_GRANTED)) {
|
|
120
|
+
this.initializeOngoingMeetingForegroundService();
|
|
121
|
+
} else {
|
|
122
|
+
System.err.println("Failed to grant permissions.");
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private void checkPermissions() {
|
|
128
|
+
List<String> permissionList = new ArrayList<String>();
|
|
129
|
+
permissionList.add(Manifest.permission.CAMERA);
|
|
130
|
+
permissionList.add(Manifest.permission.RECORD_AUDIO);
|
|
131
|
+
if (Build.VERSION.SDK_INT >= 33) {
|
|
132
|
+
permissionList.add(Manifest.permission.POST_NOTIFICATIONS);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
boolean allPermissionsGranted = true;
|
|
136
|
+
for (String permission : permissionList) {
|
|
137
|
+
if (ContextCompat.checkSelfPermission(this.reactContext.getApplicationContext(), permission) != PackageManager.PERMISSION_GRANTED) {
|
|
138
|
+
allPermissionsGranted = false;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!allPermissionsGranted) {
|
|
144
|
+
Activity currentActivity = this.reactContext.getCurrentActivity();
|
|
145
|
+
if (currentActivity instanceof PermissionAwareActivity) {
|
|
146
|
+
PermissionAwareActivity permissionAware = (PermissionAwareActivity) currentActivity;
|
|
147
|
+
permissionAware.requestPermissions(permissionList.toArray(new String[0]), PERMISSION_REQUEST_CODE, this);
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
// Permissions are already granted, we can initialize
|
|
151
|
+
initializeOngoingMeetingForegroundService();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private void initializeOngoingMeetingForegroundService(){
|
|
156
|
+
Activity activity = getCurrentActivity();
|
|
157
|
+
if (activity != null) {
|
|
158
|
+
activity.runOnUiThread(() -> {
|
|
159
|
+
DailyOngoingMeetingForegroundService.start(activity.getClass(), title, subtitle, iconName, reactContext);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private void updateOngoingMeetingForegroundService() {
|
|
165
|
+
if (!requestersShowingOngoingMeetingNotification.isEmpty()) {
|
|
166
|
+
this.checkPermissions();
|
|
94
167
|
} else {
|
|
95
168
|
DailyOngoingMeetingForegroundService.stop(reactContext);
|
|
96
169
|
}
|
package/dist/index.js
CHANGED
|
@@ -137,36 +137,8 @@ function setupGlobals() {
|
|
|
137
137
|
systemScreenCaptureStartCallback = listener;
|
|
138
138
|
}, platform: react_native_1.Platform });
|
|
139
139
|
}
|
|
140
|
-
function maybeCreatePromiseAnyPolyfill() {
|
|
141
|
-
// Support to Promise.any has only been introduced on RN 0.70.6
|
|
142
|
-
// https://github.com/facebook/react-native/releases/tag/v0.70.6
|
|
143
|
-
// As spec: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
|
|
144
|
-
// The Promise.any() static method takes an iterable of promises as input and returns a single Promise.
|
|
145
|
-
// This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value.
|
|
146
|
-
// It rejects when all of the input's promises reject (including when an empty iterable is passed)
|
|
147
|
-
if (!Promise.any) {
|
|
148
|
-
Promise.any = function (promises) {
|
|
149
|
-
return new Promise(function (resolve, reject) {
|
|
150
|
-
var errors = [];
|
|
151
|
-
promises.forEach(function (promise) {
|
|
152
|
-
return Promise.resolve(promise)
|
|
153
|
-
.then(function (value) {
|
|
154
|
-
resolve(value);
|
|
155
|
-
})
|
|
156
|
-
.catch(function (error) {
|
|
157
|
-
errors.push(error);
|
|
158
|
-
if (errors.length === promises.length) {
|
|
159
|
-
reject(errors);
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
140
|
setupEventListeners();
|
|
168
141
|
setupGlobals();
|
|
169
|
-
maybeCreatePromiseAnyPolyfill();
|
|
170
142
|
exports.default = daily_js_1.default;
|
|
171
143
|
__exportStar(require("@daily-co/daily-js"), exports);
|
|
172
144
|
__exportStar(require("@daily-co/react-native-webrtc"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daily-co/react-native-daily-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.60.0",
|
|
4
4
|
"description": "React Native library for making video calls using Daily",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,20 +28,20 @@
|
|
|
28
28
|
"baseUrl": "https://github.com/daily-co/react-native-daily-js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@daily-co/daily-js": "^0.
|
|
31
|
+
"@daily-co/daily-js": "^0.62.0",
|
|
32
32
|
"@types/react-native-background-timer": "^2.0.0",
|
|
33
33
|
"base-64": "^1.0.0",
|
|
34
34
|
"react-native-url-polyfill": "^1.1.2"
|
|
35
35
|
},
|
|
36
36
|
"///": "WHEN ONE OF THESE CHANGE, PLEASE UPDATE README.md INSTALL SNIPPET ACCORDINGLY",
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@daily-co/react-native-webrtc": "^
|
|
38
|
+
"@daily-co/react-native-webrtc": "^118.0.3-daily.2",
|
|
39
39
|
"@react-native-async-storage/async-storage": "^1.15.7",
|
|
40
40
|
"react-native-background-timer": "^2.3.1",
|
|
41
41
|
"react-native-get-random-values": "^1.9.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@daily-co/react-native-webrtc": "^
|
|
44
|
+
"@daily-co/react-native-webrtc": "^118.0.3-daily.2",
|
|
45
45
|
"@react-native-async-storage/async-storage": "^1.15.7",
|
|
46
46
|
"@types/base-64": "^1.0.0",
|
|
47
47
|
"react-native-background-timer": "^2.3.1",
|
|
@@ -87,6 +87,8 @@ export type DailyEvent =
|
|
|
87
87
|
| 'waiting-participant-removed'
|
|
88
88
|
| 'available-devices-updated'
|
|
89
89
|
| 'receive-settings-updated'
|
|
90
|
+
| 'local-audio-level'
|
|
91
|
+
| 'remote-participants-audio-level'
|
|
90
92
|
| 'dialin-connected'
|
|
91
93
|
| 'dialin-error'
|
|
92
94
|
| 'dialin-stopped'
|
|
@@ -130,6 +132,7 @@ export type DailyFatalErrorType =
|
|
|
130
132
|
|
|
131
133
|
export type DailyNonFatalErrorType =
|
|
132
134
|
| 'screen-share-error'
|
|
135
|
+
| 'local-audio-level-observer-error'
|
|
133
136
|
| 'remote-media-player-error'
|
|
134
137
|
| 'live-streaming-warning'
|
|
135
138
|
| 'meeting-session-data-error';
|
|
@@ -480,6 +483,7 @@ export interface DailyCpuLoadStats {
|
|
|
480
483
|
fps: number;
|
|
481
484
|
frameDecodeTimeSec: number;
|
|
482
485
|
interFrameDelayStandardDeviation: number;
|
|
486
|
+
cpuUsageBasedOnTargetDecode: number;
|
|
483
487
|
}[];
|
|
484
488
|
};
|
|
485
489
|
};
|
|
@@ -494,6 +498,10 @@ interface DailySendSettings {
|
|
|
494
498
|
| undefined;
|
|
495
499
|
}
|
|
496
500
|
|
|
501
|
+
export interface DailyParticipantsAudioLevel {
|
|
502
|
+
[participantId: string]: number;
|
|
503
|
+
}
|
|
504
|
+
|
|
497
505
|
export type DailyVideoSendSettingsPreset =
|
|
498
506
|
| 'default'
|
|
499
507
|
| 'bandwidth-optimized'
|
|
@@ -906,6 +914,16 @@ export interface DailyEventObjectSendSettingsUpdated {
|
|
|
906
914
|
sendSettings: DailySendSettings;
|
|
907
915
|
}
|
|
908
916
|
|
|
917
|
+
export interface DailyEventObjectLocalAudioLevel {
|
|
918
|
+
action: Extract<DailyEvent, 'local-audio-level'>;
|
|
919
|
+
audioLevel: number;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
export interface DailyEventObjectRemoteParticipantsAudioLevel {
|
|
923
|
+
action: Extract<DailyEvent, 'remote-participants-audio-level'>;
|
|
924
|
+
participantsAudioLevel: DailyParticipantsAudioLevel;
|
|
925
|
+
}
|
|
926
|
+
|
|
909
927
|
export interface DailyEventObjectLiveStreamingStarted {
|
|
910
928
|
action: Extract<DailyEvent, 'live-streaming-started'>;
|
|
911
929
|
layout?: DailyLiveStreamingLayoutConfig<'start'>;
|
|
@@ -1086,6 +1104,10 @@ export type DailyEventObject<T extends DailyEvent = any> =
|
|
|
1086
1104
|
? DailyEventObjectDialOutStopped
|
|
1087
1105
|
: T extends DailyEventObjectDialOutWarning['action']
|
|
1088
1106
|
? DailyEventObjectDialOutWarning
|
|
1107
|
+
: T extends DailyEventObjectLocalAudioLevel['action']
|
|
1108
|
+
? DailyEventObjectLocalAudioLevel
|
|
1109
|
+
: T extends DailyEventObjectRemoteParticipantsAudioLevel['action']
|
|
1110
|
+
? DailyEventObjectRemoteParticipantsAudioLevel
|
|
1089
1111
|
: any;
|
|
1090
1112
|
|
|
1091
1113
|
export type DailyNativeInCallAudioMode = 'video' | 'voice';
|
|
@@ -1352,6 +1374,12 @@ export interface DailyCall {
|
|
|
1352
1374
|
receiveSettings: DailyReceiveSettingsUpdates
|
|
1353
1375
|
): Promise<DailyReceiveSettings>;
|
|
1354
1376
|
startCamera(properties?: DailyCallOptions): Promise<void>;
|
|
1377
|
+
startLocalAudioLevelObserver(interval?: number): Promise<void>;
|
|
1378
|
+
stopLocalAudioLevelObserver(): void;
|
|
1379
|
+
getLocalAudioLevel(): number;
|
|
1380
|
+
startRemoteParticipantsAudioLevelObserver(interval?: number): Promise<void>;
|
|
1381
|
+
stopRemoteParticipantsAudioLevelObserver(): void;
|
|
1382
|
+
getRemoteParticipantsAudioLevel(): DailyParticipantsAudioLevel;
|
|
1355
1383
|
cycleCamera(): Promise<{
|
|
1356
1384
|
device: { facingMode: DailyCameraFacingMode } | null;
|
|
1357
1385
|
}>;
|
|
@@ -1424,15 +1452,15 @@ export interface DailyCall {
|
|
|
1424
1452
|
geo(): Promise<{ current: string }>;
|
|
1425
1453
|
on<T extends DailyEvent>(
|
|
1426
1454
|
event: T,
|
|
1427
|
-
handler: (event
|
|
1455
|
+
handler: (event: DailyEventObject<T>) => void
|
|
1428
1456
|
): DailyCall;
|
|
1429
1457
|
once<T extends DailyEvent>(
|
|
1430
1458
|
event: T,
|
|
1431
|
-
handler: (event
|
|
1459
|
+
handler: (event: DailyEventObject<T>) => void
|
|
1432
1460
|
): DailyCall;
|
|
1433
1461
|
off<T extends DailyEvent>(
|
|
1434
1462
|
event: T,
|
|
1435
|
-
handler: (event
|
|
1463
|
+
handler: (event: DailyEventObject<T>) => void
|
|
1436
1464
|
): DailyCall;
|
|
1437
1465
|
properties: {
|
|
1438
1466
|
dailyConfig?: DailyAdvancedConfig;
|