@applicaster/zapp-react-native-ui-components 13.0.0-alpha.2761483533 → 13.0.0-alpha.3013227535
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/BaseFocusable/index.ios.ts +1 -1
- package/Components/BaseFocusable/index.tsx +1 -1
- package/Components/Focusable/Touchable.tsx +19 -20
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -11
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/utils/index.ts +1 -1
- package/Components/Screen/index.tsx +1 -0
- package/Components/Tabs/Tab.tsx +6 -6
- package/Components/TextInputTv/index.tsx +2 -2
- package/Components/Transitioner/AnimationManager.js +8 -8
- package/Components/Transitioner/Scene.tsx +52 -23
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +59 -43
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
- package/Components/Transitioner/index.js +8 -4
- package/Components/VideoLive/LiveImageManager.ts +27 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +11 -5
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +7 -6
- package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
- package/Contexts/ScreenContext/index.tsx +3 -2
- package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
- package/package.json +5 -5
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
type Props =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
} & Partial<ParentFocus>;
|
|
3
|
+
type Props = {
|
|
4
|
+
id: string;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
onPress?: (ref: FocusManager.TouchableRef) => void;
|
|
7
|
+
onPressIn?: (ref: FocusManager.TouchableRef) => void;
|
|
8
|
+
onPressOut?: (ref: FocusManager.TouchableRef) => void;
|
|
9
|
+
onLongPress?: (ref: FocusManager.TouchableRef) => void;
|
|
10
|
+
onFocus?: (
|
|
11
|
+
ref: FocusManager.TouchableRef,
|
|
12
|
+
options: FocusManager.Android.CallbackOptions
|
|
13
|
+
) => void;
|
|
14
|
+
onBlur?: (
|
|
15
|
+
ref: FocusManager.TouchableRef,
|
|
16
|
+
options: FocusManager.Android.CallbackOptions
|
|
17
|
+
) => void;
|
|
18
|
+
|
|
19
|
+
disableFocus?: boolean;
|
|
20
|
+
blockFocus?: boolean;
|
|
21
|
+
} & Partial<ParentFocus>;
|
|
23
22
|
|
|
24
23
|
export class Touchable extends React.Component<Props> {
|
|
25
24
|
onPress(focusableRef: FocusManager.TouchableRef): void {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BorderContainerView,
|
|
3
|
+
getBorderPadding, // Export for testing (using a double underscore prefix is a common convention)
|
|
4
|
+
} from "../index";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { render } from "@testing-library/react-native";
|
|
7
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
8
|
+
import { View } from "react-native";
|
|
9
|
+
|
|
10
|
+
jest.mock("@applicaster/zapp-react-native-utils/numberUtils", () => ({
|
|
11
|
+
toNumberWithDefaultZero: jest.fn((value) => Number(value) || 0),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
describe("BorderContainerView", () => {
|
|
15
|
+
describe("getBorderPadding", () => {
|
|
16
|
+
it("returns 0 for inside", () => {
|
|
17
|
+
expect(getBorderPadding("inside", 10)).toBe(0);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("returns borderWidth / 2 for center", () => {
|
|
21
|
+
expect(getBorderPadding("center", 10)).toBe(5);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("returns borderWidth for outside", () => {
|
|
25
|
+
expect(getBorderPadding("outside", 10)).toBe(10);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("returns borderWidth for invalid position", () => {
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
expect(getBorderPadding("other_value", 10)).toBe(10);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("Border component renders null if no borderPosition", () => {
|
|
35
|
+
const style = { borderWidth: 5, borderRadius: 10, borderColor: "red" };
|
|
36
|
+
|
|
37
|
+
const padding = {
|
|
38
|
+
paddingTop: 2,
|
|
39
|
+
paddingRight: 3,
|
|
40
|
+
paddingBottom: 4,
|
|
41
|
+
paddingLeft: 5,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const borderPosition = null;
|
|
45
|
+
|
|
46
|
+
const { queryByTestId } = render(
|
|
47
|
+
<BorderContainerView
|
|
48
|
+
style={style}
|
|
49
|
+
testID="border-container"
|
|
50
|
+
borderPosition={borderPosition}
|
|
51
|
+
borderPaddingTop={toNumberWithDefaultZero(padding.paddingTop)}
|
|
52
|
+
borderPaddingRight={toNumberWithDefaultZero(padding.paddingRight)}
|
|
53
|
+
borderPaddingBottom={toNumberWithDefaultZero(padding.paddingBottom)}
|
|
54
|
+
borderPaddingLeft={toNumberWithDefaultZero(padding.paddingLeft)}
|
|
55
|
+
>
|
|
56
|
+
<View testID="child" />
|
|
57
|
+
</BorderContainerView>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const children = queryByTestId("border-container").children;
|
|
61
|
+
|
|
62
|
+
expect(children[1].props.testID).toBe("child");
|
|
63
|
+
|
|
64
|
+
expect(children[0].children.length).toBe(0);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -28,7 +28,10 @@ const styles = StyleSheet.create({
|
|
|
28
28
|
},
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
const getBorderPadding = (
|
|
31
|
+
export const getBorderPadding = (
|
|
32
|
+
borderPosition: BorderPosition,
|
|
33
|
+
borderWidth: number
|
|
34
|
+
) => {
|
|
32
35
|
switch (borderPosition) {
|
|
33
36
|
case "inside":
|
|
34
37
|
return 0;
|
|
@@ -38,22 +38,16 @@ function Image({
|
|
|
38
38
|
|
|
39
39
|
const shouldRenderImg = source && !error;
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const defaultPlaceHolderImage = React.useMemo(
|
|
45
|
-
() => ({ uri: placeholderImage || "" }),
|
|
46
|
-
[source, error]
|
|
47
|
-
);
|
|
41
|
+
const _source = shouldRenderImg
|
|
42
|
+
? withDimensions(source)
|
|
43
|
+
: { uri: placeholderImage };
|
|
48
44
|
|
|
49
45
|
return (
|
|
50
|
-
// @ts-ignore
|
|
51
46
|
<MemoizedImage
|
|
52
47
|
style={style as ImageStyle}
|
|
53
48
|
onError={React.useCallback(() => setErrorState(true), [])}
|
|
54
|
-
source
|
|
55
|
-
|
|
56
|
-
}
|
|
49
|
+
// as we have defaults as "" for placeholder image, we need to pass undefined to source to not throw warnings
|
|
50
|
+
source={_source?.uri ? _source : undefined}
|
|
57
51
|
{...R.omit(["source"], otherProps)}
|
|
58
52
|
/>
|
|
59
53
|
);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ImageBorderContainer } from "../index";
|
|
2
|
+
import { getImageContainerMarginStyles } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
3
|
+
|
|
4
|
+
const mockValue = (key) => {
|
|
5
|
+
const values = {
|
|
6
|
+
cell_padding_top: 1,
|
|
7
|
+
cell_padding_left: 2,
|
|
8
|
+
cell_padding_right: 3,
|
|
9
|
+
cell_padding_bottom: 4,
|
|
10
|
+
image_border_size: 5,
|
|
11
|
+
image_focused_border_color: "red",
|
|
12
|
+
image_selected_border_color: "blue",
|
|
13
|
+
image_focused_selected_border_color: "green",
|
|
14
|
+
image_border_color: "black",
|
|
15
|
+
image_corner_radius: 10,
|
|
16
|
+
image_border_position: "outside",
|
|
17
|
+
image_border_padding_top: 6,
|
|
18
|
+
image_border_padding_right: 7,
|
|
19
|
+
image_border_padding_bottom: 8,
|
|
20
|
+
image_border_padding_left: 9,
|
|
21
|
+
image_margin_top: 11,
|
|
22
|
+
image_margin_left: 12,
|
|
23
|
+
image_margin_right: 13,
|
|
24
|
+
image_margin_bottom: 14,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return values[key] || 0;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
describe("ImageBorderContainer", () => {
|
|
31
|
+
it("calculates style properties correctly", () => {
|
|
32
|
+
const marginStyles = getImageContainerMarginStyles({ value: mockValue });
|
|
33
|
+
|
|
34
|
+
expect(marginStyles.marginTop).toBe(11);
|
|
35
|
+
expect(marginStyles.marginLeft).toBe(12);
|
|
36
|
+
expect(marginStyles.marginRight).toBe(13);
|
|
37
|
+
expect(marginStyles.marginBottom).toBe(14);
|
|
38
|
+
|
|
39
|
+
const props = {
|
|
40
|
+
value: mockValue,
|
|
41
|
+
state: "default",
|
|
42
|
+
imageStyles: {},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = ImageBorderContainer(props);
|
|
46
|
+
|
|
47
|
+
expect(result.style.marginTop).toBe(12); // 11 + 1
|
|
48
|
+
expect(result.style.marginLeft).toBe(14); // 12 + 2
|
|
49
|
+
expect(result.style.marginRight).toBe(16); // 13 + 3
|
|
50
|
+
expect(result.style.marginBottom).toBe(18); // 14 + 4
|
|
51
|
+
expect(result.style.borderWidth).toBe(5);
|
|
52
|
+
expect(result.style.borderColor).toBe("black");
|
|
53
|
+
expect(result.style.borderRadius).toBe(10);
|
|
54
|
+
expect(result.additionalProps.borderPosition).toBe("outside");
|
|
55
|
+
expect(result.additionalProps.borderPaddingTop).toBe(6);
|
|
56
|
+
expect(result.additionalProps.borderPaddingRight).toBe(7);
|
|
57
|
+
expect(result.additionalProps.borderPaddingBottom).toBe(8);
|
|
58
|
+
expect(result.additionalProps.borderPaddingLeft).toBe(9);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("handles focused state correctly", () => {
|
|
62
|
+
const props = {
|
|
63
|
+
value: mockValue,
|
|
64
|
+
state: "focused",
|
|
65
|
+
imageStyles: {},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const result = ImageBorderContainer(props);
|
|
69
|
+
expect(result.style.borderColor).toBe("red");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("handles selected state correctly", () => {
|
|
73
|
+
const props = {
|
|
74
|
+
value: mockValue,
|
|
75
|
+
state: "selected",
|
|
76
|
+
imageStyles: {},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const result = ImageBorderContainer(props);
|
|
80
|
+
expect(result.style.borderColor).toBe("blue");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("handles focused and selected state correctly", () => {
|
|
84
|
+
const props = {
|
|
85
|
+
value: mockValue,
|
|
86
|
+
state: "focused_selected",
|
|
87
|
+
imageStyles: {},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const result = ImageBorderContainer(props);
|
|
91
|
+
expect(result.style.borderColor).toBe("green");
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -17,7 +17,7 @@ const SECONDARY_IMAGE_PREFIX = "secondary_image";
|
|
|
17
17
|
|
|
18
18
|
type ImageSizing = typeof IMAGE_SIZING_FIT | typeof IMAGE_SIZING_FILL;
|
|
19
19
|
|
|
20
|
-
type ImagePosition = typeof IMAGE_POSITION[keyof typeof IMAGE_POSITION];
|
|
20
|
+
type ImagePosition = (typeof IMAGE_POSITION)[keyof typeof IMAGE_POSITION];
|
|
21
21
|
|
|
22
22
|
export type DisplayMode =
|
|
23
23
|
| typeof DISPLAY_MODE_FIXED
|
package/Components/Tabs/Tab.tsx
CHANGED
|
@@ -69,8 +69,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
69
69
|
? tab_cell_background_color_selected_active
|
|
70
70
|
: tab_cell_background_color_selected_default
|
|
71
71
|
: focused
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
? tab_cell_background_color_active
|
|
73
|
+
: tab_cell_background_color_default,
|
|
74
74
|
justifyContent: "center",
|
|
75
75
|
alignItems: "center",
|
|
76
76
|
position: "relative",
|
|
@@ -85,8 +85,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
85
85
|
? tab_cell_border_color_active_focused
|
|
86
86
|
: tab_cell_border_color_active
|
|
87
87
|
: focused
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
? tab_cell_border_color_default_focused
|
|
89
|
+
: tab_cell_border_color_default,
|
|
90
90
|
},
|
|
91
91
|
label: {
|
|
92
92
|
fontFamily: text_label_font_family,
|
|
@@ -98,8 +98,8 @@ const getStyles = (configuration, selected, focused) => {
|
|
|
98
98
|
? text_label_selected_active_font_color
|
|
99
99
|
: text_label_selected_default_font_color
|
|
100
100
|
: focused
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
? text_label_active_font_color
|
|
102
|
+
: text_label_default_font_color,
|
|
103
103
|
},
|
|
104
104
|
underline: {
|
|
105
105
|
position: "absolute",
|
|
@@ -3,19 +3,19 @@ import { Animated } from "react-native";
|
|
|
3
3
|
import { NAV_ACTION_PUSH, NAV_ACTION_BACK } from "./Transitioner";
|
|
4
4
|
|
|
5
5
|
type TransitionConfig = {
|
|
6
|
-
duration: number
|
|
7
|
-
easing: any
|
|
6
|
+
duration: number;
|
|
7
|
+
easing: any;
|
|
8
8
|
from: {
|
|
9
|
-
style: any
|
|
10
|
-
}
|
|
9
|
+
style: any;
|
|
10
|
+
};
|
|
11
11
|
to: {
|
|
12
|
-
style: any
|
|
13
|
-
}
|
|
12
|
+
style: any;
|
|
13
|
+
};
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
type Props = {
|
|
17
|
-
transitionConfig: TransitionConfig
|
|
18
|
-
contentStyle: { [string]: any }
|
|
17
|
+
transitionConfig: TransitionConfig;
|
|
18
|
+
contentStyle: { [string]: any };
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { equals } from "ramda";
|
|
2
3
|
import { Animated, ViewProps, ViewStyle } from "react-native";
|
|
3
4
|
import { useSafeAreaFrame } from "react-native-safe-area-context";
|
|
4
5
|
|
|
@@ -8,6 +9,11 @@ import { PathnameContext } from "../../Contexts/PathnameContext";
|
|
|
8
9
|
import { ScreenDataContext } from "../../Contexts/ScreenDataContext";
|
|
9
10
|
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
|
|
10
11
|
|
|
12
|
+
const fullWidthDimensions = {
|
|
13
|
+
height: "100%",
|
|
14
|
+
width: "100%",
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
type Props = {
|
|
12
18
|
children: any;
|
|
13
19
|
style: any;
|
|
@@ -20,6 +26,47 @@ type Props = {
|
|
|
20
26
|
screenData: NavigationScreenData;
|
|
21
27
|
};
|
|
22
28
|
|
|
29
|
+
export function CurrentScreenContextProvider({
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: {
|
|
33
|
+
children: any;
|
|
34
|
+
pathname: string;
|
|
35
|
+
isActive: boolean;
|
|
36
|
+
screenData: NavigationScreenData;
|
|
37
|
+
}) {
|
|
38
|
+
const { pathname, isActive = false, screenData } = props;
|
|
39
|
+
|
|
40
|
+
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
41
|
+
|
|
42
|
+
React.useLayoutEffect(() => {
|
|
43
|
+
const screenDataChanged = !equals(initialScreenData, screenData);
|
|
44
|
+
|
|
45
|
+
if (isActive && screenDataChanged) {
|
|
46
|
+
setInitialScreenData(screenData);
|
|
47
|
+
}
|
|
48
|
+
}, [initialScreenData, screenData, isActive]);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<ScreenDataContext.Provider value={initialScreenData}>
|
|
52
|
+
<PathnameContext.Provider value={pathname}>
|
|
53
|
+
<ScreenContextProvider pathname={pathname}>
|
|
54
|
+
{children}
|
|
55
|
+
</ScreenContextProvider>
|
|
56
|
+
</PathnameContext.Provider>
|
|
57
|
+
</ScreenDataContext.Provider>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const withCurrentScreenContext = (Component) =>
|
|
62
|
+
function SceneComponent(props: Props) {
|
|
63
|
+
return (
|
|
64
|
+
<CurrentScreenContextProvider {...props}>
|
|
65
|
+
<Component {...props} />
|
|
66
|
+
</CurrentScreenContextProvider>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
23
70
|
/**
|
|
24
71
|
* Animated View container for any purpose.
|
|
25
72
|
* Renders given children with given style object.
|
|
@@ -32,53 +79,35 @@ type Props = {
|
|
|
32
79
|
* @param contentStyle
|
|
33
80
|
* @param screenUniqueId
|
|
34
81
|
*/
|
|
35
|
-
|
|
82
|
+
function SceneComponent({
|
|
36
83
|
children,
|
|
37
84
|
style,
|
|
38
85
|
pointerEvents = "auto",
|
|
39
86
|
overlayStyle,
|
|
40
87
|
animating,
|
|
41
88
|
contentStyle,
|
|
42
|
-
pathname,
|
|
43
89
|
isActive = false,
|
|
44
90
|
screenData,
|
|
45
91
|
}: Props) {
|
|
46
|
-
const [initialScreenData, setInitialScreenData] = React.useState(screenData);
|
|
47
|
-
|
|
48
92
|
useScreenOrientationHandler({
|
|
49
93
|
screenData,
|
|
50
94
|
isActive,
|
|
51
95
|
});
|
|
52
96
|
|
|
53
|
-
React.useLayoutEffect(() => {
|
|
54
|
-
if (isActive) {
|
|
55
|
-
setInitialScreenData(screenData);
|
|
56
|
-
}
|
|
57
|
-
}, [screenData, isActive]);
|
|
58
|
-
|
|
59
97
|
const frame = useSafeAreaFrame();
|
|
60
98
|
const isAnimating = animating && overlayStyle;
|
|
61
99
|
|
|
62
|
-
const dimensions = isAnimating
|
|
63
|
-
? {
|
|
64
|
-
width: "100%",
|
|
65
|
-
height: "100%",
|
|
66
|
-
}
|
|
67
|
-
: frame;
|
|
100
|
+
const dimensions = isAnimating ? fullWidthDimensions : frame;
|
|
68
101
|
|
|
69
102
|
return (
|
|
70
103
|
<Animated.View
|
|
71
104
|
pointerEvents={pointerEvents}
|
|
72
105
|
style={[style, contentStyle, dimensions]}
|
|
73
106
|
>
|
|
74
|
-
|
|
75
|
-
<PathnameContext.Provider value={pathname}>
|
|
76
|
-
<ScreenContextProvider pathname={pathname}>
|
|
77
|
-
{children}
|
|
78
|
-
</ScreenContextProvider>
|
|
79
|
-
</PathnameContext.Provider>
|
|
80
|
-
</ScreenDataContext.Provider>
|
|
107
|
+
{children}
|
|
81
108
|
{isAnimating && <Animated.View style={overlayStyle} />}
|
|
82
109
|
</Animated.View>
|
|
83
110
|
);
|
|
84
111
|
}
|
|
112
|
+
|
|
113
|
+
export const Scene = withCurrentScreenContext(SceneComponent);
|
|
@@ -1,63 +1,79 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<Scene /> renders correctly 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
4
|
+
<CurrentScreenContextProvider
|
|
5
|
+
contentStyle={
|
|
6
|
+
{
|
|
7
|
+
"paddingBottom": 49,
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
overlayStyle={
|
|
11
|
+
{
|
|
12
|
+
"opacity": 1,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
6
15
|
style={
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
{
|
|
17
|
+
"flex": 1,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
>
|
|
21
|
+
<SceneComponent
|
|
22
|
+
contentStyle={
|
|
11
23
|
{
|
|
12
24
|
"paddingBottom": 49,
|
|
13
|
-
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
overlayStyle={
|
|
14
28
|
{
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<ContextProvider>
|
|
26
|
-
<ScreenContextProvider />
|
|
27
|
-
</ContextProvider>
|
|
28
|
-
</ContextProvider>
|
|
29
|
-
</ForwardRef(AnimatedComponentWrapper)>
|
|
29
|
+
"opacity": 1,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
style={
|
|
33
|
+
{
|
|
34
|
+
"flex": 1,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
</CurrentScreenContextProvider>
|
|
30
39
|
`;
|
|
31
40
|
|
|
32
41
|
exports[`<Scene /> renders the overlay while animating 1`] = `
|
|
33
|
-
<
|
|
34
|
-
|
|
42
|
+
<CurrentScreenContextProvider
|
|
43
|
+
animating={true}
|
|
44
|
+
contentStyle={
|
|
45
|
+
{
|
|
46
|
+
"paddingBottom": 49,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
overlayStyle={
|
|
50
|
+
{
|
|
51
|
+
"opacity": 1,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
style={
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
55
|
+
{
|
|
56
|
+
"flex": 1,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
>
|
|
60
|
+
<SceneComponent
|
|
61
|
+
animating={true}
|
|
62
|
+
contentStyle={
|
|
40
63
|
{
|
|
41
64
|
"paddingBottom": 49,
|
|
42
|
-
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
overlayStyle={
|
|
43
68
|
{
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
>
|
|
50
|
-
<ContextProvider>
|
|
51
|
-
<ContextProvider>
|
|
52
|
-
<ScreenContextProvider />
|
|
53
|
-
</ContextProvider>
|
|
54
|
-
</ContextProvider>
|
|
55
|
-
<ForwardRef(AnimatedComponentWrapper)
|
|
69
|
+
"opacity": 1,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
56
72
|
style={
|
|
57
73
|
{
|
|
58
|
-
"
|
|
74
|
+
"flex": 1,
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
77
|
/>
|
|
62
|
-
</
|
|
78
|
+
</CurrentScreenContextProvider>
|
|
63
79
|
`;
|
|
@@ -9,7 +9,7 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
>
|
|
12
|
-
<
|
|
12
|
+
<SceneComponent
|
|
13
13
|
isActive={true}
|
|
14
14
|
screenUniqueId="mocked-uuid"
|
|
15
15
|
style={{}}
|
|
@@ -23,6 +23,6 @@ exports[`<TransitionerComponent /> renders correctly 1`] = `
|
|
|
23
23
|
children
|
|
24
24
|
</Text>
|
|
25
25
|
</View>
|
|
26
|
-
</
|
|
26
|
+
</SceneComponent>
|
|
27
27
|
</View>
|
|
28
28
|
`;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { useWindowDimensions } from "react-native";
|
|
3
2
|
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
4
3
|
import { useDimensions } from "@applicaster/zapp-react-native-utils/reactHooks/layout";
|
|
5
4
|
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
|
|
@@ -7,10 +6,15 @@ import { TransitionerComponent } from "./Transitioner";
|
|
|
7
6
|
|
|
8
7
|
export const Transitioner = (props) => {
|
|
9
8
|
const navigator = useNavigation();
|
|
10
|
-
const { height, width } = useWindowDimensions();
|
|
11
9
|
|
|
12
|
-
const
|
|
13
|
-
|
|
10
|
+
const {
|
|
11
|
+
width,
|
|
12
|
+
height,
|
|
13
|
+
deviceInfo: { isTablet },
|
|
14
|
+
} = useDimensions("window", {
|
|
15
|
+
updateForInactiveScreens: false,
|
|
16
|
+
deviceInfo: true,
|
|
17
|
+
});
|
|
14
18
|
|
|
15
19
|
const { appData } = usePickFromState(["appData"]);
|
|
16
20
|
const isTabletPortrait = appData?.isTabletPortrait;
|
|
@@ -8,6 +8,8 @@ import { loggerLiveImageManager } from "./loggerHelper";
|
|
|
8
8
|
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
9
9
|
import { Component } from "react";
|
|
10
10
|
|
|
11
|
+
const TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION = 500; // ms
|
|
12
|
+
|
|
11
13
|
const { log_debug, log_info, log_error } = loggerLiveImageManager;
|
|
12
14
|
|
|
13
15
|
export type LiveImageManagerEvent =
|
|
@@ -62,6 +64,9 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
62
64
|
protected currentlyPlaying: LiveImage | null = null;
|
|
63
65
|
protected primaryPlayer: Player | null = null;
|
|
64
66
|
|
|
67
|
+
private checkPlayerPositionTimeout: ReturnType<typeof setTimeout> | null =
|
|
68
|
+
null;
|
|
69
|
+
|
|
65
70
|
protected listeners: Record<
|
|
66
71
|
string,
|
|
67
72
|
Record<LiveImageManagerEvent, (event?: Record<string, any>) => void>
|
|
@@ -118,6 +123,11 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
118
123
|
});
|
|
119
124
|
};
|
|
120
125
|
|
|
126
|
+
private cancelCheckPlayerPositionTimeout = () => {
|
|
127
|
+
clearTimeout(this.checkPlayerPositionTimeout);
|
|
128
|
+
this.checkPlayerPositionTimeout = null;
|
|
129
|
+
};
|
|
130
|
+
|
|
121
131
|
public onViewportEnter = (item: LiveImage) => {
|
|
122
132
|
log_debug(
|
|
123
133
|
`onViewportEnter: live-image ${playerInfo(
|
|
@@ -125,7 +135,21 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
125
135
|
)}, primary ${playerInfo(this.primaryPlayer)}`
|
|
126
136
|
);
|
|
127
137
|
|
|
128
|
-
|
|
138
|
+
if (!isTV()) {
|
|
139
|
+
// mobile only
|
|
140
|
+
// we have to delay running checkPlayerPosition, because sometimes on fast scrolling we get wrong order onEnter, then onLeave.
|
|
141
|
+
// which could cause select wrong item to play
|
|
142
|
+
|
|
143
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
144
|
+
|
|
145
|
+
this.checkPlayerPositionTimeout = setTimeout(() => {
|
|
146
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
147
|
+
|
|
148
|
+
this.checkPlayerPosition(item);
|
|
149
|
+
}, TIMEOUT_FOR_DELAY_CHECK_PLAYER_POSITION);
|
|
150
|
+
} else {
|
|
151
|
+
this.checkPlayerPosition(item);
|
|
152
|
+
}
|
|
129
153
|
};
|
|
130
154
|
|
|
131
155
|
public onViewportLeave = (item: LiveImage) => {
|
|
@@ -246,6 +270,8 @@ export class LiveImageManager implements PlayerLifecycleListener {
|
|
|
246
270
|
};
|
|
247
271
|
|
|
248
272
|
public checkPlayerPosition = (item: LiveImage) => {
|
|
273
|
+
this.cancelCheckPlayerPositionTimeout();
|
|
274
|
+
|
|
249
275
|
log_debug(
|
|
250
276
|
`checkPlayerPosition: live-image playerId: ${playerInfo(
|
|
251
277
|
item.player
|
|
@@ -44,7 +44,10 @@ type Props = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
const PlayerLiveImageComponent = (props: Props) => {
|
|
47
|
-
const dimensions = useDimensions("screen", {
|
|
47
|
+
const dimensions = useDimensions("screen", {
|
|
48
|
+
fullDimensions: true,
|
|
49
|
+
updateForInactiveScreens: false,
|
|
50
|
+
});
|
|
48
51
|
|
|
49
52
|
const { item, style, playerId } = props;
|
|
50
53
|
|
|
@@ -135,13 +138,16 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
135
138
|
} else {
|
|
136
139
|
throw new Error("Player factory item is null");
|
|
137
140
|
}
|
|
138
|
-
}, [playerId, item, playerPluginId, screenConfig]);
|
|
141
|
+
}, [playerId, item.id, playerPluginId, screenConfig]);
|
|
139
142
|
|
|
140
143
|
React.useEffect(() => {
|
|
141
144
|
liveImageItem.setMode = setModeDebounced;
|
|
142
145
|
}, [setModeDebounced, liveImageItem]);
|
|
143
146
|
|
|
144
|
-
const { start, end } = React.useMemo(
|
|
147
|
+
const { start, end } = React.useMemo(
|
|
148
|
+
() => getAutoplaySettings(item),
|
|
149
|
+
[item.id]
|
|
150
|
+
);
|
|
145
151
|
|
|
146
152
|
const controller = liveImageItem.getPlayer();
|
|
147
153
|
const player = usePlayer(playerId);
|
|
@@ -174,7 +180,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
174
180
|
|
|
175
181
|
unregister();
|
|
176
182
|
};
|
|
177
|
-
}, [item, liveImageItem]);
|
|
183
|
+
}, [item.id, liveImageItem]);
|
|
178
184
|
|
|
179
185
|
React.useEffect(() => {
|
|
180
186
|
if (!player) {
|
|
@@ -304,7 +310,7 @@ const PlayerLiveImageComponent = (props: Props) => {
|
|
|
304
310
|
LiveImageManager.instance.checkPlayerPosition(liveImageItem);
|
|
305
311
|
}
|
|
306
312
|
},
|
|
307
|
-
[liveImageItem, dimensions]
|
|
313
|
+
[liveImageItem, dimensions.height, dimensions.width]
|
|
308
314
|
);
|
|
309
315
|
|
|
310
316
|
const platformSpecificProps = isApplePlatform()
|
|
@@ -100,10 +100,11 @@ export const AnimationView = ({
|
|
|
100
100
|
const moveUpValue = additionalData.saveArea
|
|
101
101
|
? -insets.top + (isAudioItem ? 0 : progressBarHeight)
|
|
102
102
|
: isTablet
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
? isTabletLandscape &&
|
|
104
|
+
(!isAudioItem || (isAudioItem && inlineAudioPlayer))
|
|
105
|
+
? -tabletLandscapePlayerTopPosition + progressBarHeight
|
|
106
|
+
: -130
|
|
107
|
+
: -50 + progressBarHeight;
|
|
107
108
|
|
|
108
109
|
const moveComponentHorizontalValue = additionalData.moveValue
|
|
109
110
|
? isRTL
|
|
@@ -434,8 +435,8 @@ export const AnimationComponent = (props: Props) => {
|
|
|
434
435
|
const Component = useAnimation
|
|
435
436
|
? AnimationView
|
|
436
437
|
: style
|
|
437
|
-
|
|
438
|
-
|
|
438
|
+
? View
|
|
439
|
+
: React.Fragment;
|
|
439
440
|
|
|
440
441
|
if (
|
|
441
442
|
additionalData.extraAnimation &&
|
|
@@ -108,8 +108,8 @@ export const calculateAnimationValue = (animationType, dragPosition, data) => {
|
|
|
108
108
|
: { forWidth: 3, forHeight: 3 }
|
|
109
109
|
: { forWidth: 2, forHeight: 2 }
|
|
110
110
|
: isTabletLandscape
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
? { forWidth: 8, forHeight: 6.5 }
|
|
112
|
+
: { forWidth: 3.5, forHeight: 2 };
|
|
113
113
|
|
|
114
114
|
const minWidth =
|
|
115
115
|
isAudioItem && !inlineAudioPlayer ? minimisedHeight : minimisedWidth;
|
|
@@ -99,8 +99,9 @@ export function ScreenContextProvider({
|
|
|
99
99
|
const isNested = useNestedNavigationContext();
|
|
100
100
|
const currentScreenScreenData = useCurrentScreenData();
|
|
101
101
|
|
|
102
|
-
const screenNavBarStateRef =
|
|
103
|
-
|
|
102
|
+
const screenNavBarStateRef = useRef<null | ReturnType<typeof createStore>>(
|
|
103
|
+
null
|
|
104
|
+
);
|
|
104
105
|
|
|
105
106
|
const getScreenNavBarState = useCallback(() => {
|
|
106
107
|
if (screenNavBarStateRef.current !== null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.3013227535",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"redux-mock-store": "^1.5.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@applicaster/applicaster-types": "13.0.0-alpha.
|
|
38
|
-
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.
|
|
39
|
-
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.
|
|
40
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.
|
|
37
|
+
"@applicaster/applicaster-types": "13.0.0-alpha.3013227535",
|
|
38
|
+
"@applicaster/zapp-react-native-bridge": "13.0.0-alpha.3013227535",
|
|
39
|
+
"@applicaster/zapp-react-native-redux": "13.0.0-alpha.3013227535",
|
|
40
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-alpha.3013227535",
|
|
41
41
|
"promise": "^8.3.0",
|
|
42
42
|
"react-router-native": "^5.1.2",
|
|
43
43
|
"url": "^0.11.0",
|