@stream-io/video-react-native-sdk 1.12.0 → 1.13.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 (118) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/android/build.gradle +2 -0
  3. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +72 -0
  4. package/android/src/main/java/com/streamvideo/reactnative/util/YuvFrame.kt +97 -0
  5. package/dist/commonjs/components/Call/CallContent/CallContent.js +1 -2
  6. package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
  7. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js +1 -2
  8. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
  9. package/dist/commonjs/components/Call/CallControls/AcceptCallButton.js +1 -2
  10. package/dist/commonjs/components/Call/CallControls/AcceptCallButton.js.map +1 -1
  11. package/dist/commonjs/components/Call/CallControls/LobbyControls.js +1 -2
  12. package/dist/commonjs/components/Call/CallControls/LobbyControls.js.map +1 -1
  13. package/dist/commonjs/components/Call/CallControls/ReactionsButton.js +1 -2
  14. package/dist/commonjs/components/Call/CallControls/ReactionsButton.js.map +1 -1
  15. package/dist/commonjs/components/Call/CallControls/RejectCallButton.js +1 -2
  16. package/dist/commonjs/components/Call/CallControls/RejectCallButton.js.map +1 -1
  17. package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js +1 -2
  18. package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -1
  19. package/dist/commonjs/components/Call/CallControls/internal/ReactionsPicker.js +1 -2
  20. package/dist/commonjs/components/Call/CallControls/internal/ReactionsPicker.js.map +1 -1
  21. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js +1 -2
  22. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
  23. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js +1 -2
  24. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js.map +1 -1
  25. package/dist/commonjs/components/Call/Lobby/JoinCallButton.js +1 -2
  26. package/dist/commonjs/components/Call/Lobby/JoinCallButton.js.map +1 -1
  27. package/dist/commonjs/components/Call/Lobby/Lobby.js +1 -2
  28. package/dist/commonjs/components/Call/Lobby/Lobby.js.map +1 -1
  29. package/dist/commonjs/components/Call/Lobby/LobbyFooter.js +1 -2
  30. package/dist/commonjs/components/Call/Lobby/LobbyFooter.js.map +1 -1
  31. package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js +1 -2
  32. package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js.map +1 -1
  33. package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js +1 -2
  34. package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
  35. package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js +1 -2
  36. package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLeaveStreamButton.js.map +1 -1
  37. package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js +1 -2
  38. package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
  39. package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamPlayer.js +1 -2
  40. package/dist/commonjs/components/Livestream/LivestreamPlayer/LivestreamPlayer.js.map +1 -1
  41. package/dist/commonjs/components/Livestream/LivestreamTopView/DurationBadge.js +1 -2
  42. package/dist/commonjs/components/Livestream/LivestreamTopView/DurationBadge.js.map +1 -1
  43. package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js +1 -2
  44. package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
  45. package/dist/commonjs/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.js +1 -2
  46. package/dist/commonjs/components/Participant/FloatingParticipantView/FloatingView/AnimatedFloatingView.js.map +1 -1
  47. package/dist/commonjs/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.js +1 -2
  48. package/dist/commonjs/components/Participant/FloatingParticipantView/FloatingView/ReanimatedFloatingView.js.map +1 -1
  49. package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js +1 -2
  50. package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
  51. package/dist/commonjs/components/Participant/ParticipantView/ParticipantReaction.js +1 -2
  52. package/dist/commonjs/components/Participant/ParticipantView/ParticipantReaction.js.map +1 -1
  53. package/dist/commonjs/components/Participant/ParticipantView/ParticipantView.js +1 -2
  54. package/dist/commonjs/components/Participant/ParticipantView/ParticipantView.js.map +1 -1
  55. package/dist/commonjs/components/Participant/ParticipantView/SpeechIndicator.js +1 -2
  56. package/dist/commonjs/components/Participant/ParticipantView/SpeechIndicator.js.map +1 -1
  57. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js +18 -4
  58. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
  59. package/dist/commonjs/contexts/BackgroundFilters.js +1 -2
  60. package/dist/commonjs/contexts/BackgroundFilters.js.map +1 -1
  61. package/dist/commonjs/contexts/StreamVideoContext.js +1 -2
  62. package/dist/commonjs/contexts/StreamVideoContext.js.map +1 -1
  63. package/dist/commonjs/contexts/ThemeContext.js +1 -2
  64. package/dist/commonjs/contexts/ThemeContext.js.map +1 -1
  65. package/dist/commonjs/contexts/internal/ScreenshotIosContext.js +77 -0
  66. package/dist/commonjs/contexts/internal/ScreenshotIosContext.js.map +1 -0
  67. package/dist/commonjs/hooks/index.js +11 -0
  68. package/dist/commonjs/hooks/index.js.map +1 -1
  69. package/dist/commonjs/hooks/useScreenshot.js +54 -0
  70. package/dist/commonjs/hooks/useScreenshot.js.map +1 -0
  71. package/dist/commonjs/icons/Lock.js +1 -2
  72. package/dist/commonjs/icons/Lock.js.map +1 -1
  73. package/dist/commonjs/icons/ScreenShare.js +1 -2
  74. package/dist/commonjs/icons/ScreenShare.js.map +1 -1
  75. package/dist/commonjs/icons/ScreenShareIndicator.js +1 -2
  76. package/dist/commonjs/icons/ScreenShareIndicator.js.map +1 -1
  77. package/dist/commonjs/icons/Settings.js +1 -2
  78. package/dist/commonjs/icons/Settings.js.map +1 -1
  79. package/dist/commonjs/icons/StopScreenShare.js +1 -2
  80. package/dist/commonjs/icons/StopScreenShare.js.map +1 -1
  81. package/dist/commonjs/providers/StreamCall/index.js +1 -2
  82. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  83. package/dist/commonjs/providers/StreamVideo.js +3 -3
  84. package/dist/commonjs/providers/StreamVideo.js.map +1 -1
  85. package/dist/commonjs/version.js +1 -1
  86. package/dist/module/components/Participant/ParticipantView/VideoRenderer.js +18 -3
  87. package/dist/module/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
  88. package/dist/module/contexts/internal/ScreenshotIosContext.js +68 -0
  89. package/dist/module/contexts/internal/ScreenshotIosContext.js.map +1 -0
  90. package/dist/module/hooks/index.js +1 -0
  91. package/dist/module/hooks/index.js.map +1 -1
  92. package/dist/module/hooks/useScreenshot.js +48 -0
  93. package/dist/module/hooks/useScreenshot.js.map +1 -0
  94. package/dist/module/providers/StreamVideo.js +3 -1
  95. package/dist/module/providers/StreamVideo.js.map +1 -1
  96. package/dist/module/version.js +1 -1
  97. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts +2 -2
  98. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts.map +1 -1
  99. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer.d.ts.map +1 -1
  100. package/dist/typescript/contexts/internal/ScreenshotIosContext.d.ts +11 -0
  101. package/dist/typescript/contexts/internal/ScreenshotIosContext.d.ts.map +1 -0
  102. package/dist/typescript/hooks/index.d.ts +1 -0
  103. package/dist/typescript/hooks/index.d.ts.map +1 -1
  104. package/dist/typescript/hooks/useScreenshot.d.ts +19 -0
  105. package/dist/typescript/hooks/useScreenshot.d.ts.map +1 -0
  106. package/dist/typescript/providers/StreamVideo.d.ts.map +1 -1
  107. package/dist/typescript/version.d.ts +1 -1
  108. package/expo-config-plugin/dist/common/{addNewLinesToAppDelegate.js → addNewLinesToAppDelegateObjc.js} +3 -3
  109. package/expo-config-plugin/dist/common/addToSwiftBridgingHeaderFile.js +48 -0
  110. package/expo-config-plugin/dist/withAppDelegate.js +216 -34
  111. package/ios/StreamVideoReactNative.m +96 -0
  112. package/package.json +23 -25
  113. package/src/components/Participant/ParticipantView/VideoRenderer.tsx +35 -3
  114. package/src/contexts/internal/ScreenshotIosContext.tsx +145 -0
  115. package/src/hooks/index.ts +1 -0
  116. package/src/hooks/useScreenshot.ts +78 -0
  117. package/src/providers/StreamVideo.tsx +5 -2
  118. package/src/version.ts +1 -1
