@applicaster/zapp-react-native-ui-components 16.0.0-rc.11 → 16.0.0-rc.110
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/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/CellRendererResolver/index.ts +2 -2
- package/Components/ComponentResolver/__tests__/componentResolver.test.js +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +11 -7
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +54 -0
- package/Components/GeneralContentScreen/__tests__/GeneralContentScreenHookAdapter.test.tsx +64 -0
- package/Components/GeneralContentScreen/__tests__/HookContentFocusGroup.web.test.tsx +91 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/networkService.test.ts +74 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/runInBackground.test.ts +139 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +188 -0
- package/Components/GeneralContentScreen/hookAdapter/logger.ts +6 -0
- package/Components/GeneralContentScreen/hookAdapter/networkService.ts +53 -0
- package/Components/GeneralContentScreen/hookAdapter/runInBackground.ts +48 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +90 -0
- package/Components/GeneralContentScreen/hookFocus/index.tsx +13 -0
- package/Components/GeneralContentScreen/hookFocus/index.web.tsx +69 -0
- package/Components/GeneralContentScreen/index.ts +2 -0
- package/Components/Layout/FullWidthRow.tsx +38 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +47 -21
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +34 -6
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +29 -9
- package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +4 -0
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +154 -100
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +56 -22
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +6 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +3 -1
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +32 -21
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +23 -16
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +8 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +45 -13
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/contexts/PressedStateContext.ts +3 -0
- package/Components/MasterCell/dataAdapter.ts +15 -5
- package/Components/MasterCell/hooks/index.ts +2 -0
- package/Components/MasterCell/hooks/usePressedState.ts +4 -0
- package/Components/MasterCell/index.tsx +30 -5
- package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
- package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
- package/Components/MasterCell/utils/index.ts +85 -46
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +392 -0
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +772 -0
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +728 -0
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +1028 -0
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +164 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +9 -0
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +393 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +523 -0
- package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +436 -50
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +52 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
- package/Components/OfflineHandler/__tests__/index.test.tsx +186 -17
- package/Components/OfflineHandler/hooks.ts +111 -0
- package/Components/OfflineHandler/index.tsx +91 -75
- package/Components/OfflineHandler/utils/index.ts +1 -13
- package/Components/PlayerContainer/PlayerContainer.tsx +33 -18
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +337 -0
- package/Components/PreloaderWrapper/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +87 -61
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +140 -89
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +13 -4
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
- package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/TopCutoffOverlay/index.tsx +2 -2
- package/Components/Transitioner/AnimationManager.js +1 -1
- package/Components/Transitioner/Scene.tsx +4 -3
- package/Components/Transitioner/Transitioner.tsx +98 -49
- package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Components/VideoModal/utils.ts +6 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +12 -5
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
- package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
- package/Contexts/CachedDimensionsContext/index.ts +17 -2
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Helpers/ComponentCellSelectionHelper/index.js +0 -6
- package/Helpers/index.js +0 -39
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
- package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -66
- package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
- package/Components/Screen/utils.ts +0 -16
- package/Helpers/Analytics/index.js +0 -95
- /package/Components/BackgroundImage/{BackgroundImage.tv.android.tsx → BackgroundImage.android.tv.tsx} +0 -0
- /package/Components/BackgroundImage/{BackgroundImage.tv.ios.tsx → BackgroundImage.ios.tv.tsx} +0 -0
- /package/Components/MasterCell/DefaultComponents/ButtonContainerView/{index.tv.android.tsx → index.android.tv.tsx} +0 -0
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { renderHook, act } from "@testing-library/react-native";
|
|
2
|
+
|
|
3
|
+
type DimensionsStore = {
|
|
4
|
+
setState: (
|
|
5
|
+
partial: { dimensions: Record<string, unknown>; ids: string[] },
|
|
6
|
+
replace?: boolean
|
|
7
|
+
) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const createdStores: DimensionsStore[] = [];
|
|
11
|
+
|
|
12
|
+
jest.mock("zustand", () => {
|
|
13
|
+
const actual = jest.requireActual<typeof import("zustand")>("zustand");
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...actual,
|
|
17
|
+
create: ((initializer: Parameters<typeof actual.create>[0]) => {
|
|
18
|
+
const store = actual.create(initializer);
|
|
19
|
+
createdStores.push(store);
|
|
20
|
+
|
|
21
|
+
return store;
|
|
22
|
+
}) as typeof actual.create,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
import { useCachedDimensions } from "../index";
|
|
27
|
+
|
|
28
|
+
const resetStore = () => {
|
|
29
|
+
const store = createdStores[createdStores.length - 1];
|
|
30
|
+
|
|
31
|
+
act(() => {
|
|
32
|
+
store?.setState({ dimensions: {}, ids: [] });
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
describe("useCachedDimensions", () => {
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
resetStore();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("getCachedDimensions", () => {
|
|
42
|
+
it("returns default dimensions when id has no cached value", () => {
|
|
43
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
44
|
+
|
|
45
|
+
expect(result.current.getCachedDimensions()).toEqual({
|
|
46
|
+
width: undefined,
|
|
47
|
+
height: undefined,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("returns cached dimensions after setCachedDimensions", () => {
|
|
52
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
53
|
+
const dimensions = { width: 100, height: 200 };
|
|
54
|
+
|
|
55
|
+
act(() => {
|
|
56
|
+
result.current.setCachedDimensions(dimensions);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
expect(result.current.getCachedDimensions()).toEqual(dimensions);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("setCachedDimensions", () => {
|
|
64
|
+
it("updates dimensions for the hook id", () => {
|
|
65
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
66
|
+
|
|
67
|
+
act(() => {
|
|
68
|
+
result.current.setCachedDimensions({ width: 50, height: 75 });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(result.current.getCachedDimensions()).toEqual({
|
|
72
|
+
width: 50,
|
|
73
|
+
height: 75,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("shares cached dimensions between hook instances with the same id", () => {
|
|
78
|
+
const { result: first } = renderHook(() =>
|
|
79
|
+
useCachedDimensions("shared-id")
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const { result: second } = renderHook(() =>
|
|
83
|
+
useCachedDimensions("shared-id")
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
act(() => {
|
|
87
|
+
first.current.setCachedDimensions({ width: 10, height: 20 });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
expect(second.current.getCachedDimensions()).toEqual({
|
|
91
|
+
width: 10,
|
|
92
|
+
height: 20,
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("getLastCachedDimensions", () => {
|
|
98
|
+
it("returns undefined when no dimensions have been cached", () => {
|
|
99
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
100
|
+
|
|
101
|
+
expect(result.current.getLastCachedDimensions()).toBeUndefined();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("returns the most recently cached dimensions across ids", () => {
|
|
105
|
+
const { result: first } = renderHook(() => useCachedDimensions("first"));
|
|
106
|
+
|
|
107
|
+
const { result: second } = renderHook(() =>
|
|
108
|
+
useCachedDimensions("second")
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
act(() => {
|
|
112
|
+
first.current.setCachedDimensions({ width: 100, height: 100 });
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
act(() => {
|
|
116
|
+
second.current.setCachedDimensions({ width: 200, height: 200 });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(first.current.getLastCachedDimensions()).toEqual({
|
|
120
|
+
width: 200,
|
|
121
|
+
height: 200,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("returns the latest dimensions when the same id is updated multiple times", () => {
|
|
126
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
127
|
+
|
|
128
|
+
act(() => {
|
|
129
|
+
result.current.setCachedDimensions({ width: 100, height: 100 });
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
act(() => {
|
|
133
|
+
result.current.setCachedDimensions({ width: 300, height: 400 });
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
expect(result.current.getLastCachedDimensions()).toEqual({
|
|
137
|
+
width: 300,
|
|
138
|
+
height: 400,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("return value", () => {
|
|
144
|
+
it("exposes getCachedDimensions, setCachedDimensions, and getLastCachedDimensions", () => {
|
|
145
|
+
const { result } = renderHook(() => useCachedDimensions("component-1"));
|
|
146
|
+
|
|
147
|
+
expect(result.current).toEqual({
|
|
148
|
+
getCachedDimensions: expect.any(Function),
|
|
149
|
+
setCachedDimensions: expect.any(Function),
|
|
150
|
+
getLastCachedDimensions: expect.any(Function),
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { create, useStore } from "zustand";
|
|
2
2
|
import { produce } from "immer";
|
|
3
3
|
import { useCallback, useMemo } from "react";
|
|
4
|
+
import { last } from "@applicaster/zapp-react-native-utils/utils";
|
|
4
5
|
|
|
5
6
|
type Dimensions = {
|
|
6
7
|
width: Option<number>;
|
|
@@ -10,14 +11,17 @@ type Dimensions = {
|
|
|
10
11
|
type DimensionsState = {
|
|
11
12
|
dimensions: Record<string, Dimensions>;
|
|
12
13
|
setCachedDimensions: (id: string, dimensions: Dimensions) => void;
|
|
14
|
+
ids: string[];
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
const dimensionsStore = create<DimensionsState>((set) => ({
|
|
16
18
|
dimensions: {},
|
|
19
|
+
ids: [],
|
|
17
20
|
setCachedDimensions: (id, dimensions) =>
|
|
18
21
|
set(
|
|
19
22
|
produce((draft) => {
|
|
20
23
|
draft.dimensions[id] = dimensions;
|
|
24
|
+
draft.ids.push(id);
|
|
21
25
|
})
|
|
22
26
|
),
|
|
23
27
|
}));
|
|
@@ -28,7 +32,7 @@ const initialDimensions = () => ({
|
|
|
28
32
|
});
|
|
29
33
|
|
|
30
34
|
export const useCachedDimensions = (id: string) => {
|
|
31
|
-
const { dimensions, setCachedDimensions } = useStore(
|
|
35
|
+
const { dimensions, setCachedDimensions, ids } = useStore(
|
|
32
36
|
dimensionsStore
|
|
33
37
|
) as DimensionsState;
|
|
34
38
|
|
|
@@ -40,11 +44,22 @@ export const useCachedDimensions = (id: string) => {
|
|
|
40
44
|
setCachedDimensions(id, newDimensions);
|
|
41
45
|
}, []);
|
|
42
46
|
|
|
47
|
+
const getLastCachedDimensions = useCallback(() => {
|
|
48
|
+
const previousId = last(ids);
|
|
49
|
+
|
|
50
|
+
if (!previousId) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return dimensions[previousId];
|
|
55
|
+
}, [dimensions, ids]);
|
|
56
|
+
|
|
43
57
|
return useMemo(
|
|
44
58
|
() => ({
|
|
45
59
|
getCachedDimensions,
|
|
46
60
|
setCachedDimensions: handleSetCachedDimensions,
|
|
61
|
+
getLastCachedDimensions,
|
|
47
62
|
}),
|
|
48
|
-
[getCachedDimensions, handleSetCachedDimensions]
|
|
63
|
+
[getCachedDimensions, handleSetCachedDimensions, getLastCachedDimensions]
|
|
49
64
|
);
|
|
50
65
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react-native";
|
|
3
|
+
import { withModalNavigationContextProvider } from "../";
|
|
4
|
+
|
|
5
|
+
describe("withModalNavigationContextProvider", () => {
|
|
6
|
+
it("does not re-render the wrapped component when props are unchanged", () => {
|
|
7
|
+
const Component = jest.fn(() => null);
|
|
8
|
+
const WrappedComponent = withModalNavigationContextProvider(Component);
|
|
9
|
+
const { rerender } = render(<WrappedComponent title="Modal" />);
|
|
10
|
+
|
|
11
|
+
rerender(<WrappedComponent title="Modal" />);
|
|
12
|
+
|
|
13
|
+
expect(Component).toHaveBeenCalledTimes(1);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -6,11 +6,11 @@ export function useModalNavigationContext() {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function withModalNavigationContextProvider(Component) {
|
|
9
|
-
return function WrappedWithModalNavigationContextProvider(props) {
|
|
9
|
+
return React.memo(function WrappedWithModalNavigationContextProvider(props) {
|
|
10
10
|
return (
|
|
11
11
|
<ModalNavigationContext.Provider value={true}>
|
|
12
12
|
<Component {...props} />
|
|
13
13
|
</ModalNavigationContext.Provider>
|
|
14
14
|
);
|
|
15
|
-
};
|
|
15
|
+
});
|
|
16
16
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { sendTapCellEvent, sendTapMenuItem } from "../Analytics";
|
|
2
1
|
import { getItemType } from "@applicaster/zapp-react-native-utils/navigationUtils";
|
|
3
2
|
import { SCREEN_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
|
|
4
3
|
|
|
@@ -12,7 +11,6 @@ export function onCellPress(
|
|
|
12
11
|
itemIndex,
|
|
13
12
|
layoutVersion = "v1"
|
|
14
13
|
) {
|
|
15
|
-
sendTapCellEvent(entry, component, headerTitle, itemIndex);
|
|
16
14
|
const componentScreenType = screenTypeFromComponent(component);
|
|
17
15
|
const entryScreenType = screenTypeFromEntry(entry);
|
|
18
16
|
const itemType = getItemType(entry, layoutVersion);
|
|
@@ -37,7 +35,3 @@ function screenTypeFromComponent(component) {
|
|
|
37
35
|
function screenTypeFromEntry(entry) {
|
|
38
36
|
return entry && entry.screen_type;
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
export function onMenuItemFocus({ item, index, isHome }) {
|
|
42
|
-
sendTapMenuItem({ item, index, isHome });
|
|
43
|
-
}
|
package/Helpers/index.js
CHANGED
|
@@ -7,42 +7,3 @@ export const ASSETS = {
|
|
|
7
7
|
amazon: "tv_app_background",
|
|
8
8
|
}),
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
export const ANALYTICS_CORE_EVENTS = {
|
|
12
|
-
TAP_CELL: "Tap Cell",
|
|
13
|
-
PLAY_VOD_ITEM: "Play VOD Item",
|
|
14
|
-
VOD_ITEM_PLAY_WAS_TRIGGERED: "VOD Item: Play Was Triggered",
|
|
15
|
-
CHANNEL_ITEM_PLAY_WAS_TRIGGERED: "Channel Item: Play Was Triggered",
|
|
16
|
-
PROGRAM_ITEM_PLAY_WAS_TRIGGERED: "Program Item: Play Was Triggered",
|
|
17
|
-
TAP_MENU_ICON: "Tap Menu Item",
|
|
18
|
-
HOME_SCREEN_VIEWED: "Home Screen: Viewed",
|
|
19
|
-
ITEM_NOT_AVAILABLE: "N/A",
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const ANALYTICS_ENTRY_EVENTS = {
|
|
23
|
-
ITEM_TYPE: "Item Type",
|
|
24
|
-
ITEM_TITLE: "Item Name",
|
|
25
|
-
ITEM_ID: "Item ID",
|
|
26
|
-
ITEM_LINK: "Item Link",
|
|
27
|
-
ITEM_INDEX: "Item Number",
|
|
28
|
-
ITEM_TIME_PLAYED: "Item Total Time Played",
|
|
29
|
-
ITEM_TOTAL_TIME_PLAYED: "Item Total Time Played",
|
|
30
|
-
ITEM_PLAY_COMPLETED: "Completed",
|
|
31
|
-
ITEM_CUSTOM_PROPERTY: "Custom Property",
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const ANALYTICS_COMPONENT_EVENTS = {
|
|
35
|
-
COMPONENT_ID: "Component ID",
|
|
36
|
-
COMPONENT_TYPE: "Component Type",
|
|
37
|
-
CELL_STYLE: "Cell Style",
|
|
38
|
-
HEADER_TITLE: "Header Name",
|
|
39
|
-
COMPONENT_SOURCE: "Component Source",
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const ANALYTICS_MENU_ITEM_EVENTS = {
|
|
43
|
-
ITEM_TYPE: "Item Type",
|
|
44
|
-
ITEM_TITLE: "Item Name",
|
|
45
|
-
ITEM_ID: "Item ID",
|
|
46
|
-
ITEM_HOME_SCREEN: "Home Screen",
|
|
47
|
-
ITEM_INDEX: "Item Number",
|
|
48
|
-
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { ActionExecutorContext } from "@applicaster/zapp-react-native-utils/actionsExecutor/ActionExecutorContext";
|
|
4
|
+
import {
|
|
5
|
+
buildEntryActions,
|
|
6
|
+
EntryActionDeps,
|
|
7
|
+
} from "@applicaster/zapp-react-native-utils/entryActions";
|
|
8
|
+
import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
|
|
9
|
+
import { useScreenStateStore } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useScreenStateStore";
|
|
10
|
+
import {
|
|
11
|
+
useCurrentScreenData,
|
|
12
|
+
useScreenContext,
|
|
13
|
+
} from "@applicaster/zapp-react-native-utils/reactHooks/screen";
|
|
14
|
+
import { RegisteredAction } from "@applicaster/zapp-react-native-utils/uiActionsRegistrator";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Expands `entry.extensions.entry_action` into invokable actions, against the
|
|
18
|
+
* screen this hook is called from.
|
|
19
|
+
*
|
|
20
|
+
* Entry actions are data on the entry, not an installed capability, so there is
|
|
21
|
+
* nothing to look up by identifier: the surface showing the entry expands them.
|
|
22
|
+
* That also decides which screen they execute against — the one whose tree this
|
|
23
|
+
* hook runs in, rather than whichever screen happened to be current when a
|
|
24
|
+
* global provider was registered.
|
|
25
|
+
*
|
|
26
|
+
* Pass the result to `resolveActionIdentifiers` / `resolvePlayerActions` as
|
|
27
|
+
* `expandEntryActions`.
|
|
28
|
+
*/
|
|
29
|
+
export function useEntryActionsExpander(): (
|
|
30
|
+
entry: ZappEntry | ZappFeed
|
|
31
|
+
) => RegisteredAction[] {
|
|
32
|
+
const { pathname } = useRoute();
|
|
33
|
+
|
|
34
|
+
const screenContext = useScreenContext();
|
|
35
|
+
const screenData = useCurrentScreenData();
|
|
36
|
+
const screenState = screenContext?.options;
|
|
37
|
+
const screenStateStore = useScreenStateStore();
|
|
38
|
+
const actionExecutor = React.useContext(ActionExecutorContext);
|
|
39
|
+
|
|
40
|
+
// Read through a ref so the returned expander keeps a stable identity: it
|
|
41
|
+
// feeds `useMemo` dependency lists on surfaces that re-resolve their actions
|
|
42
|
+
// on every registry change.
|
|
43
|
+
const depsRef = React.useRef<EntryActionDeps>();
|
|
44
|
+
|
|
45
|
+
depsRef.current = {
|
|
46
|
+
actionExecutor,
|
|
47
|
+
actionContext: {
|
|
48
|
+
screenData,
|
|
49
|
+
screenState,
|
|
50
|
+
screenRoute: pathname,
|
|
51
|
+
screenStateStore,
|
|
52
|
+
// From the screen context, the way `useCellClick` builds the same bag.
|
|
53
|
+
// The ZappPipes entry context is a route-keyed map, so reading `.data`
|
|
54
|
+
// off it was always undefined.
|
|
55
|
+
screenEntry: screenContext?.entry,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return React.useCallback(
|
|
60
|
+
(entry: ZappEntry | ZappFeed) => buildEntryActions(entry, depsRef.current),
|
|
61
|
+
[]
|
|
62
|
+
);
|
|
63
|
+
}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "16.0.0-rc.
|
|
3
|
+
"version": "16.0.0-rc.110",
|
|
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",
|
|
@@ -28,12 +28,13 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "16.0.0-rc.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "16.0.0-rc.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "16.0.0-rc.
|
|
31
|
+
"@applicaster/applicaster-types": "16.0.0-rc.110",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.110",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-rc.110",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-rc.110",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
|
+
"react-native-sortables": "1.7.1",
|
|
37
38
|
"url": "^0.11.0",
|
|
38
39
|
"uuid": "^3.3.2"
|
|
39
40
|
},
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
3
|
-
import { useNetworkStatusLocalizations } from "./utils";
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
children?: React.ReactNode;
|
|
7
|
-
hidden?: boolean;
|
|
8
|
-
online?: boolean;
|
|
9
|
-
previousOnline?: boolean;
|
|
10
|
-
dismiss: () => void;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const NOTIF_DURATION = 4500;
|
|
14
|
-
|
|
15
|
-
const styles: Record<any, React.CSSProperties> = {
|
|
16
|
-
body: {
|
|
17
|
-
position: "absolute",
|
|
18
|
-
bottom: 0,
|
|
19
|
-
width: 1920,
|
|
20
|
-
height: 200,
|
|
21
|
-
background:
|
|
22
|
-
"linear-gradient(180deg, rgba(17,17,17,0.9) 0%, rgba(17,17,17,1) 49%, rgba(0,0,0,0.85) 100%)",
|
|
23
|
-
display: "flex",
|
|
24
|
-
alignItems: "center",
|
|
25
|
-
justifyContent: "center",
|
|
26
|
-
flexDirection: "column",
|
|
27
|
-
color: "#fff",
|
|
28
|
-
paddingBottom: 15,
|
|
29
|
-
},
|
|
30
|
-
title: {
|
|
31
|
-
fontSize: 28,
|
|
32
|
-
margin: 0,
|
|
33
|
-
padding: 0,
|
|
34
|
-
},
|
|
35
|
-
subtitle: {
|
|
36
|
-
fontSize: 20,
|
|
37
|
-
margin: 0,
|
|
38
|
-
padding: 0,
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const NotificationView = (props: Props) => {
|
|
43
|
-
const { children, hidden, dismiss, previousOnline, online } = props;
|
|
44
|
-
|
|
45
|
-
const theme = useTheme<BaseThemePropertiesTV>();
|
|
46
|
-
const storedLocalizations = useNetworkStatusLocalizations();
|
|
47
|
-
|
|
48
|
-
const [open, setOpen] = React.useState<boolean | null>(null);
|
|
49
|
-
|
|
50
|
-
const timeout = React.useRef<NodeJS.Timeout>();
|
|
51
|
-
const wentOnline = !previousOnline && props.online;
|
|
52
|
-
|
|
53
|
-
const onClose = () => {
|
|
54
|
-
setOpen(false);
|
|
55
|
-
dismiss();
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const closeNotification = () => {
|
|
59
|
-
clearTimeout(timeout.current as NodeJS.Timeout);
|
|
60
|
-
|
|
61
|
-
timeout.current = setTimeout(() => {
|
|
62
|
-
setOpen(false);
|
|
63
|
-
}, NOTIF_DURATION);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const openNotification = () => {
|
|
67
|
-
if (!open && !hidden) {
|
|
68
|
-
setOpen(true);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const handleNotificationChange = () => {
|
|
73
|
-
if (open !== null) {
|
|
74
|
-
openNotification();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
closeNotification();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
React.useEffect(() => {
|
|
81
|
-
handleNotificationChange();
|
|
82
|
-
}, [hidden, online]);
|
|
83
|
-
|
|
84
|
-
const showOnlineMsg = wentOnline || online;
|
|
85
|
-
|
|
86
|
-
const MSG = showOnlineMsg
|
|
87
|
-
? (theme?.online_notification_title ??
|
|
88
|
-
storedLocalizations?.online_notification_title)
|
|
89
|
-
: (theme?.offline_notification_title ??
|
|
90
|
-
storedLocalizations?.offline_notification_title);
|
|
91
|
-
|
|
92
|
-
const EXTRA_MSG = showOnlineMsg
|
|
93
|
-
? (theme?.online_notification_subtitle ??
|
|
94
|
-
storedLocalizations?.online_notification_subtitle)
|
|
95
|
-
: (theme?.offline_notification_subtitle ??
|
|
96
|
-
storedLocalizations?.offline_notification_subtitle);
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
<div onClick={onClose}>
|
|
100
|
-
{children}
|
|
101
|
-
{open ? (
|
|
102
|
-
<div style={styles.body}>
|
|
103
|
-
<div style={styles.title}>
|
|
104
|
-
<h2>{MSG}</h2>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<h4 style={styles.subtitle}>{EXTRA_MSG}</h4>
|
|
108
|
-
</div>
|
|
109
|
-
) : null}
|
|
110
|
-
</div>
|
|
111
|
-
);
|
|
112
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
|
|
3
|
-
import { useNetworkStatusLocalizations } from "./utils";
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
children?: React.ReactNode;
|
|
7
|
-
online?: boolean;
|
|
8
|
-
previousOnline?: boolean;
|
|
9
|
-
dismiss: () => void;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE = 4500; // ms
|
|
13
|
-
|
|
14
|
-
const styles: Record<any, React.CSSProperties> = {
|
|
15
|
-
body: {
|
|
16
|
-
position: "absolute",
|
|
17
|
-
top: 0,
|
|
18
|
-
width: 1920,
|
|
19
|
-
height: 200,
|
|
20
|
-
background:
|
|
21
|
-
"linear-gradient(180deg, rgba(17,17,17,0.9) 0%, rgba(17,17,17,1) 49%, rgba(0,0,0,0.85) 100%)",
|
|
22
|
-
display: "flex",
|
|
23
|
-
alignItems: "center",
|
|
24
|
-
justifyContent: "center",
|
|
25
|
-
flexDirection: "column",
|
|
26
|
-
color: "#fff",
|
|
27
|
-
paddingTop: 15,
|
|
28
|
-
},
|
|
29
|
-
title: {
|
|
30
|
-
fontSize: 28,
|
|
31
|
-
margin: 0,
|
|
32
|
-
padding: 0,
|
|
33
|
-
},
|
|
34
|
-
subtitle: {
|
|
35
|
-
fontSize: 20,
|
|
36
|
-
margin: 0,
|
|
37
|
-
padding: 0,
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
let timer: NodeJS.Timeout;
|
|
42
|
-
|
|
43
|
-
export const NotificationView = (props: Props) => {
|
|
44
|
-
const { children, dismiss, previousOnline = true, online } = props;
|
|
45
|
-
|
|
46
|
-
const theme = useTheme<BaseThemePropertiesTV>();
|
|
47
|
-
const storedLocalizations = useNetworkStatusLocalizations();
|
|
48
|
-
|
|
49
|
-
const [shown, setShown] = React.useState<boolean>(false);
|
|
50
|
-
|
|
51
|
-
const onClose = () => {
|
|
52
|
-
setShown(false);
|
|
53
|
-
dismiss();
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
React.useEffect(() => {
|
|
57
|
-
if (previousOnline && online) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!previousOnline && !online) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (previousOnline && !online) {
|
|
66
|
-
// went to offline
|
|
67
|
-
clearTimeout(timer);
|
|
68
|
-
setShown(true);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!previousOnline && online) {
|
|
72
|
-
// back to online
|
|
73
|
-
setShown(true);
|
|
74
|
-
|
|
75
|
-
timer = setTimeout(() => {
|
|
76
|
-
setShown(false);
|
|
77
|
-
}, DURATION_TO_HIDE_AFTER_BACK_TO_ONLINE);
|
|
78
|
-
}
|
|
79
|
-
}, [online, previousOnline]);
|
|
80
|
-
|
|
81
|
-
const title = online
|
|
82
|
-
? (theme?.online_notification_title ??
|
|
83
|
-
storedLocalizations?.online_notification_title)
|
|
84
|
-
: (theme?.offline_notification_title ??
|
|
85
|
-
storedLocalizations?.offline_notification_title);
|
|
86
|
-
|
|
87
|
-
const subtitle = online
|
|
88
|
-
? (theme?.online_notification_subtitle ??
|
|
89
|
-
storedLocalizations?.online_notification_subtitle)
|
|
90
|
-
: (theme?.offline_notification_subtitle ??
|
|
91
|
-
storedLocalizations?.offline_notification_subtitle);
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<div onClick={onClose}>
|
|
95
|
-
{children}
|
|
96
|
-
{shown ? (
|
|
97
|
-
<div style={styles.body}>
|
|
98
|
-
<div style={styles.title}>
|
|
99
|
-
<h2>{title}</h2>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
<h4 style={styles.subtitle}>{subtitle}</h4>
|
|
103
|
-
</div>
|
|
104
|
-
) : null}
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
};
|