@applicaster/zapp-react-native-ui-components 12.0.0-alpha.3788876021 → 12.0.0-alpha.3849101242
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/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +13 -6
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
- package/Components/Layout/TV/index.tsx +12 -9
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +80 -109
- package/Components/MasterCell/DefaultComponents/DynamicBadge.tsx +4 -2
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +14 -1
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +14 -2
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +24 -9
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -3
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +1 -1
- package/Components/MeasurmentsPortal/BasicMeasurementsPortal.tsx +11 -7
- package/Components/MeasurmentsPortal/MeasurementsPortal.tsx +10 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +9 -5
- package/Components/River/ComponentsMap/ComponentsMap.tsx +92 -22
- package/Components/River/RefreshControl.tsx +55 -1
- package/Components/RouteManager/index.tsx +2 -2
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -0
- package/Components/Screen/index.tsx +35 -24
- package/Components/Transitioner/Scene.tsx +24 -19
- package/Components/Transitioner/Transitioner.tsx +9 -2
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +6 -2
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
- package/Components/VideoLive/LiveImageManager.ts +3 -0
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +11 -4
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +9 -2
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +13 -2
- package/Components/VideoModal/PlayerDetails.tsx +3 -3
- package/Components/VideoModal/PlayerWrapper.tsx +67 -60
- package/Components/VideoModal/VideoModal.tsx +19 -19
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +7 -0
- package/Components/Viewport/ViewportTracker/ViewportTracker.tsx +31 -40
- package/Components/Viewport/ViewportTracker/index.tsx +1 -0
- package/Components/Viewport/utils.js +1 -1
- package/Contexts/MenuToggleContext/{index.js → index.ts} +16 -0
- package/Contexts/ScreenContext/__tests__/__snapshots__/index.test.tsx.snap +3 -0
- package/Contexts/ScreenContext/__tests__/index.test.tsx +27 -0
- package/Contexts/ScreenContext/index.tsx +94 -25
- package/Contexts/ScreenDataContext/index.ts +3 -0
- package/events/index.ts +1 -0
- package/package.json +5 -5
- /package/Contexts/{index.js → index.ts} +0 -0
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
TapGestureHandler,
|
|
10
10
|
GestureHandlerRootView,
|
|
11
11
|
} from "react-native-gesture-handler";
|
|
12
|
+
|
|
13
|
+
import { PlayerContainerContext } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainerContext";
|
|
12
14
|
import {
|
|
13
15
|
useModalAnimationContext,
|
|
14
16
|
PlayerAnimationStateEnum,
|
|
@@ -58,6 +60,8 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
58
60
|
setLastSnap,
|
|
59
61
|
} = useModalAnimationContext();
|
|
60
62
|
|
|
63
|
+
const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
|
|
64
|
+
|
|
61
65
|
const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
|
|
62
66
|
useNavigation();
|
|
63
67
|
|
|
@@ -69,6 +73,11 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
69
73
|
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
70
74
|
playerAnimationState !== PlayerAnimationStateEnum.maximaze;
|
|
71
75
|
|
|
76
|
+
const isEnablePanGesture =
|
|
77
|
+
!isLanguageOverlayVisible &&
|
|
78
|
+
isNotMinimizeMaximazeAnimation &&
|
|
79
|
+
(isMaximazedModal || isMinimizedModal);
|
|
80
|
+
|
|
72
81
|
const isAudioItem = React.useMemo(
|
|
73
82
|
() =>
|
|
74
83
|
videoModalState.item?.content?.type?.includes?.("audio") ||
|
|
@@ -290,15 +299,13 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
290
299
|
>
|
|
291
300
|
<View pointerEvents="box-none">
|
|
292
301
|
<PanGestureHandler
|
|
293
|
-
enabled={
|
|
294
|
-
(isMaximazedModal || isMinimizedModal) &&
|
|
295
|
-
isNotMinimizeMaximazeAnimation
|
|
296
|
-
}
|
|
302
|
+
enabled={isEnablePanGesture}
|
|
297
303
|
ref={panHandlerRef}
|
|
298
304
|
simultaneousHandlers={[scrollRef, tapHandlerRef]}
|
|
299
305
|
shouldCancelWhenOutside={isMaximazedModal}
|
|
300
306
|
onGestureEvent={onGestureEvent}
|
|
301
307
|
onHandlerStateChange={onHandlerStateChange}
|
|
308
|
+
activeOffsetY={[-5, 5]}
|
|
302
309
|
>
|
|
303
310
|
<Animated.View>
|
|
304
311
|
<NativeViewGestureHandler
|
|
@@ -3,6 +3,8 @@ import { Animated, StyleSheet } from "react-native";
|
|
|
3
3
|
|
|
4
4
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
5
5
|
import { PanGestureHandler, State } from "react-native-gesture-handler";
|
|
6
|
+
|
|
7
|
+
import { PlayerContainerContext } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainerContext";
|
|
6
8
|
import {
|
|
7
9
|
useModalAnimationContext,
|
|
8
10
|
PlayerAnimationStateEnum,
|
|
@@ -35,9 +37,14 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
35
37
|
} = useModalAnimationContext();
|
|
36
38
|
|
|
37
39
|
const { videoModalState } = useNavigation();
|
|
40
|
+
const { isLanguageOverlayVisible } = React.useContext(PlayerContainerContext);
|
|
41
|
+
|
|
38
42
|
const isMaximazedModal = videoModalState.mode === "MAXIMIZED";
|
|
39
43
|
const isMinimizedModal = videoModalState.mode === "MINIMIZED";
|
|
40
44
|
|
|
45
|
+
const isEnablePanGesture =
|
|
46
|
+
!isLanguageOverlayVisible && (isMaximazedModal || isMinimizedModal);
|
|
47
|
+
|
|
41
48
|
const onGestureEvent = Animated.event(
|
|
42
49
|
[{ nativeEvent: { translationY: dragVideoPlayerY } }],
|
|
43
50
|
{ useNativeDriver: true }
|
|
@@ -53,7 +60,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
53
60
|
if (videoModalState.mode === "MAXIMIZED") {
|
|
54
61
|
if (translationY > 0) {
|
|
55
62
|
const endOffsetY =
|
|
56
|
-
lastSnap + preparedTranslationY + dragToss * velocityY +
|
|
63
|
+
lastSnap + preparedTranslationY + dragToss * velocityY + 200;
|
|
57
64
|
|
|
58
65
|
let destSnapPoint = modalSnapPoints[0];
|
|
59
66
|
|
|
@@ -127,7 +134,7 @@ export const AnimatedVideoPlayer = ({ children }: Props) => {
|
|
|
127
134
|
|
|
128
135
|
return (
|
|
129
136
|
<PanGestureHandler
|
|
130
|
-
enabled={
|
|
137
|
+
enabled={isEnablePanGesture}
|
|
131
138
|
shouldCancelWhenOutside={isMaximazedModal}
|
|
132
139
|
onGestureEvent={onGestureEvent}
|
|
133
140
|
onHandlerStateChange={onHandlerStateChange}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React, { useContext } from "react";
|
|
2
2
|
import { Animated } from "react-native";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useSafeAreaFrame,
|
|
6
|
+
useSafeAreaInsets,
|
|
7
|
+
} from "react-native-safe-area-context";
|
|
5
8
|
import { useGetBottomTabBarHeight } from "@applicaster/zapp-react-native-utils/reactHooks";
|
|
6
9
|
|
|
7
10
|
import { useConfiguration } from "../utils";
|
|
@@ -91,8 +94,16 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
|
|
|
91
94
|
const dragVideoPlayerY = React.useRef(new Animated.Value(0)).current;
|
|
92
95
|
|
|
93
96
|
const { height } = useSafeAreaFrame();
|
|
97
|
+
const { bottom: bottomSafeArea } = useSafeAreaInsets();
|
|
94
98
|
const bottomTabBarHeight = useGetBottomTabBarHeight();
|
|
95
|
-
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
If bottomTabBarHeight is equal 0 it means an app does not use bottomTabBar.
|
|
102
|
+
Because of this we need to minus bottom SafeArea offset.
|
|
103
|
+
*/
|
|
104
|
+
const minValue =
|
|
105
|
+
height - minimisedHeight - (bottomTabBarHeight || bottomSafeArea);
|
|
106
|
+
|
|
96
107
|
const modalSnapPoints = React.useMemo(() => [0, minValue], [minValue]);
|
|
97
108
|
// Last snap state which will helps us to make smooth responder to scrollview animation
|
|
98
109
|
const [lastSnap, setLastSnap] = React.useState<number>(modalSnapPoints[0]);
|
|
@@ -42,12 +42,12 @@ export const PlayerDetails = ({
|
|
|
42
42
|
: {};
|
|
43
43
|
|
|
44
44
|
// Animation setup
|
|
45
|
-
const translateY = useRef(new Animated.Value(
|
|
45
|
+
const translateY = useRef(new Animated.Value(50)).current;
|
|
46
46
|
const opacity = useRef(new Animated.Value(0)).current;
|
|
47
47
|
|
|
48
48
|
const runAnimation = () => {
|
|
49
49
|
Animated.timing(translateY, {
|
|
50
|
-
toValue:
|
|
50
|
+
toValue: -30,
|
|
51
51
|
duration: 500,
|
|
52
52
|
easing: Easing.inOut(Easing.ease),
|
|
53
53
|
useNativeDriver: true,
|
|
@@ -63,7 +63,7 @@ export const PlayerDetails = ({
|
|
|
63
63
|
|
|
64
64
|
useEffect(() => {
|
|
65
65
|
if (isAudioPlayer) {
|
|
66
|
-
setTimeout(() => runAnimation(),
|
|
66
|
+
setTimeout(() => runAnimation(), 1500);
|
|
67
67
|
}
|
|
68
68
|
}, [isAudioPlayer]);
|
|
69
69
|
|
|
@@ -14,12 +14,13 @@ import { PlayerDetails } from "./PlayerDetails";
|
|
|
14
14
|
import { playerDimesionsHack } from "./utils";
|
|
15
15
|
import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
16
16
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
17
|
+
import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
|
|
17
18
|
|
|
18
19
|
import {
|
|
19
|
-
AnimationComponent,
|
|
20
|
-
ComponentAnimationType,
|
|
21
20
|
AnimatedScrollModal,
|
|
22
21
|
AnimatedVideoPlayerComponent,
|
|
22
|
+
AnimationComponent,
|
|
23
|
+
ComponentAnimationType,
|
|
23
24
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
24
25
|
|
|
25
26
|
type DimensionsT = {
|
|
@@ -180,65 +181,71 @@ export const PlayerWrapper = (props: Props) => {
|
|
|
180
181
|
[containerDimensions, playerDimesionsHack]
|
|
181
182
|
);
|
|
182
183
|
|
|
184
|
+
const pathname = `${ROUTE_TYPES.VIDEO_MODAL}/${entry?.id}`;
|
|
185
|
+
|
|
183
186
|
return (
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
animationType={ComponentAnimationType.moveUpComponent}
|
|
210
|
-
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
211
|
-
additionalData={{
|
|
212
|
-
useLayoutMeasure: isTabletLandscape,
|
|
213
|
-
disableAnimatedComponent: !isTabletLandscape,
|
|
214
|
-
resetAnimationValue: isTabletLandscape && docked,
|
|
215
|
-
}}
|
|
216
|
-
>
|
|
217
|
-
<AnimatedVideoPlayerComponent>
|
|
218
|
-
{children(childrenStyles)}
|
|
219
|
-
</AnimatedVideoPlayerComponent>
|
|
220
|
-
</AnimationComponent>
|
|
221
|
-
</View>
|
|
222
|
-
<AnimatedScrollModal>
|
|
223
|
-
{isInlineModal ? (
|
|
224
|
-
<AnimationComponent
|
|
225
|
-
animationType={ComponentAnimationType.componentFade}
|
|
226
|
-
style={defaultStyles.flex}
|
|
187
|
+
<ScreenContextProvider pathname={pathname}>
|
|
188
|
+
<PathnameContext.Provider value={pathname}>
|
|
189
|
+
<WrapperView
|
|
190
|
+
edges={getEdges(isTablet, isInlineModal) as readonly Edge[]}
|
|
191
|
+
style={[
|
|
192
|
+
safeAreaStyles(configuration, isTablet),
|
|
193
|
+
style,
|
|
194
|
+
playerDimesionsHack,
|
|
195
|
+
]}
|
|
196
|
+
>
|
|
197
|
+
<AnimationComponent
|
|
198
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
199
|
+
additionalData={{ saveArea: true }}
|
|
200
|
+
style={directionStyles(isTabletLandscape)}
|
|
201
|
+
>
|
|
202
|
+
<ScreenContextProvider pathname={pathname}>
|
|
203
|
+
<PathnameContext.Provider value={pathname}>
|
|
204
|
+
<View
|
|
205
|
+
testID={`${entry?.id}-player-container`}
|
|
206
|
+
style={[
|
|
207
|
+
defaultStyles.playerContainer,
|
|
208
|
+
containerDimensions,
|
|
209
|
+
containerStyle,
|
|
210
|
+
playerDimesionsHack,
|
|
211
|
+
]}
|
|
227
212
|
>
|
|
228
|
-
<
|
|
229
|
-
|
|
230
|
-
style={defaultStyles.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
213
|
+
<AnimationComponent
|
|
214
|
+
animationType={ComponentAnimationType.moveUpComponent}
|
|
215
|
+
style={isTabletLandscape ? defaultStyles.flex : undefined}
|
|
216
|
+
additionalData={{
|
|
217
|
+
useLayoutMeasure: isTabletLandscape,
|
|
218
|
+
disableAnimatedComponent: !isTabletLandscape,
|
|
219
|
+
resetAnimationValue: isTabletLandscape && docked,
|
|
220
|
+
}}
|
|
221
|
+
>
|
|
222
|
+
<AnimatedVideoPlayerComponent>
|
|
223
|
+
{children(childrenStyles)}
|
|
224
|
+
</AnimatedVideoPlayerComponent>
|
|
225
|
+
</AnimationComponent>
|
|
226
|
+
</View>
|
|
227
|
+
<AnimatedScrollModal>
|
|
228
|
+
{isInlineModal ? (
|
|
229
|
+
<AnimationComponent
|
|
230
|
+
animationType={ComponentAnimationType.componentFade}
|
|
231
|
+
style={defaultStyles.flex}
|
|
232
|
+
>
|
|
233
|
+
<PlayerDetails
|
|
234
|
+
configuration={configuration}
|
|
235
|
+
style={defaultStyles.playerDetails}
|
|
236
|
+
entry={entry}
|
|
237
|
+
isTabletLandscape={isTabletLandscape}
|
|
238
|
+
/>
|
|
239
|
+
</AnimationComponent>
|
|
240
|
+
) : (
|
|
241
|
+
<View style={defaultStyles.playerDetails} />
|
|
242
|
+
)}
|
|
243
|
+
</AnimatedScrollModal>
|
|
244
|
+
</PathnameContext.Provider>
|
|
245
|
+
</ScreenContextProvider>
|
|
246
|
+
</AnimationComponent>
|
|
247
|
+
</WrapperView>
|
|
248
|
+
</PathnameContext.Provider>
|
|
249
|
+
</ScreenContextProvider>
|
|
243
250
|
);
|
|
244
251
|
};
|
|
@@ -129,17 +129,17 @@ const VideoModalComponent = () => {
|
|
|
129
129
|
const pathname = `${ROUTE_TYPES.VIDEO_MODAL}/${item?.id}`;
|
|
130
130
|
|
|
131
131
|
return (
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
<ScreenContextProvider pathname={pathname}>
|
|
133
|
+
<PathnameContext.Provider value={pathname}>
|
|
134
|
+
{itemIdHooksFinished === item?.id ? (
|
|
135
|
+
<AnimatedPlayerModalWrapper
|
|
136
|
+
style={[
|
|
137
|
+
styles.container,
|
|
138
|
+
{
|
|
139
|
+
backgroundColor,
|
|
140
|
+
},
|
|
141
|
+
]}
|
|
142
|
+
>
|
|
143
143
|
<HandlePlayable
|
|
144
144
|
item={item}
|
|
145
145
|
isModal={mode !== "PIP"}
|
|
@@ -147,14 +147,14 @@ const VideoModalComponent = () => {
|
|
|
147
147
|
modalWidth={modalSize.width}
|
|
148
148
|
mode={mode}
|
|
149
149
|
/>
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
</
|
|
157
|
-
</
|
|
150
|
+
</AnimatedPlayerModalWrapper>
|
|
151
|
+
) : (
|
|
152
|
+
<View style={styles.loaderContainer}>
|
|
153
|
+
<Spinner />
|
|
154
|
+
</View>
|
|
155
|
+
)}
|
|
156
|
+
</PathnameContext.Provider>
|
|
157
|
+
</ScreenContextProvider>
|
|
158
158
|
);
|
|
159
159
|
};
|
|
160
160
|
|
|
@@ -25,6 +25,13 @@ jest.mock("react-native-gesture-handler");
|
|
|
25
25
|
|
|
26
26
|
jest.mock("../PlayerDetails", () => ({ PlayerDetails: View }));
|
|
27
27
|
|
|
28
|
+
jest.mock(
|
|
29
|
+
"@applicaster/zapp-react-native-utils/reactHooks/screen/useScreenContext",
|
|
30
|
+
() => ({
|
|
31
|
+
useScreenContext: jest.fn().mockReturnValue({ screen: {}, entry: {} }),
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
|
|
28
35
|
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/device", () => ({
|
|
29
36
|
useIsTablet,
|
|
30
37
|
}));
|
|
@@ -6,23 +6,23 @@ import { callOnChildren } from "../utils";
|
|
|
6
6
|
|
|
7
7
|
export function ViewportTracker(props) {
|
|
8
8
|
const viewportEvents = useViewportEventsContext();
|
|
9
|
-
const { children } = props;
|
|
10
|
-
const [width, setWidth] = React.useState(0);
|
|
11
|
-
const [height, setHeight] = React.useState(0);
|
|
12
|
-
const [offsetX, setOffsetX] = React.useState(0);
|
|
13
|
-
const [offsetY, setOffsetY] = React.useState(0);
|
|
14
9
|
const [nodeHandle, setNodeHandle] = React.useState(null);
|
|
15
10
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
const childrenRef = React.useRef(props.children);
|
|
12
|
+
|
|
13
|
+
const dimensionsRef = React.useRef({ width: 0, height: 0 });
|
|
14
|
+
const offsetRef = React.useRef({ offsetX: 0, offsetY: 0 });
|
|
15
|
+
|
|
16
|
+
const assignRef = React.useCallback((ref) => {
|
|
17
|
+
childrenRef.current?.ref?.(ref);
|
|
18
|
+
setNodeHandle(findNodeHandle(ref));
|
|
19
|
+
}, []);
|
|
23
20
|
|
|
24
21
|
const onViewportChange = React.useCallback(
|
|
25
|
-
(
|
|
22
|
+
({
|
|
23
|
+
event = { ...dimensionsRef.current, ...offsetRef.current },
|
|
24
|
+
shouldMeasureLayout = true,
|
|
25
|
+
} = {}) => {
|
|
26
26
|
if (nodeHandle && event?.width > 0 && event?.height > 0) {
|
|
27
27
|
viewportEvents?.notify?.({
|
|
28
28
|
parentHandle: nodeHandle,
|
|
@@ -36,54 +36,45 @@ export function ViewportTracker(props) {
|
|
|
36
36
|
|
|
37
37
|
const onLayout = React.useCallback(
|
|
38
38
|
(event) => {
|
|
39
|
-
callOnChildren(
|
|
40
|
-
|
|
41
|
-
setHeight(event?.nativeEvent?.layout?.height);
|
|
39
|
+
callOnChildren(childrenRef.current, "onLayout", event);
|
|
40
|
+
dimensionsRef.current = event?.nativeEvent?.layout;
|
|
42
41
|
|
|
43
|
-
onViewportChange(
|
|
44
|
-
width: event?.nativeEvent?.layout?.width,
|
|
45
|
-
height: event?.nativeEvent?.layout?.height,
|
|
46
|
-
offsetX,
|
|
47
|
-
offsetY,
|
|
48
|
-
});
|
|
42
|
+
onViewportChange();
|
|
49
43
|
},
|
|
50
|
-
[
|
|
44
|
+
[onViewportChange]
|
|
51
45
|
);
|
|
52
46
|
|
|
53
47
|
const onContentSizeChange = React.useCallback(
|
|
54
48
|
(contentWidth, contentHeight) => {
|
|
55
49
|
callOnChildren(
|
|
56
|
-
|
|
50
|
+
childrenRef.current,
|
|
57
51
|
"onContentSizeChange",
|
|
58
52
|
contentWidth,
|
|
59
53
|
contentHeight
|
|
60
54
|
);
|
|
61
55
|
|
|
62
|
-
onViewportChange(
|
|
56
|
+
onViewportChange();
|
|
63
57
|
},
|
|
64
|
-
[onViewportChange
|
|
58
|
+
[onViewportChange]
|
|
65
59
|
);
|
|
66
60
|
|
|
67
61
|
const onScroll = React.useCallback(
|
|
68
62
|
(event) => {
|
|
69
|
-
callOnChildren(
|
|
70
|
-
|
|
71
|
-
setOffsetY(event?.nativeEvent?.contentOffset?.y);
|
|
63
|
+
callOnChildren(childrenRef.current, "onScroll", event);
|
|
64
|
+
offsetRef.current = event?.nativeEvent?.contentOffset;
|
|
72
65
|
|
|
73
|
-
onViewportChange(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
height,
|
|
77
|
-
offsetX: event?.nativeEvent?.contentOffset?.x,
|
|
78
|
-
offsetY: event?.nativeEvent?.contentOffset?.y,
|
|
79
|
-
},
|
|
80
|
-
false
|
|
81
|
-
);
|
|
66
|
+
onViewportChange({
|
|
67
|
+
shouldMeasureLayout: false,
|
|
68
|
+
});
|
|
82
69
|
},
|
|
83
|
-
[onViewportChange
|
|
70
|
+
[onViewportChange]
|
|
84
71
|
);
|
|
85
72
|
|
|
86
|
-
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
childrenRef.current = props.children;
|
|
75
|
+
}, [props.children]);
|
|
76
|
+
|
|
77
|
+
return React.cloneElement(React.Children.only(props.children), {
|
|
87
78
|
ref: assignRef,
|
|
88
79
|
onLayout,
|
|
89
80
|
onContentSizeChange,
|
|
@@ -6,6 +6,7 @@ import { ViewportEventContext, ViewportEvents } from "../ViewportEvents";
|
|
|
6
6
|
type Props = {
|
|
7
7
|
viewportEventsManager?: any;
|
|
8
8
|
children: React.ReactNode;
|
|
9
|
+
flatListRef?: any; // this ref is used to bind to children component
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export function ViewportTracker(props: Props) {
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
|
|
3
3
|
export function callOnChildren(children, method, ...args) {
|
|
4
4
|
const childMethod = React.Children.only(children).props[method];
|
|
5
|
-
childMethod && childMethod(...args);
|
|
5
|
+
typeof childMethod === "function" && childMethod?.(...args);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function isInViewport(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
|
|
2
|
+
import React from "react";
|
|
2
3
|
|
|
3
4
|
const initialContext = { toggleMenu: {}, closeMenu: {}, openMenu: {} };
|
|
4
5
|
|
|
@@ -16,3 +17,18 @@ const stateValidator = ({ property }) =>
|
|
|
16
17
|
property === "openMenu";
|
|
17
18
|
|
|
18
19
|
export const MenuToggleContext = createContext(initialContext, stateValidator);
|
|
20
|
+
|
|
21
|
+
export type MenuToggleContextType = {
|
|
22
|
+
toggleMenu: any;
|
|
23
|
+
setToggleMenu: () => void;
|
|
24
|
+
openMenu: any;
|
|
25
|
+
setOpenMenu: () => void;
|
|
26
|
+
closeMenu: any;
|
|
27
|
+
setCloseMenu: () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const useMenuToggleContext = () => {
|
|
31
|
+
return React.useContext<MenuToggleContextType>(
|
|
32
|
+
MenuToggleContext.ReactContext
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { render } from "@testing-library/react-native";
|
|
2
|
+
import { ScreenContext, ScreenContextProvider, withScreenContext } from "../";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
describe("ScreenContext", () => {
|
|
6
|
+
describe("ScreneContext context", () => {
|
|
7
|
+
it("should return the context", () => {
|
|
8
|
+
expect(ScreenContext).toBeDefined();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("ScreenContextProvider", () => {
|
|
13
|
+
it("should return the provider", () => {
|
|
14
|
+
expect(ScreenContextProvider).toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("withScreenContext", () => {
|
|
19
|
+
it("should return the context", () => {
|
|
20
|
+
const Component = () => null;
|
|
21
|
+
const WrappedComponent = withScreenContext(Component);
|
|
22
|
+
const { toJSON } = render(<WrappedComponent />);
|
|
23
|
+
|
|
24
|
+
expect(toJSON()).toMatchSnapshot();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|