@@ -0,0 +1,145 @@
1
+ import {
2
+ StreamVideoParticipant,
3
+ type VideoTrackType,
4
+ getLogger,
5
+ } from '@stream-io/video-client';
6
+ import React, {
7
+ createContext,
8
+ useContext,
9
+ RefObject,
10
+ useCallback,
11
+ useMemo,
12
+ } from 'react';
13
+ import { NativeModules, findNodeHandle, Platform } from 'react-native';
14
+
15
+ const { StreamVideoReactNative } = NativeModules;
16
+
17
+ type ScreenshotIosContextType = {
18
+ register: (
19
+ participant: StreamVideoParticipant,
20
+ videoTrackType: VideoTrackType,
21
+ ref: RefObject<any>,
22
+ ) => void;
23
+ deregister: (
24
+ participant: StreamVideoParticipant,
25
+ videoTrackType: VideoTrackType,
26
+ ) => void;
27
+ take: (
28
+ participant: StreamVideoParticipant,
29
+ videoTrackType: VideoTrackType,
30
+ ) => Promise<string | null>;
31
+ };
32
+
33
+ // Create the context with a default undefined value
34
+ const ScreenshotIosContext = createContext<
35
+ ScreenshotIosContextType | undefined
36
+ >(undefined);
37
+
38
+ const participantVideoViewRefMap: Map<string, RefObject<any>> = new Map();
39
+
40
+ export const ScreenshotIosContextProvider = ({
41
+ children,
42
+ }: React.PropsWithChildren<{}>) => {
43
+ // Register a participant's RTCView ref
44
+ const register = useCallback(
45
+ (
46
+ participant: StreamVideoParticipant,
47
+ videoTrackType: VideoTrackType,
48
+ ref: RefObject<any>,
49
+ ) => {
50
+ if (ref && participant.userId) {
51
+ participantVideoViewRefMap.set(
52
+ `${participant.userId}-${videoTrackType}`,
53
+ ref,
54
+ );
55
+ }
56
+ },
57
+ [],
58
+ );
59
+
60
+ const deregister = useCallback(
61
+ (participant: StreamVideoParticipant, videoTrackType: VideoTrackType) => {
62
+ if (participant.userId) {
63
+ participantVideoViewRefMap.delete(
64
+ `${participant.userId}-${videoTrackType}`,
65
+ );
66
+ }
67
+ },
68
+ [],
69
+ );
70
+
71
+ // Take a snapshot of a specific participant's view
72
+ const take = useCallback(
73
+ async (
74
+ participant: StreamVideoParticipant,
75
+ videoTrackType: VideoTrackType,
76
+ ): Promise<string | null> => {
77
+ try {
78
+ if (Platform.OS !== 'ios') {
79
+ throw new Error(
80
+ 'ScreenshotIosContextProvider is only supported on iOS',
81
+ );
82
+ }
83
+
84
+ const ref = participantVideoViewRefMap.get(
85
+ `${participant.userId}-${videoTrackType}`,
86
+ );
87
+ if (!ref || !ref.current) {
88
+ getLogger(['ScreenshotIosContextProvider'])(
89
+ 'error',
90
+ 'Cannot take snapshot: No registered view for this participant',
91
+ );
92
+ return null;
93
+ }
94
+
95
+ // Get the native handle for the view
96
+ const tag = findNodeHandle(ref.current);
97
+ if (!tag) {
98
+ getLogger(['ScreenshotIosContextProvider'])(
99
+ 'error',
100
+ 'Cannot take snapshot: Cannot get native handle for view',
101
+ );
102
+ return null;
103
+ }
104
+
105
+ // Take the snapshot using our native module
106
+ const base64Image = await StreamVideoReactNative.captureRef(tag, {});
107
+
108
+ return base64Image;
109
+ } catch (error) {
110
+ getLogger(['ScreenshotIosContextProvider'])(
111
+ 'error',
112
+ 'Error taking participant snapshot:',
113
+ error,
114
+ );
115
+ return null;
116
+ }
117
+ },
118
+ [],
119
+ );
120
+
121
+ const value = useMemo(
122
+ () => ({
123
+ register,
124
+ deregister,
125
+ take,
126
+ }),
127
+ [register, deregister, take],
128
+ );
129
+
130
+ return (
131
+ <ScreenshotIosContext.Provider value={value}>
132
+ {children}
133
+ </ScreenshotIosContext.Provider>
134
+ );
135
+ };
136
+
137
+ export const useScreenshotIosContext = (): ScreenshotIosContextType => {
138
+ const context = useContext(ScreenshotIosContext);
139
+ if (!context) {
140
+ throw new Error(
141
+ 'useScreenshotIosContext must be used within a ScreenshotIosContextProvider',
142
+ );
143
+ }
144
+ return context;
145
+ };
@@ -8,3 +8,4 @@ export * from './useAutoEnterPiPEffect';
8
8
  export * from './useApplyDefaultMediaStreamSettings';
