@stream-io/video-react-native-sdk 0.7.8 → 0.7.10

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/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ### [0.7.10](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-0.7.9...@stream-io/video-react-native-sdk-0.7.10) (2024-05-23)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `@stream-io/video-client` updated to version `1.0.8`
10
+ * `@stream-io/video-react-bindings` updated to version `0.4.34`
11
+ ### [0.7.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-0.7.8...@stream-io/video-react-native-sdk-0.7.9) (2024-05-22)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * workaround for samsung device ringtone quirks ([#1362](https://github.com/GetStream/stream-video-js/issues/1362)) ([d15380a](https://github.com/GetStream/stream-video-js/commit/d15380a4aac2bd9b7b6dc6b9de337739710c97b8))
17
+
5
18
  ### [0.7.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-0.7.7...@stream-io/video-react-native-sdk-0.7.8) (2024-05-21)
6
19
 
7
20
  ### Dependency Updates
@@ -4,6 +4,7 @@ import android.app.AppOpsManager
4
4
  import android.app.PictureInPictureParams
5
5
  import android.content.Context
6
6
  import android.content.pm.PackageManager
7
+ import android.net.Uri
7
8
  import android.os.Build
8
9
  import android.os.Process
9
10
  import android.util.Rational
@@ -13,8 +14,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
13
14
  import com.facebook.react.bridge.ReactMethod
14
15
  import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
15
16
  import com.facebook.react.bridge.Promise;
16
- import android.media.RingtoneManager;
17
-
17
+ import com.streamvideo.reactnative.util.RingtoneUtil
18
18
 
19
19
  class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
20
20
 
@@ -26,7 +26,7 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
26
26
 
