@stream-io/video-react-native-sdk 1.19.1 → 1.20.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js +10 -1
  3. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  4. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js +3 -2
  5. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
  6. package/dist/commonjs/contexts/BackgroundFilters.js +4 -0
  7. package/dist/commonjs/contexts/BackgroundFilters.js.map +1 -1
  8. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +31 -12
  9. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  10. package/dist/commonjs/hooks/useTrackDimensions.js +31 -35
  11. package/dist/commonjs/hooks/useTrackDimensions.js.map +1 -1
  12. package/dist/commonjs/providers/StreamCall/DeviceStats.js +19 -8
  13. package/dist/commonjs/providers/StreamCall/DeviceStats.js.map +1 -1
  14. package/dist/commonjs/utils/StreamVideoRN/index.js +22 -6
  15. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  16. package/dist/commonjs/version.js +1 -1
  17. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js +10 -1
  18. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  19. package/dist/module/components/Participant/ParticipantView/VideoRenderer.js +3 -2
  20. package/dist/module/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
  21. package/dist/module/contexts/BackgroundFilters.js +4 -0
  22. package/dist/module/contexts/BackgroundFilters.js.map +1 -1
  23. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +31 -12
  24. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  25. package/dist/module/hooks/useTrackDimensions.js +30 -35
  26. package/dist/module/hooks/useTrackDimensions.js.map +1 -1
  27. package/dist/module/providers/StreamCall/DeviceStats.js +20 -9
  28. package/dist/module/providers/StreamCall/DeviceStats.js.map +1 -1
  29. package/dist/module/utils/StreamVideoRN/index.js +23 -6
  30. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  31. package/dist/module/version.js +1 -1
  32. package/dist/typescript/components/Call/CallLayout/CallParticipantsGrid.d.ts.map +1 -1
  33. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer.d.ts.map +1 -1
  34. package/dist/typescript/contexts/BackgroundFilters.d.ts.map +1 -1
  35. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  36. package/dist/typescript/hooks/useTrackDimensions.d.ts +2 -2
  37. package/dist/typescript/hooks/useTrackDimensions.d.ts.map +1 -1
  38. package/dist/typescript/providers/StreamCall/DeviceStats.d.ts.map +1 -1
  39. package/dist/typescript/utils/StreamVideoRN/index.d.ts +6 -2
  40. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  41. package/dist/typescript/utils/StreamVideoRN/types.d.ts +6 -1
  42. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  43. package/dist/typescript/version.d.ts +1 -1
  44. package/package.json +7 -7
  45. package/src/components/Call/CallLayout/CallParticipantsGrid.tsx +12 -5
  46. package/src/components/Participant/ParticipantView/VideoRenderer.tsx +7 -2
  47. package/src/contexts/BackgroundFilters.tsx +4 -0
  48. package/src/hooks/useAndroidKeepCallAliveEffect.ts +30 -10
  49. package/src/hooks/useTrackDimensions.ts +51 -34
  50. package/src/providers/StreamCall/DeviceStats.tsx +20 -9
  51. package/src/utils/StreamVideoRN/index.ts +41 -6
  52. package/src/utils/StreamVideoRN/types.ts +6 -0
  53. package/src/version.ts +1 -1