9
9
  export * from './useScreenShareButton';
10
10
  export * from './useTrackDimensions';
11
+ export * from './useScreenshot';
@@ -0,0 +1,78 @@
1
+ import { useCallback } from 'react';
2
+ import { useScreenshotIosContext } from '../contexts/internal/ScreenshotIosContext';
3
+ import { NativeModules, Platform } from 'react-native';
4
+ import type { MediaStream } from '@stream-io/react-native-webrtc';
5
+ import {
6
+ StreamVideoParticipant,
7
+ getLogger,
8
+ type VideoTrackType,
9
+ } from '@stream-io/video-client';
10
+
11
+ const { StreamVideoReactNative } = NativeModules;
12
+
13
+ /**
14
+ * Hook that provides functionality to take screenshots of participant video streams.
15
+ *
16
+ * @returns An object containing the `takeScreenShot` function that captures a participant's video.
17
+ */
18
+ type UseScreenshotResult = {
19
+ /**
20
+ * Takes a screenshot of a participant's video stream.
21
+ *
22
+ * @param participant - The participant whose video stream to capture
23
+ * @param videoTrackType - The type of video track to capture ('videoTrack' or 'screenShareTrack')
24
+ * @returns A Promise that resolves to a base64-encoded png image string or null if the screenshot fails
25
+ */
26
+ takeScreenshot: (
27
+ participant: StreamVideoParticipant,
28
+ videoTrackType: VideoTrackType,
29
+ ) => Promise<string | null>;
30
+ };
31
+
32
+ export function useScreenshot(): UseScreenshotResult {
33
+ const { take } = useScreenshotIosContext();
34
+ const takeScreenshot = useCallback(
35
+ async (
36
+ participant: StreamVideoParticipant,
37
+ videoTrackType: VideoTrackType,
38
+ ) => {
39
+ if (Platform.OS === 'android') {
40
+ const { videoStream, screenShareStream } = participant;
41
+
42
+ const videoStreamForScreenshot = (videoTrackType === 'screenShareTrack'
43
+ ? screenShareStream
44
+ : videoStream) as unknown as MediaStream | undefined;
45
+
46
+ if (videoStreamForScreenshot) {
47
+ try {
48
+ return await StreamVideoReactNative.takeScreenshot(
49
+ videoStreamForScreenshot.toURL(),
50
+ );
51
+ } catch (error) {
52
+ getLogger(['useScreenshot'])(
53
+ 'error',
54
+ 'Error taking screenshot',
55
+ error,
56
+ );
57
+ return null;
58
+ }
59
+ }
60
+ return null;
61
+ } else {
62
+ try {
63
+ return await take(participant, videoTrackType);
64
+ } catch (error) {
65
+ getLogger(['useScreenshot'])(
66
+ 'error',
67
+ 'Error taking screenshot',
68
+ error,
69
+ );
70
+ return null;
71
+ }
72
+ }
73
+ },
74
+ [take],
75
+ );
76
+
77
+ return { takeScreenshot };
78
+ }
@@ -10,6 +10,7 @@ import { usePushRegisterEffect } from '../hooks';
10
10
  import { translations } from '../translations';
11
11
  import { type DeepPartial, StreamTheme } from '../contexts/ThemeContext';
12
12
  import { type Theme } from '../theme/theme';
13
+ import { ScreenshotIosContextProvider } from '../contexts/internal/ScreenshotIosContext';
13
14
 
14
15
  /**
15
16
  *
@@ -61,8 +62,10 @@ export const StreamVideo = (
61
62
  >
62
63
  <StreamTheme style={style}>
63
64
  <StreamVideoStoreProvider>
64
- <PushRegister />
65
- {children}
65
+ <ScreenshotIosContextProvider>
66
+ <PushRegister />
67
+ {children}
68
+ </ScreenshotIosContextProvider>
66
69
  </StreamVideoStoreProvider>
67
70
  </StreamTheme>
68
71
  </StreamVideoProvider>
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.12.0';
1
+ export const version = '1.13.0';