27
27
  override fun initialize() {
28
28
  super.initialize()
29
- StreamVideoReactNative.pipListeners.add {isInPictureInPictureMode ->
29
+ StreamVideoReactNative.pipListeners.add { isInPictureInPictureMode ->
30
30
  reactApplicationContext.getJSModule(
31
31
  RCTDeviceEventEmitter::class.java
32
32
  ).emit(PIP_CHANGE_EVENT, isInPictureInPictureMode)
@@ -36,7 +36,13 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
36
36
 
37
37
  @ReactMethod
38
38
  fun getDefaultRingtoneUrl(promise: Promise) {
39
- promise.resolve(RingtoneManager.getActualDefaultRingtoneUri(reactApplicationContext, RingtoneManager.TYPE_RINGTONE).toString());
39
+ val defaultRingtoneUri: Uri? =
40
+ RingtoneUtil.getActualDefaultRingtoneUri(reactApplicationContext);
41
+ if (defaultRingtoneUri != null) {
42
+ promise.resolve(defaultRingtoneUri.toString());
43
+ } else {
44
+ promise.reject(NAME, "Cannot get default ringtone in Android - check native logs for more info");
45
+ }
40
46
  }
41
47
 
42
48
  @ReactMethod
@@ -65,9 +71,9 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
65
71
  }
66
72
  }
67
73
 
68
- override fun onCatalystInstanceDestroy() {
69
- StreamVideoReactNative.pipListeners.clear()
70
- super.onCatalystInstanceDestroy()
74
+ override fun invalidate() {
75
+ StreamVideoReactNative.pipListeners.clear();
76
+ super.invalidate()
71
77
  }
72
78
 
73
79
  @ReactMethod
@@ -0,0 +1,121 @@
1
+ package com.streamvideo.reactnative.util;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.content.ContentResolver;
5
+ import android.content.Context;
6
+ import android.media.Ringtone;
7
+ import android.media.RingtoneManager;
8
+ import android.net.Uri;
9
+ import android.provider.Settings;
10
+ import android.util.Log;
11
+
12
+ import androidx.annotation.NonNull;
13
+ import androidx.annotation.Nullable;
14
+
15
+ import java.lang.reflect.InvocationTargetException;
16
+ import java.lang.reflect.Method;
17
+
18
+ /**
19
+ * Original source: https://github.com/signalapp/Signal-Android/blob/main/app/src/main/java/org/thoughtcrime/securesms/util/RingtoneUtil.java
20
+ * Some custom ROMs and some Samsung Android 11 devices have quirks around accessing the default ringtone. This attempts to deal
21
+ * with them with progressively worse approaches.
22
+ */
23
+ public final class RingtoneUtil {
24
+
25
+ private static final String TAG = "RingtoneUtil";
26
+
27
+ private RingtoneUtil() {}
28
+
29
+ public static @Nullable Ringtone getRingtone(@NonNull Context context, @NonNull Uri uri) {
30
+ Ringtone tone;
31
+ try {
32
+ tone = RingtoneManager.getRingtone(context, uri);
33
+ } catch (SecurityException e) {
34
+ Log.w(TAG, "Unable to get default ringtone due to permission", e);
35
+ tone = RingtoneManager.getRingtone(context, RingtoneUtil.getActualDefaultRingtoneUri(context));
36
+ }
37
+ return tone;
38
+ }
39
+
40
+ public static @Nullable Uri getActualDefaultRingtoneUri(@NonNull Context context) {
41
+ Log.i(TAG, "Attempting to get default ringtone directly via normal way");
42
+ try {
43
+ return RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE);
44
+ } catch (SecurityException e) {
45
+ Log.w(TAG, "Failed to get ringtone with first fallback approach", e);
46
+ }
47
+
48
+ Log.i(TAG, "Attempting to get default ringtone directly via reflection");
49
+ String uriString = getStringForUser(context.getContentResolver(), getUserId(context));
50
+ Uri ringtoneUri = uriString != null ? Uri.parse(uriString) : null;
51
+
52
+ if (ringtoneUri != null && getUserIdFromAuthority(ringtoneUri.getAuthority(), getUserId(context)) == getUserId(context)) {
53
+ ringtoneUri = getUriWithoutUserId(ringtoneUri);
54
+ }
55
+
56
+ return ringtoneUri;
57
+ }
58
+
59
+ @SuppressWarnings("JavaReflectionMemberAccess")
60
+ @SuppressLint("DiscouragedPrivateApi")
61
+ private static @Nullable String getStringForUser(@NonNull ContentResolver resolver, int userHandle) {
62
+ try {
63
+ Method getStringForUser = Settings.System.class.getMethod("getStringForUser", ContentResolver.class, String.class, int.class);
64
+ return (String) getStringForUser.invoke(Settings.System.class, resolver, Settings.System.RINGTONE, userHandle);
65
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
66
+ Log.w(TAG, "Unable to getStringForUser via reflection", e);
67
+ }
68
+ return null;
69
+ }
70
+
71
+ @SuppressWarnings("JavaReflectionMemberAccess")
72
+ @SuppressLint("DiscouragedPrivateApi")
73
+ private static int getUserId(@NonNull Context context) {
74
+ try {
75
+ Object userId = Context.class.getMethod("getUserId").invoke(context);
76
+ if (userId instanceof Integer) {
77
+ return (Integer) userId;
78
+ } else {
79
+ Log.w(TAG, "getUserId did not return an integer");
80
+ }
81
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
82
+ Log.w(TAG, "Unable to getUserId via reflection", e);
83
+ }
84
+ return 0;
85
+ }
86
+
87
+ private static @Nullable Uri getUriWithoutUserId(@Nullable Uri uri) {
88
+ if (uri == null) {
89
+ return null;
90
+ }
91
+ Uri.Builder builder = uri.buildUpon();
92
+ builder.authority(getAuthorityWithoutUserId(uri.getAuthority()));
93
+ return builder.build();
94
+ }
95
+
96
+ private static @Nullable String getAuthorityWithoutUserId(@Nullable String auth) {
97
+ if (auth == null) {
98
+ return null;
99
+ }
100
+ int end = auth.lastIndexOf('@');
101
+ return auth.substring(end + 1);
102
+ }
103
+
104
+ private static int getUserIdFromAuthority(@Nullable String authority, int defaultUserId) {
105
+ if (authority == null) {
106
+ return defaultUserId;
107
+ }
108
+
109
+ int end = authority.lastIndexOf('@');
110
+ if (end == -1) {
111
+ return defaultUserId;
112
+ }
113
+
114
+ String userIdString = authority.substring(0, end);
115
+ try {
116
+ return Integer.parseInt(userIdString);
117
+ } catch (NumberFormatException e) {
118
+ return defaultUserId;
119
+ }
120
+ }
121
+ }
@@ -6,11 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getAndroidDefaultRingtoneUrl = getAndroidDefaultRingtoneUrl;
7
7
  var _reactNative = require("react-native");
8
8
  async function getAndroidDefaultRingtoneUrl() {
9
- var _NativeModules$Stream;
10
9
  if (_reactNative.Platform.OS !== 'android') {
11
10
  return undefined;
12
11
  }
13
- const url = await ((_NativeModules$Stream = _reactNative.NativeModules.StreamVideoReactNative) === null || _NativeModules$Stream === void 0 ? void 0 : _NativeModules$Stream.getDefaultRingtoneUrl());
14
- return url;
12
+ try {
13
+ var _NativeModules$Stream;
14
+ const url = await ((_NativeModules$Stream = _reactNative.NativeModules.StreamVideoReactNative) === null || _NativeModules$Stream === void 0 ? void 0 : _NativeModules$Stream.getDefaultRingtoneUrl());
15
+ return url;
16
+ } catch (e) {
17
+ console.info(e);
18
+ }
19
+ return undefined;
15
20
  }
16
21
  //# sourceMappingURL=getAndroidDefaultRingtoneUrl.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","getAndroidDefaultRingtoneUrl","_NativeModules$Stream","Platform","OS","undefined","url","NativeModules","StreamVideoReactNative","getDefaultRingtoneUrl"],"sourceRoot":"../../../src","sources":["utils/getAndroidDefaultRingtoneUrl.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEO,eAAeC,4BAA4BA,CAAA,EAEhD;EAAA,IAAAC,qBAAA;EACA,IAAIC,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;IAC7B,OAAOC,SAAS;EAClB;EACA,MAAMC,GAAG,GACP,QAAAJ,qBAAA,GAAMK,0BAAa,CAACC,sBAAsB,cAAAN,qBAAA,uBAApCA,qBAAA,CAAsCO,qBAAqB,CAAC,CAAC;EACrE,OAAOH,GAAG;AACZ"}
1
+ {"version":3,"names":["_reactNative","require","getAndroidDefaultRingtoneUrl","Platform","OS","undefined","_NativeModules$Stream","url","NativeModules","StreamVideoReactNative","getDefaultRingtoneUrl","e","console","info"],"sourceRoot":"../../../src","sources":["utils/getAndroidDefaultRingtoneUrl.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEO,eAAeC,4BAA4BA,CAAA,EAEhD;EACA,IAAIC,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;IAC7B,OAAOC,SAAS;EAClB;EACA,IAAI;IAAA,IAAAC,qBAAA;IACF,MAAMC,GAAG,GACP,QAAAD,qBAAA,GAAME,0BAAa,CAACC,sBAAsB,cAAAH,qBAAA,uBAApCA,qBAAA,CAAsCI,qBAAqB,CAAC,CAAC;IACrE,OAAOH,GAAG;EACZ,CAAC,CAAC,OAAOI,CAAC,EAAE;IACVC,OAAO,CAACC,IAAI,CAACF,CAAC,CAAC;EACjB;EAEA,OAAON,SAAS;AAClB"}
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.version = void 0;
7
- const version = exports.version = '0.7.8';
7
+ const version = exports.version = '0.7.10';
8
8
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["version","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,OAAO"}
1
+ {"version":3,"names":["version","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAO,MAAMA,OAAO,GAAAC,OAAA,CAAAD,OAAA,GAAG,QAAQ"}
@@ -1,10 +1,15 @@
1
1
  import { NativeModules, Platform } from 'react-native';
2
2
  export async function getAndroidDefaultRingtoneUrl() {
3
- var _NativeModules$Stream;
4
3
  if (Platform.OS !== 'android') {
5
4
  return undefined;
6
5
  }
7
- const url = await ((_NativeModules$Stream = NativeModules.StreamVideoReactNative) === null || _NativeModules$Stream === void 0 ? void 0 : _NativeModules$Stream.getDefaultRingtoneUrl());
8
- return url;
6
+ try {
7
+ var _NativeModules$Stream;
8
+ const url = await ((_NativeModules$Stream = NativeModules.StreamVideoReactNative) === null || _NativeModules$Stream === void 0 ? void 0 : _NativeModules$Stream.getDefaultRingtoneUrl());
9
+ return url;
10
+ } catch (e) {
11
+ console.info(e);
12
+ }
13
+ return undefined;
9
14
  }
10
15
  //# sourceMappingURL=getAndroidDefaultRingtoneUrl.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","Platform","getAndroidDefaultRingtoneUrl","_NativeModules$Stream","OS","undefined","url","StreamVideoReactNative","getDefaultRingtoneUrl"],"sourceRoot":"../../../src","sources":["utils/getAndroidDefaultRingtoneUrl.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,OAAO,eAAeC,4BAA4BA,CAAA,EAEhD;EAAA,IAAAC,qBAAA;EACA,IAAIF,QAAQ,CAACG,EAAE,KAAK,SAAS,EAAE;IAC7B,OAAOC,SAAS;EAClB;EACA,MAAMC,GAAG,GACP,QAAAH,qBAAA,GAAMH,aAAa,CAACO,sBAAsB,cAAAJ,qBAAA,uBAApCA,qBAAA,CAAsCK,qBAAqB,CAAC,CAAC;EACrE,OAAOF,GAAG;AACZ"}
1
+ {"version":3,"names":["NativeModules","Platform","getAndroidDefaultRingtoneUrl","OS","undefined","_NativeModules$Stream","url","StreamVideoReactNative","getDefaultRingtoneUrl","e","console","info"],"sourceRoot":"../../../src","sources":["utils/getAndroidDefaultRingtoneUrl.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,OAAO,eAAeC,4BAA4BA,CAAA,EAEhD;EACA,IAAID,QAAQ,CAACE,EAAE,KAAK,SAAS,EAAE;IAC7B,OAAOC,SAAS;EAClB;EACA,IAAI;IAAA,IAAAC,qBAAA;IACF,MAAMC,GAAG,GACP,QAAAD,qBAAA,GAAML,aAAa,CAACO,sBAAsB,cAAAF,qBAAA,uBAApCA,qBAAA,CAAsCG,qBAAqB,CAAC,CAAC;IACrE,OAAOF,GAAG;EACZ,CAAC,CAAC,OAAOG,CAAC,EAAE;IACVC,OAAO,CAACC,IAAI,CAACF,CAAC,CAAC;EACjB;EAEA,OAAOL,SAAS;AAClB"}
@@ -1,2 +1,2 @@
1
- export const version = '0.7.8';
1
+ export const version = '0.7.10';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["version"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":"AAAA,OAAO,MAAMA,OAAO,GAAG,OAAO"}
1
+ {"version":3,"names":["version"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":"AAAA,OAAO,MAAMA,OAAO,GAAG,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"getAndroidDefaultRingtoneUrl.d.ts","sourceRoot":"","sources":["../../../src/utils/getAndroidDefaultRingtoneUrl.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,IAAI,OAAO,CAC3D,MAAM,GAAG,SAAS,CACnB,CAOA"}
1
+ {"version":3,"file":"getAndroidDefaultRingtoneUrl.d.ts","sourceRoot":"","sources":["../../../src/utils/getAndroidDefaultRingtoneUrl.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,IAAI,OAAO,CAC3D,MAAM,GAAG,SAAS,CACnB,CAaA"}
@@ -1,2 +1,2 @@
1
- export declare const version = "0.7.8";
1
+ export declare const version = "0.7.10";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-native-sdk",
3
- "version": "0.7.8",
3
+ "version": "0.7.10",
4
4
  "packageManager": "yarn@3.2.4",
5
5
  "main": "dist/commonjs/index.js",
6
6
  "module": "dist/module/index.js",
@@ -45,8 +45,8 @@
45
45
  "!**/.*"
46
46
  ],
47
47
  "dependencies": {
48
- "@stream-io/video-client": "^1.0.7",
49
- "@stream-io/video-react-bindings": "^0.4.33",
48
+ "@stream-io/video-client": "^1.0.8",
49
+ "@stream-io/video-react-bindings": "^0.4.34",
50
50
  "intl-pluralrules": "2.0.1",
51
51
  "lodash.merge": "^4.6.2",
52
52
  "react-native-url-polyfill": "1.3.0",
@@ -6,7 +6,13 @@ export async function getAndroidDefaultRingtoneUrl(): Promise<
6
6
  if (Platform.OS !== 'android') {
7
7
  return undefined;
8
8
  }
9
- const url =
10
- await NativeModules.StreamVideoReactNative?.getDefaultRingtoneUrl();
11
- return url;
9
+ try {
10
+ const url =
11
+ await NativeModules.StreamVideoReactNative?.getDefaultRingtoneUrl();
12
+ return url;
13
+ } catch (e) {
14
+ console.info(e);
15
+ }
16
+
17
+ return undefined;
12
18
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '0.7.8';
1
+ export const version = '0.7.10';