@@ -1,2 +1,2 @@
1
- export const version = '1.19.1';
1
+ export const version = '1.20.0';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CallParticipantsGrid.d.ts","sourceRoot":"","sources":["../../../../../src/components/Call/CallLayout/CallParticipantsGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAEL,KAAK,kCAAkC,EACxC,MAAM,8CAA8C,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAGvE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,6BAA6B,GACnE,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,GAAG,sBAAsB,CAAC,GACrE,IAAI,CAAC,kCAAkC,EAAE,iBAAiB,CAAC,GAAG;IAC5D;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,qNAWlC,yBAAyB,sBA2E3B,CAAC"}
1
+ {"version":3,"file":"CallParticipantsGrid.d.ts","sourceRoot":"","sources":["../../../../../src/components/Call/CallLayout/CallParticipantsGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAEL,KAAK,kCAAkC,EACxC,MAAM,8CAA8C,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAIvE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,6BAA6B,GACnE,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,GAAG,sBAAsB,CAAC,GACrE,IAAI,CAAC,kCAAkC,EAAE,iBAAiB,CAAC,GAAG;IAC5D;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,qNAWlC,yBAAyB,sBAiF3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"VideoRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/Participant/ParticipantView/VideoRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAIjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAwB9D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,EAClB,0BAA0B,GAC1B,WAAW,GACX,aAAa,GACb,WAAW,GACX,WAAW,GACX,aAAa,CAChB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,0FAO3B,kBAAkB,sBAqQpB,CAAC"}
1
+ {"version":3,"file":"VideoRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/Participant/ParticipantView/VideoRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAIjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAwB9D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,oBAAoB,EAClB,0BAA0B,GAC1B,WAAW,GACX,aAAa,GACb,WAAW,GACX,WAAW,GACX,aAAa,CAChB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,0FAO3B,kBAAkB,sBA0QpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackgroundFilters.d.ts","sourceRoot":"","sources":["../../../src/contexts/BackgroundFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,EAAY,MAAM,cAAc,CAAC;AAoB/C,QAAA,MAAM,sBAAsB,iCAA2B,CAAC;AAGxD,KAAK,eAAe,GAAG,OAAO,CAC5B,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5C,KAAK,CAAC,GAAG,CAAC,CACX,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7D;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,0BAA0B,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAClE;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;OAEG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AASF;;GAEG;AACH,eAAO,MAAM,oBAAoB,4BAahC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,iBAAiB,sBA0HxE,CAAC"}
1
+ {"version":3,"file":"BackgroundFilters.d.ts","sourceRoot":"","sources":["../../../src/contexts/BackgroundFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,KAAK,iBAAiB,EAMvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,EAAY,MAAM,cAAc,CAAC;AAoB/C,QAAA,MAAM,sBAAsB,iCAA2B,CAAC;AAGxD,KAAK,eAAe,GAAG,OAAO,CAC5B,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAC5C,KAAK,CAAC,GAAG,CAAC,CACX,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7D;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,0BAA0B,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAClE;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7D;;OAEG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AASF;;GAEG;AACH,eAAO,MAAM,oBAAoB,4BAahC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,iBAAiB,sBA8HxE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAndroidKeepCallAliveEffect.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAndroidKeepCallAliveEffect.ts"],"names":[],"mappings":"AAmGA;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,YA0GzC,CAAC"}
1
+ {"version":3,"file":"useAndroidKeepCallAliveEffect.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAndroidKeepCallAliveEffect.ts"],"names":[],"mappings":"AAkHA;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,YA+GzC,CAAC"}
@@ -1,10 +1,10 @@
1
- import { type StreamVideoParticipant } from '@stream-io/video-client';
1
+ import { type StreamVideoParticipant, type VideoTrackType } from '@stream-io/video-client';
2
2
  /**
3
3
  * This is a utility hook to get the dimensions of the video track of the participant.
4
4
  * Note: the `tracktype` is used only for local participants.
5
5
  * `tracktype` should be 'videoTrack' for video track and 'screenShareTrack' for screen share track.
6
6
  */
7
- export declare function useTrackDimensions(participant: StreamVideoParticipant): {
7
+ export declare function useTrackDimensions(participant: StreamVideoParticipant, trackType: VideoTrackType): {
8
8
  width: number;
9
9
  height: number;
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useTrackDimensions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useTrackDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAItE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,sBAAsB;;;EA2CrE"}
1
+ {"version":3,"file":"useTrackDimensions.d.ts","sourceRoot":"","sources":["../../../src/hooks/useTrackDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAMjC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,sBAAsB,EACnC,SAAS,EAAE,cAAc;;;EAqD1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceStats.d.ts","sourceRoot":"","sources":["../../../../src/providers/StreamCall/DeviceStats.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,WAAW,YA0CvB,CAAC"}
1
+ {"version":3,"file":"DeviceStats.d.ts","sourceRoot":"","sources":["../../../../src/providers/StreamCall/DeviceStats.tsx"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,WAAW,YAqDvB,CAAC"}
@@ -1,13 +1,16 @@
1
1
  import type { StreamVideoConfig } from './types';
2
2
  import { type NewCallNotificationCallback } from '../internal/newNotificationCallbacks';
3
+ type DeepPartial<T> = {
4
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
5
+ };
3
6
  export declare class StreamVideoRN {
4
7
  private static config;
5
8
  /**
6
9
  * Update the global config for StreamVideoRN except for push config.
7
10
  * To set push config use `StreamVideoRN.setPushConfig` instead.
8
- * This function accepts a partial config object that will be merged with the default config.
11
+ * This function accepts a partial config object that will be deeply merged with the default config.
9
12
  */
10
- static updateConfig(updateConfig: Partial<Omit<StreamVideoConfig, 'push'>>): void;
13
+ static updateConfig(updateConfig: DeepPartial<Omit<StreamVideoConfig, 'push'>>): void;
11
14
  static updateAndroidIncomingCallChannel(updateChannel: Partial<NonNullable<StreamVideoConfig['push']>['android']['incomingCallChannel']>): void;
12
15
  /**
13
16
  * Set the push config for StreamVideoRN.
@@ -39,4 +42,5 @@ export declare class StreamVideoRN {
39
42
  */
40
43
  static addOnNewCallNotificationListener(callback: NewCallNotificationCallback): () => void;
41
44
  }
45
+ export {};
42
46
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAiC,EAC/B,KAAK,2BAA2B,EACjC,MAAM,sCAAsC,CAAC;AAsB9C,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA+B;IAEpD;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAO1E,MAAM,CAAC,gCAAgC,CACrC,aAAa,EAAE,OAAO,CACpB,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CACzE;IAWH;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAsBvE,MAAM,CAAC,SAAS;IAIhB;;;OAGG;IACH,MAAM,CAAC,YAAY;IASnB,MAAM,CAAC,wBAAwB;IAI/B;;;;OAIG;IACH,MAAM,CAAC,gCAAgC,CACrC,QAAQ,EAAE,2BAA2B;CAYxC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAiC,EAC/B,KAAK,2BAA2B,EACjC,MAAM,sCAAsC,CAAC;AAK9C,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC;AAmDF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA+B;IAEpD;;;;OAIG;IACH,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAK5D,MAAM,CAAC,gCAAgC,CACrC,aAAa,EAAE,OAAO,CACpB,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CACzE;IAWH;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAsBvE,MAAM,CAAC,SAAS;IAIhB;;;OAGG;IACH,MAAM,CAAC,YAAY;IASnB,MAAM,CAAC,wBAAwB;IAI/B;;;;OAIG;IACH,MAAM,CAAC,gCAAgC,CACrC,QAAQ,EAAE,2BAA2B;CAYxC"}
@@ -1,4 +1,4 @@
1
- import { type ClientPublishOptions, StreamVideoClient } from '@stream-io/video-client';
1
+ import { type ClientPublishOptions, StreamVideoClient, type Call } from '@stream-io/video-client';
2
2
  import type { AndroidChannel } from '@notifee/react-native';
3
3
  export type NonRingingPushEvent = 'call.live_started' | 'call.notification' | 'call.missed';
4
4
  export type StreamVideoConfig = {
@@ -140,6 +140,11 @@ export type StreamVideoConfig = {
140
140
  title: string;
141
141
  body: string;
142
142
  };
143
+ /**
144
+ * The task to run in the foreground service
145
+ * The task must resolve a promise once complete
146
+ */
147
+ taskToRun: (call: Call) => Promise<void>;
143
148
  };
144
149
  };
145
150
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,mBAAmB,GAC3B,mBAAmB,GACnB,mBAAmB,GACnB,aAAa,CAAC;AAElB,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;QACtC,GAAG,EAAE;YACH;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;QACF,OAAO,EAAE;YACP;;;;eAIG;YACH,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B;;;;;;;;;eASG;YACH,WAAW,CAAC,EAAE,cAAc,CAAC;YAC7B;;;;;;;;;eASG;YACH,mBAAmB,CAAC,EAAE,cAAc,CAAC;YACrC;;;;;;;;;eASG;YACH,mCAAmC,CAAC,EAAE;gBACpC,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC9C,OAAO,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC7C,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;gBACpC,qBAAqB,CAAC,EAAE,MAAM,MAAM,CAAC;aACtC,CAAC;YACF;;;;;;;;;;;;;;;;;;;eAmBG;YACH,2BAA2B,CAAC,EAAE;gBAC5B,QAAQ,EAAE,CACR,IAAI,EAAE,mBAAmB,EACzB,eAAe,EAAE,MAAM,KACpB,MAAM,CAAC;gBACZ,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;aACzE,CAAC;SACH,CAAC;QACF;;;;;;;;;;;;;;;;;WAiBG;QACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;QACtE;yJACiJ;QACjJ,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;QAChC;yJACiJ;QACjJ,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;QACpC,8EAA8E;QAC9E,+BAA+B,CAAC,EAAE,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,mBAAmB,KACtB,IAAI,CAAC;KACX,CAAC;IACF,iBAAiB,EAAE;QACjB,OAAO,EAAE;YACP;;eAEG;YACH,OAAO,EAAE,cAAc,CAAC;YACxB;;eAEG;YACH,iBAAiB,EAAE;gBACjB,KAAK,EAAE,MAAM,CAAC;gBACd,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/utils/StreamVideoRN/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,iBAAiB,EACjB,KAAK,IAAI,EACV,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,mBAAmB,GAC3B,mBAAmB,GACnB,mBAAmB,GACnB,aAAa,CAAC;AAElB,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB;;;;WAIG;QACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;QACtC,GAAG,EAAE;YACH;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;QACF,OAAO,EAAE;YACP;;;;eAIG;YACH,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB;;;;eAIG;YACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAC1B;;;;;;;;;eASG;YACH,WAAW,CAAC,EAAE,cAAc,CAAC;YAC7B;;;;;;;;;eASG;YACH,mBAAmB,CAAC,EAAE,cAAc,CAAC;YACrC;;;;;;;;;eASG;YACH,mCAAmC,CAAC,EAAE;gBACpC,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC9C,OAAO,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;gBAC7C,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;gBACpC,qBAAqB,CAAC,EAAE,MAAM,MAAM,CAAC;aACtC,CAAC;YACF;;;;;;;;;;;;;;;;;;;eAmBG;YACH,2BAA2B,CAAC,EAAE;gBAC5B,QAAQ,EAAE,CACR,IAAI,EAAE,mBAAmB,EACzB,eAAe,EAAE,MAAM,KACpB,MAAM,CAAC;gBACZ,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;aACzE,CAAC;SACH,CAAC;QACF;;;;;;;;;;;;;;;;;WAiBG;QACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;QACtE;yJACiJ;QACjJ,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;QAChC;yJACiJ;QACjJ,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;QACpC,8EAA8E;QAC9E,+BAA+B,CAAC,EAAE,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,mBAAmB,KACtB,IAAI,CAAC;KACX,CAAC;IACF,iBAAiB,EAAE;QACjB,OAAO,EAAE;YACP;;eAEG;YACH,OAAO,EAAE,cAAc,CAAC;YACxB;;eAEG;YACH,iBAAiB,EAAE;gBACjB,KAAK,EAAE,MAAM,CAAC;gBACd,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;YACF;;;eAGG;YACH,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;SAC1C,CAAC;KACH,CAAC;CACH,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const version = "1.19.1";
1
+ export declare const version = "1.20.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-native-sdk",
3
- "version": "1.19.1",
3
+ "version": "1.20.0",
4
4
  "description": "Stream Video SDK for React Native",
5
5
  "author": "https://getstream.io",
6
6
  "homepage": "https://getstream.io/video/docs/react-native/",
@@ -45,8 +45,8 @@
45
45
  "!**/.*"
46
46
  ],
47
47
  "dependencies": {
48
- "@stream-io/video-client": "1.27.0",
49
- "@stream-io/video-react-bindings": "1.7.9",
48
+ "@stream-io/video-client": "1.27.1",
49
+ "@stream-io/video-react-bindings": "1.7.10",
50
50
  "intl-pluralrules": "2.0.1",
51
51
  "lodash.merge": "^4.6.2",
52
52
  "react-native-url-polyfill": "1.3.0",
@@ -60,7 +60,7 @@
60
60
  "@react-native-firebase/app": ">=17.5.0",
61
61
  "@react-native-firebase/messaging": ">=17.5.0",
62
62
  "@stream-io/noise-cancellation-react-native": ">=0.1.0",
63
- "@stream-io/react-native-webrtc": ">=125.2.1",
63
+ "@stream-io/react-native-webrtc": ">=125.4.0",
64
64
  "@stream-io/video-filters-react-native": ">=0.1.0",
65
65
  "expo": ">=47.0.0",
66
66
  "expo-build-properties": "*",
@@ -125,9 +125,9 @@
125
125
  "@react-native-firebase/app": "^22.1.0",
126
126
  "@react-native-firebase/messaging": "^22.1.0",
127
127
  "@react-native/babel-preset": "^0.79.2",
128
- "@stream-io/noise-cancellation-react-native": "^0.1.1",
129
- "@stream-io/react-native-webrtc": "^125.3.1",
130
- "@stream-io/video-filters-react-native": "^0.5.0",
128
+ "@stream-io/noise-cancellation-react-native": "^0.2.0",
129
+ "@stream-io/react-native-webrtc": "^125.4.0",
130
+ "@stream-io/video-filters-react-native": "^0.6.0",
131
131
  "@testing-library/jest-native": "^5.4.3",
132
132
  "@testing-library/react-native": "13.2.0",
133
133
  "@tsconfig/node14": "14.1.3",
@@ -11,6 +11,7 @@ import { useTheme } from '../../../contexts/ThemeContext';
11
11
  import type { CallContentProps } from '../CallContent';
12
12
  import type { ParticipantViewComponentProps } from '../../Participant';
13
13
  import { useIsInPiPMode } from '../../../hooks/useIsInPiPMode';
14
+ import { StreamVideoParticipant } from '@stream-io/video-client';
14
15
 
15
16
  /**
16
17
  * Props for the CallParticipantsGrid component.
@@ -71,11 +72,17 @@ export const CallParticipantsGrid = ({
71
72
  remoteParticipants.length > 0 &&
72
73
  remoteParticipants.length < 3;
73
74
 
74
- let participants = showFloatingView
75
- ? showLocalParticipant && localParticipant
76
- ? [localParticipant]
77
- : remoteParticipants
78
- : allParticipants;
75
+ let participants: StreamVideoParticipant[];
76
+
77
+ if (showFloatingView) {
78
+ if (showLocalParticipant && localParticipant) {
79
+ participants = [localParticipant];
80
+ } else {
81
+ participants = remoteParticipants;
82
+ }
83
+ } else {
84
+ participants = allParticipants;
85
+ }
79
86
 
80
87
  if (isInPiPMode) {
81
88
  if (dominantSpeaker && !dominantSpeaker.isLocalParticipant) {
@@ -73,7 +73,10 @@ export const VideoRenderer = ({
73
73
  deregister: deregisterIosScreenshot,
74
74
  } = useScreenshotIosContext();
75
75
 
76
- const videoDimensions = useTrackDimensions(participant);
76
+ const videoDimensions = useTrackDimensions(participant, trackType);
77
+
78
+ const isVideoDimensionsValid =
79
+ videoDimensions.width > 0 && videoDimensions.height > 0;
77
80
 
78
81
  const {
79
82
  isLocalParticipant,
@@ -291,7 +294,9 @@ export const VideoRenderer = ({
291
294
  onLayout={onLayout}
292
295
  style={[styles.container, videoRenderer.container]}
293
296
  >
294
- {canShowVideo && videoStreamToRender ? (
297
+ {canShowVideo &&
298
+ videoStreamToRender &&
299
+ (objectFit || isVideoDimensionsValid) ? (
295
300
  <RTCView
296
301
  style={[styles.videoStream, videoRenderer.videoStream]}
297
302
  streamURL={videoStreamToRender.toURL()}
@@ -139,6 +139,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
139
139
  } else if (blurIntensity === 'light') {
140
140
  filterName = 'BackgroundBlurLight';
141
141
  }
142
+ call?.tracer.trace('backgroundFilters.apply', filterName);
142
143
  (call?.camera.state.mediaStream as MediaStream | undefined)
143
144
  ?.getVideoTracks()
144
145
  .forEach((track) => {
@@ -164,6 +165,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
164
165
  } else if (blurIntensity === 'light') {
165
166
  filterName = 'BlurLight';
166
167
  }
168
+ call?.tracer.trace('backgroundFilters.apply', filterName);
167
169
  (call?.camera.state.mediaStream as MediaStream | undefined)
168
170
  ?.getVideoTracks()
169
171
  .forEach((track) => {
@@ -187,6 +189,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
187
189
  registeredImageFiltersSetRef.current.add(imageUri);
188
190
  }
189
191
  const filterName = `VirtualBackground-${imageUri}`;
192
+ call?.tracer.trace('backgroundFilters.apply', filterName);
190
193
  (call?.camera.state.mediaStream as MediaStream | undefined)
191
194
  ?.getVideoTracks()
192
195
  .forEach((track) => {
@@ -201,6 +204,7 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
201
204
  if (!isSupported) {
202
205
  return;
203
206
  }
207
+ call?.tracer.trace('backgroundFilters.disableAll', null);
204
208
  (call?.camera.state.mediaStream as MediaStream | undefined)
205
209
  ?.getVideoTracks()
206
210
  .forEach((track) => {
@@ -7,13 +7,16 @@ import {
7
7
  NativeModules,
8
8
  Platform,
9
9
  } from 'react-native';
10
- import { CallingState, getLogger } from '@stream-io/video-client';
10
+ import { Call, CallingState, getLogger } from '@stream-io/video-client';
11
11
  import {
12
12
  getKeepCallAliveForegroundServiceTypes,
13
13
  getNotifeeLibNoThrowForKeepCallAlive,
14
14
  } from '../utils/push/libs/notifee';
15
15
 
16
16
  const notifeeLib = getNotifeeLibNoThrowForKeepCallAlive();
17
+ const callToPassToForegroundService: { current: Call | undefined } = {
18
+ current: undefined,
19
+ };
17
20
 
18
21
  function setForegroundService() {
19
22
  if (Platform.OS === 'ios' || !notifeeLib) return;
@@ -28,22 +31,29 @@ function setForegroundService() {
28
31
  return;
29
32
  }
30
33
  notifeeLib.default.registerForegroundService(() => {
31
- return new Promise(() => {
34
+ const task = new Promise((resolve) => {
32
35
  const logger = getLogger(['setForegroundService method']);
33
36
  logger('info', 'Foreground service running for call in progress');
37
+ // any task to run from SDK in the foreground service must be added
38
+ resolve(true);
34
39
  });
40
+ const videoConfig = StreamVideoRN.getConfig();
41
+ const foregroundServiceConfig = videoConfig.foregroundService;
42
+ const { taskToRun } = foregroundServiceConfig.android;
43
+ const call = callToPassToForegroundService.current;
44
+ if (!call) {
45
+ const logger = getLogger(['setForegroundService method']);
46
+ logger('warn', 'No call to pass to foreground service');
47
+ return task.then(() => new Promise(() => {}));
48
+ }
49
+ callToPassToForegroundService.current = undefined;
50
+ return task.then(() => taskToRun(call));
35
51
  });
36
52
  },
37
53
  );
38
54
  }
39
55
 
40
56
  async function startForegroundService(call_cid: string) {
41
- const videoConfig = StreamVideoRN.getConfig();
42
- const foregroundServiceConfig = videoConfig.foregroundService;
43
- const { title, body } = foregroundServiceConfig.android.notificationTexts;
44
-
45
- // check for notification permission and then start the foreground service
46
- if (!notifeeLib) return;
47
57
  const isCallAliveConfigured =
48
58
  await NativeModules.StreamVideoReactNative.isCallAliveConfigured();
49
59
  if (!isCallAliveConfigured) {
@@ -54,6 +64,8 @@ async function startForegroundService(call_cid: string) {
54
64
  );
55
65
  return;
56
66
  }
67
+ // check for notification permission and then start the foreground service
68
+ if (!notifeeLib) return;
57
69
  const settings = await notifeeLib.default.getNotificationSettings();
58
70
  if (
59
71
  settings.authorizationStatus !== notifeeLib.AuthorizationStatus.AUTHORIZED
@@ -65,6 +77,9 @@ async function startForegroundService(call_cid: string) {
65
77
  );
66
78
  return;
67
79
  }
80
+ const videoConfig = StreamVideoRN.getConfig();
81
+ const foregroundServiceConfig = videoConfig.foregroundService;
82
+ const notificationTexts = foregroundServiceConfig.android.notificationTexts;
68
83
  const channelId = foregroundServiceConfig.android.channel.id;
69
84
  await notifeeLib.default.createChannel(
70
85
  foregroundServiceConfig.android.channel,
@@ -76,8 +91,8 @@ async function startForegroundService(call_cid: string) {
76
91
  requestAnimationFrame(() => {
77
92
  notifeeLib.default.displayNotification({
78
93
  id: call_cid,
79
- title,
80
- body,
94
+ title: notificationTexts.title,
95
+ body: notificationTexts.body,
81
96
  android: {
82
97
  channelId,
83
98
  smallIcon: videoConfig.push?.android.smallIcon,
@@ -107,6 +122,7 @@ export const useAndroidKeepCallAliveEffect = () => {
107
122
  const foregroundServiceStartedRef = useRef(false);
108
123
 
109
124
  const call = useCall();
125
+ callToPassToForegroundService.current = call;
110
126
  const activeCallCid = call?.cid;
111
127
  const { useCallCallingState } = useCallStateHooks();
112
128
  const callingState = useCallCallingState();
@@ -141,6 +157,7 @@ export const useAndroidKeepCallAliveEffect = () => {
141
157
  (notification) => notification.id === activeCallCid,
142
158
  );
143
159
  if (activeCallNotification) {
160
+ callToPassToForegroundService.current = undefined;
144
161
  // this means that we have a incoming call notification shown as foreground service and we must stop it
145
162
  notifee.stopForegroundService();
146
163
  notifee.cancelDisplayedNotification(activeCallCid);
@@ -179,6 +196,7 @@ export const useAndroidKeepCallAliveEffect = () => {
179
196
  callingState === CallingState.LEFT
180
197
  ) {
181
198
  if (foregroundServiceStartedRef.current) {
199
+ callToPassToForegroundService.current = undefined;
182
200
  // stop foreground service when the call is not active
183
201
  notifeeLib.default.stopForegroundService();
184
202
  foregroundServiceStartedRef.current = false;
@@ -190,6 +208,7 @@ export const useAndroidKeepCallAliveEffect = () => {
190
208
  (notification) => notification.id === activeCallCid,
191
209
  );
192
210
  if (activeCallNotification) {
211
+ callToPassToForegroundService.current = undefined;
193
212
  // this means that we have a incoming call notification shown as foreground service and we must stop it
194
213
  notifeeLib.default.stopForegroundService();
195
214
  }
@@ -204,6 +223,7 @@ export const useAndroidKeepCallAliveEffect = () => {
204
223
  // stop foreground service when this effect is unmounted
205
224
  if (foregroundServiceStartedRef.current) {
206
225
  if (!notifeeLib) return;
226
+ callToPassToForegroundService.current = undefined;
207
227
  notifeeLib.default.stopForegroundService();
208
228
  foregroundServiceStartedRef.current = false;
209
229
  }
@@ -1,53 +1,70 @@
1
- import { type StreamVideoParticipant } from '@stream-io/video-client';
2
- import { useCall } from '@stream-io/video-react-bindings';
1
+ import {
2
+ type StreamVideoParticipant,
3
+ type VideoTrackType,
4
+ } from '@stream-io/video-client';
3
5
  import { useEffect, useState } from 'react';
6
+ import { NativeEventEmitter, NativeModules } from 'react-native';
7
+
8
+ const webRTCEventEmitter = new NativeEventEmitter(NativeModules.WebRTCModule);
4
9
 
5
10
  /**
6
11
  * This is a utility hook to get the dimensions of the video track of the participant.
7
12
  * Note: the `tracktype` is used only for local participants.
8
13
  * `tracktype` should be 'videoTrack' for video track and 'screenShareTrack' for screen share track.
9
14
  */
10
- export function useTrackDimensions(participant: StreamVideoParticipant) {
11
- const [trackDimensions, setTrackDimensions] = useState({
12
- width: 0,
13
- height: 0,
14
- });
15
- const call = useCall();
16
- const { sessionId } = participant;
15
+ export function useTrackDimensions(
16
+ participant: StreamVideoParticipant,
17
+ trackType: VideoTrackType,
18
+ ) {
19
+ const { videoStream, screenShareStream } = participant;
20
+ const stream =
21
+ trackType === 'screenShareTrack' ? screenShareStream : videoStream;
22
+ const [track] = stream?.getVideoTracks() ?? [];
23
+ const trackId = track?.id;
17
24
 
18
- useEffect(() => {
19
- if (!call) return;
20
- call.startReportingStatsFor(sessionId);
21
- return () => {
22
- call.stopReportingStatsFor(sessionId);
25
+ const [trackDimensions, setTrackDimensions] = useState(() => {
26
+ const settings = track?.getSettings();
27
+ const width = settings?.width ?? 0;
28
+ const height = settings?.height ?? 0;
29
+ return {
30
+ width,
31
+ height,
23
32
  };
24
- }, [call, sessionId]);
33
+ });
25
34
 
26
- // for remote participants track.getSettings() is not supported it returns an empty object
27
- // and for local participants we can get from track.getSettings() but it reports the wrong dimensions as it sends the constraints
28
- // so we need to rely on call stats for all participants to get the dimensions
35
+ // Set up videoTrackDimensionChanged event listener for more direct dimension updates
29
36
  useEffect(() => {
30
- if (!call) return;
31
- const sub = call.state.callStatsReport$.subscribe((report) => {
32
- if (!report) return;
33
- const reportForTracks = report.participants[sessionId];
34
- const trackStats = reportForTracks
35
- ?.flatMap((r) => r.streams)
36
- .filter((track) => track.kind === 'video');
37
- if (!trackStats) return;
38
- const stat = trackStats[0];
39
- if (stat) {
40
- const { frameWidth = 0, frameHeight = 0 } = stat;
37
+ if (!trackId || !NativeModules.WebRTCModule) return;
38
+
39
+ const handleVideoTrackDimensionChanged = (eventData: {
40
+ pcId: string;
41
+ trackId: string;
42
+ width: number;
43
+ height: number;
44
+ }) => {
45
+ // Only handle events for this specific participant
46
+ if (eventData.trackId === trackId) {
41
47
  setTrackDimensions((prev) => {
42
- if (prev.width !== frameWidth || prev.height !== frameHeight) {
43
- return { width: frameWidth, height: frameHeight };
48
+ if (
49
+ prev.width !== eventData.width ||
50
+ prev.height !== eventData.height
51
+ ) {
52
+ return { width: eventData.width, height: eventData.height };
44
53
  }
45
54
  return prev;
46
55
  });
47
56
  }
48
- });
49
- return () => sub.unsubscribe();
50
- }, [call, sessionId]);
57
+ };
58
+
59
+ const subscription = webRTCEventEmitter.addListener(
60
+ 'videoTrackDimensionChanged',
61
+ handleVideoTrackDimensionChanged,
62
+ );
63
+
64
+ return () => {
65
+ subscription.remove();
66
+ };
67
+ }, [trackId, track]);
51
68
 
52
69
  return trackDimensions;
53
70
  }
@@ -1,4 +1,4 @@
1
- import { useCallStateHooks } from '@stream-io/video-react-bindings';
1
+ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
2
2
  import { useEffect } from 'react';
3
3
  import {
4
4
  CallingState,
@@ -17,28 +17,39 @@ const eventEmitter = NativeModules?.StreamVideoReactNative
17
17
  export const DeviceStats = () => {
18
18
  const { useCallCallingState } = useCallStateHooks();
19
19
  const callingState = useCallCallingState();
20
+ const call = useCall();
20
21
 
21
22
  useEffect(() => {
22
- if (callingState !== CallingState.JOINED) {
23
- return;
24
- }
23
+ if (!call || callingState !== CallingState.JOINED) return;
25
24
 
26
25
  NativeModules?.StreamVideoReactNative.isLowPowerModeEnabled().then(
27
- (initialPowerMode: boolean) => setPowerState(initialPowerMode),
26
+ (initialPowerMode: boolean) => {
27
+ setPowerState(initialPowerMode);
28
+ call.tracer.trace('device.lowPowerMode', initialPowerMode);
29
+ },
28
30
  );
29
31
 
30
32
  const powerModeSubscription = eventEmitter?.addListener(
31
33
  'isLowPowerModeEnabled',
32
- (isLowPowerMode: boolean) => setPowerState(isLowPowerMode),
34
+ (isLowPowerMode: boolean) => {
35
+ setPowerState(isLowPowerMode);
36
+ call.tracer.trace('device.lowPowerMode', isLowPowerMode);
37
+ },
33
38
  );
34
39
 
35
40
  NativeModules?.StreamVideoReactNative.currentThermalState().then(
36
- (initialState: string) => setThermalState(initialState),
41
+ (initialState: string) => {
42
+ setThermalState(initialState);
43
+ call.tracer.trace('device.thermalState', initialState);
44
+ },
37
45
  );
38
46
 
39
47
  const thermalStateSubscription = eventEmitter?.addListener(
40
48
  'thermalStateDidChange',
41
- (thermalState: string) => setThermalState(thermalState),
49
+ (thermalState: string) => {
50
+ setThermalState(thermalState);
51
+ call.tracer.trace('device.thermalStateChanged', thermalState);
52
+ },
42
53
  );
43
54
 
44
55
  // on android we need to explicitly start and stop the thermal status updates
@@ -53,7 +64,7 @@ export const DeviceStats = () => {
53
64
  NativeModules?.StreamVideoReactNative.stopThermalStatusUpdates();
54
65
  }
55
66
  };
56
- }, [callingState]);
67
+ }, [call, callingState]);
57
68
 
58
69
  return null;
59
70
  };
@@ -6,6 +6,41 @@ import newNotificationCallbacks, {
6
6
  import { setupIosCallKeepEvents } from '../push/setupIosCallKeepEvents';
7
7
  import { setupIosVoipPushEvents } from '../push/setupIosVoipPushEvents';
8
8
 
9
+ // Utility type for deep partial
10
+ type DeepPartial<T> = {
11
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
12
+ };
13
+
14
+ // Helper function for deep merging
15
+ function deepMerge<T extends Record<string, any>>(
16
+ target: T,
17
+ source: DeepPartial<T>,
18
+ ): T {
19
+ const result = { ...target };
20
+
21
+ for (const key in source) {
22
+ if (source[key] !== undefined) {
23
+ if (
24
+ typeof source[key] === 'object' &&
25
+ source[key] !== null &&
26
+ !Array.isArray(source[key]) &&
27
+ typeof target[key] === 'object' &&
28
+ target[key] !== null &&
29
+ !Array.isArray(target[key])
30
+ ) {
31
+ result[key] = deepMerge(
32
+ target[key],
33
+ source[key] as DeepPartial<T[typeof key]>,
34
+ );
35
+ } else {
36
+ result[key] = source[key] as T[typeof key];
37
+ }
38
+ }
39
+ }
40
+
41
+ return result;
42
+ }
43
+
9
44
  const DEFAULT_STREAM_VIDEO_CONFIG: StreamVideoConfig = {
10
45
  foregroundService: {
11
46
  android: {
@@ -20,6 +55,7 @@ const DEFAULT_STREAM_VIDEO_CONFIG: StreamVideoConfig = {
20
55
  title: 'Call in progress',
21
56
  body: 'Tap to return to the call',
22
57
  },
58
+ taskToRun: () => new Promise(() => {}),
23
59
  },
24
60
  },
25
61
  };
@@ -30,13 +66,12 @@ export class StreamVideoRN {
30
66
  /**
31
67
  * Update the global config for StreamVideoRN except for push config.
32
68
  * To set push config use `StreamVideoRN.setPushConfig` instead.
33
- * This function accepts a partial config object that will be merged with the default config.
69
+ * This function accepts a partial config object that will be deeply merged with the default config.
34
70
  */
35
- static updateConfig(updateConfig: Partial<Omit<StreamVideoConfig, 'push'>>) {
36
- this.config = {
37
- ...this.config,
38
- ...updateConfig,
39
- };
71
+ static updateConfig(
72
+ updateConfig: DeepPartial<Omit<StreamVideoConfig, 'push'>>,
73
+ ) {
74
+ this.config = deepMerge(this.config, updateConfig);
40
75
  }
41
76
 
42
77
  static updateAndroidIncomingCallChannel(
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  type ClientPublishOptions,
3
3
  StreamVideoClient,
4
+ type Call,
4
5
  } from '@stream-io/video-client';
5
6
  import type { AndroidChannel } from '@notifee/react-native';
6
7
 
@@ -154,6 +155,11 @@ export type StreamVideoConfig = {
154
155
  title: string;
155
156
  body: string;
156
157
  };
158
+ /**
159
+ * The task to run in the foreground service
160
+ * The task must resolve a promise once complete
161
+ */
162
+ taskToRun: (call: Call) => Promise<void>;
157
163
  };
158
164
  };
159
165
  };
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.19.1';
1
+ export const version = '1.20.0';