@applicaster/zapp-react-native-ui-components 12.0.0-alpha.5933014273 → 12.0.0-alpha.6158046395
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/Cell/Cell.tsx +8 -1
- package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
- package/Components/Focusable/index.android.tsx +15 -9
- package/Components/FocusableList/FocusableChild.ts +2 -2
- package/Components/FocusableList/index.tsx +11 -12
- package/Components/FocusableScrollView/index.tsx +1 -1
- package/Components/Image/Image.android.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +11 -5
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +6 -1
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
- package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
- package/Components/MasterCell/utils/index.ts +3 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +14 -8
- package/Components/Transitioner/Transitioner.tsx +13 -3
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
- package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +3 -9
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +38 -40
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +9 -6
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +28 -26
- package/Components/VideoModal/PlayerDetails.tsx +16 -2
- package/Components/VideoModal/PlayerWrapper.tsx +40 -10
- package/Components/VideoModal/VideoModal.tsx +33 -27
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +56 -10
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +4 -1
- package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
- package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
- package/Contexts/CachedDimensionsContext/index.ts +13 -9
- package/Contexts/ConfirmDialogState/index.ts +1 -1
- package/Contexts/ScreenContext/index.tsx +6 -1
- package/package.json +5 -5
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -276,13 +276,20 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
276
276
|
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
277
277
|
>
|
|
278
278
|
{(focused, event) => {
|
|
279
|
+
const isFocused = this.isCellFocused(focused);
|
|
280
|
+
|
|
281
|
+
if (isFocused) {
|
|
282
|
+
const accessibilityManager = AccessibilityManager.getInstance();
|
|
283
|
+
accessibilityManager.readText({ text: item.title });
|
|
284
|
+
}
|
|
285
|
+
|
|
279
286
|
return (
|
|
280
287
|
<FocusableCell
|
|
281
288
|
{...{
|
|
282
289
|
index,
|
|
283
290
|
CellRenderer,
|
|
284
291
|
item,
|
|
285
|
-
focused:
|
|
292
|
+
focused: isFocused,
|
|
286
293
|
scrollTo: this.scrollToIndex(event),
|
|
287
294
|
behavior,
|
|
288
295
|
}}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, act } from "@testing-library/react-native";
|
|
3
|
+
import { Touchable } from "../../Touchable";
|
|
4
|
+
|
|
5
|
+
const mockUseIsRTL = jest.fn();
|
|
6
|
+
|
|
7
|
+
jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
|
|
8
|
+
useIsRTL: mockUseIsRTL,
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
const mockUseFocusManager = jest.fn();
|
|
12
|
+
|
|
13
|
+
jest.mock("@applicaster/zapp-react-native-utils/focusManager", () => ({
|
|
14
|
+
useFocusManager: mockUseFocusManager,
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const mockUsePrevious = jest.fn();
|
|
18
|
+
|
|
19
|
+
jest.mock("@applicaster/zapp-react-native-utils/reactHooks/utils", () => ({
|
|
20
|
+
usePrevious: mockUsePrevious,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const { Focusable } = require("../index.android");
|
|
24
|
+
|
|
25
|
+
describe("Focusable", () => {
|
|
26
|
+
const mockFocusManager = {
|
|
27
|
+
isFocused: jest.fn(),
|
|
28
|
+
onDisableFocusChange: jest.fn(),
|
|
29
|
+
registerFocusable: jest.fn(),
|
|
30
|
+
focusedId: "test-id",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
mockUseIsRTL.mockReturnValue(false);
|
|
36
|
+
mockUseFocusManager.mockReturnValue(mockFocusManager);
|
|
37
|
+
mockUsePrevious.mockReturnValue(false);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("updates disableFocus state when disableFocus prop changes", () => {
|
|
41
|
+
const { rerender } = render(
|
|
42
|
+
<Focusable id="test-id" disableFocus={false}>
|
|
43
|
+
<Touchable testID="touchable" />
|
|
44
|
+
</Focusable>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
rerender(
|
|
48
|
+
<Focusable id="test-id" disableFocus={true}>
|
|
49
|
+
<Touchable testID="touchable" />
|
|
50
|
+
</Focusable>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(mockFocusManager.onDisableFocusChange).toHaveBeenCalledWith(
|
|
54
|
+
"test-id"
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("calls focusManager.registerFocusable on mount and unregisters on unmount", () => {
|
|
59
|
+
const unregister = jest.fn();
|
|
60
|
+
mockFocusManager.registerFocusable.mockReturnValue(unregister);
|
|
61
|
+
|
|
62
|
+
const { unmount } = render(
|
|
63
|
+
<Focusable id="test-id">
|
|
64
|
+
<Touchable testID="touchable" />
|
|
65
|
+
</Focusable>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(mockFocusManager.registerFocusable).toHaveBeenCalled();
|
|
69
|
+
act(() => unmount());
|
|
70
|
+
expect(unregister).toHaveBeenCalled();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -128,7 +128,10 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
128
128
|
|
|
129
129
|
const _onBlur = React.useCallback(
|
|
130
130
|
(ref, options = {}) => {
|
|
131
|
-
|
|
131
|
+
if (ref.props.id !== focusManager.focusedId) {
|
|
132
|
+
setFocused(false);
|
|
133
|
+
}
|
|
134
|
+
|
|
132
135
|
onBlur?.(ref, options);
|
|
133
136
|
},
|
|
134
137
|
[onBlur]
|
|
@@ -148,15 +151,14 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
148
151
|
[isRTL, nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight]
|
|
149
152
|
);
|
|
150
153
|
|
|
151
|
-
const contextState = React.useMemo(
|
|
152
|
-
|
|
154
|
+
const contextState = React.useMemo(() => {
|
|
155
|
+
return {
|
|
153
156
|
focused,
|
|
154
157
|
...parentFocus,
|
|
155
158
|
ref: touchableRef,
|
|
156
159
|
setIsFocusable,
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
);
|
|
160
|
+
};
|
|
161
|
+
}, [parentFocus, focused]);
|
|
160
162
|
|
|
161
163
|
return (
|
|
162
164
|
<Touchable
|
|
@@ -173,9 +175,13 @@ function FocusableComponent(props: Props, forwardedRef) {
|
|
|
173
175
|
{...parentFocus}
|
|
174
176
|
>
|
|
175
177
|
<FocusableContext.Provider value={contextState}>
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
{React.useMemo(
|
|
179
|
+
() =>
|
|
180
|
+
typeof children === "function"
|
|
181
|
+
? children(focused, parentFocus, touchableRef)
|
|
182
|
+
: children,
|
|
183
|
+
[children, focused, parentFocus]
|
|
184
|
+
)}
|
|
179
185
|
</FocusableContext.Provider>
|
|
180
186
|
</Touchable>
|
|
181
187
|
);
|
|
@@ -31,14 +31,14 @@ const useParentFocus = (
|
|
|
31
31
|
|
|
32
32
|
function FocusableChildComponent(props) {
|
|
33
33
|
const { setIsFocusable, ...focusableContext } = useFocusable();
|
|
34
|
+
const focused = useCellState(props.id);
|
|
35
|
+
|
|
34
36
|
const parentFocus = useParentFocus(props, focusableContext);
|
|
35
37
|
|
|
36
38
|
const onLoadFailed = React.useCallback(() => {
|
|
37
39
|
setIsFocusable(false);
|
|
38
40
|
}, []);
|
|
39
41
|
|
|
40
|
-
const focused = useCellState(props.id);
|
|
41
|
-
|
|
42
42
|
return props.renderItem({
|
|
43
43
|
...props,
|
|
44
44
|
focused,
|
|
@@ -88,6 +88,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
88
88
|
data = [],
|
|
89
89
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
90
90
|
onAllComponentsLoaded, // TODO: re-implement it
|
|
91
|
+
omitPropsPropagation = [],
|
|
91
92
|
} = props;
|
|
92
93
|
|
|
93
94
|
useCheckItemIdsForUnique({ componentId: props.id, items: data });
|
|
@@ -252,9 +253,9 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
252
253
|
]
|
|
253
254
|
);
|
|
254
255
|
|
|
255
|
-
const
|
|
256
|
-
(
|
|
257
|
-
|
|
256
|
+
const getFlatListProps = React.useCallback(
|
|
257
|
+
R.omit(
|
|
258
|
+
[
|
|
258
259
|
"onListElementFocus",
|
|
259
260
|
"onListElementPress",
|
|
260
261
|
"onListElementPressOut",
|
|
@@ -267,17 +268,17 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
267
268
|
"focusableItemProps",
|
|
268
269
|
"renderItem",
|
|
269
270
|
"extraChildrenData",
|
|
270
|
-
"extraData",
|
|
271
|
-
"keyExtractor",
|
|
272
271
|
"onAllComponentsLoaded",
|
|
273
272
|
"focused",
|
|
274
273
|
"id",
|
|
275
274
|
"initialFocusDirection",
|
|
276
275
|
"withStateMemory",
|
|
277
276
|
"useSequentialLoading",
|
|
278
|
-
...
|
|
279
|
-
]
|
|
280
|
-
|
|
277
|
+
...omitPropsPropagation,
|
|
278
|
+
],
|
|
279
|
+
R.__
|
|
280
|
+
),
|
|
281
|
+
[omitPropsPropagation]
|
|
281
282
|
);
|
|
282
283
|
|
|
283
284
|
const onEndReached = React.useCallback(
|
|
@@ -289,7 +290,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
289
290
|
|
|
290
291
|
const initialNumToRender = toFiniteNumberWithDefault(
|
|
291
292
|
10,
|
|
292
|
-
|
|
293
|
+
props.initialNumToRender
|
|
293
294
|
);
|
|
294
295
|
|
|
295
296
|
return (
|
|
@@ -298,12 +299,10 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
|
|
|
298
299
|
<FlatList
|
|
299
300
|
focusable={false}
|
|
300
301
|
scrollEnabled={false}
|
|
301
|
-
extraData={props.extraData}
|
|
302
302
|
ref={ref}
|
|
303
|
-
{...
|
|
303
|
+
{...getFlatListProps(props)}
|
|
304
304
|
renderItem={renderItem}
|
|
305
305
|
onEndReached={onEndReached}
|
|
306
|
-
keyExtractor={props.keyExtractor}
|
|
307
306
|
initialNumToRender={initialNumToRender}
|
|
308
307
|
/>
|
|
309
308
|
</ChildrenFocusDeactivatorView>
|
|
@@ -8,5 +8,5 @@ import { useImageSource } from "./utils";
|
|
|
8
8
|
export const QBImage = (props: FastImageProps) => {
|
|
9
9
|
const source = useImageSource(props.source);
|
|
10
10
|
|
|
11
|
-
return <FastImage {...props} source={source} />;
|
|
11
|
+
return <FastImage useLastImageAsDefaultSource {...props} source={source} />;
|
|
12
12
|
};
|
|
@@ -66,20 +66,26 @@ export function ActionButton(props: Props) {
|
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
useEffect(() => {
|
|
69
|
-
if (actionDisabled || !actionContext)
|
|
69
|
+
if ((actionDisabled || !actionContext) && actionState !== null) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
70
72
|
|
|
71
73
|
setActionState(actionContext.initialEntryState(item));
|
|
72
|
-
}, [actionDisabled, item?.id, actionContext]);
|
|
74
|
+
}, [actionDisabled, item?.id, actionContext, action]);
|
|
73
75
|
|
|
74
76
|
const onPress = useCallback(() => {
|
|
75
77
|
actionContext.invokeAction(item, {
|
|
76
|
-
updateState:
|
|
78
|
+
updateState: (state) => {
|
|
79
|
+
setActionState(state);
|
|
80
|
+
},
|
|
77
81
|
});
|
|
78
|
-
}, [actionState, actionContext?.state,
|
|
82
|
+
}, [actionState, actionContext?.state, item?.id]);
|
|
79
83
|
|
|
80
84
|
useEffect(() => {
|
|
81
85
|
if (typeof actionContext?.addListener === "function") {
|
|
82
|
-
return actionContext?.addListener(item.id as string,
|
|
86
|
+
return actionContext?.addListener(item.id as string, (state) => {
|
|
87
|
+
setActionState(state);
|
|
88
|
+
});
|
|
83
89
|
}
|
|
84
90
|
}, [item?.id]);
|
|
85
91
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
ifElseFocusedSelected,
|
|
4
4
|
ifElseSelected,
|
|
5
5
|
} from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
6
|
+
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
7
|
|
|
7
8
|
import { getPositionStyles } from "./utils";
|
|
8
9
|
|
|
@@ -31,7 +32,11 @@ export const CellBadge = ({
|
|
|
31
32
|
return {
|
|
32
33
|
type: View, // Cell badge view
|
|
33
34
|
style: {
|
|
34
|
-
flex:
|
|
35
|
+
flex: platformSelect({
|
|
36
|
+
tvos: 0,
|
|
37
|
+
android_tv: 0,
|
|
38
|
+
default: 1,
|
|
39
|
+
}),
|
|
35
40
|
position: "absolute",
|
|
36
41
|
...getPositionStyles(position, {
|
|
37
42
|
width: value("cell_badge_width"),
|
|
@@ -47,9 +47,8 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
|
|
|
47
47
|
|
|
48
48
|
const accessibilityManager = useAccessibilityManager({});
|
|
49
49
|
|
|
50
|
-
const { ttsLabel } =
|
|
51
|
-
?.initialEntryState(item)
|
|
52
|
-
?.getAccessibility(item);
|
|
50
|
+
const { ttsLabel = "" } =
|
|
51
|
+
actionContext?.initialEntryState(item)?.getAccessibility?.(item) || {};
|
|
53
52
|
|
|
54
53
|
const onPress = (event) => {
|
|
55
54
|
event?.preventDefault?.();
|
|
@@ -38,21 +38,22 @@ function Image({
|
|
|
38
38
|
|
|
39
39
|
const shouldRenderImg = source && !error;
|
|
40
40
|
|
|
41
|
+
// Default placeholder image fallback is empty string because it won't rerender
|
|
42
|
+
// in case of undefined or {uri: undefined} source
|
|
43
|
+
// https://github.com/facebook/react-native/issues/9195
|
|
41
44
|
const defaultPlaceHolderImage = React.useMemo(
|
|
42
45
|
() => ({ uri: placeholderImage || "" }),
|
|
43
46
|
[source, error]
|
|
44
47
|
);
|
|
45
48
|
|
|
46
|
-
const _source = shouldRenderImg
|
|
47
|
-
? withDimensions(source)
|
|
48
|
-
: defaultPlaceHolderImage;
|
|
49
|
-
|
|
50
49
|
return (
|
|
51
50
|
// @ts-ignore
|
|
52
51
|
<MemoizedImage
|
|
53
52
|
style={style as ImageStyle}
|
|
54
53
|
onError={() => setErrorState(true)}
|
|
55
|
-
source={
|
|
54
|
+
source={
|
|
55
|
+
shouldRenderImg ? withDimensions(source) : defaultPlaceHolderImage
|
|
56
|
+
}
|
|
56
57
|
{...R.omit(["source"], otherProps)}
|
|
57
58
|
/>
|
|
58
59
|
);
|
|
@@ -31,10 +31,10 @@ function Image({
|
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<RnImage
|
|
34
|
-
defaultSource={placeholderImage ||
|
|
34
|
+
defaultSource={placeholderImage || null}
|
|
35
35
|
style={style}
|
|
36
36
|
source={updatedSource}
|
|
37
|
-
{...R.omit(["source"], otherProps)}
|
|
37
|
+
{...R.omit(["source", "placeholderImage"], otherProps)}
|
|
38
38
|
/>
|
|
39
39
|
);
|
|
40
40
|
}
|
|
@@ -16,13 +16,13 @@ export class MasterCellAsyncRenderManager {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
public emitAsyncElementRegistrate = () => {
|
|
19
|
-
this.asyncElementRegistrate$.next();
|
|
19
|
+
this.asyncElementRegistrate$.next(null);
|
|
20
20
|
|
|
21
21
|
return this.decrementAsyncElementRegistrationCount;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
public emitAsyncElementLayout = () => {
|
|
25
|
-
this.asyncElementLayout$.next();
|
|
25
|
+
this.asyncElementLayout$.next(null);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
public decrementAsyncElementRegistrationCount = () => {
|
|
@@ -53,10 +53,9 @@ function resolveColorForProp(entry, style, colorProp) {
|
|
|
53
53
|
const colorFromProp = style[colorProp];
|
|
54
54
|
const nestedEntryValue = R.path(colorFromProp.split("."), entry);
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
) {
|
|
56
|
+
const color = colorFromProp.replace(".00", "").replace(".0", ""); // https://github.com/dreamyguy/validate-color/issues/44
|
|
57
|
+
|
|
58
|
+
if (nestedEntryValue === undefined && !validateColor(color)) {
|
|
60
59
|
logWarning(colorFromProp, style, entry, nestedEntryValue);
|
|
61
60
|
}
|
|
62
61
|
|
|
@@ -362,13 +362,15 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
362
362
|
const toggleFullscreen = (event) => {
|
|
363
363
|
const { fullscreen = false } = event || {};
|
|
364
364
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
365
|
+
setTimeout(() => {
|
|
366
|
+
if (fullscreen) {
|
|
367
|
+
navigator.fullscreenVideoModal();
|
|
368
|
+
playerEvent("onFullscreenPlayerWillPresent");
|
|
369
|
+
} else {
|
|
370
|
+
navigator.maximiseVideoModal();
|
|
371
|
+
playerEvent("onFullscreenPlayerWillDismiss");
|
|
372
|
+
}
|
|
373
|
+
});
|
|
372
374
|
};
|
|
373
375
|
|
|
374
376
|
const onCellTap = (entry) => {
|
|
@@ -463,6 +465,10 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
463
465
|
|
|
464
466
|
if (mode === VideoModalMode.FULLSCREEN) {
|
|
465
467
|
toggleFullscreen({ fullscreen: false });
|
|
468
|
+
|
|
469
|
+
if (!isModal) {
|
|
470
|
+
playerManager.closeNativePlayer();
|
|
471
|
+
}
|
|
466
472
|
}
|
|
467
473
|
|
|
468
474
|
return !!(
|
|
@@ -519,7 +525,7 @@ const PlayerContainerComponent = (props: Props) => {
|
|
|
519
525
|
}
|
|
520
526
|
|
|
521
527
|
return () => {
|
|
522
|
-
playerEvent("player_did_close");
|
|
528
|
+
playerEvent("player_did_close", { item });
|
|
523
529
|
|
|
524
530
|
if (!isModal) {
|
|
525
531
|
showNavBar(true);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import { update, compose, tail, append, take, identity } from "ramda";
|
|
3
|
+
import { update, compose, tail, append, take, identity, isNil } from "ramda";
|
|
4
4
|
|
|
5
5
|
import { AnimationManager } from "./AnimationManager";
|
|
6
6
|
import { Scene } from "./Scene";
|
|
@@ -50,6 +50,10 @@ function scenesForBackTransition(props: SceneProps, { scenes }) {
|
|
|
50
50
|
: [prepareScene(props.children), scenes[0]];
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
const isModalClosed = (navigator) => {
|
|
54
|
+
return !!isNil(navigator?.modalData);
|
|
55
|
+
};
|
|
56
|
+
|
|
53
57
|
type Props = {
|
|
54
58
|
transitionConfig: any;
|
|
55
59
|
children: React.ReactNode;
|
|
@@ -313,7 +317,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
313
317
|
<Scene
|
|
314
318
|
key={scenes[from.index].key}
|
|
315
319
|
pathname={scenes[from.index].key}
|
|
316
|
-
isActive={
|
|
320
|
+
isActive={
|
|
321
|
+
scenes[from.index].key === this.props.navigator.currentRoute &&
|
|
322
|
+
isModalClosed(this.props.navigator)
|
|
323
|
+
}
|
|
317
324
|
style={from.style}
|
|
318
325
|
pointerEvents="none"
|
|
319
326
|
overlayStyle={from.overlayStyle}
|
|
@@ -329,7 +336,10 @@ export class TransitionerComponent extends React.PureComponent<Props, State> {
|
|
|
329
336
|
const toScene = scenes[to.index] && (
|
|
330
337
|
<Scene
|
|
331
338
|
pathname={scenes[to.index].key}
|
|
332
|
-
isActive={
|
|
339
|
+
isActive={
|
|
340
|
+
scenes[to.index].key === this.props.navigator.currentRoute &&
|
|
341
|
+
isModalClosed(this.props.navigator)
|
|
342
|
+
}
|
|
333
343
|
key={scenes[to.index].key}
|
|
334
344
|
style={to.style}
|
|
335
345
|
overlayStyle={to.overlayStyle}
|
|
@@ -45,15 +45,9 @@ export const AnimatedPlayerModalWrapper = (props: Props) => {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
React.useEffect(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
setStartComponentsAnimation(true);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
return () => {
|
|
55
|
-
translateYListener && translateY.removeListener(translateYListener);
|
|
56
|
-
};
|
|
48
|
+
(playerAnimationState === PlayerAnimationStateEnum.minimize ||
|
|
49
|
+
playerAnimationState === PlayerAnimationStateEnum.maximaze) &&
|
|
50
|
+
setStartComponentsAnimation(true);
|
|
57
51
|
}, [playerAnimationState]);
|
|
58
52
|
|
|
59
53
|
return (
|
|
@@ -66,9 +66,10 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
66
66
|
const { maximiseVideoModal, minimiseVideoModal, videoModalState } =
|
|
67
67
|
useNavigation();
|
|
68
68
|
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const
|
|
69
|
+
const { mode: videoModalMode, item: videoModalItem } = videoModalState;
|
|
70
|
+
const isMaximazedModal = videoModalMode === "MAXIMIZED";
|
|
71
|
+
const isMinimizedModal = videoModalMode === "MINIMIZED";
|
|
72
|
+
const previousItemId = usePrevious(videoModalItem?.id);
|
|
72
73
|
|
|
73
74
|
const isNotMinimizeMaximazeAnimation =
|
|
74
75
|
playerAnimationState !== PlayerAnimationStateEnum.minimize &&
|
|
@@ -81,9 +82,9 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
81
82
|
|
|
82
83
|
const isAudioItem = React.useMemo(
|
|
83
84
|
() =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
[
|
|
85
|
+
videoModalItem?.content?.type?.includes?.("audio") ||
|
|
86
|
+
videoModalItem?.type?.value === "audio",
|
|
87
|
+
[videoModalItem]
|
|
87
88
|
);
|
|
88
89
|
|
|
89
90
|
// Refs for components
|
|
@@ -114,7 +115,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
114
115
|
const preparedTranslationY =
|
|
115
116
|
Math.abs(translationY) - lastScrollYValue.current;
|
|
116
117
|
|
|
117
|
-
if (
|
|
118
|
+
if (videoModalMode === "MAXIMIZED") {
|
|
118
119
|
const endOffsetY =
|
|
119
120
|
lastSnap + preparedTranslationY + dragToss * velocityY + 150;
|
|
120
121
|
|
|
@@ -161,7 +162,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
161
162
|
resetPlayerAnimationState();
|
|
162
163
|
}
|
|
163
164
|
},
|
|
164
|
-
[lastSnap, modalSnapPoints, playerAnimationState,
|
|
165
|
+
[lastSnap, modalSnapPoints, playerAnimationState, videoModalMode]
|
|
165
166
|
);
|
|
166
167
|
|
|
167
168
|
const onScroll = React.useCallback(({ nativeEvent }) => {
|
|
@@ -196,10 +197,9 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
196
197
|
}, []);
|
|
197
198
|
|
|
198
199
|
React.useEffect(() => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
) {
|
|
200
|
+
const { mode, previousMode, item } = videoModalState;
|
|
201
|
+
|
|
202
|
+
if (mode === "MINIMIZED" && previousMode === "MAXIMIZED") {
|
|
203
203
|
// set animation to the minimize values if moving from the player to another screen
|
|
204
204
|
if (playerAnimationState === null) {
|
|
205
205
|
setScrollModalAnimatedValue(
|
|
@@ -214,21 +214,17 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
214
214
|
dragScrollY,
|
|
215
215
|
dragVideoPlayerY
|
|
216
216
|
);
|
|
217
|
-
} else {
|
|
218
|
-
resetPlayerAnimationState();
|
|
219
217
|
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
previousItemId
|
|
226
|
-
previousItemId !== videoModalState.item?.id
|
|
218
|
+
} else if (
|
|
219
|
+
playerAnimationState === null &&
|
|
220
|
+
((previousItemId === item?.id &&
|
|
221
|
+
mode === "MAXIMIZED" &&
|
|
222
|
+
(previousMode === "MINIMIZED" || previousMode === "MAXIMIZED")) ||
|
|
223
|
+
(previousItemId !== item?.id && mode !== "FULLSCREEN"))
|
|
227
224
|
) {
|
|
228
225
|
setPlayerAnimationState(PlayerAnimationStateEnum.maximaze);
|
|
229
|
-
setTimeout(() => resetPlayerAnimationState());
|
|
230
226
|
}
|
|
231
|
-
}, [videoModalState
|
|
227
|
+
}, [videoModalState]);
|
|
232
228
|
|
|
233
229
|
React.useEffect(() => {
|
|
234
230
|
if (playerAnimationState === PlayerAnimationStateEnum.minimize) {
|
|
@@ -253,22 +249,22 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
253
249
|
translateYOffset,
|
|
254
250
|
getAnimatedConfig(modalSnapPoints[1])
|
|
255
251
|
).start(() => {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
252
|
+
minimiseVideoModal();
|
|
253
|
+
|
|
254
|
+
setScrollModalAnimatedValue(
|
|
255
|
+
translateYOffset,
|
|
256
|
+
modalSnapPoints[1],
|
|
257
|
+
setLastSnap
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
resetScrollAnimatedValues(
|
|
261
|
+
lastScrollY,
|
|
262
|
+
lastScrollYValue,
|
|
263
|
+
dragScrollY,
|
|
264
|
+
dragVideoPlayerY
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
resetPlayerAnimationState();
|
|
272
268
|
});
|
|
273
269
|
} else if (playerAnimationState === PlayerAnimationStateEnum.maximaze) {
|
|
274
270
|
Animated.timing(translateYOffset, getAnimatedConfig(0)).start(() => {
|
|
@@ -285,7 +281,9 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
285
281
|
resetPlayerAnimationState();
|
|
286
282
|
});
|
|
287
283
|
}
|
|
284
|
+
}, [playerAnimationState]);
|
|
288
285
|
|
|
286
|
+
React.useEffect(() => {
|
|
289
287
|
const lastScrollYListenerId = lastScrollY.addListener(({ value }) => {
|
|
290
288
|
lastScrollYValue.current = value;
|
|
291
289
|
});
|
|
@@ -311,7 +309,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
|
|
|
311
309
|
lastScrollY.removeListener(lastScrollYListenerId);
|
|
312
310
|
dragScrollY.removeListener(dragListenerId);
|
|
313
311
|
};
|
|
314
|
-
}, [playerAnimationState, isAudioItem,
|
|
312
|
+
}, [playerAnimationState, isAudioItem, isMinimizedModal]);
|
|
315
313
|
|
|
316
314
|
const Wrapper = React.useMemo(
|
|
317
315
|
() => (Platform.OS === "android" ? GestureHandlerRootView : View),
|