@100mslive/react-native-room-kit 1.0.9 → 1.1.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 (56) hide show
  1. package/README.md +5 -6
  2. package/lib/commonjs/components/GridView.js +9 -4
  3. package/lib/commonjs/components/GridView.js.map +1 -1
  4. package/lib/commonjs/components/Meeting.js +1 -0
  5. package/lib/commonjs/components/Meeting.js.map +1 -1
  6. package/lib/commonjs/components/OverlayContainer.js +6 -3
  7. package/lib/commonjs/components/OverlayContainer.js.map +1 -1
  8. package/lib/commonjs/components/OverlayedViews.js +5 -2
  9. package/lib/commonjs/components/OverlayedViews.js.map +1 -1
  10. package/lib/commonjs/components/PeerVideoTile/HMSPinchGesture.js +18 -87
  11. package/lib/commonjs/components/PeerVideoTile/HMSPinchGesture.js.map +1 -1
  12. package/lib/commonjs/components/PeerVideoTile/PeerVideoTileView.js +3 -1
  13. package/lib/commonjs/components/PeerVideoTile/PeerVideoTileView.js.map +1 -1
  14. package/lib/commonjs/components/TilesContainer.js +1 -1
  15. package/lib/commonjs/components/WebrtcView.js +14 -6
  16. package/lib/commonjs/components/WebrtcView.js.map +1 -1
  17. package/lib/commonjs/hooks-util.js +11 -1
  18. package/lib/commonjs/hooks-util.js.map +1 -1
  19. package/lib/module/components/GridView.js +10 -5
  20. package/lib/module/components/GridView.js.map +1 -1
  21. package/lib/module/components/Meeting.js +2 -1
  22. package/lib/module/components/Meeting.js.map +1 -1
  23. package/lib/module/components/OverlayContainer.js +5 -3
  24. package/lib/module/components/OverlayContainer.js.map +1 -1
  25. package/lib/module/components/OverlayedViews.js +5 -2
  26. package/lib/module/components/OverlayedViews.js.map +1 -1
  27. package/lib/module/components/PeerVideoTile/HMSPinchGesture.js +18 -87
  28. package/lib/module/components/PeerVideoTile/HMSPinchGesture.js.map +1 -1
  29. package/lib/module/components/PeerVideoTile/PeerVideoTileView.js +3 -1
  30. package/lib/module/components/PeerVideoTile/PeerVideoTileView.js.map +1 -1
  31. package/lib/module/components/TilesContainer.js +1 -1
  32. package/lib/module/components/WebrtcView.js +15 -7
  33. package/lib/module/components/WebrtcView.js.map +1 -1
  34. package/lib/module/hooks-util.js +10 -1
  35. package/lib/module/hooks-util.js.map +1 -1
  36. package/lib/typescript/components/GridView.d.ts.map +1 -1
  37. package/lib/typescript/components/Meeting.d.ts.map +1 -1
  38. package/lib/typescript/components/OverlayContainer.d.ts +5 -1
  39. package/lib/typescript/components/OverlayContainer.d.ts.map +1 -1
  40. package/lib/typescript/components/OverlayedViews.d.ts +2 -1
  41. package/lib/typescript/components/OverlayedViews.d.ts.map +1 -1
  42. package/lib/typescript/components/PeerVideoTile/HMSPinchGesture.d.ts.map +1 -1
  43. package/lib/typescript/components/PeerVideoTile/PeerVideoTileView.d.ts.map +1 -1
  44. package/lib/typescript/components/WebrtcView.d.ts.map +1 -1
  45. package/lib/typescript/hooks-util.d.ts +1 -0
  46. package/lib/typescript/hooks-util.d.ts.map +1 -1
  47. package/package.json +2 -2
  48. package/src/components/GridView.tsx +14 -5
  49. package/src/components/Meeting.tsx +3 -0
  50. package/src/components/OverlayContainer.tsx +12 -3
  51. package/src/components/OverlayedViews.tsx +7 -3
  52. package/src/components/PeerVideoTile/HMSPinchGesture.tsx +28 -71
  53. package/src/components/PeerVideoTile/PeerVideoTileView.tsx +4 -1
  54. package/src/components/TilesContainer.tsx +1 -1
  55. package/src/components/WebrtcView.tsx +27 -9
  56. package/src/hooks-util.ts +13 -0
@@ -21,7 +21,10 @@ import { PaginationDots } from './PaginationDots';
21
21
  import { setGridViewActivePage } from '../redux/actions';
22
22
  import { Tile } from './Tile';
23
23
  import { useIsLandscapeOrientation } from '../utils/dimension';
24
- import { useSafeAreaFrame } from 'react-native-safe-area-context';
24
+ import {
25
+ useSafeAreaFrame,
26
+ useSafeAreaInsets,
27
+ } from 'react-native-safe-area-context';
25
28
 
26
29
  export type GridViewProps = {
27
30
  onPeerTileMorePress(peerTrackNode: PeerTrackNode): void;
@@ -144,7 +147,7 @@ export const GridView = React.forwardRef<GridViewRefAttrs, GridViewProps>(
144
147
  );
145
148
 
146
149
  return (
147
- <View style={styles.container}>
150
+ <View style={[styles.container]}>
148
151
  <View onLayout={_handleLayoutChange} style={styles.measureLayoutView} />
149
152
 
150
153
  {screenshareTilesAvailable ? (
@@ -258,7 +261,11 @@ const RegularTiles = React.forwardRef<
258
261
  <FlatList
259
262
  ref={flatlistRef}
260
263
  horizontal={true}
261
- style={Platform.OS === 'ios' ? { maxHeight: safeHeight - 16 } : null}
264
+ style={
265
+ Platform.OS === 'ios'
266
+ ? { maxHeight: safeHeight - (isLandscapeOrientation ? 0 : 16) }
267
+ : null
268
+ }
262
269
  data={pairedPeers}
263
270
  initialNumToRender={1}
264
271
  maxToRenderPerBatch={1}
@@ -297,6 +304,7 @@ const ScreenshareTiles = React.forwardRef<
297
304
  ScreenshareTilesProps
298
305
  >(({ onPeerTileMorePress, setHmsViewRefs }, flatlistRef) => {
299
306
  const { width } = useWindowDimensions();
307
+ const { left, right } = useSafeAreaInsets();
300
308
  const isLandscapeOrientation = useIsLandscapeOrientation();
301
309
  const [activePage, setActivePage] = useState(0);
302
310
  const screensharePeerTrackNodes = useSelector(
@@ -318,20 +326,21 @@ const ScreenshareTiles = React.forwardRef<
318
326
  },
319
327
  []
320
328
  );
329
+ const tileWidth = width + left + right;
321
330
 
322
331
  const _renderItem = React.useCallback(
323
332
  ({ item }) => {
324
333
  return (
325
334
  <Tile
326
335
  height={'100%'}
327
- width={width}
336
+ width={tileWidth}
328
337
  peerTrackNode={item}
329
338
  onPeerTileMorePress={onPeerTileMorePress}
330
339
  setHmsViewRefs={setHmsViewRefs}
331
340
  />
332
341
  );
333
342
  },
334
- [width, onPeerTileMorePress, setHmsViewRefs]
343
+ [tileWidth, onPeerTileMorePress, setHmsViewRefs]
335
344
  );
336
345
 
337
346
  return (
@@ -15,6 +15,7 @@ import {
15
15
  useHMSReconnection,
16
16
  useHMSRemovedFromRoomUpdate,
17
17
  useHMSRoomStyle,
18
+ useLandscapeImmersiveMode,
18
19
  usePIPListener,
19
20
  useSetDefaultChatRecipient,
20
21
  } from '../hooks-util';
@@ -61,6 +62,8 @@ export const Meeting: React.FC<MeetingProps> = ({ peerTrackNodes }) => {
61
62
  // Handle Back button press and show leave room modal
62
63
  useBackButtonPress();
63
64
 
65
+ useLandscapeImmersiveMode();
66
+
64
67
  // Clearing any pending modal opening tasks
65
68
  React.useEffect(() => {
66
69
  return () => {
@@ -1,5 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
+ import type { StyleProp, ViewStyle } from 'react-native';
4
+ import type { AnimatedStyle } from 'react-native-reanimated';
5
+ import Animated from 'react-native-reanimated';
3
6
 
4
7
  type OverlayContainerProps = {};
5
8
 
@@ -9,10 +12,16 @@ export const OverlayContainer: React.FC<OverlayContainerProps> & {
9
12
  return <View style={styles.container}>{children}</View>;
10
13
  };
11
14
 
12
- type OverlayProps = {};
15
+ export type OverlayProps = {
16
+ animatedStyle?: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
17
+ };
13
18
 
14
- const Overlay: React.FC<OverlayProps> = ({ children }) => {
15
- return <View style={styles.absoluteContainer}>{children}</View>;
19
+ const Overlay: React.FC<OverlayProps> = ({ children, animatedStyle }) => {
20
+ return (
21
+ <Animated.View style={[styles.absoluteContainer, animatedStyle]}>
22
+ {children}
23
+ </Animated.View>
24
+ );
16
25
  };
17
26
 
18
27
  OverlayContainer.Overlay = Overlay;
@@ -3,18 +3,22 @@ import type { SharedValue } from 'react-native-reanimated';
3
3
 
4
4
  import { HMSNotifications } from './HMSNotifications';
5
5
  import { OverlayContainer } from './OverlayContainer';
6
+ import type { OverlayProps } from './OverlayContainer';
6
7
  import { HLSChatView } from './HMSOverlayChatView';
7
8
  import { useShowChatAndParticipants } from '../hooks-util';
8
9
 
9
10
  export type OverlayedViewsProps = {
10
11
  offset: SharedValue<number>;
11
- };
12
+ } & OverlayProps;
12
13
 
13
- const _OverlayedViews: React.FC<OverlayedViewsProps> = ({ offset }) => {
14
+ const _OverlayedViews: React.FC<OverlayedViewsProps> = ({
15
+ offset,
16
+ animatedStyle,
17
+ }) => {
14
18
  const { overlayChatVisible } = useShowChatAndParticipants();
15
19
 
16
20
  return (
17
- <OverlayContainer.Overlay>
21
+ <OverlayContainer.Overlay animatedStyle={animatedStyle}>
18
22
  {overlayChatVisible ? <HLSChatView offset={offset} /> : null}
19
23
 
20
24
  <HMSNotifications />
@@ -21,25 +21,6 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
21
21
  */
22
22
  const dimensions = useSharedValue({ width: 0, height: 0 });
23
23
 
24
- /**
25
- * - Tracking number of active pointers in pinch gesture
26
- * "Focal point" is used as an origin point for scaling the view
27
- * when active number of pointers change, focal point is also changed causing a flicker effect
28
- *
29
- * To remove flicker effect, when `numberOfPointers` change, we calculate the amount of change in focal point
30
- * and use the `(new focal point) + (amount of change in focal point)` to apply transformations
31
- */
32
- const numberOfPointers = useSharedValue(0);
33
-
34
- /**
35
- * - Current focal point to apply scaling
36
- * "Focal point" is used as an origin point for scaling the view
37
- * > We transform the "center of View" to the "focal point", "apply scaling" and then "undo the transformation"
38
- */
39
- const focalPoint = useSharedValue({ x: 0, y: 0 });
40
-
41
- const adjustedFocalPoint = useSharedValue({ x: 0, y: 0 });
42
-
43
24
  /**
44
25
  * - focal point captured at the start of the pinch gesture
45
26
  * We use this point to calculate the amount of translation of focal point
@@ -51,17 +32,6 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
51
32
  */
52
33
  const focalPointAtStart = useSharedValue({ x: 0, y: 0 });
53
34
 
54
- /**
55
- * - x,y coords representing the amount by which focal point shifted due to change in `numberOfPointers`
56
- * e.g. focal point when `numberOfPointers = 2` - (20, 100)
57
- * focal point when `numberOfPointers` reduced to `1` - (40, 300)
58
- *
59
- * focal point got shifted by `20` points on x-axis and `200` points on y-axis. Thus, `focalShift = (20, 200)`
60
- *
61
- * Usage: TODO
62
- */
63
- const focalShift = useSharedValue({ x: 0, y: 0 });
64
-
65
35
  const scale = useSharedValue(1);
66
36
  const savedScale = useSharedValue(1);
67
37
  const translation = useSharedValue({ x: 0, y: 0 });
@@ -80,9 +50,22 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
80
50
  const panGesture = Gesture.Pan()
81
51
  .maxPointers(1)
82
52
  .onUpdate((e) => {
53
+ if (savedScale.value <= 1) {
54
+ return;
55
+ }
56
+ const swipeOnXAxis = e.translationX + savedTranslation.value.x;
57
+ const swipeOnYAxis = e.translationY + savedTranslation.value.y;
58
+
59
+ const diffX =
60
+ (dimensions.value.width * savedScale.value - dimensions.value.width) /
61
+ 2;
62
+ const diffY =
63
+ (dimensions.value.height * savedScale.value - dimensions.value.height) /
64
+ 2;
65
+
83
66
  translation.value = {
84
- x: e.translationX + savedTranslation.value.x,
85
- y: e.translationY + savedTranslation.value.y,
67
+ x: Math.max(Math.min(swipeOnXAxis, diffX), -diffX),
68
+ y: Math.max(Math.min(swipeOnYAxis, diffY), -diffY),
86
69
  };
87
70
  })
88
71
  .onEnd(() => {
@@ -91,45 +74,26 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
91
74
 
92
75
  const pinchGesture = Gesture.Pinch()
93
76
  .onStart((e) => {
94
- numberOfPointers.value = e.numberOfPointers;
95
77
  focalPointAtStart.value = { x: e.focalX, y: e.focalY };
96
-
97
- adjustedFocalPoint.value = {
98
- x: e.focalX - focalShift.value.x, // subtracting "focal point shift" value from "current focal point", we will get "focal point before the shift", and apply transformations on the that focal point
99
- y: e.focalY - focalShift.value.y, // subtracting "focal point shift" value from "current focal point", we will get "focal point before the shift", and apply transformations on the that focal point
100
- };
101
78
  })
102
79
  .onUpdate((e) => {
103
- // Calculating `focal point` shift values when `numberOfPointers` changes
104
- if (numberOfPointers.value !== e.numberOfPointers) {
105
- numberOfPointers.value = e.numberOfPointers;
106
-
107
- focalShift.value = {
108
- x: e.focalX - (focalPoint.value.x - focalShift.value.x),
109
- y: e.focalY - (focalPoint.value.y - focalShift.value.y),
110
- };
111
- }
80
+ scale.value = Math.min(Math.max(savedScale.value * e.scale, 0.94), 5.2);
112
81
 
113
- adjustedFocalPoint.value = {
114
- x: e.focalX - focalShift.value.x, // subtracting "focal point shift" value from "current focal point", we will get "focal point before the shift", and apply transformations on the that focal point
115
- y: e.focalY - focalShift.value.y, // subtracting "focal point shift" value from "current focal point", we will get "focal point before the shift", and apply transformations on the that focal point
116
- };
82
+ const offsetX = dimensions.value.width / 2 - focalPointAtStart.value.x;
83
+ const offsetY = dimensions.value.height / 2 - focalPointAtStart.value.y;
84
+
85
+ const swipeOnXAxis = offsetX * scale.value + savedTranslation.value.x;
86
+ const swipeOnYAxis = offsetY * scale.value + savedTranslation.value.y;
87
+
88
+ const diffX =
89
+ (dimensions.value.width * scale.value - dimensions.value.width) / 2;
90
+ const diffY =
91
+ (dimensions.value.height * scale.value - dimensions.value.height) / 2;
117
92
 
118
- // Applying translations
119
93
  translation.value = {
120
- x:
121
- adjustedFocalPoint.value.x -
122
- focalPointAtStart.value.x + // subtracting "focal point position capturred at start of gesture" from "adjusted focal point position" we will get the translation value
123
- savedTranslation.value.x, // Adding current translation to previous Translation to make it a continuous gesture
124
- y:
125
- adjustedFocalPoint.value.y -
126
- focalPointAtStart.value.y + // subtracting "focal point position capturred at start of gesture" from "adjusted focal point position" we will get the translation value
127
- savedTranslation.value.y, // Adding current translation to previous Translation to make it a continuous gesture
94
+ x: Math.max(Math.min(swipeOnXAxis, diffX), -diffX),
95
+ y: Math.max(Math.min(swipeOnYAxis, diffY), -diffY),
128
96
  };
129
-
130
- // saving focal point to apply scaling on correct position
131
- focalPoint.value = { x: e.focalX, y: e.focalY };
132
- scale.value = Math.min(Math.max(savedScale.value * e.scale, 0.94), 5.2);
133
97
  })
134
98
  .onEnd(() => {
135
99
  if (scale.value < 1) {
@@ -143,7 +107,6 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
143
107
  savedScale.value = scale.value;
144
108
  }
145
109
 
146
- focalShift.value = { x: 0, y: 0 };
147
110
  savedTranslation.value = translation.value;
148
111
  });
149
112
 
@@ -151,13 +114,7 @@ export const HMSPinchGesture: React.FC<HMSPinchGestureProps> = ({
151
114
  transform: [
152
115
  { translateX: translation.value.x },
153
116
  { translateY: translation.value.y },
154
- { translateX: focalPointAtStart.value.x - dimensions.value.width / 2 },
155
- { translateY: focalPointAtStart.value.y - dimensions.value.height / 2 },
156
117
  { scale: scale.value },
157
- { translateX: -(focalPointAtStart.value.x - dimensions.value.width / 2) },
158
- {
159
- translateY: -(focalPointAtStart.value.y - dimensions.value.height / 2),
160
- },
161
118
  ],
162
119
  }));
163
120
 
@@ -28,6 +28,7 @@ import {
28
28
  import { useHMSRoomStyleSheet } from '../../hooks-util';
29
29
  import { HMSFullScreenButton } from './HMSFullScreenButton';
30
30
  import { TestIds } from '../../utils/constants';
31
+ import { useIsLandscapeOrientation } from '../../utils/dimension';
31
32
 
32
33
  export interface PeerVideoTileViewProps {
33
34
  peerTrackNode: PeerTrackNode;
@@ -146,6 +147,8 @@ export const _PeerVideoTileView = React.forwardRef<
146
147
  !canTakeActionOnPeer || // If local peer can't take action on peer, Or
147
148
  !allowedToPublish; // If local peer can't publish tracks
148
149
 
150
+ const isLandscapeOrientation = useIsLandscapeOrientation();
151
+
149
152
  return (
150
153
  <View style={styles.container}>
151
154
  <AvatarView
@@ -181,7 +184,7 @@ export const _PeerVideoTileView = React.forwardRef<
181
184
 
182
185
  {/* Handling Peer Audio Mute indicator */}
183
186
  {screenShareTile && showingVideoTrack ? (
184
- isPipModeActive ? null : (
187
+ isPipModeActive || isLandscapeOrientation ? null : (
185
188
  <HMSFullScreenButton peerTrackNode={peerTrackNode} />
186
189
  )
187
190
  ) : peerCanPublishAudio ? (
@@ -55,7 +55,7 @@ const _TilesContainer: React.FC<TilesContainerProps> = ({
55
55
  ? 'row'
56
56
  : 'column',
57
57
  },
58
- { width: Dimensions.get('window').width - left - right },
58
+ { width: Dimensions.get('window').width + left + right },
59
59
  ]}
60
60
  >
61
61
  {peerTrackNodes.length <= 3 ? (
@@ -1,7 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { useSelector } from 'react-redux';
3
3
  import {
4
- SafeAreaView,
5
4
  useSafeAreaFrame,
6
5
  useSafeAreaInsets,
7
6
  } from 'react-native-safe-area-context';
@@ -25,6 +24,7 @@ import { OverlayContainer } from './OverlayContainer';
25
24
  import { OverlayedViews } from './OverlayedViews';
26
25
  import { useFooterHeight } from './Footer';
27
26
  import { useHeaderHeight } from './Header';
27
+ import { View } from 'react-native';
28
28
 
29
29
  interface WebrtcViewProps {
30
30
  offset: SharedValue<number>;
@@ -72,21 +72,36 @@ export const WebrtcView = React.forwardRef<GridViewRefAttrs, WebrtcViewProps>(
72
72
  !state.app.localPeerTrackNode && pairedPeers.length === 0
73
73
  );
74
74
 
75
+ const fullHeight = height - top - (isPortrait ? bottom : 0);
76
+ const smallHeight = isPortrait
77
+ ? height - headerHeight - footerHeight
78
+ : height;
79
+
75
80
  const animatedStyles = useAnimatedStyle(() => {
81
+ return {
82
+ height: interpolate(offset.value, [0, 1], [fullHeight, smallHeight]),
83
+ };
84
+ }, [fullHeight, smallHeight]);
85
+
86
+ const headerPlaceholderAnimatedStyles = useAnimatedStyle(() => {
76
87
  return {
77
88
  height: interpolate(
78
89
  offset.value,
79
90
  [0, 1],
80
- [height - top - bottom, height - headerHeight - footerHeight]
91
+ [top, isPortrait ? headerHeight : top]
81
92
  ),
82
93
  };
83
- }, [height, top, bottom, footerHeight, headerHeight]);
94
+ }, [headerHeight, top, isPortrait]);
84
95
 
85
- const headerPlaceholderAnimatedStyles = useAnimatedStyle(() => {
96
+ const overlayedAnimatedStyles = useAnimatedStyle(() => {
86
97
  return {
87
- height: interpolate(offset.value, [0, 1], [top, headerHeight]),
98
+ bottom: interpolate(
99
+ offset.value,
100
+ [0, 1],
101
+ [!isPortrait ? bottom : 0, 0]
102
+ ),
88
103
  };
89
- }, [headerHeight, top]);
104
+ }, [isPortrait, bottom]);
90
105
 
91
106
  if (isPipModeActive) {
92
107
  return (
@@ -104,7 +119,7 @@ export const WebrtcView = React.forwardRef<GridViewRefAttrs, WebrtcViewProps>(
104
119
  }
105
120
 
106
121
  return (
107
- <SafeAreaView edges={['left', 'right']} style={{ flex: 1 }}>
122
+ <View style={{ flex: 1 }}>
108
123
  <Animated.View style={headerPlaceholderAnimatedStyles} />
109
124
 
110
125
  <Animated.View style={animatedStyles}>
@@ -123,10 +138,13 @@ export const WebrtcView = React.forwardRef<GridViewRefAttrs, WebrtcViewProps>(
123
138
  />
124
139
  )}
125
140
 
126
- <OverlayedViews offset={offset} />
141
+ <OverlayedViews
142
+ animatedStyle={overlayedAnimatedStyles}
143
+ offset={offset}
144
+ />
127
145
  </OverlayContainer>
128
146
  </Animated.View>
129
- </SafeAreaView>
147
+ </View>
130
148
  );
131
149
  }
132
150
  );
package/src/hooks-util.ts CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  useHmsViewsResolutionsState,
22
22
  setSoftInputMode,
23
23
  getSoftInputMode,
24
+ WindowController,
24
25
  // useHMSPeerUpdates,
25
26
  } from '@100mslive/react-native-hms';
26
27
  import type { Chat as ChatConfig } from '@100mslive/types-prebuilt/elements/chat';
@@ -2535,6 +2536,18 @@ export const useBackButtonPress = () => {
2535
2536
  }, [handleBackPress, handleModalVisibleType]);
2536
2537
  };
2537
2538
 
2539
+ export const useLandscapeImmersiveMode = () => {
2540
+ const isLandscapeOrientation = useIsLandscapeOrientation();
2541
+
2542
+ useEffect(() => {
2543
+ if (isLandscapeOrientation) {
2544
+ WindowController.hideSystemBars();
2545
+
2546
+ return WindowController.showSystemBars;
2547
+ }
2548
+ }, [isLandscapeOrientation]);
2549
+ };
2550
+
2538
2551
  export const useSavePropsToStore = (
2539
2552
  props: HMSPrebuiltProps,
2540
2553
  dispatch: AppDispatch